@lumencast/runtime 0.3.0 → 0.5.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.
Files changed (130) hide show
  1. package/README.md +57 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/animate/frame-coalescer.d.ts +13 -0
  4. package/dist/animate/frame-coalescer.d.ts.map +1 -0
  5. package/dist/animate/frame-coalescer.js +46 -0
  6. package/dist/animate/frame-coalescer.js.map +1 -0
  7. package/dist/animate/keyframes.d.ts +1 -1
  8. package/dist/animate/keyframes.d.ts.map +1 -1
  9. package/dist/animate/keyframes.js +20 -6
  10. package/dist/animate/keyframes.js.map +1 -1
  11. package/dist/animate/transitions.d.ts +33 -1
  12. package/dist/animate/transitions.d.ts.map +1 -1
  13. package/dist/animate/transitions.js +78 -3
  14. package/dist/animate/transitions.js.map +1 -1
  15. package/dist/{broadcast-B82fQPph.js → broadcast-3vYij4k-.js} +3 -3
  16. package/dist/{broadcast-B82fQPph.js.map → broadcast-3vYij4k-.js.map} +1 -1
  17. package/dist/{control-DIfwMYRb.js → control-BFNkY7-6.js} +4 -4
  18. package/dist/{control-DIfwMYRb.js.map → control-BFNkY7-6.js.map} +1 -1
  19. package/dist/{index-BFZXQAD7.js → index-CyOlpZAL.js} +318 -145
  20. package/dist/index-CyOlpZAL.js.map +1 -0
  21. package/dist/index.d.ts +5 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.html +1 -1
  24. package/dist/index.js +10 -0
  25. package/dist/index.js.map +1 -1
  26. package/dist/lumencast.js +9 -2
  27. package/dist/mount.d.ts.map +1 -1
  28. package/dist/mount.js +11 -1
  29. package/dist/mount.js.map +1 -1
  30. package/dist/render/bind-animate.d.ts +40 -0
  31. package/dist/render/bind-animate.d.ts.map +1 -0
  32. package/dist/render/bind-animate.js +329 -0
  33. package/dist/render/bind-animate.js.map +1 -0
  34. package/dist/render/bundle.d.ts +48 -6
  35. package/dist/render/bundle.d.ts.map +1 -1
  36. package/dist/render/bundle.js +71 -4
  37. package/dist/render/bundle.js.map +1 -1
  38. package/dist/render/color-interp.d.ts +18 -0
  39. package/dist/render/color-interp.d.ts.map +1 -0
  40. package/dist/render/color-interp.js +303 -0
  41. package/dist/render/color-interp.js.map +1 -0
  42. package/dist/render/css-color.d.ts +16 -0
  43. package/dist/render/css-color.d.ts.map +1 -0
  44. package/dist/render/css-color.js +130 -0
  45. package/dist/render/css-color.js.map +1 -0
  46. package/dist/render/diagnostics.d.ts +26 -0
  47. package/dist/render/diagnostics.d.ts.map +1 -0
  48. package/dist/render/diagnostics.js +58 -0
  49. package/dist/render/diagnostics.js.map +1 -0
  50. package/dist/render/fill.d.ts +15 -3
  51. package/dist/render/fill.d.ts.map +1 -1
  52. package/dist/render/fill.js +81 -14
  53. package/dist/render/fill.js.map +1 -1
  54. package/dist/render/filter-clamp.d.ts +35 -0
  55. package/dist/render/filter-clamp.d.ts.map +1 -0
  56. package/dist/render/filter-clamp.js +90 -0
  57. package/dist/render/filter-clamp.js.map +1 -0
  58. package/dist/render/keyframe-player.d.ts +4 -1
  59. package/dist/render/keyframe-player.d.ts.map +1 -1
  60. package/dist/render/keyframe-player.js +2 -2
  61. package/dist/render/keyframe-player.js.map +1 -1
  62. package/dist/render/primitives/frame.d.ts +16 -1
  63. package/dist/render/primitives/frame.d.ts.map +1 -1
  64. package/dist/render/primitives/frame.js +44 -13
  65. package/dist/render/primitives/frame.js.map +1 -1
  66. package/dist/render/primitives/image.d.ts +1 -1
  67. package/dist/render/primitives/image.d.ts.map +1 -1
  68. package/dist/render/primitives/image.js +8 -5
  69. package/dist/render/primitives/image.js.map +1 -1
  70. package/dist/render/primitives/index.d.ts +3 -0
  71. package/dist/render/primitives/index.d.ts.map +1 -1
  72. package/dist/render/primitives/index.js.map +1 -1
  73. package/dist/render/primitives/instance.d.ts +1 -1
  74. package/dist/render/primitives/instance.d.ts.map +1 -1
  75. package/dist/render/primitives/instance.js +10 -13
  76. package/dist/render/primitives/instance.js.map +1 -1
  77. package/dist/render/primitives/shape.d.ts +9 -3
  78. package/dist/render/primitives/shape.d.ts.map +1 -1
  79. package/dist/render/primitives/shape.js +58 -14
  80. package/dist/render/primitives/shape.js.map +1 -1
  81. package/dist/render/primitives/text.d.ts +35 -4
  82. package/dist/render/primitives/text.d.ts.map +1 -1
  83. package/dist/render/primitives/text.js +181 -9
  84. package/dist/render/primitives/text.js.map +1 -1
  85. package/dist/render/prop-allowlist.d.ts +10 -0
  86. package/dist/render/prop-allowlist.d.ts.map +1 -0
  87. package/dist/render/prop-allowlist.js +112 -0
  88. package/dist/render/prop-allowlist.js.map +1 -0
  89. package/dist/render/svg-path.d.ts +35 -0
  90. package/dist/render/svg-path.d.ts.map +1 -0
  91. package/dist/render/svg-path.js +211 -0
  92. package/dist/render/svg-path.js.map +1 -0
  93. package/dist/render/tree.d.ts.map +1 -1
  94. package/dist/render/tree.js +30 -5
  95. package/dist/render/tree.js.map +1 -1
  96. package/dist/{status-pill-DNHbHdag.js → status-pill-DIpXc5du.js} +2 -2
  97. package/dist/{status-pill-DNHbHdag.js.map → status-pill-DIpXc5du.js.map} +1 -1
  98. package/dist/{test-Dp0QrKYM.js → test-ByRec1kd.js} +4 -4
  99. package/dist/{test-Dp0QrKYM.js.map → test-ByRec1kd.js.map} +1 -1
  100. package/dist/tree-D5wYHpPu.js +1230 -0
  101. package/dist/tree-D5wYHpPu.js.map +1 -0
  102. package/dist/types.d.ts +26 -0
  103. package/dist/types.d.ts.map +1 -1
  104. package/package.json +5 -4
  105. package/src/animate/frame-coalescer.ts +63 -0
  106. package/src/animate/keyframes.ts +24 -5
  107. package/src/animate/transitions.ts +85 -3
  108. package/src/index.ts +24 -0
  109. package/src/mount.ts +12 -1
  110. package/src/render/bind-animate.tsx +370 -0
  111. package/src/render/bundle.ts +102 -10
  112. package/src/render/color-interp.ts +303 -0
  113. package/src/render/css-color.ts +145 -0
  114. package/src/render/diagnostics.ts +75 -0
  115. package/src/render/fill.tsx +85 -14
  116. package/src/render/filter-clamp.ts +99 -0
  117. package/src/render/keyframe-player.tsx +10 -2
  118. package/src/render/primitives/frame.tsx +53 -14
  119. package/src/render/primitives/image.tsx +8 -4
  120. package/src/render/primitives/index.ts +3 -0
  121. package/src/render/primitives/instance.tsx +14 -15
  122. package/src/render/primitives/shape.tsx +78 -14
  123. package/src/render/primitives/text.tsx +226 -9
  124. package/src/render/prop-allowlist.ts +119 -0
  125. package/src/render/svg-path.ts +215 -0
  126. package/src/render/tree.tsx +41 -6
  127. package/src/types.ts +27 -0
  128. package/dist/index-BFZXQAD7.js.map +0 -1
  129. package/dist/tree-x5Qd9Kq0.js +0 -508
  130. package/dist/tree-x5Qd9Kq0.js.map +0 -1
