@noobsociety/nsds 0.1.2 → 0.2.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 (73) hide show
  1. package/CHANGELOG.md +24 -3
  2. package/README.md +347 -193
  3. package/dist/components/hud/HUDBar.d.ts +17 -0
  4. package/dist/components/hud/HUDDivider.d.ts +11 -0
  5. package/dist/components/hud/HUDLabel.d.ts +17 -0
  6. package/dist/components/icons/RPGIcon.d.ts +42 -0
  7. package/dist/index.cjs +1 -0
  8. package/dist/index.d.ts +18 -0
  9. package/dist/index.js +587 -0
  10. package/{styles.css → dist/styles.css} +1 -0
  11. package/dist/tailwind/package.json +1 -0
  12. package/dist/tailwind/preset.js +144 -0
  13. package/{tokens → dist/tokens}/colors.css +25 -19
  14. package/dist/tokens/hud.css +133 -0
  15. package/{tokens → dist/tokens}/motion.css +9 -9
  16. package/{tokens → dist/tokens}/spacing.css +9 -16
  17. package/{tokens → dist/tokens}/typography.css +2 -2
  18. package/package.json +34 -62
  19. package/SKILL.md +0 -18
  20. package/assets/bg.png +0 -0
  21. package/assets/bloop.png +0 -0
  22. package/assets/hero.png +0 -0
  23. package/assets/lamp.png +0 -0
  24. package/assets/logo.png +0 -0
  25. package/assets/mailbox.png +0 -0
  26. package/assets/plaza.png +0 -0
  27. package/assets/prickle.png +0 -0
  28. package/assets/sign.png +0 -0
  29. package/components/buttons/Button.js +0 -55
  30. package/components/buttons/Button.prompt.md +0 -22
  31. package/components/buttons/buttons.card.html +0 -24
  32. package/components/cards/FeatureCard.js +0 -36
  33. package/components/cards/FeatureCard.prompt.md +0 -17
  34. package/components/cards/QuestCard.js +0 -27
  35. package/components/cards/QuestCard.prompt.md +0 -19
  36. package/components/cards/cards.card.html +0 -54
  37. package/components/navigation/SectionArrow.js +0 -28
  38. package/components/navigation/navigation.card.html +0 -29
  39. package/components/react/index.d.ts +0 -11
  40. package/components/react/index.js +0 -4
  41. package/components/shared/styles.js +0 -22
  42. package/guidelines/brand.card.html +0 -41
  43. package/guidelines/colors.card.html +0 -43
  44. package/guidelines/motion.card.html +0 -24
  45. package/guidelines/pixel-accents.card.html +0 -50
  46. package/guidelines/radii-shadows.card.html +0 -28
  47. package/guidelines/semantic-colors.card.html +0 -30
  48. package/guidelines/spacing.card.html +0 -53
  49. package/guidelines/sprites.card.html +0 -22
  50. package/guidelines/type.card.html +0 -24
  51. package/index.d.ts +0 -1
  52. package/index.js +0 -1
  53. package/mui-theme/ThemeProvider.js +0 -14
  54. package/mui-theme/ThemeProvider.tsx +0 -20
  55. package/mui-theme/examples/FeatureCard.tsx +0 -52
  56. package/mui-theme/examples/QuestStatusChip.tsx +0 -41
  57. package/mui-theme/examples/SectionHeader.tsx +0 -44
  58. package/mui-theme/index.d.ts +0 -49
  59. package/mui-theme/index.js +0 -2
  60. package/mui-theme/index.ts +0 -2
  61. package/mui-theme/preview.dc.html +0 -195
  62. package/mui-theme/support.js +0 -1513
  63. package/mui-theme/theme.js +0 -594
  64. package/mui-theme/theme.ts +0 -604
  65. package/references/noobsociety-monokai.dc.html +0 -360
  66. package/support.js +0 -1513
  67. package/ui-kits/homepage/index.html +0 -319
  68. /package/{components → dist/components}/buttons/Button.d.ts +0 -0
  69. /package/{components → dist/components}/cards/FeatureCard.d.ts +0 -0
  70. /package/{components → dist/components}/cards/QuestCard.d.ts +0 -0
  71. /package/{components → dist/components}/navigation/SectionArrow.d.ts +0 -0
  72. /package/{components → dist/components}/primitives.css +0 -0
  73. /package/{tokens → dist/tokens}/base.css +0 -0
