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