@glissade/scene 0.17.0 → 0.17.1

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.
@@ -0,0 +1,194 @@
1
+ import { MeshInterpolation, MeshPaint as MeshPaint$1, MeshPoint, Paint, Vec2 } from "@glissade/core";
2
+
3
+ //#region src/matrix.d.ts
4
+
5
+ type Mat2x3 = readonly [number, number, number, number, number, number];
6
+ declare const IDENTITY: Mat2x3;
7
+ declare function multiply(m1: Mat2x3, m2: Mat2x3): Mat2x3;
8
+ /** Compose translate × rotate × scale (rotation in degrees). */
9
+ declare function fromTRS(position: Vec2, rotationDeg: number, scale: Vec2): Mat2x3;
10
+ /** Inverse affine: [A | t]⁻¹ = [A⁻¹ | −A⁻¹t]; null when degenerate (det 0). */
11
+ declare function invert(m: Mat2x3): Mat2x3 | null;
12
+ declare function applyToPoint(m: Mat2x3, p: Vec2): Vec2;
13
+ declare function matEquals(a: Mat2x3, b: Mat2x3): boolean;
14
+ //#endregion
15
+ //#region src/displayList.d.ts
16
+ type ResourceId = number;
17
+ /**
18
+ * Path data as plain segments (JSON-serializable; backends build Path2D/SkPath):
19
+ * M/L: point; C: cubic; Q: quadratic; Z: close
20
+ * E: ellipse arc — cx, cy, rx, ry, rotationRad, startAngleRad, endAngleRad
21
+ */
22
+ type PathSeg = ['M', number, number] | ['L', number, number] | ['C', number, number, number, number, number, number] | ['Q', number, number, number, number] | ['E', number, number, number, number, number, number, number] | ['Z'];
23
+ type Resource = {
24
+ kind: 'path';
25
+ segs: PathSeg[];
26
+ } | {
27
+ kind: 'image';
28
+ assetId: string;
29
+ }
30
+ /** One source-grid video frame: backends resolve via their VideoFrameSource registry (§3.8). */ | {
31
+ kind: 'videoFrame';
32
+ assetId: string;
33
+ mediaT: number;
34
+ };
35
+ type BlendMode = 'source-over' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten';
36
+ interface StrokeStyle {
37
+ width: number;
38
+ cap?: 'butt' | 'round' | 'square';
39
+ join?: 'miter' | 'round' | 'bevel';
40
+ miterLimit?: number;
41
+ dash?: number[];
42
+ dashOffset?: number;
43
+ }
44
+ interface FontSpec {
45
+ family: string;
46
+ size: number;
47
+ weight?: number;
48
+ style?: 'normal' | 'italic';
49
+ }
50
+ /**
51
+ * Group filters (§3.4): a CLOSED union — validated data, never a CSS
52
+ * passthrough string — limited to effects both rasterizers implement
53
+ * faithfully. Cross-backend parity is perceptual (SSIM), not byte-exact:
54
+ * filters are where rasterizers diverge most. Per-backend output stays
55
+ * deterministic on the pinned toolchain (golden-tested on Skia).
56
+ */
57
+ type FilterSpec = {
58
+ kind: 'blur'; /** Gaussian stdDeviation, px; ≥ 0. */
59
+ radius: number;
60
+ } | {
61
+ kind: 'drop-shadow';
62
+ dx: number;
63
+ dy: number; /** ≥ 0 */
64
+ blur: number;
65
+ color: string;
66
+ } | {
67
+ kind: 'brightness'; /** 1 = identity; ≥ 0. */
68
+ amount: number;
69
+ } | {
70
+ kind: 'contrast'; /** 1 = identity; ≥ 0. */
71
+ amount: number;
72
+ } | {
73
+ kind: 'saturate'; /** 1 = identity; ≥ 0. */
74
+ amount: number;
75
+ };
76
+ declare class FilterValidationError extends Error {
77
+ constructor(message: string);
78
+ }
79
+ /** Document-layer validation: reject unknown kinds and out-of-range params loudly. */
80
+ declare function validateFilters(filters: readonly FilterSpec[]): void;
81
+ /**
82
+ * Compile the validated union to the canvas 2D `ctx.filter` syntax — both
83
+ * backends speak it (browser canvas and @napi-rs/canvas/Skia). This is the
84
+ * ONLY place the CSS-like syntax appears; documents never carry it.
85
+ */
86
+ declare function filtersToCanvasFilter(filters: readonly FilterSpec[]): string;
87
+ /**
88
+ * Outer glow as stacked zero-offset drop-shadows — the classic recipe, fully
89
+ * deterministic on both backends (it is just filters). intensity stacks more
90
+ * layers; pair with a signal binding to follow an animated fill.
91
+ */
92
+ declare function glow(color: string, radius?: number, intensity?: number): FilterSpec[];
93
+ interface Rect {
94
+ x: number;
95
+ y: number;
96
+ w: number;
97
+ h: number;
98
+ }
99
+ /**
100
+ * Shader effect pass (§3.7): runs over the group's rasterized texture.
101
+ * EXPLICITLY outside the determinism guarantee — GPU/driver per-pixel
102
+ * variance breaks distributed reproducibility; export with shaders is
103
+ * best-effort, single machine. Uniform VALUES are resolved at emit time
104
+ * (they ride on signals), so the IR stays a plain serializable snapshot.
105
+ */
106
+ interface ShaderRef {
107
+ /** WGSL fragment module: declare `struct Uniforms` + `@fragment fn effect(@location(0) uv: vec2f) -> @location(0) vec4f`. */
108
+ wgsl: string;
109
+ /** Scalar uniforms, packed as f32 in SORTED KEY ORDER into the Uniforms struct. */
110
+ uniforms: Record<string, number>;
111
+ /** Named texture inputs: binding name → image/video asset id (the source canvas is binding 0). Reserved for multi-input passes. */
112
+ textures?: Record<string, string>;
113
+ }
114
+ type DrawCommand = {
115
+ op: 'save';
116
+ } | {
117
+ op: 'restore';
118
+ } | {
119
+ op: 'transform';
120
+ m: Mat2x3;
121
+ } | {
122
+ op: 'clip';
123
+ path: ResourceId;
124
+ rule?: 'nonzero' | 'evenodd';
125
+ } | {
126
+ op: 'fillPath';
127
+ path: ResourceId;
128
+ paint: Paint;
129
+ } | {
130
+ op: 'strokePath';
131
+ path: ResourceId;
132
+ paint: Paint;
133
+ stroke: StrokeStyle;
134
+ } | {
135
+ op: 'fillText';
136
+ text: string;
137
+ font: FontSpec;
138
+ paint: Paint;
139
+ x: number;
140
+ y: number;
141
+ align?: 'left' | 'center' | 'right';
142
+ } | {
143
+ op: 'drawImage';
144
+ image: ResourceId;
145
+ src?: Rect;
146
+ dst: Rect;
147
+ smoothing?: boolean;
148
+ } | {
149
+ op: 'pushGroup';
150
+ opacity: number;
151
+ blend: BlendMode;
152
+ filters: FilterSpec[];
153
+ shader?: ShaderRef;
154
+ cacheKey?: string;
155
+ } | {
156
+ op: 'popGroup';
157
+ };
158
+ interface DisplayList {
159
+ commands: DrawCommand[];
160
+ resources: Resource[];
161
+ size: {
162
+ w: number;
163
+ h: number;
164
+ };
165
+ }
166
+ interface DisplayListBuilder {
167
+ push(cmd: DrawCommand): void;
168
+ resource(res: Resource): ResourceId;
169
+ /**
170
+ * §3.5 cacheKey seam — OPTIONAL so non-cache emits and lightweight mock
171
+ * builders never need them. `createDisplayListBuilder` supplies all three;
172
+ * `Node.emit` calls them only for `cache:true` nodes when present.
173
+ */
174
+ /** Count of commands emitted so far — a markpoint for cacheKey ranges. */
175
+ mark?(): number;
176
+ /**
177
+ * A stable hash of the command slice [start, end) plus the FULL content of
178
+ * every resource those commands reference (not just ids — interned ids are a
179
+ * per-list detail). Pure function of the slice; identical slices at two times
180
+ * hash equal, so a static subtree caches. Opaque buffers collapse to a length
181
+ * marker (mirrors cacheColdAudit's serializer). Undefined for an empty slice.
182
+ */
183
+ cacheKey?(start: number, end: number): string | undefined;
184
+ /** Stamp a cacheKey onto the pushGroup already emitted at index `i`. */
185
+ patchCacheKey?(i: number, key: string): void;
186
+ }
187
+ declare function createDisplayListBuilder(size: {
188
+ w: number;
189
+ h: number;
190
+ }): DisplayListBuilder & {
191
+ finish(): DisplayList;
192
+ };
193
+ //#endregion
194
+ export { Mat2x3 as C, matEquals as D, invert as E, multiply as O, IDENTITY as S, fromTRS as T, StrokeStyle as _, FilterSpec as a, glow as b, MeshInterpolation as c, Paint as d, PathSeg as f, ShaderRef as g, ResourceId as h, DrawCommand as i, MeshPaint$1 as l, Resource as m, DisplayList as n, FilterValidationError as o, Rect as p, DisplayListBuilder as r, FontSpec as s, BlendMode as t, MeshPoint as u, createDisplayListBuilder as v, applyToPoint as w, validateFilters as x, filtersToCanvasFilter as y };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { $ as breakLines, A as Polyline, At as invert, B as validateHachure, C as Video, Ct as filtersToCanvasFilter, D as revealSchedule, Dt as Mat2x3, E as pathFromSegs, Et as IDENTITY, F as flatten, G as HitArea, H as AnchorSpec, I as hachureLines, J as PropInit, K as Node, L as resolveSketch, M as SketchStyle, Mt as multiply, N as SketchValidationError, O as roundedRectSegs, Ot as applyToPoint, P as arcLength, Q as TextMetricsLite, R as roughen, S as TextProps, St as createDisplayListBuilder, T as WordBox, Tt as validateFilters, U as BindablePropTarget, V as validateSketch, W as EvalContext, X as MEASURE_QUANTUM_PX, Y as resolveAnchor, Z as TextMeasurer, _ as PathProps, _t as Rect$1, a as LayoutEngineMissingError, at as BlendMode, b as ShapeProps, bt as ShaderRef, c as requireLayoutEngine, ct as DrawCommand, d as Custom, dt as FontSpec, et as estimatingMeasurer, f as Group, ft as MeshInterpolation, g as Path, gt as PathSeg, h as LineBox, ht as Paint, i as LayoutEngine, it as setDefaultMeasurer, j as ResolvedSketch, jt as matEquals, k as HachureSpec, kt as fromTRS, l as setLayoutEngine, lt as FilterSpec, m as ImageProps, mt as MeshPoint, n as LayoutChildSpec, nt as segmentGraphemes, ot as DisplayList, p as ImageNode, pt as MeshPaint, q as NodeProps, r as LayoutContainerSpec, rt as segmentWords, s as getLayoutEngine, st as DisplayListBuilder, t as LayoutBox, tt as quantize, u as Circle, ut as FilterValidationError, v as Rect, vt as Resource, w as VideoProps, wt as glow, x as Text, xt as StrokeStyle, y as RevealMark, yt as ResourceId, z as sketchStrokes } from "./layoutEngine.js";
1
+ import { C as Mat2x3, D as matEquals, E as invert, O as multiply, S as IDENTITY, T as fromTRS, _ as StrokeStyle, a as FilterSpec, b as glow, c as MeshInterpolation, d as Paint, f as PathSeg, g as ShaderRef, h as ResourceId, i as DrawCommand, l as MeshPaint, m as Resource, n as DisplayList, o as FilterValidationError, p as Rect$1, r as DisplayListBuilder, s as FontSpec, t as BlendMode, u as MeshPoint, v as createDisplayListBuilder, w as applyToPoint, x as validateFilters, y as filtersToCanvasFilter } from "./displayList.js";
2
+ import { $ as TextMetricsLite, A as HachureSpec, B as sketchStrokes, C as Video, D as pathFromSegs, E as coercePathData, F as arcLength, G as EvalContext, H as validateSketch, I as flatten, J as NodeProps, K as HitArea, L as hachureLines, M as ResolvedSketch, N as SketchStyle, O as revealSchedule, P as SketchValidationError, Q as TextMeasurer, R as resolveSketch, S as TextProps, T as WordBox, U as AnchorSpec, V as validateHachure, W as BindablePropTarget, X as resolveAnchor, Y as PropInit, Z as MEASURE_QUANTUM_PX, _ as PathProps, a as LayoutEngineMissingError, at as setDefaultMeasurer, b as ShapeProps, c as requireLayoutEngine, d as Custom, et as breakLines, f as Group, g as Path, h as LineBox, i as LayoutEngine, it as segmentWords, j as Polyline, k as roundedRectSegs, l as setLayoutEngine, m as ImageProps, n as LayoutChildSpec, nt as quantize, p as ImageNode, q as Node, r as LayoutContainerSpec, rt as segmentGraphemes, s as getLayoutEngine, t as LayoutBox, tt as estimatingMeasurer, u as Circle, v as Rect, w as VideoProps, x as Text, y as RevealMark, z as roughen } from "./layoutEngine.js";
2
3
  import { BindableSignal, BoundTimeline, CompiledTimeline, CoverageReport, EaseSpec, FontMode, FontUsage, MeshPaint as MeshPaint$1, PathValue, Playhead, Rng, Timeline, Track, Vec2 } from "@glissade/core";