package/support.js DELETED
@@ -1,1513 +0,0 @@
1
- // GENERATED from dc-runtime/src/*.ts — do not edit. Rebuild with `cd dc-runtime && bun run build`.
2
- "use strict";
3
- (() => {
4
- var __defProp = Object.defineProperty;
5
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
-
8
- // src/react.ts
9
- function getReact() {
10
- const R = window.React;
11
- if (!R) throw new Error("dc-runtime: window.React is not available yet");
12
- return R;
13
- }
14
- function getReactDOM() {
15
- const RD = window.ReactDOM;
16
- if (!RD) throw new Error("dc-runtime: window.ReactDOM is not available yet");
17
- return RD;
18
- }
19
- var h = ((...args) => getReact().createElement(
20
- ...args
21
- ));
22
-
23
- // src/parse.ts
24
- function parseDcDocument(doc) {
25
- const dc = doc.querySelector("x-dc");
26
- if (!dc) return null;
27
- const scriptEl = doc.querySelector("script[data-dc-script]");
28
- const { props, preview } = parseDataProps(
29
- scriptEl?.getAttribute("data-props") ?? null
30
- );
31
- return {
32
- template: dc.innerHTML,
33
- js: scriptEl ? scriptEl.textContent || "" : "",
34
- props,
35
- preview
36
- };
37
- }
38
- function parseDcText(src) {
39
- const openMatch = /<x-dc(?:\s[^>]*)?>/.exec(src);
40
- if (!openMatch) return null;
41
- const close = src.lastIndexOf("</x-dc>");
42
- if (close === -1 || close < openMatch.index) return null;
43
- const template = src.slice(openMatch.index + openMatch[0].length, close);
44
- const doc = new DOMParser().parseFromString(src, "text/html");
45
- const scriptEl = doc.querySelector("script[data-dc-script]");
46
- const { props, preview } = parseDataProps(
47
- scriptEl?.getAttribute("data-props") ?? null
48
- );
49
- return {
50
- template,
51
- js: scriptEl ? scriptEl.textContent || "" : "",
52
- props,
53
- preview
54
- };
55
- }
56
- function parseDataProps(raw) {
57
- if (!raw) return { props: null, preview: null };
58
- let parsed;
59
- try {
60
- parsed = JSON.parse(raw);
61
- } catch {
62
- return { props: null, preview: null };
63
- }
64
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
65
- return { props: null, preview: null };
66
- }
67
- const obj = parsed;
68
- const preview = obj.$preview && typeof obj.$preview === "object" ? obj.$preview : null;
69
- const rest = {};
70
- for (const k of Object.keys(obj)) {
71
- if (k[0] !== "$") rest[k] = obj[k];
72
- }
73
- return { props: Object.keys(rest).length ? rest : null, preview };
74
- }
75
- function dcNameFromPath(pathname) {
76
- let p = pathname || "";
77
- try {
78
- p = decodeURIComponent(p);
79
- } catch {
80
- }
81
- const base = p.split("/").pop() || "Root";
82
- return base.replace(/\.dc\.html$/, "").replace(/\.html?$/, "") || "Root";
83
- }
84
-
85
- // src/boot.ts
86
- var BASE_CSS = `
87
- .sc-placeholder{background:rgba(255,255,255,.3);border:1px solid rgba(0,0,0,.5);
88
- border-radius:2px;box-sizing:border-box;overflow:hidden}
89
- @keyframes sc-shine{0%{background-position:100% 50%}100%{background-position:0% 50%}}
90
- html.sc-dc-streaming .sc-placeholder,
91
- html.sc-dc-streaming .sc-interp.sc-missing{position:relative;
92
- background:color-mix(in srgb,currentColor 5%,transparent);
93
- border-color:transparent}
94
- html.sc-dc-streaming .sc-placeholder::before,
95
- html.sc-dc-streaming .sc-interp.sc-missing::before{content:'';
96
- position:absolute;inset:0;pointer-events:none;
97
- background:linear-gradient(90deg,rgba(217,119,87,0) 25%,rgba(247,225,211,.95) 37%,rgba(217,119,87,0) 63%);
98
- background-size:400% 100%;animation:sc-shine 1.4s ease infinite}
99
- html.sc-dc-streaming .sc-placeholder:nth-child(n+9 of .sc-placeholder)::before,
100
- html.sc-dc-streaming .sc-interp.sc-missing:nth-child(n+9 of .sc-interp.sc-missing)::before{animation:none;
101
- background:color-mix(in srgb,currentColor 8%,transparent)}
102
- .sc-placeholder-error{padding:4px 8px;font:11px/1.4 ui-monospace,monospace;
103
- color:rgba(0,0,0,.7);word-break:break-word}
104
- .sc-interp.sc-missing{display:inline-block;width:2em;height:1em;overflow:hidden;
105
- vertical-align:text-bottom;background:rgba(255,255,255,.3);border:1px solid rgba(0,0,0,.5);
106
- border-radius:2px;box-sizing:border-box;color:transparent;
107
- user-select:none}
108
- .sc-interp.sc-unresolved{font-family:ui-monospace,monospace;font-size:.85em;
109
- color:rgba(0,0,0,.5);background:rgba(0,0,0,.05);border-radius:3px;
110
- padding:0 3px}
111
- .sc-host.sc-has-error{position:relative}
112
- .sc-logic-error{position:absolute;top:8px;left:8px;z-index:2147483647;max-width:60ch;
113
- padding:6px 10px;background:#b00020;color:#fff;font:12px/1.4 ui-monospace,monospace;
114
- border-radius:4px;white-space:pre-wrap;pointer-events:none}
115
- /* Mirrors PRINT_BASELINE_CSS in apps/web deck-stage-export.ts \u2014 keep both
116
- in sync until dc-runtime regains a build step. */
117
- @media print {
118
- @page { margin: 0.5cm; }
119
- section, article, figure, table { break-inside: avoid; }
120
- *, *::before, *::after {
121
- print-color-adjust: exact; -webkit-print-color-adjust: exact;
122
- backdrop-filter: none !important; -webkit-backdrop-filter: none !important;
123
- animation-delay: -99s !important; animation-duration: .001s !important;
124
- animation-iteration-count: 1 !important; animation-fill-mode: both !important;
125
- animation-play-state: running !important; transition-duration: 0s !important;
126
- }
127
- }
128
- `;
129
- var FULL_PAGE_CSS = "html,body{height:100%;margin:0}#dc-root,#dc-root>.sc-host{height:100%}";
130
- function rootNameForDocument(doc, loc) {
131
- let bootPath = loc.pathname || "";
132
- if (!/\.dc\.html?$/i.test(safeDecode(bootPath))) {
133
- try {
134
- bootPath = new URL(doc.baseURI || "/").pathname;
135
- } catch {
136
- }
137
- }
138
- return dcNameFromPath(bootPath);
139
- }
140
- function safeDecode(s) {
141
- try {
142
- return decodeURIComponent(s);
143
- } catch {
144
- return s;
145
- }
146
- }
147
- function boot(runtime, doc = document) {
148
- const parsed = parseDcDocument(doc);
149
- if (!parsed) return null;
150
- const React = getReact();
151
- const rootName = rootNameForDocument(doc, location);
152
- runtime.markFetched(rootName);
153
- runtime.adoptParsed(rootName, parsed);
154
- fetch(location.href).then((res) => res.ok ? res.text() : "").then((t) => {
155
- const raw = t ? parseDcText(t) : null;
156
- if (raw?.template) runtime.updateHtml(rootName, raw.template);
157
- }).catch(() => {
158
- });
159
- const dc = doc.querySelector("x-dc");
160
- const hostEl = doc.createElement("div");
161
- hostEl.id = "dc-root";
162
- dc.replaceWith(hostEl);
163
- if (!parsed.preview) {
164
- const s = doc.createElement("style");
165
- s.textContent = FULL_PAGE_CSS;
166
- doc.head.appendChild(s);
167
- }
168
- const Root = runtime.getDC(rootName);
169
- const entry = runtime.registry.get(rootName);
170
- function StandaloneRoot() {
171
- const [, setTick] = React.useState(0);
172
- React.useEffect(() => {
173
- const sub = () => setTick((n) => n + 1);
174
- entry.subs.add(sub);
175
- return () => {
176
- entry.subs.delete(sub);
177
- };
178
- }, []);
179
- return h(Root, entry.propOverrides || null);
180
- }
181
- const ReactDOM = getReactDOM();
182
- if (ReactDOM.createRoot)
183
- ReactDOM.createRoot(hostEl).render(h(StandaloneRoot));
184
- else ReactDOM.render(h(StandaloneRoot), hostEl);
185
- return rootName;
186
- }
187
-
188
- // src/expr.ts
189
- var IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*/;
190
- var NUMBER_RE = /^-?\d+(\.\d+)?$/;
191
- function resolve(vals, src) {
192
- const expr = String(src).trim();
193
- if (!expr) return void 0;
194
- if (expr[0] === "(" && expr[expr.length - 1] === ")" && parensWrapWhole(expr)) {
195
- return resolve(vals, expr.slice(1, -1));
196
- }
197
- const eq = findTopLevelEquality(expr);
198
- if (eq) {
199
- const lv = resolve(vals, expr.slice(0, eq.index));
200
- const rv = resolve(vals, expr.slice(eq.index + eq.op.length));
201
- switch (eq.op) {
202
- case "===":
203
- return lv === rv;
204
- case "!==":
205
- return lv !== rv;
206
- case "==":
207
- return lv == rv;
208
- default:
209
- return lv != rv;
210
- }
211
- }
212
- if (expr[0] === "!") return !resolve(vals, expr.slice(1));
213
- if (expr === "true") return true;
214
- if (expr === "false") return false;
215
- if (expr === "null") return null;
216
- if (expr === "undefined") return void 0;
217
- if (NUMBER_RE.test(expr)) return Number(expr);
218
- if (expr.length >= 2 && (expr[0] === '"' || expr[0] === "'") && expr[expr.length - 1] === expr[0]) {
219
- return expr.slice(1, -1);
220
- }
221
- return resolvePath(vals, expr);
222
- }
223
- function parensWrapWhole(expr) {
224
- let depth = 0;
225
- for (let i = 0; i < expr.length - 1; i++) {
226
- if (expr[i] === "(") depth++;
227
- else if (expr[i] === ")") {
228
- depth--;
229
- if (depth === 0) return false;
230
- }
231
- }
232
- return true;
233
- }
234
- function findTopLevelEquality(expr) {
235
- let depth = 0;
236
- for (let i = 0; i < expr.length; i++) {
237
- const c = expr[i];
238
- if (c === "[" || c === "(") depth++;
239
- else if (c === "]" || c === ")") depth--;
240
- else if (depth === 0 && (c === "=" || c === "!") && expr[i + 1] === "=") {
241
- if (i > 0 && (expr[i - 1] === "=" || expr[i - 1] === "!")) continue;
242
- if (!expr.slice(0, i).trim()) continue;
243
- const op = expr[i + 2] === "=" ? c + "==" : c + "=";
244
- return { index: i, op };
245
- }
246
- }
247
- return null;
248
- }
249
- function resolvePath(vals, expr) {
250
- const head = expr.match(IDENT_RE);
251
- if (!head) return void 0;
252
- let cur = vals == null ? void 0 : vals[head[0]];
253
- let i = head[0].length;
254
- while (i < expr.length) {
255
- if (expr[i] === ".") {
256
- const m = expr.slice(i + 1).match(IDENT_RE) || expr.slice(i + 1).match(/^\d+/);
257
- if (!m) return void 0;
258
- cur = cur == null ? void 0 : cur[m[0]];
259
- i += 1 + m[0].length;
260
- } else if (expr[i] === "[") {
261
- let depth = 1;
262
- let j = i + 1;
263
- while (j < expr.length && depth > 0) {
264
- if (expr[j] === "[") depth++;
265
- else if (expr[j] === "]") {
266
- depth--;
267
- if (depth === 0) break;
268
- }
269
- j++;
270
- }
271
- if (depth !== 0) return void 0;
272
- const key = resolve(vals, expr.slice(i + 1, j));
273
- cur = cur == null ? void 0 : cur[key];
274
- i = j + 1;
275
- } else {
276
- return void 0;
277
- }
278
- }
279
- return cur;
280
- }
281
-
282
- // src/encode.ts
283
- var CAMEL_ATTR = "sc-camel-";
284
- var RAW_WRAP = {
285
- select: "sc-raw-select",
286
- table: "sc-raw-table",
287
- tbody: "sc-raw-tbody",
288
- thead: "sc-raw-thead",
289
- tfoot: "sc-raw-tfoot",
290
- tr: "sc-raw-tr",
291
- td: "sc-raw-td",
292
- th: "sc-raw-th",
293
- caption: "sc-raw-caption"
294
- };
295
- var RAW_UNWRAP = Object.fromEntries(
296
- Object.entries(RAW_WRAP).map(([k, v]) => [v, k])
297
- );
298
- var EVENT_MAP = {
299
- onclick: "onClick",
300
- onchange: "onChange",
301
- oninput: "onInput",
302
- onsubmit: "onSubmit",
303
- onkeydown: "onKeyDown",
304
- onkeyup: "onKeyUp",
305
- onkeypress: "onKeyPress",
306
- onmousedown: "onMouseDown",
307
- onmouseup: "onMouseUp",
308
- onmouseenter: "onMouseEnter",
309
- onmouseleave: "onMouseLeave",
310
- onfocus: "onFocus",
311
- onblur: "onBlur",
312
- ondoubleclick: "onDoubleClick",
313
- oncontextmenu: "onContextMenu"
314
- };
315
- var ATTRS = `(?:[^>"']|"[^"]*"|'[^']*')*`;
316
- var IMPORT_SELF_CLOSE_RE = new RegExp(
317
- "<(x-import|dc-import)(" + ATTRS + ")/>",
318
- "gi"
319
- );
320
- var CAMEL_ATTR_RE = /(\s)([a-z]+[A-Z][A-Za-z0-9]*)(\s*=)/g;
321
- function encodeCase(html) {
322
- html = html.replace(
323
- IMPORT_SELF_CLOSE_RE,
324
- (_, t, a) => "<" + t + a + "></" + t + ">"
325
- );
326
- html = html.replace(/<helmet(\s|>)/gi, "<sc-helmet$1");
327
- html = html.replace(/<\/helmet\s*>/gi, "</sc-helmet>");
328
- html = html.replace(
329
- CAMEL_ATTR_RE,
330
- (_, sp, name, eq) => sp + CAMEL_ATTR + name.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase()) + eq
331
- );
332
- for (const [real, alias] of Object.entries(RAW_WRAP)) {
333
- html = html.replace(
334
- new RegExp("(</?)" + real + "(?=[\\s>])", "gi"),
335
- "$1" + alias
336
- );
337
- }
338
- return html;
339
- }
340
- function kebabToCamel(s) {
341
- return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
342
- }
343
- function cssToObj(css) {
344
- const o = {};
345
- for (const decl of css.split(";")) {
346
- const i = decl.indexOf(":");
347
- if (i < 0) continue;
348
- const prop = decl.slice(0, i).trim();
349
- o[prop.startsWith("--") ? prop : kebabToCamel(prop)] = decl.slice(i + 1).trim();
350
- }
351
- return o;
352
- }
353
- function compileAttr(raw) {
354
- const whole = raw.match(/^\s*\{\{([\s\S]+?)\}\}\s*$/);
355
- if (whole) {
356
- const path = whole[1];
357
- return (vals) => resolve(vals, path);
358
- }
359
- if (raw.includes("{{")) {
360
- const parts = raw.split(/\{\{([\s\S]+?)\}\}/g);
361
- return (vals) => parts.map((s, i) => i & 1 ? resolve(vals, s) ?? "" : s).join("");
362
- }
363
- return () => raw;
364
- }
365
-
366
- // src/compile.ts
367
- function collectProps(node, isComponent, host) {
368
- const propGetters = [];
369
- const pseudoClasses = [];
370
- let hintSize = null;
371
- for (const { name, value } of [...node.attributes]) {
372
- if (name === "sc-name" || name === "data-dc-tpl") continue;
373
- let key = name;
374
- if (key.startsWith(CAMEL_ATTR))
375
- key = kebabToCamel(key.slice(CAMEL_ATTR.length));
376
- if (key === "hint-size") {
377
- hintSize = value;
378
- continue;
379
- }
380
- if (key.startsWith("style-")) {
381
- pseudoClasses.push(host.pseudoClass(key.slice(6), value));
382
- continue;
383
- }
384
- if (isComponent) {
385
- if (key.includes("-")) key = kebabToCamel(key);
386
- } else {
387
- if (key === "class") key = "className";
388
- else if (key === "for") key = "htmlFor";
389
- else if (key.startsWith("on"))
390
- key = EVENT_MAP[key] || "on" + key[2].toUpperCase() + key.slice(3);
391
- }
392
- propGetters.push([key, compileAttr(value)]);
393
- }
394
- return { propGetters, pseudoClasses, hintSize };
395
- }
396
- var HOST_STYLE_PROPS = /* @__PURE__ */ new Set([
397
- "position",
398
- "left",
399
- "right",
400
- "top",
401
- "bottom",
402
- "inset",
403
- "width",
404
- "height",
405
- "z-index",
406
- "transform"
407
- ]);
408
- function hostPositionStyle(style) {
409
- const all = typeof style === "string" ? cssToObj(style) : style != null && typeof style === "object" ? style : null;
410
- if (!all) return void 0;
411
- const out = {};
412
- for (const [k, v] of Object.entries(all)) {
413
- const kebab = k.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase());
414
- if (HOST_STYLE_PROPS.has(kebab)) out[k] = v;
415
- }
416
- return Object.keys(out).length ? out : void 0;
417
- }
418
- function compileTemplate(html, host) {
419
- const tpl = document.createElement("template");
420
- //! nosemgrep: direct-inner-html-assignment
421
- tpl.innerHTML = encodeCase(html);
422
- let tplN = 0;
423
- (function stamp(node) {
424
- if (node.nodeType === Node.ELEMENT_NODE) {
425
- node.setAttribute("data-dc-tpl", String(tplN++));
426
- }
427
- for (const c of node.childNodes) stamp(c);
428
- })(tpl.content);
429
- const builders = walkChildren(tpl.content, host);
430
- const render = ((vals, ctx) => builders.map((b, i) => b(vals || {}, ctx, i)));
431
- render.__annotated = tpl.innerHTML;
432
- return render;
433
- }
434
- function walkChildren(node, host) {
435
- return [...node.childNodes].map((c) => walk(c, host)).filter((b) => b != null);
436
- }
437
- function walk(node, host) {
438
- if (node.nodeType === Node.TEXT_NODE) return walkText(node);
439
- if (node.nodeType !== Node.ELEMENT_NODE) return null;
440
- const el = node;
441
- const tag = el.tagName.toLowerCase();
442
- if (tag === "sc-for") return walkFor(el, host);
443
- if (tag === "sc-if") return walkIf(el, host);
444
- if (tag === "x-import") return walkXImport(el, host);
445
- if (tag === "sc-helmet") return host.helmet(el);
446
- if (tag === "dc-import") return walkComponent(el, host);
447
- return walkElement(el, host);
448
- }
449
- var warnedHoles = /* @__PURE__ */ new Set();
450
- function warnUnresolved(ctx, what) {
451
- const key = (ctx?.__name || "?") + "\0" + what;
452
- if (warnedHoles.has(key)) return;
453
- warnedHoles.add(key);
454
- console.warn("[dc-runtime] " + (ctx?.__name || "template") + ": " + what);
455
- }
456
- function walkText(node) {
457
- const txt = node.nodeValue ?? "";
458
- if (!txt.includes("{{")) {
459
- if (!txt.trim() && !txt.includes(" ")) return null;
460
- return () => txt;
461
- }
462
- const parts = txt.split(/\{\{([\s\S]+?)\}\}/g);
463
- return (vals, ctx, key) => h(
464
- getReact().Fragment,
465
- { key },
466
- ...parts.map((p, i) => {
467
- if (!(i & 1)) return p;
468
- const v = resolve(vals, p);
469
- if (v === void 0) {
470
- if (!ctx?.__streamingNow) {
471
- if (document.body?.hasAttribute("data-dc-editor-on")) {
472
- return h(
473
- "span",
474
- { key: i, className: "sc-interp sc-unresolved" },
475
- "{{ " + p.trim() + " }}"
476
- );
477
- }
478
- warnUnresolved(
479
- ctx,
480
- "{{ " + p.trim() + " }} never resolved \u2014 rendered as empty"
481
- );
482
- return null;
483
- }
484
- return h(
485
- "span",
486
- { key: i, className: "sc-interp sc-missing" },
487
- p.trim()
488
- );
489
- }
490
- if (getReact().isValidElement(v) || Array.isArray(v)) {
491
- return h(getReact().Fragment, { key: i }, v);
492
- }
493
- if (v === null || typeof v === "boolean") return null;
494
- return h("span", { key: i, className: "sc-interp" }, String(v));
495
- })
496
- );
497
- }
498
- function walkFor(el, host) {
499
- const listGet = compileAttr(el.getAttribute("list") || "");
500
- const asName = el.getAttribute("as") || "item";
501
- const hintN = parseInt(el.getAttribute("hint-placeholder-count") || "0", 10);
502
- const kids = walkChildren(el, host);
503
- const listSrc = el.getAttribute("list") || "";
504
- return (vals, ctx, key) => {
505
- let list = listGet(vals);
506
- if (!Array.isArray(list)) {
507
- if (!ctx?.__streamingNow) {
508
- if (list !== void 0 && list !== null) {
509
- warnUnresolved(
510
- ctx,
511
- 'sc-for list="' + listSrc + '" is not an array (' + typeof list + ")"
512
- );
513
- }
514
- list = [];
515
- } else {
516
- list = hintN > 0 ? Array(hintN).fill(void 0) : [];
517
- }
518
- }
519
- return h(
520
- getReact().Fragment,
521
- { key },
522
- list.map((item, i) => {
523
- const sub = { ...vals, [asName]: item, $index: i };
524
- return h(
525
- getReact().Fragment,
526
- { key: i },
527
- kids.map((b, j) => b(sub, ctx, j))
528
- );
529
- })
530
- );
531
- };
532
- }
533
- function walkIf(el, host) {
534
- const valGet = compileAttr(el.getAttribute("value") || "");
535
- const hintRaw = el.getAttribute("hint-placeholder-val");
536
- const hintGet = hintRaw != null ? compileAttr(hintRaw) : null;
537
- const kids = walkChildren(el, host);
538
- return (vals, ctx, key) => {
539
- let v = valGet(vals);
540
- if (v === void 0 && hintGet && ctx?.__streamingNow) v = hintGet(vals);
541
- return v ? h(
542
- getReact().Fragment,
543
- { key },
544
- kids.map((b, j) => b(vals, ctx, j))
545
- ) : null;
546
- };
547
- }
548
- function walkComponent(el, host) {
549
- const name = el.getAttribute("name") || el.getAttribute("component") || "";
550
- el.removeAttribute("name");
551
- el.removeAttribute("component");
552
- const tplId = el.getAttribute("data-dc-tpl");
553
- const styleRaw = el.getAttribute("style");
554
- el.removeAttribute("style");
555
- const styleGet = styleRaw != null ? compileAttr(styleRaw) : null;
556
- const { propGetters, hintSize } = collectProps(el, true, host);
557
- const kids = walkChildren(el, host);
558
- return (vals, ctx, key) => {
559
- const props = {
560
- key,
561
- __hintSize: hintSize,
562
- __tplId: tplId,
563
- __hostStyle: styleGet ? hostPositionStyle(styleGet(vals)) : void 0
564
- };
565
- for (const [k, g] of propGetters) props[k] = g(vals);
566
- if (kids.length) props.children = kids.map((b, j) => b(vals, ctx, j));
567
- return h(host.component(name), props);
568
- };
569
- }
570
- function walkXImport(el, host) {
571
- const globalNameGet = compileAttr(
572
- el.getAttribute("component-from-global-scope") || ""
573
- );
574
- const exportNameGet = compileAttr(
575
- el.getAttribute("component") || el.getAttribute("name") || ""
576
- );
577
- const url = el.getAttribute("from") || el.getAttribute("src") || el.getAttribute("import") || "";
578
- const kind = /\.(jsx|tsx)(\?|#|$)/i.test(url) ? "jsx" : "js";
579
- const tplId = el.getAttribute("data-dc-tpl");
580
- const styleRaw = el.getAttribute("style");
581
- el.removeAttribute("style");
582
- const styleGet = styleRaw != null ? compileAttr(styleRaw) : null;
583
- const wrap = tplId != null || styleGet != null;
584
- const { propGetters, hintSize } = collectProps(el, true, host);
585
- const hasContent = el.children.length > 0 || !!(el.textContent || "").trim();
586
- const kids = hasContent ? walkChildren(el, host) : [];
587
- const urlBindable = url.includes("{{");
588
- if (url && !urlBindable) host.loadExternal(kind, url);
589
- const evalName = (g, vals) => {
590
- const v = g(vals);
591
- const s = v == null ? "" : String(v);
592
- return s.includes("{{") ? "" : s;
593
- };
594
- return (vals, ctx, key) => {
595
- const globalName = evalName(globalNameGet, vals);
596
- const name = globalName || evalName(exportNameGet, vals);
597
- const C = !name || urlBindable ? null : globalName ? host.resolveExternalGlobal(url, globalName) : host.resolveExternal(url, name);
598
- const hostStyle = styleGet ? hostPositionStyle(styleGet(vals)) : void 0;
599
- const wrapper = wrap ? {
600
- key,
601
- className: "sc-host-x",
602
- "data-dc-tpl": tplId,
603
- style: hostStyle || { display: "contents" }
604
- } : null;
605
- if (!C) {
606
- const error = urlBindable ? "x-import `from` cannot contain {{ \u2026 }} \u2014 module URLs are resolved at parse time; use a literal URL" : host.resolveExternalError(url, name);
607
- const ph = host.placeholder({
608
- key: wrapper ? void 0 : key,
609
- name,
610
- hintSize,
611
- error
612
- });
613
- return wrapper ? h("div", wrapper, ph) : ph;
614
- }
615
- const props = wrapper ? {} : { key };
616
- let unresolvedHole = false;
617
- for (const [k, g] of propGetters) {
618
- if (k === "component" || k === "componentFromGlobalScope" || k === "name" || k === "from" || k === "src" || k === "import") {
619
- continue;
620
- }
621
- const v = g(vals);
622
- if (v === void 0) unresolvedHole = true;
623
- props[k] = v;
624
- }
625
- if (unresolvedHole && ctx?.__htmlStreamingNow) {
626
- const ph = host.placeholder({
627
- key: wrapper ? void 0 : key,
628
- name,
629
- hintSize,
630
- error: null
631
- });
632
- return wrapper ? h("div", wrapper, ph) : ph;
633
- }
634
- if (kids.length) props.children = kids.map((b, j) => b(vals, ctx, j));
635
- return wrapper ? h("div", wrapper, h(C, props)) : h(C, props);
636
- };
637
- }
638
- function walkElement(el, host) {
639
- const realTag = RAW_UNWRAP[el.localName] || el.localName;
640
- const tplId = el.getAttribute("data-dc-tpl");
641
- const { propGetters, pseudoClasses } = collectProps(el, false, host);
642
- const kids = walkChildren(el, host);
643
- return (vals, ctx, key) => {
644
- const props = { key, "data-dc-tpl": tplId };
645
- for (const [k, g] of propGetters) {
646
- let v = g(vals);
647
- if (k === "style" && typeof v === "string") v = cssToObj(v);
648
- if ((k === "value" || k === "checked") && v === void 0) {
649
- v = k === "checked" ? false : "";
650
- }
651
- props[k] = v;
652
- }
653
- if (pseudoClasses.length) {
654
- props.className = [props.className, ...pseudoClasses].filter(Boolean).join(" ");
655
- }
656
- return h(realTag, props, ...kids.map((b, j) => b(vals, ctx, j)));
657
- };
658
- }
659
-
660
- // src/logic.ts
661
- var StreamableLogic = class {
662
- constructor(props) {
663
- __publicField(this, "props");
664
- __publicField(this, "state", {});
665
- /** Back-pointer to the wrapper component, installed after construction. */
666
- __publicField(this, "__host");
667
- this.props = props || {};
668
- }
669
- setState(update, cb) {
670
- this.__host && this.__host.__setLogicState(update, cb);
671
- }
672
- forceUpdate() {
673
- this.__host && this.__host.forceUpdate();
674
- }
675
- componentDidMount() {
676
- }
677
- componentDidUpdate(_prevProps) {
678
- }
679
- componentWillUnmount() {
680
- }
681
- /** The flat object the template renders against (merged over props). */
682
- renderVals() {
683
- return {};
684
- }
685
- };
686
- function evalDcLogic(src) {
687
- //! nosemgrep: eval-and-function-constructor
688
- const fn = new Function(
689
- "DCLogic",
690
- "StreamableLogic",
691
- "React",
692
- src + '\n;return (typeof Component!=="undefined"&&Component)||undefined;'
693
- );
694
- return fn(StreamableLogic, StreamableLogic, getReact());
695
- }
696
-
697
- // src/component.ts
698
- function shallowEqual(a, b) {
699
- if (!b) return false;
700
- const ak = Object.keys(a).filter((k) => k !== "children");
701
- const bk = Object.keys(b).filter((k) => k !== "children");
702
- if (ak.length !== bk.length) return false;
703
- for (const k of ak) if (a[k] !== b[k]) return false;
704
- return true;
705
- }
706
- function Placeholder({
707
- name,
708
- hintSize,
709
- streaming,
710
- error
711
- }) {
712
- const [w, hgt] = (hintSize || "100%,60px").split(",");
713
- return h(
714
- "div",
715
- {
716
- className: "sc-placeholder" + (streaming ? " sc-streaming" : ""),
717
- style: { width: w.trim(), height: hgt && hgt.trim() },
718
- title: name
719
- },
720
- error ? h(
721
- "div",
722
- { className: "sc-placeholder-error" },
723
- (name ? name + ": " : "") + error
724
- ) : null
725
- );
726
- }
727
- function hintToMin(hint) {
728
- if (!hint) return void 0;
729
- const [w, hgt] = hint.split(",");
730
- return { minWidth: w.trim(), minHeight: hgt && hgt.trim() };
731
- }
732
- function createComponentFactory(registry, ensureFetched) {
733
- const React = getReact();
734
- const AncestorContext = React.createContext([]);
735
- class StreamableComponent extends React.Component {
736
- constructor(props) {
737
- super(props);
738
- __publicField(this, "__name");
739
- __publicField(this, "__sub");
740
- __publicField(this, "__needsDidMount", false);
741
- /** Snapshot of the registry's streaming flags taken at render time —
742
- * builders read it off the RenderCtx (this) to pick placeholder vs
743
- * render-nothing for unresolved values. */
744
- __publicField(this, "__streamingNow", false);
745
- __publicField(this, "__htmlStreamingNow", false);
746
- /** When a construct throws, remember the (class, registry.ver, props)
747
- * triple so render-time reconcile doesn't re-attempt it on every parent
748
- * re-render. A registry bump (new class, template, external module
749
- * resolving via bumpAll) changes `ver` and breaks the memo so an
750
- * env-dependent constructor can self-heal. */
751
- __publicField(this, "__failedLogic", null);
752
- __publicField(this, "__failedUserProps", null);
753
- __publicField(this, "__failedVer", -1);
754
- /** Per-instance constructor error — kept here (not on the registry entry)
755
- * so one instance's successful construct can't hide a sibling's failure,
756
- * and a construct can never wipe an eval error `updateJs` recorded on
757
- * `r.logicError`. */
758
- __publicField(this, "__ctorError", null);
759
- __publicField(this, "logic");
760
- this.__name = props.__name;
761
- this.state = { __v: 0, __err: null };
762
- this.__sub = () => {
763
- if (this.state.__err) this.setState({ __err: null });
764
- this.forceUpdate();
765
- };
766
- this.__makeLogic(registry.get(this.__name).Logic, null);
767
- ensureFetched(this.__name);
768
- }
769
- /** Error-boundary hook: a render crash anywhere in this DC's subtree
770
- * (its own template, an x-import'd component, a child DC without its
771
- * own deeper boundary) lands here instead of unmounting the page. */
772
- static getDerivedStateFromError(e) {
773
- return { __err: e instanceof Error && e.message ? e.message : String(e) };
774
- }
775
- componentDidCatch(e, info) {
776
- console.error(
777
- "[dc-runtime] render error in <" + this.__name + ">:",
778
- e,
779
- info?.componentStack || ""
780
- );
781
- }
782
- /** Instantiate the logic class (or the no-op base) and adopt `prevState`
783
- * over its initial state — used both at mount and on hot-swap. */
784
- __makeLogic(Logic, prevState) {
785
- const L = Logic || StreamableLogic;
786
- try {
787
- this.logic = new L(this.__userProps());
788
- this.__failedLogic = null;
789
- this.__failedUserProps = null;
790
- this.__ctorError = null;
791
- } catch (e) {
792
- console.error(e);
793
- this.__failedLogic = Logic;
794
- this.__failedUserProps = this.__userProps();
795
- this.__failedVer = registry.get(this.__name).ver;
796
- this.__ctorError = this.__name + ": " + (e instanceof Error && e.message ? e.message : String(e));
797
- this.logic = new StreamableLogic(
798
- this.__userProps()
799
- );
800
- }
801
- this.logic.__host = this;
802
- if (prevState)
803
- this.logic.state = { ...this.logic.state || {}, ...prevState };
804
- }
805
- /** The props the author's logic + template see — internal __-prefixed
806
- * wiring stripped. */
807
- __userProps() {
808
- const { __name, __hintSize, __tplId, __hostStyle, ...rest } = this.props;
809
- return rest;
810
- }
811
- __setLogicState(update, cb) {
812
- const prev = this.logic.state;
813
- const patch = typeof update === "function" ? update(prev) : update;
814
- this.logic.state = { ...prev, ...patch };
815
- this.setState((s) => ({ __v: s.__v + 1 }), cb);
816
- }
817
- /** Swap the logic instance when the registry's Logic class changed
818
- * (streaming completion, hot reload). State carries over; didMount
819
- * re-fires after the swap commits so refs exist. */
820
- __reconcileLogic() {
821
- const r = registry.get(this.__name);
822
- const Next = r.Logic;
823
- const Cur = this.logic.constructor;
824
- if (Next === Cur || !Next && Cur === StreamableLogic || Next === this.__failedLogic && r.ver === this.__failedVer && shallowEqual(this.__userProps(), this.__failedUserProps)) {
825
- return;
826
- }
827
- if (!this.__needsDidMount) {
828
- try {
829
- this.logic.componentWillUnmount();
830
- } catch (e) {
831
- console.error(e);
832
- }
833
- }
834
- this.__makeLogic(Next, this.logic.state);
835
- this.__needsDidMount = true;
836
- }
837
- componentDidMount() {
838
- registry.get(this.__name).subs.add(this.__sub);
839
- try {
840
- this.logic.componentDidMount();
841
- } catch (e) {
842
- console.error(e);
843
- }
844
- }
845
- componentDidUpdate(prevProps) {
846
- this.logic.props = this.__userProps();
847
- if (this.__needsDidMount) {
848
- if (this.state.__err || !registry.get(this.__name).tpl) return;
849
- this.__needsDidMount = false;
850
- try {
851
- this.logic.componentDidMount();
852
- } catch (e) {
853
- console.error(e);
854
- }
855
- } else {
856
- try {
857
- this.logic.componentDidUpdate(prevProps);
858
- } catch (e) {
859
- console.error(e);
860
- }
861
- }
862
- }
863
- componentWillUnmount() {
864
- registry.get(this.__name).subs.delete(this.__sub);
865
- if (!this.__needsDidMount) {
866
- try {
867
- this.logic.componentWillUnmount();
868
- } catch (e) {
869
- console.error(e);
870
- }
871
- }
872
- }
873
- render() {
874
- const r = registry.get(this.__name);
875
- const cls = "sc-host" + (r.htmlStreaming ? " sc-streaming-html" : "") + (r.jsStreaming ? " sc-streaming-js" : "");
876
- const hintStyle = r.htmlStreaming ? hintToMin(this.props.__hintSize) : void 0;
877
- const hostStyle = this.props.__hostStyle || hintStyle ? { ...hintStyle || {}, ...this.props.__hostStyle || {} } : void 0;
878
- const hostBase = {
879
- className: cls,
880
- style: hostStyle,
881
- "data-sc-name": this.__name,
882
- "data-dc-tpl": this.props.__tplId
883
- };
884
- const chain = Array.isArray(this.context) ? this.context : [];
885
- if (chain.includes(this.__name)) {
886
- const cycle = [
887
- ...chain.slice(chain.indexOf(this.__name)),
888
- this.__name
889
- ].join(" \u2192 ");
890
- return h(
891
- "div",
892
- { ...hostBase, className: cls + " sc-has-error" },
893
- h(Placeholder, {
894
- name: this.__name,
895
- hintSize: this.props.__hintSize,
896
- error: "circular import: " + cycle
897
- })
898
- );
899
- }
900
- if (this.state.__err) {
901
- return h(
902
- "div",
903
- { ...hostBase, className: cls + " sc-has-error" },
904
- h(
905
- "div",
906
- { className: "sc-logic-error" },
907
- this.__name + ": " + this.state.__err
908
- ),
909
- h(Placeholder, {
910
- name: this.__name,
911
- hintSize: this.props.__hintSize,
912
- error: this.state.__err
913
- })
914
- );
915
- }
916
- this.__reconcileLogic();
917
- if (!r.tpl) {
918
- return h(
919
- "div",
920
- hostBase,
921
- h(Placeholder, { name: this.__name, hintSize: this.props.__hintSize })
922
- );
923
- }
924
- const userProps = this.__userProps();
925
- this.logic.props = userProps;
926
- let vals = userProps;
927
- let renderErr = r.logicError || this.__ctorError;
928
- try {
929
- vals = { ...userProps, ...this.logic.renderVals() || {} };
930
- } catch (e) {
931
- console.error(e);
932
- renderErr = this.__name + ".renderVals(): " + (e instanceof Error && e.message ? e.message : String(e));
933
- }
934
- this.__streamingNow = !!(r.htmlStreaming || r.jsStreaming);
935
- this.__htmlStreamingNow = !!r.htmlStreaming;
936
- return h(
937
- "div",
938
- { ...hostBase, className: cls + (renderErr ? " sc-has-error" : "") },
939
- renderErr && h("div", { className: "sc-logic-error" }, renderErr),
940
- h(
941
- AncestorContext.Provider,
942
- { value: [...chain, this.__name] },
943
- r.tpl(vals, this)
944
- )
945
- );
946
- }
947
- }
948
- __publicField(StreamableComponent, "contextType", AncestorContext);
949
- const named = /* @__PURE__ */ new Map();
950
- function getDC(name) {
951
- const hit = named.get(name);
952
- if (hit) return hit;
953
- function Dispatcher(p) {
954
- const [, setTick] = React.useState(0);
955
- React.useEffect(() => {
956
- const sub = () => setTick((n) => n + 1);
957
- registry.get(name).subs.add(sub);
958
- return () => {
959
- registry.get(name).subs.delete(sub);
960
- };
961
- }, []);
962
- ensureFetched(name);
963
- return h(StreamableComponent, { ...p, __name: name });
964
- }
965
- Dispatcher.displayName = name;
966
- named.set(name, Dispatcher);
967
- return Dispatcher;
968
- }
969
- return {
970
- getDC,
971
- StreamableComponent
972
- };
973
- }
974
-
975
- // src/external.ts
976
- var isCustomElementName = (n) => !n.includes(".") && n.includes("-");
977
- function isRenderableType(g) {
978
- if (typeof g === "function") return !isElementClass(g);
979
- return typeof g === "object" && g !== null && typeof g.$$typeof === "symbol";
980
- }
981
- function resolveDottedPath(root, name) {
982
- let cur = root;
983
- for (const seg of name.split(".")) {
984
- if (cur == null) return void 0;
985
- cur = cur[seg];
986
- }
987
- return cur;
988
- }
989
- var BABEL_URL = "https://unpkg.com/@babel/standalone@7.26.4/babel.min.js";
990
- var GLOBAL_POLL_INTERVAL_MS = 50;
991
- var GLOBAL_POLL_TIMEOUT_MS = 3e4;
992
- function createExternalModules(onResolved) {
993
- const cache = /* @__PURE__ */ new Map();
994
- let babelLoading = null;
995
- const reportedMissing = /* @__PURE__ */ new Map();
996
- const polling = /* @__PURE__ */ new Set();
997
- function ensureBabel() {
998
- if (window.Babel) return Promise.resolve();
999
- if (babelLoading) return babelLoading;
1000
- babelLoading = new Promise((res, rej) => {
1001
- const s = document.createElement("script");
1002
- s.src = BABEL_URL;
1003
- s.crossOrigin = "anonymous";
1004
- s.onload = () => res();
1005
- s.onerror = rej;
1006
- document.head.appendChild(s);
1007
- });
1008
- return babelLoading;
1009
- }
1010
- function load(kind, url) {
1011
- if (cache.has(url)) return;
1012
- cache.set(url, null);
1013
- console.info("[dc-runtime] x-import: loading", url, "(" + kind + ")");
1014
- const ready = kind === "jsx" ? ensureBabel() : Promise.resolve();
1015
- ready.then(() => fetch(url)).then((r) => {
1016
- if (!r.ok) throw new Error("HTTP " + r.status);
1017
- return r.text();
1018
- }).then((src) => {
1019
- const code = kind === "jsx" ? window.Babel.transform(src, {
1020
- filename: url,
1021
- presets: ["react", "typescript"]
1022
- }).code : src;
1023
- const module = { exports: {} };
1024
- const before = new Set(Object.keys(window));
1025
- //! nosemgrep: eval-and-function-constructor
1026
- new Function("React", "module", "exports", "require", code)(
1027
- getReact(),
1028
- module,
1029
- module.exports,
1030
- () => ({})
1031
- );
1032
- const globals = {};
1033
- for (const k of Object.keys(window)) {
1034
- if (!before.has(k) && typeof window[k] === "function") {
1035
- globals[k] = window[k];
1036
- }
1037
- }
1038
- cache.set(url, { mod: module.exports, globals });
1039
- console.info(
1040
- "[dc-runtime] x-import: loaded",
1041
- url,
1042
- "\u2014 exports:",
1043
- Object.keys(module.exports),
1044
- "window globals:",
1045
- Object.keys(globals)
1046
- );
1047
- onResolved();
1048
- }).catch((e) => {
1049
- cache.set(url, {
1050
- mod: {},
1051
- globals: {},
1052
- error: "failed to load: " + (e instanceof Error && e.message ? e.message : String(e))
1053
- });
1054
- console.error(
1055
- "[dc-runtime] x-import: FAILED to load",
1056
- url,
1057
- "(" + kind + ")",
1058
- e
1059
- );
1060
- onResolved();
1061
- });
1062
- }
1063
- function resolve2(url, name) {
1064
- const entry = cache.get(url);
1065
- if (!entry) return null;
1066
- const { mod, globals } = entry;
1067
- const C = mod && mod[name] || globals && globals[name] || typeof window !== "undefined" && window[name] || mod && mod.default;
1068
- if (typeof C === "function") return C;
1069
- const key = url + "\0" + name;
1070
- if (!reportedMissing.has(key)) {
1071
- reportedMissing.set(
1072
- key,
1073
- entry.error || 'no export named "' + name + '" (has: ' + Object.keys(mod).join(", ") + ")"
1074
- );
1075
- console.error(
1076
- "[dc-runtime] x-import: module",
1077
- url,
1078
- "loaded but has no component named",
1079
- JSON.stringify(name),
1080
- "\u2014 available exports:",
1081
- Object.keys(mod),
1082
- "window globals:",
1083
- Object.keys(globals),
1084
- ". The module must `module.exports = {" + name + "}` or set `window." + name + "`."
1085
- );
1086
- }
1087
- return null;
1088
- }
1089
- function waitForGlobal(name) {
1090
- if (polling.has(name)) return;
1091
- polling.add(name);
1092
- const started = Date.now();
1093
- const isCE = isCustomElementName(name);
1094
- const tick = () => {
1095
- const found = isCE ? customElements.get(name) : isRenderableType(resolveDottedPath(window, name));
1096
- if (found) {
1097
- polling.delete(name);
1098
- onResolved();
1099
- return;
1100
- }
1101
- if (Date.now() - started >= GLOBAL_POLL_TIMEOUT_MS) {
1102
- console.warn(
1103
- "[dc-runtime] x-import: global",
1104
- JSON.stringify(name),
1105
- "never appeared on window after " + GLOBAL_POLL_TIMEOUT_MS + "ms"
1106
- );
1107
- return;
1108
- }
1109
- setTimeout(tick, GLOBAL_POLL_INTERVAL_MS);
1110
- };
1111
- setTimeout(tick, GLOBAL_POLL_INTERVAL_MS);
1112
- }
1113
- function resolveGlobal(url, name) {
1114
- const isCE = isCustomElementName(name);
1115
- if (!url) {
1116
- if (isCE) {
1117
- if (customElements.get(name)) return name;
1118
- waitForGlobal(name);
1119
- return null;
1120
- }
1121
- const g2 = resolveDottedPath(window, name);
1122
- if (isRenderableType(g2)) return g2;
1123
- waitForGlobal(name);
1124
- return null;
1125
- }
1126
- const entry = cache.get(url);
1127
- if (!entry) return null;
1128
- if (isCE && customElements.get(name)) return name;
1129
- const g = entry.globals[name] ?? resolveDottedPath(window, name);
1130
- if (isRenderableType(g)) return g;
1131
- if (name.includes(".")) return null;
1132
- const key = url + "\0global\0" + name;
1133
- if (!reportedMissing.has(key)) {
1134
- reportedMissing.set(key, null);
1135
- if (isCE && !customElements.get(name)) {
1136
- console.warn(
1137
- "[dc-runtime] x-import:",
1138
- url,
1139
- "loaded but no custom element",
1140
- JSON.stringify(name),
1141
- "is registered and window." + name + " is not a function \u2014 rendering <" + name + "> as an unknown element."
1142
- );
1143
- }
1144
- }
1145
- return name;
1146
- }
1147
- function getError(url, name) {
1148
- const entry = cache.get(url);
1149
- if (entry?.error) return entry.error;
1150
- return reportedMissing.get(url + "\0" + name) || null;
1151
- }
1152
- return { load, resolve: resolve2, resolveGlobal, getError };
1153
- }
1154
- function isElementClass(g) {
1155
- try {
1156
- return typeof g === "function" && typeof HTMLElement !== "undefined" && g.prototype instanceof HTMLElement;
1157
- } catch {
1158
- return false;
1159
- }
1160
- }
1161
-
1162
- // src/helmet.ts
1163
- function createHelmetManager(doc, isStreaming) {
1164
- const mounted = /* @__PURE__ */ new Set();
1165
- const live = /* @__PURE__ */ new Map();
1166
- function compile(node) {
1167
- const raw = [...node.children];
1168
- const helmetClosed = node.nextSibling != null || node.parentNode?.nextSibling != null;
1169
- return (_vals, ctx) => {
1170
- const name = ctx && ctx.__name || "";
1171
- const streaming = !!(name && isStreaming(name));
1172
- for (let i = 0; i < raw.length; i++) {
1173
- const child = raw[i];
1174
- const tag = child.tagName;
1175
- const mayBePartial = streaming && !helmetClosed && i === raw.length - 1;
1176
- if (tag === "SCRIPT") {
1177
- if (mayBePartial) continue;
1178
- const key = "SCRIPT|" + (child.getAttribute("src") || child.textContent || "");
1179
- if (mounted.has(key)) continue;
1180
- mounted.add(key);
1181
- const el = doc.createElement("script");
1182
- for (const { name: an, value } of [...child.attributes])
1183
- el.setAttribute(an, value);
1184
- if (child.textContent) el.textContent = child.textContent;
1185
- doc.head.appendChild(el);
1186
- } else if (tag === "LINK" || tag === "META") {
1187
- if (mayBePartial) continue;
1188
- const key = tag + "|" + (child.getAttribute("href") || child.getAttribute("src") || child.outerHTML);
1189
- if (mounted.has(key)) continue;
1190
- mounted.add(key);
1191
- doc.head.appendChild(child.cloneNode(true));
1192
- } else {
1193
- const key = name + "|" + i;
1194
- let el = live.get(key);
1195
- if (!el || el.tagName !== tag) {
1196
- if (el) el.remove();
1197
- el = doc.createElement(tag.toLowerCase());
1198
- live.set(key, el);
1199
- doc.head.appendChild(el);
1200
- }
1201
- for (const { name: an, value } of [...child.attributes]) {
1202
- if (el.getAttribute(an) !== value) el.setAttribute(an, value);
1203
- }
1204
- if (el.textContent !== child.textContent)
1205
- el.textContent = child.textContent;
1206
- }
1207
- }
1208
- return null;
1209
- };
1210
- }
1211
- return { compile };
1212
- }
1213
-
1214
- // src/pseudo.ts
1215
- function createPseudoSheet(doc) {
1216
- let el = null;
1217
- const cache = /* @__PURE__ */ new Map();
1218
- let n = 0;
1219
- return (pseudo, css) => {
1220
- const k = pseudo + "|" + css;
1221
- const hit = cache.get(k);
1222
- if (hit) return hit;
1223
- if (!el) {
1224
- el = doc.createElement("style");
1225
- doc.head.appendChild(el);
1226
- }
1227
- const cls = "scp" + (n++).toString(36);
1228
- const sel = pseudo === "before" || pseudo === "after" ? "." + cls + "::" + pseudo : "." + cls + ":" + pseudo;
1229
- el.sheet.insertRule(sel + "{" + css + "}", el.sheet.cssRules.length);
1230
- cache.set(k, cls);
1231
- return cls;
1232
- };
1233
- }
1234
-
1235
- // src/registry.ts
1236
- function createRegistry() {
1237
- const entries = /* @__PURE__ */ Object.create(null);
1238
- function get(name) {
1239
- return entries[name] || (entries[name] = {
1240
- html: "",
1241
- tpl: null,
1242
- Logic: null,
1243
- jsStreaming: false,
1244
- htmlStreaming: false,
1245
- ver: 0,
1246
- subs: /* @__PURE__ */ new Set(),
1247
- fetched: false
1248
- });
1249
- }
1250
- function bump(name) {
1251
- const r = get(name);
1252
- r.ver++;
1253
- for (const fn of r.subs) fn();
1254
- }
1255
- return {
1256
- entries,
1257
- get,
1258
- bump,
1259
- bumpAll() {
1260
- for (const n in entries) bump(n);
1261
- }
1262
- };
1263
- }
1264
-
1265
- // src/runtime.ts
1266
- var COMPONENT_DIR = ".";
1267
- function createRuntime(doc = document) {
1268
- const registry = createRegistry();
1269
- const pseudoClass = createPseudoSheet(doc);
1270
- const helmet = createHelmetManager(
1271
- doc,
1272
- (name) => registry.get(name).htmlStreaming
1273
- );
1274
- const external = createExternalModules(() => registry.bumpAll());
1275
- const factory = createComponentFactory(registry, ensureFetched);
1276
- const host = {
1277
- component: (name) => factory.getDC(name),
1278
- placeholder: (props) => h(Placeholder, props),
1279
- helmet: (node) => helmet.compile(node),
1280
- loadExternal: (kind, url) => external.load(kind, url),
1281
- resolveExternal: (url, name) => external.resolve(url, name),
1282
- resolveExternalGlobal: (url, name) => external.resolveGlobal(url, name),
1283
- resolveExternalError: (url, name) => external.getError(url, name),
1284
- pseudoClass
1285
- };
1286
- function ensureFetched(name) {
1287
- const r = registry.get(name);
1288
- if (r.fetched) return;
1289
- r.fetched = true;
1290
- const url = COMPONENT_DIR + "/" + encodeURIComponent(name) + ".dc.html";
1291
- fetch(url).then((res) => {
1292
- if (!res.ok) {
1293
- console.error(
1294
- "[dc-runtime] sibling fetch for <" + name + "/> failed:",
1295
- url,
1296
- "returned",
1297
- res.status,
1298
- "\u2014 the reference renders as an empty placeholder."
1299
- );
1300
- return "";
1301
- }
1302
- return res.text();
1303
- }).then((t) => {
1304
- if (!t) return;
1305
- const parsed = parseDcText(t);
1306
- if (!parsed) {
1307
- console.error(
1308
- "[dc-runtime] sibling fetch for <" + name + "/>:",
1309
- url,
1310
- "has no <x-dc> block \u2014 not a Design Component."
1311
- );
1312
- return;
1313
- }
1314
- if (parsed.props) r.propsMeta = parsed.props;
1315
- if (parsed.preview) r.preview = parsed.preview;
1316
- if (parsed.template && !r.html) updateHtml(name, parsed.template);
1317
- if (parsed.js && !r.Logic) updateJs(name, parsed.js);
1318
- }).catch(
1319
- (e) => console.error(
1320
- "[dc-runtime] sibling fetch for <" + name + "/> threw:",
1321
- url,
1322
- e
1323
- )
1324
- );
1325
- }
1326
- function updateHtml(name, html) {
1327
- const r = registry.get(name);
1328
- r.html = html;
1329
- try {
1330
- r.tpl = compileTemplate(html, host);
1331
- } catch (e) {
1332
- console.error("[dc-runtime] template compile FAILED for", name, e);
1333
- }
1334
- registry.bump(name);
1335
- }
1336
- function updateJs(name, src) {
1337
- const r = registry.get(name);
1338
- const seq = r.jsSeq = (r.jsSeq || 0) + 1;
1339
- try {
1340
- const Cls = evalDcLogic(src);
1341
- if (r.jsSeq !== seq) return;
1342
- if (typeof Cls !== "function") {
1343
- r.logicError = name + ".dc.html: <script data-dc-script> must define `class Component extends DCLogic`";
1344
- } else {
1345
- r.logicError = null;
1346
- r.Logic = Cls;
1347
- }
1348
- } catch (e) {
1349
- if (r.jsSeq !== seq) return;
1350
- console.error(
1351
- "[dc-runtime] logic class eval FAILED for",
1352
- name,
1353
- "\u2014 the template renders with props only.",
1354
- e
1355
- );
1356
- r.logicError = name + ": " + (e instanceof Error && e.message ? e.message : String(e));
1357
- }
1358
- registry.bump(name);
1359
- }
1360
- function setStreaming(name, kind, on) {
1361
- const r = registry.get(name);
1362
- if (kind === "html") r.htmlStreaming = !!on;
1363
- else r.jsStreaming = !!on;
1364
- let any = false;
1365
- for (const n in registry.entries) {
1366
- const e = registry.entries[n];
1367
- if (e && (e.htmlStreaming || e.jsStreaming)) {
1368
- any = true;
1369
- break;
1370
- }
1371
- }
1372
- doc.documentElement.classList.toggle("sc-dc-streaming", any);
1373
- registry.bump(name);
1374
- }
1375
- function dcUpdate(name, kind, content, streaming) {
1376
- if (streaming) registry.get(name).fetched = true;
1377
- if (kind === "html") {
1378
- setStreaming(name, "html", !!streaming);
1379
- updateHtml(name, content);
1380
- } else if (kind === "js") {
1381
- setStreaming(name, "js", !!streaming);
1382
- if (!streaming) updateJs(name, content);
1383
- } else if (kind === "props") {
1384
- const { props, preview } = parseDataProps(content);
1385
- const r = registry.get(name);
1386
- r.propsMeta = props ?? void 0;
1387
- r.preview = preview;
1388
- registry.bump(name);
1389
- }
1390
- }
1391
- function setProps(name, overrides) {
1392
- registry.get(name).propOverrides = overrides && typeof overrides === "object" ? { ...overrides } : null;
1393
- registry.bump(name);
1394
- }
1395
- function adoptParsed(name, parsed) {
1396
- if (!parsed) return;
1397
- const r = registry.get(name);
1398
- if (parsed.props) r.propsMeta = parsed.props;
1399
- if (parsed.preview) r.preview = parsed.preview;
1400
- if (parsed.template) updateHtml(name, parsed.template);
1401
- if (parsed.js) updateJs(name, parsed.js);
1402
- }
1403
- return {
1404
- registry,
1405
- getDC: factory.getDC,
1406
- updateHtml,
1407
- updateJs,
1408
- dcUpdate,
1409
- setProps,
1410
- adoptParsed,
1411
- markFetched: (name) => {
1412
- registry.get(name).fetched = true;
1413
- },
1414
- annotatedTemplate: (name) => {
1415
- const r = registry.get(name);
1416
- return r.tpl && r.tpl.__annotated || null;
1417
- },
1418
- templateSource: (name) => registry.get(name).html || null,
1419
- StreamableLogic
1420
- };
1421
- }
1422
-
1423
- // src/index.ts
1424
- var REACT_URL = "https://unpkg.com/react@18.3.1/umd/react.production.min.js";
1425
- var REACT_SRI = "sha384-DGyLxAyjq0f9SPpVevD6IgztCFlnMF6oW/XQGmfe+IsZ8TqEiDrcHkMLKI6fiB/Z";
1426
- var REACT_DOM_URL = "https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js";
1427
- var REACT_DOM_SRI = "sha384-gTGxhz21lVGYNMcdJOyq01Edg0jhn/c22nsx0kyqP0TxaV5WVdsSH1fSDUf5YJj1";
1428
- function hideRawTemplate() {
1429
- const s = document.createElement("style");
1430
- s.textContent = "x-dc{display:none!important}";
1431
- document.head.appendChild(s);
1432
- }
1433
- function loadScript(src, integrity) {
1434
- return new Promise((resolve2, reject) => {
1435
- //! nosemgrep: create-script-element
1436
- const s = document.createElement("script");
1437
- s.src = src;
1438
- s.integrity = integrity;
1439
- s.crossOrigin = "anonymous";
1440
- s.async = false;
1441
- s.onload = () => resolve2();
1442
- s.onerror = () => reject(new Error(`failed to load ${src}`));
1443
- document.head.appendChild(s);
1444
- });
1445
- }
1446
- function loadReactUmd() {
1447
- const w = window;
1448
- if (w.React && w.ReactDOM) return Promise.resolve();
1449
- return Promise.all([
1450
- loadScript(REACT_URL, REACT_SRI),
1451
- loadScript(REACT_DOM_URL, REACT_DOM_SRI)
1452
- ]).then(() => void 0);
1453
- }
1454
- function init() {
1455
- const runtime = createRuntime(document);
1456
- let rootName = "Root";
1457
- const baseCss = document.createElement("style");
1458
- baseCss.textContent = BASE_CSS;
1459
- document.head.prepend(baseCss);
1460
- const notifyHost = () => {
1461
- if (window.parent === window) return;
1462
- const r = runtime.registry.entries[rootName];
1463
- try {
1464
- window.parent.postMessage(
1465
- {
1466
- type: "__dc_booted",
1467
- rootName,
1468
- propsMeta: r && r.propsMeta || null,
1469
- preview: r && r.preview || null
1470
- },
1471
- "*"
1472
- );
1473
- } catch {
1474
- }
1475
- };
1476
- const api = {
1477
- __dcUpdate: (name, kind, content, streaming) => {
1478
- runtime.dcUpdate(name, kind, content, streaming);
1479
- if (name === rootName && !streaming && kind === "props") notifyHost();
1480
- },
1481
- __dcSetProps: (name, overrides) => runtime.setProps(name, overrides),
1482
- /** Name of the component currently mounted as the page root — DC tools
1483
- * push their template-stream here when targeting "the open page". */
1484
- __dcRootName: () => rootName,
1485
- /** Editor bridge — the encoded, `data-dc-tpl`-annotated template source.
1486
- * The host editor parses this into its own template DOM so it can map a
1487
- * rendered node (carrying the same `data-dc-tpl`) back to the source
1488
- * node that emitted it. Returns the encoded form (`<sc-comp>`,
1489
- * `sc-camel-*` attrs); the editor decodes on serialize. */
1490
- __dcAnnotatedTemplate: (name) => runtime.annotatedTemplate(name),
1491
- /** Editor bridge — the *original* (decoded) template source. */
1492
- __dcTemplateSource: (name) => runtime.templateSource(name),
1493
- __dcBoot: () => {
1494
- rootName = boot(runtime, document) ?? rootName;
1495
- notifyHost();
1496
- },
1497
- __dcRegistry: runtime.registry.entries,
1498
- getDC: (name) => runtime.getDC(name),
1499
- // `DCLogic` is the documented base class name; `StreamableLogic` is the
1500
- // implementation alias kept for any project that already references it.
1501
- DCLogic: runtime.StreamableLogic,
1502
- StreamableLogic: runtime.StreamableLogic
1503
- };
1504
- Object.assign(window, api);
1505
- if (document.readyState !== "loading") api.__dcBoot();
1506
- else document.addEventListener("DOMContentLoaded", () => api.__dcBoot());
1507
- }
1508
- hideRawTemplate();
1509
- loadReactUmd().then(init).catch((err) => {
1510
- console.error("[dc] failed to load React or boot:", err);
1511
- throw err;
1512
- });
1513
- })();