iwb_canvas_engine 3.0.0
iwb_canvas_engine: ^3.0.0 copied to clipboard
Scene-based canvas engine for Flutter: model, rendering, input, JSON serialization.
3.0.0 - 2026-02-13 #
Breaking #
- Runtime snapshot boundaries are now strict:
SceneController(initialSnapshot: ...)throwsArgumentErrorfor malformed snapshots.replaceScene(...)throwsArgumentErrorfor malformed snapshots.
- Runtime snapshot import no longer auto-inserts a missing background layer.
- JSON codec now rejects non-positive
background.grid.cellSizeregardless of grid enabled state. - Write-boundary validation is now strict:
addNode(...)rejects malformedNodeSpecvalues withArgumentError.patchNode(...)rejects malformed presentNodePatchfields withArgumentError.writeNodeTransformSet(...),writeSelectionTransform(...), andwriteSelectionTranslate(...)reject non-finiteTransform2D/Offset.opacityis now strict at write boundary ([0,1]) instead of relying on soft normalization.
- Text node write API is now size-derived:
TextNodeSpecno longer acceptssize.TextNodePatchno longer acceptssize.
- Interactive controller event streams (
actions,editTextRequests) are now asynchronous; listeners are no longer invoked in the emitter call stack.
Changed #
- Controller repaint/listener notifications are now deferred to a microtask after commit and coalesced to one notification per event-loop tick, so
write(...)calls inside listeners no longer trip nested-write guards from the originating transaction. - Transactional repaint requests are now buffered until successful commit; rollback discards buffered repaint/signals, and successful commit delivers signals before repaint listener notification.
- Spatial-index invalidation now tracks hit candidate bounds (
nodeHitTestCandidateBoundsWorld) sohitPaddingupdates rebuild candidate lookup correctly. - Spatial index now uses a dual-path layout (
grid cells+large candidates) withkMaxCellsPerNode = 1024, so a single huge node can no longer explode per-cell indexing cost. - Spatial index construction is fixed to the internal index cell size and no longer depends on background visual grid settings.
- Spatial index commits are now incremental: local hit-geometry changes update per-node cell coverage (
added/removed/hitGeometryChangedIds) without full-index rebuild; rebuild is kept as a fallback path when incremental apply is not possible. - Interactive pen/highlighter commits now enforce
kMaxStrokePointsPerNode = 20_000with deterministic index-uniform downsampling that preserves stroke endpoints. - Path-stroke precise hit-testing now enforces
kMaxStrokeHitSamplesPerMetric = 2_048by increasing sampling step on very long path metrics. - Spatial index query now enforces
kMaxQueryCells = 50_000; oversized queries switch to bounded all-candidate scan with exact intersection filtering instead of unbounded cell iteration. - Transaction write path now uses scene/layer/node copy-on-write: first mutation shallow-clones scene metadata and clones only touched layers/nodes, while no-op node patches skip COW cloning.
- Commit state-change path now keeps node-id index incrementally: local non-structural commits reuse existing
allNodeIds, structural commits materialize ids lazily once, andnodeIdSeedis treated as a monotonic generator (lower-bounded by committed scene ids). - Commit/store now maintain
nodeLocator(NodeId -> layer/node position) and writer hot paths use locator-based O(1) lookup instead of linear node-id scans. - Stroke render-path cache now validates freshness by
(node.id, pointsRevision)in O(1), avoiding per-frame point-list hashing/traversal in cache checks. - Move-mode drag now uses preview translation during pointer move and commits scene translation once on pointer up; pointer cancel no longer mutates document state.
- Added shared internal scene-value validation (
scene_value_validation.dart) and wired it into runtime snapshot import and JSON encode/decode validation paths. - Selection transaction hot paths now keep a hash-based mutable working set in place (
toggle/clear/erase/delete/replace) instead of rebuildingSetinstances on each step. - Text node bounds are now derived in-engine from text layout inputs; snapshot/JSON import recomputes text size on load so stale serialized values do not stay authoritative at runtime.
- Added load-profile benchmark tooling (
dart run tool/bench/run_load_profiles.dart --profile=<smoke|full>) with structured JSON output and dedicated benchmark cases for large node/stroke scenes and worst-case spatial/path scenarios. - CI now runs smoke load profiles and uploads benchmark artifacts; a new nightly workflow runs full load profiles and extended randomized transaction fuzzing.
- Randomized transaction fuzz tests now support environment-based scaling (
IWB_FUZZ_SEEDS,IWB_FUZZ_STEPS,IWB_FUZZ_BASE_SEED) and explicitly assert finite numeric state after each step.
2.0.1 - 2026-02-10 #
Breaking #
SceneWriteTxnno longer exposes node-id bookkeeping methods (writeNewNodeId,writeContainsNodeId,writeRegisterNodeId,writeUnregisterNodeId,writeRebuildNodeIdIndex).ActionCommittedand internal committed signal payloads are now immutable snapshots (mutatingnodeIds/payloadthrows).
Changed #
- Commit pipeline now finalizes store state first and only then emits committed signals.
- Controller commit now derives
allNodeIdsandnodeIdSeedfrom the committed scene as the single source of truth. SceneWriter.writeNodeErasenow respects deletable-layer policy consistently with selection delete flow.SceneWriter.writeGridCellSizeandSceneWriter.writeCameraOffsetnow reject non-finite/invalid inputs at write boundary.- Selection normalization now preserves explicit non-selectable ids, so
selectAll(onlySelectable: false)remains stable after commit. - Commit state-change path no longer performs a redundant second deep clone of scene data; mutating transactions now clone once (clone-on-first-mutation).
- Added runtime commit invariant assertions for store consistency in debug/test execution.
2.0.0 - 2026-02-10 #
Breaking #
- Removed
lib/advanced.dart;iwb_canvas_engine.dartis now the single public entrypoint. iwb_canvas_engine.dartno longer exports mutable core model files (src/core/scene.dart,src/core/nodes.dart).SceneControllerInteractiveV2removed legacy mutable API:- removed constructor parameter
scene, - removed getters
coreandscene, addNodenow accepts onlyNodeSpec.
- removed constructor parameter
- Public transactional write callback now uses
SceneWriteTxn(safe contract without rawscene,writeFindNode, orwriteMark*APIs).
Added #
- New public
SceneWriteTxncontract (lib/src/public/scene_write_txn.dart). - New public
SceneRenderStatecontract (lib/src/public/scene_render_state.dart) for painter/view integration. SceneControllerV2.requestRepaint()for explicit repaint without transactional mutation.- Commit-path tests for no-op, signals-only, and selection-policy patch normalization.
- Guardrails for single entrypoint and safe transaction API surface.
Changed #
TxnContextnow uses lazy scene clone-on-first-mutation.- Commit pipeline supports explicit branches:
- no-op: no commit/revision/repaint,
- signals-only: commit revision + signal flush without repaint,
- state-change/document-replace: full commit path.
- Selection normalization now handles node patches that affect selection policy for selected nodes.
- Interactive controller refactored to avoid read-only transaction misuse and raw writer mutations in move rollback.
1.0.0 - 2026-02-10 #
Breaking #
- Finalized the v2 public API in
iwb_canvas_engine.dart/advanced.dartaround immutable snapshots, specs, and patch semantics. - Removed the legacy mutable public surface from package entrypoints.
Added #
- Stable interactive runtime aliases:
SceneControllerandSceneViewover v2 implementations. - Strict JSON v2 codec contracts (
schemaVersion = 2) with canonical validation errors viaSceneJsonFormatException. - Bounded render caches and spatial-index optimizations for interactive performance.
- Expanded automated validation with parity, regression, invariant coverage, and import-boundary checks.
Changed #
- Hardened scene invariants: unique node ids, single canonical background layer, explicit constructor/decoder canonicalization.
- Improved input transactional behavior for move/draw/eraser flows, including cancel safety and monotonic event timelines.
- Improved rendering consistency and parity for selection visuals, text line-height semantics, and thin-line snapping behavior.
- Refreshed package documentation (
README,API_GUIDE,ARCHITECTURE) for the1.0.0release baseline.