elit 3.6.5 → 3.6.7

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 (154) hide show
  1. package/Cargo.lock +1 -1
  2. package/Cargo.toml +1 -1
  3. package/README.md +6 -0
  4. package/dist/build.cjs +421 -331
  5. package/dist/build.d.ts +1 -16
  6. package/dist/build.js +420 -330
  7. package/dist/build.mjs +420 -330
  8. package/dist/chokidar.cjs +219 -182
  9. package/dist/chokidar.d.ts +25 -10
  10. package/dist/chokidar.js +217 -182
  11. package/dist/chokidar.mjs +218 -183
  12. package/dist/cli.cjs +21608 -20241
  13. package/dist/cli.d.ts +19 -37
  14. package/dist/cli.mjs +21262 -19910
  15. package/dist/config.cjs +357 -350
  16. package/dist/config.d.ts +19 -240
  17. package/dist/config.js +520 -515
  18. package/dist/config.mjs +346 -341
  19. package/dist/contracts-BeW9k0yZ.d.ts +54 -0
  20. package/dist/contracts-D7KIS-TK.d.ts +36 -0
  21. package/dist/coverage.cjs +448 -485
  22. package/dist/coverage.d.ts +13 -59
  23. package/dist/coverage.js +447 -484
  24. package/dist/coverage.mjs +447 -484
  25. package/dist/database.cjs +819 -828
  26. package/dist/database.d.ts +8 -24
  27. package/dist/database.js +818 -829
  28. package/dist/database.mjs +818 -829
  29. package/dist/desktop-auto-render.cjs +1700 -1522
  30. package/dist/desktop-auto-render.d.ts +4 -9
  31. package/dist/desktop-auto-render.js +1695 -1517
  32. package/dist/desktop-auto-render.mjs +1696 -1518
  33. package/dist/desktop.cjs +3 -1
  34. package/dist/desktop.d.ts +4 -1
  35. package/dist/desktop.js +1 -1
  36. package/dist/desktop.mjs +1 -1
  37. package/dist/dev-build.cjs +830 -0
  38. package/dist/dev-build.d.ts +53 -0
  39. package/dist/dev-build.js +3318 -0
  40. package/dist/dev-build.mjs +797 -0
  41. package/dist/dom.cjs +717 -590
  42. package/dist/dom.d.ts +2 -15
  43. package/dist/dom.js +714 -587
  44. package/dist/dom.mjs +716 -589
  45. package/dist/el.cjs +62 -52
  46. package/dist/el.d.ts +5 -10
  47. package/dist/el.js +60 -52
  48. package/dist/el.mjs +60 -52
  49. package/dist/fs.cjs +72 -63
  50. package/dist/fs.d.ts +22 -19
  51. package/dist/fs.js +71 -62
  52. package/dist/fs.mjs +71 -62
  53. package/dist/hmr.cjs +40 -14
  54. package/dist/hmr.d.ts +11 -23
  55. package/dist/hmr.js +38 -14
  56. package/dist/hmr.mjs +38 -14
  57. package/dist/http.cjs +251 -99
  58. package/dist/http.d.ts +38 -104
  59. package/dist/http.js +249 -99
  60. package/dist/http.mjs +249 -99
  61. package/dist/https.cjs +524 -228
  62. package/dist/https.d.ts +44 -36
  63. package/dist/https.js +520 -226
  64. package/dist/https.mjs +522 -228
  65. package/dist/index.cjs +7502 -7690
  66. package/dist/index.d.ts +8 -3
  67. package/dist/index.js +7486 -7676
  68. package/dist/index.mjs +7497 -7686
  69. package/dist/mime-types.cjs +10 -4
  70. package/dist/mime-types.d.ts +8 -11
  71. package/dist/mime-types.js +9 -3
  72. package/dist/mime-types.mjs +9 -3
  73. package/dist/native.cjs +8616 -8869
  74. package/dist/native.d.ts +7 -8
  75. package/dist/native.js +8682 -8935
  76. package/dist/native.mjs +8615 -8868
  77. package/dist/path.cjs +83 -77
  78. package/dist/path.d.ts +29 -29
  79. package/dist/path.js +82 -76
  80. package/dist/path.mjs +82 -76
  81. package/dist/pm.cjs +3300 -0
  82. package/dist/pm.d.ts +256 -0
  83. package/dist/pm.js +5638 -0
  84. package/dist/pm.mjs +3196 -0
  85. package/dist/preview-build.cjs +712 -0
  86. package/dist/preview-build.d.ts +59 -0
  87. package/dist/preview-build.js +3194 -0
  88. package/dist/preview-build.mjs +676 -0
  89. package/dist/render-context.cjs +13 -2
  90. package/dist/render-context.d.ts +9 -31
  91. package/dist/render-context.js +11 -2
  92. package/dist/render-context.mjs +11 -2
  93. package/dist/router.cjs +787 -645
  94. package/dist/router.d.ts +8 -12
  95. package/dist/router.js +786 -644
  96. package/dist/router.mjs +786 -644
  97. package/dist/runtime.cjs +1 -1
  98. package/dist/runtime.js +1 -1
  99. package/dist/runtime.mjs +1 -1
  100. package/dist/server.cjs +3315 -2603
  101. package/dist/server.d.ts +49 -4
  102. package/dist/server.js +7611 -2834
  103. package/dist/server.mjs +3317 -2607
  104. package/dist/smtp-server.cjs +128 -0
  105. package/dist/smtp-server.d.ts +27 -0
  106. package/dist/smtp-server.js +4199 -0
  107. package/dist/smtp-server.mjs +100 -0
  108. package/dist/state-DvEkDehk.d.ts +195 -0
  109. package/dist/state.cjs +768 -658
  110. package/dist/state.d.ts +11 -69
  111. package/dist/state.js +760 -650
  112. package/dist/state.mjs +767 -657
  113. package/dist/style.cjs +1011 -968
  114. package/dist/style.d.ts +13 -127
  115. package/dist/style.js +1009 -970
  116. package/dist/style.mjs +1011 -971
  117. package/dist/test-reporter.cjs +332 -316
  118. package/dist/test-reporter.d.ts +28 -33
  119. package/dist/test-reporter.js +328 -312
  120. package/dist/test-reporter.mjs +328 -312
  121. package/dist/test-runtime.cjs +927 -968
  122. package/dist/test-runtime.d.ts +24 -99
  123. package/dist/test-runtime.js +922 -965
  124. package/dist/test-runtime.mjs +922 -965
  125. package/dist/test.cjs +4428 -4273
  126. package/dist/test.d.ts +2 -8
  127. package/dist/test.js +4307 -4154
  128. package/dist/test.mjs +4419 -4267
  129. package/dist/types-BONVzPtp.d.ts +59 -0
  130. package/dist/types-BR4wMiVx.d.ts +32 -0
  131. package/dist/types-C4gKykuG.d.ts +23 -0
  132. package/dist/types-CIhpN1-K.d.ts +64 -0
  133. package/dist/types-Ckj8md_j.d.ts +84 -0
  134. package/dist/types-CpjQTAkX.d.ts +24 -0
  135. package/dist/types-D0LjrYjS.d.ts +14 -0
  136. package/dist/types-DAisuVr5.d.ts +75 -0
  137. package/dist/types-tJn88E1N.d.ts +242 -0
  138. package/dist/types.d.ts +71 -226
  139. package/dist/universal.cjs +1 -1
  140. package/dist/universal.d.ts +1 -5
  141. package/dist/universal.js +1 -1
  142. package/dist/universal.mjs +1 -1
  143. package/dist/websocket-XfyK23zD.d.ts +119 -0
  144. package/dist/ws.cjs +129 -108
  145. package/dist/ws.d.ts +21 -131
  146. package/dist/ws.js +128 -109
  147. package/dist/ws.mjs +128 -109
  148. package/dist/wss.cjs +757 -479
  149. package/dist/wss.d.ts +31 -28
  150. package/dist/wss.js +755 -479
  151. package/dist/wss.mjs +758 -482
  152. package/package.json +16 -1
  153. package/vendor/epaint-0.31.1/src/image.rs +418 -0
  154. package/dist/server-CcBFc2F5.d.ts +0 -449