@@ -0,0 +1,303 @@
1
+ // sRGB colour interpolation (LSML 1.1 §6.5) — issue #33.
2
+ //
3
+ // Both endpoints of a colour animation are first CANONICALISED through
4
+ // the strict shared parser (`parseCssColor`, css-color.ts — ADR 001
5
+ // RC#11/RC#12, never a raw string), then converted to RGBA channels in
6
+ // [0, 1] and interpolated component-wise :
7
+ //
8
+ // out_c = a_c + t * (b_c - a_c) for c ∈ {r, g, b, a}
9
+ //
10
+ // with `t` produced by the easing curve. The output is serialised back
11
+ // to `rgba()` form — which itself round-trips through `parseCssColor`
12
+ // at the consuming primitive (belt and braces).
13
+ //
14
+ // All conversions are constant-time per value (the parser already
15
+ // bounds inputs to 64 chars) ; the named-colour table is a flat map
16
+ // lookup.
17
+ import { parseCssColor } from "./css-color";
18
+ // CSS Color 4 §6.1 named colours → packed 0xRRGGBB. Kept numeric (not
19
+ // hex strings) to minimise bundle weight ; the set of NAMES here is
20
+ // exactly the set accepted by css-color.ts (`transparent` and
21
+ // `currentcolor` are handled separately — `currentcolor` cannot be
22
+ // interpolated without computed-style context and is rejected).
23
+ const NAMED_RGB = {
24
+ aliceblue: 0xf0f8ff,
25
+ antiquewhite: 0xfaebd7,
26
+ aqua: 0x00ffff,
27
+ aquamarine: 0x7fffd4,
28
+ azure: 0xf0ffff,
29
+ beige: 0xf5f5dc,
30
+ bisque: 0xffe4c4,
31
+ black: 0x000000,
32
+ blanchedalmond: 0xffebcd,
33
+ blue: 0x0000ff,
34
+ blueviolet: 0x8a2be2,
35
+ brown: 0xa52a2a,
36
+ burlywood: 0xdeb887,
37
+ cadetblue: 0x5f9ea0,
38
+ chartreuse: 0x7fff00,
39
+ chocolate: 0xd2691e,
40
+ coral: 0xff7f50,
41
+ cornflowerblue: 0x6495ed,
42
+ cornsilk: 0xfff8dc,
43
+ crimson: 0xdc143c,
44
+ cyan: 0x00ffff,
45
+ darkblue: 0x00008b,
46
+ darkcyan: 0x008b8b,
47
+ darkgoldenrod: 0xb8860b,
48
+ darkgray: 0xa9a9a9,
49
+ darkgreen: 0x006400,
50
+ darkgrey: 0xa9a9a9,
51
+ darkkhaki: 0xbdb76b,
52
+ darkmagenta: 0x8b008b,
53
+ darkolivegreen: 0x556b2f,
54
+ darkorange: 0xff8c00,
55
+ darkorchid: 0x9932cc,
56
+ darkred: 0x8b0000,
57
+ darksalmon: 0xe9967a,
58
+ darkseagreen: 0x8fbc8f,
59
+ darkslateblue: 0x483d8b,
60
+ darkslategray: 0x2f4f4f,
61
+ darkslategrey: 0x2f4f4f,
62
+ darkturquoise: 0x00ced1,
63
+ darkviolet: 0x9400d3,
64
+ deeppink: 0xff1493,
65
+ deepskyblue: 0x00bfff,
66
+ dimgray: 0x696969,
67
+ dimgrey: 0x696969,
68
+ dodgerblue: 0x1e90ff,
69
+ firebrick: 0xb22222,
70
+ floralwhite: 0xfffaf0,
71
+ forestgreen: 0x228b22,
72
+ fuchsia: 0xff00ff,
73
+ gainsboro: 0xdcdcdc,
74
+ ghostwhite: 0xf8f8ff,
75
+ gold: 0xffd700,
76
+ goldenrod: 0xdaa520,
77
+ gray: 0x808080,
78
+ green: 0x008000,
79
+ greenyellow: 0xadff2f,
80
+ grey: 0x808080,
81
+ honeydew: 0xf0fff0,
82
+ hotpink: 0xff69b4,
83
+ indianred: 0xcd5c5c,
84
+ indigo: 0x4b0082,
85
+ ivory: 0xfffff0,
86
+ khaki: 0xf0e68c,
87
+ lavender: 0xe6e6fa,
88
+ lavenderblush: 0xfff0f5,
89
+ lawngreen: 0x7cfc00,
90
+ lemonchiffon: 0xfffacd,
91
+ lightblue: 0xadd8e6,
92
+ lightcoral: 0xf08080,
93
+ lightcyan: 0xe0ffff,
94
+ lightgoldenrodyellow: 0xfafad2,
95
+ lightgray: 0xd3d3d3,
96
+ lightgreen: 0x90ee90,
97
+ lightgrey: 0xd3d3d3,
98
+ lightpink: 0xffb6c1,
99
+ lightsalmon: 0xffa07a,
100
+ lightseagreen: 0x20b2aa,
101
+ lightskyblue: 0x87cefa,
102
+ lightslategray: 0x778899,
103
+ lightslategrey: 0x778899,
104
+ lightsteelblue: 0xb0c4de,
105
+ lightyellow: 0xffffe0,
106
+ lime: 0x00ff00,
107
+ limegreen: 0x32cd32,
108
+ linen: 0xfaf0e6,
109
+ magenta: 0xff00ff,
110
+ maroon: 0x800000,
111
+ mediumaquamarine: 0x66cdaa,
112
+ mediumblue: 0x0000cd,
113
+ mediumorchid: 0xba55d3,
114
+ mediumpurple: 0x9370db,
115
+ mediumseagreen: 0x3cb371,
116
+ mediumslateblue: 0x7b68ee,
117
+ mediumspringgreen: 0x00fa9a,
118
+ mediumturquoise: 0x48d1cc,
119
+ mediumvioletred: 0xc71585,
120
+ midnightblue: 0x191970,
121
+ mintcream: 0xf5fffa,
122
+ mistyrose: 0xffe4e1,
123
+ moccasin: 0xffe4b5,
124
+ navajowhite: 0xffdead,
125
+ navy: 0x000080,
126
+ oldlace: 0xfdf5e6,
127
+ olive: 0x808000,
128
+ olivedrab: 0x6b8e23,
129
+ orange: 0xffa500,
130
+ orangered: 0xff4500,
131
+ orchid: 0xda70d6,
132
+ palegoldenrod: 0xeee8aa,
133
+ palegreen: 0x98fb98,
134
+ paleturquoise: 0xafeeee,
135
+ palevioletred: 0xdb7093,
136
+ papayawhip: 0xffefd5,
137
+ peachpuff: 0xffdab9,
138
+ peru: 0xcd853f,
139
+ pink: 0xffc0cb,
140
+ plum: 0xdda0dd,
141
+ powderblue: 0xb0e0e6,
142
+ purple: 0x800080,
143
+ rebeccapurple: 0x663399,
144
+ red: 0xff0000,
145
+ rosybrown: 0xbc8f8f,
146
+ royalblue: 0x4169e1,
147
+ saddlebrown: 0x8b4513,
148
+ salmon: 0xfa8072,
149
+ sandybrown: 0xf4a460,
150
+ seagreen: 0x2e8b57,
151
+ seashell: 0xfff5ee,
152
+ sienna: 0xa0522d,
153
+ silver: 0xc0c0c0,
154
+ skyblue: 0x87ceeb,
155
+ slateblue: 0x6a5acd,
156
+ slategray: 0x708090,
157
+ slategrey: 0x708090,
158
+ snow: 0xfffafa,
159
+ springgreen: 0x00ff7f,
160
+ steelblue: 0x4682b4,
161
+ tan: 0xd2b48c,
162
+ teal: 0x008080,
163
+ thistle: 0xd8bfd8,
164
+ tomato: 0xff6347,
165
+ turquoise: 0x40e0d0,
166
+ violet: 0xee82ee,
167
+ wheat: 0xf5deb3,
168
+ white: 0xffffff,
169
+ whitesmoke: 0xf5f5f5,
170
+ yellow: 0xffff00,
171
+ yellowgreen: 0x9acd32,
172
+ };
173
+ /**
174
+ * Canonicalise + convert an untrusted colour value to RGBA channels in
175
+ * [0, 1]. The value passes through `parseCssColor` FIRST — anything the
176
+ * strict parser rejects converts to `null` here (never interpolate a
177
+ * raw string, §6.5 step 1 / RC#11). `currentcolor` is also rejected :
178
+ * it has no concrete channels without computed-style context.
179
+ */
180
+ export function cssColorToRgba(value) {
181
+ const v = parseCssColor(value);
182
+ if (v === null)
183
+ return null;
184
+ if (v.startsWith("#"))
185
+ return hexToRgba(v);
186
+ if (v.startsWith("rgb")) {
187
+ const body = v.slice(v.indexOf("(") + 1, -1);
188
+ const parts = body.split(",").map((p) => p.trim());
189
+ if (parts.length < 3)
190
+ return null;
191
+ const pct = parts[0].endsWith("%");
192
+ const scale = pct ? 100 : 255;
193
+ const r = channel(parts[0], scale);
194
+ const g = channel(parts[1], scale);
195
+ const b = channel(parts[2], scale);
196
+ const a = parts.length > 3 ? alphaChannel(parts[3]) : 1;
197
+ if (r === null || g === null || b === null || a === null)
198
+ return null;
199
+ return [r, g, b, a];
200
+ }
201
+ if (v.startsWith("hsl")) {
202
+ const body = v.slice(v.indexOf("(") + 1, -1);
203
+ const parts = body.split(",").map((p) => p.trim());
204
+ if (parts.length < 3)
205
+ return null;
206
+ const h = Number(parts[0].replace("deg", ""));
207
+ const s = Number(parts[1].replace("%", "")) / 100;
208
+ const l = Number(parts[2].replace("%", "")) / 100;
209
+ const a = parts.length > 3 ? alphaChannel(parts[3]) : 1;
210
+ if (![h, s, l].every(Number.isFinite) || a === null)
211
+ return null;
212
+ const [r, g, b] = hslToRgb(h, s, l);
213
+ return [r, g, b, a];
214
+ }
215
+ if (v === "transparent")
216
+ return [0, 0, 0, 0];
217
+ if (v === "currentcolor")
218
+ return null;
219
+ const packed = NAMED_RGB[v];
220
+ if (packed === undefined)
221
+ return null;
222
+ return [((packed >> 16) & 0xff) / 255, ((packed >> 8) & 0xff) / 255, (packed & 0xff) / 255, 1];
223
+ }
224
+ function hexToRgba(v) {
225
+ const h = v.slice(1);
226
+ if (h.length === 3 || h.length === 4) {
227
+ const r = parseInt(h[0] + h[0], 16);
228
+ const g = parseInt(h[1] + h[1], 16);
229
+ const b = parseInt(h[2] + h[2], 16);
230
+ const a = h.length === 4 ? parseInt(h[3] + h[3], 16) : 255;
231
+ return [r / 255, g / 255, b / 255, a / 255];
232
+ }
233
+ if (h.length === 6 || h.length === 8) {
234
+ const r = parseInt(h.slice(0, 2), 16);
235
+ const g = parseInt(h.slice(2, 4), 16);
236
+ const b = parseInt(h.slice(4, 6), 16);
237
+ const a = h.length === 8 ? parseInt(h.slice(6, 8), 16) : 255;
238
+ return [r / 255, g / 255, b / 255, a / 255];
239
+ }
240
+ return null;
241
+ }
242
+ function channel(token, scale) {
243
+ const n = Number(token.replace("%", ""));
244
+ if (!Number.isFinite(n))
245
+ return null;
246
+ return clamp01(n / scale);
247
+ }
248
+ function alphaChannel(token) {
249
+ const pct = token.endsWith("%");
250
+ const n = Number(token.replace("%", ""));
251
+ if (!Number.isFinite(n))
252
+ return null;
253
+ return clamp01(pct ? n / 100 : n);
254
+ }
255
+ /** Standard HSL → RGB (CSS Color 4 §7.1). h in degrees, s/l in [0,1]. */
256
+ function hslToRgb(h, s, l) {
257
+ const hue = ((h % 360) + 360) % 360;
258
+ const c = (1 - Math.abs(2 * l - 1)) * s;
259
+ const hp = hue / 60;
260
+ const x = c * (1 - Math.abs((hp % 2) - 1));
261
+ let r = 0;
262
+ let g = 0;
263
+ let b = 0;
264
+ if (hp < 1)
265
+ [r, g, b] = [c, x, 0];
266
+ else if (hp < 2)
267
+ [r, g, b] = [x, c, 0];
268
+ else if (hp < 3)
269
+ [r, g, b] = [0, c, x];
270
+ else if (hp < 4)
271
+ [r, g, b] = [0, x, c];
272
+ else if (hp < 5)
273
+ [r, g, b] = [x, 0, c];
274
+ else
275
+ [r, g, b] = [c, 0, x];
276
+ const m = l - c / 2;
277
+ return [clamp01(r + m), clamp01(g + m), clamp01(b + m)];
278
+ }
279
+ /** Component-wise sRGB lerp (§6.5 step 2). `t` may overshoot (springs) ;
280
+ * channels clamp back into [0, 1] after mixing. */
281
+ export function mixRgba(a, b, t) {
282
+ return [
283
+ clamp01(a[0] + t * (b[0] - a[0])),
284
+ clamp01(a[1] + t * (b[1] - a[1])),
285
+ clamp01(a[2] + t * (b[2] - a[2])),
286
+ clamp01(a[3] + t * (b[3] - a[3])),
287
+ ];
288
+ }
289
+ /** Serialise RGBA back to `rgba()` form (§6.5 step 3). The output is
290
+ * always re-accepted by `parseCssColor` (integer channels, alpha with
291
+ * at most 4 decimals). */
292
+ export function serializeRgba(rgba) {
293
+ const r = Math.round(clamp01(rgba[0]) * 255);
294
+ const g = Math.round(clamp01(rgba[1]) * 255);
295
+ const b = Math.round(clamp01(rgba[2]) * 255);
296
+ // 4 decimals max so the alpha token matches the strict grammar.
297
+ const a = Math.round(clamp01(rgba[3]) * 10000) / 10000;
298
+ return `rgba(${r}, ${g}, ${b}, ${a})`;
299
+ }
300
+ function clamp01(n) {
301
+ return n < 0 ? 0 : n > 1 ? 1 : n;
302
+ }
303
+ //# sourceMappingURL=color-interp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"color-interp.js","sourceRoot":"","sources":["../../src/render/color-interp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Validate an untrusted colour value against the strict grammar above.
3
+ *
4
+ * Returns the validated string (trimmed ; named colours lowercased) or
5
+ * `null` on rejection. A `null` MUST be handled as "omit the style /
6
+ * use the primitive's safe default" — never interpolate the raw input.
7
+ */
8
+ export declare function parseCssColor(value: unknown): string | null;
9
+ /**
10
+ * Diagnostic for a rejected value. Bastion R9 (ADR 001 §5.1) : the
11
+ * rejected VALUE is never logged nor forwarded — only `node.id` (RC#7,
12
+ * issue #34), the field name and a static reason. Routed through the
13
+ * structured diagnostics channel (events, no logs in `broadcast`).
14
+ */
15
+ export declare function warnRejectedColor(field: string, nodeId?: string): void;
16
+ //# sourceMappingURL=css-color.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-color.d.ts","sourceRoot":"","sources":["../../src/render/css-color.ts"],"names":[],"mappings":"AAwFA;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAmC3D;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAMtE"}
@@ -0,0 +1,130 @@
1
+ // Strict CSS colour parser — the ONLY gate through which untrusted
2
+ // colour values (bundle props AND live LSDP deltas, see `resolveProps`
3
+ // in tree.tsx) may reach an inline CSS style.
4
+ //
5
+ // ADR 001 §6 RC#11 (CSS strict) + RC#12 (anti-ReDoS), threat model
6
+ // Bastion 2026-06-10, issue #35. Sites #30/#31/#33 must reuse this
7
+ // module — never re-implement colour validation locally.
8
+ //
9
+ // Accepted grammar (LSML 1.1 §6.5 colour forms, nothing more) :
10
+ // - hex : #RGB | #RGBA | #RRGGBB | #RRGGBBAA
11
+ // - rgb() : rgb(R, G, B) | rgba(R, G, B, A) — 0-255 or percentages
12
+ // - hsl() : hsl(H, S%, L%) | hsla(H, S%, L%, A)
13
+ // - named : canonical CSS named colours + `transparent` + `currentcolor`
14
+ // Anything else — including `url(`, `;`, `}`, `expression(`, var(),
15
+ // calc(), whitespace tricks — is REJECTED (null). Never passthrough.
16
+ //
17
+ // ── Linear-time justification (RC#12, written per Bastion) ──────────
18
+ // 1. Inputs longer than MAX_LEN (64) are rejected before any regex
19
+ // runs, so every step below operates on a bounded string.
20
+ // 2. The charset pre-scan is a single O(n) pass over one character
21
+ // class — it rejects `;`, `}`, `:`, `/`, quotes, backslashes and
22
+ // control characters outright, so no later step ever sees them.
23
+ // 3. Every regex is anchored (`^…$`) and built exclusively from
24
+ // literals, character classes and BOUNDED quantifiers ({m,n}, ?).
25
+ // There are no nested unbounded quantifiers ((a+)+ style), no
26
+ // overlapping alternations under a quantifier — i.e. no input can
27
+ // trigger super-linear backtracking. Combined with the 64-char cap,
28
+ // total work is O(64) per value regardless of payload shape.
29
+ // ─────────────────────────────────────────────────────────────────────
30
+ import { emitDiagnostic } from "./diagnostics";
31
+ const MAX_LEN = 64;
32
+ // Single-pass charset allowlist. Only characters that can appear in
33
+ // the accepted grammar. Notably ABSENT : `;` `}` `{` `:` `/` `"` `'`
34
+ // `\` `<` `>` `-` and all control chars — the injection metacharacters.
35
+ const CHARSET_RE = /^[#a-zA-Z0-9(),.% ]{1,64}$/;
36
+ // hex — 3/4/6/8 hex digits. Alternation of fixed-width character-class
37
+ // runs : strictly linear.
38
+ const HEX_RE = /^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/;
39
+ // Number tokens. All quantifiers bounded ; `(?:\.\d{1,4})?` is an
40
+ // optional bounded group — one possible match per position, no
41
+ // ambiguity, no backtracking blow-up.
42
+ const NUM = String.raw `\d{1,3}(?:\.\d{1,4})?`; // 0 … 999.9999
43
+ const ALPHA = String.raw `(?:0|1|0?\.\d{1,4}|${NUM}%)`; // 0-1 or %
44
+ const SP = String.raw `[ ]{0,4}`; // bounded optional spaces
45
+ // rgb(R, G, B[, A]) — channels all plain numbers or all percentages
46
+ // are both accepted (range-checked numerically after the match).
47
+ const RGB_RE = new RegExp(`^rgba?\\(${SP}(${NUM})(%?)${SP},${SP}(${NUM})(%?)${SP},${SP}(${NUM})(%?)${SP}` +
48
+ `(?:,${SP}${ALPHA}${SP})?\\)$`);
49
+ // hsl(H[deg], S%, L%[, A])
50
+ const HSL_RE = new RegExp(`^hsla?\\(${SP}(${NUM})(?:deg)?${SP},${SP}(${NUM})%${SP},${SP}(${NUM})%${SP}` +
51
+ `(?:,${SP}${ALPHA}${SP})?\\)$`);
52
+ // Canonical CSS named colours (CSS Color 4 §6.1) + the two keywords
53
+ // that behave like colours in every site we render.
54
+ const NAMED = new Set(("aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue " +
55
+ "blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk " +
56
+ "crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki " +
57
+ "darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen " +
58
+ "darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue " +
59
+ "dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite " +
60
+ "gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki " +
61
+ "lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan " +
62
+ "lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen " +
63
+ "lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen " +
64
+ "linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple " +
65
+ "mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred " +
66
+ "midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab " +
67
+ "orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip " +
68
+ "peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue " +
69
+ "saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue " +
70
+ "slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet " +
71
+ "wheat white whitesmoke yellow yellowgreen transparent currentcolor").split(" "));
72
+ /**
73
+ * Validate an untrusted colour value against the strict grammar above.
74
+ *
75
+ * Returns the validated string (trimmed ; named colours lowercased) or
76
+ * `null` on rejection. A `null` MUST be handled as "omit the style /
77
+ * use the primitive's safe default" — never interpolate the raw input.
78
+ */
79
+ export function parseCssColor(value) {
80
+ if (typeof value !== "string")
81
+ return null;
82
+ const v = value.trim();
83
+ if (v.length === 0 || v.length > MAX_LEN)
84
+ return null;
85
+ // Contractual explicit rejects (Bastion RC#11) — redundant with the
86
+ // charset scan below, kept as belt-and-braces so the contract holds
87
+ // even if the grammar is ever extended.
88
+ const lower = v.toLowerCase();
89
+ if (lower.includes("url(") || v.includes(";") || v.includes("}"))
90
+ return null;
91
+ // Single-pass charset allowlist (kills every CSS metacharacter).
92
+ if (!CHARSET_RE.test(v))
93
+ return null;
94
+ if (v.startsWith("#"))
95
+ return HEX_RE.test(v) ? v : null;
96
+ if (lower.startsWith("rgb")) {
97
+ const m = RGB_RE.exec(lower);
98
+ if (!m)
99
+ return null;
100
+ // Range check : percent channels ≤ 100, plain channels ≤ 255, no mixing.
101
+ const pct = [m[2], m[4], m[6]];
102
+ if (!(pct.every((p) => p === "%") || pct.every((p) => p === "")))
103
+ return null;
104
+ const max = pct[0] === "%" ? 100 : 255;
105
+ for (const ch of [m[1], m[3], m[5]]) {
106
+ if (Number(ch) > max)
107
+ return null;
108
+ }
109
+ return lower;
110
+ }
111
+ if (lower.startsWith("hsl")) {
112
+ const m = HSL_RE.exec(lower);
113
+ if (!m)
114
+ return null;
115
+ if (Number(m[1]) > 360 || Number(m[2]) > 100 || Number(m[3]) > 100)
116
+ return null;
117
+ return lower;
118
+ }
119
+ return NAMED.has(lower) ? lower : null;
120
+ }
121
+ /**
122
+ * Diagnostic for a rejected value. Bastion R9 (ADR 001 §5.1) : the
123
+ * rejected VALUE is never logged nor forwarded — only `node.id` (RC#7,
124
+ * issue #34), the field name and a static reason. Routed through the
125
+ * structured diagnostics channel (events, no logs in `broadcast`).
126
+ */
127
+ export function warnRejectedColor(field, nodeId) {
128
+ emitDiagnostic(nodeId, field, "rejected unsafe colour : not a strict hex/rgb()/hsl()/named colour");
129
+ }
130
+ //# sourceMappingURL=css-color.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"css-color.js","sourceRoot":"","sources":["../../src/render/css-color.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /** Placeholder id for nodes that don't declare an `id`. */
2
+ export declare const ANON_NODE_ID = "<anon>";
3
+ export interface RenderDiagnostic {
4
+ /** `RenderNode.id` of the node the field belongs to (RC#7), or
5
+ * `ANON_NODE_ID` when the node has none. */
6
+ nodeId: string;
7
+ /** Name of the field/prop concerned (e.g. `text.colour`,
8
+ * `shape.paths.data`, `bindAnimate.opacity`). Never its value (R9). */
9
+ field: string;
10
+ /** Static reason — why the field was rejected or not rendered. */
11
+ reason: string;
12
+ }
13
+ export type DiagnosticHandler = (diagnostic: RenderDiagnostic) => void;
14
+ /**
15
+ * Register a diagnostics handler (one per `mount()`, plus tests).
16
+ * Returns the unregister function. Multiple concurrent mounts each
17
+ * receive every diagnostic — node ids are bundle-scoped, so a host
18
+ * running several mounts should disambiguate on its side.
19
+ */
20
+ export declare function addDiagnosticsHandler(handler: DiagnosticHandler): () => void;
21
+ /**
22
+ * Emit one anti-drop diagnostic. `field` and `reason` MUST be static
23
+ * strings / field names — never interpolate a prop or leaf value (R9).
24
+ */
25
+ export declare function emitDiagnostic(nodeId: string | undefined, field: string, reason: string): void;
26
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/render/diagnostics.ts"],"names":[],"mappings":"AAqBA,2DAA2D;AAC3D,eAAO,MAAM,YAAY,WAAW,CAAC;AAErC,MAAM,WAAW,gBAAgB;IAC/B;iDAC6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf;4EACwE;IACxE,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAIvE;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,IAAI,CAK5E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAkB9F"}
@@ -0,0 +1,58 @@
1
+ // Anti-silent-drop diagnostics channel (ADR 001 §3.4 D4, issue #34).
2
+ //
3
+ // Every render-side diagnostic — rejected colour/filter/path/typography
4
+ // value, unknown prop, unrendered spec'd field — flows through
5
+ // `emitDiagnostic`. The diagnostic is an EVENT, not a console.log :
6
+ // hosts subscribe via `MountOptions.onDiagnostic` (wired by `mount()`)
7
+ // and receive a structured `{ nodeId, field, reason }`. When no handler
8
+ // is registered, the runtime falls back to a DEV-only `console.warn`
9
+ // so authors still see drops during development — and `broadcast`
10
+ // builds stay silent on the console, per the CLAUDE.md "no logs in
11
+ // broadcast" rule.
12
+ //
13
+ // ── Hygiene contract (Bastion R9, ADR 001 §5.1) ─────────────────────
14
+ // A diagnostic NEVER carries the value of a leaf or a prop — only the
15
+ // node id, the field name and a STATIC reason string. Leaf values can
16
+ // hold sensitive on-air content ; they must not transit any diagnostic
17
+ // channel. Callers pass field names and literal reasons exclusively.
18
+ // The R9 sentinel test (r9-sentinel.test.tsx) enforces this end to end,
19
+ // and statically checks that `console.warn` only exists in this module.
20
+ // ─────────────────────────────────────────────────────────────────────
21
+ /** Placeholder id for nodes that don't declare an `id`. */
22
+ export const ANON_NODE_ID = "<anon>";
23
+ const handlers = new Set();
24
+ /**
25
+ * Register a diagnostics handler (one per `mount()`, plus tests).
26
+ * Returns the unregister function. Multiple concurrent mounts each
27
+ * receive every diagnostic — node ids are bundle-scoped, so a host
28
+ * running several mounts should disambiguate on its side.
29
+ */
30
+ export function addDiagnosticsHandler(handler) {
31
+ handlers.add(handler);
32
+ return () => {
33
+ handlers.delete(handler);
34
+ };
35
+ }
36
+ /**
37
+ * Emit one anti-drop diagnostic. `field` and `reason` MUST be static
38
+ * strings / field names — never interpolate a prop or leaf value (R9).
39
+ */
40
+ export function emitDiagnostic(nodeId, field, reason) {
41
+ const diagnostic = { nodeId: nodeId ?? ANON_NODE_ID, field, reason };
42
+ if (handlers.size > 0) {
43
+ for (const handler of handlers) {
44
+ try {
45
+ handler(diagnostic);
46
+ }
47
+ catch {
48
+ // A host handler that throws must never break the render path.
49
+ }
50
+ }
51
+ return;
52
+ }
53
+ // DEV-only console fallback — broadcast builds log nothing.
54
+ if (import.meta.env.DEV) {
55
+ console.warn(`[lumencast] node "${diagnostic.nodeId}": field "${field}" ${reason} (value withheld per R9)`);
56
+ }
57
+ }
58
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/render/diagnostics.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,EAAE;AACF,wEAAwE;AACxE,+DAA+D;AAC/D,oEAAoE;AACpE,uEAAuE;AACvE,wEAAwE;AACxE,qEAAqE;AACrE,kEAAkE;AAClE,mEAAmE;AACnE,mBAAmB;AACnB,EAAE;AACF,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,uEAAuE;AACvE,qEAAqE;AACrE,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AAExE,2DAA2D;AAC3D,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAerC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE9C;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAA0B;IAC9D,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtB,OAAO,GAAG,EAAE;QACV,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAA0B,EAAE,KAAa,EAAE,MAAc;IACtF,MAAM,UAAU,GAAqB,EAAE,MAAM,EAAE,MAAM,IAAI,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACvF,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACH,OAAO,CAAC,UAAU,CAAC,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,+DAA+D;YACjE,CAAC;QACH,CAAC;QACD,OAAO;IACT,CAAC;IACD,4DAA4D;IAC5D,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACxB,OAAO,CAAC,IAAI,CACV,qBAAqB,UAAU,CAAC,MAAM,aAAa,KAAK,KAAK,MAAM,0BAA0B,CAC9F,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -35,7 +35,19 @@ export declare function renderFill(fill: Fill): FillRenderResult;
35
35
  /** Compile an array of Fill into a CSS `background-image` value usable
36
36
  * on a `<div>` (frame backgrounds — non-SVG context). Returns the CSS
37
37
  * string + opacity. Stops use percentages in CSS gradient syntax. */
38
- export declare function backgroundsToCss(fills: Fill[]): CSSProperties;
39
- /** Coerce loose JSON into a Fill array. Returns [] for non-arrays. */
40
- export declare function parseFills(value: unknown): Fill[];
38
+ export declare function backgroundsToCss(fills: Fill[], nodeId?: string): CSSProperties;
39
+ /** Validate every colour carried by a Fill array through the strict
40
+ * parser (RC#11 — issue #30 contractual comment : SVG `fill`/`stroke`
41
+ * attributes and `<stop stop-color>` are injection sites too, since
42
+ * fills arrive from untrusted bundles AND live LSDP deltas). A fill
43
+ * whose solid colour — or ANY gradient stop colour — is rejected drops
44
+ * the whole layer with a diagnostic : never passthrough, never a
45
+ * half-built gradient. Returned fills carry canonicalised colours. */
46
+ export declare function sanitizeFills(fills: Fill[], field: string, nodeId?: string): Fill[];
47
+ /** Coerce loose JSON into a Fill array. Returns [] for non-arrays.
48
+ * A structurally-valid fill entry whose `kind` is not renderable by
49
+ * this runtime (e.g. `angular-gradient` / `diamond-gradient`, promoted
50
+ * to core by the LSML 1.2 RFC) is dropped WITH a diagnostic — never
51
+ * silently (ADR 001 §3.4, issue #34). */
52
+ export declare function parseFills(value: unknown, field?: string, nodeId?: string): Fill[];
41
53
  //# sourceMappingURL=fill.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/render/fill.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAEzD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,IAAI,GACZ;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAQN,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;CACb;AAED;iEACiE;AACjE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,gBAAgB,CAuDvD;AAED;;qEAEqE;AACrE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,aAAa,CAM7D;AAoCD,sEAAsE;AACtE,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,CAGjD"}
1
+ {"version":3,"file":"fill.d.ts","sourceRoot":"","sources":["../../src/render/fill.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAIzD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,IAAI,GACZ;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAClD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAC;IACxB,MAAM,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAQN,MAAM,WAAW,gBAAgB;IAC/B,uDAAuD;IACvD,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,6DAA6D;IAC7D,GAAG,EAAE,MAAM,CAAC;CACb;AAED;iEACiE;AACjE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,gBAAgB,CAuDvD;AAED;;qEAEqE;AACrE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAM9E;AAsDD;;;;;;sEAMsE;AACtE,wBAAgB,aAAa,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CA2BnF;AAED;;;;yCAIyC;AACzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,CAclF"}