@rasamjs/core 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +14 -4
- package/CHANGELOG.md +59 -0
- package/COMPONENTS.md +229 -0
- package/README.md +39 -6
- package/RELEASING.md +4 -2
- package/dist/advanced.d.ts +1 -1
- package/dist/advanced.d.ts.map +1 -1
- package/dist/catalog/fragment.d.ts +2 -2
- package/dist/catalog/fragment.d.ts.map +1 -1
- package/dist/catalog/fragment.js.map +1 -1
- package/dist/changes/derived.d.ts +10 -0
- package/dist/changes/derived.d.ts.map +1 -0
- package/dist/changes/derived.js +14 -0
- package/dist/changes/derived.js.map +1 -0
- package/dist/changes/restore.d.ts.map +1 -1
- package/dist/changes/restore.js +22 -4
- package/dist/changes/restore.js.map +1 -1
- package/dist/changes/service.d.ts +5 -0
- package/dist/changes/service.d.ts.map +1 -1
- package/dist/changes/service.js +16 -2
- package/dist/changes/service.js.map +1 -1
- package/dist/components/changes.d.ts +34 -0
- package/dist/components/changes.d.ts.map +1 -0
- package/dist/components/changes.js +119 -0
- package/dist/components/changes.js.map +1 -0
- package/dist/components/component.d.ts +62 -0
- package/dist/components/component.d.ts.map +1 -0
- package/dist/components/component.js +355 -0
- package/dist/components/component.js.map +1 -0
- package/dist/components/decorators.d.ts +7 -0
- package/dist/components/decorators.d.ts.map +1 -0
- package/dist/components/decorators.js +81 -0
- package/dist/components/decorators.js.map +1 -0
- package/dist/components/metadata.d.ts +10 -0
- package/dist/components/metadata.d.ts.map +1 -0
- package/dist/components/metadata.js +85 -0
- package/dist/components/metadata.js.map +1 -0
- package/dist/components/registry.d.ts +24 -0
- package/dist/components/registry.d.ts.map +1 -0
- package/dist/components/registry.js +78 -0
- package/dist/components/registry.js.map +1 -0
- package/dist/components/types.d.ts +54 -0
- package/dist/components/types.d.ts.map +1 -0
- package/dist/components/types.js +2 -0
- package/dist/components/types.js.map +1 -0
- package/dist/components/view.d.ts +9 -0
- package/dist/components/view.d.ts.map +1 -0
- package/dist/components/view.js +104 -0
- package/dist/components/view.js.map +1 -0
- package/dist/components.d.ts +6 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/components.js +5 -0
- package/dist/components.js.map +1 -0
- package/dist/core/node.d.ts +7 -0
- package/dist/core/node.d.ts.map +1 -1
- package/dist/core/node.js +30 -0
- package/dist/core/node.js.map +1 -1
- package/dist/interchange/clone.d.ts.map +1 -1
- package/dist/interchange/clone.js +3 -2
- package/dist/interchange/clone.js.map +1 -1
- package/dist/interchange/reconstruct.d.ts.map +1 -1
- package/dist/interchange/reconstruct.js +16 -12
- package/dist/interchange/reconstruct.js.map +1 -1
- package/dist/interchange/references.d.ts.map +1 -1
- package/dist/interchange/references.js +10 -4
- package/dist/interchange/references.js.map +1 -1
- package/dist/mixins/parent-internals.d.ts +6 -0
- package/dist/mixins/parent-internals.d.ts.map +1 -1
- package/dist/mixins/parent-internals.js +34 -0
- package/dist/mixins/parent-internals.js.map +1 -1
- package/dist/mixins/parent.d.ts.map +1 -1
- package/dist/mixins/parent.js +6 -1
- package/dist/mixins/parent.js.map +1 -1
- package/dist/mixins/types.d.ts +2 -2
- package/dist/mixins/types.d.ts.map +1 -1
- package/dist/resources/references.d.ts +2 -0
- package/dist/resources/references.d.ts.map +1 -1
- package/dist/resources/references.js +3 -3
- package/dist/resources/references.js.map +1 -1
- package/dist/services/catalog.d.ts.map +1 -1
- package/dist/services/catalog.js +5 -3
- package/dist/services/catalog.js.map +1 -1
- package/dist/services/defs-manager.d.ts +2 -0
- package/dist/services/defs-manager.d.ts.map +1 -1
- package/dist/services/defs-manager.js +4 -0
- package/dist/services/defs-manager.js.map +1 -1
- package/dist/services/element-key.d.ts +4 -0
- package/dist/services/element-key.d.ts.map +1 -0
- package/dist/services/element-key.js +12 -0
- package/dist/services/element-key.js.map +1 -0
- package/dist/services/initialization.d.ts +7 -0
- package/dist/services/initialization.d.ts.map +1 -0
- package/dist/services/initialization.js +27 -0
- package/dist/services/initialization.js.map +1 -0
- package/dist/services/registry.d.ts +8 -0
- package/dist/services/registry.d.ts.map +1 -1
- package/dist/services/registry.js +45 -10
- package/dist/services/registry.js.map +1 -1
- package/dist/services/types.d.ts +17 -0
- package/dist/services/types.d.ts.map +1 -1
- package/dist/template/parts.d.ts +12 -6
- package/dist/template/parts.d.ts.map +1 -1
- package/dist/template/parts.js +36 -29
- package/dist/template/parts.js.map +1 -1
- package/dist/template/render.d.ts +6 -7
- package/dist/template/render.d.ts.map +1 -1
- package/dist/template/render.js +188 -44
- package/dist/template/render.js.map +1 -1
- package/dist/template/svg-tag.d.ts +5 -1
- package/dist/template/svg-tag.d.ts.map +1 -1
- package/dist/template/svg-tag.js.map +1 -1
- package/dist/text/internals.d.ts +1 -0
- package/dist/text/internals.d.ts.map +1 -1
- package/dist/types/common.d.ts +27 -0
- package/dist/types/common.d.ts.map +1 -1
- package/package.json +156 -148
- package/reports/adoption.json +20 -20
- package/reports/animation-benchmark.json +612 -612
- package/reports/benchmark.json +40 -40
- package/reports/components-benchmark-before.json +10 -0
- package/reports/components-benchmark.json +10 -0
- package/reports/creation.json +26 -26
- package/reports/interchange-benchmark.json +85 -85
- package/reports/public-api-contract.json +334 -17
- package/reports/size-components.json +102 -0
- package/reports/size-parity.json +47 -34
- package/reports/size.json +6 -4
- package/reports/svgjs-comparison.json +3100 -3100
- package/reports/svgjs-comparison.md +16 -16
- package/reports/svgjs-parity-current.json +135 -42
- package/src/advanced.ts +1 -1
- package/src/catalog/fragment.ts +2 -2
- package/src/changes/derived.ts +19 -0
- package/src/changes/restore.ts +27 -4
- package/src/changes/service.ts +21 -6
- package/src/components/changes.ts +131 -0
- package/src/components/component.ts +401 -0
- package/src/components/decorators.ts +104 -0
- package/src/components/metadata.ts +111 -0
- package/src/components/registry.ts +79 -0
- package/src/components/types.ts +66 -0
- package/src/components/view.ts +123 -0
- package/src/components.ts +15 -0
- package/src/core/node.ts +32 -1
- package/src/interchange/clone.ts +3 -2
- package/src/interchange/reconstruct.ts +16 -12
- package/src/interchange/references.ts +12 -4
- package/src/mixins/parent-internals.ts +37 -0
- package/src/mixins/parent.ts +13 -4
- package/src/mixins/types.ts +2 -2
- package/src/resources/references.ts +5 -5
- package/src/services/catalog.ts +5 -3
- package/src/services/defs-manager.ts +5 -0
- package/src/services/element-key.ts +14 -0
- package/src/services/initialization.ts +25 -0
- package/src/services/registry.ts +47 -10
- package/src/services/types.ts +21 -0
- package/src/template/parts.ts +54 -39
- package/src/template/render.ts +211 -54
- package/src/template/svg-tag.ts +6 -1
- package/src/text/internals.ts +1 -0
- package/src/types/common.ts +29 -0
package/API.md
CHANGED
|
@@ -14,9 +14,9 @@ Runtime exports (32):
|
|
|
14
14
|
|
|
15
15
|
`BBox`, `Circle`, `ClipPath`, `Defs`, `Ellipse`, `Group`, `Line`, `LinearGradient`, `Marker`, `Matrix`, `Path`, `PathArray`, `PathBuilder`, `PointArray`, `Polygon`, `Polyline`, `RadialGradient`, `Rect`, `Renderer`, `SVG`, `Shape`, `Stop`, `Svg`, `SvgNode`, `SvgTemplate`, `SvgText`, `Use`, `Vec2`, `ViewBox`, `ViewportError`, `attr`, `svg`.
|
|
16
16
|
|
|
17
|
-
Type-only exports (
|
|
17
|
+
Type-only exports (48):
|
|
18
18
|
|
|
19
|
-
`AnyNode`, `AttributeValue`, `Bounds`, `Box`, `CircleOptions`, `ClipPathOptions`, `CommonAttributes`, `Disposable`, `DrawingPointerEvent`, `EllipseOptions`, `GeometryChange`, `GradientStop`, `Length`, `LineOptions`, `LinearGradientOptions`, `MarkerOptions`, `MatrixDecomposition`, `MatrixValues`, `NestedSvgOptions`, `NodeEvents`, `PaintValue`, `PathAttributes`, `PathCommand`, `PathInput`, `PathOptions`, `PathSegment`, `Point`, `PointInput`, `PointerEventType`, `PolygonOptions`, `PolylineAttributes`, `PolylineOptions`, `RadialGradientOptions`, `RectOptions`, `ResourceReference`, `SVGOptions`, `StyleProperties`, `SvgAttributes`, `SvgOptions`, `TemplateInstance`, `TemplateValue`, `TextAttributes`, `TextMeasurementProvider`, `TextOptions`, `TransformState`, `UseOptions`.
|
|
19
|
+
`AnyNode`, `AttributeValue`, `Bounds`, `Box`, `CircleOptions`, `ClipPathOptions`, `CommonAttributes`, `Disposable`, `DrawingPointerEvent`, `EditRules`, `EllipseOptions`, `GeometryChange`, `GradientStop`, `Length`, `LineOptions`, `LinearGradientOptions`, `MarkerOptions`, `MatrixDecomposition`, `MatrixValues`, `NestedSvgOptions`, `NodeEvents`, `PaintValue`, `PathAttributes`, `PathCommand`, `PathInput`, `PathOptions`, `PathSegment`, `Point`, `PointInput`, `PointerEventType`, `PolygonOptions`, `PolylineAttributes`, `PolylineOptions`, `PortDefinition`, `RadialGradientOptions`, `RectOptions`, `ResourceReference`, `SVGOptions`, `StyleProperties`, `SvgAttributes`, `SvgOptions`, `TemplateInstance`, `TemplateValue`, `TextAttributes`, `TextMeasurementProvider`, `TextOptions`, `TransformState`, `UseOptions`.
|
|
20
20
|
|
|
21
21
|
## @rasamjs/core/advanced
|
|
22
22
|
|
|
@@ -24,9 +24,9 @@ Runtime exports (57):
|
|
|
24
24
|
|
|
25
25
|
`Attributes`, `BBox`, `BoundsService`, `Circle`, `ClipPath`, `Creatable`, `Defs`, `DefsManager`, `DomFactory`, `DrawingContext`, `Elements`, `Ellipse`, `Emitter`, `Gradient`, `Group`, `Guards`, `Line`, `LinearGradient`, `Marker`, `Matrix`, `Namespace`, `Parent`, `Path`, `PathArray`, `PathBuilder`, `PathGeometry`, `PointArray`, `PointerRouter`, `Polygon`, `Polyline`, `RadialGradient`, `Rect`, `Registry`, `Renderer`, `SVG`, `Scheduler`, `Shape`, `Sizable`, `Stop`, `Styleable`, `Svg`, `SvgNode`, `SvgTag`, `SvgTemplate`, `SvgText`, `Textual`, `Transformable`, `Use`, `Vec2`, `ViewBox`, `ViewportError`, `attr`, `isParent`, `isTextual`, `isTransformable`, `mix`, `svg`.
|
|
26
26
|
|
|
27
|
-
Type-only exports (
|
|
27
|
+
Type-only exports (55):
|
|
28
28
|
|
|
29
|
-
`AnyNode`, `AttributeValue`, `Bounds`, `Box`, `CircleOptions`, `ClipPathOptions`, `CommonAttributes`, `CreatableFeature`, `Ctor`, `Disposable`, `DrawingPointerEvent`, `ElementClass`, `EllipseOptions`, `GeometryChange`, `GradientStop`, `Length`, `LineOptions`, `LinearGradientOptions`, `MarkerOptions`, `MatrixDecomposition`, `MatrixValues`, `NestedSvgOptions`, `NodeEvents`, `PaintValue`, `ParentFeature`, `ParentNode`, `PathAttributes`, `PathCommand`, `PathInput`, `PathOptions`, `PathSegment`, `Point`, `PointInput`, `PointerEventType`, `PolygonOptions`, `PolylineAttributes`, `PolylineOptions`, `RadialGradientOptions`, `RectOptions`, `ResourceReference`, `SVGOptions`, `SizableFeature`, `StyleProperties`, `SvgAttributes`, `SvgOptions`, `TemplateInstance`, `TemplateValue`, `TextAttributes`, `TextMeasurementProvider`, `TextOptions`, `TransformState`, `UseOptions`.
|
|
29
|
+
`AnyNode`, `AttributeValue`, `Bounds`, `Box`, `CircleOptions`, `ClipPathOptions`, `CommonAttributes`, `CreatableFeature`, `Ctor`, `Disposable`, `DrawingPointerEvent`, `EditRules`, `ElementClass`, `ElementVariant`, `EllipseOptions`, `GeometryChange`, `GradientStop`, `Length`, `LineOptions`, `LinearGradientOptions`, `MarkerOptions`, `MatrixDecomposition`, `MatrixValues`, `NestedSvgOptions`, `NodeEvents`, `PaintValue`, `ParentFeature`, `ParentNode`, `PathAttributes`, `PathCommand`, `PathInput`, `PathOptions`, `PathSegment`, `Point`, `PointInput`, `PointerEventType`, `PolygonOptions`, `PolylineAttributes`, `PolylineOptions`, `PortDefinition`, `RadialGradientOptions`, `RectOptions`, `ResourceReference`, `SVGOptions`, `SizableFeature`, `StyleProperties`, `SvgAttributes`, `SvgOptions`, `TemplateInstance`, `TemplateValue`, `TextAttributes`, `TextMeasurementProvider`, `TextOptions`, `TransformState`, `UseOptions`.
|
|
30
30
|
|
|
31
31
|
## @rasamjs/core/animation
|
|
32
32
|
|
|
@@ -58,6 +58,16 @@ Type-only exports (14):
|
|
|
58
58
|
|
|
59
59
|
`ChangeBatch`, `ChangeDerivation`, `ChangeEvent`, `ChangeGroup`, `ChangeMetadata`, `ContentState`, `ModelChange`, `ModelFeatures`, `ModelSnapshot`, `NativeNodeState`, `NodeHandle`, `Placement`, `PropertyState`, `TextPolicies`.
|
|
60
60
|
|
|
61
|
+
## @rasamjs/core/components
|
|
62
|
+
|
|
63
|
+
Runtime exports (7):
|
|
64
|
+
|
|
65
|
+
`Component`, `ComponentTypes`, `action`, `component`, `isComponentChild`, `prop`, `state`.
|
|
66
|
+
|
|
67
|
+
Type-only exports (9):
|
|
68
|
+
|
|
69
|
+
`ActionDefinition`, `ComponentClass`, `ComponentDefinition`, `ComponentFields`, `ComponentOptions`, `ComponentProps`, `PropDefinition`, `PropOptions`, `PropValue`.
|
|
70
|
+
|
|
61
71
|
## @rasamjs/core/data
|
|
62
72
|
|
|
63
73
|
Runtime exports (5):
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## [0.3.0] - 2026-11-07
|
|
6
|
+
|
|
7
|
+
- Add `DefsManager.consumersOf(target)`, the nodes holding a typed reference to a target,
|
|
8
|
+
read from the reference index instead of scanning the drawing.
|
|
9
|
+
- Treat connector ends (`data-rasam-connector-start` and `-end`) as links, not
|
|
10
|
+
resources: exporting or copying a connector no longer copies its targets into
|
|
11
|
+
`<defs>`, and importing one whose target was left out drops that link instead of
|
|
12
|
+
throwing.
|
|
13
|
+
- Add component ports: override `ports()` to declare named connection points from
|
|
14
|
+
props and the saved size, in local coordinates with an optional side. The frozen,
|
|
15
|
+
validated `portDefinitions` getter is computed again only when saved props change,
|
|
16
|
+
and core exports the structural `PortDefinition` type that connectors read.
|
|
17
|
+
- Add `actionDefinitions` to components: their `@action` methods with undo labels.
|
|
18
|
+
- Add `resize: 'props'` components and edit rules: the size is saved as built-in
|
|
19
|
+
`width` and `height` props that `render()` reads through `width()` and `height()`,
|
|
20
|
+
`size()` changes them as one undo step and redraws at once, and the transformer
|
|
21
|
+
resizes such a component through `size()` instead of scaling it.
|
|
22
|
+
- Add the `notation: 'si'` prop option, so editors accept and show engineering
|
|
23
|
+
notation such as `4.7k`, `4k7` or `4.7 kΩ`.
|
|
24
|
+
- Render `@state` changes for every component in one shared frame per drawing, as one
|
|
25
|
+
temporary change. History now restores a component's props, position and existence
|
|
26
|
+
but not its rendered children; after undo, redo or a cancelled group the component
|
|
27
|
+
redraws them from restored props and current live state. Live renders that add or
|
|
28
|
+
remove nodes no longer make undo fail, recreated instances start from state
|
|
29
|
+
defaults, and the conflict exception for live-painted holes is removed.
|
|
30
|
+
- Preserve restored props and redo when `created()` writes defaults; the hook still
|
|
31
|
+
runs on every copy. Isolate internal edits from application `edit()` methods,
|
|
32
|
+
validate raw props JSON before mutation, and rebuild saved views with extra attrs.
|
|
33
|
+
- Share component change routing per drawing, discover only added subtrees, and cache
|
|
34
|
+
sibling order between structural edits so moves do not scale with drawing size.
|
|
35
|
+
- Rename the type registry to `ComponentTypes` and infer `create()` option names and
|
|
36
|
+
value types from public primitive fields. Record delegated 34 KiB catalog, 41 KiB
|
|
37
|
+
components and 20.5 KiB root gzip caps, with a reproducible component benchmark.
|
|
38
|
+
- Add the opt-in `@rasamjs/core/components` entry: class components, `@component`,
|
|
39
|
+
`@prop`, `@state`, `@action`, per-drawing type registries, metadata and icons.
|
|
40
|
+
Preserve classes and props through migration, native adoption, import, clone,
|
|
41
|
+
clipboard and replay; bind saved children before subsequent updates. Batch live
|
|
42
|
+
state per frame as temporary changes and reject inherited-member field collisions.
|
|
43
|
+
|
|
44
|
+
- Compare template bindings with current model values so rendering after undo or
|
|
45
|
+
cancellation restores attributes and text without replacing element nodes.
|
|
46
|
+
- Add element variants: a class with `static variant` registers for one `data-*`
|
|
47
|
+
attribute value of its tag, next to the tag's base class. Creation, adoption, import,
|
|
48
|
+
clone and change replay resolve it, and the identifying value is fixed and reserved.
|
|
49
|
+
The registry adds `resolve(element)`, `registered(Constructor)` and `variant()`.
|
|
50
|
+
- Templates render nested templates in holes between elements or at the top level:
|
|
51
|
+
a template, an iterable of templates, or `null`/`undefined`/booleans/`''` for
|
|
52
|
+
nothing. Items whose literal matches by index update in place; updates validate and
|
|
53
|
+
build new items off the drawing before changing it. Replacing a template, or removing
|
|
54
|
+
nested items, now disposes them semantically, so undo restores them and no longer
|
|
55
|
+
clears history.
|
|
56
|
+
- Add the structural `EditRules` type that editing tools read from `node.editRules`
|
|
57
|
+
to limit rotation, resizing and flips per node.
|
|
58
|
+
- Add `static ownsChildren` for containers whose class owns its children. Outside
|
|
59
|
+
structural edits throw before allocating or moving anything; the class edits them
|
|
60
|
+
through `withOwnChildren()`, and core's adoption, replay and owner destruction pass.
|
|
61
|
+
|
|
62
|
+
## [0.2.0] - 2026-11-06
|
|
63
|
+
|
|
5
64
|
- Add `document: 'presentation'` imports to retain scoped root styles and compositing
|
|
6
65
|
while omitting the viewport envelope. Validate document envelopes before unwrapping.
|
|
7
66
|
Add `document: 'replace'` for empty drawings so full-document restoration does not
|
package/COMPONENTS.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Class components
|
|
2
|
+
|
|
3
|
+
Import the opt-in `@rasamjs/core/components` entry. Components are trusted application
|
|
4
|
+
classes extending `Component`, which is a closed `Group`. Position, rotation and scale
|
|
5
|
+
belong to that group; transforming it never calls `render()`.
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { SVG, svg } from '@rasamjs/core';
|
|
9
|
+
import {
|
|
10
|
+
Component,
|
|
11
|
+
ComponentTypes,
|
|
12
|
+
component,
|
|
13
|
+
prop,
|
|
14
|
+
state,
|
|
15
|
+
action,
|
|
16
|
+
} from '@rasamjs/core/components';
|
|
17
|
+
|
|
18
|
+
@component({ type: 'status', name: 'Status', category: 'Indicators', version: 1 })
|
|
19
|
+
class Status extends Component {
|
|
20
|
+
@prop({ label: 'Caption' }) caption = 'Ready';
|
|
21
|
+
@prop() active = false;
|
|
22
|
+
@state() brightness = 1;
|
|
23
|
+
|
|
24
|
+
@action('Toggle status')
|
|
25
|
+
toggle() {
|
|
26
|
+
this.active = !this.active;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
override render() {
|
|
30
|
+
return svg`<circle r="15" fill="${this.active ? 'lime' : 'gray'}" opacity="${this.brightness}"/><text y="35">${this.caption}</text>`;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const drawing = SVG(document.querySelector<HTMLElement>('#canvas')!, { elements: [Status] });
|
|
35
|
+
const types = new ComponentTypes(drawing, [Status]);
|
|
36
|
+
const status = drawing.create(Status, { caption: 'Connected' });
|
|
37
|
+
status.translate(100, 80);
|
|
38
|
+
status.toggle();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Use standard TypeScript decorators with `useDefineForClassFields` (the default for
|
|
42
|
+
ES2022). Do not enable legacy `experimentalDecorators`. The playground's Vite transform
|
|
43
|
+
handles these decorators. Each concrete type needs its own `@component` decorator.
|
|
44
|
+
Application classes declare no static fields: the decorator supplies core's variant
|
|
45
|
+
registration, and the base class supplies owned-child behavior.
|
|
46
|
+
|
|
47
|
+
`@prop()` supports strings, finite numbers, booleans and null. Defaults come from field
|
|
48
|
+
initializers. Its options are `label`, `unit`, `min`, `max`, `step`, `options`,
|
|
49
|
+
`type: 'color'` and `notation: 'si'` for property-panel metadata. With `notation: 'si'`,
|
|
50
|
+
editors accept `4.7k`, `4k7` or `100n` and show values as `4.7 kΩ`. Numeric limits and choice lists are checked
|
|
51
|
+
on construction, loading and assignment. Unknown props and fields colliding with
|
|
52
|
+
rasam's inherited members are rejected. Use names such as `active` and `renderedFill`:
|
|
53
|
+
`on` and `fill` already name rasam methods. `propDefinitions` exposes frozen metadata.
|
|
54
|
+
The same validation applies to direct `data-rasam-props` writes, before any model
|
|
55
|
+
or rendered value changes.
|
|
56
|
+
|
|
57
|
+
`create(Type, options)` infers field names and value types from the concrete class,
|
|
58
|
+
so misspelled keys and wrong value types are TypeScript errors. Standard decorators
|
|
59
|
+
cannot distinguish `@prop` from state, helpers or getters in TypeScript's type system:
|
|
60
|
+
the inferred `ComponentFields<Type>` includes public primitive values. Runtime
|
|
61
|
+
validation still rejects every creation option that is not a decorated prop.
|
|
62
|
+
|
|
63
|
+
Every changed prop creates one labelled edit. Rendering runs synchronously as a
|
|
64
|
+
derived change in that edit, updating existing template holes. An enclosing core
|
|
65
|
+
change group or `@action('Label')` groups several writes into one undo step. Actions
|
|
66
|
+
must be synchronous. Failed actions roll back saved props and rendered children;
|
|
67
|
+
live state remains outside history. `actionDefinitions` lists an instance's `@action`
|
|
68
|
+
methods as frozen `{ name, label }` entries, inherited ones first; an overriding
|
|
69
|
+
`@action` keeps its place and takes the new label. Editors use it for action buttons. Plain helper fields do not trigger rendering.
|
|
70
|
+
|
|
71
|
+
`@state()` keeps values in memory. Assignments coalesce into one shared animation
|
|
72
|
+
frame per drawing: every changed instance renders once, together, as one temporary
|
|
73
|
+
`components` change, so a thousand animated instances cost one change event per frame.
|
|
74
|
+
They never create undo steps or dirty the editor's document autosave. Live state may
|
|
75
|
+
change structure too, for example a glow drawn only while `on` is true, or a row of
|
|
76
|
+
pins whose length is a state value.
|
|
77
|
+
|
|
78
|
+
If one instance's render throws, the others still render and the error surfaces from
|
|
79
|
+
that frame. `resetState()` restores the instance's
|
|
80
|
+
initial state; `types.resetState()` resets its drawing. Object state defaults must be
|
|
81
|
+
structured-cloneable; nested mutations do not trigger a render, so assign a new value.
|
|
82
|
+
|
|
83
|
+
Subclasses inherit decorated fields, ordinary methods and edit rules, and can add
|
|
84
|
+
fields or override `render()`. Redeclaring an inherited decorated field is rejected.
|
|
85
|
+
`created()` runs synchronously after initialization for every instance, including
|
|
86
|
+
load, clone, paste and history reconstruction. It may initialize props for a brand-new
|
|
87
|
+
instance. On restored instances (`this.adopting`), prop assignments in this hook are
|
|
88
|
+
ignored, including raw props-attribute writes, so saved values and redo remain intact.
|
|
89
|
+
Use the hook for per-instance state and subscriptions; use `migrate` to update saved
|
|
90
|
+
props. `destroyed()` runs on disposal and `changed(name)` for decorated-field changes,
|
|
91
|
+
including replayed prop changes.
|
|
92
|
+
|
|
93
|
+
Rendered children are derived from props and live state. History restores a
|
|
94
|
+
component's props, position and existence, never its children: right after undo,
|
|
95
|
+
redo or a cancelled group, each restored or recreated component redraws, as one
|
|
96
|
+
temporary change, from its restored props and its current live state. A recreated
|
|
97
|
+
instance starts from its state defaults. So live renders that add or remove nodes
|
|
98
|
+
never break undo, and an outside write to a rendered child lasts only until the next
|
|
99
|
+
render.
|
|
100
|
+
|
|
101
|
+
`@component` takes a stable lowercase hyphenated `type`, a display `name`, optional
|
|
102
|
+
`category` (default `General`), `version` (default 1), and editing rules. `rotate` is
|
|
103
|
+
`'free'`, `false`, or a positive degree step dividing 360; `flip` defaults to true;
|
|
104
|
+
`resize` defaults to `'scale'` and can be false or `'props'`. The read-only `editRules`
|
|
105
|
+
getter lets the existing transformer and flip commands enforce them without importing
|
|
106
|
+
this entry.
|
|
107
|
+
|
|
108
|
+
With `resize: 'props'`, a resize changes the component's size instead of scaling it,
|
|
109
|
+
so strokes and text keep their size. The size is saved as built-in `width` and `height`
|
|
110
|
+
props, with defaults from `@component({ resize: 'props', width, height })` (100 when
|
|
111
|
+
left out). Read them in `render()` with `this.width()` and `this.height()`; set them
|
|
112
|
+
with `size(width, height)`, `width(value)`, `height(value)` or `create(Type, { width })`.
|
|
113
|
+
Each change is one undo step and redraws at once. Sizes are at least 1 user unit. The
|
|
114
|
+
transformer resizes such a component through `size()` when it is selected alone; a
|
|
115
|
+
multi-selection that contains one cannot resize. Draw the component inside the box
|
|
116
|
+
from (0, 0) to its width and height, so resize handles follow the pointer exactly.
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
@component({ type: 'panel', name: 'Panel', resize: 'props', width: 150, height: 90 })
|
|
120
|
+
class Panel extends Component {
|
|
121
|
+
@prop() title = 'Notes';
|
|
122
|
+
override render() {
|
|
123
|
+
return svg`<g><rect width="${this.width()}" height="${this.height()}" fill="white" stroke="black"/><text x="10" y="17">${this.title}</text></g>`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Multi-selections use the strictest permissions and the smallest rotation step shared
|
|
129
|
+
by all members. The editor's geometry properties follow the same rules. Application
|
|
130
|
+
commands can use `combineEditRules` from `@rasamjs/transformer` before making edits;
|
|
131
|
+
core setters remain available for programmatic transforms.
|
|
132
|
+
|
|
133
|
+
Outside structural child edits throw before allocating or moving anything. Components
|
|
134
|
+
can themselves be moved, removed, cloned and edited as normal nodes. Compose
|
|
135
|
+
`!isComponentChild(node)` with a selection filter to prevent drilling into their
|
|
136
|
+
rendered children. The editor playground demonstrates that composition.
|
|
137
|
+
`@rasamjs/editor/components` adds editor registration, palette placement tools and a
|
|
138
|
+
properties service built from `@prop` metadata.
|
|
139
|
+
|
|
140
|
+
## Ports
|
|
141
|
+
|
|
142
|
+
Ports are named points where links attach, such as the two ends of a resistor or the
|
|
143
|
+
pins of a chip. Override `ports()` to declare them. Like `render()`, it reads `this`:
|
|
144
|
+
use props and, with `resize: 'props'`, the saved size. Points are in the component's
|
|
145
|
+
local coordinates at 0°, so moves, rotations and flips carry them along. The optional
|
|
146
|
+
`side` (`'left'`, `'right'`, `'top'` or `'bottom'`) is the direction a link leaves in.
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
@component({ type: 'chip', name: 'Chip' })
|
|
150
|
+
class Chip extends Component {
|
|
151
|
+
@prop({ min: 2, max: 16, step: 2 }) pins = 4;
|
|
152
|
+
|
|
153
|
+
override ports(): PortDefinition[] {
|
|
154
|
+
const half = this.pins / 2;
|
|
155
|
+
return Array.from({ length: this.pins }, (_, index) => ({
|
|
156
|
+
name: `p${index + 1}`,
|
|
157
|
+
x: index < half ? 0 : 60,
|
|
158
|
+
y: 10 + (index % half) * 20,
|
|
159
|
+
side: index < half ? 'left' : 'right',
|
|
160
|
+
}));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
override render() {
|
|
164
|
+
return svg`<rect width="60" height="${(this.pins / 2) * 20}"/>`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`portDefinitions` returns them validated and frozen. It calls `ports()` again only when
|
|
170
|
+
the saved props change, including after undo, redo or a raw props write. Names must be
|
|
171
|
+
unique, non-empty strings, `x` and `y` finite numbers, and `side` one of the four
|
|
172
|
+
names; anything else throws a clear error. Live state never moves a port: reading a
|
|
173
|
+
`@state` field inside `ports()` throws. Subclasses inherit ports and can extend them
|
|
174
|
+
with `super.ports()`. Components have no ports by default. `PortDefinition` comes from
|
|
175
|
+
`@rasamjs/core`, so other packages can read `node.portDefinitions` without importing
|
|
176
|
+
this entry, the way tools read `editRules`. `@rasamjs/connectors` attaches link ends
|
|
177
|
+
to them with `{ target, port }`.
|
|
178
|
+
|
|
179
|
+
## Save, load and migrate
|
|
180
|
+
|
|
181
|
+
Saved SVG contains the rendered children and three attributes on the component group:
|
|
182
|
+
|
|
183
|
+
```xml
|
|
184
|
+
<g data-rasam-component="status" data-rasam-version="1"
|
|
185
|
+
data-rasam-props='{"caption":"Connected","active":false}'>…</g>
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Register constructors through `SVG(..., { elements: [Status] })` before loading, or
|
|
189
|
+
`new ComponentTypes(drawing, [Status])` before import. Core's `parent.create()` also
|
|
190
|
+
registers the constructor for that drawing. Loads, clones, clipboard operations and
|
|
191
|
+
history retain the class. Reconstruction finishes after references and model features
|
|
192
|
+
are copied; the engine then binds matching saved wrappers or replaces the saved tree
|
|
193
|
+
when the template structure changed. Later rendering never appends a second copy.
|
|
194
|
+
Saved hosts or descendants with attributes absent from the template are rebuilt,
|
|
195
|
+
including unmanaged native attributes, so loading cannot retain stale styling.
|
|
196
|
+
|
|
197
|
+
For a new saved version, provide `migrate(props, oldVersion)` returning props for the
|
|
198
|
+
current version. It is called once on older saved input. Missing props use current
|
|
199
|
+
field defaults. Future versions, missing migrations for old versions, malformed JSON
|
|
200
|
+
and invalid props throw. Migration code should be synchronous and free of external
|
|
201
|
+
side effects. Unknown types remain plain groups with their saved appearance; a
|
|
202
|
+
`ComponentTypes` service reports each unknown type once through `console.warn`.
|
|
203
|
+
|
|
204
|
+
State fields are absent from saved props. Explicit SVG export includes their current
|
|
205
|
+
appearance, so passive viewers see the current drawing. Loading recomputes the look
|
|
206
|
+
from saved props and fresh state defaults.
|
|
207
|
+
|
|
208
|
+
## Type registry and icons
|
|
209
|
+
|
|
210
|
+
`ComponentTypes.register(Type)` registers another type locally. `list(category?)` returns
|
|
211
|
+
sorted frozen definitions; `get(type)` returns the constructor. `icon(type, parent)`
|
|
212
|
+
renders a default instance through the same class into a supplied drawing or group.
|
|
213
|
+
Use a separate small drawing for palette icons. `destroy()` stops the service's
|
|
214
|
+
observer; drawing disposal also cleans it up.
|
|
215
|
+
|
|
216
|
+
The engine shares one change observer and one derivation callback per drawing.
|
|
217
|
+
Dispatch targets changed components, and type discovery visits only newly added
|
|
218
|
+
subtrees or a node whose type attribute changed. Movement does not scan the drawing.
|
|
219
|
+
|
|
220
|
+
The Phase 1 demos use primitive template bindings. Core's separately developed
|
|
221
|
+
template-power work controls nested templates and arrays; component definitions
|
|
222
|
+
do not require those features. Filters, embedded HTML and component nesting are not
|
|
223
|
+
part of this phase.
|
|
224
|
+
|
|
225
|
+
Validate the entry with `bun run check:size:components` (42 KiB gzip cap).
|
|
226
|
+
`bun run api:check`, `bun run check:consumer`
|
|
227
|
+
and `bun run check:docs` also cover the new public entry.
|
|
228
|
+
Use `bun run bench:components` for the 2,000-object/200-move benchmark, or
|
|
229
|
+
`bun run bench:components --revision=07a1160` to reproduce the reviewed version.
|
package/README.md
CHANGED
|
@@ -9,6 +9,9 @@ Start with the generated [public entry points](API.md) and the
|
|
|
9
9
|
The [release procedure](RELEASING.md) describes reproducible acceptance checks;
|
|
10
10
|
publishing remains separately authorized.
|
|
11
11
|
|
|
12
|
+
For class-defined SVG nodes with saved props, live state and undoable actions, see
|
|
13
|
+
the opt-in [`@rasamjs/core/components` guide](COMPONENTS.md).
|
|
14
|
+
|
|
12
15
|
## Start
|
|
13
16
|
|
|
14
17
|
Install dependencies at the repository root, then run the remaining commands in
|
|
@@ -437,20 +440,50 @@ instance.destroy();
|
|
|
437
440
|
```
|
|
438
441
|
|
|
439
442
|
`Renderer.render(parent, template)` is also available. Each instance owns a host
|
|
440
|
-
group and its mounted nodes. A different template literal identity
|
|
441
|
-
|
|
443
|
+
group and its mounted nodes. A different template literal identity replaces the prior
|
|
444
|
+
instance. Compilation is cached by literal identity.
|
|
445
|
+
|
|
446
|
+
A hole between elements, or at the top level, renders nested templates. It takes a
|
|
447
|
+
template, an array or other iterable of templates (nested arrays flatten), or `null`,
|
|
448
|
+
`undefined`, a boolean or `''` for nothing, so it can draw lists and conditions:
|
|
449
|
+
|
|
450
|
+
```ts
|
|
451
|
+
const chip = (pins: number[], on: boolean) => svg`
|
|
452
|
+
<g>
|
|
453
|
+
<rect width="40" height="60"/>
|
|
454
|
+
${pins.map((y) => svg`<line x1="0" y1="${y}" x2="-10" y2="${y}"/>`)}
|
|
455
|
+
${on ? svg`<circle cx="20" cy="30" r="6" fill="lime"/>` : null}
|
|
456
|
+
</g>`;
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
On update, an item whose template literal matches the one at the same index updates
|
|
460
|
+
in place; other items are rebuilt. An update validates every binding and builds new
|
|
461
|
+
items off the drawing first, so a failed update changes nothing. Nested items follow
|
|
462
|
+
their container's child rules, such as only `stop` inside a gradient. Removed items and
|
|
463
|
+
replaced templates are disposed so that undo restores them without clearing history.
|
|
442
464
|
|
|
443
465
|
Static markup is trusted application code. Dynamic primitives become text or
|
|
444
466
|
attribute values, never markup. Whole quoted attribute holes remove the attribute
|
|
445
|
-
for null/undefined; mixed attributes and text use empty segments. Tag names
|
|
446
|
-
attribute names
|
|
447
|
-
|
|
467
|
+
for null/undefined; mixed attributes and text use empty segments. Tag names and
|
|
468
|
+
attribute names are static. Text holes belong inside `text` elements and take only
|
|
469
|
+
primitives. Dynamic `on*` bindings, dynamic CSS strings, and external URL references
|
|
448
470
|
are rejected. Dynamic URLs are restricted to local `#id` and `url(#id)` references.
|
|
449
471
|
|
|
450
472
|
Templates initialize shapes from their bindings and keep declared resources inside
|
|
451
473
|
their template-owned containers. Resource IDs may be declared in markup and remain
|
|
452
474
|
immutable after initialization.
|
|
453
475
|
|
|
476
|
+
A custom class can share a tag with a built-in class. A `Group` subclass with
|
|
477
|
+
`static variant = { attribute: 'data-type', value: 'led' }` registers for
|
|
478
|
+
`<g data-type="led">` only. Creation writes that attribute, it can't change, and other
|
|
479
|
+
classes can't use its value. Once the class is registered in a drawing, adoption,
|
|
480
|
+
import, clone and undo/redo rebuild it instead of a plain group; `registry.resolve(element)`
|
|
481
|
+
returns the class an element would get. `static ownsChildren = true` reserves a
|
|
482
|
+
container's children for its class: outside builders, `add()`, moves, reordering,
|
|
483
|
+
removal and templates throw before changing anything. The class edits them inside
|
|
484
|
+
`this.withOwnChildren(callback)`, and adoption, clone, undo/redo and destroying the
|
|
485
|
+
owner keep working.
|
|
486
|
+
|
|
454
487
|
Registration is local to each drawing. `SVG()` registers the full built-in catalog;
|
|
455
488
|
`create(Constructor, options)` registers a custom constructor as it creates the node.
|
|
456
489
|
With the lower-level `Svg` constructor, `Elements.register(registry)` can register
|
|
@@ -744,7 +777,7 @@ URLs still require `externalUrls: 'http'`. Register the media catalog before imp
|
|
|
744
777
|
|
|
745
778
|
## Release status and license
|
|
746
779
|
|
|
747
|
-
`@rasamjs/core@0.
|
|
780
|
+
`@rasamjs/core@0.2.0` is published,
|
|
748
781
|
licensed under [MIT](./LICENSE). The name is not reserved by these checks. Recheck the intended registry at the
|
|
749
782
|
time of a separately authorized publication.
|
|
750
783
|
The package remains `private: true` until publication is separately authorized.
|
package/RELEASING.md
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
# Release preparation
|
|
2
2
|
|
|
3
|
-
The source manifest is `@rasamjs/core@0.
|
|
4
|
-
`private: true` between releases. It has no runtime dependencies.
|
|
3
|
+
The source manifest is `@rasamjs/core@0.3.0`, ESM-only, MIT-licensed and kept
|
|
4
|
+
`private: true` between releases. It has no runtime dependencies. The 0.3.0 release
|
|
5
|
+
adds class components, named ports, nested templates and the reference-index APIs
|
|
6
|
+
used by connectors 0.2.0. The owner authorized publication on 2026-11-07. Core 0.1.2 was
|
|
5
7
|
published on 2026-11-02 with transformer 0.4.0, selection 0.3.0, tools 0.2.0 and the first
|
|
6
8
|
viewport 0.1.0 in the [editor release](https://github.com/hdevlop/rasam/releases/tag/viewport-v0.1.0);
|
|
7
9
|
it gives replay observers the restored sibling order and keeps text reads out of change
|
package/dist/advanced.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { Namespace } from './dom/namespace.js';
|
|
|
7
7
|
export { DrawingContext } from './services/context.js';
|
|
8
8
|
export { Scheduler } from './services/scheduler.js';
|
|
9
9
|
export { Registry } from './services/registry.js';
|
|
10
|
-
export type { ElementClass } from './services/types.js';
|
|
10
|
+
export type { ElementClass, ElementVariant } from './services/types.js';
|
|
11
11
|
export { BoundsService } from './services/bounds.js';
|
|
12
12
|
export { DefsManager } from './services/defs-manager.js';
|
|
13
13
|
export { Transformable } from './mixins/transformable.js';
|
package/dist/advanced.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../src/advanced.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"advanced.d.ts","sourceRoot":"","sources":["../src/advanced.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAE3B,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,YAAY,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AnyNode } from '../core/types.js';
|
|
2
|
-
import type { ElementClass } from '../services/types.js';
|
|
2
|
+
import type { ElementClass, CreationOptions } from '../services/types.js';
|
|
3
3
|
import type { ParentNode } from '../mixins/types.js';
|
|
4
4
|
/** A detached managed forest. Insertion moves its nodes and leaves this reusable value empty. */
|
|
5
5
|
export declare class SvgFragment {
|
|
@@ -8,7 +8,7 @@ export declare class SvgFragment {
|
|
|
8
8
|
get isDestroyed(): boolean;
|
|
9
9
|
get nodes(): readonly AnyNode[];
|
|
10
10
|
add<Node extends AnyNode>(node: Node, index?: number): Node;
|
|
11
|
-
create<Options, Child extends AnyNode>(Constructor: ElementClass<Options, Child>, options: Options): Child;
|
|
11
|
+
create<Options, Child extends AnyNode>(Constructor: ElementClass<Options, Child>, options: NoInfer<CreationOptions<Options, Child>>): Child;
|
|
12
12
|
insertInto(parent: ParentNode, index?: number): readonly AnyNode[];
|
|
13
13
|
detachChildren(): readonly AnyNode[];
|
|
14
14
|
clear(): this;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fragment.d.ts","sourceRoot":"","sources":["../../src/catalog/fragment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"fragment.d.ts","sourceRoot":"","sources":["../../src/catalog/fragment.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,iGAAiG;AACjG,qBAAa,WAAW;;IAEtB,YAAY,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,OAAO,EAAO,EAUzD;IACD,IAAI,WAAW,IAAI,OAAO,CAEzB;IACD,IAAI,KAAK,IAAI,SAAS,OAAO,EAAE,CAG9B;IAED,GAAG,CAAC,IAAI,SAAS,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAE1D;IACD,MAAM,CAAC,OAAO,EAAE,KAAK,SAAS,OAAO,EACnC,WAAW,EAAE,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,EACzC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,GAChD,KAAK,CAEP;IACD,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,SAAyB,GAAG,SAAS,OAAO,EAAE,CAsBjF;IACD,cAAc,IAAI,SAAS,OAAO,EAAE,CAMnC;IACD,KAAK,IAAI,IAAI,CAKZ;IACD,OAAO,IAAI,IAAI,CAEd;IAED,OAAO,CAAC,SAAS;CA2BlB;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,SAAS,OAAO,EAAO,GAAG,WAAW,CAEpF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fragment.js","sourceRoot":"","sources":["../../src/catalog/fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAI7C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,iGAAiG;AACjG,MAAM,OAAO,WAAW;IACb,KAAK,CAAQ;IACtB,YAAY,KAAc,EAAE,KAAK,GAAuB,EAAE;QACxD,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IACD,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;IAClE,CAAC;IACD,IAAI,KAAK;QACP,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED,GAAG,CAAuB,IAAU,EAAE,KAAc;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,CACJ,WAAyC,EACzC,
|
|
1
|
+
{"version":3,"file":"fragment.js","sourceRoot":"","sources":["../../src/catalog/fragment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAI7C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,iGAAiG;AACjG,MAAM,OAAO,WAAW;IACb,KAAK,CAAQ;IACtB,YAAY,KAAc,EAAE,KAAK,GAAuB,EAAE;QACxD,KAAK,CAAC,UAAU,EAAE,CAAC;QACnB,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC;YACH,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACrB,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IACD,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;IAClE,CAAC;IACD,IAAI,KAAK;QACP,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC7B,CAAC;IAED,GAAG,CAAuB,IAAU,EAAE,KAAc;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,CACJ,WAAyC,EACzC,OAAiD;QAEjD,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IACD,UAAU,CAAC,MAAkB,EAAE,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM;QAC3D,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE;YAC7C,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC;YACxB,MAAM,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO;gBACvC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;YAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACzB,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAc,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;oBAC1C,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,KAAK,IAAI,QAAQ,GAAG,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC,MAAM,EAAE,QAAQ,EAAE;oBAC3D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;gBAC/C,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IACD,cAAc;QACZ,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE;YACrD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;YACzB,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YACxC,OAAO,KAAK,CAAC;QACf,CAAC,CAAC,CAAC;IACL,CAAC;IACD,KAAK;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE;YACrD,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxC,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;IACL,CAAC;IACD,OAAO;QACL,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IACvB,CAAC;IAEO,SAAS,CAAC,KAAyB;QACzC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAW,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC;YAChC,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC5C,IAAI,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC;oBAC1B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;gBACpE,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACpC,IAAI;YACJ,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC;SAC3C,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC;YACH,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,QAAQ,CAAC,IAAI,CACjD,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAC1C,EAAE,CAAC;gBACF,IAAI,MAAM;oBAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;;oBAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;YACrB,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc,EAAE,KAAK,GAAuB,EAAE;IACrE,OAAO,IAAI,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AnyNode } from '../core/types.js';
|
|
2
|
+
import type { ModelChange } from './types.js';
|
|
3
|
+
/** Marks a class whose children are drawn from its own state, such as a component. */
|
|
4
|
+
export declare const derivesChildren: unique symbol;
|
|
5
|
+
export declare const ownsDerived: (Constructor: unknown) => boolean;
|
|
6
|
+
/** Records the owner's current descendants as derived. The owner redraws them after replay. */
|
|
7
|
+
export declare function markDerived(owner: AnyNode): void;
|
|
8
|
+
/** Replay skips derived nodes and their owners' child lists. */
|
|
9
|
+
export declare const isDerivedChange: (change: ModelChange) => boolean;
|
|
10
|
+
//# sourceMappingURL=derived.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.d.ts","sourceRoot":"","sources":["../../src/changes/derived.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,sFAAsF;AACtF,eAAO,MAAM,eAAe,eAA4B,CAAC;AAGzD,eAAO,MAAM,WAAW,gBAAiB,OAAO,KAAG,OACgC,CAAC;AAEpF,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAEhD;AAED,gEAAgE;AAChE,eAAO,MAAM,eAAe,WAAY,WAAW,KAAG,OAEyB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Marks a class whose children are drawn from its own state, such as a component. */
|
|
2
|
+
export const derivesChildren = Symbol('derivesChildren');
|
|
3
|
+
const derived = new WeakSet();
|
|
4
|
+
export const ownsDerived = (Constructor) => !!Constructor?.[derivesChildren];
|
|
5
|
+
/** Records the owner's current descendants as derived. The owner redraws them after replay. */
|
|
6
|
+
export function markDerived(owner) {
|
|
7
|
+
for (const node of owner.descendants())
|
|
8
|
+
if (node !== owner)
|
|
9
|
+
derived.add(node);
|
|
10
|
+
}
|
|
11
|
+
/** Replay skips derived nodes and their owners' child lists. */
|
|
12
|
+
export const isDerivedChange = (change) => derived.has(change.target.node) ||
|
|
13
|
+
(change.domain === 'children' && ownsDerived(change.target.node.constructor));
|
|
14
|
+
//# sourceMappingURL=derived.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derived.js","sourceRoot":"","sources":["../../src/changes/derived.ts"],"names":[],"mappings":"AAGA,sFAAsF;AACtF,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;AACzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAW,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,WAAoB,EAAW,EAAE,CAC3D,CAAC,CAAE,WAA2D,EAAE,CAAC,eAAe,CAAC,CAAC;AAEpF,+FAA+F;AAC/F,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,WAAW,EAAE;QAAE,IAAI,IAAI,KAAK,KAAK;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAChF,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAmB,EAAW,EAAE,CAC9D,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;IAC/B,CAAC,MAAM,CAAC,MAAM,KAAK,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../src/changes/restore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../src/changes/restore.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAehD,OAAO,KAAK,EAEV,WAAW,EAIZ,MAAM,YAAY,CAAC;AAqDpB,qFAAqF;AACrF,wBAAgB,cAAc,CAC5B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,SAAS,WAAW,EAAE,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,GACzB,IAAI,CAKN"}
|
package/dist/changes/restore.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { destroySubtrees } from '../core/destruction.js';
|
|
2
|
-
import { validateChild } from '../mixins/parent-internals.js';
|
|
2
|
+
import { validateChild, withInternalStructure } from '../mixins/parent-internals.js';
|
|
3
3
|
import { readTransformState } from '../mixins/transform-state.js';
|
|
4
4
|
import { referenceValue } from '../services/reference-value.js';
|
|
5
|
+
import { initializeNode } from '../services/initialization.js';
|
|
6
|
+
import { isDerivedChange, ownsDerived } from './derived.js';
|
|
5
7
|
import { captureState, sameState, stateAdapter, combineChanges } from './state.js';
|
|
6
8
|
import { ChangeConflictError, ChangeRollbackError, restoreModelState, validateModelState, } from './types.js';
|
|
7
9
|
function currentValue(snapshot, change) {
|
|
@@ -15,6 +17,13 @@ function currentValue(snapshot, change) {
|
|
|
15
17
|
return snapshot.contributesToBounds;
|
|
16
18
|
return snapshot[change.domain];
|
|
17
19
|
}
|
|
20
|
+
/** An owner's derived child list is redrawn, not restored, so conflicts ignore it. */
|
|
21
|
+
function comparable(value, change) {
|
|
22
|
+
const snapshot = value;
|
|
23
|
+
return change.domain === 'existence' && snapshot && ownsDerived(snapshot.constructor)
|
|
24
|
+
? { ...snapshot, children: undefined }
|
|
25
|
+
: value;
|
|
26
|
+
}
|
|
18
27
|
function contentFeatures(content) {
|
|
19
28
|
return {
|
|
20
29
|
parts: content.parts.map((part) => (typeof part === 'string' ? part : part.node)),
|
|
@@ -56,7 +65,8 @@ export function restoreChanges(owner, changes, direction) {
|
|
|
56
65
|
}
|
|
57
66
|
function applyChanges(owner, changes, direction) {
|
|
58
67
|
const service = owner.context.changes;
|
|
59
|
-
|
|
68
|
+
// An owner redraws its derived children after replay, from the state replay restored.
|
|
69
|
+
changes = combineChanges(changes).filter((change) => !isDerivedChange(change));
|
|
60
70
|
service.resetOrders();
|
|
61
71
|
service.configure(stateAdapter);
|
|
62
72
|
try {
|
|
@@ -73,7 +83,8 @@ function applyChanges(owner, changes, direction) {
|
|
|
73
83
|
domains.set(change.target, new Set());
|
|
74
84
|
}
|
|
75
85
|
const expected = direction === 'undo' ? change.after : change.before;
|
|
76
|
-
|
|
86
|
+
const current = currentValue(before.get(change.target), change);
|
|
87
|
+
if (!sameState(comparable(current, change), comparable(expected, change)))
|
|
77
88
|
throw new ChangeConflictError(`Conflicting ${change.domain} state on node ${change.target.id}`);
|
|
78
89
|
desired.set(change.target, applyStateChange(desired.get(change.target), change, direction === 'undo' ? change.before : change.after));
|
|
79
90
|
domains
|
|
@@ -136,7 +147,7 @@ function validateGraph(owner, states, counts) {
|
|
|
136
147
|
for (const [target, state] of states) {
|
|
137
148
|
if (!state)
|
|
138
149
|
continue;
|
|
139
|
-
if (context.registry.
|
|
150
|
+
if (context.registry.registered(state.constructor) !== state.constructor)
|
|
140
151
|
throw new ChangeConflictError(`Constructor is not registered: ${state.constructor.tag}`);
|
|
141
152
|
const id = state.properties.id?.value;
|
|
142
153
|
if (id !== undefined &&
|
|
@@ -203,7 +214,11 @@ function validateGraph(owner, states, counts) {
|
|
|
203
214
|
if (counts.get(node) > 0)
|
|
204
215
|
throw new ChangeConflictError('A removed node would retain live typed references');
|
|
205
216
|
}
|
|
217
|
+
/** Replay restores exact prior trees, including children that their class owns. */
|
|
206
218
|
function applyPrepared(owner, states, domains) {
|
|
219
|
+
withInternalStructure(() => applyStates(owner, states, domains));
|
|
220
|
+
}
|
|
221
|
+
function applyStates(owner, states, domains) {
|
|
207
222
|
const context = owner.context;
|
|
208
223
|
const recreated = new Set();
|
|
209
224
|
// Allocate all nodes before restoring any reference or content edge.
|
|
@@ -285,6 +300,7 @@ function applyPrepared(owner, states, domains) {
|
|
|
285
300
|
// Parent order is authoritative across compound edits and separate edit callbacks.
|
|
286
301
|
for (const [target, state] of states)
|
|
287
302
|
if (state?.children &&
|
|
303
|
+
!ownsDerived(state.constructor) &&
|
|
288
304
|
(recreated.has(target) ||
|
|
289
305
|
domains.get(target).has('children') ||
|
|
290
306
|
domains.get(target).has('existence'))) {
|
|
@@ -312,6 +328,8 @@ function applyPrepared(owner, states, domains) {
|
|
|
312
328
|
const roots = [...retired].filter((node) => !node.parent || !retired.has(node.parent));
|
|
313
329
|
if (roots.length)
|
|
314
330
|
owner[destroySubtrees](roots);
|
|
331
|
+
for (const target of recreated)
|
|
332
|
+
initializeNode(target.node);
|
|
315
333
|
context.bounds.invalidate();
|
|
316
334
|
}
|
|
317
335
|
//# sourceMappingURL=restore.js.map
|