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