@lumencast/compiler 0.4.0 → 0.6.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/src/index.ts CHANGED
@@ -1,6 +1,18 @@
1
1
  // Public surface of @lumencast/compiler.
2
2
 
3
- export { compileBundle, type CompileOptions } from "./compile.js";
3
+ export {
4
+ compileBundle,
5
+ validatePathData,
6
+ BIND_ANIMATE_SCALAR_KEYS,
7
+ BIND_ANIMATE_COLOR_KEYS,
8
+ MAX_FILTER_BLUR_PX,
9
+ MAX_FILTER_BRIGHTNESS,
10
+ MAX_PATH_SUBPATH_BYTES,
11
+ MAX_PATH_SUBPATHS,
12
+ MAX_PATH_COMMANDS,
13
+ type CompileOptions,
14
+ type CompileDiagnostic,
15
+ } from "./compile.js";
4
16
  export { canonicalize, hashBundle, ZERO_HASH } from "./canonicalize.js";
5
17
  export type {
6
18
  LSMLBundle,
@@ -8,6 +20,12 @@ export type {
8
20
  LSMLPrimitiveKind,
9
21
  LSMLBindObject,
10
22
  LSMLAnimateDirective,
23
+ LSMLFill,
24
+ LSMLFillStop,
25
+ LSMLStroke,
26
+ LSMLPath,
27
+ LSMLKeyframes,
28
+ LSMLKeyframeStep,
11
29
  LSMLStack,
12
30
  LSMLGrid,
13
31
  LSMLFrame,
package/src/lsml-types.ts CHANGED
@@ -30,6 +30,66 @@ export interface LSMLBindObject {
30
30
  items?: string;
31
31
  }
32
32
 
33
+ /** 1.1+ — a gradient stop (LSML §4.12). */
34
+ export interface LSMLFillStop {
35
+ offset: number;
36
+ color: string;
37
+ opacity?: number;
38
+ }
39
+
40
+ /** 1.1+ — Fill union used by `shape.fills[]` and `frame.backgrounds[]`
41
+ * (LSML §4.12). Discriminated on `kind`. */
42
+ export type LSMLFill =
43
+ | { kind: "solid"; color: string; opacity?: number }
44
+ | { kind: "linear-gradient"; angle_deg?: number; stops: LSMLFillStop[]; opacity?: number }
45
+ | {
46
+ kind: "radial-gradient";
47
+ center?: { x: number; y: number };
48
+ radius?: number;
49
+ stops: LSMLFillStop[];
50
+ opacity?: number;
51
+ };
52
+
53
+ /** 1.1+ — one stacked stroke layer (LSML §4.6). */
54
+ export interface LSMLStroke {
55
+ color: string;
56
+ width: number;
57
+ }
58
+
59
+ /** 1.1+ — one subpath of a `geometry: "path"` shape (LSML §4.6). */
60
+ export interface LSMLPath {
61
+ /** SVG path `d` attribute syntax. Validated at compile (ADR 001 RC#10). */
62
+ data: string;
63
+ /** Winding rule for this subpath. Default `"NONZERO"`. */
64
+ windingRule?: "NONZERO" | "EVENODD";
65
+ }
66
+
67
+ /** 1.1+ — one waypoint of a keyframe sequence (LSML §6.6). Same shapes
68
+ * as `animate.transform` / `animate.opacity` / `animate.filter`. */
69
+ export interface LSMLKeyframeStep {
70
+ /** Timeline position 0..1, normalised over `duration_ms`. */
71
+ at: number;
72
+ transform?: {
73
+ translate?: [number, number];
74
+ scale?: number | [number, number];
75
+ rotate?: number;
76
+ };
77
+ opacity?: number;
78
+ filter?: {
79
+ blur?: number;
80
+ brightness?: number;
81
+ };
82
+ }
83
+
84
+ /** 1.1+ — multi-step keyframe sequence (LSML §6.6). */
85
+ export interface LSMLKeyframes {
86
+ /** LeafPath whose value-change replays the sequence. Omitted = mount-only. */
87
+ key?: string;
88
+ steps: LSMLKeyframeStep[];
89
+ duration_ms: number;
90
+ easing?: "linear" | "ease-in" | "ease-out" | "ease-in-out";
91
+ }
92
+
33
93
  /** The visual state an `animate` directive can target (and, via `from`,
34
94
  * start from). `from` carries the same fields ; it is the mount-time
35
95
  * initial state that makes an authored `animate` play *on mount* without
@@ -53,6 +113,9 @@ export interface LSMLAnimateDirective extends LSMLAnimateState {
53
113
  easing?: "linear" | "ease-in" | "ease-out" | "ease-in-out" | "spring";
54
114
  stiffness?: number;
55
115
  damping?: number;
116
+ /** 1.1 §6.2 — spring mass (kg, default 1). Lowered into the
117
+ * runtime's `SpringTransition` (ADR 001 phase B, issue #33). */
118
+ mass?: number;
56
119
  };
57
120
  /** LSML 1.1 — mount-time initial state. When present, the element
58
121
  * mounts with these values and animates to its declared target
@@ -69,6 +132,14 @@ export interface LSMLBaseNode {
69
132
  /** 1.1+ — bind universal props to leaf paths. */
70
133
  bindUniversal?: Record<string, string>;
71
134
  animate?: LSMLAnimateDirective;
135
+ /** 1.1+ §6.3 — animation targets bound to leaf paths. Keys MUST
136
+ * reference animatable properties (the §6.1 list, plus the node
137
+ * kind's colour-typed property per §6.5) ; any other key is a hard
138
+ * compile error (ADR 001 §3.3 / RC#13 — throw, not warn). Lowered
139
+ * to the RenderNode `animateBindings` map. */
140
+ bindAnimate?: Record<string, string>;
141
+ /** 1.1+ §6.6 — keyframe sequence, played on mount or `key` change. */
142
+ keyframes?: LSMLKeyframes;
72
143
  children?: LSMLNode[];
73
144
  /** 1.1+ — visibility flag (LSML §5.4). Defaults to true. */
74
145
  visible?: boolean;
@@ -106,7 +177,15 @@ export interface LSMLFrame extends LSMLBaseNode {
106
177
  kind: "frame";
107
178
  size?: { w: number; h: number };
108
179
  position?: { x: number; y: number };
180
+ /** Single solid background. Mutually exclusive with `backgrounds`. */
109
181
  background?: string;
182
+ /** 1.1+ — stacked backgrounds, top-to-bottom (LSML §4.3 + §4.12).
183
+ * Mutually exclusive with `background`. */
184
+ backgrounds?: LSMLFill[];
185
+ /** 1.1+ — clip children to the frame's `size` (LSML §4.3). Spec
186
+ * default is `true` ; the default is runtime-side, the compiler only
187
+ * forwards an explicit value. */
188
+ clipsContent?: boolean;
110
189
  }
111
190
 
112
191
  export interface LSMLText extends LSMLBaseNode {
@@ -118,6 +197,10 @@ export interface LSMLText extends LSMLBaseNode {
118
197
  color?: string;
119
198
  textAlign?: "start" | "center" | "end" | "left" | "right";
120
199
  lineHeight?: number;
200
+ letterSpacing?: number;
201
+ textTransform?: "none" | "uppercase" | "lowercase" | "capitalize";
202
+ textDecoration?: "none" | "underline" | "line-through";
203
+ fontStyle?: "normal" | "italic" | "oblique";
121
204
  };
122
205
  format?: { kind: string; [extra: string]: unknown };
123
206
  maxLines?: number;
@@ -134,9 +217,20 @@ export interface LSMLShape extends LSMLBaseNode {
134
217
  kind: "shape";
135
218
  geometry: "rect" | "circle" | "path";
136
219
  size?: { w: number; h: number };
220
+ /** Single-path shorthand (LSML §4.6). Mutually exclusive with `paths`. */
137
221
  pathData?: string;
222
+ /** 1.1+ — multi-subpath geometry with per-subpath winding rules
223
+ * (LSML §4.6). Mutually exclusive with `pathData`. */
224
+ paths?: LSMLPath[];
225
+ /** Single solid fill. Mutually exclusive with `fills`. */
138
226
  fill?: string;
227
+ /** 1.1+ — stacked fills, top-to-bottom (LSML §4.6 + §4.12).
228
+ * Mutually exclusive with `fill`. */
229
+ fills?: LSMLFill[];
230
+ /** Single stroke. Mutually exclusive with `strokes`. */
139
231
  stroke?: { color: string; width: number };
232
+ /** 1.1+ — stacked strokes, top-to-bottom (LSML §4.6). */
233
+ strokes?: LSMLStroke[];
140
234
  cornerRadius?: number;
141
235
  ariaLabel?: string;
142
236
  }
@@ -157,6 +251,9 @@ export interface LSMLRepeat extends LSMLBaseNode {
157
251
  key?: string;
158
252
  template: LSMLNode;
159
253
  limit?: number;
254
+ /** 1.1+ §6.7 — per-iteration animation stagger in milliseconds.
255
+ * Iteration N's animations start `N * stagger_ms` after iteration 0. */
256
+ stagger_ms?: number;
160
257
  }
161
258
 
162
259
  /** 1.1+ — `instance` primitive (LSML §4.9). Mounts a sub-scene by id with