3
4
  import { ChannelOverride, Clip } from "@glissade/core/clips";
4
5
 
@@ -892,4 +893,4 @@ declare function meshRasterSize(bw: number, bh: number): {
892
893
  h: number;
893
894
  };
894
895
  //#endregion
895
- export { ALL_FILTER_KINDS, type AnchorSpec, type BackendCaps, type BindablePropTarget, type BlendMode, type CacheColdResult, type CanvasLike, Circle, ColdAssetError, type CommandDelta, type Ctx2DLike, Custom, DL_SNAPSHOT_VERSION, DeterminismViolationError, type DisplayDiff, type DisplayList, type DisplayListBuilder, type DlSnapshot, DlSnapshotError, type DrawCommand, type DrawOnEachOptions, type DrawOnOptions, DuplicateNodeIdError, type EachBox, type EachContext, type EachDistribute, EachError, type EachLayout, type EachMotion, type EachOpts, type EachResult, type EditMark, type EvalContext, type FieldChange, type FilterKind, type FilterSpec, FilterValidationError, FollowPath, type FollowPathProps, type FontByteLoader, type FontSpec, Group, type GuardMode, type HachureSpec, Highlight, type HighlightProps, type HitArea, IDENTITY, ImageNode as Image, ImageNode, type ImageDataLike, type ImageHandle, type ImageProps, type LayoutBox, type LayoutChildSpec, type LayoutContainerSpec, type LayoutEngine, LayoutEngineMissingError, type LineBox, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, type Mat2x3, type MeshInterpolation, type MeshPaint, type MeshPoint, NODE_TAXONOMY, Node, type NodeProps, type NodeTypeName, type Paint, Path, type PathLike, type PathProps, type PathSampler, type PathSeg, type Place, type Polyline, type PropInit, Raster2D, type Raster2DHost, Rect, type Rect$1 as RectShape, type RenderBackend, ReservedNodeIdError, type ResolvedSketch, type Resource, type ResourceId, type RevealMark, type Scene, type SceneInit, type SceneModule, type ShaderCaps, ShaderEffect, type ShaderEffectProps, type ShaderRef, type ShapeProps, type SketchStyle, SketchValidationError, type StepMark, type StrokeStyle, Text, TextCursor, type TextCursorProps, type TextMeasurer, type TextMetricsLite, type TextProps, TokenHighlight, type TokenHighlightProps, TokenMatchError, type TokenRange, type TypeEdit, type TypewriterResult, type ValidateSceneFontsOptions, Video, type VideoFrameSource, type VideoProps, type WordBox, applyToPoint, arcLength, auditCacheCold, bindScene, breakLines, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, diffDisplayLists, drawOn, drawOnEach, each, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, followPath, fontString, formatDisplayDiff, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, matEquals, matchTokenRun, meshRasterSize, motionPath, multiply, parseDisplaySnapshot, pathFromSegs, pathLength, pointAtLength, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, serializeDisplayList, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, tokenHighlight, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
896
+ export { ALL_FILTER_KINDS, type AnchorSpec, type BackendCaps, type BindablePropTarget, type BlendMode, type CacheColdResult, type CanvasLike, Circle, ColdAssetError, type CommandDelta, type Ctx2DLike, Custom, DL_SNAPSHOT_VERSION, DeterminismViolationError, type DisplayDiff, type DisplayList, type DisplayListBuilder, type DlSnapshot, DlSnapshotError, type DrawCommand, type DrawOnEachOptions, type DrawOnOptions, DuplicateNodeIdError, type EachBox, type EachContext, type EachDistribute, EachError, type EachLayout, type EachMotion, type EachOpts, type EachResult, type EditMark, type EvalContext, type FieldChange, type FilterKind, type FilterSpec, FilterValidationError, FollowPath, type FollowPathProps, type FontByteLoader, type FontSpec, Group, type GuardMode, type HachureSpec, Highlight, type HighlightProps, type HitArea, IDENTITY, ImageNode as Image, ImageNode, type ImageDataLike, type ImageHandle, type ImageProps, type LayoutBox, type LayoutChildSpec, type LayoutContainerSpec, type LayoutEngine, LayoutEngineMissingError, type LineBox, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, type Mat2x3, type MeshInterpolation, type MeshPaint, type MeshPoint, NODE_TAXONOMY, Node, type NodeProps, type NodeTypeName, type Paint, Path, type PathLike, type PathProps, type PathSampler, type PathSeg, type Place, type Polyline, type PropInit, Raster2D, type Raster2DHost, Rect, type Rect$1 as RectShape, type RenderBackend, ReservedNodeIdError, type ResolvedSketch, type Resource, type ResourceId, type RevealMark, type Scene, type SceneInit, type SceneModule, type ShaderCaps, ShaderEffect, type ShaderEffectProps, type ShaderRef, type ShapeProps, type SketchStyle, SketchValidationError, type StepMark, type StrokeStyle, Text, TextCursor, type TextCursorProps, type TextMeasurer, type TextMetricsLite, type TextProps, TokenHighlight, type TokenHighlightProps, TokenMatchError, type TokenRange, type TypeEdit, type TypewriterResult, type ValidateSceneFontsOptions, Video, type VideoFrameSource, type VideoProps, type WordBox, applyToPoint, arcLength, auditCacheCold, bindScene, breakLines, coercePathData, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, diffDisplayLists, drawOn, drawOnEach, each, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, followPath, fontString, formatDisplayDiff, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, matEquals, matchTokenRun, meshRasterSize, motionPath, multiply, parseDisplaySnapshot, pathFromSegs, pathLength, pointAtLength, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, serializeDisplayList, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, tokenHighlight, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- import { $ as multiply, A as estimatingMeasurer, B as validateFilters, C as sketchStrokes, D as resolveAnchor, E as Node, F as setDefaultMeasurer, G as formatDisplayDiff, H as DlSnapshotError, I as FilterValidationError, J as IDENTITY, K as parseDisplaySnapshot, L as createDisplayListBuilder, M as quantize, N as segmentGraphemes, O as MEASURE_QUANTUM_PX, P as segmentWords, Q as matEquals, R as filtersToCanvasFilter, S as roughen, T as validateSketch, U as collapseReplacer, V as DL_SNAPSHOT_VERSION, W as diffDisplayLists, X as fromTRS, Y as applyToPoint, Z as invert, _ as arcLength, a as Circle, b as hashStr, c as ImageNode, d as Text, f as Video, g as SketchValidationError, h as roundedRectSegs, i as setLayoutEngine, j as fallbackMeasurer, k as breakLines, l as Path, m as revealSchedule, n as getLayoutEngine, o as Custom, p as pathFromSegs, q as serializeDisplayList, r as requireLayoutEngine, s as Group, t as LayoutEngineMissingError, u as Rect, v as flatten, w as validateHachure, x as resolveSketch, y as hachureLines, z as glow } from "./layoutEngine.js";
1
+ import { A as segmentGraphemes, B as collapseReplacer, C as Node, D as estimatingMeasurer, E as breakLines, F as filtersToCanvasFilter, G as IDENTITY, H as formatDisplayDiff, I as glow, J as invert, K as applyToPoint, L as validateFilters, M as setDefaultMeasurer, N as FilterValidationError, O as fallbackMeasurer, P as createDisplayListBuilder, R as DL_SNAPSHOT_VERSION, S as validateSketch, T as MEASURE_QUANTUM_PX, U as parseDisplaySnapshot, V as diffDisplayLists, W as serializeDisplayList, X as multiply, Y as matEquals, _ as hashStr, a as Path, b as sketchStrokes, c as Video, d as revealSchedule, f as roundedRectSegs, g as hachureLines, h as flatten, i as ImageNode, j as segmentWords, k as quantize, l as coercePathData, m as arcLength, n as Custom, o as Rect, p as SketchValidationError, q as fromTRS, r as Group, s as Text, t as Circle, u as pathFromSegs, v as resolveSketch, w as resolveAnchor, x as validateHachure, y as roughen, z as DlSnapshotError } from "./nodes.js";
2
+ import { i as setLayoutEngine, n as getLayoutEngine, r as requireLayoutEngine, t as LayoutEngineMissingError } from "./layoutEngine.js";
2
3
  import { bindTimeline, buildFontRegistry, compileTimeline, createPlayhead, emitDevWarning, evaluateAt, key, lerpColor, oklabToRgba, parseCmap, parseColor, random, rgbaToOklab, signal, stagger, track, validateFonts, vec2Signal } from "@glissade/core";
3
4
  //#region src/taxonomy.ts
4
5
  /**
@@ -1850,4 +1851,4 @@ var Raster2D = class {
1850
1851
  }
1851
1852
  };
1852
1853
  //#endregion
1853
- export { ALL_FILTER_KINDS, Circle, ColdAssetError, Custom, DL_SNAPSHOT_VERSION, DeterminismViolationError, DlSnapshotError, DuplicateNodeIdError, EachError, FilterValidationError, FollowPath, Group, Highlight, IDENTITY, ImageNode as Image, ImageNode, LayoutEngineMissingError, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, NODE_TAXONOMY, Node, Path, Raster2D, Rect, ReservedNodeIdError, ShaderEffect, SketchValidationError, Text, TextCursor, TokenHighlight, TokenMatchError, Video, applyToPoint, arcLength, auditCacheCold, bindScene, breakLines, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, diffDisplayLists, drawOn, drawOnEach, each, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, followPath, fontString, formatDisplayDiff, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, matEquals, matchTokenRun, meshRasterSize, motionPath, multiply, parseDisplaySnapshot, pathFromSegs, pathLength, pointAtLength, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, serializeDisplayList, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, tokenHighlight, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
1854
+ export { ALL_FILTER_KINDS, Circle, ColdAssetError, Custom, DL_SNAPSHOT_VERSION, DeterminismViolationError, DlSnapshotError, DuplicateNodeIdError, EachError, FilterValidationError, FollowPath, Group, Highlight, IDENTITY, ImageNode as Image, ImageNode, LayoutEngineMissingError, MEASURE_QUANTUM_PX, MESH_DOWNSCALE, MESH_SHEPARD_POWER, MESH_SIGMA, NODE_TAXONOMY, Node, Path, Raster2D, Rect, ReservedNodeIdError, ShaderEffect, SketchValidationError, Text, TextCursor, TokenHighlight, TokenMatchError, Video, applyToPoint, arcLength, auditCacheCold, bindScene, breakLines, coercePathData, collapseReplacer, collectLocalizedTextUsages, collectTextUsages, createDisplayListBuilder, createScene, diffDisplayLists, drawOn, drawOnEach, each, estimatingMeasurer, evaluate, filtersToCanvasFilter, flatten, followPath, fontString, formatDisplayDiff, fromTRS, getLayoutEngine, glow, hachureLines, highlight, invert, matEquals, matchTokenRun, meshRasterSize, motionPath, multiply, parseDisplaySnapshot, pathFromSegs, pathLength, pointAtLength, quantize, rasterizeMesh, requireLayoutEngine, resolveAnchor, resolveSketch, revealSchedule, roughen, roundedRectSegs, segmentGraphemes, segmentWords, serializeDisplayList, setDefaultMeasurer, setLayoutEngine, sketchStrokes, textCursor, tokenHighlight, typewriter, validateFilters, validateHachure, validateSceneFonts, validateSketch, withDeterminismGuards };
package/dist/layout.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { J as PropInit, K as Node, W as EvalContext, Z as TextMeasurer, a as LayoutEngineMissingError, f as Group, i as LayoutEngine, l as setLayoutEngine, n as LayoutChildSpec, o as LayoutResult, q as NodeProps, r as LayoutContainerSpec, s as getLayoutEngine, st as DisplayListBuilder, t as LayoutBox } from "./layoutEngine.js";
1
+ import { r as DisplayListBuilder } from "./displayList.js";
2
+ import { G as EvalContext, J as NodeProps, Q as TextMeasurer, Y as PropInit, a as LayoutEngineMissingError, f as Group, i as LayoutEngine, l as setLayoutEngine, n as LayoutChildSpec, o as LayoutResult, q as Node, r as LayoutContainerSpec, s as getLayoutEngine, t as LayoutBox } from "./layoutEngine.js";
2
3
  import { BindableSignal } from "@glissade/core";
3
4
 
4
5
  //#region src/layout.d.ts
package/dist/layout.js CHANGED
@@ -1,4 +1,5 @@
1
- import { i as setLayoutEngine, j as fallbackMeasurer, n as getLayoutEngine, r as requireLayoutEngine, s as Group, t as LayoutEngineMissingError } from "./layoutEngine.js";
1
+ import { O as fallbackMeasurer, r as Group } from "./nodes.js";
2
+ import { i as setLayoutEngine, n as getLayoutEngine, r as requireLayoutEngine, t as LayoutEngineMissingError } from "./layoutEngine.js";
2
3
  import { computed, signal } from "@glissade/core";
3
4
  //#region src/layout.ts
4
5
  /**
@@ -1,197 +1,8 @@
1
- import { BindableSignal, MeshInterpolation, MeshPaint as MeshPaint$1, MeshPoint, Paint, PathValue, ReadonlySignal, Rng, Track, ValueTypeId, Vec2, Vec2Signal } from "@glissade/core";
1
+ import { C as Mat2x3, a as FilterSpec, d as Paint, f as PathSeg, g as ShaderRef, r as DisplayListBuilder, s as FontSpec, t as BlendMode } from "./displayList.js";
2
+ import { BindableSignal, PathValue, ReadonlySignal, Rng, Track, ValueTypeId, Vec2, Vec2Signal } from "@glissade/core";
2
3
 
3
- //#region src/matrix.d.ts
4
-
5
- type Mat2x3 = readonly [number, number, number, number, number, number];
6
- declare const IDENTITY: Mat2x3;
7
- declare function multiply(m1: Mat2x3, m2: Mat2x3): Mat2x3;
8
- /** Compose translate × rotate × scale (rotation in degrees). */
9
- declare function fromTRS(position: Vec2, rotationDeg: number, scale: Vec2): Mat2x3;
10
- /** Inverse affine: [A | t]⁻¹ = [A⁻¹ | −A⁻¹t]; null when degenerate (det 0). */
11
- declare function invert(m: Mat2x3): Mat2x3 | null;
12
- declare function applyToPoint(m: Mat2x3, p: Vec2): Vec2;
13
- declare function matEquals(a: Mat2x3, b: Mat2x3): boolean;
14
- //#endregion
15
- //#region src/displayList.d.ts
16
- type ResourceId = number;
17
- /**
18
- * Path data as plain segments (JSON-serializable; backends build Path2D/SkPath):
19
- * M/L: point; C: cubic; Q: quadratic; Z: close
20
- * E: ellipse arc — cx, cy, rx, ry, rotationRad, startAngleRad, endAngleRad
21
- */
22
- type PathSeg = ['M', number, number] | ['L', number, number] | ['C', number, number, number, number, number, number] | ['Q', number, number, number, number] | ['E', number, number, number, number, number, number, number] | ['Z'];
23
- type Resource = {
24
- kind: 'path';
25
- segs: PathSeg[];
26
- } | {
27
- kind: 'image';
28
- assetId: string;
29
- }
30
- /** One source-grid video frame: backends resolve via their VideoFrameSource registry (§3.8). */ | {
31
- kind: 'videoFrame';
32
- assetId: string;
33
- mediaT: number;
34
- };
35
- type BlendMode = 'source-over' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten';
36
- interface StrokeStyle {
37
- width: number;
38
- cap?: 'butt' | 'round' | 'square';
39
- join?: 'miter' | 'round' | 'bevel';
40
- miterLimit?: number;
41
- dash?: number[];
42
- dashOffset?: number;
43
- }
44
- interface FontSpec {
45
- family: string;
46
- size: number;
47
- weight?: number;
48
- style?: 'normal' | 'italic';
49
- }
50
- /**
51
- * Group filters (§3.4): a CLOSED union — validated data, never a CSS
52
- * passthrough string — limited to effects both rasterizers implement
53
- * faithfully. Cross-backend parity is perceptual (SSIM), not byte-exact:
54
- * filters are where rasterizers diverge most. Per-backend output stays
55
- * deterministic on the pinned toolchain (golden-tested on Skia).
56
- */
57
- type FilterSpec = {
58
- kind: 'blur'; /** Gaussian stdDeviation, px; ≥ 0. */
59
- radius: number;
60
- } | {
61
- kind: 'drop-shadow';
62
- dx: number;
63
- dy: number; /** ≥ 0 */
64
- blur: number;
65
- color: string;
66
- } | {
67
- kind: 'brightness'; /** 1 = identity; ≥ 0. */
68
- amount: number;
69
- } | {
70
- kind: 'contrast'; /** 1 = identity; ≥ 0. */
71
- amount: number;
72
- } | {
73
- kind: 'saturate'; /** 1 = identity; ≥ 0. */
74
- amount: number;
75
- };
76
- declare class FilterValidationError extends Error {
77
- constructor(message: string);
78
- }
79
- /** Document-layer validation: reject unknown kinds and out-of-range params loudly. */
80
- declare function validateFilters(filters: readonly FilterSpec[]): void;
81
- /**
82
- * Compile the validated union to the canvas 2D `ctx.filter` syntax — both
83
- * backends speak it (browser canvas and @napi-rs/canvas/Skia). This is the
84
- * ONLY place the CSS-like syntax appears; documents never carry it.
85
- */
86
- declare function filtersToCanvasFilter(filters: readonly FilterSpec[]): string;
87
- /**
88
- * Outer glow as stacked zero-offset drop-shadows — the classic recipe, fully
89
- * deterministic on both backends (it is just filters). intensity stacks more
90
- * layers; pair with a signal binding to follow an animated fill.
91
- */
92
- declare function glow(color: string, radius?: number, intensity?: number): FilterSpec[];
93
- interface Rect$1 {
94
- x: number;
95
- y: number;
96
- w: number;
97
- h: number;
98
- }
99
- /**
100
- * Shader effect pass (§3.7): runs over the group's rasterized texture.
101
- * EXPLICITLY outside the determinism guarantee — GPU/driver per-pixel
102
- * variance breaks distributed reproducibility; export with shaders is
103
- * best-effort, single machine. Uniform VALUES are resolved at emit time
104
- * (they ride on signals), so the IR stays a plain serializable snapshot.
105
- */
106
- interface ShaderRef {
107
- /** WGSL fragment module: declare `struct Uniforms` + `@fragment fn effect(@location(0) uv: vec2f) -> @location(0) vec4f`. */
108
- wgsl: string;
109
- /** Scalar uniforms, packed as f32 in SORTED KEY ORDER into the Uniforms struct. */
110
- uniforms: Record<string, number>;
111
- /** Named texture inputs: binding name → image/video asset id (the source canvas is binding 0). Reserved for multi-input passes. */
112
- textures?: Record<string, string>;
113
- }
114
- type DrawCommand = {
115
- op: 'save';
116
- } | {
117
- op: 'restore';
118
- } | {
119
- op: 'transform';
120
- m: Mat2x3;
121
- } | {
122
- op: 'clip';
123
- path: ResourceId;
124
- rule?: 'nonzero' | 'evenodd';
125
- } | {
126
- op: 'fillPath';
127
- path: ResourceId;
128
- paint: Paint;
129
- } | {
130
- op: 'strokePath';
131
- path: ResourceId;
132
- paint: Paint;
133
- stroke: StrokeStyle;
134
- } | {
135
- op: 'fillText';
136
- text: string;
137
- font: FontSpec;
138
- paint: Paint;
139
- x: number;
140
- y: number;
141
- align?: 'left' | 'center' | 'right';
142
- } | {
143
- op: 'drawImage';
144
- image: ResourceId;
145
- src?: Rect$1;
146
- dst: Rect$1;
147
- smoothing?: boolean;
148
- } | {
149
- op: 'pushGroup';
150
- opacity: number;
151
- blend: BlendMode;
152
- filters: FilterSpec[];
153
- shader?: ShaderRef;
154
- cacheKey?: string;
155
- } | {
156
- op: 'popGroup';
157
- };
158
- interface DisplayList {
159
- commands: DrawCommand[];
160
- resources: Resource[];
161
- size: {
162
- w: number;
163
- h: number;
164
- };
165
- }
166
- interface DisplayListBuilder {
167
- push(cmd: DrawCommand): void;
168
- resource(res: Resource): ResourceId;
169
- /**
170
- * §3.5 cacheKey seam — OPTIONAL so non-cache emits and lightweight mock
171
- * builders never need them. `createDisplayListBuilder` supplies all three;
172
- * `Node.emit` calls them only for `cache:true` nodes when present.
173
- */
174
- /** Count of commands emitted so far — a markpoint for cacheKey ranges. */
175
- mark?(): number;
176
- /**
177
- * A stable hash of the command slice [start, end) plus the FULL content of
178
- * every resource those commands reference (not just ids — interned ids are a
179
- * per-list detail). Pure function of the slice; identical slices at two times
180
- * hash equal, so a static subtree caches. Opaque buffers collapse to a length
181
- * marker (mirrors cacheColdAudit's serializer). Undefined for an empty slice.
182
- */
183
- cacheKey?(start: number, end: number): string | undefined;
184
- /** Stamp a cacheKey onto the pushGroup already emitted at index `i`. */
185
- patchCacheKey?(i: number, key: string): void;
186
- }
187
- declare function createDisplayListBuilder(size: {
188
- w: number;
189
- h: number;
190
- }): DisplayListBuilder & {
191
- finish(): DisplayList;
192
- };
193
- //#endregion
194
4
  //#region src/text.d.ts
5
+
195
6
  interface TextMetricsLite {
196
7
  width: number;
197
8
  ascent: number;
@@ -560,6 +371,15 @@ declare abstract class Shape extends Node {
560
371
  * The seed is consumed fresh each draw, so re-evaluation is byte-identical. */
561
372
  private drawSketch;
562
373
  }
374
+ /**
375
+ * Coerce a `Path.data` init to a `PathValue`: an array of contour objects
376
+ * passes through; anything else (a string, a number, …) is a construction-time
377
+ * error. SVG `d` strings are NOT parsed here — that parser lives on the
378
+ * tree-shakeable `@glissade/scene/path` subpath (kept off the base embed), so a
379
+ * string `data` throws a clear error pointing at `pathFromSvg(d)`. Returns `[]`
380
+ * for `undefined` (the empty-path default).
381
+ */
382
+ declare function coercePathData(data: unknown): PathValue;
563
383
  /**
564
384
  * `PathSeg[]` → `PathValue` (Lottie vertex contours) — the inverse of
565
385
  * `Path.pathSegs`, so geometry from `roundedRectSegs` / `sketchStrokes` /
@@ -597,8 +417,15 @@ declare class Circle extends Shape {
597
417
  protected pathSegs(): PathSeg[];
598
418
  }
599
419
  interface PathProps extends ShapeProps {
600
- /** The geometry (§2.2 'path' value): bezier contours in vertex form, animatable via a track on '<id>/d'. */
601
- data?: PropInit<PathValue>;
420
+ /**
421
+ * The geometry (§2.2 'path' value): bezier contours in vertex form,
422
+ * animatable via a track on '<id>/d'. Accepts a `PathValue` directly or a
423
+ * computed `() => PathValue`. For an SVG `d` STRING, parse it first with
424
+ * `pathFromSvg(d)` from the tree-shakeable `@glissade/scene/path` subpath
425
+ * (off the base embed) — passing a bare string throws a clear construction
426
+ * error rather than dragging the parser onto every embed.
427
+ */
428
+ data?: PropInit<PathValue> | string;
602
429
  }
603
430
  /**
604
431
  * Arbitrary bezier geometry — the Lottie-import landing spot and the target
@@ -874,4 +701,4 @@ declare function setLayoutEngine(e: LayoutEngine): void;
874
701
  declare function getLayoutEngine(): LayoutEngine | null;
875
702
  declare function requireLayoutEngine(): LayoutEngine;
876
703
  //#endregion
877
- export { breakLines as $, Polyline as A, invert as At, validateHachure as B, Video as C, filtersToCanvasFilter as Ct, revealSchedule as D, Mat2x3 as Dt, pathFromSegs as E, IDENTITY as Et, flatten as F, HitArea as G, AnchorSpec as H, hachureLines as I, PropInit as J, Node as K, resolveSketch as L, SketchStyle as M, multiply as Mt, SketchValidationError as N, roundedRectSegs as O, applyToPoint as Ot, arcLength as P, TextMetricsLite as Q, roughen as R, TextProps as S, createDisplayListBuilder as St, WordBox as T, validateFilters as Tt, BindablePropTarget as U, validateSketch as V, EvalContext as W, MEASURE_QUANTUM_PX as X, resolveAnchor as Y, TextMeasurer as Z, PathProps as _, Rect$1 as _t, LayoutEngineMissingError as a, BlendMode as at, ShapeProps as b, ShaderRef as bt, requireLayoutEngine as c, DrawCommand as ct, Custom as d, FontSpec as dt, estimatingMeasurer as et, Group as f, MeshInterpolation as ft, Path as g, PathSeg as gt, LineBox as h, Paint as ht, LayoutEngine as i, setDefaultMeasurer as it, ResolvedSketch as j, matEquals as jt, HachureSpec as k, fromTRS as kt, setLayoutEngine as l, FilterSpec as lt, ImageProps as m, MeshPoint as mt, LayoutChildSpec as n, segmentGraphemes as nt, LayoutResult as o, DisplayList as ot, ImageNode as p, MeshPaint$1 as pt, NodeProps as q, LayoutContainerSpec as r, segmentWords as rt, getLayoutEngine as s, DisplayListBuilder as st, LayoutBox as t, quantize as tt, Circle as u, FilterValidationError as ut, Rect as v, Resource as vt, VideoProps as w, glow as wt, Text as x, StrokeStyle as xt, RevealMark as y, ResourceId as yt, sketchStrokes as z };
704
+ export { TextMetricsLite as $, HachureSpec as A, sketchStrokes as B, Video as C, pathFromSegs as D, coercePathData as E, arcLength as F, EvalContext as G, validateSketch as H, flatten as I, NodeProps as J, HitArea as K, hachureLines as L, ResolvedSketch as M, SketchStyle as N, revealSchedule as O, SketchValidationError as P, TextMeasurer as Q, resolveSketch as R, TextProps as S, WordBox as T, AnchorSpec as U, validateHachure as V, BindablePropTarget as W, resolveAnchor as X, PropInit as Y, MEASURE_QUANTUM_PX as Z, PathProps as _, LayoutEngineMissingError as a, setDefaultMeasurer as at, ShapeProps as b, requireLayoutEngine as c, Custom as d, breakLines as et, Group as f, Path as g, LineBox as h, LayoutEngine as i, segmentWords as it, Polyline as j, roundedRectSegs as k, setLayoutEngine as l, ImageProps as m, LayoutChildSpec as n, quantize as nt, LayoutResult as o, ImageNode as p, Node as q, LayoutContainerSpec as r, segmentGraphemes as rt, getLayoutEngine as s, LayoutBox as t, estimatingMeasurer as tt, Circle as u, Rect as v, VideoProps as w, Text as x, RevealMark as y, roughen as z };