@rasamjs/core 0.1.2 → 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 +29 -9
- package/CHANGELOG.md +98 -1
- package/COMPONENTS.md +229 -0
- package/README.md +178 -25
- package/RELEASING.md +31 -21
- 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 +10 -2
- package/dist/changes/service.d.ts.map +1 -1
- package/dist/changes/service.js +45 -6
- package/dist/changes/service.js.map +1 -1
- package/dist/changes/types.d.ts +9 -0
- package/dist/changes/types.d.ts.map +1 -1
- package/dist/changes/types.js.map +1 -1
- package/dist/changes.d.ts +5 -3
- package/dist/changes.d.ts.map +1 -1
- package/dist/changes.js +103 -2
- package/dist/changes.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/dom/images.d.ts.map +1 -1
- package/dist/dom/images.js +3 -1
- package/dist/dom/images.js.map +1 -1
- package/dist/elements/image.d.ts.map +1 -1
- package/dist/elements/image.js +4 -1
- package/dist/elements/image.js.map +1 -1
- package/dist/interchange/clone.d.ts.map +1 -1
- package/dist/interchange/clone.js +4 -3
- package/dist/interchange/clone.js.map +1 -1
- package/dist/interchange/dom.d.ts +3 -1
- package/dist/interchange/dom.d.ts.map +1 -1
- package/dist/interchange/dom.js +29 -5
- package/dist/interchange/dom.js.map +1 -1
- package/dist/interchange/markup.d.ts.map +1 -1
- package/dist/interchange/markup.js +71 -3
- package/dist/interchange/markup.js.map +1 -1
- package/dist/interchange/policy.d.ts.map +1 -1
- package/dist/interchange/policy.js +4 -0
- package/dist/interchange/policy.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/interchange/types.d.ts +10 -1
- package/dist/interchange/types.d.ts.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/transformable.d.ts.map +1 -1
- package/dist/mixins/transformable.js +25 -27
- package/dist/mixins/transformable.js.map +1 -1
- package/dist/mixins/types.d.ts +2 -2
- package/dist/mixins/types.d.ts.map +1 -1
- package/dist/raster/frame.d.ts +12 -0
- package/dist/raster/frame.d.ts.map +1 -0
- package/dist/raster/frame.js +43 -0
- package/dist/raster/frame.js.map +1 -0
- package/dist/raster/images.d.ts +2 -0
- package/dist/raster/images.d.ts.map +1 -0
- package/dist/raster/images.js +60 -0
- package/dist/raster/images.js.map +1 -0
- package/dist/raster/render.d.ts +3 -0
- package/dist/raster/render.d.ts.map +1 -0
- package/dist/raster/render.js +40 -0
- package/dist/raster/render.js.map +1 -0
- package/dist/raster/types.d.ts +10 -0
- package/dist/raster/types.d.ts.map +1 -0
- package/dist/raster/types.js +2 -0
- package/dist/raster/types.js.map +1 -0
- package/dist/raster.d.ts +6 -0
- package/dist/raster.d.ts.map +1 -0
- package/dist/raster.js +10 -0
- package/dist/raster.js.map +1 -0
- package/dist/resources/references.d.ts +2 -0
- package/dist/resources/references.d.ts.map +1 -1
- package/dist/resources/references.js +3 -1
- 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/services/viewport.d.ts +2 -0
- package/dist/services/viewport.d.ts.map +1 -1
- package/dist/services/viewport.js +4 -3
- package/dist/services/viewport.js.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/content.d.ts +0 -2
- package/dist/text/content.d.ts.map +1 -1
- package/dist/text/content.js +4 -10
- package/dist/text/content.js.map +1 -1
- package/dist/text/internals.d.ts +1 -0
- package/dist/text/internals.d.ts.map +1 -1
- package/dist/text/policies.d.ts +7 -0
- package/dist/text/policies.d.ts.map +1 -0
- package/dist/text/policies.js +13 -0
- package/dist/text/policies.js.map +1 -0
- package/dist/types/common.d.ts +27 -0
- package/dist/types/common.d.ts.map +1 -1
- package/package.json +156 -143
- package/reports/adoption.json +20 -20
- package/reports/animation-benchmark.json +616 -616
- package/reports/benchmark.json +65 -65
- 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 +353 -23
- package/reports/public-api-review.md +23 -0
- package/reports/size-components.json +102 -0
- package/reports/size-parity.json +82 -34
- package/reports/size.json +6 -4
- package/reports/svgjs-comparison.json +3466 -3466
- package/reports/svgjs-comparison.md +19 -19
- package/reports/svgjs-parity-current.json +177 -60
- 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 +60 -11
- package/src/changes/types.ts +9 -0
- package/src/changes.ts +93 -4
- 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/dom/images.ts +2 -1
- package/src/elements/image.ts +4 -1
- package/src/interchange/clone.ts +4 -3
- package/src/interchange/dom.ts +34 -5
- package/src/interchange/markup.ts +77 -3
- package/src/interchange/policy.ts +6 -0
- package/src/interchange/reconstruct.ts +16 -12
- package/src/interchange/references.ts +12 -4
- package/src/interchange/types.ts +10 -1
- package/src/mixins/parent-internals.ts +37 -0
- package/src/mixins/parent.ts +13 -4
- package/src/mixins/transformable.ts +23 -25
- package/src/mixins/types.ts +2 -2
- package/src/raster/frame.ts +53 -0
- package/src/raster/images.ts +73 -0
- package/src/raster/render.ts +45 -0
- package/src/raster/types.ts +9 -0
- package/src/raster.ts +13 -0
- package/src/resources/references.ts +5 -1
- 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/services/viewport.ts +5 -4
- 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/content.ts +4 -14
- package/src/text/internals.ts +1 -0
- package/src/text/policies.ts +18 -0
- package/src/types/common.ts +29 -0
package/API.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Public entry points
|
|
2
2
|
|
|
3
3
|
Generated from emitted declarations and document-free runtime imports.
|
|
4
|
-
Run `
|
|
4
|
+
Run `bun run api:check` to detect changes; review differences before `api:update`.
|
|
5
5
|
|
|
6
6
|
Only documented operations are supported application APIs. Deep imports, mutable
|
|
7
7
|
service bookkeeping, TypeScript-private methods and undocumented symbol hooks remain internal,
|
|
@@ -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
|
|
|
@@ -50,13 +50,23 @@ Type-only exports (7):
|
|
|
50
50
|
|
|
51
51
|
## @rasamjs/core/changes
|
|
52
52
|
|
|
53
|
-
Runtime exports (
|
|
53
|
+
Runtime exports (15):
|
|
54
54
|
|
|
55
|
-
`ChangeConflictError`, `ChangeObserverError`, `ChangeRollbackError`, `beginChangeGroup`, `captureModelState`, `changeKey`, `claimRecorder`, `combineChanges`, `observeChanges`, `restoreChanges`, `restoreModelState`, `sameState`, `validateModelState`, `withChanges`.
|
|
55
|
+
`ChangeConflictError`, `ChangeObserverError`, `ChangeRollbackError`, `beginChangeGroup`, `captureModelState`, `changeKey`, `claimRecorder`, `combineChanges`, `deriveChanges`, `observeChanges`, `restoreChanges`, `restoreModelState`, `sameState`, `validateModelState`, `withChanges`.
|
|
56
56
|
|
|
57
|
-
Type-only exports (
|
|
57
|
+
Type-only exports (14):
|
|
58
58
|
|
|
59
|
-
`ChangeBatch`, `ChangeEvent`, `ChangeGroup`, `ChangeMetadata`, `ContentState`, `ModelChange`, `ModelFeatures`, `ModelSnapshot`, `NativeNodeState`, `NodeHandle`, `Placement`, `PropertyState`, `TextPolicies`.
|
|
59
|
+
`ChangeBatch`, `ChangeDerivation`, `ChangeEvent`, `ChangeGroup`, `ChangeMetadata`, `ContentState`, `ModelChange`, `ModelFeatures`, `ModelSnapshot`, `NativeNodeState`, `NodeHandle`, `Placement`, `PropertyState`, `TextPolicies`.
|
|
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`.
|
|
60
70
|
|
|
61
71
|
## @rasamjs/core/data
|
|
62
72
|
|
|
@@ -128,6 +138,16 @@ Type-only exports (1):
|
|
|
128
138
|
|
|
129
139
|
`NodePredicate`.
|
|
130
140
|
|
|
141
|
+
## @rasamjs/core/raster
|
|
142
|
+
|
|
143
|
+
Runtime exports (1):
|
|
144
|
+
|
|
145
|
+
`exportImage`.
|
|
146
|
+
|
|
147
|
+
Type-only exports (1):
|
|
148
|
+
|
|
149
|
+
`RasterOptions`.
|
|
150
|
+
|
|
131
151
|
## @rasamjs/core/resources
|
|
132
152
|
|
|
133
153
|
Runtime exports (4):
|
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,103 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## Unreleased
|
|
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
|
+
|
|
64
|
+
- Add `document: 'presentation'` imports to retain scoped root styles and compositing
|
|
65
|
+
while omitting the viewport envelope. Validate document envelopes before unwrapping.
|
|
66
|
+
Add `document: 'replace'` for empty drawings so full-document restoration does not
|
|
67
|
+
apply configured root presentation twice; fragments retain their defaults.
|
|
68
|
+
- Isolate the text-policy cloning bridge so interchange bundles do not retain the
|
|
69
|
+
rich-text implementation; keep the existing interchange size budget.
|
|
70
|
+
|
|
71
|
+
- Preserve omitted ancestor transforms and nested SVG viewports in content-framed
|
|
72
|
+
subtree exports, including raster exports of nested shapes.
|
|
73
|
+
|
|
74
|
+
- Keep matrix and transform-snapshot reads outside model edit transactions.
|
|
75
|
+
Release destroyed native image sources and avoid restarting a missing-source
|
|
76
|
+
request when disposing a completed image metadata probe.
|
|
77
|
+
|
|
78
|
+
- Add opt-in `deriveChanges()` to include synchronous dependent writes in the same
|
|
79
|
+
operation/group before recording, skipping getters and restoration. Recognize reserved
|
|
80
|
+
connector endpoint references during SVG export/import and clone ID remapping.
|
|
81
|
+
|
|
82
|
+
- Restore exported embedded image data URLs on `<image>` elements during SVG import.
|
|
83
|
+
Data URLs on links and Use instances, unsupported MIME types and active URL schemes
|
|
84
|
+
remain rejected.
|
|
85
|
+
|
|
86
|
+
- Add optional `./raster` PNG/JPEG/WebP export with scale, background, content/viewBox
|
|
87
|
+
framing, same-origin/data image embedding, snapshot isolation and clear decode or
|
|
88
|
+
tainted-canvas failures. Document nonembedded web fonts/styles and pixel limits.
|
|
89
|
+
- Add an isolated 12 KiB raster budget; existing entry budgets are unchanged.
|
|
90
|
+
|
|
91
|
+
- Add labelled change groups and `ChangeGroup.cancel()`, including rollback without
|
|
92
|
+
history, restored completion signals, conflict detection and observer-error reporting.
|
|
93
|
+
- Add content-framed SVG export with padding and whole-document import with `SyntaxError`
|
|
94
|
+
parse diagnostics. Document import accepts an XML declaration and a DOCTYPE without an
|
|
95
|
+
internal subset. Default export and nested SVG import behavior remain compatible.
|
|
96
|
+
|
|
97
|
+
- Add editor Phase 0 test-only group rollback spikes for text creation, attribute edits,
|
|
98
|
+
observer notifications and preservation of unrelated edits.
|
|
99
|
+
|
|
100
|
+
## [0.1.2] - 2026-11-02
|
|
4
101
|
|
|
5
102
|
### Fixed
|
|
6
103
|
|
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.
|