@@ -17,22 +17,26 @@ var __copyProps = (to, from, except, desc) => {
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
- // src/desktop-auto-render.ts
21
- var desktop_auto_render_exports = {};
22
- __export(desktop_auto_render_exports, {
20
+ // src/desktop/auto-render/index.ts
21
+ var auto_render_exports = {};
22
+ __export(auto_render_exports, {
23
23
  completeDesktopAutoRender: () => completeDesktopAutoRender,
24
24
  installDesktopRenderTracking: () => installDesktopRenderTracking
25
25
  });
26
- module.exports = __toCommonJS(desktop_auto_render_exports);
26
+ module.exports = __toCommonJS(auto_render_exports);
27
27
 
28
- // src/render-context.ts
28
+ // src/desktop/render-context/constants.ts
29
29
  var RUNTIME_TARGET_KEY = "__ELIT_RUNTIME_TARGET__";
30
30
  var CAPTURED_RENDER_KEY = "__ELIT_CAPTURED_RENDER__";
31
31
  var DESKTOP_RENDER_OPTIONS_KEY = "__ELIT_DESKTOP_RENDER_OPTIONS__";
32
32
  var RUNTIME_TARGET_ENV = "ELIT_RUNTIME_TARGET";
33
+
34
+ // src/desktop/render-context/globals.ts
33
35
  function getGlobalRenderScope() {
34
36
  return globalThis;
35
37
  }
38
+
39
+ // src/desktop/render-context/runtime-target.ts
36
40
  function isRenderRuntimeTarget(value) {
37
41
  return value === "web" || value === "desktop" || value === "mobile" || value === "unknown";
38
42
  }
@@ -48,7 +52,8 @@ function detectRenderRuntimeTarget() {
48
52
  if (typeof globalScope.createWindow === "function") {
49
53
  return "desktop";
50
54
  }
51
- const argv = Array.isArray(globalScope.process?.argv) ? globalScope.process.argv.join(" ") : "";
55
+ const argvValues = globalScope.process?.argv;
56
+ const argv = Array.isArray(argvValues) ? argvValues.join(" ") : "";
52
57
  if (/\bdesktop\b/i.test(argv)) {
53
58
  return "desktop";
54
59
  }
@@ -57,6 +62,8 @@ function detectRenderRuntimeTarget() {
57
62
  }
58
63
  return "unknown";
59
64
  }
65
+
66
+ // src/desktop/render-context/captured-render.ts
60
67
  function captureRenderedVNode(rootElement, vNode, target = detectRenderRuntimeTarget()) {
61
68
  const globalScope = getGlobalRenderScope();
62
69
  globalScope[RUNTIME_TARGET_KEY] = target;
@@ -72,11 +79,13 @@ function getCapturedRenderedVNode() {
72
79
  function clearCapturedRenderedVNode() {
73
80
  delete getGlobalRenderScope()[CAPTURED_RENDER_KEY];
74
81
  }
82
+
83
+ // src/desktop/render-context/desktop-options.ts
75
84
  function getDesktopRenderOptions() {
76
85
  return getGlobalRenderScope()[DESKTOP_RENDER_OPTIONS_KEY];
77
86
  }
78
87
 
79
- // src/dom.ts
88
+ // src/client/dom/helpers.ts
80
89
  function resolveElement(rootElement) {
81
90
  return typeof rootElement === "string" ? document.getElementById(rootElement.replace("#", "")) : rootElement;
82
91
  }
@@ -104,1029 +113,1248 @@ function resolveTextareaValue(tagName, props) {
104
113
  function hasDocumentApi() {
105
114
  return typeof document !== "undefined";
106
115
  }
107
- var DomNode = class {
108
- constructor() {
109
- this.elementCache = /* @__PURE__ */ new WeakMap();
110
- this.reactiveNodes = /* @__PURE__ */ new Map();
111
- }
112
- createElement(tagName, props = {}, children = []) {
113
- return { tagName, props, children };
114
- }
115
- renderToDOM(vNode, parent) {
116
- if (vNode == null || vNode === false) return;
117
- if (typeof vNode !== "object") {
118
- parent.appendChild(document.createTextNode(String(vNode)));
119
- return;
120
- }
121
- if (this.isState(vNode)) {
122
- const textNode = document.createTextNode(String(vNode.value ?? ""));
123
- parent.appendChild(textNode);
124
- vNode.subscribe((newValue) => {
125
- textNode.textContent = String(newValue ?? "");
126
- });
127
- return;
128
- }
129
- if (Array.isArray(vNode)) {
130
- for (const child of vNode) {
131
- this.renderToDOM(child, parent);
132
- }
133
- return;
134
- }
135
- const { tagName, props, children } = vNode;
136
- const textareaValue = resolveTextareaValue(tagName, props);
137
- if (!tagName) {
138
- for (const child of children) {
139
- if (shouldSkipChild(child)) continue;
140
- if (Array.isArray(child)) {
141
- for (const c of child) {
142
- !shouldSkipChild(c) && this.renderToDOM(c, parent);
143
- }
144
- } else {
145
- this.renderToDOM(child, parent);
146
- }
147
- }
148
- return;
149
- }
150
- const isSVG = tagName === "svg" || tagName[0] === "s" && tagName[1] === "v" && tagName[2] === "g" || parent.namespaceURI === "http://www.w3.org/2000/svg";
151
- const el = isSVG ? document.createElementNS("http://www.w3.org/2000/svg", tagName.replace("svg", "").toLowerCase() || tagName) : document.createElement(tagName);
152
- for (const key in props) {
153
- const value = props[key];
154
- if (value == null || value === false) continue;
155
- const c = key.charCodeAt(0);
156
- if (c === 99 && (key.length < 6 || key[5] === "N")) {
157
- const classValue = Array.isArray(value) ? value.join(" ") : value;
158
- isSVG ? el.setAttribute("class", classValue) : el.className = classValue;
159
- } else if (c === 115 && key.length === 5) {
160
- if (typeof value === "string") {
161
- el.style.cssText = value;
162
- } else {
163
- const s = el.style;
164
- for (const k in value) s[k] = value[k];
165
- }
166
- } else if (c === 111 && key.charCodeAt(1) === 110) {
167
- el[key.toLowerCase()] = value;
168
- } else if (c === 100 && key.length > 20) {
169
- el.innerHTML = value.__html;
170
- } else if (c === 114 && key === "ref") {
171
- setTimeout(() => {
172
- typeof value === "function" ? value(el) : value.current = el;
173
- }, 0);
174
- } else if (textareaValue !== void 0 && key === "value") {
175
- continue;
116
+ function isState(value) {
117
+ return value && typeof value === "object" && "value" in value && "subscribe" in value && typeof value.subscribe === "function";
118
+ }
119
+
120
+ // src/client/dom/dom-render.ts
121
+ function isSvgElement(tagName, parent) {
122
+ return tagName === "svg" || tagName[0] === "s" && tagName[1] === "v" && tagName[2] === "g" || parent.namespaceURI === "http://www.w3.org/2000/svg";
123
+ }
124
+ function applyProps(el, props, textareaValue) {
125
+ for (const key in props) {
126
+ const value = props[key];
127
+ if (value == null || value === false) continue;
128
+ const c = key.charCodeAt(0);
129
+ if (c === 99 && (key.length < 6 || key[5] === "N")) {
130
+ const classValue = Array.isArray(value) ? value.join(" ") : String(value);
131
+ if (el instanceof SVGElement) {
132
+ el.setAttribute("class", classValue);
176
133
  } else {
177
- el.setAttribute(key, value === true ? "" : String(value));
134
+ el.className = classValue;
178
135
  }
179
- }
180
- const renderableChildren = textareaValue === void 0 ? children : [];
181
- const len = renderableChildren.length;
182
- if (!len) {
183
- if (textareaValue !== void 0) {
184
- el.value = textareaValue;
136
+ } else if (c === 115 && key.length === 5) {
137
+ if (typeof value === "string") {
138
+ el.style.cssText = value;
139
+ } else {
140
+ const style = el.style;
141
+ for (const styleKey in value) {
142
+ style[styleKey] = value[styleKey];
143
+ }
185
144
  }
186
- parent.appendChild(el);
187
- return;
188
- }
189
- const renderChildren = (target) => {
190
- for (let i = 0; i < len; i++) {
191
- const child = renderableChildren[i];
192
- if (shouldSkipChild(child)) continue;
193
- if (Array.isArray(child)) {
194
- for (let j = 0, cLen = child.length; j < cLen; j++) {
195
- const c = child[j];
196
- !shouldSkipChild(c) && this.renderToDOM(c, target);
197
- }
145
+ } else if (c === 111 && key.charCodeAt(1) === 110) {
146
+ el[key.toLowerCase()] = value;
147
+ } else if (c === 100 && key.length > 20) {
148
+ el.innerHTML = value.__html;
149
+ } else if (c === 114 && key === "ref") {
150
+ setTimeout(() => {
151
+ if (typeof value === "function") {
152
+ value(el);
198
153
  } else {
199
- this.renderToDOM(child, target);
154
+ value.current = el;
200
155
  }
201
- }
202
- };
203
- if (len > 30) {
204
- const fragment = document.createDocumentFragment();
205
- renderChildren(fragment);
206
- el.appendChild(fragment);
156
+ }, 0);
157
+ } else if (textareaValue !== void 0 && key === "value") {
158
+ continue;
207
159
  } else {
208
- renderChildren(el);
160
+ el.setAttribute(key, value === true ? "" : String(value));
209
161
  }
210
- parent.appendChild(el);
211
162
  }
212
- render(rootElement, vNode) {
213
- if (!hasDocumentApi()) {
214
- const runtimeTarget = detectRenderRuntimeTarget();
215
- if (runtimeTarget === "desktop" || runtimeTarget === "mobile") {
216
- captureRenderedVNode(rootElement, vNode, runtimeTarget);
217
- return {};
163
+ }
164
+ function renderChildren(children, target) {
165
+ const len = children.length;
166
+ for (let i = 0; i < len; i++) {
167
+ const child = children[i];
168
+ if (shouldSkipChild(child)) continue;
169
+ if (Array.isArray(child)) {
170
+ for (let j = 0, childLen = child.length; j < childLen; j++) {
171
+ const nestedChild = child[j];
172
+ if (!shouldSkipChild(nestedChild)) {
173
+ renderToDOM(nestedChild, target);
174
+ }
218
175
  }
219
- throw new Error("render() requires a DOM or an Elit desktop/mobile runtime target.");
220
- }
221
- const el = ensureElement(resolveElement(rootElement), rootElement);
222
- el.innerHTML = "";
223
- if (vNode.children && vNode.children.length > 500) {
224
- const fragment = document.createDocumentFragment();
225
- this.renderToDOM(vNode, fragment);
226
- el.appendChild(fragment);
227
176
  } else {
228
- this.renderToDOM(vNode, el);
177
+ renderToDOM(child, target);
229
178
  }
230
- return el;
231
179
  }
232
- batchRender(rootElement, vNodes) {
233
- const el = ensureElement(resolveElement(rootElement), rootElement);
234
- const len = vNodes.length;
235
- if (len > 3e3) {
236
- const fragment = document.createDocumentFragment();
237
- let processed = 0;
238
- const chunkSize = 1500;
239
- const processChunk = () => {
240
- const end = Math.min(processed + chunkSize, len);
241
- for (let i = processed; i < end; i++) {
242
- this.renderToDOM(vNodes[i], fragment);
243
- }
244
- processed = end;
245
- if (processed >= len) {
246
- el.appendChild(fragment);
247
- } else {
248
- requestAnimationFrame(processChunk);
249
- }
250
- };
251
- processChunk();
252
- } else {
253
- const fragment = document.createDocumentFragment();
254
- for (let i = 0; i < len; i++) {
255
- this.renderToDOM(vNodes[i], fragment);
256
- }
257
- el.appendChild(fragment);
258
- }
259
- return el;
180
+ }
181
+ function renderToDOM(vNode, parent) {
182
+ if (vNode == null || vNode === false) return;
183
+ if (typeof vNode !== "object") {
184
+ parent.appendChild(document.createTextNode(String(vNode)));
185
+ return;
260
186
  }
261
- renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
262
- const el = ensureElement(resolveElement(rootElement), rootElement);
263
- const len = vNodes.length;
264
- let index = 0;
265
- const renderChunk = () => {
266
- const end = Math.min(index + chunkSize, len);
267
- const fragment = document.createDocumentFragment();
268
- for (let i = index; i < end; i++) {
269
- this.renderToDOM(vNodes[i], fragment);
270
- }
271
- el.appendChild(fragment);
272
- index = end;
273
- if (onProgress) onProgress(index, len);
274
- if (index < len) {
275
- requestAnimationFrame(renderChunk);
276
- }
277
- };
278
- requestAnimationFrame(renderChunk);
279
- return el;
187
+ if (isState(vNode)) {
188
+ const textNode = document.createTextNode(String(vNode.value ?? ""));
189
+ parent.appendChild(textNode);
190
+ vNode.subscribe((newValue) => {
191
+ textNode.textContent = String(newValue ?? "");
192
+ });
193
+ return;
280
194
  }
281
- renderToHead(...vNodes) {
282
- const head = document.head;
283
- if (head) {
284
- for (const vNode of vNodes.flat()) {
285
- vNode && this.renderToDOM(vNode, head);
286
- }
195
+ if (Array.isArray(vNode)) {
196
+ for (const child of vNode) {
197
+ renderToDOM(child, parent);
287
198
  }
288
- return head;
199
+ return;
289
200
  }
290
- addStyle(cssText) {
291
- const el = document.createElement("style");
292
- el.textContent = cssText;
293
- return document.head.appendChild(el);
201
+ const { tagName, props, children } = vNode;
202
+ const textareaValue = resolveTextareaValue(tagName, props);
203
+ if (!tagName) {
204
+ renderChildren(children, parent);
205
+ return;
294
206
  }
295
- addMeta(attrs) {
296
- const el = document.createElement("meta");
297
- for (const k in attrs) el.setAttribute(k, attrs[k]);
298
- return document.head.appendChild(el);
207
+ const el = isSvgElement(tagName, parent) ? document.createElementNS("http://www.w3.org/2000/svg", tagName.replace("svg", "").toLowerCase() || tagName) : document.createElement(tagName);
208
+ applyProps(el, props, textareaValue);
209
+ const renderableChildren = textareaValue === void 0 ? children : [];
210
+ if (!renderableChildren.length) {
211
+ if (textareaValue !== void 0) {
212
+ el.value = textareaValue;
213
+ }
214
+ parent.appendChild(el);
215
+ return;
299
216
  }
300
- addLink(attrs) {
301
- const el = document.createElement("link");
302
- for (const k in attrs) el.setAttribute(k, attrs[k]);
303
- return document.head.appendChild(el);
217
+ if (renderableChildren.length > 30) {
218
+ const fragment = document.createDocumentFragment();
219
+ renderChildren(renderableChildren, fragment);
220
+ el.appendChild(fragment);
221
+ } else {
222
+ renderChildren(renderableChildren, el);
304
223
  }
305
- setTitle(text) {
306
- return document.title = text;
224
+ parent.appendChild(el);
225
+ }
226
+ function render(rootElement, vNode) {
227
+ if (!hasDocumentApi()) {
228
+ const runtimeTarget = detectRenderRuntimeTarget();
229
+ if (runtimeTarget === "desktop" || runtimeTarget === "mobile") {
230
+ captureRenderedVNode(rootElement, vNode, runtimeTarget);
231
+ return {};
232
+ }
233
+ throw new Error("render() requires a DOM or an Elit desktop/mobile runtime target.");
234
+ }
235
+ const el = ensureElement(resolveElement(rootElement), rootElement);
236
+ el.innerHTML = "";
237
+ if (vNode.children && vNode.children.length > 500) {
238
+ const fragment = document.createDocumentFragment();
239
+ renderToDOM(vNode, fragment);
240
+ el.appendChild(fragment);
241
+ } else {
242
+ renderToDOM(vNode, el);
307
243
  }
308
- // Reactive State Management
309
- createState(initialValue, options = {}) {
310
- let value = initialValue;
311
- const listeners = /* @__PURE__ */ new Set();
312
- let updateTimer = null;
313
- const { throttle = 0, deep = false } = options;
314
- const notify = () => listeners.forEach((fn) => fn(value));
315
- const scheduleUpdate = () => {
316
- if (throttle > 0) {
317
- if (!updateTimer) {
318
- updateTimer = setTimeout(() => {
319
- updateTimer = null;
320
- notify();
321
- }, throttle);
322
- }
244
+ return el;
245
+ }
246
+ function batchRender(rootElement, vNodes) {
247
+ const el = ensureElement(resolveElement(rootElement), rootElement);
248
+ const len = vNodes.length;
249
+ if (len > 3e3) {
250
+ const fragment = document.createDocumentFragment();
251
+ let processed = 0;
252
+ const chunkSize = 1500;
253
+ const processChunk = () => {
254
+ const end = Math.min(processed + chunkSize, len);
255
+ for (let i = processed; i < end; i++) {
256
+ renderToDOM(vNodes[i], fragment);
257
+ }
258
+ processed = end;
259
+ if (processed >= len) {
260
+ el.appendChild(fragment);
323
261
  } else {
324
- notify();
262
+ requestAnimationFrame(processChunk);
325
263
  }
326
264
  };
327
- return {
328
- get value() {
329
- return value;
330
- },
331
- set value(newValue) {
332
- const changed = deep ? JSON.stringify(value) !== JSON.stringify(newValue) : value !== newValue;
333
- if (changed) {
334
- value = newValue;
335
- scheduleUpdate();
336
- }
337
- },
338
- subscribe(fn) {
339
- listeners.add(fn);
340
- return () => listeners.delete(fn);
341
- },
342
- destroy() {
343
- listeners.clear();
344
- updateTimer && clearTimeout(updateTimer);
265
+ processChunk();
266
+ } else {
267
+ const fragment = document.createDocumentFragment();
268
+ for (let i = 0; i < len; i++) {
269
+ renderToDOM(vNodes[i], fragment);
270
+ }
271
+ el.appendChild(fragment);
272
+ }
273
+ return el;
274
+ }
275
+ function renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
276
+ const el = ensureElement(resolveElement(rootElement), rootElement);
277
+ const len = vNodes.length;
278
+ let index = 0;
279
+ const renderChunkFrame = () => {
280
+ const end = Math.min(index + chunkSize, len);
281
+ const fragment = document.createDocumentFragment();
282
+ for (let i = index; i < end; i++) {
283
+ renderToDOM(vNodes[i], fragment);
284
+ }
285
+ el.appendChild(fragment);
286
+ index = end;
287
+ if (onProgress) {
288
+ onProgress(index, len);
289
+ }
290
+ if (index < len) {
291
+ requestAnimationFrame(renderChunkFrame);
292
+ }
293
+ };
294
+ requestAnimationFrame(renderChunkFrame);
295
+ return el;
296
+ }
297
+ function renderToHead(...vNodes) {
298
+ const head = document.head;
299
+ if (head) {
300
+ for (const vNode of vNodes.flat()) {
301
+ if (vNode) {
302
+ renderToDOM(vNode, head);
345
303
  }
346
- };
304
+ }
347
305
  }
348
- computed(states, computeFn) {
349
- const values = states.map((s) => s.value);
350
- const result = this.createState(computeFn(...values));
351
- states.forEach((state, index) => {
352
- state.subscribe((newValue) => {
353
- values[index] = newValue;
354
- result.value = computeFn(...values);
355
- });
356
- });
357
- return result;
306
+ return head;
307
+ }
308
+ function addStyle(cssText) {
309
+ const el = document.createElement("style");
310
+ el.textContent = cssText;
311
+ return document.head.appendChild(el);
312
+ }
313
+ function addMeta(attrs) {
314
+ const el = document.createElement("meta");
315
+ for (const key in attrs) {
316
+ el.setAttribute(key, attrs[key]);
358
317
  }
359
- effect(stateFn) {
360
- stateFn();
318
+ return document.head.appendChild(el);
319
+ }
320
+ function addLink(attrs) {
321
+ const el = document.createElement("link");
322
+ for (const key in attrs) {
323
+ el.setAttribute(key, attrs[key]);
361
324
  }
362
- // Virtual scrolling helper for large lists
363
- createVirtualList(container2, items, renderItem, itemHeight = 50, bufferSize = 5) {
364
- const viewportHeight = container2.clientHeight;
365
- const totalHeight = items.length * itemHeight;
366
- let scrollTop = 0;
367
- const getVisibleRange = () => {
368
- const start = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
369
- const end = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + bufferSize);
370
- return { start, end };
371
- };
372
- const render2 = () => {
373
- const { start, end } = getVisibleRange();
374
- const wrapper = document.createElement("div");
375
- wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
376
- for (let i = start; i < end; i++) {
377
- const itemEl = document.createElement("div");
378
- itemEl.style.cssText = `position:absolute;top:${i * itemHeight}px;height:${itemHeight}px;width:100%`;
379
- this.renderToDOM(renderItem(items[i], i), itemEl);
380
- wrapper.appendChild(itemEl);
381
- }
382
- container2.innerHTML = "";
383
- container2.appendChild(wrapper);
384
- };
385
- const scrollHandler = () => {
386
- scrollTop = container2.scrollTop;
387
- requestAnimationFrame(render2);
388
- };
389
- container2.addEventListener("scroll", scrollHandler);
390
- render2();
391
- return {
392
- render: render2,
393
- destroy: () => {
394
- container2.removeEventListener("scroll", scrollHandler);
395
- container2.innerHTML = "";
396
- }
397
- };
325
+ return document.head.appendChild(el);
326
+ }
327
+ function setTitle(text) {
328
+ return document.title = text;
329
+ }
330
+ function cleanupUnusedElements(root, elementCache) {
331
+ const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
332
+ const toRemove = [];
333
+ while (walker.nextNode()) {
334
+ const node = walker.currentNode;
335
+ if (node.id && node.id.startsWith("r") && !elementCache.has(node)) {
336
+ toRemove.push(node);
337
+ }
398
338
  }
399
- // Lazy load components
400
- lazy(loadFn) {
401
- let component = null;
402
- let loading = false;
403
- return async (...args) => {
404
- if (!component && !loading) {
405
- loading = true;
406
- component = await loadFn();
407
- loading = false;
339
+ toRemove.forEach((el) => el.remove());
340
+ return toRemove.length;
341
+ }
342
+
343
+ // src/client/dom/reactive.ts
344
+ function createReactiveChild(state, reactiveNodes, renderFn) {
345
+ const currentValue = renderFn(state.value);
346
+ if (typeof window !== "undefined" && typeof document !== "undefined") {
347
+ const entry = { node: null, renderFn };
348
+ reactiveNodes.set(state, entry);
349
+ state.subscribe(() => {
350
+ if (entry.node && entry.node.parentNode) {
351
+ const newValue = renderFn(state.value);
352
+ entry.node.textContent = String(newValue ?? "");
408
353
  }
409
- return component ? component(...args) : { tagName: "div", props: { class: "loading" }, children: ["Loading..."] };
410
- };
354
+ });
411
355
  }
412
- // Memory management - cleanup unused elements
413
- cleanupUnusedElements(root) {
414
- const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT);
415
- const toRemove = [];
416
- while (walker.nextNode()) {
417
- const node = walker.currentNode;
418
- if (node.id && node.id.startsWith("r") && !this.elementCache.has(node)) {
419
- toRemove.push(node);
356
+ return currentValue;
357
+ }
358
+
359
+ // src/client/dom/string-render.ts
360
+ var SELF_CLOSING_TAGS = /* @__PURE__ */ new Set([
361
+ "area",
362
+ "base",
363
+ "br",
364
+ "col",
365
+ "embed",
366
+ "hr",
367
+ "img",
368
+ "input",
369
+ "link",
370
+ "meta",
371
+ "param",
372
+ "source",
373
+ "track",
374
+ "wbr"
375
+ ]);
376
+ function resolveStateValue(value) {
377
+ return isState(value) ? value.value : value;
378
+ }
379
+ function isReactiveWrapper(vNode) {
380
+ if (!vNode || typeof vNode !== "object" || !vNode.tagName) {
381
+ return false;
382
+ }
383
+ return vNode.tagName === "span" && vNode.props?.id && typeof vNode.props.id === "string" && /^r[a-z0-9]{9}$/.test(vNode.props.id);
384
+ }
385
+ function unwrapReactive(vNode) {
386
+ if (!isReactiveWrapper(vNode)) {
387
+ return vNode;
388
+ }
389
+ const children = vNode.children;
390
+ if (!children || children.length === 0) {
391
+ return "";
392
+ }
393
+ if (children.length === 1) {
394
+ const child = children[0];
395
+ if (child && typeof child === "object" && child.tagName === "span") {
396
+ const props = child.props;
397
+ const hasNoProps = !props || Object.keys(props).length === 0;
398
+ const hasSingleStringChild = child.children && child.children.length === 1 && typeof child.children[0] === "string";
399
+ if (hasNoProps && hasSingleStringChild) {
400
+ return child.children[0];
420
401
  }
421
402
  }
422
- toRemove.forEach((el) => el.remove());
423
- return toRemove.length;
403
+ return unwrapReactive(child);
424
404
  }
425
- // Server-Side Rendering - convert VNode to HTML string
426
- renderToString(vNode, options = {}) {
427
- const { pretty = false, indent = 0 } = options;
428
- const indentStr = pretty ? " ".repeat(indent) : "";
429
- const newLine = pretty ? "\n" : "";
430
- let resolvedVNode = this.resolveStateValue(vNode);
431
- resolvedVNode = this.unwrapReactive(resolvedVNode);
432
- if (Array.isArray(resolvedVNode)) {
433
- return resolvedVNode.map((child) => this.renderToString(child, options)).join("");
434
- }
435
- if (typeof resolvedVNode !== "object" || resolvedVNode === null) {
436
- if (resolvedVNode === null || resolvedVNode === void 0 || resolvedVNode === false) {
437
- return "";
405
+ return children.map((child) => unwrapReactive(child));
406
+ }
407
+ function escapeHtml(text) {
408
+ const htmlEscapes = {
409
+ "&": "&amp;",
410
+ "<": "&lt;",
411
+ ">": "&gt;",
412
+ '"': "&quot;",
413
+ "'": "&#x27;"
414
+ };
415
+ return text.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
416
+ }
417
+ function isSelfClosingTag(tagName) {
418
+ return SELF_CLOSING_TAGS.has(tagName.toLowerCase());
419
+ }
420
+ function styleToString(style) {
421
+ if (typeof style === "string") {
422
+ return style;
423
+ }
424
+ if (typeof style === "object" && style !== null) {
425
+ const styles2 = [];
426
+ for (const key in style) {
427
+ const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
428
+ styles2.push(`${cssKey}:${style[key]}`);
429
+ }
430
+ return styles2.join(";");
431
+ }
432
+ return "";
433
+ }
434
+ function propsToAttributes(props, tagName) {
435
+ const attrs = [];
436
+ for (const key in props) {
437
+ if (key === "children" || key === "dangerouslySetInnerHTML" || key === "ref" || tagName === "textarea" && key === "value") {
438
+ continue;
439
+ }
440
+ let value = props[key];
441
+ value = resolveStateValue(value);
442
+ if (value == null || value === false) continue;
443
+ if (key.startsWith("on") && typeof value === "function") {
444
+ continue;
445
+ }
446
+ if (key === "className" || key === "class") {
447
+ const className = Array.isArray(value) ? value.join(" ") : value;
448
+ if (className) {
449
+ attrs.push(`class="${escapeHtml(String(className))}"`);
438
450
  }
439
- return this.escapeHtml(String(resolvedVNode));
451
+ continue;
440
452
  }
441
- const { tagName, props, children } = resolvedVNode;
442
- const textareaValue = resolveTextareaValue(tagName, props);
443
- const isSelfClosing = this.isSelfClosingTag(tagName);
444
- let html = `${indentStr}<${tagName}`;
445
- const attrs = this.propsToAttributes(props, tagName);
446
- if (attrs) {
447
- html += ` ${attrs}`;
453
+ if (key === "style") {
454
+ const styleStr = styleToString(value);
455
+ if (styleStr) {
456
+ attrs.push(`style="${escapeHtml(styleStr)}"`);
457
+ }
458
+ continue;
448
459
  }
449
- if (isSelfClosing) {
450
- html += ` />${newLine}`;
451
- return html;
460
+ if (value === true) {
461
+ attrs.push(key);
462
+ continue;
452
463
  }
453
- html += ">";
454
- if (textareaValue !== void 0) {
455
- html += this.escapeHtml(textareaValue);
456
- html += `</${tagName}>${newLine}`;
457
- return html;
458
- }
459
- if (props.dangerouslySetInnerHTML) {
460
- html += props.dangerouslySetInnerHTML.__html;
461
- html += `</${tagName}>${newLine}`;
462
- return html;
463
- }
464
- if (children && children.length > 0) {
465
- const resolvedChildren = children.map((c) => {
466
- const resolved = this.resolveStateValue(c);
467
- return this.unwrapReactive(resolved);
468
- });
469
- const hasComplexChildren = resolvedChildren.some(
470
- (c) => typeof c === "object" && c !== null && !Array.isArray(c) && "tagName" in c
471
- );
472
- if (pretty && hasComplexChildren) {
473
- html += newLine;
474
- for (const child of resolvedChildren) {
475
- if (shouldSkipChild(child)) continue;
476
- if (Array.isArray(child)) {
477
- for (const c of child) {
478
- if (!shouldSkipChild(c)) {
479
- html += this.renderToString(c, { pretty, indent: indent + 1 });
480
- }
464
+ attrs.push(`${key}="${escapeHtml(String(value))}"`);
465
+ }
466
+ return attrs.join(" ");
467
+ }
468
+ function renderToString(vNode, options = {}) {
469
+ const { pretty = false, indent = 0 } = options;
470
+ const indentStr = pretty ? " ".repeat(indent) : "";
471
+ const newLine = pretty ? "\n" : "";
472
+ let resolvedVNode = resolveStateValue(vNode);
473
+ resolvedVNode = unwrapReactive(resolvedVNode);
474
+ if (Array.isArray(resolvedVNode)) {
475
+ return resolvedVNode.map((child) => renderToString(child, options)).join("");
476
+ }
477
+ if (typeof resolvedVNode !== "object" || resolvedVNode === null) {
478
+ if (resolvedVNode === null || resolvedVNode === void 0 || resolvedVNode === false) {
479
+ return "";
480
+ }
481
+ return escapeHtml(String(resolvedVNode));
482
+ }
483
+ const { tagName, props, children } = resolvedVNode;
484
+ const textareaValue = resolveTextareaValue(tagName, props);
485
+ const selfClosing = isSelfClosingTag(tagName);
486
+ let html = `${indentStr}<${tagName}`;
487
+ const attrs = propsToAttributes(props, tagName);
488
+ if (attrs) {
489
+ html += ` ${attrs}`;
490
+ }
491
+ if (selfClosing) {
492
+ html += ` />${newLine}`;
493
+ return html;
494
+ }
495
+ html += ">";
496
+ if (textareaValue !== void 0) {
497
+ html += escapeHtml(textareaValue);
498
+ html += `</${tagName}>${newLine}`;
499
+ return html;
500
+ }
501
+ if (props.dangerouslySetInnerHTML) {
502
+ html += props.dangerouslySetInnerHTML.__html;
503
+ html += `</${tagName}>${newLine}`;
504
+ return html;
505
+ }
506
+ const isRawText = tagName === "script" || tagName === "style";
507
+ if (children && children.length > 0) {
508
+ const resolvedChildren = children.map((child) => unwrapReactive(resolveStateValue(child)));
509
+ const hasComplexChildren = resolvedChildren.some(
510
+ (child) => typeof child === "object" && child !== null && !Array.isArray(child) && "tagName" in child
511
+ );
512
+ if (pretty && hasComplexChildren) {
513
+ html += newLine;
514
+ for (const child of resolvedChildren) {
515
+ if (shouldSkipChild(child)) continue;
516
+ if (Array.isArray(child)) {
517
+ for (const nestedChild of child) {
518
+ if (!shouldSkipChild(nestedChild)) {
519
+ html += isRawText && typeof nestedChild === "string" ? nestedChild : renderToString(nestedChild, { pretty, indent: indent + 1 });
481
520
  }
482
- } else {
483
- html += this.renderToString(child, { pretty, indent: indent + 1 });
484
521
  }
522
+ } else {
523
+ html += isRawText && typeof child === "string" ? child : renderToString(child, { pretty, indent: indent + 1 });
485
524
  }
486
- html += indentStr;
487
- } else {
488
- for (const child of resolvedChildren) {
489
- if (shouldSkipChild(child)) continue;
490
- if (Array.isArray(child)) {
491
- for (const c of child) {
492
- if (!shouldSkipChild(c)) {
493
- html += this.renderToString(c, { pretty: false, indent: 0 });
494
- }
525
+ }
526
+ html += indentStr;
527
+ } else {
528
+ for (const child of resolvedChildren) {
529
+ if (shouldSkipChild(child)) continue;
530
+ if (Array.isArray(child)) {
531
+ for (const nestedChild of child) {
532
+ if (!shouldSkipChild(nestedChild)) {
533
+ html += isRawText && typeof nestedChild === "string" ? nestedChild : renderToString(nestedChild, { pretty: false, indent: 0 });
495
534
  }
496
- } else {
497
- html += this.renderToString(child, { pretty: false, indent: 0 });
498
535
  }
536
+ } else {
537
+ html += isRawText && typeof child === "string" ? child : renderToString(child, { pretty: false, indent: 0 });
499
538
  }
500
539
  }
501
540
  }
502
- html += `</${tagName}>${newLine}`;
503
- return html;
504
541
  }
505
- resolveStateValue(value) {
506
- if (value && typeof value === "object" && "value" in value && "subscribe" in value) {
507
- return value.value;
542
+ html += `</${tagName}>${newLine}`;
543
+ return html;
544
+ }
545
+ function renderToHTMLDocument(vNode, options = {}) {
546
+ const {
547
+ title = "",
548
+ meta = [],
549
+ links = [],
550
+ scripts = [],
551
+ styles: styles2 = [],
552
+ lang = "en",
553
+ head = "",
554
+ bodyAttrs = {},
555
+ pretty = false
556
+ } = options;
557
+ const nl = pretty ? "\n" : "";
558
+ const indent = pretty ? " " : "";
559
+ const indent2 = pretty ? " " : "";
560
+ let html = `<!DOCTYPE html>${nl}<html lang="${lang}">${nl}${indent}<head>${nl}${indent2}<meta charset="UTF-8">${nl}${indent2}<meta name="viewport" content="width=device-width, initial-scale=1.0">${nl}`;
561
+ if (title) {
562
+ html += `${indent2}<title>${escapeHtml(title)}</title>${nl}`;
563
+ }
564
+ for (const metaAttrs of meta) {
565
+ html += `${indent2}<meta`;
566
+ for (const key in metaAttrs) {
567
+ html += ` ${key}="${escapeHtml(metaAttrs[key])}"`;
508
568
  }
509
- return value;
569
+ html += `>${nl}`;
510
570
  }
511
- isReactiveWrapper(vNode) {
512
- if (!vNode || typeof vNode !== "object" || !vNode.tagName) {
513
- return false;
571
+ for (const linkAttrs of links) {
572
+ html += `${indent2}<link`;
573
+ for (const key in linkAttrs) {
574
+ html += ` ${key}="${escapeHtml(linkAttrs[key])}"`;
514
575
  }
515
- return vNode.tagName === "span" && vNode.props?.id && typeof vNode.props.id === "string" && vNode.props.id.match(/^r[a-z0-9]{9}$/);
576
+ html += `>${nl}`;
516
577
  }
517
- unwrapReactive(vNode) {
518
- if (!this.isReactiveWrapper(vNode)) {
519
- return vNode;
520
- }
521
- const children = vNode.children;
522
- if (!children || children.length === 0) {
523
- return "";
578
+ for (const style of styles2) {
579
+ if (style.href) {
580
+ html += `${indent2}<link rel="stylesheet" href="${escapeHtml(style.href)}">${nl}`;
581
+ } else if (style.content) {
582
+ html += `${indent2}<style>${style.content}</style>${nl}`;
524
583
  }
525
- if (children.length === 1) {
526
- const child = children[0];
527
- if (child && typeof child === "object" && child.tagName === "span") {
528
- const props = child.props;
529
- const hasNoProps = !props || Object.keys(props).length === 0;
530
- const hasSingleStringChild = child.children && child.children.length === 1 && typeof child.children[0] === "string";
531
- if (hasNoProps && hasSingleStringChild) {
532
- return child.children[0];
533
- }
534
- }
535
- return this.unwrapReactive(child);
536
- }
537
- return children.map((c) => this.unwrapReactive(c));
538
584
  }
539
- escapeHtml(text) {
540
- const htmlEscapes = {
541
- "&": "&amp;",
542
- "<": "&lt;",
543
- ">": "&gt;",
544
- '"': "&quot;",
545
- "'": "&#x27;"
546
- };
547
- return text.replace(/[&<>"']/g, (char) => htmlEscapes[char]);
548
- }
549
- isSelfClosingTag(tagName) {
550
- const selfClosingTags = /* @__PURE__ */ new Set([
551
- "area",
552
- "base",
553
- "br",
554
- "col",
555
- "embed",
556
- "hr",
557
- "img",
558
- "input",
559
- "link",
560
- "meta",
561
- "param",
562
- "source",
563
- "track",
564
- "wbr"
565
- ]);
566
- return selfClosingTags.has(tagName.toLowerCase());
567
- }
568
- propsToAttributes(props, tagName) {
569
- const attrs = [];
570
- for (const key in props) {
571
- if (key === "children" || key === "dangerouslySetInnerHTML" || key === "ref" || tagName === "textarea" && key === "value") {
572
- continue;
573
- }
574
- let value = props[key];
575
- value = this.resolveStateValue(value);
576
- if (value == null || value === false) continue;
577
- if (key.startsWith("on") && typeof value === "function") {
578
- continue;
579
- }
580
- if (key === "className" || key === "class") {
581
- const className = Array.isArray(value) ? value.join(" ") : value;
582
- if (className) {
583
- attrs.push(`class="${this.escapeHtml(String(className))}"`);
584
- }
585
- continue;
586
- }
587
- if (key === "style") {
588
- const styleStr = this.styleToString(value);
589
- if (styleStr) {
590
- attrs.push(`style="${this.escapeHtml(styleStr)}"`);
591
- }
592
- continue;
593
- }
594
- if (value === true) {
595
- attrs.push(key);
596
- continue;
597
- }
598
- attrs.push(`${key}="${this.escapeHtml(String(value))}"`);
599
- }
600
- return attrs.join(" ");
585
+ if (head) {
586
+ html += head + nl;
587
+ }
588
+ html += `${indent}</head>${nl}${indent}<body`;
589
+ for (const key in bodyAttrs) {
590
+ html += ` ${key}="${escapeHtml(bodyAttrs[key])}"`;
601
591
  }
602
- styleToString(style) {
603
- if (typeof style === "string") {
604
- return style;
592
+ html += `>${nl}`;
593
+ html += renderToString(vNode, { pretty, indent: 2 });
594
+ for (const script of scripts) {
595
+ html += `${indent2}<script`;
596
+ if (script.type) {
597
+ html += ` type="${escapeHtml(script.type)}"`;
605
598
  }
606
- if (typeof style === "object" && style !== null) {
607
- const styles2 = [];
608
- for (const key in style) {
609
- const cssKey = key.replace(/([A-Z])/g, "-$1").toLowerCase();
610
- styles2.push(`${cssKey}:${style[key]}`);
611
- }
612
- return styles2.join(";");
599
+ if (script.async) {
600
+ html += " async";
613
601
  }
614
- return "";
615
- }
616
- isState(value) {
617
- return value && typeof value === "object" && "value" in value && "subscribe" in value && typeof value.subscribe === "function";
618
- }
619
- createReactiveChild(state, renderFn) {
620
- const currentValue = renderFn(state.value);
621
- if (typeof window !== "undefined" && typeof document !== "undefined") {
622
- const entry = { node: null, renderFn };
623
- this.reactiveNodes.set(state, entry);
624
- state.subscribe(() => {
625
- if (entry.node && entry.node.parentNode) {
626
- const newValue = renderFn(state.value);
627
- entry.node.textContent = String(newValue ?? "");
628
- }
629
- });
602
+ if (script.defer) {
603
+ html += " defer";
604
+ }
605
+ if (script.src) {
606
+ html += ` src="${escapeHtml(script.src)}"></script>${nl}`;
607
+ } else if (script.content) {
608
+ html += `>${script.content}</script>${nl}`;
609
+ } else {
610
+ html += `></script>${nl}`;
630
611
  }
631
- return currentValue;
632
612
  }
633
- jsonToVNode(json) {
634
- if (this.isState(json)) {
635
- return this.createReactiveChild(json, (v) => v);
636
- }
637
- if (isPrimitiveJson(json)) {
638
- return json;
639
- }
640
- const { tag, attributes = {}, children } = json;
641
- const props = {};
642
- for (const key in attributes) {
643
- const value = attributes[key];
644
- if (key === "class") {
645
- props.className = this.isState(value) ? value.value : value;
646
- } else {
647
- props[key] = this.isState(value) ? value.value : value;
648
- }
613
+ html += `${indent}</body>${nl}</html>`;
614
+ return html;
615
+ }
616
+
617
+ // src/client/dom/json.ts
618
+ function jsonToVNode(json, reactiveNodes) {
619
+ if (isState(json)) {
620
+ return createReactiveChild(json, reactiveNodes, (value) => value);
621
+ }
622
+ if (isPrimitiveJson(json)) {
623
+ return json;
624
+ }
625
+ const { tag, attributes = {}, children } = json;
626
+ const props = {};
627
+ for (const key in attributes) {
628
+ const value = attributes[key];
629
+ if (key === "class") {
630
+ props.className = isState(value) ? value.value : value;
631
+ } else {
632
+ props[key] = isState(value) ? value.value : value;
649
633
  }
650
- const childrenArray = [];
651
- if (children != null) {
652
- if (Array.isArray(children)) {
653
- for (const child of children) {
654
- if (this.isState(child)) {
655
- childrenArray.push(this.createReactiveChild(child, (v) => v));
656
- } else {
657
- const converted = this.jsonToVNode(child);
658
- if (converted != null && converted !== false) {
659
- childrenArray.push(converted);
660
- }
634
+ }
635
+ const childrenArray = [];
636
+ if (children != null) {
637
+ if (Array.isArray(children)) {
638
+ for (const child of children) {
639
+ if (isState(child)) {
640
+ childrenArray.push(createReactiveChild(child, reactiveNodes, (value) => value));
641
+ } else {
642
+ const converted = jsonToVNode(child, reactiveNodes);
643
+ if (converted != null && converted !== false) {
644
+ childrenArray.push(converted);
661
645
  }
662
646
  }
663
- } else if (this.isState(children)) {
664
- childrenArray.push(this.createReactiveChild(children, (v) => v));
665
- } else if (typeof children === "object" && "tag" in children) {
666
- const converted = this.jsonToVNode(children);
667
- if (converted != null && converted !== false) {
668
- childrenArray.push(converted);
669
- }
670
- } else {
671
- childrenArray.push(children);
672
647
  }
673
- }
674
- return { tagName: tag, props, children: childrenArray };
675
- }
676
- vNodeJsonToVNode(json) {
677
- if (this.isState(json)) {
678
- return this.createReactiveChild(json, (v) => v);
679
- }
680
- if (isPrimitiveJson(json)) {
681
- return json;
682
- }
683
- const { tagName, props = {}, children = [] } = json;
684
- const resolvedProps = {};
685
- for (const key in props) {
686
- const value = props[key];
687
- resolvedProps[key] = this.isState(value) ? value.value : value;
688
- }
689
- const childrenArray = [];
690
- for (const child of children) {
691
- if (this.isState(child)) {
692
- childrenArray.push(this.createReactiveChild(child, (v) => v));
693
- } else {
694
- const converted = this.vNodeJsonToVNode(child);
695
- if (converted != null && converted !== false) {
696
- childrenArray.push(converted);
697
- }
648
+ } else if (isState(children)) {
649
+ childrenArray.push(createReactiveChild(children, reactiveNodes, (value) => value));
650
+ } else if (typeof children === "object" && children !== null && "tag" in children) {
651
+ const converted = jsonToVNode(children, reactiveNodes);
652
+ if (converted != null && converted !== false) {
653
+ childrenArray.push(converted);
698
654
  }
655
+ } else {
656
+ childrenArray.push(children);
699
657
  }
700
- return { tagName, props: resolvedProps, children: childrenArray };
701
- }
702
- renderJson(rootElement, json) {
703
- const vNode = this.jsonToVNode(json);
704
- if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
705
- throw new Error("Invalid JSON structure");
706
- }
707
- return this.render(rootElement, vNode);
708
658
  }
709
- renderVNode(rootElement, json) {
710
- const vNode = this.vNodeJsonToVNode(json);
711
- if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
712
- throw new Error("Invalid VNode JSON structure");
659
+ return { tagName: tag, props, children: childrenArray };
660
+ }
661
+ function vNodeJsonToVNode(json, reactiveNodes) {
662
+ if (isState(json)) {
663
+ return createReactiveChild(json, reactiveNodes, (value) => value);
664
+ }
665
+ if (isPrimitiveJson(json)) {
666
+ return json;
667
+ }
668
+ const { tagName, props = {}, children = [] } = json;
669
+ const resolvedProps = {};
670
+ for (const key in props) {
671
+ const value = props[key];
672
+ resolvedProps[key] = isState(value) ? value.value : value;
673
+ }
674
+ const childrenArray = [];
675
+ for (const child of children) {
676
+ if (isState(child)) {
677
+ childrenArray.push(createReactiveChild(child, reactiveNodes, (value) => value));
678
+ } else {
679
+ const converted = vNodeJsonToVNode(child, reactiveNodes);
680
+ if (converted != null && converted !== false) {
681
+ childrenArray.push(converted);
682
+ }
713
683
  }
714
- return this.render(rootElement, vNode);
715
684
  }
716
- renderJsonToString(json, options = {}) {
717
- const vNode = this.jsonToVNode(json);
718
- return this.renderToString(vNode, options);
685
+ return { tagName, props: resolvedProps, children: childrenArray };
686
+ }
687
+ function renderJson(rootElement, json, reactiveNodes) {
688
+ const vNode = jsonToVNode(json, reactiveNodes);
689
+ if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
690
+ throw new Error("Invalid JSON structure");
719
691
  }
720
- renderVNodeToString(json, options = {}) {
721
- const vNode = this.vNodeJsonToVNode(json);
722
- return this.renderToString(vNode, options);
692
+ return render(rootElement, vNode);
693
+ }
694
+ function renderVNode(rootElement, json, reactiveNodes) {
695
+ const vNode = vNodeJsonToVNode(json, reactiveNodes);
696
+ if (!vNode || typeof vNode !== "object" || !("tagName" in vNode)) {
697
+ throw new Error("Invalid VNode JSON structure");
723
698
  }
724
- // Generate complete HTML document as string (for SSR)
725
- renderToHTMLDocument(vNode, options = {}) {
726
- const { title = "", meta = [], links = [], scripts = [], styles: styles2 = [], lang = "en", head = "", bodyAttrs = {}, pretty = false } = options;
727
- const nl = pretty ? "\n" : "";
728
- const indent = pretty ? " " : "";
729
- const indent2 = pretty ? " " : "";
730
- let html = `<!DOCTYPE html>${nl}<html lang="${lang}">${nl}${indent}<head>${nl}${indent2}<meta charset="UTF-8">${nl}${indent2}<meta name="viewport" content="width=device-width, initial-scale=1.0">${nl}`;
731
- if (title) html += `${indent2}<title>${this.escapeHtml(title)}</title>${nl}`;
732
- for (const m of meta) {
733
- html += `${indent2}<meta`;
734
- for (const k in m) html += ` ${k}="${this.escapeHtml(m[k])}"`;
735
- html += `>${nl}`;
736
- }
737
- for (const l of links) {
738
- html += `${indent2}<link`;
739
- for (const k in l) html += ` ${k}="${this.escapeHtml(l[k])}"`;
740
- html += `>${nl}`;
741
- }
742
- for (const s of styles2) {
743
- if (s.href) {
744
- html += `${indent2}<link rel="stylesheet" href="${this.escapeHtml(s.href)}">${nl}`;
745
- } else if (s.content) {
746
- html += `${indent2}<style>${s.content}</style>${nl}`;
699
+ return render(rootElement, vNode);
700
+ }
701
+ function renderJsonToString(json, reactiveNodes, options = {}) {
702
+ const vNode = jsonToVNode(json, reactiveNodes);
703
+ return renderToString(vNode, options);
704
+ }
705
+ function renderVNodeToString(json, reactiveNodes, options = {}) {
706
+ const vNode = vNodeJsonToVNode(json, reactiveNodes);
707
+ return renderToString(vNode, options);
708
+ }
709
+
710
+ // src/client/dom/state-utils.ts
711
+ function createState(initialValue, options = {}) {
712
+ let value = initialValue;
713
+ const listeners = /* @__PURE__ */ new Set();
714
+ let updateTimer = null;
715
+ const { throttle = 0, deep = false } = options;
716
+ const notify = () => listeners.forEach((listener) => listener(value));
717
+ const scheduleUpdate = () => {
718
+ if (throttle > 0) {
719
+ if (!updateTimer) {
720
+ updateTimer = setTimeout(() => {
721
+ updateTimer = null;
722
+ notify();
723
+ }, throttle);
747
724
  }
725
+ } else {
726
+ notify();
748
727
  }
749
- if (head) html += head + nl;
750
- html += `${indent}</head>${nl}${indent}<body`;
751
- for (const k in bodyAttrs) html += ` ${k}="${this.escapeHtml(bodyAttrs[k])}"`;
752
- html += `>${nl}`;
753
- html += this.renderToString(vNode, { pretty, indent: 2 });
754
- for (const script of scripts) {
755
- html += `${indent2}<script`;
756
- if (script.type) html += ` type="${this.escapeHtml(script.type)}"`;
757
- if (script.async) html += ` async`;
758
- if (script.defer) html += ` defer`;
759
- if (script.src) {
760
- html += ` src="${this.escapeHtml(script.src)}"></script>${nl}`;
761
- } else if (script.content) {
762
- html += `>${script.content}</script>${nl}`;
763
- } else {
764
- html += `></script>${nl}`;
728
+ };
729
+ return {
730
+ get value() {
731
+ return value;
732
+ },
733
+ set value(newValue) {
734
+ const changed = deep ? JSON.stringify(value) !== JSON.stringify(newValue) : value !== newValue;
735
+ if (changed) {
736
+ value = newValue;
737
+ scheduleUpdate();
738
+ }
739
+ },
740
+ subscribe(fn) {
741
+ listeners.add(fn);
742
+ return () => listeners.delete(fn);
743
+ },
744
+ destroy() {
745
+ listeners.clear();
746
+ if (updateTimer) {
747
+ clearTimeout(updateTimer);
765
748
  }
766
749
  }
767
- html += `${indent}</body>${nl}</html>`;
768
- return html;
769
- }
770
- // Expose elementCache for reactive updates
771
- getElementCache() {
772
- return this.elementCache;
773
- }
774
- };
775
- var dom = new DomNode();
776
- var render = dom.render.bind(dom);
777
- var renderToString = dom.renderToString.bind(dom);
778
-
779
- // src/style.ts
780
- var ELIT_SHARED_STYLE_STORE_KEY = "__elitSharedStyleStore__";
781
- function createStyleStore() {
782
- return {
783
- variables: [],
784
- rules: [],
785
- mediaRules: [],
786
- keyframes: [],
787
- fontFaces: [],
788
- imports: [],
789
- containerRules: [],
790
- supportsRules: [],
791
- layerRules: [],
792
- layerOrder: []
793
750
  };
794
751
  }
795
- function getSharedStyleStore() {
796
- const globalScope = globalThis;
797
- if (!globalScope[ELIT_SHARED_STYLE_STORE_KEY]) {
798
- globalScope[ELIT_SHARED_STYLE_STORE_KEY] = createStyleStore();
799
- }
800
- return globalScope[ELIT_SHARED_STYLE_STORE_KEY];
752
+ function computed(states, computeFn) {
753
+ const values = states.map((state) => state.value);
754
+ const result = createState(computeFn(...values));
755
+ states.forEach((state, index) => {
756
+ state.subscribe((newValue) => {
757
+ values[index] = newValue;
758
+ result.value = computeFn(...values);
759
+ });
760
+ });
761
+ return result;
801
762
  }
802
- var CreateStyle = class {
803
- constructor(store) {
804
- this.variables = [];
805
- this.rules = [];
806
- this.mediaRules = [];
807
- this.keyframes = [];
808
- this.fontFaces = [];
809
- this.imports = [];
810
- this.containerRules = [];
811
- this.supportsRules = [];
812
- this.layerRules = [];
813
- this._layerOrder = [];
814
- this.parsedSelectorChainCache = /* @__PURE__ */ new Map();
815
- if (!store) {
816
- return;
763
+ function effect(stateFn) {
764
+ stateFn();
765
+ }
766
+ function createVirtualList(container2, items, renderItem, itemHeight = 50, bufferSize = 5) {
767
+ const viewportHeight = container2.clientHeight;
768
+ const totalHeight = items.length * itemHeight;
769
+ let scrollTop = 0;
770
+ const getVisibleRange = () => {
771
+ const start = Math.max(0, Math.floor(scrollTop / itemHeight) - bufferSize);
772
+ const end = Math.min(items.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + bufferSize);
773
+ return { start, end };
774
+ };
775
+ const render3 = () => {
776
+ const { start, end } = getVisibleRange();
777
+ const wrapper = document.createElement("div");
778
+ wrapper.style.cssText = `height:${totalHeight}px;position:relative`;
779
+ for (let i = start; i < end; i++) {
780
+ const itemEl = document.createElement("div");
781
+ itemEl.style.cssText = `position:absolute;top:${i * itemHeight}px;height:${itemHeight}px;width:100%`;
782
+ renderToDOM(renderItem(items[i], i), itemEl);
783
+ wrapper.appendChild(itemEl);
784
+ }
785
+ container2.innerHTML = "";
786
+ container2.appendChild(wrapper);
787
+ };
788
+ const scrollHandler = () => {
789
+ scrollTop = container2.scrollTop;
790
+ requestAnimationFrame(render3);
791
+ };
792
+ container2.addEventListener("scroll", scrollHandler);
793
+ render3();
794
+ return {
795
+ render: render3,
796
+ destroy: () => {
797
+ container2.removeEventListener("scroll", scrollHandler);
798
+ container2.innerHTML = "";
817
799
  }
818
- this.variables = store.variables;
819
- this.rules = store.rules;
820
- this.mediaRules = store.mediaRules;
821
- this.keyframes = store.keyframes;
822
- this.fontFaces = store.fontFaces;
823
- this.imports = store.imports;
824
- this.containerRules = store.containerRules;
825
- this.supportsRules = store.supportsRules;
826
- this.layerRules = store.layerRules;
827
- this._layerOrder = store.layerOrder;
800
+ };
801
+ }
802
+ function lazy(loadFn) {
803
+ let component = null;
804
+ let loading = false;
805
+ return async (...args) => {
806
+ if (!component && !loading) {
807
+ loading = true;
808
+ component = await loadFn();
809
+ loading = false;
810
+ }
811
+ return component ? component(...args) : { tagName: "div", props: { class: "loading" }, children: ["Loading..."] };
812
+ };
813
+ }
814
+
815
+ // src/client/dom/index.ts
816
+ var DomNode = class {
817
+ constructor() {
818
+ this.elementCache = /* @__PURE__ */ new WeakMap();
819
+ this.reactiveNodes = /* @__PURE__ */ new Map();
828
820
  }
829
- // CSS Variables
830
- addVar(name, value) {
831
- const cssVar = {
832
- name: name.startsWith("--") ? name : `--${name}`,
833
- value,
834
- toString() {
835
- return `var(${this.name})`;
836
- }
837
- };
838
- this.variables.push(cssVar);
839
- return cssVar;
821
+ createElement(tagName, props = {}, children = []) {
822
+ return { tagName, props, children };
840
823
  }
841
- var(variable, fallback) {
842
- const varName = typeof variable === "string" ? variable.startsWith("--") ? variable : `--${variable}` : variable.name;
843
- return fallback ? `var(${varName}, ${fallback})` : `var(${varName})`;
824
+ renderToDOM(vNode, parent) {
825
+ return renderToDOM(vNode, parent);
844
826
  }
845
- // Basic Selectors
846
- addTag(tag, styles2) {
847
- const rule = { selector: tag, styles: styles2, type: "tag" };
848
- this.rules.push(rule);
849
- return rule;
827
+ render(rootElement, vNode) {
828
+ return render(rootElement, vNode);
850
829
  }
851
- addClass(name, styles2) {
852
- const selector = name.startsWith(".") ? name : `.${name}`;
853
- const rule = { selector, styles: styles2, type: "class" };
854
- this.rules.push(rule);
855
- return rule;
830
+ batchRender(rootElement, vNodes) {
831
+ return batchRender(rootElement, vNodes);
856
832
  }
857
- addId(name, styles2) {
858
- const selector = name.startsWith("#") ? name : `#${name}`;
859
- const rule = { selector, styles: styles2, type: "id" };
860
- this.rules.push(rule);
861
- return rule;
833
+ renderChunked(rootElement, vNodes, chunkSize = 5e3, onProgress) {
834
+ return renderChunked(rootElement, vNodes, chunkSize, onProgress);
862
835
  }
863
- // Pseudo Selectors
864
- addPseudoClass(pseudo, styles2, baseSelector) {
865
- const pseudoClass = pseudo.startsWith(":") ? pseudo : `:${pseudo}`;
866
- const selector = baseSelector ? `${baseSelector}${pseudoClass}` : pseudoClass;
867
- const rule = { selector, styles: styles2, type: "pseudo-class" };
868
- this.rules.push(rule);
869
- return rule;
836
+ renderToHead(...vNodes) {
837
+ return renderToHead(...vNodes);
870
838
  }
871
- addPseudoElement(pseudo, styles2, baseSelector) {
872
- const pseudoElement = pseudo.startsWith("::") ? pseudo : `::${pseudo}`;
873
- const selector = baseSelector ? `${baseSelector}${pseudoElement}` : pseudoElement;
874
- const rule = { selector, styles: styles2, type: "pseudo-element" };
875
- this.rules.push(rule);
876
- return rule;
839
+ addStyle(cssText) {
840
+ return addStyle(cssText);
877
841
  }
878
- // Attribute Selectors
879
- addAttribute(attr, styles2, baseSelector) {
880
- const attrSelector = attr.startsWith("[") ? attr : `[${attr}]`;
881
- const selector = baseSelector ? `${baseSelector}${attrSelector}` : attrSelector;
882
- const rule = { selector, styles: styles2, type: "attribute" };
883
- this.rules.push(rule);
884
- return rule;
842
+ addMeta(attrs) {
843
+ return addMeta(attrs);
885
844
  }
886
- attrEquals(attr, value, styles2, baseSelector) {
887
- return this.addAttribute(`${attr}="${value}"`, styles2, baseSelector);
845
+ addLink(attrs) {
846
+ return addLink(attrs);
888
847
  }
889
- attrContainsWord(attr, value, styles2, baseSelector) {
890
- return this.addAttribute(`${attr}~="${value}"`, styles2, baseSelector);
848
+ setTitle(text) {
849
+ return setTitle(text);
891
850
  }
892
- attrStartsWith(attr, value, styles2, baseSelector) {
893
- return this.addAttribute(`${attr}^="${value}"`, styles2, baseSelector);
851
+ // Reactive State Management
852
+ createState(initialValue, options = {}) {
853
+ return createState(initialValue, options);
894
854
  }
895
- attrEndsWith(attr, value, styles2, baseSelector) {
896
- return this.addAttribute(`${attr}$="${value}"`, styles2, baseSelector);
855
+ computed(states, computeFn) {
856
+ return computed(states, computeFn);
897
857
  }
898
- attrContains(attr, value, styles2, baseSelector) {
899
- return this.addAttribute(`${attr}*="${value}"`, styles2, baseSelector);
858
+ effect(stateFn) {
859
+ effect(stateFn);
900
860
  }
901
- // Combinator Selectors
902
- descendant(ancestor, descendant2, styles2) {
903
- return this.createAndAddRule(`${ancestor} ${descendant2}`, styles2);
861
+ // Virtual scrolling helper for large lists
862
+ createVirtualList(container2, items, renderItem, itemHeight = 50, bufferSize = 5) {
863
+ return createVirtualList(container2, items, renderItem, itemHeight, bufferSize);
904
864
  }
905
- child(parent, childSel, styles2) {
906
- return this.createAndAddRule(`${parent} > ${childSel}`, styles2);
865
+ // Lazy load components
866
+ lazy(loadFn) {
867
+ return lazy(loadFn);
907
868
  }
908
- adjacentSibling(element, sibling, styles2) {
909
- return this.createAndAddRule(`${element} + ${sibling}`, styles2);
869
+ // Memory management - cleanup unused elements
870
+ cleanupUnusedElements(root) {
871
+ return cleanupUnusedElements(root, this.elementCache);
910
872
  }
911
- generalSibling(element, sibling, styles2) {
912
- return this.createAndAddRule(`${element} ~ ${sibling}`, styles2);
873
+ // Server-Side Rendering - convert VNode to HTML string
874
+ renderToString(vNode, options = {}) {
875
+ return renderToString(vNode, options);
913
876
  }
914
- multiple(selectors, styles2) {
915
- return this.createAndAddRule(selectors.join(", "), styles2);
877
+ jsonToVNode(json) {
878
+ return jsonToVNode(json, this.reactiveNodes);
916
879
  }
917
- // Nesting (BEM-style)
918
- addName(name, styles2) {
919
- const selector = name.startsWith("--") ? `&${name}` : `&--${name}`;
920
- const rule = { selector, styles: styles2, type: "name" };
921
- return rule;
880
+ vNodeJsonToVNode(json) {
881
+ return vNodeJsonToVNode(json, this.reactiveNodes);
922
882
  }
923
- nesting(parentRule, ...childRules) {
924
- parentRule.nested = childRules;
925
- return parentRule;
883
+ renderJson(rootElement, json) {
884
+ return renderJson(rootElement, json, this.reactiveNodes);
926
885
  }
927
- // @keyframes - Animations
928
- keyframe(name, steps) {
929
- const keyframeSteps = Object.entries(steps).map(([step, styles2]) => ({
930
- step: step === "from" ? "from" : step === "to" ? "to" : `${step}%`,
931
- styles: styles2
932
- }));
933
- const kf = { name, steps: keyframeSteps };
934
- this.keyframes.push(kf);
935
- return kf;
886
+ renderVNode(rootElement, json) {
887
+ return renderVNode(rootElement, json, this.reactiveNodes);
936
888
  }
937
- keyframeFromTo(name, from, to) {
938
- return this.keyframe(name, { from, to });
889
+ renderJsonToString(json, options = {}) {
890
+ return renderJsonToString(json, this.reactiveNodes, options);
939
891
  }
940
- // @font-face - Custom Fonts
941
- fontFace(options) {
942
- this.fontFaces.push(options);
943
- return options;
892
+ renderVNodeToString(json, options = {}) {
893
+ return renderVNodeToString(json, this.reactiveNodes, options);
944
894
  }
945
- // @import - Import Stylesheets
946
- import(url, mediaQuery) {
947
- const importRule = mediaQuery ? `@import url("${url}") ${mediaQuery};` : `@import url("${url}");`;
948
- this.imports.push(importRule);
949
- return importRule;
895
+ // Generate complete HTML document as string (for SSR)
896
+ renderToHTMLDocument(vNode, options = {}) {
897
+ return renderToHTMLDocument(vNode, options);
950
898
  }
951
- // @media - Media Queries
952
- media(type, condition, rules) {
953
- const mediaRule = { type, condition, rules: this.rulesToCSSRules(rules) };
954
- this.mediaRules.push(mediaRule);
955
- return mediaRule;
899
+ // Expose elementCache for reactive updates
900
+ getElementCache() {
901
+ return this.elementCache;
956
902
  }
957
- mediaScreen(condition, rules) {
958
- return this.media("screen", condition, rules);
903
+ };
904
+ var dom = new DomNode();
905
+ var render2 = dom.render.bind(dom);
906
+ var renderToString2 = dom.renderToString.bind(dom);
907
+
908
+ // src/client/style/condition-utils.ts
909
+ function splitConditionalClauses(value, operator) {
910
+ const clauses = [];
911
+ let token = "";
912
+ let depth = 0;
913
+ for (let index = 0; index < value.length; index++) {
914
+ const char = value[index];
915
+ if (char === "(") {
916
+ depth += 1;
917
+ } else if (char === ")" && depth > 0) {
918
+ depth -= 1;
919
+ }
920
+ const operatorToken = ` ${operator} `;
921
+ if (depth === 0 && value.slice(index, index + operatorToken.length).toLowerCase() === operatorToken) {
922
+ const trimmed = token.trim();
923
+ if (trimmed) {
924
+ clauses.push(trimmed);
925
+ }
926
+ token = "";
927
+ index += operatorToken.length - 1;
928
+ continue;
929
+ }
930
+ token += char;
931
+ }
932
+ const trailing = token.trim();
933
+ if (trailing) {
934
+ clauses.push(trailing);
935
+ }
936
+ return clauses;
937
+ }
938
+ function matchesSupportsDeclaration(property, value) {
939
+ const normalizedProperty = property.trim().toLowerCase();
940
+ const normalizedValue = value.trim().toLowerCase();
941
+ const supportedProperties = /* @__PURE__ */ new Set([
942
+ "align-items",
943
+ "background",
944
+ "background-color",
945
+ "backdrop-filter",
946
+ "border",
947
+ "border-radius",
948
+ "box-shadow",
949
+ "color",
950
+ "column-gap",
951
+ "container-name",
952
+ "container-type",
953
+ "display",
954
+ "flex",
955
+ "flex-direction",
956
+ "flex-grow",
957
+ "flex-wrap",
958
+ "font-family",
959
+ "font-size",
960
+ "font-weight",
961
+ "gap",
962
+ "grid-template-columns",
963
+ "height",
964
+ "justify-content",
965
+ "letter-spacing",
966
+ "line-height",
967
+ "margin",
968
+ "margin-bottom",
969
+ "margin-left",
970
+ "margin-right",
971
+ "margin-top",
972
+ "max-height",
973
+ "max-width",
974
+ "min-height",
975
+ "min-width",
976
+ "padding",
977
+ "padding-bottom",
978
+ "padding-end",
979
+ "padding-horizontal",
980
+ "padding-left",
981
+ "padding-right",
982
+ "padding-start",
983
+ "padding-top",
984
+ "padding-vertical",
985
+ "row-gap",
986
+ "text-align",
987
+ "text-decoration",
988
+ "text-transform",
989
+ "width"
990
+ ]);
991
+ if (!supportedProperties.has(normalizedProperty)) {
992
+ return false;
959
993
  }
960
- mediaPrint(rules) {
961
- return this.media("print", "", rules);
994
+ if (normalizedProperty === "display") {
995
+ return (/* @__PURE__ */ new Set(["block", "flex", "grid", "inline", "inline-block", "inline-flex", "inline-grid"])).has(normalizedValue);
962
996
  }
963
- mediaMinWidth(minWidth, rules) {
964
- return this.media("screen", `min-width: ${minWidth}`, rules);
997
+ if (normalizedProperty === "backdrop-filter") {
998
+ return /blur\(/.test(normalizedValue);
965
999
  }
966
- mediaMaxWidth(maxWidth, rules) {
967
- return this.media("screen", `max-width: ${maxWidth}`, rules);
1000
+ if (normalizedProperty === "container-type") {
1001
+ return (/* @__PURE__ */ new Set(["inline-size", "size"])).has(normalizedValue);
968
1002
  }
969
- mediaDark(rules) {
970
- const mediaRule = { type: "", condition: "prefers-color-scheme: dark", rules: this.rulesToCSSRules(rules) };
971
- this.mediaRules.push(mediaRule);
972
- return mediaRule;
1003
+ return true;
1004
+ }
1005
+ function matchesSupportsCondition(condition) {
1006
+ const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim();
1007
+ if (!normalized) {
1008
+ return true;
973
1009
  }
974
- mediaLight(rules) {
975
- const mediaRule = { type: "", condition: "prefers-color-scheme: light", rules: this.rulesToCSSRules(rules) };
976
- this.mediaRules.push(mediaRule);
977
- return mediaRule;
1010
+ if (normalized.toLowerCase().startsWith("not ")) {
1011
+ return !matchesSupportsCondition(normalized.slice(4));
978
1012
  }
979
- mediaReducedMotion(rules) {
980
- const mediaRule = { type: "", condition: "prefers-reduced-motion: reduce", rules: this.rulesToCSSRules(rules) };
981
- this.mediaRules.push(mediaRule);
982
- return mediaRule;
1013
+ const orClauses = splitConditionalClauses(normalized, "or");
1014
+ if (orClauses.length > 1) {
1015
+ return orClauses.some((clause) => matchesSupportsCondition(clause));
983
1016
  }
984
- // @container - Container Queries
985
- container(condition, rules, name) {
986
- const containerRule = { name, condition, rules: this.rulesToCSSRules(rules) };
987
- this.containerRules.push(containerRule);
988
- return containerRule;
1017
+ const andClauses = splitConditionalClauses(normalized, "and");
1018
+ if (andClauses.length > 1) {
1019
+ return andClauses.every((clause) => matchesSupportsCondition(clause));
989
1020
  }
990
- addContainer(name, styles2) {
991
- const containerStyles = { ...styles2, containerName: name };
992
- return this.addClass(name, containerStyles);
1021
+ const declarationMatch = normalized.match(/^([a-z-]+)\s*:\s*(.+)$/i);
1022
+ if (!declarationMatch) {
1023
+ return false;
993
1024
  }
994
- // @supports - Feature Queries
995
- supports(condition, rules) {
996
- const supportsRule = { condition, rules: this.rulesToCSSRules(rules) };
997
- this.supportsRules.push(supportsRule);
998
- return supportsRule;
1025
+ return matchesSupportsDeclaration(declarationMatch[1], declarationMatch[2]);
1026
+ }
1027
+ function findMatchingContainerTarget(ancestors, name) {
1028
+ const normalizedName = typeof name === "string" && name.trim() ? name.trim().toLowerCase() : void 0;
1029
+ for (let index = ancestors.length - 1; index >= 0; index--) {
1030
+ const ancestor = ancestors[index];
1031
+ if (!ancestor?.isContainer || ancestor.containerWidth === void 0) {
1032
+ continue;
1033
+ }
1034
+ if (!normalizedName) {
1035
+ return ancestor;
1036
+ }
1037
+ if ((ancestor.containerNames ?? []).includes(normalizedName)) {
1038
+ return ancestor;
1039
+ }
999
1040
  }
1000
- // @layer - Cascade Layers
1001
- layerOrder(...layers) {
1002
- this._layerOrder = layers;
1041
+ return void 0;
1042
+ }
1043
+ function matchesContainerCondition(condition, containerWidth) {
1044
+ const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim().toLowerCase();
1045
+ if (!normalized) {
1046
+ return true;
1003
1047
  }
1004
- layer(name, rules) {
1005
- const layerRule = { name, rules: this.rulesToCSSRules(rules) };
1006
- this.layerRules.push(layerRule);
1007
- return layerRule;
1048
+ if (normalized.startsWith("not ")) {
1049
+ return !matchesContainerCondition(normalized.slice(4), containerWidth);
1008
1050
  }
1009
- // Custom Rules
1010
- add(rules) {
1011
- const cssRules = Object.entries(rules).map(([selector, styles2]) => {
1012
- const rule = { selector, styles: styles2, type: "custom" };
1013
- this.rules.push(rule);
1014
- return rule;
1015
- });
1016
- return cssRules;
1051
+ const orClauses = splitConditionalClauses(normalized, "or");
1052
+ if (orClauses.length > 1) {
1053
+ return orClauses.some((clause) => matchesContainerCondition(clause, containerWidth));
1017
1054
  }
1018
- important(value) {
1019
- return `${value} !important`;
1055
+ const andClauses = splitConditionalClauses(normalized, "and");
1056
+ if (andClauses.length > 1) {
1057
+ return andClauses.every((clause) => matchesContainerCondition(clause, containerWidth));
1020
1058
  }
1021
- getVariables() {
1022
- return Object.fromEntries(this.variables.map((variable) => [variable.name, variable.value]));
1059
+ if (normalized.startsWith("min-width:")) {
1060
+ const minWidth = parseMediaLength(normalized.slice("min-width:".length));
1061
+ return minWidth !== void 0 && containerWidth >= minWidth;
1023
1062
  }
1024
- resolveVariableReferences(value, variables) {
1025
- let resolved = value;
1026
- for (let index = 0; index < 8; index++) {
1027
- let replaced = false;
1028
- resolved = resolved.replace(/var\(\s*(--[\w-]+)\s*(?:,\s*([^\)]+))?\)/g, (match, name, fallback) => {
1029
- const variableValue = variables[name];
1030
- if (variableValue !== void 0) {
1031
- replaced = true;
1032
- return variableValue;
1033
- }
1034
- if (fallback !== void 0) {
1035
- replaced = true;
1036
- return fallback.trim();
1037
- }
1038
- return match;
1039
- });
1040
- if (!replaced) {
1041
- break;
1042
- }
1063
+ if (normalized.startsWith("max-width:")) {
1064
+ const maxWidth = parseMediaLength(normalized.slice("max-width:".length));
1065
+ return maxWidth !== void 0 && containerWidth <= maxWidth;
1066
+ }
1067
+ return false;
1068
+ }
1069
+ function parseMediaLength(value) {
1070
+ const match = value.trim().match(/^(-?\d+(?:\.\d+)?)(px|rem|em)?$/i);
1071
+ if (!match) {
1072
+ return void 0;
1073
+ }
1074
+ const numericValue = Number(match[1]);
1075
+ const unit = (match[2] ?? "px").toLowerCase();
1076
+ if (unit === "rem" || unit === "em") {
1077
+ return numericValue * 16;
1078
+ }
1079
+ return numericValue;
1080
+ }
1081
+ function matchesMediaCondition(condition, options) {
1082
+ const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim().toLowerCase();
1083
+ if (!normalized) {
1084
+ return true;
1085
+ }
1086
+ if (normalized.startsWith("min-width:")) {
1087
+ const minWidth = parseMediaLength(normalized.slice("min-width:".length));
1088
+ return minWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth >= minWidth;
1089
+ }
1090
+ if (normalized.startsWith("max-width:")) {
1091
+ const maxWidth = parseMediaLength(normalized.slice("max-width:".length));
1092
+ return maxWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth <= maxWidth;
1093
+ }
1094
+ if (normalized === "prefers-color-scheme: dark") {
1095
+ return options.colorScheme === "dark";
1096
+ }
1097
+ if (normalized === "prefers-color-scheme: light") {
1098
+ return (options.colorScheme ?? "light") === "light";
1099
+ }
1100
+ if (normalized === "prefers-reduced-motion: reduce") {
1101
+ return options.reducedMotion === true;
1102
+ }
1103
+ return false;
1104
+ }
1105
+ function matchesMediaRule(rule, options) {
1106
+ const mediaType = options.mediaType ?? "screen";
1107
+ if (rule.type && rule.type !== mediaType && rule.type !== "all") {
1108
+ return false;
1109
+ }
1110
+ if (!rule.condition.trim()) {
1111
+ return true;
1112
+ }
1113
+ return rule.condition.split(/\band\b/i).map((part) => part.trim()).filter(Boolean).every((part) => matchesMediaCondition(part, options));
1114
+ }
1115
+ function getOrderedLayerNames(layerOrder2, layerRules) {
1116
+ const orderedLayerNames = [];
1117
+ for (const layerName of layerOrder2) {
1118
+ const normalizedName = layerName.trim();
1119
+ if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
1120
+ orderedLayerNames.push(normalizedName);
1043
1121
  }
1044
- return resolved.replace(/\s*!important\s*$/i, "").trim();
1045
1122
  }
1046
- normalizeTargetIdentity(target) {
1047
- return {
1048
- tagName: typeof target.tagName === "string" && target.tagName.trim() ? target.tagName.trim().toLowerCase() : void 0,
1049
- classNames: Array.isArray(target.classNames) ? target.classNames.map((className) => className.trim()).filter(Boolean) : [],
1050
- attributes: target.attributes ? Object.fromEntries(
1051
- Object.entries(target.attributes).filter(([, value]) => value !== void 0 && value !== null && value !== false).map(([name, value]) => [name.toLowerCase(), String(value)])
1052
- ) : {},
1053
- pseudoStates: Array.isArray(target.pseudoStates) ? [...new Set(target.pseudoStates.map((pseudoState) => pseudoState.trim().toLowerCase()).filter(Boolean))] : [],
1054
- childIndex: typeof target.childIndex === "number" && Number.isFinite(target.childIndex) ? target.childIndex : void 0,
1055
- siblingCount: typeof target.siblingCount === "number" && Number.isFinite(target.siblingCount) ? target.siblingCount : void 0,
1056
- sameTypeIndex: typeof target.sameTypeIndex === "number" && Number.isFinite(target.sameTypeIndex) ? target.sameTypeIndex : void 0,
1057
- sameTypeCount: typeof target.sameTypeCount === "number" && Number.isFinite(target.sameTypeCount) ? target.sameTypeCount : void 0,
1058
- containerNames: Array.isArray(target.containerNames) ? [...new Set(target.containerNames.map((containerName) => containerName.trim().toLowerCase()).filter(Boolean))] : [],
1059
- containerWidth: typeof target.containerWidth === "number" && Number.isFinite(target.containerWidth) ? target.containerWidth : void 0,
1060
- isContainer: target.isContainer === true,
1061
- isScopeReference: target.isScopeReference === true
1062
- };
1123
+ for (const layerRule of layerRules) {
1124
+ const normalizedName = layerRule.name.trim();
1125
+ if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
1126
+ orderedLayerNames.push(normalizedName);
1127
+ }
1063
1128
  }
1064
- normalizeTarget(target) {
1065
- const cached = this.nativeTargetNormalizationCache?.get(target);
1066
- if (cached) {
1067
- return cached;
1129
+ return orderedLayerNames;
1130
+ }
1131
+
1132
+ // src/client/style/selector-parser.ts
1133
+ function splitSelectorList(value) {
1134
+ const selectors = [];
1135
+ let token = "";
1136
+ let attributeDepth = 0;
1137
+ let parenthesisDepth = 0;
1138
+ let quoted;
1139
+ for (let index = 0; index < value.length; index++) {
1140
+ const char = value[index];
1141
+ if (quoted) {
1142
+ token += char;
1143
+ if (char === quoted && value[index - 1] !== "\\") {
1144
+ quoted = void 0;
1145
+ }
1146
+ continue;
1068
1147
  }
1069
- const normalized = {
1070
- ...this.normalizeTargetIdentity(target),
1071
- previousSiblings: [],
1072
- nextSiblings: [],
1073
- children: []
1074
- };
1075
- this.nativeTargetNormalizationCache?.set(target, normalized);
1076
- normalized.previousSiblings = Array.isArray(target.previousSiblings) ? target.previousSiblings.map((sibling) => this.normalizeTarget(sibling)) : [];
1077
- normalized.nextSiblings = Array.isArray(target.nextSiblings) ? target.nextSiblings.map((sibling) => this.normalizeTarget(sibling)) : [];
1078
- normalized.children = Array.isArray(target.children) ? target.children.map((child) => this.normalizeTarget(child)) : [];
1079
- return normalized;
1148
+ if (char === '"' || char === "'") {
1149
+ quoted = char;
1150
+ token += char;
1151
+ continue;
1152
+ }
1153
+ if (char === "[") {
1154
+ attributeDepth += 1;
1155
+ token += char;
1156
+ continue;
1157
+ }
1158
+ if (char === "]" && attributeDepth > 0) {
1159
+ attributeDepth -= 1;
1160
+ token += char;
1161
+ continue;
1162
+ }
1163
+ if (attributeDepth === 0 && char === "(") {
1164
+ parenthesisDepth += 1;
1165
+ token += char;
1166
+ continue;
1167
+ }
1168
+ if (attributeDepth === 0 && char === ")" && parenthesisDepth > 0) {
1169
+ parenthesisDepth -= 1;
1170
+ token += char;
1171
+ continue;
1172
+ }
1173
+ if (attributeDepth === 0 && parenthesisDepth === 0 && char === ",") {
1174
+ const trimmed = token.trim();
1175
+ if (trimmed) {
1176
+ selectors.push(trimmed);
1177
+ }
1178
+ token = "";
1179
+ continue;
1180
+ }
1181
+ token += char;
1080
1182
  }
1081
- withNativeTargetNormalizationCache(callback) {
1082
- const previousCache = this.nativeTargetNormalizationCache;
1083
- this.nativeTargetNormalizationCache = /* @__PURE__ */ new WeakMap();
1084
- try {
1085
- return callback();
1086
- } finally {
1087
- this.nativeTargetNormalizationCache = previousCache;
1183
+ const trailing = token.trim();
1184
+ if (trailing) {
1185
+ selectors.push(trailing);
1186
+ }
1187
+ return selectors;
1188
+ }
1189
+ function parsePseudoSelectorToken(token, startIndex) {
1190
+ if (token[startIndex] !== ":" || token[startIndex + 1] === ":") {
1191
+ return void 0;
1192
+ }
1193
+ let cursor = startIndex + 1;
1194
+ const nameMatch = token.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
1195
+ if (!nameMatch) {
1196
+ return void 0;
1197
+ }
1198
+ const pseudoName = nameMatch[1].toLowerCase();
1199
+ cursor += nameMatch[0].length;
1200
+ if (token[cursor] !== "(") {
1201
+ return { value: pseudoName, nextIndex: cursor };
1202
+ }
1203
+ const argumentStart = cursor + 1;
1204
+ let attributeDepth = 0;
1205
+ let parenthesisDepth = 1;
1206
+ let quoted;
1207
+ cursor += 1;
1208
+ while (cursor < token.length) {
1209
+ const char = token[cursor];
1210
+ if (quoted) {
1211
+ if (char === quoted && token[cursor - 1] !== "\\") {
1212
+ quoted = void 0;
1213
+ }
1214
+ cursor += 1;
1215
+ continue;
1216
+ }
1217
+ if (char === '"' || char === "'") {
1218
+ quoted = char;
1219
+ cursor += 1;
1220
+ continue;
1221
+ }
1222
+ if (char === "[") {
1223
+ attributeDepth += 1;
1224
+ cursor += 1;
1225
+ continue;
1226
+ }
1227
+ if (char === "]" && attributeDepth > 0) {
1228
+ attributeDepth -= 1;
1229
+ cursor += 1;
1230
+ continue;
1231
+ }
1232
+ if (attributeDepth === 0 && char === "(") {
1233
+ parenthesisDepth += 1;
1234
+ cursor += 1;
1235
+ continue;
1236
+ }
1237
+ if (attributeDepth === 0 && char === ")") {
1238
+ parenthesisDepth -= 1;
1239
+ if (parenthesisDepth === 0) {
1240
+ const pseudoArgument = token.slice(argumentStart, cursor).trim();
1241
+ return {
1242
+ value: pseudoArgument.length > 0 ? `${pseudoName}(${pseudoArgument})` : `${pseudoName}()`,
1243
+ nextIndex: cursor + 1
1244
+ };
1245
+ }
1246
+ cursor += 1;
1247
+ continue;
1088
1248
  }
1249
+ cursor += 1;
1089
1250
  }
1090
- splitConditionalClauses(value, operator) {
1091
- const clauses = [];
1092
- let token = "";
1093
- let depth = 0;
1094
- for (let index = 0; index < value.length; index++) {
1095
- const char = value[index];
1096
- if (char === "(") {
1097
- depth += 1;
1098
- } else if (char === ")" && depth > 0) {
1099
- depth -= 1;
1251
+ return void 0;
1252
+ }
1253
+ function parseSimpleSelectorToken(token) {
1254
+ const trimmed = token.trim();
1255
+ if (!trimmed || /[*&]/.test(trimmed)) {
1256
+ return void 0;
1257
+ }
1258
+ let cursor = 0;
1259
+ let tagName;
1260
+ let idName;
1261
+ const classNames = [];
1262
+ const attributes = [];
1263
+ const pseudoClasses = [];
1264
+ const tagMatch = trimmed.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
1265
+ if (tagMatch) {
1266
+ tagName = tagMatch[1].toLowerCase();
1267
+ cursor += tagMatch[0].length;
1268
+ }
1269
+ while (cursor < trimmed.length) {
1270
+ const char = trimmed[cursor];
1271
+ if (char === ".") {
1272
+ const classMatch = trimmed.slice(cursor).match(/^\.([_a-zA-Z][-_a-zA-Z0-9]*)/);
1273
+ if (!classMatch) {
1274
+ return void 0;
1100
1275
  }
1101
- const operatorToken = ` ${operator} `;
1102
- if (depth === 0 && value.slice(index, index + operatorToken.length).toLowerCase() === operatorToken) {
1103
- const trimmed = token.trim();
1104
- if (trimmed) {
1105
- clauses.push(trimmed);
1106
- }
1107
- token = "";
1108
- index += operatorToken.length - 1;
1109
- continue;
1276
+ classNames.push(classMatch[1]);
1277
+ cursor += classMatch[0].length;
1278
+ continue;
1279
+ }
1280
+ if (char === "#") {
1281
+ const idMatch = trimmed.slice(cursor).match(/^#([_a-zA-Z][-_a-zA-Z0-9]*)/);
1282
+ if (!idMatch || idName) {
1283
+ return void 0;
1110
1284
  }
1111
- token += char;
1285
+ idName = idMatch[1];
1286
+ cursor += idMatch[0].length;
1287
+ continue;
1112
1288
  }
1113
- const trailing = token.trim();
1114
- if (trailing) {
1115
- clauses.push(trailing);
1289
+ if (char === "[") {
1290
+ const endIndex = trimmed.indexOf("]", cursor + 1);
1291
+ if (endIndex === -1) {
1292
+ return void 0;
1293
+ }
1294
+ const rawAttribute = trimmed.slice(cursor + 1, endIndex).trim();
1295
+ const attrMatch = rawAttribute.match(/^([_a-zA-Z][-_a-zA-Z0-9]*)(?:\s*(=|~=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+)))?$/);
1296
+ if (!attrMatch) {
1297
+ return void 0;
1298
+ }
1299
+ attributes.push({
1300
+ name: attrMatch[1].toLowerCase(),
1301
+ operator: attrMatch[2],
1302
+ value: attrMatch[3] ?? attrMatch[4] ?? attrMatch[5]
1303
+ });
1304
+ cursor = endIndex + 1;
1305
+ continue;
1306
+ }
1307
+ if (char === ":") {
1308
+ const pseudoToken = parsePseudoSelectorToken(trimmed, cursor);
1309
+ if (!pseudoToken) {
1310
+ return void 0;
1311
+ }
1312
+ pseudoClasses.push(pseudoToken.value);
1313
+ cursor = pseudoToken.nextIndex;
1314
+ continue;
1116
1315
  }
1117
- return clauses;
1316
+ return void 0;
1317
+ }
1318
+ if (!tagName && !idName && classNames.length === 0 && attributes.length === 0 && pseudoClasses.length === 0) {
1319
+ return void 0;
1118
1320
  }
1119
- splitSelectorList(value) {
1120
- const selectors = [];
1321
+ return { tagName, idName, classNames, attributes, pseudoClasses };
1322
+ }
1323
+ function extractSupportedSelectorChains(selector, parsedSelectorChainCache) {
1324
+ const cached = parsedSelectorChainCache.get(selector);
1325
+ if (cached) {
1326
+ return cached;
1327
+ }
1328
+ const parsedChains = splitSelectorList(selector).map((segment) => segment.trim()).map((segment) => {
1329
+ const chain = [];
1121
1330
  let token = "";
1331
+ let combinator = "descendant";
1332
+ let invalid = false;
1122
1333
  let attributeDepth = 0;
1123
1334
  let parenthesisDepth = 0;
1124
1335
  let quoted;
1125
- for (let index = 0; index < value.length; index++) {
1126
- const char = value[index];
1336
+ const flushToken = () => {
1337
+ const trimmedToken = token.trim();
1338
+ token = "";
1339
+ if (!trimmedToken || invalid) {
1340
+ return;
1341
+ }
1342
+ const parsed = parseSimpleSelectorToken(trimmedToken);
1343
+ if (!parsed) {
1344
+ invalid = true;
1345
+ return;
1346
+ }
1347
+ if (chain.length > 0) {
1348
+ parsed.combinator = combinator;
1349
+ }
1350
+ chain.push(parsed);
1351
+ combinator = "descendant";
1352
+ };
1353
+ for (let index = 0; index < segment.length; index++) {
1354
+ const char = segment[index];
1127
1355
  if (quoted) {
1128
1356
  token += char;
1129
- if (char === quoted && value[index - 1] !== "\\") {
1357
+ if (char === quoted && segment[index - 1] !== "\\") {
1130
1358
  quoted = void 0;
1131
1359
  }
1132
1360
  continue;
@@ -1141,8 +1369,10 @@ var CreateStyle = class {
1141
1369
  token += char;
1142
1370
  continue;
1143
1371
  }
1144
- if (char === "]" && attributeDepth > 0) {
1145
- attributeDepth -= 1;
1372
+ if (char === "]") {
1373
+ if (attributeDepth > 0) {
1374
+ attributeDepth -= 1;
1375
+ }
1146
1376
  token += char;
1147
1377
  continue;
1148
1378
  }
@@ -1156,374 +1386,159 @@ var CreateStyle = class {
1156
1386
  token += char;
1157
1387
  continue;
1158
1388
  }
1159
- if (attributeDepth === 0 && parenthesisDepth === 0 && char === ",") {
1160
- const trimmed = token.trim();
1161
- if (trimmed) {
1162
- selectors.push(trimmed);
1389
+ if (attributeDepth === 0 && parenthesisDepth === 0 && (char === ">" || char === "+" || char === "~")) {
1390
+ flushToken();
1391
+ if (invalid) {
1392
+ break;
1163
1393
  }
1164
- token = "";
1394
+ combinator = char === ">" ? "child" : char === "+" ? "adjacent-sibling" : "general-sibling";
1165
1395
  continue;
1166
1396
  }
1167
- token += char;
1168
- }
1169
- const trailing = token.trim();
1170
- if (trailing) {
1171
- selectors.push(trailing);
1172
- }
1173
- return selectors;
1174
- }
1175
- parsePseudoSelectorToken(token, startIndex) {
1176
- if (token[startIndex] !== ":" || token[startIndex + 1] === ":") {
1177
- return void 0;
1178
- }
1179
- let cursor = startIndex + 1;
1180
- const nameMatch = token.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
1181
- if (!nameMatch) {
1182
- return void 0;
1183
- }
1184
- const pseudoName = nameMatch[1].toLowerCase();
1185
- cursor += nameMatch[0].length;
1186
- if (token[cursor] !== "(") {
1187
- return { value: pseudoName, nextIndex: cursor };
1188
- }
1189
- const argumentStart = cursor + 1;
1190
- let attributeDepth = 0;
1191
- let parenthesisDepth = 1;
1192
- let quoted;
1193
- cursor += 1;
1194
- while (cursor < token.length) {
1195
- const char = token[cursor];
1196
- if (quoted) {
1197
- if (char === quoted && token[cursor - 1] !== "\\") {
1198
- quoted = void 0;
1199
- }
1200
- cursor += 1;
1201
- continue;
1202
- }
1203
- if (char === '"' || char === "'") {
1204
- quoted = char;
1205
- cursor += 1;
1206
- continue;
1207
- }
1208
- if (char === "[") {
1209
- attributeDepth += 1;
1210
- cursor += 1;
1211
- continue;
1212
- }
1213
- if (char === "]" && attributeDepth > 0) {
1214
- attributeDepth -= 1;
1215
- cursor += 1;
1216
- continue;
1217
- }
1218
- if (attributeDepth === 0 && char === "(") {
1219
- parenthesisDepth += 1;
1220
- cursor += 1;
1221
- continue;
1222
- }
1223
- if (attributeDepth === 0 && char === ")") {
1224
- parenthesisDepth -= 1;
1225
- if (parenthesisDepth === 0) {
1226
- const pseudoArgument = token.slice(argumentStart, cursor).trim();
1227
- return {
1228
- value: pseudoArgument.length > 0 ? `${pseudoName}(${pseudoArgument})` : `${pseudoName}()`,
1229
- nextIndex: cursor + 1
1230
- };
1397
+ if (attributeDepth === 0 && parenthesisDepth === 0 && /\s/.test(char)) {
1398
+ flushToken();
1399
+ if (invalid) {
1400
+ break;
1231
1401
  }
1232
- cursor += 1;
1233
1402
  continue;
1234
1403
  }
1235
- cursor += 1;
1236
- }
1237
- return void 0;
1238
- }
1239
- matchesSupportsDeclaration(property, value) {
1240
- const normalizedProperty = property.trim().toLowerCase();
1241
- const normalizedValue = value.trim().toLowerCase();
1242
- const supportedProperties = /* @__PURE__ */ new Set([
1243
- "align-items",
1244
- "background",
1245
- "background-color",
1246
- "backdrop-filter",
1247
- "border",
1248
- "border-radius",
1249
- "box-shadow",
1250
- "color",
1251
- "column-gap",
1252
- "container-name",
1253
- "container-type",
1254
- "display",
1255
- "flex",
1256
- "flex-direction",
1257
- "flex-grow",
1258
- "flex-wrap",
1259
- "font-family",
1260
- "font-size",
1261
- "font-weight",
1262
- "gap",
1263
- "grid-template-columns",
1264
- "height",
1265
- "justify-content",
1266
- "letter-spacing",
1267
- "line-height",
1268
- "margin",
1269
- "margin-bottom",
1270
- "margin-left",
1271
- "margin-right",
1272
- "margin-top",
1273
- "max-height",
1274
- "max-width",
1275
- "min-height",
1276
- "min-width",
1277
- "padding",
1278
- "padding-bottom",
1279
- "padding-end",
1280
- "padding-horizontal",
1281
- "padding-left",
1282
- "padding-right",
1283
- "padding-start",
1284
- "padding-top",
1285
- "padding-vertical",
1286
- "row-gap",
1287
- "text-align",
1288
- "text-decoration",
1289
- "text-transform",
1290
- "width"
1291
- ]);
1292
- if (!supportedProperties.has(normalizedProperty)) {
1293
- return false;
1294
- }
1295
- if (normalizedProperty === "display") {
1296
- return (/* @__PURE__ */ new Set(["block", "flex", "grid", "inline", "inline-block", "inline-flex", "inline-grid"])).has(normalizedValue);
1297
- }
1298
- if (normalizedProperty === "backdrop-filter") {
1299
- return /blur\(/.test(normalizedValue);
1300
- }
1301
- if (normalizedProperty === "container-type") {
1302
- return (/* @__PURE__ */ new Set(["inline-size", "size"])).has(normalizedValue);
1303
- }
1304
- return true;
1305
- }
1306
- matchesSupportsCondition(condition) {
1307
- const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim();
1308
- if (!normalized) {
1309
- return true;
1310
- }
1311
- if (normalized.toLowerCase().startsWith("not ")) {
1312
- return !this.matchesSupportsCondition(normalized.slice(4));
1313
- }
1314
- const orClauses = this.splitConditionalClauses(normalized, "or");
1315
- if (orClauses.length > 1) {
1316
- return orClauses.some((clause) => this.matchesSupportsCondition(clause));
1317
- }
1318
- const andClauses = this.splitConditionalClauses(normalized, "and");
1319
- if (andClauses.length > 1) {
1320
- return andClauses.every((clause) => this.matchesSupportsCondition(clause));
1404
+ token += char;
1321
1405
  }
1322
- const declarationMatch = normalized.match(/^([a-z-]+)\s*:\s*(.+)$/i);
1323
- if (!declarationMatch) {
1324
- return false;
1406
+ flushToken();
1407
+ if (invalid || chain.length === 0) {
1408
+ return void 0;
1325
1409
  }
1326
- return this.matchesSupportsDeclaration(declarationMatch[1], declarationMatch[2]);
1410
+ return chain.some((part) => Boolean(part.tagName) || Boolean(part.idName) || part.classNames.length > 0 || part.attributes.length > 0 || part.pseudoClasses.length > 0) ? chain : void 0;
1411
+ }).filter((segment) => Array.isArray(segment) && segment.length > 0);
1412
+ parsedSelectorChainCache.set(selector, parsedChains);
1413
+ return parsedChains;
1414
+ }
1415
+
1416
+ // src/client/style/native-resolver.ts
1417
+ var NativeStyleResolver = class {
1418
+ constructor() {
1419
+ this.parsedSelectorChainCache = /* @__PURE__ */ new Map();
1327
1420
  }
1328
- findMatchingContainerTarget(ancestors, name) {
1329
- const normalizedName = typeof name === "string" && name.trim() ? name.trim().toLowerCase() : void 0;
1330
- for (let index = ancestors.length - 1; index >= 0; index--) {
1331
- const ancestor = ancestors[index];
1332
- if (!ancestor?.isContainer || ancestor.containerWidth === void 0) {
1333
- continue;
1334
- }
1335
- if (!normalizedName) {
1336
- return ancestor;
1337
- }
1338
- if ((ancestor.containerNames ?? []).includes(normalizedName)) {
1339
- return ancestor;
1421
+ resolveNativeStyles(target, ancestors = [], options = {}, context) {
1422
+ return this.withNativeTargetNormalizationCache(() => {
1423
+ const normalizedTarget = this.normalizeTarget(target);
1424
+ if (!normalizedTarget.tagName && (!normalizedTarget.classNames || normalizedTarget.classNames.length === 0)) {
1425
+ return {};
1340
1426
  }
1341
- }
1342
- return void 0;
1343
- }
1344
- matchesContainerCondition(condition, containerWidth) {
1345
- const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim().toLowerCase();
1346
- if (!normalized) {
1347
- return true;
1348
- }
1349
- if (normalized.startsWith("not ")) {
1350
- return !this.matchesContainerCondition(normalized.slice(4), containerWidth);
1351
- }
1352
- const orClauses = this.splitConditionalClauses(normalized, "or");
1353
- if (orClauses.length > 1) {
1354
- return orClauses.some((clause) => this.matchesContainerCondition(clause, containerWidth));
1355
- }
1356
- const andClauses = this.splitConditionalClauses(normalized, "and");
1357
- if (andClauses.length > 1) {
1358
- return andClauses.every((clause) => this.matchesContainerCondition(clause, containerWidth));
1359
- }
1360
- if (normalized.startsWith("min-width:")) {
1361
- const minWidth = this.parseMediaLength(normalized.slice("min-width:".length));
1362
- return minWidth !== void 0 && containerWidth >= minWidth;
1363
- }
1364
- if (normalized.startsWith("max-width:")) {
1365
- const maxWidth = this.parseMediaLength(normalized.slice("max-width:".length));
1366
- return maxWidth !== void 0 && containerWidth <= maxWidth;
1367
- }
1368
- return false;
1369
- }
1370
- parseSimpleSelectorToken(token) {
1371
- const trimmed = token.trim();
1372
- if (!trimmed || /[*&]/.test(trimmed)) {
1373
- return void 0;
1374
- }
1375
- let cursor = 0;
1376
- let tagName;
1377
- let idName;
1378
- const classNames = [];
1379
- const attributes = [];
1380
- const pseudoClasses = [];
1381
- const tagMatch = trimmed.slice(cursor).match(/^([_a-zA-Z][-_a-zA-Z0-9]*)/);
1382
- if (tagMatch) {
1383
- tagName = tagMatch[1].toLowerCase();
1384
- cursor += tagMatch[0].length;
1385
- }
1386
- while (cursor < trimmed.length) {
1387
- const char = trimmed[cursor];
1388
- if (char === ".") {
1389
- const classMatch = trimmed.slice(cursor).match(/^\.([_a-zA-Z][-_a-zA-Z0-9]*)/);
1390
- if (!classMatch) {
1391
- return void 0;
1427
+ const normalizedAncestors = ancestors.map((ancestor) => this.normalizeTarget(ancestor));
1428
+ const resolved = {};
1429
+ const applyRules = (rules) => {
1430
+ for (const rule of rules) {
1431
+ const selectorChains = extractSupportedSelectorChains(rule.selector, this.parsedSelectorChainCache);
1432
+ if (selectorChains.length === 0) {
1433
+ continue;
1434
+ }
1435
+ const matches = selectorChains.some((selectorChain) => this.matchesSelectorChain(normalizedTarget, normalizedAncestors, selectorChain));
1436
+ if (!matches) {
1437
+ continue;
1438
+ }
1439
+ for (const [property, value] of Object.entries(rule.styles)) {
1440
+ resolved[property] = typeof value === "string" ? this.resolveVariableReferences(value, context.variables) : value;
1441
+ }
1442
+ }
1443
+ };
1444
+ for (const layerName of getOrderedLayerNames(context.layerOrder, context.layerRules)) {
1445
+ for (const layerRule of context.layerRules) {
1446
+ if (layerRule.name.trim() === layerName) {
1447
+ applyRules(layerRule.rules);
1448
+ }
1392
1449
  }
1393
- classNames.push(classMatch[1]);
1394
- cursor += classMatch[0].length;
1395
- continue;
1396
1450
  }
1397
- if (char === "#") {
1398
- const idMatch = trimmed.slice(cursor).match(/^#([_a-zA-Z][-_a-zA-Z0-9]*)/);
1399
- if (!idMatch || idName) {
1400
- return void 0;
1451
+ applyRules(context.rules);
1452
+ for (const supportsRule of context.supportsRules) {
1453
+ if (matchesSupportsCondition(supportsRule.condition)) {
1454
+ applyRules(supportsRule.rules);
1401
1455
  }
1402
- idName = idMatch[1];
1403
- cursor += idMatch[0].length;
1404
- continue;
1405
1456
  }
1406
- if (char === "[") {
1407
- const endIndex = trimmed.indexOf("]", cursor + 1);
1408
- if (endIndex === -1) {
1409
- return void 0;
1457
+ for (const containerRule of context.containerRules) {
1458
+ const matchingContainer = findMatchingContainerTarget(normalizedAncestors, containerRule.name);
1459
+ if (matchingContainer && this.hasContainerWidth(matchingContainer) && matchesContainerCondition(containerRule.condition, matchingContainer.containerWidth)) {
1460
+ applyRules(containerRule.rules);
1410
1461
  }
1411
- const rawAttribute = trimmed.slice(cursor + 1, endIndex).trim();
1412
- const attrMatch = rawAttribute.match(/^([_a-zA-Z][-_a-zA-Z0-9]*)(?:\s*(=|~=|\^=|\$=|\*=)\s*(?:"([^"]*)"|'([^']*)'|([^\s"']+)))?$/);
1413
- if (!attrMatch) {
1414
- return void 0;
1462
+ }
1463
+ for (const mediaRule of context.mediaRules) {
1464
+ if (matchesMediaRule(mediaRule, options)) {
1465
+ applyRules(mediaRule.rules);
1415
1466
  }
1416
- attributes.push({
1417
- name: attrMatch[1].toLowerCase(),
1418
- operator: attrMatch[2],
1419
- value: attrMatch[3] ?? attrMatch[4] ?? attrMatch[5]
1420
- });
1421
- cursor = endIndex + 1;
1422
- continue;
1423
1467
  }
1424
- if (char === ":") {
1425
- const pseudoToken = this.parsePseudoSelectorToken(trimmed, cursor);
1426
- if (!pseudoToken) {
1427
- return void 0;
1468
+ return resolved;
1469
+ });
1470
+ }
1471
+ resolveClassStyles(classNames, context) {
1472
+ return this.resolveNativeStyles({ classNames }, [], {}, context);
1473
+ }
1474
+ hasContainerWidth(target) {
1475
+ return typeof target.containerWidth === "number" && Number.isFinite(target.containerWidth);
1476
+ }
1477
+ resolveVariableReferences(value, variables) {
1478
+ let resolved = value;
1479
+ for (let index = 0; index < 8; index++) {
1480
+ let replaced = false;
1481
+ resolved = resolved.replace(/var\(\s*(--[\w-]+)\s*(?:,\s*([^\)]+))?\)/g, (match, name, fallback) => {
1482
+ const variableValue = variables[name];
1483
+ if (variableValue !== void 0) {
1484
+ replaced = true;
1485
+ return variableValue;
1428
1486
  }
1429
- pseudoClasses.push(pseudoToken.value);
1430
- cursor = pseudoToken.nextIndex;
1431
- continue;
1487
+ if (fallback !== void 0) {
1488
+ replaced = true;
1489
+ return fallback.trim();
1490
+ }
1491
+ return match;
1492
+ });
1493
+ if (!replaced) {
1494
+ break;
1432
1495
  }
1433
- return void 0;
1434
- }
1435
- if (!tagName && !idName && classNames.length === 0 && attributes.length === 0 && pseudoClasses.length === 0) {
1436
- return void 0;
1437
1496
  }
1438
- return { tagName, idName, classNames, attributes, pseudoClasses };
1497
+ return resolved.replace(/\s*!important\s*$/i, "").trim();
1498
+ }
1499
+ normalizeTargetIdentity(target) {
1500
+ return {
1501
+ tagName: typeof target.tagName === "string" && target.tagName.trim() ? target.tagName.trim().toLowerCase() : void 0,
1502
+ classNames: Array.isArray(target.classNames) ? target.classNames.map((className) => className.trim()).filter(Boolean) : [],
1503
+ attributes: target.attributes ? Object.fromEntries(
1504
+ Object.entries(target.attributes).filter(([, value]) => value !== void 0 && value !== null && value !== false).map(([name, value]) => [name.toLowerCase(), String(value)])
1505
+ ) : {},
1506
+ pseudoStates: Array.isArray(target.pseudoStates) ? [...new Set(target.pseudoStates.map((pseudoState) => pseudoState.trim().toLowerCase()).filter(Boolean))] : [],
1507
+ childIndex: typeof target.childIndex === "number" && Number.isFinite(target.childIndex) ? target.childIndex : void 0,
1508
+ siblingCount: typeof target.siblingCount === "number" && Number.isFinite(target.siblingCount) ? target.siblingCount : void 0,
1509
+ sameTypeIndex: typeof target.sameTypeIndex === "number" && Number.isFinite(target.sameTypeIndex) ? target.sameTypeIndex : void 0,
1510
+ sameTypeCount: typeof target.sameTypeCount === "number" && Number.isFinite(target.sameTypeCount) ? target.sameTypeCount : void 0,
1511
+ containerNames: Array.isArray(target.containerNames) ? [...new Set(target.containerNames.map((containerName) => containerName.trim().toLowerCase()).filter(Boolean))] : [],
1512
+ containerWidth: typeof target.containerWidth === "number" && Number.isFinite(target.containerWidth) ? target.containerWidth : void 0,
1513
+ isContainer: target.isContainer === true,
1514
+ isScopeReference: target.isScopeReference === true
1515
+ };
1439
1516
  }
1440
- extractSupportedSelectorChains(selector) {
1441
- const cached = this.parsedSelectorChainCache.get(selector);
1517
+ normalizeTarget(target) {
1518
+ const cached = this.nativeTargetNormalizationCache?.get(target);
1442
1519
  if (cached) {
1443
1520
  return cached;
1444
1521
  }
1445
- const parsedChains = this.splitSelectorList(selector).map((segment) => segment.trim()).map((segment) => {
1446
- const chain = [];
1447
- let token = "";
1448
- let combinator = "descendant";
1449
- let invalid = false;
1450
- let attributeDepth = 0;
1451
- let parenthesisDepth = 0;
1452
- let quoted;
1453
- const flushToken = () => {
1454
- const trimmedToken = token.trim();
1455
- token = "";
1456
- if (!trimmedToken || invalid) {
1457
- return;
1458
- }
1459
- const parsed = this.parseSimpleSelectorToken(trimmedToken);
1460
- if (!parsed) {
1461
- invalid = true;
1462
- return;
1463
- }
1464
- if (chain.length > 0) {
1465
- parsed.combinator = combinator;
1466
- }
1467
- chain.push(parsed);
1468
- combinator = "descendant";
1469
- };
1470
- for (let index = 0; index < segment.length; index++) {
1471
- const char = segment[index];
1472
- if (quoted) {
1473
- token += char;
1474
- if (char === quoted && segment[index - 1] !== "\\") {
1475
- quoted = void 0;
1476
- }
1477
- continue;
1478
- }
1479
- if (char === '"' || char === "'") {
1480
- quoted = char;
1481
- token += char;
1482
- continue;
1483
- }
1484
- if (char === "[") {
1485
- attributeDepth += 1;
1486
- token += char;
1487
- continue;
1488
- }
1489
- if (char === "]") {
1490
- if (attributeDepth > 0) {
1491
- attributeDepth -= 1;
1492
- }
1493
- token += char;
1494
- continue;
1495
- }
1496
- if (attributeDepth === 0 && char === "(") {
1497
- parenthesisDepth += 1;
1498
- token += char;
1499
- continue;
1500
- }
1501
- if (attributeDepth === 0 && char === ")" && parenthesisDepth > 0) {
1502
- parenthesisDepth -= 1;
1503
- token += char;
1504
- continue;
1505
- }
1506
- if (attributeDepth === 0 && parenthesisDepth === 0 && (char === ">" || char === "+" || char === "~")) {
1507
- flushToken();
1508
- if (invalid) break;
1509
- combinator = char === ">" ? "child" : char === "+" ? "adjacent-sibling" : "general-sibling";
1510
- continue;
1511
- }
1512
- if (attributeDepth === 0 && parenthesisDepth === 0 && /\s/.test(char)) {
1513
- flushToken();
1514
- if (invalid) break;
1515
- continue;
1516
- }
1517
- token += char;
1518
- }
1519
- flushToken();
1520
- if (invalid || chain.length === 0) {
1521
- return void 0;
1522
- }
1523
- return chain.some((part) => Boolean(part.tagName) || Boolean(part.idName) || part.classNames.length > 0 || part.attributes.length > 0 || part.pseudoClasses.length > 0) ? chain : void 0;
1524
- }).filter((segment) => Array.isArray(segment) && segment.length > 0);
1525
- this.parsedSelectorChainCache.set(selector, parsedChains);
1526
- return parsedChains;
1522
+ const normalized = {
1523
+ ...this.normalizeTargetIdentity(target),
1524
+ previousSiblings: [],
1525
+ nextSiblings: [],
1526
+ children: []
1527
+ };
1528
+ this.nativeTargetNormalizationCache?.set(target, normalized);
1529
+ normalized.previousSiblings = Array.isArray(target.previousSiblings) ? target.previousSiblings.map((sibling) => this.normalizeTarget(sibling)) : [];
1530
+ normalized.nextSiblings = Array.isArray(target.nextSiblings) ? target.nextSiblings.map((sibling) => this.normalizeTarget(sibling)) : [];
1531
+ normalized.children = Array.isArray(target.children) ? target.children.map((child) => this.normalizeTarget(child)) : [];
1532
+ return normalized;
1533
+ }
1534
+ withNativeTargetNormalizationCache(callback) {
1535
+ const previousCache = this.nativeTargetNormalizationCache;
1536
+ this.nativeTargetNormalizationCache = /* @__PURE__ */ new WeakMap();
1537
+ try {
1538
+ return callback();
1539
+ } finally {
1540
+ this.nativeTargetNormalizationCache = previousCache;
1541
+ }
1527
1542
  }
1528
1543
  matchesAttributeSelector(targetValue, selector) {
1529
1544
  if (selector.operator === void 0) {
@@ -1610,13 +1625,13 @@ var CreateStyle = class {
1610
1625
  if (!pseudoArgument) {
1611
1626
  return false;
1612
1627
  }
1613
- const selectorArguments = this.splitSelectorList(pseudoArgument);
1628
+ const selectorArguments = splitSelectorList(pseudoArgument);
1614
1629
  if (selectorArguments.length === 0) {
1615
1630
  return false;
1616
1631
  }
1617
1632
  const parsedSelectors = [];
1618
1633
  for (const selectorArgument of selectorArguments) {
1619
- const parsedSelector = this.parseSimpleSelectorToken(selectorArgument);
1634
+ const parsedSelector = parseSimpleSelectorToken(selectorArgument);
1620
1635
  if (!parsedSelector) {
1621
1636
  return false;
1622
1637
  }
@@ -1665,7 +1680,7 @@ var CreateStyle = class {
1665
1680
  return Number.isInteger(n) && n >= 0;
1666
1681
  }
1667
1682
  matchesHasPseudoClass(target, pseudoArgument) {
1668
- const selectorArguments = this.splitSelectorList(pseudoArgument);
1683
+ const selectorArguments = splitSelectorList(pseudoArgument);
1669
1684
  if (selectorArguments.length === 0) {
1670
1685
  return false;
1671
1686
  }
@@ -1680,7 +1695,7 @@ var CreateStyle = class {
1680
1695
  if (!scopeRelativeSelector) {
1681
1696
  return false;
1682
1697
  }
1683
- const selectorChains = this.extractSupportedSelectorChains(scopeRelativeSelector);
1698
+ const selectorChains = extractSupportedSelectorChains(scopeRelativeSelector, this.parsedSelectorChainCache);
1684
1699
  if (selectorChains.length === 0) {
1685
1700
  return false;
1686
1701
  }
@@ -1787,289 +1802,404 @@ var CreateStyle = class {
1787
1802
  }
1788
1803
  }
1789
1804
  }
1790
- parseMediaLength(value) {
1791
- const match = value.trim().match(/^(-?\d+(?:\.\d+)?)(px|rem|em)?$/i);
1792
- if (!match) {
1793
- return void 0;
1794
- }
1795
- const numericValue = Number(match[1]);
1796
- const unit = (match[2] ?? "px").toLowerCase();
1797
- if (unit === "rem" || unit === "em") {
1798
- return numericValue * 16;
1799
- }
1800
- return numericValue;
1805
+ };
1806
+
1807
+ // src/client/style/renderer.ts
1808
+ function toKebabCase(str) {
1809
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
1810
+ }
1811
+ function stylesToString(styles2, indent = " ") {
1812
+ return Object.entries(styles2).map(([prop, value]) => {
1813
+ const cssValue = typeof value === "object" && value !== null && "name" in value ? `var(${value.name})` : value;
1814
+ return `${indent}${toKebabCase(prop)}: ${cssValue};`;
1815
+ }).join("\n");
1816
+ }
1817
+ function renderRule(rule, indent = "") {
1818
+ let css = `${indent}${rule.selector} {
1819
+ ${stylesToString(rule.styles, indent + " ")}
1820
+ `;
1821
+ if (rule.nested && rule.nested.length > 0) {
1822
+ for (const nestedRule of rule.nested) {
1823
+ const nestedSelector = nestedRule.selector.startsWith("&") ? nestedRule.selector.replace(/&/g, rule.selector) : `${rule.selector} ${nestedRule.selector}`;
1824
+ css += `
1825
+ ${indent}${nestedSelector} {
1826
+ ${stylesToString(nestedRule.styles, indent + " ")}
1827
+ ${indent}}
1828
+ `;
1829
+ }
1830
+ }
1831
+ css += `${indent}}`;
1832
+ return css;
1833
+ }
1834
+ function renderRulesWithIndent(rules, indent = " ") {
1835
+ return rules.map((rule) => renderRule(rule, indent)).join("\n");
1836
+ }
1837
+ function renderMediaRule(media) {
1838
+ const condition = media.type && media.condition ? `${media.type} and (${media.condition})` : media.type ? media.type : `(${media.condition})`;
1839
+ return `@media ${condition} {
1840
+ ${renderRulesWithIndent(media.rules)}
1841
+ }`;
1842
+ }
1843
+ function renderKeyframes(kf) {
1844
+ let css = `@keyframes ${kf.name} {
1845
+ `;
1846
+ for (const step of kf.steps) {
1847
+ css += ` ${step.step} {
1848
+ ${stylesToString(step.styles, " ")}
1849
+ }
1850
+ `;
1851
+ }
1852
+ css += "}";
1853
+ return css;
1854
+ }
1855
+ function renderFontFace(ff) {
1856
+ let css = "@font-face {\n";
1857
+ css += ` font-family: "${ff.fontFamily}";
1858
+ `;
1859
+ css += ` src: ${ff.src};
1860
+ `;
1861
+ if (ff.fontWeight) css += ` font-weight: ${ff.fontWeight};
1862
+ `;
1863
+ if (ff.fontStyle) css += ` font-style: ${ff.fontStyle};
1864
+ `;
1865
+ if (ff.fontDisplay) css += ` font-display: ${ff.fontDisplay};
1866
+ `;
1867
+ if (ff.unicodeRange) css += ` unicode-range: ${ff.unicodeRange};
1868
+ `;
1869
+ css += "}";
1870
+ return css;
1871
+ }
1872
+ function renderContainerRule(container2) {
1873
+ const nameStr = container2.name ? `${container2.name} ` : "";
1874
+ return `@container ${nameStr}(${container2.condition}) {
1875
+ ${renderRulesWithIndent(container2.rules)}
1876
+ }`;
1877
+ }
1878
+ function renderSupportsRule(supports) {
1879
+ return `@supports (${supports.condition}) {
1880
+ ${renderRulesWithIndent(supports.rules)}
1881
+ }`;
1882
+ }
1883
+ function renderLayerRule(layer2) {
1884
+ return `@layer ${layer2.name} {
1885
+ ${renderRulesWithIndent(layer2.rules)}
1886
+ }`;
1887
+ }
1888
+ function renderStyleSheet(context, ...additionalRules) {
1889
+ const parts = [];
1890
+ if (context.imports.length > 0) {
1891
+ parts.push(context.imports.join("\n"));
1892
+ }
1893
+ if (context.layerOrder.length > 0) {
1894
+ parts.push(`@layer ${context.layerOrder.join(", ")};`);
1895
+ }
1896
+ if (context.variables.length > 0) {
1897
+ const varDeclarations = context.variables.map((variable) => ` ${variable.name}: ${variable.value};`).join("\n");
1898
+ parts.push(`:root {
1899
+ ${varDeclarations}
1900
+ }`);
1901
+ }
1902
+ for (const ff of context.fontFaces) {
1903
+ parts.push(renderFontFace(ff));
1904
+ }
1905
+ for (const kf of context.keyframes) {
1906
+ parts.push(renderKeyframes(kf));
1907
+ }
1908
+ const allRules = [...context.rules];
1909
+ const allMediaRules = [...context.mediaRules];
1910
+ const allKeyframes = [];
1911
+ const allContainerRules = [...context.containerRules];
1912
+ const allSupportsRules = [...context.supportsRules];
1913
+ const allLayerRules = [...context.layerRules];
1914
+ for (const item of additionalRules) {
1915
+ if (!item) {
1916
+ continue;
1917
+ }
1918
+ if (Array.isArray(item)) {
1919
+ allRules.push(...item);
1920
+ } else if ("condition" in item && "rules" in item && !("name" in item && "steps" in item)) {
1921
+ if ("type" in item) {
1922
+ allMediaRules.push(item);
1923
+ } else if ("name" in item && typeof item.name === "string") {
1924
+ allContainerRules.push(item);
1925
+ } else {
1926
+ allSupportsRules.push(item);
1927
+ }
1928
+ } else if ("name" in item && "steps" in item) {
1929
+ allKeyframes.push(item);
1930
+ } else if ("name" in item && "rules" in item) {
1931
+ allLayerRules.push(item);
1932
+ } else {
1933
+ allRules.push(item);
1934
+ }
1935
+ }
1936
+ for (const kf of allKeyframes) {
1937
+ parts.push(renderKeyframes(kf));
1938
+ }
1939
+ for (const layer2 of allLayerRules) {
1940
+ parts.push(renderLayerRule(layer2));
1941
+ }
1942
+ for (const rule of allRules) {
1943
+ parts.push(renderRule(rule));
1944
+ }
1945
+ for (const supports of allSupportsRules) {
1946
+ parts.push(renderSupportsRule(supports));
1947
+ }
1948
+ for (const container2 of allContainerRules) {
1949
+ parts.push(renderContainerRule(container2));
1950
+ }
1951
+ for (const media of allMediaRules) {
1952
+ parts.push(renderMediaRule(media));
1953
+ }
1954
+ return parts.join("\n\n");
1955
+ }
1956
+
1957
+ // src/client/style/store.ts
1958
+ var ELIT_SHARED_STYLE_STORE_KEY = "__elitSharedStyleStore__";
1959
+ function createStyleStore() {
1960
+ return {
1961
+ variables: [],
1962
+ rules: [],
1963
+ mediaRules: [],
1964
+ keyframes: [],
1965
+ fontFaces: [],
1966
+ imports: [],
1967
+ containerRules: [],
1968
+ supportsRules: [],
1969
+ layerRules: [],
1970
+ layerOrder: []
1971
+ };
1972
+ }
1973
+ function getSharedStyleStore() {
1974
+ const globalScope = globalThis;
1975
+ if (!globalScope[ELIT_SHARED_STYLE_STORE_KEY]) {
1976
+ globalScope[ELIT_SHARED_STYLE_STORE_KEY] = createStyleStore();
1977
+ }
1978
+ return globalScope[ELIT_SHARED_STYLE_STORE_KEY];
1979
+ }
1980
+
1981
+ // src/client/style/index.ts
1982
+ var CreateStyle = class {
1983
+ constructor(store) {
1984
+ this.variables = [];
1985
+ this.rules = [];
1986
+ this.mediaRules = [];
1987
+ this.keyframes = [];
1988
+ this.fontFaces = [];
1989
+ this.imports = [];
1990
+ this.containerRules = [];
1991
+ this.supportsRules = [];
1992
+ this.layerRules = [];
1993
+ this._layerOrder = [];
1994
+ this.nativeStyleResolver = new NativeStyleResolver();
1995
+ if (!store) {
1996
+ return;
1997
+ }
1998
+ this.variables = store.variables;
1999
+ this.rules = store.rules;
2000
+ this.mediaRules = store.mediaRules;
2001
+ this.keyframes = store.keyframes;
2002
+ this.fontFaces = store.fontFaces;
2003
+ this.imports = store.imports;
2004
+ this.containerRules = store.containerRules;
2005
+ this.supportsRules = store.supportsRules;
2006
+ this.layerRules = store.layerRules;
2007
+ this._layerOrder = store.layerOrder;
2008
+ }
2009
+ addVar(name, value) {
2010
+ const cssVar = {
2011
+ name: name.startsWith("--") ? name : `--${name}`,
2012
+ value,
2013
+ toString() {
2014
+ return `var(${this.name})`;
2015
+ }
2016
+ };
2017
+ this.variables.push(cssVar);
2018
+ return cssVar;
2019
+ }
2020
+ var(variable, fallback) {
2021
+ const varName = typeof variable === "string" ? variable.startsWith("--") ? variable : `--${variable}` : variable.name;
2022
+ return fallback ? `var(${varName}, ${fallback})` : `var(${varName})`;
2023
+ }
2024
+ addTag(tag, styles2) {
2025
+ const rule = { selector: tag, styles: styles2, type: "tag" };
2026
+ this.rules.push(rule);
2027
+ return rule;
2028
+ }
2029
+ addClass(name, styles2) {
2030
+ const selector = name.startsWith(".") ? name : `.${name}`;
2031
+ const rule = { selector, styles: styles2, type: "class" };
2032
+ this.rules.push(rule);
2033
+ return rule;
2034
+ }
2035
+ addId(name, styles2) {
2036
+ const selector = name.startsWith("#") ? name : `#${name}`;
2037
+ const rule = { selector, styles: styles2, type: "id" };
2038
+ this.rules.push(rule);
2039
+ return rule;
2040
+ }
2041
+ addPseudoClass(pseudo, styles2, baseSelector) {
2042
+ const pseudoClass = pseudo.startsWith(":") ? pseudo : `:${pseudo}`;
2043
+ const selector = baseSelector ? `${baseSelector}${pseudoClass}` : pseudoClass;
2044
+ const rule = { selector, styles: styles2, type: "pseudo-class" };
2045
+ this.rules.push(rule);
2046
+ return rule;
2047
+ }
2048
+ addPseudoElement(pseudo, styles2, baseSelector) {
2049
+ const pseudoElement = pseudo.startsWith("::") ? pseudo : `::${pseudo}`;
2050
+ const selector = baseSelector ? `${baseSelector}${pseudoElement}` : pseudoElement;
2051
+ const rule = { selector, styles: styles2, type: "pseudo-element" };
2052
+ this.rules.push(rule);
2053
+ return rule;
2054
+ }
2055
+ addAttribute(attr, styles2, baseSelector) {
2056
+ const attrSelector = attr.startsWith("[") ? attr : `[${attr}]`;
2057
+ const selector = baseSelector ? `${baseSelector}${attrSelector}` : attrSelector;
2058
+ const rule = { selector, styles: styles2, type: "attribute" };
2059
+ this.rules.push(rule);
2060
+ return rule;
2061
+ }
2062
+ attrEquals(attr, value, styles2, baseSelector) {
2063
+ return this.addAttribute(`${attr}="${value}"`, styles2, baseSelector);
2064
+ }
2065
+ attrContainsWord(attr, value, styles2, baseSelector) {
2066
+ return this.addAttribute(`${attr}~="${value}"`, styles2, baseSelector);
2067
+ }
2068
+ attrStartsWith(attr, value, styles2, baseSelector) {
2069
+ return this.addAttribute(`${attr}^="${value}"`, styles2, baseSelector);
2070
+ }
2071
+ attrEndsWith(attr, value, styles2, baseSelector) {
2072
+ return this.addAttribute(`${attr}$="${value}"`, styles2, baseSelector);
1801
2073
  }
1802
- matchesMediaCondition(condition, options) {
1803
- const normalized = condition.trim().replace(/^\(+|\)+$/g, "").trim().toLowerCase();
1804
- if (!normalized) {
1805
- return true;
1806
- }
1807
- if (normalized.startsWith("min-width:")) {
1808
- const minWidth = this.parseMediaLength(normalized.slice("min-width:".length));
1809
- return minWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth >= minWidth;
1810
- }
1811
- if (normalized.startsWith("max-width:")) {
1812
- const maxWidth = this.parseMediaLength(normalized.slice("max-width:".length));
1813
- return maxWidth !== void 0 && options.viewportWidth !== void 0 && options.viewportWidth <= maxWidth;
1814
- }
1815
- if (normalized === "prefers-color-scheme: dark") {
1816
- return options.colorScheme === "dark";
1817
- }
1818
- if (normalized === "prefers-color-scheme: light") {
1819
- return (options.colorScheme ?? "light") === "light";
1820
- }
1821
- if (normalized === "prefers-reduced-motion: reduce") {
1822
- return options.reducedMotion === true;
1823
- }
1824
- return false;
2074
+ attrContains(attr, value, styles2, baseSelector) {
2075
+ return this.addAttribute(`${attr}*="${value}"`, styles2, baseSelector);
1825
2076
  }
1826
- matchesMediaRule(rule, options) {
1827
- const mediaType = options.mediaType ?? "screen";
1828
- if (rule.type && rule.type !== mediaType && rule.type !== "all") {
1829
- return false;
1830
- }
1831
- if (!rule.condition.trim()) {
1832
- return true;
1833
- }
1834
- return rule.condition.split(/\band\b/i).map((part) => part.trim()).filter(Boolean).every((part) => this.matchesMediaCondition(part, options));
2077
+ descendant(ancestor, descendant2, styles2) {
2078
+ return this.createAndAddRule(`${ancestor} ${descendant2}`, styles2);
1835
2079
  }
1836
- getOrderedLayerNames() {
1837
- const orderedLayerNames = [];
1838
- for (const layerName of this._layerOrder) {
1839
- const normalizedName = layerName.trim();
1840
- if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
1841
- orderedLayerNames.push(normalizedName);
1842
- }
1843
- }
1844
- for (const layerRule of this.layerRules) {
1845
- const normalizedName = layerRule.name.trim();
1846
- if (normalizedName && !orderedLayerNames.includes(normalizedName)) {
1847
- orderedLayerNames.push(normalizedName);
1848
- }
1849
- }
1850
- return orderedLayerNames;
2080
+ child(parent, childSel, styles2) {
2081
+ return this.createAndAddRule(`${parent} > ${childSel}`, styles2);
1851
2082
  }
1852
- resolveNativeStyles(target, ancestors = [], options = {}) {
1853
- return this.withNativeTargetNormalizationCache(() => {
1854
- const normalizedTarget = this.normalizeTarget(target);
1855
- if (!normalizedTarget.tagName && (!normalizedTarget.classNames || normalizedTarget.classNames.length === 0)) {
1856
- return {};
1857
- }
1858
- const normalizedAncestors = ancestors.map((ancestor) => this.normalizeTarget(ancestor));
1859
- const variables = this.getVariables();
1860
- const resolved = {};
1861
- const applyRules = (rules) => {
1862
- for (const rule of rules) {
1863
- const selectorChains = this.extractSupportedSelectorChains(rule.selector);
1864
- if (selectorChains.length === 0) {
1865
- continue;
1866
- }
1867
- const matches = selectorChains.some((selectorChain) => this.matchesSelectorChain(normalizedTarget, normalizedAncestors, selectorChain));
1868
- if (!matches) {
1869
- continue;
1870
- }
1871
- for (const [property, value] of Object.entries(rule.styles)) {
1872
- resolved[property] = typeof value === "string" ? this.resolveVariableReferences(value, variables) : value;
1873
- }
1874
- }
1875
- };
1876
- for (const layerName of this.getOrderedLayerNames()) {
1877
- for (const layerRule of this.layerRules) {
1878
- if (layerRule.name.trim() === layerName) {
1879
- applyRules(layerRule.rules);
1880
- }
1881
- }
1882
- }
1883
- applyRules(this.rules);
1884
- for (const supportsRule of this.supportsRules) {
1885
- if (this.matchesSupportsCondition(supportsRule.condition)) {
1886
- applyRules(supportsRule.rules);
1887
- }
1888
- }
1889
- for (const containerRule of this.containerRules) {
1890
- const matchingContainer = this.findMatchingContainerTarget(normalizedAncestors, containerRule.name);
1891
- if (matchingContainer && this.matchesContainerCondition(containerRule.condition, matchingContainer.containerWidth)) {
1892
- applyRules(containerRule.rules);
1893
- }
1894
- }
1895
- for (const mediaRule of this.mediaRules) {
1896
- if (this.matchesMediaRule(mediaRule, options)) {
1897
- applyRules(mediaRule.rules);
1898
- }
1899
- }
1900
- return resolved;
1901
- });
2083
+ adjacentSibling(element, sibling, styles2) {
2084
+ return this.createAndAddRule(`${element} + ${sibling}`, styles2);
1902
2085
  }
1903
- resolveClassStyles(classNames) {
1904
- return this.resolveNativeStyles({ classNames });
2086
+ generalSibling(element, sibling, styles2) {
2087
+ return this.createAndAddRule(`${element} ~ ${sibling}`, styles2);
1905
2088
  }
1906
- // Utility Methods
1907
- toKebabCase(str) {
1908
- return str.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
2089
+ multiple(selectors, styles2) {
2090
+ return this.createAndAddRule(selectors.join(", "), styles2);
1909
2091
  }
1910
- // Helper: Create and add rule (eliminates duplication in combinator selectors)
1911
- createAndAddRule(selector, styles2, type = "custom") {
1912
- const rule = { selector, styles: styles2, type };
1913
- this.rules.push(rule);
1914
- return rule;
2092
+ addName(name, styles2) {
2093
+ const selector = name.startsWith("--") ? `&${name}` : `&--${name}`;
2094
+ return { selector, styles: styles2, type: "name" };
1915
2095
  }
1916
- // Helper: Convert rules object to CSSRule array (eliminates duplication in media/container/supports/layer)
1917
- rulesToCSSRules(rules) {
1918
- return Object.entries(rules).map(([selector, styles2]) => ({
1919
- selector,
1920
- styles: styles2,
1921
- type: "custom"
2096
+ nesting(parentRule, ...childRules) {
2097
+ parentRule.nested = childRules;
2098
+ return parentRule;
2099
+ }
2100
+ keyframe(name, steps) {
2101
+ const keyframeSteps = Object.entries(steps).map(([step, styles2]) => ({
2102
+ step: step === "from" ? "from" : step === "to" ? "to" : `${step}%`,
2103
+ styles: styles2
1922
2104
  }));
2105
+ const kf = { name, steps: keyframeSteps };
2106
+ this.keyframes.push(kf);
2107
+ return kf;
1923
2108
  }
1924
- // Helper: Render rules with indentation (eliminates duplication in render methods)
1925
- renderRulesWithIndent(rules, indent = " ") {
1926
- return rules.map((rule) => this.renderRule(rule, indent)).join("\n");
2109
+ keyframeFromTo(name, from, to) {
2110
+ return this.keyframe(name, { from, to });
1927
2111
  }
1928
- stylesToString(styles2, indent = " ") {
1929
- return Object.entries(styles2).map(([prop, value]) => {
1930
- const cssValue = typeof value === "object" && value !== null && "name" in value ? `var(${value.name})` : value;
1931
- return `${indent}${this.toKebabCase(prop)}: ${cssValue};`;
1932
- }).join("\n");
2112
+ fontFace(options) {
2113
+ this.fontFaces.push(options);
2114
+ return options;
1933
2115
  }
1934
- renderRule(rule, indent = "") {
1935
- let css = `${indent}${rule.selector} {
1936
- ${this.stylesToString(rule.styles, indent + " ")}
1937
- `;
1938
- if (rule.nested && rule.nested.length > 0) {
1939
- for (const nestedRule of rule.nested) {
1940
- const nestedSelector = nestedRule.selector.startsWith("&") ? nestedRule.selector.replace(/&/g, rule.selector) : `${rule.selector} ${nestedRule.selector}`;
1941
- css += `
1942
- ${indent}${nestedSelector} {
1943
- ${this.stylesToString(nestedRule.styles, indent + " ")}
1944
- ${indent}}
1945
- `;
1946
- }
1947
- }
1948
- css += `${indent}}`;
1949
- return css;
2116
+ import(url, mediaQuery) {
2117
+ const importRule = mediaQuery ? `@import url("${url}") ${mediaQuery};` : `@import url("${url}");`;
2118
+ this.imports.push(importRule);
2119
+ return importRule;
1950
2120
  }
1951
- renderMediaRule(media) {
1952
- const condition = media.type && media.condition ? `${media.type} and (${media.condition})` : media.type ? media.type : `(${media.condition})`;
1953
- return `@media ${condition} {
1954
- ${this.renderRulesWithIndent(media.rules)}
1955
- }`;
2121
+ media(type, condition, rules) {
2122
+ const mediaRule = { type, condition, rules: this.rulesToCSSRules(rules) };
2123
+ this.mediaRules.push(mediaRule);
2124
+ return mediaRule;
1956
2125
  }
1957
- renderKeyframes(kf) {
1958
- let css = `@keyframes ${kf.name} {
1959
- `;
1960
- for (const step of kf.steps) {
1961
- css += ` ${step.step} {
1962
- ${this.stylesToString(step.styles, " ")}
1963
- }
1964
- `;
1965
- }
1966
- css += "}";
1967
- return css;
2126
+ mediaScreen(condition, rules) {
2127
+ return this.media("screen", condition, rules);
1968
2128
  }
1969
- renderFontFace(ff) {
1970
- let css = "@font-face {\n";
1971
- css += ` font-family: "${ff.fontFamily}";
1972
- `;
1973
- css += ` src: ${ff.src};
1974
- `;
1975
- if (ff.fontWeight) css += ` font-weight: ${ff.fontWeight};
1976
- `;
1977
- if (ff.fontStyle) css += ` font-style: ${ff.fontStyle};
1978
- `;
1979
- if (ff.fontDisplay) css += ` font-display: ${ff.fontDisplay};
1980
- `;
1981
- if (ff.unicodeRange) css += ` unicode-range: ${ff.unicodeRange};
1982
- `;
1983
- css += "}";
1984
- return css;
2129
+ mediaPrint(rules) {
2130
+ return this.media("print", "", rules);
1985
2131
  }
1986
- renderContainerRule(container2) {
1987
- const nameStr = container2.name ? `${container2.name} ` : "";
1988
- return `@container ${nameStr}(${container2.condition}) {
1989
- ${this.renderRulesWithIndent(container2.rules)}
1990
- }`;
2132
+ mediaMinWidth(minWidth, rules) {
2133
+ return this.media("screen", `min-width: ${minWidth}`, rules);
1991
2134
  }
1992
- renderSupportsRule(supports) {
1993
- return `@supports (${supports.condition}) {
1994
- ${this.renderRulesWithIndent(supports.rules)}
1995
- }`;
2135
+ mediaMaxWidth(maxWidth, rules) {
2136
+ return this.media("screen", `max-width: ${maxWidth}`, rules);
1996
2137
  }
1997
- renderLayerRule(layer2) {
1998
- return `@layer ${layer2.name} {
1999
- ${this.renderRulesWithIndent(layer2.rules)}
2000
- }`;
2138
+ mediaDark(rules) {
2139
+ const mediaRule = { type: "", condition: "prefers-color-scheme: dark", rules: this.rulesToCSSRules(rules) };
2140
+ this.mediaRules.push(mediaRule);
2141
+ return mediaRule;
2142
+ }
2143
+ mediaLight(rules) {
2144
+ const mediaRule = { type: "", condition: "prefers-color-scheme: light", rules: this.rulesToCSSRules(rules) };
2145
+ this.mediaRules.push(mediaRule);
2146
+ return mediaRule;
2147
+ }
2148
+ mediaReducedMotion(rules) {
2149
+ const mediaRule = { type: "", condition: "prefers-reduced-motion: reduce", rules: this.rulesToCSSRules(rules) };
2150
+ this.mediaRules.push(mediaRule);
2151
+ return mediaRule;
2152
+ }
2153
+ container(condition, rules, name) {
2154
+ const containerRule = { name, condition, rules: this.rulesToCSSRules(rules) };
2155
+ this.containerRules.push(containerRule);
2156
+ return containerRule;
2157
+ }
2158
+ addContainer(name, styles2) {
2159
+ const containerStyles = { ...styles2, containerName: name };
2160
+ return this.addClass(name, containerStyles);
2161
+ }
2162
+ supports(condition, rules) {
2163
+ const supportsRule = { condition, rules: this.rulesToCSSRules(rules) };
2164
+ this.supportsRules.push(supportsRule);
2165
+ return supportsRule;
2166
+ }
2167
+ layerOrder(...layers) {
2168
+ this._layerOrder = layers;
2169
+ }
2170
+ layer(name, rules) {
2171
+ const layerRule = { name, rules: this.rulesToCSSRules(rules) };
2172
+ this.layerRules.push(layerRule);
2173
+ return layerRule;
2174
+ }
2175
+ add(rules) {
2176
+ return Object.entries(rules).map(([selector, styles2]) => {
2177
+ const rule = { selector, styles: styles2, type: "custom" };
2178
+ this.rules.push(rule);
2179
+ return rule;
2180
+ });
2181
+ }
2182
+ important(value) {
2183
+ return `${value} !important`;
2184
+ }
2185
+ getVariables() {
2186
+ return Object.fromEntries(this.variables.map((variable) => [variable.name, variable.value]));
2187
+ }
2188
+ resolveNativeStyles(target, ancestors = [], options = {}) {
2189
+ return this.nativeStyleResolver.resolveNativeStyles(target, ancestors, options, this.getResolverContext());
2190
+ }
2191
+ resolveClassStyles(classNames) {
2192
+ return this.nativeStyleResolver.resolveClassStyles(classNames, this.getResolverContext());
2001
2193
  }
2002
- // Render Output
2003
2194
  render(...additionalRules) {
2004
- const parts = [];
2005
- if (this.imports.length > 0) {
2006
- parts.push(this.imports.join("\n"));
2007
- }
2008
- if (this._layerOrder.length > 0) {
2009
- parts.push(`@layer ${this._layerOrder.join(", ")};`);
2010
- }
2011
- if (this.variables.length > 0) {
2012
- const varDeclarations = this.variables.map((v) => ` ${v.name}: ${v.value};`).join("\n");
2013
- parts.push(`:root {
2014
- ${varDeclarations}
2015
- }`);
2016
- }
2017
- for (const ff of this.fontFaces) {
2018
- parts.push(this.renderFontFace(ff));
2019
- }
2020
- for (const kf of this.keyframes) {
2021
- parts.push(this.renderKeyframes(kf));
2022
- }
2023
- const allRules = [...this.rules];
2024
- const allMediaRules = [...this.mediaRules];
2025
- const allKeyframes = [];
2026
- const allContainerRules = [...this.containerRules];
2027
- const allSupportsRules = [...this.supportsRules];
2028
- const allLayerRules = [...this.layerRules];
2029
- for (const item of additionalRules) {
2030
- if (!item) continue;
2031
- if (Array.isArray(item)) {
2032
- allRules.push(...item);
2033
- } else if ("condition" in item && "rules" in item && !("name" in item && "steps" in item)) {
2034
- if ("type" in item) {
2035
- allMediaRules.push(item);
2036
- } else if ("name" in item && typeof item.name === "string") {
2037
- allContainerRules.push(item);
2038
- } else {
2039
- allSupportsRules.push(item);
2040
- }
2041
- } else if ("name" in item && "steps" in item) {
2042
- allKeyframes.push(item);
2043
- } else if ("name" in item && "rules" in item) {
2044
- allLayerRules.push(item);
2045
- } else {
2046
- allRules.push(item);
2047
- }
2048
- }
2049
- for (const kf of allKeyframes) {
2050
- parts.push(this.renderKeyframes(kf));
2051
- }
2052
- for (const layer2 of allLayerRules) {
2053
- parts.push(this.renderLayerRule(layer2));
2054
- }
2055
- for (const rule of allRules) {
2056
- parts.push(this.renderRule(rule));
2057
- }
2058
- for (const supports of allSupportsRules) {
2059
- parts.push(this.renderSupportsRule(supports));
2060
- }
2061
- for (const container2 of allContainerRules) {
2062
- parts.push(this.renderContainerRule(container2));
2063
- }
2064
- for (const media of allMediaRules) {
2065
- parts.push(this.renderMediaRule(media));
2066
- }
2067
- return parts.join("\n\n");
2195
+ return renderStyleSheet(this.getRenderContext(), ...additionalRules);
2068
2196
  }
2069
2197
  inject(styleId) {
2070
2198
  const css = this.render();
2071
2199
  const style = document.createElement("style");
2072
- if (styleId) style.id = styleId;
2200
+ if (styleId) {
2201
+ style.id = styleId;
2202
+ }
2073
2203
  style.textContent = css;
2074
2204
  document.head.appendChild(style);
2075
2205
  return style;
@@ -2086,6 +2216,43 @@ ${varDeclarations}
2086
2216
  this.layerRules.length = 0;
2087
2217
  this._layerOrder.length = 0;
2088
2218
  }
2219
+ getResolverContext() {
2220
+ return {
2221
+ variables: this.getVariables(),
2222
+ rules: this.rules,
2223
+ mediaRules: this.mediaRules,
2224
+ containerRules: this.containerRules,
2225
+ supportsRules: this.supportsRules,
2226
+ layerRules: this.layerRules,
2227
+ layerOrder: this._layerOrder
2228
+ };
2229
+ }
2230
+ getRenderContext() {
2231
+ return {
2232
+ imports: this.imports,
2233
+ layerOrder: this._layerOrder,
2234
+ variables: this.variables,
2235
+ fontFaces: this.fontFaces,
2236
+ keyframes: this.keyframes,
2237
+ rules: this.rules,
2238
+ mediaRules: this.mediaRules,
2239
+ containerRules: this.containerRules,
2240
+ supportsRules: this.supportsRules,
2241
+ layerRules: this.layerRules
2242
+ };
2243
+ }
2244
+ createAndAddRule(selector, styles2, type = "custom") {
2245
+ const rule = { selector, styles: styles2, type };
2246
+ this.rules.push(rule);
2247
+ return rule;
2248
+ }
2249
+ rulesToCSSRules(rules) {
2250
+ return Object.entries(rules).map(([selector, styles2]) => ({
2251
+ selector,
2252
+ styles: styles2,
2253
+ type: "custom"
2254
+ }));
2255
+ }
2089
2256
  };
2090
2257
  var styles = new CreateStyle(getSharedStyleStore());
2091
2258
  var {
@@ -2126,23 +2293,28 @@ var {
2126
2293
  supports: supportsStyle,
2127
2294
  layerOrder,
2128
2295
  layer,
2129
- add: addStyle,
2296
+ add: addStyle2,
2130
2297
  important,
2131
2298
  getVariables: getStyleVariables,
2299
+ resolveNativeStyles,
2132
2300
  resolveClassStyles,
2133
2301
  render: renderStyle,
2134
2302
  inject: injectStyle,
2135
2303
  clear: clearStyle
2136
2304
  } = styles;
2137
2305
 
2138
- // src/desktop-auto-render.ts
2306
+ // src/desktop/auto-render/constants.ts
2139
2307
  var DESKTOP_RENDER_TRACKED_KEY = "__ELIT_DESKTOP_RENDER_TRACKED__";
2140
2308
  var DESKTOP_WINDOW_CREATED_KEY = "__ELIT_DESKTOP_WINDOW_CREATED__";
2141
2309
  var DESKTOP_MESSAGE_HANDLER_KEY = "__ELIT_DESKTOP_MESSAGE_HANDLER__";
2310
+
2311
+ // src/desktop/auto-render/globals.ts
2142
2312
  function getDesktopAutoRenderGlobals() {
2143
2313
  return globalThis;
2144
2314
  }
2145
- function escapeHtml(text) {
2315
+
2316
+ // src/desktop/auto-render/html.ts
2317
+ function escapeHtml2(text) {
2146
2318
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
2147
2319
  }
2148
2320
  function escapeStyleText(css) {
@@ -2155,7 +2327,7 @@ function buildDesktopAutoHtml(options) {
2155
2327
  <head>
2156
2328
  <meta charset="utf-8" />
2157
2329
  <meta name="viewport" content="width=device-width, initial-scale=1" />
2158
- <title>${escapeHtml(options.title)}</title>
2330
+ <title>${escapeHtml2(options.title)}</title>
2159
2331
  ${styleTag}
2160
2332
  </head>
2161
2333
  <body>
@@ -2190,6 +2362,8 @@ ${styleTag}
2190
2362
  </body>
2191
2363
  </html>`;
2192
2364
  }
2365
+
2366
+ // src/desktop/auto-render/message-handler.ts
2193
2367
  function resolveDesktopBridgePayloadRoute(payload) {
2194
2368
  if (!payload) {
2195
2369
  return void 0;
@@ -2206,19 +2380,6 @@ function resolveDesktopBridgePayloadRoute(payload) {
2206
2380
  }
2207
2381
  return void 0;
2208
2382
  }
2209
- function installDesktopRenderTracking() {
2210
- const globalScope = getDesktopAutoRenderGlobals();
2211
- globalScope[DESKTOP_WINDOW_CREATED_KEY] = false;
2212
- if (globalScope[DESKTOP_RENDER_TRACKED_KEY] || typeof globalScope.createWindow !== "function") {
2213
- return;
2214
- }
2215
- const originalCreateWindow = globalScope.createWindow.bind(globalScope);
2216
- globalScope.createWindow = (options) => {
2217
- globalScope[DESKTOP_WINDOW_CREATED_KEY] = true;
2218
- return originalCreateWindow(options);
2219
- };
2220
- globalScope[DESKTOP_RENDER_TRACKED_KEY] = true;
2221
- }
2222
2383
  function installDesktopMessageHandler(options) {
2223
2384
  const globalScope = getDesktopAutoRenderGlobals();
2224
2385
  let routeHistory = [];
@@ -2326,6 +2487,23 @@ function installDesktopMessageHandler(options) {
2326
2487
  });
2327
2488
  globalScope[DESKTOP_MESSAGE_HANDLER_KEY] = true;
2328
2489
  }
2490
+
2491
+ // src/desktop/auto-render/tracking.ts
2492
+ function installDesktopRenderTracking() {
2493
+ const globalScope = getDesktopAutoRenderGlobals();
2494
+ globalScope[DESKTOP_WINDOW_CREATED_KEY] = false;
2495
+ if (globalScope[DESKTOP_RENDER_TRACKED_KEY] || typeof globalScope.createWindow !== "function") {
2496
+ return;
2497
+ }
2498
+ const originalCreateWindow = globalScope.createWindow.bind(globalScope);
2499
+ globalScope.createWindow = (options) => {
2500
+ globalScope[DESKTOP_WINDOW_CREATED_KEY] = true;
2501
+ return originalCreateWindow(options);
2502
+ };
2503
+ globalScope[DESKTOP_RENDER_TRACKED_KEY] = true;
2504
+ }
2505
+
2506
+ // src/desktop/auto-render/complete.ts
2329
2507
  function completeDesktopAutoRender(options = {}) {
2330
2508
  installDesktopRenderTracking();
2331
2509
  const globalScope = getDesktopAutoRenderGlobals();
@@ -2357,7 +2535,7 @@ function completeDesktopAutoRender(options = {}) {
2357
2535
  icon: resolvedOptions.icon,
2358
2536
  html: buildDesktopAutoHtml({
2359
2537
  css: styles.render(),
2360
- markup: renderToString(capturedRender.vNode),
2538
+ markup: renderToString2(capturedRender.vNode),
2361
2539
  title: resolvedOptions.title
2362
2540
  })
2363
2541
  });