@openelement/core 0.41.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -0
  3. package/package.json +124 -0
  4. package/src/binding-activation.d.ts +2 -0
  5. package/src/binding-activation.js +254 -0
  6. package/src/binding-descriptor.d.ts +79 -0
  7. package/src/binding-descriptor.js +9 -0
  8. package/src/context.d.ts +32 -0
  9. package/src/context.js +76 -0
  10. package/src/csr.d.ts +13 -0
  11. package/src/csr.js +14 -0
  12. package/src/dsd-hydration-events.d.ts +2 -0
  13. package/src/dsd-hydration-events.js +13 -0
  14. package/src/dsd-hydration.d.ts +40 -0
  15. package/src/dsd-hydration.js +48 -0
  16. package/src/errors.d.ts +54 -0
  17. package/src/errors.js +113 -0
  18. package/src/event-hydration.d.ts +12 -0
  19. package/src/event-hydration.js +118 -0
  20. package/src/event-marker.d.ts +7 -0
  21. package/src/event-marker.js +54 -0
  22. package/src/html-escape.d.ts +29 -0
  23. package/src/html-escape.js +126 -0
  24. package/src/hydrate.d.ts +15 -0
  25. package/src/hydrate.js +15 -0
  26. package/src/index.d.ts +58 -0
  27. package/src/index.js +46 -0
  28. package/src/island-transform.d.ts +14 -0
  29. package/src/island-transform.js +60 -0
  30. package/src/island.d.ts +59 -0
  31. package/src/island.js +342 -0
  32. package/src/isr-runtime.d.ts +28 -0
  33. package/src/isr-runtime.js +99 -0
  34. package/src/isr.d.ts +22 -0
  35. package/src/isr.js +41 -0
  36. package/src/jsx-render-dom.d.ts +22 -0
  37. package/src/jsx-render-dom.js +376 -0
  38. package/src/jsx-runtime.d.ts +58 -0
  39. package/src/jsx-runtime.js +99 -0
  40. package/src/jsx-types.d.ts +46 -0
  41. package/src/logger.d.ts +15 -0
  42. package/src/logger.js +24 -0
  43. package/src/prop.d.ts +24 -0
  44. package/src/prop.js +160 -0
  45. package/src/registry.d.ts +17 -0
  46. package/src/registry.js +219 -0
  47. package/src/render-dsd-stream.d.ts +46 -0
  48. package/src/render-dsd-stream.js +86 -0
  49. package/src/render-dsd.d.ts +27 -0
  50. package/src/render-dsd.js +315 -0
  51. package/src/render-ir.d.ts +32 -0
  52. package/src/render-ir.js +245 -0
  53. package/src/runtime.d.ts +9 -0
  54. package/src/runtime.js +16 -0
  55. package/src/security.d.ts +1 -0
  56. package/src/security.js +40 -0
  57. package/src/signal-context.d.ts +15 -0
  58. package/src/signal-context.js +59 -0
  59. package/src/static.d.ts +35 -0
  60. package/src/static.js +34 -0
  61. package/src/style-sheet.d.ts +9 -0
  62. package/src/style-sheet.js +56 -0
  63. package/src/tag-utils.d.ts +11 -0
  64. package/src/tag-utils.js +28 -0
  65. package/src/vnode.d.ts +15 -0
  66. package/src/vnode.js +31 -0
@@ -0,0 +1,29 @@
1
+ import type { SafeHtml, UnsafeHtml } from '@openelement/protocol/framework';
2
+ export type { SafeHtml, UnsafeHtml };
3
+ export declare function escapeHtml(str: string): string;
4
+ /** Escape an HTML attribute value */ export declare function escapeAttr(value: string): string;
5
+ /** Escape a string for use as an attribute value (double-quoted) */ export declare function escapeAttrValue(value: unknown): string;
6
+ /**
7
+ * Wrap rendered HTML in a full HTML document.
8
+ * Adds DOCTYPE, head (title, meta, preload), and body.
9
+ * Supports CSP nonce and dev scripts (e.g. Vite client, route module registration).
10
+ */ export declare function wrapInDocument(html: string, options?: {
11
+ title?: string;
12
+ lang?: string;
13
+ /** Client-side module script injected after rendered HTML. */ clientScript?: string;
14
+ meta?: {
15
+ description?: string;
16
+ tags?: Array<Record<string, string | number | boolean>>;
17
+ };
18
+ /** Raw HTML script tags to inject after rendered HTML (e.g. Vite client, route module registration). */ devScripts?: string;
19
+ headExtras?: string;
20
+ /** Raw route-local head fragments from explicit dangerous page metadata. */ dangerouslyHeadFragments?: string[];
21
+ /** Trust script tags that were produced by structured framework injection APIs. */ allowHeadExtrasScripts?: boolean;
22
+ /** CSP nonce, if provided, added to all generated <script> tags. */ cspNonce?: string;
23
+ }): string;
24
+ import type { RouteEntry } from '@openelement/protocol/framework';
25
+ /**
26
+ * Render an error page to HTML string.
27
+ * In dev mode, shows detailed error information for debugging.
28
+ * In production, shows a generic safe error page.
29
+ */ export declare function renderSsrError(error: Error, statusOrRoute: number | RouteEntry, isDev?: boolean): string;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @openelement/core - Safe/Unsafe HTML Contract
3
+ *
4
+ * Branded types for HTML escaping semantics:
5
+ * - SafeHtml: A string that has been HTML-escaped (safe for text content)
6
+ * - UnsafeHtml: A string that is intentionally raw HTML (do not double-escape)
7
+ *
8
+ * @module @openelement/core/html-escape
9
+ */ // ─── L1: Safe/Unsafe HTML Contract ──────────────────────────────
10
+ import { createLogger, warnOnce } from './logger.js';
11
+ const log = createLogger('core');
12
+ /**
13
+ * Escape a string for safe HTML text content insertion.
14
+ * Uses single-pass replacement for performance (P-01 fix).
15
+ * Branded types are compile-time only - removed dead runtime branches (M-01 fix).
16
+ */ const ESCAPE_MAP = {
17
+ '&': '&amp;',
18
+ '<': '&lt;',
19
+ '>': '&gt;',
20
+ '"': '&quot;',
21
+ "'": '&#39;'
22
+ };
23
+ export function escapeHtml(str) {
24
+ if (typeof str !== 'string') return '';
25
+ return str.replace(/[&<>"']/g, (ch)=>ESCAPE_MAP[ch] || ch);
26
+ }
27
+ /** Escape an HTML attribute value */ export function escapeAttr(value) {
28
+ return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
29
+ }
30
+ /** Escape a string for use as an attribute value (double-quoted) */ export function escapeAttrValue(value) {
31
+ if (value === null || value === undefined) return '';
32
+ return escapeAttr(String(value));
33
+ }
34
+ /**
35
+ * Wrap rendered HTML in a full HTML document.
36
+ * Adds DOCTYPE, head (title, meta, preload), and body.
37
+ * Supports CSP nonce and dev scripts (e.g. Vite client, route module registration).
38
+ */ export function wrapInDocument(html, options = {}) {
39
+ const { title = 'openElement', lang = 'en', clientScript = '', meta, devScripts = '', headExtras = '', dangerouslyHeadFragments = [], allowHeadExtrasScripts = false, cspNonce } = options;
40
+ // v0.14.5: CSP nonce format validation per CSP spec (base64 value)
41
+ const NONCE_RE = /^[A-Za-z0-9+/=_-]+$/;
42
+ const validNonce = cspNonce && NONCE_RE.test(cspNonce) ? cspNonce : undefined;
43
+ if (cspNonce && !validNonce) {
44
+ log.warn(`Invalid CSP nonce format: "${cspNonce}". Nonce should be a base64-encoded value.`);
45
+ }
46
+ // v0.14.8: C-02 fix - Runtime enforcement for headExtras.
47
+ // If headExtras contains <script> tags and allowHeadExtrasScripts is false,
48
+ // strip them to prevent XSS. Developer should use inject.scripts for safe injection.
49
+ let safeHeadExtras = headExtras;
50
+ if (!allowHeadExtrasScripts && headExtras) {
51
+ // Strip <script> tags and their content
52
+ safeHeadExtras = headExtras.replace(/<script[\s>][\s\S]*?<\/script\s*>/gi, '');
53
+ if (safeHeadExtras !== headExtras) {
54
+ warnOnce('headExtrasScripts', log, 'headExtras contained <script> tags which were stripped for security. ' + 'Use inject.scripts for safe script injection, or set allowHeadExtrasScripts: true.');
55
+ }
56
+ // Strip on* event handler attributes (strong XSS indicator)
57
+ if (/\s+on\w+\s*=/i.test(safeHeadExtras)) {
58
+ safeHeadExtras = safeHeadExtras.replace(/\s+on\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^\s>]+)/gi, '');
59
+ log.warn('headExtras contained on* event handler attributes which were stripped for security.');
60
+ }
61
+ }
62
+ // v0.14.3: Basic HTML tag balance validation for headExtras.
63
+ // Checks that opening and closing tag counts match for major HTML elements.
64
+ // This catches obviously malformed HTML (e.g., unclosed <!-- comments).
65
+ if (headExtras) {
66
+ // Check for unclosed HTML comments: <!-- without matching -->
67
+ const commentOpens = (headExtras.match(/<!--/g) || []).length;
68
+ const commentCloses = (headExtras.match(/-->/g) || []).length;
69
+ if (commentOpens !== commentCloses) {
70
+ log.warn('headExtras has unbalanced HTML comments (<!-- vs -->). ' + 'This may cause HTML parsing issues.');
71
+ }
72
+ }
73
+ const metaTags = [];
74
+ if (meta?.description) {
75
+ const safeDesc = escapeAttrValue(meta.description);
76
+ metaTags.push(` <meta name="description" content="${safeDesc}">`);
77
+ }
78
+ if (Array.isArray(meta?.tags)) {
79
+ for (const tag of meta.tags){
80
+ const attrs = Object.entries(tag).map(([key, value])=>`${escapeAttr(key)}="${escapeAttrValue(value)}"`).join(' ');
81
+ if (attrs) metaTags.push(` <meta ${attrs}>`);
82
+ }
83
+ }
84
+ const metaBlock = metaTags.length > 0 ? '\n' + metaTags.join('\n') + '\n' : '';
85
+ const dangerousHeadBlock = dangerouslyHeadFragments.length > 0 ? '\n ' + dangerouslyHeadFragments.join('\n ') : '';
86
+ const safeTitle = escapeHtml(title);
87
+ const safeLang = escapeAttr(lang);
88
+ return `<!DOCTYPE html>
89
+ <html lang="${safeLang}">
90
+ <head>
91
+ <meta charset="UTF-8">
92
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
93
+ <title>${safeTitle}</title>${metaBlock}
94
+ ${safeHeadExtras}${dangerousHeadBlock}
95
+ </head>
96
+ <body>
97
+ ${html}
98
+ ${clientScript}${devScripts}
99
+ </body>
100
+ </html>`;
101
+ }
102
+ /**
103
+ * Render an error page to HTML string.
104
+ * In dev mode, shows detailed error information for debugging.
105
+ * In production, shows a generic safe error page.
106
+ */ export function renderSsrError(error, statusOrRoute, isDev = false) {
107
+ const status = typeof statusOrRoute === 'number' ? statusOrRoute : 500;
108
+ const title = isDev ? 'SSR Render Error' : `Error ${status}`;
109
+ const message = escapeHtml(error.message);
110
+ const stack = isDev && error.stack ? escapeHtml(error.stack) : '';
111
+ return `<!DOCTYPE html>
112
+ <html lang="en">
113
+ <head>
114
+ <meta charset="UTF-8">
115
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
116
+ <title>${title}</title>
117
+ ${isDev ? '<style>body{font-family:system-ui;max-width:800px;margin:2rem auto;padding:0 1rem}pre{background:#f5f5f5;padding:1rem;overflow:auto;border-radius:4px}</style>' : ''}
118
+ </head>
119
+ <body>
120
+ <h1>${title}</h1>
121
+ <p>${isDev ? `<strong>${message}</strong>` : message}</p>
122
+ ${stack ? `<pre>${stack}</pre>` : ''}
123
+ </body>
124
+ </html>`;
125
+ }
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9odG1sLWVzY2FwZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBvcGVuZWxlbWVudC9jb3JlIC0gU2FmZS9VbnNhZmUgSFRNTCBDb250cmFjdFxuICpcbiAqIEJyYW5kZWQgdHlwZXMgZm9yIEhUTUwgZXNjYXBpbmcgc2VtYW50aWNzOlxuICogLSBTYWZlSHRtbDogIEEgc3RyaW5nIHRoYXQgaGFzIGJlZW4gSFRNTC1lc2NhcGVkIChzYWZlIGZvciB0ZXh0IGNvbnRlbnQpXG4gKiAtIFVuc2FmZUh0bWw6IEEgc3RyaW5nIHRoYXQgaXMgaW50ZW50aW9uYWxseSByYXcgSFRNTCAoZG8gbm90IGRvdWJsZS1lc2NhcGUpXG4gKlxuICogQG1vZHVsZSBAb3BlbmVsZW1lbnQvY29yZS9odG1sLWVzY2FwZVxuICovXG5cbi8vIOKUgOKUgOKUgCBMMTogU2FmZS9VbnNhZmUgSFRNTCBDb250cmFjdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyLCB3YXJuT25jZSB9IGZyb20gJy4vbG9nZ2VyLmpzJztcblxuY29uc3QgbG9nID0gY3JlYXRlTG9nZ2VyKCdjb3JlJyk7XG5cbmltcG9ydCB0eXBlIHsgU2FmZUh0bWwsIFVuc2FmZUh0bWwgfSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvZnJhbWV3b3JrJztcbmV4cG9ydCB0eXBlIHsgU2FmZUh0bWwsIFVuc2FmZUh0bWwgfTtcblxuLyoqXG4gKiBFc2NhcGUgYSBzdHJpbmcgZm9yIHNhZmUgSFRNTCB0ZXh0IGNvbnRlbnQgaW5zZXJ0aW9uLlxuICogVXNlcyBzaW5nbGUtcGFzcyByZXBsYWNlbWVudCBmb3IgcGVyZm9ybWFuY2UgKFAtMDEgZml4KS5cbiAqIEJyYW5kZWQgdHlwZXMgYXJlIGNvbXBpbGUtdGltZSBvbmx5IC0gcmVtb3ZlZCBkZWFkIHJ1bnRpbWUgYnJhbmNoZXMgKE0tMDEgZml4KS5cbiAqL1xuY29uc3QgRVNDQVBFX01BUDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgJyYnOiAnJmFtcDsnLFxuICAnPCc6ICcmbHQ7JyxcbiAgJz4nOiAnJmd0OycsXG4gICdcIic6ICcmcXVvdDsnLFxuICBcIidcIjogJyYjMzk7Jyxcbn07XG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlSHRtbChzdHI6IHN0cmluZyk6IHN0cmluZyB7XG4gIGlmICh0eXBlb2Ygc3RyICE9PSAnc3RyaW5nJykgcmV0dXJuICcnO1xuICByZXR1cm4gc3RyLnJlcGxhY2UoL1smPD5cIiddL2csIChjaCkgPT4gRVNDQVBFX01BUFtjaF0gfHwgY2gpO1xufVxuXG4vKiogRXNjYXBlIGFuIEhUTUwgYXR0cmlidXRlIHZhbHVlICovXG5leHBvcnQgZnVuY3Rpb24gZXNjYXBlQXR0cih2YWx1ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZhbHVlXG4gICAgLnJlcGxhY2UoLyYvZywgJyZhbXA7JylcbiAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpXG4gICAgLnJlcGxhY2UoLycvZywgJyYjMzk7JylcbiAgICAucmVwbGFjZSgvPC9nLCAnJmx0OycpXG4gICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKTtcbn1cblxuLyoqIEVzY2FwZSBhIHN0cmluZyBmb3IgdXNlIGFzIGFuIGF0dHJpYnV0ZSB2YWx1ZSAoZG91YmxlLXF1b3RlZCkgKi9cbmV4cG9ydCBmdW5jdGlvbiBlc2NhcGVBdHRyVmFsdWUodmFsdWU6IHVua25vd24pOiBzdHJpbmcge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuICcnO1xuICByZXR1cm4gZXNjYXBlQXR0cihTdHJpbmcodmFsdWUpKTtcbn1cblxuLyoqXG4gKiBXcmFwIHJlbmRlcmVkIEhUTUwgaW4gYSBmdWxsIEhUTUwgZG9jdW1lbnQuXG4gKiBBZGRzIERPQ1RZUEUsIGhlYWQgKHRpdGxlLCBtZXRhLCBwcmVsb2FkKSwgYW5kIGJvZHkuXG4gKiBTdXBwb3J0cyBDU1Agbm9uY2UgYW5kIGRldiBzY3JpcHRzIChlLmcuIFZpdGUgY2xpZW50LCByb3V0ZSBtb2R1bGUgcmVnaXN0cmF0aW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdyYXBJbkRvY3VtZW50KFxuICBodG1sOiBzdHJpbmcsXG4gIG9wdGlvbnM6IHtcbiAgICB0aXRsZT86IHN0cmluZztcbiAgICBsYW5nPzogc3RyaW5nO1xuICAgIC8qKiBDbGllbnQtc2lkZSBtb2R1bGUgc2NyaXB0IGluamVjdGVkIGFmdGVyIHJlbmRlcmVkIEhUTUwuICovXG4gICAgY2xpZW50U2NyaXB0Pzogc3RyaW5nO1xuICAgIG1ldGE/OiB7XG4gICAgICBkZXNjcmlwdGlvbj86IHN0cmluZztcbiAgICAgIHRhZ3M/OiBBcnJheTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuPj47XG4gICAgfTtcbiAgICAvKiogUmF3IEhUTUwgc2NyaXB0IHRhZ3MgdG8gaW5qZWN0IGFmdGVyIHJlbmRlcmVkIEhUTUwgKGUuZy4gVml0ZSBjbGllbnQsIHJvdXRlIG1vZHVsZSByZWdpc3RyYXRpb24pLiAqL1xuICAgIGRldlNjcmlwdHM/OiBzdHJpbmc7XG4gICAgaGVhZEV4dHJhcz86IHN0cmluZztcbiAgICAvKiogUmF3IHJvdXRlLWxvY2FsIGhlYWQgZnJhZ21lbnRzIGZyb20gZXhwbGljaXQgZGFuZ2Vyb3VzIHBhZ2UgbWV0YWRhdGEuICovXG4gICAgZGFuZ2Vyb3VzbHlIZWFkRnJhZ21lbnRzPzogc3RyaW5nW107XG4gICAgLyoqIFRydXN0IHNjcmlwdCB0YWdzIHRoYXQgd2VyZSBwcm9kdWNlZCBieSBzdHJ1Y3R1cmVkIGZyYW1ld29yayBpbmplY3Rpb24gQVBJcy4gKi9cbiAgICBhbGxvd0hlYWRFeHRyYXNTY3JpcHRzPzogYm9vbGVhbjtcbiAgICAvKiogQ1NQIG5vbmNlLCBpZiBwcm92aWRlZCwgYWRkZWQgdG8gYWxsIGdlbmVyYXRlZCA8c2NyaXB0PiB0YWdzLiAqL1xuICAgIGNzcE5vbmNlPzogc3RyaW5nO1xuICB9ID0ge30sXG4pOiBzdHJpbmcge1xuICBjb25zdCB7XG4gICAgdGl0bGUgPSAnb3BlbkVsZW1lbnQnLFxuICAgIGxhbmcgPSAnZW4nLFxuICAgIGNsaWVudFNjcmlwdCA9ICcnLFxuICAgIG1ldGEsXG4gICAgZGV2U2NyaXB0cyA9ICcnLFxuICAgIGhlYWRFeHRyYXMgPSAnJyxcbiAgICBkYW5nZXJvdXNseUhlYWRGcmFnbWVudHMgPSBbXSxcbiAgICBhbGxvd0hlYWRFeHRyYXNTY3JpcHRzID0gZmFsc2UsXG4gICAgY3NwTm9uY2UsXG4gIH0gPSBvcHRpb25zO1xuICAvLyB2MC4xNC41OiBDU1Agbm9uY2UgZm9ybWF0IHZhbGlkYXRpb24gcGVyIENTUCBzcGVjIChiYXNlNjQgdmFsdWUpXG4gIGNvbnN0IE5PTkNFX1JFID0gL15bQS1aYS16MC05Ky89Xy1dKyQvO1xuICBjb25zdCB2YWxpZE5vbmNlID0gY3NwTm9uY2UgJiYgTk9OQ0VfUkUudGVzdChjc3BOb25jZSkgPyBjc3BOb25jZSA6IHVuZGVmaW5lZDtcbiAgaWYgKGNzcE5vbmNlICYmICF2YWxpZE5vbmNlKSB7XG4gICAgbG9nLndhcm4oYEludmFsaWQgQ1NQIG5vbmNlIGZvcm1hdDogXCIke2NzcE5vbmNlfVwiLiBOb25jZSBzaG91bGQgYmUgYSBiYXNlNjQtZW5jb2RlZCB2YWx1ZS5gKTtcbiAgfVxuICAvLyB2MC4xNC44OiBDLTAyIGZpeCAtIFJ1bnRpbWUgZW5mb3JjZW1lbnQgZm9yIGhlYWRFeHRyYXMuXG4gIC8vIElmIGhlYWRFeHRyYXMgY29udGFpbnMgPHNjcmlwdD4gdGFncyBhbmQgYWxsb3dIZWFkRXh0cmFzU2NyaXB0cyBpcyBmYWxzZSxcbiAgLy8gc3RyaXAgdGhlbSB0byBwcmV2ZW50IFhTUy4gRGV2ZWxvcGVyIHNob3VsZCB1c2UgaW5qZWN0LnNjcmlwdHMgZm9yIHNhZmUgaW5qZWN0aW9uLlxuICBsZXQgc2FmZUhlYWRFeHRyYXMgPSBoZWFkRXh0cmFzO1xuICBpZiAoIWFsbG93SGVhZEV4dHJhc1NjcmlwdHMgJiYgaGVhZEV4dHJhcykge1xuICAgIC8vIFN0cmlwIDxzY3JpcHQ+IHRhZ3MgYW5kIHRoZWlyIGNvbnRlbnRcbiAgICBzYWZlSGVhZEV4dHJhcyA9IGhlYWRFeHRyYXMucmVwbGFjZSgvPHNjcmlwdFtcXHM+XVtcXHNcXFNdKj88XFwvc2NyaXB0XFxzKj4vZ2ksICcnKTtcbiAgICBpZiAoc2FmZUhlYWRFeHRyYXMgIT09IGhlYWRFeHRyYXMpIHtcbiAgICAgIHdhcm5PbmNlKFxuICAgICAgICAnaGVhZEV4dHJhc1NjcmlwdHMnLFxuICAgICAgICBsb2csXG4gICAgICAgICdoZWFkRXh0cmFzIGNvbnRhaW5lZCA8c2NyaXB0PiB0YWdzIHdoaWNoIHdlcmUgc3RyaXBwZWQgZm9yIHNlY3VyaXR5LiAnICtcbiAgICAgICAgICAnVXNlIGluamVjdC5zY3JpcHRzIGZvciBzYWZlIHNjcmlwdCBpbmplY3Rpb24sIG9yIHNldCBhbGxvd0hlYWRFeHRyYXNTY3JpcHRzOiB0cnVlLicsXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBTdHJpcCBvbiogZXZlbnQgaGFuZGxlciBhdHRyaWJ1dGVzIChzdHJvbmcgWFNTIGluZGljYXRvcilcbiAgICBpZiAoL1xccytvblxcdytcXHMqPS9pLnRlc3Qoc2FmZUhlYWRFeHRyYXMpKSB7XG4gICAgICBzYWZlSGVhZEV4dHJhcyA9IHNhZmVIZWFkRXh0cmFzLnJlcGxhY2UoXG4gICAgICAgIC9cXHMrb25cXHcrXFxzKj1cXHMqKD86XCJbXlwiXSpcInwnW14nXSonfFteXFxzPl0rKS9naSxcbiAgICAgICAgJycsXG4gICAgICApO1xuICAgICAgbG9nLndhcm4oXG4gICAgICAgICdoZWFkRXh0cmFzIGNvbnRhaW5lZCBvbiogZXZlbnQgaGFuZGxlciBhdHRyaWJ1dGVzIHdoaWNoIHdlcmUgc3RyaXBwZWQgZm9yIHNlY3VyaXR5LicsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIHYwLjE0LjM6IEJhc2ljIEhUTUwgdGFnIGJhbGFuY2UgdmFsaWRhdGlvbiBmb3IgaGVhZEV4dHJhcy5cbiAgLy8gQ2hlY2tzIHRoYXQgb3BlbmluZyBhbmQgY2xvc2luZyB0YWcgY291bnRzIG1hdGNoIGZvciBtYWpvciBIVE1MIGVsZW1lbnRzLlxuICAvLyBUaGlzIGNhdGNoZXMgb2J2aW91c2x5IG1hbGZvcm1lZCBIVE1MIChlLmcuLCB1bmNsb3NlZCA8IS0tIGNvbW1lbnRzKS5cbiAgaWYgKGhlYWRFeHRyYXMpIHtcbiAgICAvLyBDaGVjayBmb3IgdW5jbG9zZWQgSFRNTCBjb21tZW50czogPCEtLSB3aXRob3V0IG1hdGNoaW5nIC0tPlxuICAgIGNvbnN0IGNvbW1lbnRPcGVucyA9IChoZWFkRXh0cmFzLm1hdGNoKC88IS0tL2cpIHx8IFtdKS5sZW5ndGg7XG4gICAgY29uc3QgY29tbWVudENsb3NlcyA9IChoZWFkRXh0cmFzLm1hdGNoKC8tLT4vZykgfHwgW10pLmxlbmd0aDtcbiAgICBpZiAoY29tbWVudE9wZW5zICE9PSBjb21tZW50Q2xvc2VzKSB7XG4gICAgICBsb2cud2FybihcbiAgICAgICAgJ2hlYWRFeHRyYXMgaGFzIHVuYmFsYW5jZWQgSFRNTCBjb21tZW50cyAoPCEtLSB2cyAtLT4pLiAnICtcbiAgICAgICAgICAnVGhpcyBtYXkgY2F1c2UgSFRNTCBwYXJzaW5nIGlzc3Vlcy4nLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbiAgY29uc3QgbWV0YVRhZ3M6IHN0cmluZ1tdID0gW107XG4gIGlmIChtZXRhPy5kZXNjcmlwdGlvbikge1xuICAgIGNvbnN0IHNhZmVEZXNjID0gZXNjYXBlQXR0clZhbHVlKG1ldGEuZGVzY3JpcHRpb24pO1xuICAgIG1ldGFUYWdzLnB1c2goYCAgPG1ldGEgbmFtZT1cImRlc2NyaXB0aW9uXCIgY29udGVudD1cIiR7c2FmZURlc2N9XCI+YCk7XG4gIH1cbiAgaWYgKEFycmF5LmlzQXJyYXkobWV0YT8udGFncykpIHtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBtZXRhLnRhZ3MpIHtcbiAgICAgIGNvbnN0IGF0dHJzID0gT2JqZWN0LmVudHJpZXModGFnKVxuICAgICAgICAubWFwKChba2V5LCB2YWx1ZV0pID0+IGAke2VzY2FwZUF0dHIoa2V5KX09XCIke2VzY2FwZUF0dHJWYWx1ZSh2YWx1ZSl9XCJgKVxuICAgICAgICAuam9pbignICcpO1xuICAgICAgaWYgKGF0dHJzKSBtZXRhVGFncy5wdXNoKGAgIDxtZXRhICR7YXR0cnN9PmApO1xuICAgIH1cbiAgfVxuICBjb25zdCBtZXRhQmxvY2sgPSBtZXRhVGFncy5sZW5ndGggPiAwID8gJ1xcbicgKyBtZXRhVGFncy5qb2luKCdcXG4nKSArICdcXG4nIDogJyc7XG4gIGNvbnN0IGRhbmdlcm91c0hlYWRCbG9jayA9IGRhbmdlcm91c2x5SGVhZEZyYWdtZW50cy5sZW5ndGggPiAwXG4gICAgPyAnXFxuICAnICsgZGFuZ2Vyb3VzbHlIZWFkRnJhZ21lbnRzLmpvaW4oJ1xcbiAgJylcbiAgICA6ICcnO1xuXG4gIGNvbnN0IHNhZmVUaXRsZSA9IGVzY2FwZUh0bWwodGl0bGUpO1xuICBjb25zdCBzYWZlTGFuZyA9IGVzY2FwZUF0dHIobGFuZyk7XG5cbiAgcmV0dXJuIGA8IURPQ1RZUEUgaHRtbD5cbjxodG1sIGxhbmc9XCIke3NhZmVMYW5nfVwiPlxuPGhlYWQ+XG4gIDxtZXRhIGNoYXJzZXQ9XCJVVEYtOFwiPlxuICA8bWV0YSBuYW1lPVwidmlld3BvcnRcIiBjb250ZW50PVwid2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMFwiPlxuICA8dGl0bGU+JHtzYWZlVGl0bGV9PC90aXRsZT4ke21ldGFCbG9ja31cbiAgJHtzYWZlSGVhZEV4dHJhc30ke2Rhbmdlcm91c0hlYWRCbG9ja31cbjwvaGVhZD5cbjxib2R5PlxuICAke2h0bWx9XG4gICR7Y2xpZW50U2NyaXB0fSR7ZGV2U2NyaXB0c31cbjwvYm9keT5cbjwvaHRtbD5gO1xufVxuXG4vLyDilIDilIDilIAgRXJyb3IgcGFnZSByZW5kZXJpbmcg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmltcG9ydCB0eXBlIHsgUm91dGVFbnRyeSB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9mcmFtZXdvcmsnO1xuXG4vKipcbiAqIFJlbmRlciBhbiBlcnJvciBwYWdlIHRvIEhUTUwgc3RyaW5nLlxuICogSW4gZGV2IG1vZGUsIHNob3dzIGRldGFpbGVkIGVycm9yIGluZm9ybWF0aW9uIGZvciBkZWJ1Z2dpbmcuXG4gKiBJbiBwcm9kdWN0aW9uLCBzaG93cyBhIGdlbmVyaWMgc2FmZSBlcnJvciBwYWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVuZGVyU3NyRXJyb3IoXG4gIGVycm9yOiBFcnJvcixcbiAgc3RhdHVzT3JSb3V0ZTogbnVtYmVyIHwgUm91dGVFbnRyeSxcbiAgaXNEZXY6IGJvb2xlYW4gPSBmYWxzZSxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHN0YXR1cyA9IHR5cGVvZiBzdGF0dXNPclJvdXRlID09PSAnbnVtYmVyJyA/IHN0YXR1c09yUm91dGUgOiA1MDA7XG4gIGNvbnN0IHRpdGxlID0gaXNEZXYgPyAnU1NSIFJlbmRlciBFcnJvcicgOiBgRXJyb3IgJHtzdGF0dXN9YDtcbiAgY29uc3QgbWVzc2FnZSA9IGVzY2FwZUh0bWwoZXJyb3IubWVzc2FnZSk7XG4gIGNvbnN0IHN0YWNrID0gaXNEZXYgJiYgZXJyb3Iuc3RhY2sgPyBlc2NhcGVIdG1sKGVycm9yLnN0YWNrKSA6ICcnO1xuXG4gIHJldHVybiBgPCFET0NUWVBFIGh0bWw+XG48aHRtbCBsYW5nPVwiZW5cIj5cbjxoZWFkPlxuICA8bWV0YSBjaGFyc2V0PVwiVVRGLThcIj5cbiAgPG1ldGEgbmFtZT1cInZpZXdwb3J0XCIgY29udGVudD1cIndpZHRoPWRldmljZS13aWR0aCwgaW5pdGlhbC1zY2FsZT0xLjBcIj5cbiAgPHRpdGxlPiR7dGl0bGV9PC90aXRsZT5cbiAgJHtcbiAgICBpc0RldlxuICAgICAgPyAnPHN0eWxlPmJvZHl7Zm9udC1mYW1pbHk6c3lzdGVtLXVpO21heC13aWR0aDo4MDBweDttYXJnaW46MnJlbSBhdXRvO3BhZGRpbmc6MCAxcmVtfXByZXtiYWNrZ3JvdW5kOiNmNWY1ZjU7cGFkZGluZzoxcmVtO292ZXJmbG93OmF1dG87Ym9yZGVyLXJhZGl1czo0cHh9PC9zdHlsZT4nXG4gICAgICA6ICcnXG4gIH1cbjwvaGVhZD5cbjxib2R5PlxuICA8aDE+JHt0aXRsZX08L2gxPlxuICA8cD4ke2lzRGV2ID8gYDxzdHJvbmc+JHttZXNzYWdlfTwvc3Ryb25nPmAgOiBtZXNzYWdlfTwvcD5cbiAgJHtzdGFjayA/IGA8cHJlPiR7c3RhY2t9PC9wcmU+YCA6ICcnfVxuPC9ib2R5PlxuPC9odG1sPmA7XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0NBUUMsR0FFRCxtRUFBbUU7QUFFbkUsU0FBUyxZQUFZLEVBQUUsUUFBUSxRQUFRLGNBQWM7QUFFckQsTUFBTSxNQUFNLGFBQWE7QUFLekI7Ozs7Q0FJQyxHQUNELE1BQU0sYUFBcUM7RUFDekMsS0FBSztFQUNMLEtBQUs7RUFDTCxLQUFLO0VBQ0wsS0FBSztFQUNMLEtBQUs7QUFDUDtBQUNBLE9BQU8sU0FBUyxXQUFXLEdBQVc7RUFDcEMsSUFBSSxPQUFPLFFBQVEsVUFBVSxPQUFPO0VBQ3BDLE9BQU8sSUFBSSxPQUFPLENBQUMsWUFBWSxDQUFDLEtBQU8sVUFBVSxDQUFDLEdBQUcsSUFBSTtBQUMzRDtBQUVBLG1DQUFtQyxHQUNuQyxPQUFPLFNBQVMsV0FBVyxLQUFhO0VBQ3RDLE9BQU8sTUFDSixPQUFPLENBQUMsTUFBTSxTQUNkLE9BQU8sQ0FBQyxNQUFNLFVBQ2QsT0FBTyxD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
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @openelement/core/hydrate - DSD interactive runtime surface.
3
+ *
4
+ * Includes the static rendering surface plus marker-based event hydration
5
+ * and DSD shadow-root hydration helpers. Used by DSD interactive islands.
6
+ *
7
+ * ADR-0109 Phase 1: split @openelement/core into static, hydrate, and csr.
8
+ */ export * from "./static.js";
9
+ export type { BindingDescriptor, BindingDispose, BindingLifecycle } from "./binding-descriptor.js";
10
+ export { applyBindingDescriptor } from "./binding-activation.js";
11
+ export { collectEventBindings, eventRecordsToDescriptors, hydrateEventMarkers } from "./event-hydration.js";
12
+ export type { EventBinding, EventBindingRecord } from "./event-hydration.js";
13
+ export { createDsdRenderRoot, hydrateDsdEvents } from "./dsd-hydration.js";
14
+ export type { Constructor, DsdHydration } from "./dsd-hydration.js";
15
+ export { bindHydrateEvents } from "./dsd-hydration-events.js";
package/src/hydrate.js ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @openelement/core/hydrate - DSD interactive runtime surface.
3
+ *
4
+ * Includes the static rendering surface plus marker-based event hydration
5
+ * and DSD shadow-root hydration helpers. Used by DSD interactive islands.
6
+ *
7
+ * ADR-0109 Phase 1: split @openelement/core into static, hydrate, and csr.
8
+ */ export * from './static.js';
9
+ export { applyBindingDescriptor } from './binding-activation.js';
10
+ // Marker-based event hydration (DOM-specific parts not in static.ts)
11
+ export { collectEventBindings, eventRecordsToDescriptors, hydrateEventMarkers } from './event-hydration.js';
12
+ // DSD hydration contract
13
+ export { createDsdRenderRoot, hydrateDsdEvents } from './dsd-hydration.js';
14
+ export { bindHydrateEvents } from './dsd-hydration-events.js';
15
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9oeWRyYXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG9wZW5lbGVtZW50L2NvcmUvaHlkcmF0ZSAtIERTRCBpbnRlcmFjdGl2ZSBydW50aW1lIHN1cmZhY2UuXG4gKlxuICogSW5jbHVkZXMgdGhlIHN0YXRpYyByZW5kZXJpbmcgc3VyZmFjZSBwbHVzIG1hcmtlci1iYXNlZCBldmVudCBoeWRyYXRpb25cbiAqIGFuZCBEU0Qgc2hhZG93LXJvb3QgaHlkcmF0aW9uIGhlbHBlcnMuIFVzZWQgYnkgRFNEIGludGVyYWN0aXZlIGlzbGFuZHMuXG4gKlxuICogQURSLTAxMDkgUGhhc2UgMTogc3BsaXQgQG9wZW5lbGVtZW50L2NvcmUgaW50byBzdGF0aWMsIGh5ZHJhdGUsIGFuZCBjc3IuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9zdGF0aWMuanMnO1xuXG4vLyBCaW5kaW5nIGxheWVyXG5leHBvcnQgdHlwZSB7IEJpbmRpbmdEZXNjcmlwdG9yLCBCaW5kaW5nRGlzcG9zZSwgQmluZGluZ0xpZmVjeWNsZSB9IGZyb20gJy4vYmluZGluZy1kZXNjcmlwdG9yLmpzJztcbmV4cG9ydCB7IGFwcGx5QmluZGluZ0Rlc2NyaXB0b3IgfSBmcm9tICcuL2JpbmRpbmctYWN0aXZhdGlvbi5qcyc7XG5cbi8vIE1hcmtlci1iYXNlZCBldmVudCBoeWRyYXRpb24gKERPTS1zcGVjaWZpYyBwYXJ0cyBub3QgaW4gc3RhdGljLnRzKVxuZXhwb3J0IHtcbiAgY29sbGVjdEV2ZW50QmluZGluZ3MsXG4gIGV2ZW50UmVjb3Jkc1RvRGVzY3JpcHRvcnMsXG4gIGh5ZHJhdGVFdmVudE1hcmtlcnMsXG59IGZyb20gJy4vZXZlbnQtaHlkcmF0aW9uLmpzJztcbmV4cG9ydCB0eXBlIHsgRXZlbnRCaW5kaW5nLCBFdmVudEJpbmRpbmdSZWNvcmQgfSBmcm9tICcuL2V2ZW50LWh5ZHJhdGlvbi5qcyc7XG5cbi8vIERTRCBoeWRyYXRpb24gY29udHJhY3RcbmV4cG9ydCB7IGNyZWF0ZURzZFJlbmRlclJvb3QsIGh5ZHJhdGVEc2RFdmVudHMgfSBmcm9tICcuL2RzZC1oeWRyYXRpb24uanMnO1xuZXhwb3J0IHR5cGUgeyBDb25zdHJ1Y3RvciwgRHNkSHlkcmF0aW9uIH0gZnJvbSAnLi9kc2QtaHlkcmF0aW9uLmpzJztcbmV4cG9ydCB7IGJpbmRIeWRyYXRlRXZlbnRzIH0gZnJvbSAnLi9kc2QtaHlkcmF0aW9uLWV2ZW50cy5qcyc7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Q0FPQyxHQUVELGNBQWMsY0FBYztBQUk1QixTQUFTLHNCQUFzQixRQUFRLDBCQUEwQjtBQUVqRSxxRUFBcUU7QUFDckUsU0FDRSxvQkFBb0IsRUFDcEIseUJBQXlCLEVBQ3pCLG1CQUFtQixRQUNkLHVCQUF1QjtBQUc5Qix5QkFBeUI7QUFDekIsU0FBUyxtQkFBbUIsRUFBRSxnQkFBZ0IsUUFBUSxxQkFBcUI7QUFFM0UsU0FBUyxpQkFBaUIsUUFBUSw0QkFBNEIifQ==
package/src/index.d.ts ADDED
@@ -0,0 +1,58 @@
1
+ /**
2
+ * @openelement/core - Pure runtime.
3
+ *
4
+ * openElement is a static-first framework with a pure runtime core:
5
+ * - Zero node:* imports - no filesystem, no process, no path
6
+ * - Zero Vite dependency - no Plugin, no build orchestration
7
+ * - Zero npm: specifiers - works in Deno, Node, Bun, Edge
8
+ * - Pure Web Standard: URL, fetch, import.meta.url, console
9
+ *
10
+ * Rendering: DSD (Declarative Shadow DOM) string concatenation
11
+ * Islands: Custom Element registration + prop deserialization
12
+ *
13
+ * Build orchestration (Vite plugins) lives in @openelement/adapter-vite.
14
+ * For the unified openElement() entry, use @openelement/app/vite instead.
15
+ */ export type { AppShellConfig, AppShellDefinition, ComponentLayer, FrameworkOptions, HydrateEventDescriptor, HydrationStrategy, IsrManifestEntry, LayoutsConfig, LocalePath, OpenElementApiContext, OpenElementBuildContextLike, OpenElementMiddleware, OpenElementMiddlewareContext, OpenElementRenderer, RegistryIndex, RegistryIndexEntry, RouteEntry, SafeHtml, SpecialFileType, StrategySource, UnsafeHtml, ValidationError, ValidationResult, ValidationWarning } from '@openelement/protocol/framework';
16
+ export type { IslandDescriptor, SsrContext } from '@openelement/protocol/context';
17
+ export { ERROR_PREFIX, ErrorCode, OpenElementError, PropValidationError, RenderError, reportError, setErrorTelemetryHook, SsrRenderError } from "./errors.js";
18
+ export type { ErrorPhase, ErrorSeverity, ErrorTelemetryHook } from '@openelement/protocol/errors';
19
+ export { createSsrContext, extractParams, parseQuery } from "./context.js";
20
+ export { renderSsrError, wrapInDocument } from "./html-escape.js";
21
+ export { createIsrCacheKey, isIsrRouteConfig, MemoryIsrCache } from "./isr.js";
22
+ export type { CacheAdapter, CacheEntry, IsrCacheEntry, IsrCacheResult, IsrCacheState, IsrRouteConfig } from '@openelement/protocol/isr';
23
+ export { findIsrManifestEntry, renderIsrResponse } from "./isr-runtime.js";
24
+ export type { IsrRuntimeOptions, IsrRuntimeRenderContext, IsrRuntimeRenderResult, IsrRuntimeResult, IsrRuntimeState } from "./isr-runtime.js";
25
+ export { StyleSheet } from "./style-sheet.js";
26
+ export type { StyleSheetLike, StyleSheetRule } from '@openelement/protocol/style-sheet';
27
+ export { bindHydrateEvents } from "./dsd-hydration-events.js";
28
+ export type { Constructor, DsdHydration } from "./dsd-hydration.js";
29
+ export { createRenderDsdStreamMetrics, renderDsd, renderDsdStream } from "./render-dsd.js";
30
+ export type { RenderDsdOptions } from "./render-dsd.js";
31
+ export type { RenderDsdStreamChunk, RenderDsdStreamComponent, RenderDsdStreamMetrics, RenderDsdStreamOptions } from "./render-dsd-stream.js";
32
+ export { camelToKebab, serializeAttrs } from "./render-ir.js";
33
+ export type { DomSimulationAttempt, DomSimulationReport, DsdBuildReport, DsdComponent, DsdComponentConstructor, DsdHydrationHintSummary, DsdHydrationStrategySummary, DsdMetricsSummary, DsdOptions, DsdPageDiagnostics, DsdRenderMetrics, HydrationHint, IsrRouteRecord, ManifestDecision, RendererProtocol, RenderErrorCode, RenderHooks, RenderInput, RenderOutput, RenderPhase, SsrAdmissionDecision } from '@openelement/protocol/render';
34
+ export type { OpenElementAttribute, OpenElementCssPart, OpenElementCssProperty, OpenElementDeclaration, OpenElementEvent, OpenElementExport, OpenElementExtensions, OpenElementMember, OpenElementModule, OpenElementPackageExtensions, OpenElementPackageManifest, OpenElementSlot } from '@openelement/protocol/manifest';
35
+ export type { CemCompatibilityReport, CompatibilityClassification, CompatibilityTier, ManifestValidationReport, ValidatedTag, ValidationDiagnostic } from '@openelement/protocol/manifest';
36
+ export { escapeAttr, escapeAttrValue, escapeHtml } from "./html-escape.js";
37
+ export { isSignalLike, unwrapSignalLike } from '@openelement/signal';
38
+ export type { SignalLike, Unsubscribe } from '@openelement/protocol/signal';
39
+ export { consumeContext, type Context, createContext, provideContext } from "./signal-context.js";
40
+ export { createLogger } from "./logger.js";
41
+ /** @internal — use @openelement/core/security subpath */ export { DANGEROUS_KEYS } from "./security.js";
42
+ export { isValidTagName } from "./tag-utils.js";
43
+ export { bindSsrProps, defineCustomElement, defineIsland, getIslandMeta, getSsrProps } from "./island.js";
44
+ export type { IslandMeta, IslandOptions } from '@openelement/protocol/island';
45
+ export { transformIslandSource } from "./island-transform.js";
46
+ export type { IslandTransformOptions, IslandTransformResult } from '@openelement/protocol/island';
47
+ export { applyBindingDescriptor } from "./binding-activation.js";
48
+ export type { BindingDescriptor, BindingDispose, BindingLifecycle } from "./binding-descriptor.js";
49
+ export type { Action, ActionContext, DataAdapter, Loader, LoaderContext } from '@openelement/protocol/data';
50
+ export { clear as clearRegistry, generateIndex, getAll as getAllManifests, getByTagName, register as registerManifest, validate as validateManifest } from "./registry.js";
51
+ export type { VNode } from '@openelement/protocol/vnode';
52
+ export { isVNode } from "./vnode.js";
53
+ export { Fragment, trustedHtml } from "./jsx-runtime.js";
54
+ export { renderToDom } from "./jsx-render-dom.js";
55
+ export { renderDsdTree } from "./render-ir.js";
56
+ export { collectEventBindings, createEventMarkerContext, type EventBindingRecord, type EventMarkerContext, eventMarkerId, eventTypeFromProp, hydrateEventMarkers, serializeEventMarkers } from "./event-hydration.js";
57
+ export { disposeStaticProps, handleStaticPropAttributeChange, initializeStaticProps, registerStaticObservedAttributes, syncStaticPropsFromAttributes, unwrap } from "./prop.js";
58
+ export type { NormalizedPropDecl, PropDecl, PropDeclFull, PropDeclShorthand, PropsFrom, PropType } from '@openelement/protocol/prop';
package/src/index.js ADDED
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @openelement/core - Pure runtime.
3
+ *
4
+ * openElement is a static-first framework with a pure runtime core:
5
+ * - Zero node:* imports - no filesystem, no process, no path
6
+ * - Zero Vite dependency - no Plugin, no build orchestration
7
+ * - Zero npm: specifiers - works in Deno, Node, Bun, Edge
8
+ * - Pure Web Standard: URL, fetch, import.meta.url, console
9
+ *
10
+ * Rendering: DSD (Declarative Shadow DOM) string concatenation
11
+ * Islands: Custom Element registration + prop deserialization
12
+ *
13
+ * Build orchestration (Vite plugins) lives in @openelement/adapter-vite.
14
+ * For the unified openElement() entry, use @openelement/app/vite instead.
15
+ */ // --- Public API re-exports -----------------------------------------
16
+ export { ERROR_PREFIX, ErrorCode, OpenElementError, PropValidationError, RenderError, reportError, setErrorTelemetryHook, SsrRenderError } from './errors.js';
17
+ export { createSsrContext, extractParams, parseQuery } from './context.js';
18
+ export { renderSsrError, wrapInDocument } from './html-escape.js';
19
+ export { createIsrCacheKey, isIsrRouteConfig, MemoryIsrCache } from './isr.js';
20
+ export { findIsrManifestEntry, renderIsrResponse } from './isr-runtime.js';
21
+ export { StyleSheet } from './style-sheet.js';
22
+ export { bindHydrateEvents } from './dsd-hydration-events.js';
23
+ export { createRenderDsdStreamMetrics, renderDsd, renderDsdStream } from './render-dsd.js';
24
+ export { camelToKebab, serializeAttrs } from './render-ir.js';
25
+ export { escapeAttr, escapeAttrValue, escapeHtml } from './html-escape.js';
26
+ export { // v0.24.3: Neutral signal utilities — no template dependency
27
+ isSignalLike, unwrapSignalLike } from '@openelement/signal';
28
+ export { consumeContext, createContext, provideContext } from './signal-context.js';
29
+ export { createLogger } from './logger.js';
30
+ /** @internal — use @openelement/core/security subpath */ export { DANGEROUS_KEYS } from './security.js';
31
+ export { isValidTagName } from './tag-utils.js';
32
+ export { bindSsrProps, defineCustomElement, defineIsland, getIslandMeta, getSsrProps } from './island.js';
33
+ export { transformIslandSource } from './island-transform.js';
34
+ // Unified binding layer (ADR-0109 Phase 1)
35
+ export { applyBindingDescriptor } from './binding-activation.js';
36
+ // WC Package Protocol (v0.17+)
37
+ export { clear as clearRegistry, generateIndex, getAll as getAllManifests, getByTagName, register as registerManifest, validate as validateManifest } from './registry.js';
38
+ export { isVNode } from './vnode.js';
39
+ export { Fragment, trustedHtml } from './jsx-runtime.js';
40
+ // Renderers
41
+ export { renderToDom } from './jsx-render-dom.js';
42
+ export { renderDsdTree } from './render-ir.js';
43
+ export { collectEventBindings, createEventMarkerContext, eventMarkerId, eventTypeFromProp, hydrateEventMarkers, serializeEventMarkers } from './event-hydration.js';
44
+ // static props runtime + Signal unwrap
45
+ export { disposeStaticProps, handleStaticPropAttributeChange, initializeStaticProps, registerStaticObservedAttributes, syncStaticPropsFromAttributes, unwrap } from './prop.js';
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBvcGVuZWxlbWVudC9jb3JlIC0gUHVyZSBydW50aW1lLlxuICpcbiAqIG9wZW5FbGVtZW50IGlzIGEgc3RhdGljLWZpcnN0IGZyYW1ld29yayB3aXRoIGEgcHVyZSBydW50aW1lIGNvcmU6XG4gKiAtIFplcm8gbm9kZToqIGltcG9ydHMgLSBubyBmaWxlc3lzdGVtLCBubyBwcm9jZXNzLCBubyBwYXRoXG4gKiAtIFplcm8gVml0ZSBkZXBlbmRlbmN5IC0gbm8gUGx1Z2luLCBubyBidWlsZCBvcmNoZXN0cmF0aW9uXG4gKiAtIFplcm8gbnBtOiBzcGVjaWZpZXJzIC0gd29ya3MgaW4gRGVubywgTm9kZSwgQnVuLCBFZGdlXG4gKiAtIFB1cmUgV2ViIFN0YW5kYXJkOiBVUkwsIGZldGNoLCBpbXBvcnQubWV0YS51cmwsIGNvbnNvbGVcbiAqXG4gKiBSZW5kZXJpbmc6IERTRCAoRGVjbGFyYXRpdmUgU2hhZG93IERPTSkgc3RyaW5nIGNvbmNhdGVuYXRpb25cbiAqIElzbGFuZHM6IEN1c3RvbSBFbGVtZW50IHJlZ2lzdHJhdGlvbiArIHByb3AgZGVzZXJpYWxpemF0aW9uXG4gKlxuICogQnVpbGQgb3JjaGVzdHJhdGlvbiAoVml0ZSBwbHVnaW5zKSBsaXZlcyBpbiBAb3BlbmVsZW1lbnQvYWRhcHRlci12aXRlLlxuICogRm9yIHRoZSB1bmlmaWVkIG9wZW5FbGVtZW50KCkgZW50cnksIHVzZSBAb3BlbmVsZW1lbnQvYXBwL3ZpdGUgaW5zdGVhZC5cbiAqL1xuXG4vLyAtLS0gUHVibGljIEFQSSByZS1leHBvcnRzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCB0eXBlIHtcbiAgQXBwU2hlbGxDb25maWcsXG4gIEFwcFNoZWxsRGVmaW5pdGlvbixcbiAgQ29tcG9uZW50TGF5ZXIsXG4gIEZyYW1ld29ya09wdGlvbnMsXG4gIEh5ZHJhdGVFdmVudERlc2NyaXB0b3IsXG4gIEh5ZHJhdGlvblN0cmF0ZWd5LFxuICBJc3JNYW5pZmVzdEVudHJ5LFxuICBMYXlvdXRzQ29uZmlnLFxuICBMb2NhbGVQYXRoLFxuICBPcGVuRWxlbWVudEFwaUNvbnRleHQsXG4gIE9wZW5FbGVtZW50QnVpbGRDb250ZXh0TGlrZSxcbiAgT3BlbkVsZW1lbnRNaWRkbGV3YXJlLFxuICBPcGVuRWxlbWVudE1pZGRsZXdhcmVDb250ZXh0LFxuICBPcGVuRWxlbWVudFJlbmRlcmVyLFxuICBSZWdpc3RyeUluZGV4LFxuICBSZWdpc3RyeUluZGV4RW50cnksXG4gIFJvdXRlRW50cnksXG4gIFNhZmVIdG1sLFxuICBTcGVjaWFsRmlsZVR5cGUsXG4gIFN0cmF0ZWd5U291cmNlLFxuICBVbnNhZmVIdG1sLFxuICBWYWxpZGF0aW9uRXJyb3IsXG4gIFZhbGlkYXRpb25SZXN1bHQsXG4gIFZhbGlkYXRpb25XYXJuaW5nLFxufSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvZnJhbWV3b3JrJztcbmV4cG9ydCB0eXBlIHsgSXNsYW5kRGVzY3JpcHRvciwgU3NyQ29udGV4dCB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9jb250ZXh0JztcblxuZXhwb3J0IHtcbiAgRVJST1JfUFJFRklYLFxuICBFcnJvckNvZGUsXG4gIE9wZW5FbGVtZW50RXJyb3IsXG4gIFByb3BWYWxpZGF0aW9uRXJyb3IsXG4gIFJlbmRlckVycm9yLFxuICByZXBvcnRFcnJvcixcbiAgc2V0RXJyb3JUZWxlbWV0cnlIb29rLFxuICBTc3JSZW5kZXJFcnJvcixcbn0gZnJvbSAnLi9lcnJvcnMuanMnO1xuZXhwb3J0IHR5cGUgeyBFcnJvclBoYXNlLCBFcnJvclNldmVyaXR5LCBFcnJvclRlbGVtZXRyeUhvb2sgfSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvZXJyb3JzJztcbmV4cG9ydCB7IGNyZWF0ZVNzckNvbnRleHQsIGV4dHJhY3RQYXJhbXMsIHBhcnNlUXVlcnkgfSBmcm9tICcuL2NvbnRleHQuanMnO1xuZXhwb3J0IHsgcmVuZGVyU3NyRXJyb3IsIHdyYXBJbkRvY3VtZW50IH0gZnJvbSAnLi9odG1sLWVzY2FwZS5qcyc7XG5leHBvcnQgeyBjcmVhdGVJc3JDYWNoZUtleSwgaXNJc3JSb3V0ZUNvbmZpZywgTWVtb3J5SXNyQ2FjaGUgfSBmcm9tICcuL2lzci5qcyc7XG5leHBvcnQgdHlwZSB7XG4gIENhY2hlQWRhcHRlcixcbiAgQ2FjaGVFbnRyeSxcbiAgSXNyQ2FjaGVFbnRyeSxcbiAgSXNyQ2FjaGVSZXN1bHQsXG4gIElzckNhY2hlU3RhdGUsXG4gIElzclJvdXRlQ29uZmlnLFxufSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvaXNyJztcbmV4cG9ydCB7IGZpbmRJc3JNYW5pZmVzdEVudHJ5LCByZW5kZXJJc3JSZXNwb25zZSB9IGZyb20gJy4vaXNyLXJ1bnRpbWUuanMnO1xuZXhwb3J0IHR5cGUge1xuICBJc3JSdW50aW1lT3B0aW9ucyxcbiAgSXNyUnVudGltZVJlbmRlckNvbnRleHQsXG4gIElzclJ1bnRpbWVSZW5kZXJSZXN1bHQsXG4gIElzclJ1bnRpbWVSZXN1bHQsXG4gIElzclJ1bnRpbWVTdGF0ZSxcbn0gZnJvbSAnLi9pc3ItcnVudGltZS5qcyc7XG5leHBvcnQgeyBTdHlsZVNoZWV0IH0gZnJvbSAnLi9zdHlsZS1zaGVldC5qcyc7XG5leHBvcnQgdHlwZSB7IFN0eWxlU2hlZXRMaWtlLCBTdHlsZVNoZWV0UnVsZSB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9zdHlsZS1zaGVldCc7XG5leHBvcnQgeyBiaW5kSHlkcmF0ZUV2ZW50cyB9IGZyb20gJy4vZHNkLWh5ZHJhdGlvbi1ldmVudHMuanMnO1xuZXhwb3J0IHR5cGUgeyBDb25zdHJ1Y3RvciwgRHNkSHlkcmF0aW9uIH0gZnJvbSAnLi9kc2QtaHlkcmF0aW9uLmpzJztcbmV4cG9ydCB7IGNyZWF0ZVJlbmRlckRzZFN0cmVhbU1ldHJpY3MsIHJlbmRlckRzZCwgcmVuZGVyRHNkU3RyZWFtIH0gZnJvbSAnLi9yZW5kZXItZHNkLmpzJztcbmV4cG9ydCB0eXBlIHsgUmVuZGVyRHNkT3B0aW9ucyB9IGZyb20gJy4vcmVuZGVyLWRzZC5qcyc7XG5leHBvcnQgdHlwZSB7XG4gIFJlbmRlckRzZFN0cmVhbUNodW5rLFxuICBSZW5kZXJEc2RTdHJlYW1Db21wb25lbnQsXG4gIFJlbmRlckRzZFN0cmVhbU1ldHJpY3MsXG4gIFJlbmRlckRzZFN0cmVhbU9wdGlvbnMsXG59IGZyb20gJy4vcmVuZGVyLWRzZC1zdHJlYW0uanMnO1xuZXhwb3J0IHsgY2FtZWxUb0tlYmFiLCBzZXJpYWxpemVBdHRycyB9IGZyb20gJy4vcmVuZGVyLWlyLmpzJztcbmV4cG9ydCB0eXBlIHtcbiAgRG9tU2ltdWxhdGlvbkF0dGVtcHQsXG4gIERvbVNpbXVsYXRpb25SZXBvcnQsXG4gIERzZEJ1aWxkUmVwb3J0LFxuICBEc2RDb21wb25lbnQsXG4gIERzZENvbXBvbmVudENvbnN0cnVjdG9yLFxuICBEc2RIeWRyYXRpb25IaW50U3VtbWFyeSxcbiAgRHNkSHlkcmF0aW9uU3RyYXRlZ3lTdW1tYXJ5LFxuICBEc2RNZXRyaWNzU3VtbWFyeSxcbiAgRHNkT3B0aW9ucyxcbiAgRHNkUGFnZURpYWdub3N0aWNzLFxuICBEc2RSZW5kZXJNZXRyaWNzLFxuICBIeWRyYXRpb25IaW50LFxuICBJc3JSb3V0ZVJlY29yZCxcbiAgTWFuaWZlc3REZWNpc2lvbixcbiAgUmVuZGVyZXJQcm90b2NvbCxcbiAgUmVuZGVyRXJyb3JDb2RlLFxuICBSZW5kZXJIb29rcyxcbiAgUmVuZGVySW5wdXQsXG4gIFJlbmRlck91dHB1dCxcbiAgUmVuZGVyUGhhc2UsXG4gIFNzckFkbWlzc2lvbkRlY2lzaW9uLFxufSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvcmVuZGVyJztcbmV4cG9ydCB0eXBlIHtcbiAgT3BlbkVsZW1lbnRBdHRyaWJ1dGUsXG4gIE9wZW5FbGVtZW50Q3NzUGFydCxcbiAgT3BlbkVsZW1lbnRDc3NQcm9wZXJ0eSxcbiAgT3BlbkVsZW1lbnREZWNsYXJhdGlvbixcbiAgT3BlbkVsZW1lbnRFdmVudCxcbiAgT3BlbkVsZW1lbnRFeHBvcnQsXG4gIE9wZW5FbGVtZW50RXh0ZW5zaW9ucyxcbiAgT3BlbkVsZW1lbnRNZW1iZXIsXG4gIE9wZW5FbGVtZW50TW9kdWxlLFxuICBPcGVuRWxlbWVudFBhY2thZ2VFeHRlbnNpb25zLFxuICBPcGVuRWxlbWVudFBhY2thZ2VNYW5pZmVzdCxcbiAgT3BlbkVsZW1lbnRTbG90LFxufSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvbWFuaWZlc3QnO1xuZXhwb3J0IHR5cGUge1xuICBDZW1Db21wYXRpYmlsaXR5UmVwb3J0LFxuICBDb21wYXRpYmlsaXR5Q2xhc3NpZmljYXRpb24sXG4gIENvbXBhdGliaWxpdHlUaWVyLFxuICBNYW5pZmVzdFZhbGlkYXRpb25SZXBvcnQsXG4gIFZhbGlkYXRlZFRhZyxcbiAgVmFsaWRhdGlvbkRpYWdub3N0aWMsXG59IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9tYW5pZmVzdCc7XG5leHBvcnQgeyBlc2NhcGVBdHRyLCBlc2NhcGVBdHRyVmFsdWUsIGVzY2FwZUh0bWwgfSBmcm9tICcuL2h0bWwtZXNjYXBlLmpzJztcbmV4cG9ydCB7XG4gIC8vIHYwLjI0LjM6IE5ldXRyYWwgc2lnbmFsIHV0aWxpdGllcyDigJQgbm8gdGVtcGxhdGUgZGVwZW5kZW5jeVxuICBpc1NpZ25hbExpa2UsXG4gIHVud3JhcFNpZ25hbExpa2UsXG59IGZyb20gJ0BvcGVuZWxlbWVudC9zaWduYWwnO1xuZXhwb3J0IHR5cGUgeyBTaWduYWxMaWtlLCBVbnN1YnNjcmliZSB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9zaWduYWwnO1xuZXhwb3J0IHsgY29uc3VtZUNvbnRleHQsIHR5cGUgQ29udGV4dCwgY3JlYXRlQ29udGV4dCwgcHJvdmlkZUNvbnRleHQgfSBmcm9tICcuL3NpZ25hbC1jb250ZXh0LmpzJztcbmV4cG9ydCB7IGNyZWF0ZUxvZ2dlciB9IGZyb20gJy4vbG9nZ2VyLmpzJztcbi8qKiBAaW50ZXJuYWwg4oCUIHVzZSBAb3BlbmVsZW1lbnQvY29yZS9zZWN1cml0eSBzdWJwYXRoICovXG5leHBvcnQgeyBEQU5HRVJPVVNfS0VZUyB9IGZyb20gJy4vc2VjdXJpdHkuanMnO1xuZXhwb3J0IHsgaXNWYWxpZFRhZ05hbWUgfSBmcm9tICcuL3RhZy11dGlscy5qcyc7XG5leHBvcnQge1xuICBiaW5kU3NyUHJvcHMsXG4gIGRlZmluZUN1c3RvbUVsZW1lbnQsXG4gIGRlZmluZUlzbGFuZCxcbiAgZ2V0SXNsYW5kTWV0YSxcbiAgZ2V0U3NyUHJvcHMsXG59IGZyb20gJy4vaXNsYW5kLmpzJztcbmV4cG9ydCB0eXBlIHsgSXNsYW5kTWV0YSwgSXNsYW5kT3B0aW9ucyB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9pc2xhbmQnO1xuZXhwb3J0IHsgdHJhbnNmb3JtSXNsYW5kU291cmNlIH0gZnJvbSAnLi9pc2xhbmQtdHJhbnNmb3JtLmpzJztcbmV4cG9ydCB0eXBlIHsgSXNsYW5kVHJhbnNmb3JtT3B0aW9ucywgSXNsYW5kVHJhbnNmb3JtUmVzdWx0IH0gZnJvbSAnQG9wZW5lbGVtZW50L3Byb3RvY29sL2lzbGFuZCc7XG5cbi8vIFVuaWZpZWQgYmluZGluZyBsYXllciAoQURSLTAxMDkgUGhhc2UgMSlcbmV4cG9ydCB7IGFwcGx5QmluZGluZ0Rlc2NyaXB0b3IgfSBmcm9tICcuL2JpbmRpbmctYWN0aXZhdGlvbi5qcyc7XG5leHBvcnQgdHlwZSB7IEJpbmRpbmdEZXNjcmlwdG9yLCBCaW5kaW5nRGlzcG9zZSwgQmluZGluZ0xpZmVjeWNsZSB9IGZyb20gJy4vYmluZGluZy1kZXNjcmlwdG9yLmpzJztcblxuLy8gRGF0YSBhZGFwdGVycyDigJQgdHlwZSBjb250cmFjdCBzdXJmYWNlIG9ubHkgKEFEUi0wMDk1KVxuZXhwb3J0IHR5cGUge1xuICBBY3Rpb24sXG4gIEFjdGlvbkNvbnRleHQsXG4gIERhdGFBZGFwdGVyLFxuICBMb2FkZXIsXG4gIExvYWRlckNvbnRleHQsXG59IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC9kYXRhJztcblxuLy8gV0MgUGFja2FnZSBQcm90b2NvbCAodjAuMTcrKVxuZXhwb3J0IHtcbiAgY2xlYXIgYXMgY2xlYXJSZWdpc3RyeSxcbiAgZ2VuZXJhdGVJbmRleCxcbiAgZ2V0QWxsIGFzIGdldEFsbE1hbmlmZXN0cyxcbiAgZ2V0QnlUYWdOYW1lLFxuICByZWdpc3RlciBhcyByZWdpc3Rlck1hbmlmZXN0LFxuICB2YWxpZGF0ZSBhcyB2YWxpZGF0ZU1hbmlmZXN0LFxufSBmcm9tICcuL3JlZ2lzdHJ5LmpzJztcbi8vIHYwLjI0LjEgKEFEUi0wMDU3KTogSlNYICsgU2lnbmFsIGNvbXBvbmVudCBtb2RlbFxuLy8gVk5vZGUgJiBqc3gtcnVudGltZVxuZXhwb3J0IHR5cGUgeyBWTm9kZSB9IGZyb20gJ0BvcGVuZWxlbWVudC9wcm90b2NvbC92bm9kZSc7XG5leHBvcnQgeyBpc1ZOb2RlIH0gZnJvbSAnLi92bm9kZS5qcyc7XG5leHBvcnQgeyBGcmFnbWVudCwgdHJ1c3RlZEh0bWwgfSBmcm9tICcuL2pzeC1ydW50aW1lLmpzJztcbi8vIFJlbmRlcmVyc1xuZXhwb3J0IHsgcmVuZGVyVG9Eb20gfSBmcm9tICcuL2pzeC1yZW5kZXItZG9tLmpzJztcbmV4cG9ydCB7IHJlbmRlckRzZFRyZWUgfSBmcm9tICcuL3JlbmRlci1pci5qcyc7XG5leHBvcnQge1xuICBjb2xsZWN0RXZlbnRCaW5kaW5ncyxcbiAgY3JlYXRlRXZlbnRNYXJrZXJDb250ZXh0LFxuICB0eXBlIEV2ZW50QmluZGluZ1JlY29yZCxcbiAgdHlwZSBFdmVudE1hcmtlckNvbnRleHQsXG4gIGV2ZW50TWFya2VySWQsXG4gIGV2ZW50VHlwZUZyb21Qcm9wLFxuICBoeWRyYXRlRXZlbnRNYXJrZXJzLFxuICBzZXJpYWxpemVFdmVudE1hcmtlcnMsXG59IGZyb20gJy4vZXZlbnQtaHlkcmF0aW9uLmpzJztcbi8vIHN0YXRpYyBwcm9wcyBydW50aW1lICsgU2lnbmFsIHVud3JhcFxuZXhwb3J0IHtcbiAgZGlzcG9zZVN0YXRpY1Byb3BzLFxuICBoYW5kbGVTdGF0aWNQcm9wQXR0cmlidXRlQ2hhbmdlLFxuICBpbml0aWFsaXplU3RhdGljUHJvcHMsXG4gIHJlZ2lzdGVyU3RhdGljT2JzZXJ2ZWRBdHRyaWJ1dGVzLFxuICBzeW5jU3RhdGljUHJvcHNGcm9tQXR0cmlidXRlcyxcbiAgdW53cmFwLFxufSBmcm9tICcuL3Byb3AuanMnO1xuZXhwb3J0IHR5cGUge1xuICBOb3JtYWxpemVkUHJvcERlY2wsXG4gIFByb3BEZWNsLFxuICBQcm9wRGVjbEZ1bGwsXG4gIFByb3BEZWNsU2hvcnRoYW5kLFxuICBQcm9wc0Zyb20sXG4gIFByb3BUeXBlLFxufSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvcHJvcCc7XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7O0NBY0MsR0FFRCxzRUFBc0U7QUE4QnRFLFNBQ0UsWUFBWSxFQUNaLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsbUJBQW1CLEVBQ25CLFdBQVcsRUFDWCxXQUFXLEVBQ1gscUJBQXFCLEVBQ3JCLGNBQWMsUUFDVCxjQUFjO0FBRXJCLFNBQVMsZ0JBQWdCLEVBQUUsYUFBYSxFQUFFLFVBQVUsUUFBUSxlQUFlO0FBQzNFLFNBQVMsY0FBYyxFQUFFLGNBQWMsUUFBUSxtQkFBbUI7QUFDbEUsU0FBUyxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLFFBQVEsV0FBVztBQVMvRSxTQUFTLG9CQUFvQixFQUFFLGlCQUFpQixRQUFRLG1CQUFtQjtBQVEzRSxTQUFTLFVBQVUsUUFBUSxtQkFBbUI7QUFFOUMsU0FBUyxpQkFBaUIsUUFBUSw0QkFBNEI7QUFFOUQsU0FBUyw0QkFBNEIsRUFBRSxTQUFTLEVBQUUsZUFBZSxRQUFRLGtCQUFrQjtBQVEzRixTQUFTLFlBQVksRUFBRSxjQUFjLFFBQVEsaUJBQWlCO0FBOEM5RCxTQUFTLFVBQVUsRUFBRSxlQUFlLEVBQUUsVUFBVSxRQUFRLG1CQUFtQjtBQUMzRSxTQUNFLDZEQUE2RDtBQUM3RCxZQUFZLEVBQ1osZ0JBQWdCLFFBQ1gsc0JBQXNCO0FBRTdCLFNBQVMsY0FBYyxFQUFnQixhQUFhLEVBQUUsY0FBYyxRQUFRLHNCQUFzQjtBQUNsRyxTQUFTLFlBQVksUUFBUSxjQUFjO0FBQzNDLHVEQUF1RCxHQUN2RCxTQUFTLGNBQWMsUUFBUSxnQkFBZ0I7QUFDL0MsU0FBUyxjQUFjLFFBQVEsaUJBQWlCO0FBQ2hELFNBQ0UsWUFBWSxFQUNaLG1CQUFtQixFQUNuQixZQUFZLEVBQ1osYUFBYSxFQUNiLFdBQVcsUUFDTixjQUFjO0FBRXJCLFNBQVMscUJBQXFCLFFBQVEsd0JBQXdCO0FBRzlELDJDQUEyQztBQUMzQyxTQUFTLHNCQUFzQixRQUFRLDBCQUEwQjtBQVlqRSwrQkFBK0I7QUFDL0IsU0FDRSxTQUFTLGFBQWEsRUFDdEIsYUFBYSxFQUNiLFVBQVUsZUFBZSxFQUN6QixZQUFZLEVBQ1osWUFBWSxnQkFBZ0IsRUFDNUIsWUFBWSxnQkFBZ0IsUUFDdkIsZ0JBQWdCO0FBSXZCLFNBQVMsT0FBTyxRQUFRLGFBQWE7QUFDckMsU0FBUyxRQUFRLEVBQUUsV0FBVyxRQUFRLG1CQUFtQjtBQUN6RCxZQUFZO0FBQ1osU0FBUyxXQUFXLFFBQVEsc0JBQXNCO0FBQ2xELFNBQVMsYUFBYSxRQUFRLGlCQUFpQjtBQUMvQyxTQUNFLG9CQUFvQixFQUNwQix3QkFBd0IsRUFHeEIsYUFBYSxFQUNiLGlCQUFpQixFQUNqQixtQkFBbUIsRUFDbkIscUJBQXFCLFFBQ2hCLHVCQUF1QjtBQUM5Qix1Q0FBdUM7QUFDdkMsU0FDRSxrQkFBa0IsRUFDbEIsK0JBQStCLEVBQy9CLHFCQUFxQixFQUNyQixnQ0FBZ0MsRUFDaEMsNkJBQTZCLEVBQzdCLE1BQU0sUUFDRCxZQUFZIn0=
@@ -0,0 +1,14 @@
1
+ /**
2
+ * @openelement/core — Island transform core logic.
3
+ *
4
+ * Pure function: injects island metadata markers into source code.
5
+ * Zero Vite dependency. Usable with any build tool.
6
+ */ import type { IslandTransformOptions, IslandTransformResult } from '@openelement/protocol/island';
7
+ export type { IslandTransformOptions, IslandTransformResult };
8
+ /**
9
+ * Inject island metadata markers into source code.
10
+ *
11
+ * Only transforms files inside the islands directory.
12
+ * Tag names must be lowercase + hyphens (Custom Elements spec).
13
+ * Unsafe characters cause a thrown error.
14
+ */ export declare function transformIslandSource(source: string, options: IslandTransformOptions): IslandTransformResult;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * @openelement/core — Island transform core logic.
3
+ *
4
+ * Pure function: injects island metadata markers into source code.
5
+ * Zero Vite dependency. Usable with any build tool.
6
+ */ /**
7
+ * Inject island metadata markers into source code.
8
+ *
9
+ * Only transforms files inside the islands directory.
10
+ * Tag names must be lowercase + hyphens (Custom Elements spec).
11
+ * Unsafe characters cause a thrown error.
12
+ */ export function transformIslandSource(source, options) {
13
+ const { islandsDir, filePath } = options;
14
+ // Normalize to forward slashes and ensure leading slash for reliable matching
15
+ let normalizedPath = filePath.replace(/\\/g, '/');
16
+ if (!normalizedPath.startsWith('/')) {
17
+ normalizedPath = '/' + normalizedPath;
18
+ }
19
+ const normalizedIslandsDir = islandsDir.replace(/\\/g, '/');
20
+ // Only transform files in the islands directory
21
+ if (!normalizedPath.includes(`/${normalizedIslandsDir}/`)) {
22
+ return {
23
+ code: source,
24
+ islands: []
25
+ };
26
+ }
27
+ // Extract tag name from file path: replace path separators with hyphens
28
+ // matching route-scanner.ts fileToTagName() behavior.
29
+ // e.g. "nested/my-widget.tsx" → "my-widget", "my-widget.tsx" → "my-widget"
30
+ const relativePath = normalizedPath.split(`/${islandsDir}/`)[1] ?? normalizedPath.split('/').pop();
31
+ const tagName = relativePath.replace(/\.(tsx?|jsx?)$/, '').replace(/[/\\]/g, '-').toLowerCase();
32
+ // Validate tag name (must contain a hyphen for Custom Elements)
33
+ if (!tagName.includes('-')) {
34
+ return {
35
+ code: source,
36
+ islands: []
37
+ };
38
+ }
39
+ // Security: only allow lowercase letters, digits, and hyphens
40
+ if (!/^[a-z0-9-]+$/.test(tagName)) {
41
+ throw new Error(`Island tag name "${tagName}" contains unsafe characters. ` + `Only lowercase letters, digits, and hyphens are allowed.`);
42
+ }
43
+ // Inject metadata markers
44
+ const injected = `
45
+ // --- Island Markers (auto-injected) ---
46
+ export const __island = true;
47
+ export const __tagName = '${tagName}';
48
+ // --- End Island Markers ---
49
+ `;
50
+ return {
51
+ code: source + '\n' + injected,
52
+ islands: [
53
+ {
54
+ tagName,
55
+ filePath
56
+ }
57
+ ]
58
+ };
59
+ }
60
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9vcGVuZWxlbWVudC9vcGVuZWxlbWVudC9wYWNrYWdlcy9jb3JlL3NyYy9pc2xhbmQtdHJhbnNmb3JtLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQG9wZW5lbGVtZW50L2NvcmUg4oCUIElzbGFuZCB0cmFuc2Zvcm0gY29yZSBsb2dpYy5cbiAqXG4gKiBQdXJlIGZ1bmN0aW9uOiBpbmplY3RzIGlzbGFuZCBtZXRhZGF0YSBtYXJrZXJzIGludG8gc291cmNlIGNvZGUuXG4gKiBaZXJvIFZpdGUgZGVwZW5kZW5jeS4gVXNhYmxlIHdpdGggYW55IGJ1aWxkIHRvb2wuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBJc2xhbmRUcmFuc2Zvcm1PcHRpb25zLCBJc2xhbmRUcmFuc2Zvcm1SZXN1bHQgfSBmcm9tICdAb3BlbmVsZW1lbnQvcHJvdG9jb2wvaXNsYW5kJztcbmV4cG9ydCB0eXBlIHsgSXNsYW5kVHJhbnNmb3JtT3B0aW9ucywgSXNsYW5kVHJhbnNmb3JtUmVzdWx0IH07XG5cbi8qKlxuICogSW5qZWN0IGlzbGFuZCBtZXRhZGF0YSBtYXJrZXJzIGludG8gc291cmNlIGNvZGUuXG4gKlxuICogT25seSB0cmFuc2Zvcm1zIGZpbGVzIGluc2lkZSB0aGUgaXNsYW5kcyBkaXJlY3RvcnkuXG4gKiBUYWcgbmFtZXMgbXVzdCBiZSBsb3dlcmNhc2UgKyBoeXBoZW5zIChDdXN0b20gRWxlbWVudHMgc3BlYykuXG4gKiBVbnNhZmUgY2hhcmFjdGVycyBjYXVzZSBhIHRocm93biBlcnJvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zZm9ybUlzbGFuZFNvdXJjZShcbiAgc291cmNlOiBzdHJpbmcsXG4gIG9wdGlvbnM6IElzbGFuZFRyYW5zZm9ybU9wdGlvbnMsXG4pOiBJc2xhbmRUcmFuc2Zvcm1SZXN1bHQge1xuICBjb25zdCB7IGlzbGFuZHNEaXIsIGZpbGVQYXRoIH0gPSBvcHRpb25zO1xuICAvLyBOb3JtYWxpemUgdG8gZm9yd2FyZCBzbGFzaGVzIGFuZCBlbnN1cmUgbGVhZGluZyBzbGFzaCBmb3IgcmVsaWFibGUgbWF0Y2hpbmdcbiAgbGV0IG5vcm1hbGl6ZWRQYXRoID0gZmlsZVBhdGgucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuICBpZiAoIW5vcm1hbGl6ZWRQYXRoLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgIG5vcm1hbGl6ZWRQYXRoID0gJy8nICsgbm9ybWFsaXplZFBhdGg7XG4gIH1cbiAgY29uc3Qgbm9ybWFsaXplZElzbGFuZHNEaXIgPSBpc2xhbmRzRGlyLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcblxuICAvLyBPbmx5IHRyYW5zZm9ybSBmaWxlcyBpbiB0aGUgaXNsYW5kcyBkaXJlY3RvcnlcbiAgaWYgKCFub3JtYWxpemVkUGF0aC5pbmNsdWRlcyhgLyR7bm9ybWFsaXplZElzbGFuZHNEaXJ9L2ApKSB7XG4gICAgcmV0dXJuIHsgY29kZTogc291cmNlLCBpc2xhbmRzOiBbXSB9O1xuICB9XG5cbiAgLy8gRXh0cmFjdCB0YWcgbmFtZSBmcm9tIGZpbGUgcGF0aDogcmVwbGFjZSBwYXRoIHNlcGFyYXRvcnMgd2l0aCBoeXBoZW5zXG4gIC8vIG1hdGNoaW5nIHJvdXRlLXNjYW5uZXIudHMgZmlsZVRvVGFnTmFtZSgpIGJlaGF2aW9yLlxuICAvLyBlLmcuIFwibmVzdGVkL215LXdpZGdldC50c3hcIiDihpIgXCJteS13aWRnZXRcIiwgXCJteS13aWRnZXQudHN4XCIg4oaSIFwibXktd2lkZ2V0XCJcbiAgY29uc3QgcmVsYXRpdmVQYXRoID0gbm9ybWFsaXplZFBhdGguc3BsaXQoYC8ke2lzbGFuZHNEaXJ9L2ApWzFdID8/XG4gICAgbm9ybWFsaXplZFBhdGguc3BsaXQoJy8nKS5wb3AoKSE7XG4gIGNvbnN0IHRhZ05hbWUgPSByZWxhdGl2ZVBhdGhcbiAgICAucmVwbGFjZSgvXFwuKHRzeD98anN4PykkLywgJycpXG4gICAgLnJlcGxhY2UoL1svXFxcXF0vZywgJy0nKVxuICAgIC50b0xvd2VyQ2FzZSgpO1xuXG4gIC8vIFZhbGlkYXRlIHRhZyBuYW1lIChtdXN0IGNvbnRhaW4gYSBoeXBoZW4gZm9yIEN1c3RvbSBFbGVtZW50cylcbiAgaWYgKCF0YWdOYW1lLmluY2x1ZGVzKCctJykpIHtcbiAgICByZXR1cm4geyBjb2RlOiBzb3VyY2UsIGlzbGFuZHM6IFtdIH07XG4gIH1cblxuICAvLyBTZWN1cml0eTogb25seSBhbGxvdyBsb3dlcmNhc2UgbGV0dGVycywgZGlnaXRzLCBhbmQgaHlwaGVuc1xuICBpZiAoIS9eW2EtejAtOS1dKyQvLnRlc3QodGFnTmFtZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgSXNsYW5kIHRhZyBuYW1lIFwiJHt0YWdOYW1lfVwiIGNvbnRhaW5zIHVuc2FmZSBjaGFyYWN0ZXJzLiBgICtcbiAgICAgICAgYE9ubHkgbG93ZXJjYXNlIGxldHRlcnMsIGRpZ2l0cywgYW5kIGh5cGhlbnMgYXJlIGFsbG93ZWQuYCxcbiAgICApO1xuICB9XG5cbiAgLy8gSW5qZWN0IG1ldGFkYXRhIG1hcmtlcnNcbiAgY29uc3QgaW5qZWN0ZWQgPSBgXG4vLyAtLS0gSXNsYW5kIE1hcmtlcnMgKGF1dG8taW5qZWN0ZWQpIC0tLVxuZXhwb3J0IGNvbnN0IF9faXNsYW5kID0gdHJ1ZTtcbmV4cG9ydCBjb25zdCBfX3RhZ05hbWUgPSAnJHt0YWdOYW1lfSc7XG4vLyAtLS0gRW5kIElzbGFuZCBNYXJrZXJzIC0tLVxuYDtcblxuICByZXR1cm4ge1xuICAgIGNvZGU6IHNvdXJjZSArICdcXG4nICsgaW5qZWN0ZWQsXG4gICAgaXNsYW5kczogW3sgdGFnTmFtZSwgZmlsZVBhdGggfV0sXG4gIH07XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7O0NBS0MsR0FLRDs7Ozs7O0NBTUMsR0FDRCxPQUFPLFNBQVMsc0JBQ2QsTUFBYyxFQUNkLE9BQStCO0VBRS9CLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLEdBQUc7RUFDakMsOEVBQThFO0VBQzlFLElBQUksaUJBQWlCLFNBQVMsT0FBTyxDQUFDLE9BQU87RUFDN0MsSUFBSSxDQUFDLGVBQWUsVUFBVSxDQUFDLE1BQU07SUFDbkMsaUJBQWlCLE1BQU07RUFDekI7RUFDQSxNQUFNLHVCQUF1QixXQUFXLE9BQU8sQ0FBQyxPQUFPO0VBRXZELGdEQUFnRDtFQUNoRCxJQUFJLENBQUMsZUFBZSxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUscUJBQXFCLENBQUMsQ0FBQyxHQUFHO0lBQ3pELE9BQU87TUFBRSxNQUFNO01BQVEsU0FBUyxFQUFFO0lBQUM7RUFDckM7RUFFQSx3RUFBd0U7RUFDeEUsc0RBQXNEO0VBQ3RELDJFQUEyRTtFQUMzRSxNQUFNLGVBQWUsZUFBZSxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFDN0QsZUFBZSxLQUFLLENBQUMsS0FBSyxHQUFHO0VBQy9CLE1BQU0sVUFBVSxhQUNiLE9BQU8sQ0FBQyxrQkFBa0IsSUFDMUIsT0FBTyxDQUFDLFVBQVUsS0FDbEIsV0FBVztFQUVkLGdFQUFnRTtFQUNoRSxJQUFJLENBQUMsUUFBUSxRQUFRLENBQUMsTUFBTTtJQUMxQixPQUFPO01BQUUsTUFBTTtNQUFRLFNBQVMsRUFBRTtJQUFDO0VBQ3JDO0VBRUEsOERBQThEO0VBQzlELElBQUksQ0FBQyxlQUFlLElBQUksQ0FBQyxVQUFVO0lBQ2pDLE1BQU0sSUFBSSxNQUNSLENBQUMsaUJBQWlCLEVBQUUsUUFBUSw4QkFBOEIsQ0FBQyxHQUN6RCxDQUFDLHdEQUF3RCxDQUFDO0VBRWhFO0VBRUEsMEJBQTBCO0VBQzFCLE1BQU0sV0FBVyxDQUFDOzs7MEJBR00sRUFBRSxRQUFROztBQUVwQyxDQUFDO0VBRUMsT0FBTztJQUNMLE1BQU0sU0FBUyxPQUFPO0lBQ3RCLFNBQVM7TUFBQztRQUFFO1FBQVM7TUFBUztLQUFFO0VBQ2xDO0FBQ0YifQ==
@@ -0,0 +1,59 @@
1
+ import type { IslandMeta, IslandOptions } from '@openelement/protocol/island';
2
+ /**
3
+ * SSR-safe custom element registration helper.
4
+ * v0.29.1: Merged from custom-element.ts.
5
+ */ export declare function defineCustomElement(tag: string, ctor: CustomElementConstructor): void;
6
+ export declare function getIslandMeta(ctor: CustomElementConstructor): IslandMeta | undefined;
7
+ /**
8
+ * Get the value of the data-ssr-props attribute from a host element.
9
+ * Used to reconstruct SSR props on client upgrade.
10
+ *
11
+ * @param el - The custom element host element
12
+ * @returns Parsed props object, or null if no data-ssr-props attribute
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * connectedCallback() {
17
+ * super.connectedCallback();
18
+ * const props = getSsrProps(this);
19
+ * if (props) {
20
+ * this.count = props.count ?? 0;
21
+ * }
22
+ * }
23
+ * ```
24
+ */ export declare function getSsrProps(el: HTMLElement): Record<string, unknown> | null;
25
+ export declare function bindSsrProps(el: HTMLElement): void;
26
+ /**
27
+ * Wrap a component class as a openElement Island.
28
+ *
29
+ * Handles:
30
+ * - Automatic customElements.define() registration
31
+ * - Strategy-based upgrade timing
32
+ * - data-ssr-props binding (open:bind)
33
+ * - __island / __tagName export markers
34
+ * - __layer metadata (dsd-static, dsd-interactive, or pure-island)
35
+ * - Idempotent registration (safe for SSR with multiple routes)
36
+ *
37
+ * v0.6.2: Added `dsd` option. When false, the island is a Pure Island
38
+ * (Layer 3) - no DSD template is emitted, framework fully owns shadow root.
39
+ *
40
+ * @param tagName - Custom element tag name (must contain hyphen)
41
+ * @param componentClass - Custom Element constructor (framework-agnostic)
42
+ * @param options - Island options
43
+ * @returns The component class (for chaining / re-export)
44
+ *
45
+ * @example
46
+ * ```ts
47
+ * // Basic usage (DSD enabled by default)
48
+ * export default defineIsland('my-counter', MyCounter);
49
+ *
50
+ * // Pure Island - no DSD, full framework reactivity
51
+ * export default defineIsland('my-counter', MyCounter, { dsd: false });
52
+ *
53
+ * // With visible strategy (IntersectionObserver)
54
+ * export default defineIsland('my-counter', MyCounter, { strategy: 'visible' });
55
+ *
56
+ * // With load strategy (immediate upgrade)
57
+ * export default defineIsland('my-counter', MyCounter, { strategy: 'load' });
58
+ * ```
59
+ */ export declare function defineIsland<T extends CustomElementConstructor>(tagName: string, componentClass: T, options?: IslandOptions): T;