sibujs 4.6.0 → 4.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +62 -8
  3. package/dist/browser.d.cts +23 -0
  4. package/dist/browser.d.ts +23 -0
  5. package/dist/browser.js +6 -5
  6. package/dist/build.cjs +2388 -1004
  7. package/dist/build.d.cts +147 -44
  8. package/dist/build.d.ts +147 -44
  9. package/dist/build.js +1410 -564
  10. package/dist/cdn.dev.global.js +14 -12
  11. package/dist/cdn.full.dev.global.js +15 -13
  12. package/dist/cdn.full.global.js +14 -12
  13. package/dist/cdn.global.js +12 -10
  14. package/dist/chunk-3ACAAQIN.js +224 -0
  15. package/dist/{chunk-7NCARGJW.js → chunk-44MTL7ED.js} +6 -6
  16. package/dist/{chunk-BAAG6ZTI.js → chunk-4WMSTZ7J.js} +8 -5
  17. package/dist/{chunk-H3SRKIYX.js → chunk-62BDYGAG.js} +8 -0
  18. package/dist/{chunk-DKGBBKOF.js → chunk-C5PEWEGH.js} +20 -5
  19. package/dist/{chunk-3ISI6ACU.js → chunk-C7AA2CZX.js} +1 -1
  20. package/dist/{chunk-UZQ6ALFS.js → chunk-CZPRSWSS.js} +1 -1
  21. package/dist/{chunk-D33YTSX5.js → chunk-DSID757X.js} +5 -4
  22. package/dist/{chunk-OXUY2A6L.js → chunk-EGUQLBHE.js} +22 -8
  23. package/dist/{chunk-2INLLLMZ.js → chunk-EXXSN3BW.js} +202 -26
  24. package/dist/{chunk-HURREPU2.js → chunk-FC6KCJSA.js} +87 -150
  25. package/dist/{chunk-HYXDKS4N.js → chunk-GSGNX35Q.js} +5 -5
  26. package/dist/{chunk-7GQCWFOE.js → chunk-J3YQ457H.js} +171 -85
  27. package/dist/{chunk-ORMZXBKQ.js → chunk-JUTFX2RM.js} +18 -10
  28. package/dist/{chunk-QE4TTDU3.js → chunk-KJ3UKABJ.js} +12 -11
  29. package/dist/{chunk-XRRZKZYX.js → chunk-LI4W3U6C.js} +1 -1
  30. package/dist/{chunk-47M47FOM.js → chunk-O6TRVMJI.js} +58 -6
  31. package/dist/{chunk-JSXPZCET.js → chunk-Q5J2LVKH.js} +1 -1
  32. package/dist/{chunk-5MT6SJ3P.js → chunk-QGMSESDD.js} +10 -5
  33. package/dist/{chunk-AIF3Z2T7.js → chunk-RGLPEBDE.js} +13 -10
  34. package/dist/{chunk-5Q4R7HCL.js → chunk-TQQUN4WR.js} +11 -2
  35. package/dist/{chunk-PK6FK2G2.js → chunk-UCNP3HVM.js} +183 -30
  36. package/dist/{chunk-XC4MEKGA.js → chunk-V3LHZSU5.js} +8 -2
  37. package/dist/{chunk-VVWPJ543.js → chunk-VWT3VXPL.js} +55 -20
  38. package/dist/{chunk-SXXVZMKZ.js → chunk-ZVLHNEEL.js} +17 -35
  39. package/dist/{contracts-DRIuclVT.d.cts → contracts-CLqzJnOV.d.ts} +28 -17
  40. package/dist/{contracts-DRIuclVT.d.ts → contracts-CTOJXu-x.d.cts} +28 -17
  41. package/dist/{customElement-MmInOW1U.d.ts → customElement-pYDKUzWl.d.cts} +11 -3
  42. package/dist/{customElement-MmInOW1U.d.cts → customElement-pYDKUzWl.d.ts} +11 -3
  43. package/dist/data.cjs +205 -39
  44. package/dist/data.d.cts +119 -3
  45. package/dist/data.d.ts +119 -3
  46. package/dist/data.js +6 -6
  47. package/dist/devtools.cjs +18 -5
  48. package/dist/devtools.js +5 -5
  49. package/dist/ecosystem.cjs +462 -58
  50. package/dist/ecosystem.d.cts +2 -1
  51. package/dist/ecosystem.d.ts +2 -1
  52. package/dist/ecosystem.js +9 -8
  53. package/dist/extras.cjs +852 -296
  54. package/dist/extras.d.cts +5 -4
  55. package/dist/extras.d.ts +5 -4
  56. package/dist/extras.js +24 -23
  57. package/dist/index.cjs +721 -176
  58. package/dist/index.d.cts +220 -169
  59. package/dist/index.d.ts +220 -169
  60. package/dist/index.js +16 -12
  61. package/dist/motion.cjs +12 -4
  62. package/dist/motion.js +3 -3
  63. package/dist/patterns.cjs +37 -21
  64. package/dist/patterns.d.cts +2 -1
  65. package/dist/patterns.d.ts +2 -1
  66. package/dist/patterns.js +6 -6
  67. package/dist/performance.cjs +48 -6
  68. package/dist/performance.d.cts +12 -2
  69. package/dist/performance.d.ts +12 -2
  70. package/dist/performance.js +8 -6
  71. package/dist/plugins.cjs +672 -261
  72. package/dist/plugins.d.cts +131 -13
  73. package/dist/plugins.d.ts +131 -13
  74. package/dist/plugins.js +83 -47
  75. package/dist/{ssr-XOTUASDO.js → ssr-5OWAH3U2.js} +4 -2
  76. package/dist/{ssr-Bli9XRW5.d.cts → ssr-C8hgIAw7.d.cts} +6 -0
  77. package/dist/{ssr-Bli9XRW5.d.ts → ssr-C8hgIAw7.d.ts} +6 -0
  78. package/dist/ssr.cjs +509 -142
  79. package/dist/ssr.d.cts +55 -5
  80. package/dist/ssr.d.ts +55 -5
  81. package/dist/ssr.js +11 -9
  82. package/dist/{tagFactory-DFstCLQV.d.cts → tagFactory-8qL9LCIx.d.cts} +58 -19
  83. package/dist/{tagFactory-DkaNVUNV.d.ts → tagFactory-BL2fymez.d.ts} +58 -19
  84. package/dist/testing.cjs +17 -4
  85. package/dist/testing.js +4 -4
  86. package/dist/types-CJFViL6Q.d.cts +26 -0
  87. package/dist/types-CJFViL6Q.d.ts +26 -0
  88. package/dist/ui.cjs +635 -254
  89. package/dist/ui.d.cts +3 -2
  90. package/dist/ui.d.ts +3 -2
  91. package/dist/ui.js +9 -8
  92. package/dist/widgets.cjs +22 -14
  93. package/dist/widgets.js +7 -7
  94. package/package.json +8 -5
package/dist/build.js CHANGED
@@ -1,24 +1,940 @@
1
1
  import {
2
2
  index_exports
3
- } from "./chunk-7GQCWFOE.js";
4
- import "./chunk-JSXPZCET.js";
5
- import "./chunk-HURREPU2.js";
6
- import "./chunk-UZQ6ALFS.js";
7
- import "./chunk-3ISI6ACU.js";
8
- import "./chunk-VVWPJ543.js";
9
- import "./chunk-47M47FOM.js";
10
- import "./chunk-QE4TTDU3.js";
11
- import "./chunk-2INLLLMZ.js";
3
+ } from "./chunk-J3YQ457H.js";
4
+ import "./chunk-Q5J2LVKH.js";
5
+ import "./chunk-FC6KCJSA.js";
6
+ import "./chunk-CZPRSWSS.js";
7
+ import "./chunk-C7AA2CZX.js";
8
+ import "./chunk-62BDYGAG.js";
9
+ import "./chunk-VWT3VXPL.js";
10
+ import "./chunk-O6TRVMJI.js";
11
+ import "./chunk-3ACAAQIN.js";
12
+ import "./chunk-KJ3UKABJ.js";
12
13
  import "./chunk-7ZHH77QA.js";
13
- import "./chunk-XC4MEKGA.js";
14
+ import "./chunk-V3LHZSU5.js";
15
+ import {
16
+ isEventHandlerAttr,
17
+ isHtmlContentAttribute,
18
+ isUrlAttribute
19
+ } from "./chunk-EXXSN3BW.js";
14
20
  import "./chunk-7XHATCIH.js";
15
21
  import "./chunk-5HZXGZ6T.js";
16
- import "./chunk-D33YTSX5.js";
17
- import "./chunk-5Q4R7HCL.js";
22
+ import "./chunk-DSID757X.js";
23
+ import "./chunk-TQQUN4WR.js";
18
24
  import "./chunk-NYNYSPK7.js";
19
25
 
20
- // src/build/compileTemplates.ts
21
- var VOID_ELEMENTS = /* @__PURE__ */ new Set([
26
+ // src/build/sourceEdit.ts
27
+ function isLineBreak(c) {
28
+ return c === 10 || c === 13 || c === 8232 || c === 8233;
29
+ }
30
+ function lineBreaksIn(code, start, end) {
31
+ let out = "";
32
+ for (let i = start; i < end; i++) {
33
+ if (isLineBreak(code.charCodeAt(i))) out += code[i];
34
+ }
35
+ return out;
36
+ }
37
+ var LINE_SEPARATOR = String.fromCharCode(8232);
38
+ var PARAGRAPH_SEPARATOR = String.fromCharCode(8233);
39
+ function jsStringLiteral(value) {
40
+ const json = JSON.stringify(value);
41
+ if (!json.includes(LINE_SEPARATOR) && !json.includes(PARAGRAPH_SEPARATOR)) return json;
42
+ const bs = "\\";
43
+ return json.split(LINE_SEPARATOR).join(`${bs}u2028`).split(PARAGRAPH_SEPARATOR).join(`${bs}u2029`);
44
+ }
45
+ function normalizeEdits(edits) {
46
+ const sorted = edits.map((edit, order) => ({ edit, order })).sort(
47
+ (a, b) => a.edit.start - b.edit.start || a.edit.end - a.edit.start - (b.edit.end - b.edit.start) || a.order - b.order
48
+ ).map((x) => x.edit);
49
+ for (let i = 1; i < sorted.length; i++) {
50
+ if (sorted[i].start < sorted[i - 1].end) return null;
51
+ }
52
+ return sorted;
53
+ }
54
+ function applyEdits(code, edits, append = "") {
55
+ let out = "";
56
+ let pos = 0;
57
+ for (const edit of edits) {
58
+ out += code.slice(pos, edit.start) + edit.text;
59
+ pos = edit.end;
60
+ }
61
+ return out + code.slice(pos) + append;
62
+ }
63
+ var BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
64
+ function vlq(value) {
65
+ let v = value < 0 ? -value << 1 | 1 : value << 1;
66
+ let out = "";
67
+ do {
68
+ let digit = v & 31;
69
+ v >>>= 5;
70
+ if (v > 0) digit |= 32;
71
+ out += BASE64[digit];
72
+ } while (v > 0);
73
+ return out;
74
+ }
75
+ function isWordStart(c) {
76
+ return c >= 97 && c <= 122 || c >= 65 && c <= 90 || c === 95 || c === 36 || c > 127 || c >= 48 && c <= 57;
77
+ }
78
+ function editsSourceMap(code, edits, append, source) {
79
+ const lineStarts = [0];
80
+ for (let i = 0; i < code.length; i++) if (code.charCodeAt(i) === 10) lineStarts.push(i + 1);
81
+ const origLine = (offset) => {
82
+ let lo = 0;
83
+ let hi = lineStarts.length - 1;
84
+ while (lo < hi) {
85
+ const mid = lo + hi + 1 >> 1;
86
+ if (lineStarts[mid] <= offset) lo = mid;
87
+ else hi = mid - 1;
88
+ }
89
+ return lo;
90
+ };
91
+ const lines = [[]];
92
+ let col = 0;
93
+ const mark = (offset) => {
94
+ const line = lines[lines.length - 1];
95
+ const last = line[line.length - 1];
96
+ if (last && last[0] === col) return;
97
+ const ol = origLine(offset);
98
+ line.push([col, ol, offset - lineStarts[ol]]);
99
+ };
100
+ const newline = () => {
101
+ lines.push([]);
102
+ col = 0;
103
+ };
104
+ const emitOriginal = (from, to) => {
105
+ for (let i = from; i < to; i++) {
106
+ const c = code.charCodeAt(i);
107
+ if (c === 10) {
108
+ newline();
109
+ continue;
110
+ }
111
+ if (i === from || col === 0 || isWordStart(c) && !isWordStart(code.charCodeAt(i - 1))) mark(i);
112
+ col++;
113
+ }
114
+ };
115
+ const emitReplacement = (edit) => {
116
+ let origOffset = edit.start;
117
+ let pending = true;
118
+ for (let i = 0; i < edit.text.length; i++) {
119
+ if (edit.text.charCodeAt(i) === 10) {
120
+ newline();
121
+ const nl = code.indexOf("\n", origOffset);
122
+ if (nl !== -1 && nl < edit.end) {
123
+ origOffset = nl + 1;
124
+ pending = true;
125
+ } else {
126
+ pending = false;
127
+ }
128
+ continue;
129
+ }
130
+ if (pending) {
131
+ mark(origOffset);
132
+ pending = false;
133
+ }
134
+ col++;
135
+ }
136
+ };
137
+ let pos = 0;
138
+ for (const edit of edits) {
139
+ emitOriginal(pos, edit.start);
140
+ emitReplacement(edit);
141
+ pos = edit.end;
142
+ }
143
+ emitOriginal(pos, code.length);
144
+ for (let i = 0; i < append.length; i++) {
145
+ if (append.charCodeAt(i) === 10) newline();
146
+ }
147
+ let prevLine = 0;
148
+ let prevCol = 0;
149
+ let prevSource = 0;
150
+ const mappings = lines.map((segments) => {
151
+ let prevGen = 0;
152
+ return segments.map(([gen, ol, oc]) => {
153
+ const s = vlq(gen - prevGen) + vlq(0 - prevSource) + vlq(ol - prevLine) + vlq(oc - prevCol);
154
+ prevGen = gen;
155
+ prevSource = 0;
156
+ prevLine = ol;
157
+ prevCol = oc;
158
+ return s;
159
+ }).join(",");
160
+ }).join(";");
161
+ return { version: 3, sources: [source], sourcesContent: [code], names: [], mappings };
162
+ }
163
+
164
+ // src/build/sourceScan.ts
165
+ var REGEX_AFTER_KEYWORD = /* @__PURE__ */ new Set([
166
+ "return",
167
+ "typeof",
168
+ "instanceof",
169
+ "in",
170
+ "of",
171
+ "new",
172
+ "delete",
173
+ "void",
174
+ "throw",
175
+ "case",
176
+ "do",
177
+ "else",
178
+ "yield",
179
+ "await"
180
+ ]);
181
+ function isIdentStart(c) {
182
+ return c >= 97 && c <= 122 || c >= 65 && c <= 90 || c === 95 || c === 36 || c > 127;
183
+ }
184
+ function isIdentPart(c) {
185
+ return isIdentStart(c) || c >= 48 && c <= 57;
186
+ }
187
+ function isDigit(c) {
188
+ return c >= 48 && c <= 57;
189
+ }
190
+ var ScanError = class extends Error {
191
+ };
192
+ var scanStats = { tokenize: 0 };
193
+ function tokenize(code) {
194
+ scanStats.tokenize++;
195
+ let pos = 0;
196
+ const len = code.length;
197
+ if (code.startsWith("#!")) {
198
+ const nl = code.indexOf("\n");
199
+ pos = nl === -1 ? len : nl;
200
+ }
201
+ function regexAllowed(prev) {
202
+ if (!prev) return true;
203
+ switch (prev.type) {
204
+ case "number":
205
+ case "string":
206
+ case "regex":
207
+ case "template":
208
+ return false;
209
+ case "ident":
210
+ return REGEX_AFTER_KEYWORD.has(prev.value);
211
+ case "punct":
212
+ return prev.value !== ")" && prev.value !== "]";
213
+ }
214
+ }
215
+ function skipTrivia() {
216
+ while (pos < len) {
217
+ const c = code.charCodeAt(pos);
218
+ if (c === 32 || c === 9 || c === 10 || c === 13 || c === 11 || c === 12 || c === 160 || c === 65279) {
219
+ pos++;
220
+ } else if (c === 8232 || c === 8233) {
221
+ pos++;
222
+ } else if (c === 47 && code.charCodeAt(pos + 1) === 47) {
223
+ pos += 2;
224
+ while (pos < len) {
225
+ const d = code.charCodeAt(pos);
226
+ if (d === 10 || d === 13 || d === 8232 || d === 8233) break;
227
+ pos++;
228
+ }
229
+ } else if (c === 47 && code.charCodeAt(pos + 1) === 42) {
230
+ const end = code.indexOf("*/", pos + 2);
231
+ if (end === -1) throw new ScanError("unterminated comment");
232
+ pos = end + 2;
233
+ } else {
234
+ break;
235
+ }
236
+ }
237
+ }
238
+ function readString() {
239
+ const start = pos;
240
+ const quote = code[pos];
241
+ pos++;
242
+ while (pos < len) {
243
+ const c = code[pos];
244
+ if (c === "\\") {
245
+ pos += 2;
246
+ continue;
247
+ }
248
+ if (c === quote) {
249
+ pos++;
250
+ return { type: "string", start, end: pos };
251
+ }
252
+ if (c === "\n" || c === "\r") throw new ScanError("line break in string");
253
+ pos++;
254
+ }
255
+ throw new ScanError("unterminated string");
256
+ }
257
+ function readRegex() {
258
+ const start = pos;
259
+ pos++;
260
+ let inClass = false;
261
+ while (pos < len) {
262
+ const c = code[pos];
263
+ if (c === "\\") {
264
+ pos += 2;
265
+ continue;
266
+ }
267
+ if (c === "\n" || c === "\r") throw new ScanError("line break in regex");
268
+ if (inClass) {
269
+ if (c === "]") inClass = false;
270
+ } else if (c === "[") {
271
+ inClass = true;
272
+ } else if (c === "/") {
273
+ pos++;
274
+ while (pos < len && isIdentPart(code.charCodeAt(pos))) pos++;
275
+ return { type: "regex", start, end: pos };
276
+ }
277
+ pos++;
278
+ }
279
+ throw new ScanError("unterminated regex");
280
+ }
281
+ function readTemplate() {
282
+ const start = pos;
283
+ pos++;
284
+ const quasis = [];
285
+ const exprs = [];
286
+ let quasiStart = pos;
287
+ while (pos < len) {
288
+ const c = code[pos];
289
+ if (c === "\\") {
290
+ pos += 2;
291
+ continue;
292
+ }
293
+ if (c === "`") {
294
+ quasis.push({ start: quasiStart, end: pos });
295
+ pos++;
296
+ return { type: "template", start, end: pos, quasis, exprs };
297
+ }
298
+ if (c === "$" && code[pos + 1] === "{") {
299
+ quasis.push({ start: quasiStart, end: pos });
300
+ pos += 2;
301
+ const exprStart = pos;
302
+ const tokens = readList(true);
303
+ exprs.push({ start: exprStart, end: pos, tokens });
304
+ pos++;
305
+ quasiStart = pos;
306
+ continue;
307
+ }
308
+ pos++;
309
+ }
310
+ throw new ScanError("unterminated template");
311
+ }
312
+ function readList(inTemplateExpr) {
313
+ const tokens = [];
314
+ let depth = 0;
315
+ for (; ; ) {
316
+ skipTrivia();
317
+ if (pos >= len) {
318
+ if (inTemplateExpr || depth !== 0) throw new ScanError("unexpected end of input");
319
+ return tokens;
320
+ }
321
+ const c = code.charCodeAt(pos);
322
+ const prev = tokens[tokens.length - 1];
323
+ if (c === 34 || c === 39) {
324
+ tokens.push(readString());
325
+ } else if (c === 96) {
326
+ tokens.push(readTemplate());
327
+ } else if (isIdentStart(c) || c === 92) {
328
+ const start = pos;
329
+ pos++;
330
+ while (pos < len) {
331
+ const d = code.charCodeAt(pos);
332
+ if (isIdentPart(d)) pos++;
333
+ else if (d === 92) pos += 2;
334
+ else break;
335
+ }
336
+ tokens.push({ type: "ident", start, end: pos, value: code.slice(start, pos) });
337
+ } else if (isDigit(c) || c === 46 && isDigit(code.charCodeAt(pos + 1))) {
338
+ const start = pos;
339
+ pos++;
340
+ while (pos < len) {
341
+ const d = code.charCodeAt(pos);
342
+ if (isIdentPart(d) || d === 46) pos++;
343
+ else break;
344
+ }
345
+ tokens.push({ type: "number", start, end: pos, value: code.slice(start, pos) });
346
+ } else if (c === 47 && regexAllowed(prev)) {
347
+ tokens.push(readRegex());
348
+ } else {
349
+ const start = pos;
350
+ let value = code[pos];
351
+ if (code.startsWith("...", pos)) value = "...";
352
+ else if (code.startsWith("?.", pos) && !isDigit(code.charCodeAt(pos + 2))) value = "?.";
353
+ else if (code.startsWith("=>", pos)) value = "=>";
354
+ pos += value.length;
355
+ if (value === "{") {
356
+ depth++;
357
+ } else if (value === "}") {
358
+ if (depth === 0) {
359
+ if (inTemplateExpr) {
360
+ pos = start;
361
+ return tokens;
362
+ }
363
+ throw new ScanError("unbalanced brace");
364
+ }
365
+ depth--;
366
+ }
367
+ tokens.push({ type: "punct", start, end: pos, value });
368
+ }
369
+ }
370
+ }
371
+ try {
372
+ return readList(false);
373
+ } catch (err) {
374
+ if (err instanceof ScanError) return null;
375
+ throw err;
376
+ }
377
+ }
378
+ function cookEscapes(raw) {
379
+ let out = "";
380
+ let i = 0;
381
+ const n = raw.length;
382
+ while (i < n) {
383
+ const ch = raw[i];
384
+ if (ch === "\r") {
385
+ out += "\n";
386
+ i += raw[i + 1] === "\n" ? 2 : 1;
387
+ continue;
388
+ }
389
+ if (ch !== "\\") {
390
+ out += ch;
391
+ i++;
392
+ continue;
393
+ }
394
+ const e = raw[i + 1];
395
+ i += 2;
396
+ switch (e) {
397
+ case "n":
398
+ out += "\n";
399
+ break;
400
+ case "t":
401
+ out += " ";
402
+ break;
403
+ case "r":
404
+ out += "\r";
405
+ break;
406
+ case "b":
407
+ out += "\b";
408
+ break;
409
+ case "f":
410
+ out += "\f";
411
+ break;
412
+ case "v":
413
+ out += "\v";
414
+ break;
415
+ case "0":
416
+ if (i < n && isDigit(raw.charCodeAt(i))) return null;
417
+ out += "\0";
418
+ break;
419
+ case "x": {
420
+ const hex = raw.slice(i, i + 2);
421
+ if (!/^[0-9a-fA-F]{2}$/.test(hex)) return null;
422
+ out += String.fromCharCode(Number.parseInt(hex, 16));
423
+ i += 2;
424
+ break;
425
+ }
426
+ case "u": {
427
+ if (raw[i] === "{") {
428
+ const close = raw.indexOf("}", i);
429
+ if (close === -1) return null;
430
+ const hex = raw.slice(i + 1, close);
431
+ if (!/^[0-9a-fA-F]+$/.test(hex)) return null;
432
+ const cp = Number.parseInt(hex, 16);
433
+ if (cp > 1114111) return null;
434
+ out += String.fromCodePoint(cp);
435
+ i = close + 1;
436
+ } else {
437
+ const hex = raw.slice(i, i + 4);
438
+ if (!/^[0-9a-fA-F]{4}$/.test(hex)) return null;
439
+ out += String.fromCharCode(Number.parseInt(hex, 16));
440
+ i += 4;
441
+ }
442
+ break;
443
+ }
444
+ case "\r":
445
+ if (raw[i] === "\n") i++;
446
+ break;
447
+ case "\n":
448
+ case "\u2028":
449
+ case "\u2029":
450
+ break;
451
+ case void 0:
452
+ return null;
453
+ default:
454
+ if (isDigit(e.charCodeAt(0))) return null;
455
+ out += e;
456
+ }
457
+ }
458
+ return out;
459
+ }
460
+ function stringTokenValue(code, tok) {
461
+ if (tok.type !== "string") return null;
462
+ return cookEscapes(code.slice(tok.start + 1, tok.end - 1));
463
+ }
464
+ function collectImports(code, tokens) {
465
+ const decls = [];
466
+ for (let i = 0; i < tokens.length; i++) {
467
+ const tok = tokens[i];
468
+ if (tok.type !== "ident" || tok.value !== "import") continue;
469
+ const prev = tokens[i - 1];
470
+ if (prev && prev.type === "punct" && (prev.value === "." || prev.value === "?.")) continue;
471
+ const next = tokens[i + 1];
472
+ if (!next) return null;
473
+ if (next.type === "punct" && (next.value === "(" || next.value === ".")) continue;
474
+ let j = i + 1;
475
+ const bindings = [];
476
+ let typeOnly = false;
477
+ if (next.type === "string") {
478
+ const source2 = stringTokenValue(code, next);
479
+ if (source2 === null) return null;
480
+ let end2 = next.end;
481
+ const semi = tokens[j + 1];
482
+ if (semi && semi.type === "punct" && semi.value === ";") end2 = semi.end;
483
+ decls.push({ source: source2, bindings, start: tok.start, end: end2 });
484
+ continue;
485
+ }
486
+ const at = (k) => tokens[k];
487
+ const isPunct = (k, v) => {
488
+ const t = at(k);
489
+ return !!t && t.type === "punct" && t.value === v;
490
+ };
491
+ const isIdent = (k, v) => {
492
+ const t = at(k);
493
+ return !!t && t.type === "ident" && (v === void 0 || t.value === v);
494
+ };
495
+ if (isIdent(j, "type") && !isIdent(j + 1, "from") && !isPunct(j + 1, ",")) {
496
+ typeOnly = true;
497
+ j++;
498
+ }
499
+ if (isIdent(j) && !isIdent(j, "from")) {
500
+ bindings.push({ imported: "default", local: at(j).value });
501
+ j++;
502
+ if (isPunct(j, ",")) j++;
503
+ }
504
+ if (isPunct(j, "*")) {
505
+ if (!isIdent(j + 1, "as") || !isIdent(j + 2)) return null;
506
+ bindings.push({ imported: "*", local: at(j + 2).value });
507
+ j += 3;
508
+ } else if (isPunct(j, "{")) {
509
+ j++;
510
+ while (!isPunct(j, "}")) {
511
+ const t = at(j);
512
+ if (!t) return null;
513
+ let specTypeOnly = false;
514
+ if (isIdent(j, "type") && (isIdent(j + 1) || at(j + 1)?.type === "string") && !isIdent(j + 1, "as")) {
515
+ specTypeOnly = true;
516
+ j++;
517
+ }
518
+ const nameTok = at(j);
519
+ let imported = null;
520
+ if (nameTok?.type === "ident") imported = nameTok.value;
521
+ else if (nameTok?.type === "string") imported = stringTokenValue(code, nameTok);
522
+ if (imported === null) return null;
523
+ j++;
524
+ let local = imported;
525
+ if (isIdent(j, "as")) {
526
+ if (!isIdent(j + 1)) return null;
527
+ local = at(j + 1).value;
528
+ j += 2;
529
+ }
530
+ if (!specTypeOnly) bindings.push({ imported, local });
531
+ if (isPunct(j, ",")) j++;
532
+ else if (!isPunct(j, "}")) return null;
533
+ }
534
+ j++;
535
+ }
536
+ if (!isIdent(j, "from")) return null;
537
+ const srcTok = at(j + 1);
538
+ if (!srcTok || srcTok.type !== "string") return null;
539
+ const source = stringTokenValue(code, srcTok);
540
+ if (source === null) return null;
541
+ let end = srcTok.end;
542
+ j += 2;
543
+ if (isIdent(j, "with") || isIdent(j, "assert")) {
544
+ if (!isPunct(j + 1, "{")) return null;
545
+ let k = j + 2;
546
+ while (at(k) && !isPunct(k, "}")) k++;
547
+ if (!at(k)) return null;
548
+ end = at(k).end;
549
+ j = k + 1;
550
+ }
551
+ if (isPunct(j, ";")) end = at(j).end;
552
+ decls.push({ source, bindings: typeOnly ? [] : bindings, start: tok.start, end });
553
+ i = j;
554
+ }
555
+ return decls;
556
+ }
557
+ var SCAN_CACHE_SIZE = 4;
558
+ var scanCache = /* @__PURE__ */ new Map();
559
+ function scanModule(code) {
560
+ const hit = scanCache.get(code);
561
+ if (hit !== void 0) return hit;
562
+ const tokens = tokenize(code);
563
+ const imports = tokens && collectImports(code, tokens);
564
+ const scan = tokens && imports ? { tokens, imports } : null;
565
+ if (scanCache.size >= SCAN_CACHE_SIZE) scanCache.delete(scanCache.keys().next().value);
566
+ scanCache.set(code, scan);
567
+ return scan;
568
+ }
569
+ function isSibuSource(source) {
570
+ return source === "sibujs" || source.startsWith("sibujs/");
571
+ }
572
+ function sibuBindings(imports, mainOnly = false) {
573
+ const out = /* @__PURE__ */ new Map();
574
+ for (const decl of imports) {
575
+ if (mainOnly ? decl.source !== "sibujs" : !isSibuSource(decl.source)) continue;
576
+ for (const b of decl.bindings) {
577
+ if (b.imported === "*" || b.imported === "default") continue;
578
+ out.set(b.local, b.imported);
579
+ }
580
+ }
581
+ return out;
582
+ }
583
+ function forEachBindingRef(tokens, imports, visit) {
584
+ const inImport = (offset) => imports.some((d) => offset >= d.start && offset < d.end);
585
+ const walk = (list) => {
586
+ for (let i = 0; i < list.length; i++) {
587
+ const tok = list[i];
588
+ if (tok.type === "template") {
589
+ for (const e of tok.exprs) walk(e.tokens);
590
+ continue;
591
+ }
592
+ if (tok.type !== "ident") continue;
593
+ const prev = list[i - 1];
594
+ if (prev && prev.type === "punct" && (prev.value === "." || prev.value === "?." || prev.value === "#")) continue;
595
+ if (inImport(tok.start)) continue;
596
+ visit({ tok, list, index: i });
597
+ }
598
+ };
599
+ walk(tokens);
600
+ }
601
+ var EXPRESSION_KEYWORDS = /* @__PURE__ */ new Set([...REGEX_AFTER_KEYWORD, "default", "extends"]);
602
+ function isLineTerminator(c) {
603
+ return c === 10 || c === 13 || c === 8232 || c === 8233;
604
+ }
605
+ function lineBreakBetween(code, from, to) {
606
+ for (let i = from; i < to; i++) if (isLineTerminator(code.charCodeAt(i))) return true;
607
+ return false;
608
+ }
609
+ function endsValue(tok) {
610
+ if (!tok) return false;
611
+ switch (tok.type) {
612
+ case "number":
613
+ case "string":
614
+ case "regex":
615
+ case "template":
616
+ return true;
617
+ case "ident":
618
+ return !EXPRESSION_KEYWORDS.has(tok.value);
619
+ case "punct":
620
+ return tok.value === ")" || tok.value === "]";
621
+ }
622
+ }
623
+ function isDeclarationHead(code, list, index) {
624
+ const tok = list[index];
625
+ const prev = list[index - 1];
626
+ if (prev?.type === "ident") {
627
+ if (prev.value === "function") return true;
628
+ if (!EXPRESSION_KEYWORDS.has(prev.value) && !lineBreakBetween(code, prev.end, tok.start)) return true;
629
+ } else if (prev?.type === "punct") {
630
+ const before = list[index - 2];
631
+ if (prev.value === "*" && !endsValue(before) && !(before?.type === "ident" && before.value === "yield"))
632
+ return true;
633
+ if (prev.value === "@") return true;
634
+ }
635
+ let depth = 0;
636
+ let close = -1;
637
+ for (let k = index + 1; k < list.length; k++) {
638
+ const t = list[k];
639
+ if (t.type !== "punct") continue;
640
+ if (t.value === "(") depth++;
641
+ else if (t.value === ")" && --depth === 0) {
642
+ close = k;
643
+ break;
644
+ }
645
+ }
646
+ if (close === -1) return true;
647
+ const after = list[close + 1];
648
+ if (after?.type !== "punct") return false;
649
+ if (after.value === "{") return true;
650
+ if (after.value === ":") {
651
+ if (!prev) return true;
652
+ if (prev.type === "punct") return ["{", "}", ";", ",", "*"].includes(prev.value);
653
+ return prev.type === "ident" && !EXPRESSION_KEYWORDS.has(prev.value);
654
+ }
655
+ return false;
656
+ }
657
+ function bindingUses(code, scan, names) {
658
+ const shadowed = /* @__PURE__ */ new Set();
659
+ const bound = /* @__PURE__ */ new Map();
660
+ for (const decl of scan.imports) {
661
+ for (const b of decl.bindings) bound.set(b.local, (bound.get(b.local) ?? 0) + 1);
662
+ }
663
+ for (const name of names) if ((bound.get(name) ?? 0) > 1) shadowed.add(name);
664
+ const calls = [];
665
+ const tagged = [];
666
+ forEachBindingRef(scan.tokens, scan.imports, (ref) => {
667
+ const { tok, list, index } = ref;
668
+ if (!names.has(tok.value)) return;
669
+ const next = list[index + 1];
670
+ if (next && next.type === "punct" && next.value === "(") {
671
+ if (isDeclarationHead(code, list, index)) shadowed.add(tok.value);
672
+ else calls.push(ref);
673
+ } else if (next && next.type === "template") {
674
+ const prev = list[index - 1];
675
+ if (prev?.type === "punct" && prev.value === "@") shadowed.add(tok.value);
676
+ else tagged.push(ref);
677
+ } else {
678
+ shadowed.add(tok.value);
679
+ }
680
+ });
681
+ return {
682
+ calls: calls.filter((r) => !shadowed.has(r.tok.value)),
683
+ tagged: tagged.filter((r) => !shadowed.has(r.tok.value)),
684
+ shadowed
685
+ };
686
+ }
687
+ function uniquePrefix(code, base = "__sibujs") {
688
+ let prefix = `${base}$`;
689
+ for (let n = 1; code.includes(prefix); n++) prefix = `${base}${n}$`;
690
+ return prefix;
691
+ }
692
+ var PURE_FACTORIES = /* @__PURE__ */ new Set([
693
+ "tagFactory",
694
+ "context",
695
+ "defineComponent",
696
+ "withProps",
697
+ "withDefaults",
698
+ "pure",
699
+ "noSideEffect"
700
+ ]);
701
+ var PURE_COMMENT = "/*#__PURE__*/ ";
702
+ function pureAnnotationEdits(code) {
703
+ if (!code.includes("sibujs")) return [];
704
+ const scan = scanModule(code);
705
+ if (!scan) return [];
706
+ const candidates = /* @__PURE__ */ new Set();
707
+ for (const [local, imported] of sibuBindings(scan.imports)) if (PURE_FACTORIES.has(imported)) candidates.add(local);
708
+ if (candidates.size === 0) return [];
709
+ const uses = bindingUses(code, scan, candidates);
710
+ const unsafe = new Set(uses.shadowed);
711
+ for (const ref of uses.tagged) unsafe.add(ref.tok.value);
712
+ return uses.calls.filter(({ tok }) => {
713
+ if (unsafe.has(tok.value)) return false;
714
+ return !/\/\*\s*[#@]__PURE__\s*\*\/\s*$/.test(code.slice(Math.max(0, tok.start - 40), tok.start));
715
+ }).map(({ tok }) => ({ start: tok.start, end: tok.start, text: PURE_COMMENT }));
716
+ }
717
+ function injectPureAnnotations(code) {
718
+ const edits = normalizeEdits(pureAnnotationEdits(code));
719
+ return edits && edits.length > 0 ? applyEdits(code, edits) : code;
720
+ }
721
+ function importsSibu(code) {
722
+ if (!code.includes("sibujs")) return false;
723
+ const scan = scanModule(code);
724
+ return !!scan?.imports.some((d) => isSibuSource(d.source));
725
+ }
726
+
727
+ // src/build/staticAnalysis.ts
728
+ var STATIC_TAGS = /* @__PURE__ */ new Set([
729
+ "div",
730
+ "span",
731
+ "section",
732
+ "article",
733
+ "header",
734
+ "footer",
735
+ "nav",
736
+ "main",
737
+ "aside",
738
+ "p",
739
+ "h1",
740
+ "h2",
741
+ "h3",
742
+ "h4",
743
+ "h5",
744
+ "h6",
745
+ "blockquote",
746
+ "li",
747
+ "ol",
748
+ "ul",
749
+ "a",
750
+ "b",
751
+ "em",
752
+ "i",
753
+ "strong",
754
+ "small",
755
+ "code",
756
+ "mark",
757
+ "img",
758
+ "br",
759
+ "hr",
760
+ "input",
761
+ "button",
762
+ "form",
763
+ "label",
764
+ "details",
765
+ "summary",
766
+ "dialog"
767
+ ]);
768
+ var VOID_ELEMENTS = /* @__PURE__ */ new Set([
769
+ "br",
770
+ "hr",
771
+ "img",
772
+ "input",
773
+ "meta",
774
+ "link",
775
+ "area",
776
+ "base",
777
+ "col",
778
+ "embed",
779
+ "param",
780
+ "source",
781
+ "track",
782
+ "wbr"
783
+ ]);
784
+ var SPECIAL_PROPS = /* @__PURE__ */ new Set(["style", "ref", "on", "onElement"]);
785
+ var NON_REFLECTING_BOOLEANS = /* @__PURE__ */ new Set(["checked", "selected"]);
786
+ function readLiteral(code, tok) {
787
+ if (!tok) return null;
788
+ if (tok.type === "string") {
789
+ const value = stringTokenValue(code, tok);
790
+ return value === null ? null : { kind: "string", value };
791
+ }
792
+ if (tok.type === "number" && /^(0|[1-9]\d*)(\.\d+)?$/.test(tok.value)) {
793
+ return { kind: "number", value: String(Number(tok.value)) };
794
+ }
795
+ if (tok.type === "ident" && ["true", "false", "null", "undefined"].includes(tok.value)) {
796
+ return { kind: "keyword", value: tok.value };
797
+ }
798
+ return null;
799
+ }
800
+ function parserSafeText(s) {
801
+ return !s.includes("\r") && !s.includes("\0");
802
+ }
803
+ function escapeHtml(str) {
804
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
805
+ }
806
+ function escapeAttr(str) {
807
+ return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
808
+ }
809
+ function attributeHtml(name, lit) {
810
+ if (!/^[a-zA-Z][a-zA-Z0-9-]*$/.test(name)) return null;
811
+ const lower = name.toLowerCase();
812
+ if (SPECIAL_PROPS.has(name) || lower === "style" || lower === "srcset") return null;
813
+ if (isEventHandlerAttr(name) || isUrlAttribute(name) || isHtmlContentAttribute(name)) return null;
814
+ if (lit.kind === "keyword") {
815
+ if (lit.value === "null" || lit.value === "undefined") return "";
816
+ const on = lit.value === "true";
817
+ if (lower.startsWith("aria-")) return `${lower}="${on}"`;
818
+ if (NON_REFLECTING_BOOLEANS.has(lower)) return null;
819
+ return on ? `${lower}=""` : "";
820
+ }
821
+ if (!parserSafeText(lit.value)) return null;
822
+ return `${lower}="${escapeAttr(lit.value)}"`;
823
+ }
824
+ function parseCall(code, list, i) {
825
+ const at = (k2) => list[k2];
826
+ const isPunct = (k2, v) => {
827
+ const t = at(k2);
828
+ return !!t && t.type === "punct" && t.value === v;
829
+ };
830
+ let k = i + 1;
831
+ const result = { end: 0, cls: null, id: null, attrs: [], text: null };
832
+ let nodesText = null;
833
+ if (isPunct(k, "{")) {
834
+ k++;
835
+ const seen = /* @__PURE__ */ new Set();
836
+ while (!isPunct(k, "}")) {
837
+ const keyTok = at(k);
838
+ let key = null;
839
+ if (keyTok?.type === "ident") key = keyTok.value;
840
+ else if (keyTok?.type === "string") key = stringTokenValue(code, keyTok);
841
+ if (key === null || !isPunct(k + 1, ":")) return null;
842
+ if (seen.has(key.toLowerCase())) return null;
843
+ seen.add(key.toLowerCase());
844
+ const lit = readLiteral(code, at(k + 2));
845
+ if (lit === null) return null;
846
+ k += 3;
847
+ if (isPunct(k, ",")) k++;
848
+ else if (!isPunct(k, "}")) return null;
849
+ if (key === "class" || key === "id") {
850
+ if (lit.kind !== "string" || !parserSafeText(lit.value)) return null;
851
+ if (key === "class") result.cls = lit.value;
852
+ else result.id = lit.value;
853
+ } else if (key === "nodes") {
854
+ if (lit.kind !== "string" || !parserSafeText(lit.value)) return null;
855
+ nodesText = lit.value;
856
+ } else {
857
+ const html = attributeHtml(key, lit);
858
+ if (html === null) return null;
859
+ if (html) result.attrs.push(html);
860
+ }
861
+ }
862
+ k++;
863
+ if (isPunct(k, ",")) {
864
+ const second = readLiteral(code, at(k + 1));
865
+ if (second === null) {
866
+ if (!isPunct(k + 1, ")")) return null;
867
+ k++;
868
+ } else {
869
+ if (second.kind !== "string" || !parserSafeText(second.value)) return null;
870
+ result.text = second.value;
871
+ k += 2;
872
+ if (isPunct(k, ",")) k++;
873
+ }
874
+ }
875
+ if (result.text === null) result.text = nodesText;
876
+ } else {
877
+ const first = readLiteral(code, at(k));
878
+ if (first === null || first.kind !== "string" || !parserSafeText(first.value)) return null;
879
+ k++;
880
+ if (isPunct(k, ",") && at(k + 1)?.type === "string") {
881
+ const second = readLiteral(code, at(k + 1));
882
+ if (second === null || second.kind !== "string" || !parserSafeText(second.value)) return null;
883
+ result.cls = first.value;
884
+ result.text = second.value;
885
+ k += 2;
886
+ } else {
887
+ result.text = first.value;
888
+ }
889
+ if (isPunct(k, ",")) k++;
890
+ }
891
+ if (!isPunct(k, ")")) return null;
892
+ result.end = at(k).end;
893
+ return result;
894
+ }
895
+ function toHtml(tag, call) {
896
+ const attrs = [];
897
+ if (call.cls !== null) attrs.push(`class="${escapeAttr(call.cls)}"`);
898
+ if (call.id !== null) attrs.push(`id="${escapeAttr(call.id)}"`);
899
+ attrs.push(...call.attrs);
900
+ const attrStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
901
+ if (VOID_ELEMENTS.has(tag)) {
902
+ if (call.text) return null;
903
+ return `<${tag}${attrStr} />`;
904
+ }
905
+ return `<${tag}${attrStr}>${escapeHtml(call.text ?? "")}</${tag}>`;
906
+ }
907
+ function analyzeStaticTemplates(code) {
908
+ const none = { hasStaticPatterns: false, patterns: [] };
909
+ if (!code.includes("sibujs")) return none;
910
+ const scan = scanModule(code);
911
+ if (!scan) return none;
912
+ const factories = /* @__PURE__ */ new Map();
913
+ for (const decl of scan.imports) {
914
+ if (decl.source !== "sibujs") continue;
915
+ for (const b of decl.bindings) if (STATIC_TAGS.has(b.imported)) factories.set(b.local, b.imported);
916
+ }
917
+ if (factories.size === 0) return none;
918
+ const uses = bindingUses(code, scan, new Set(factories.keys()));
919
+ const unsafe = new Set(uses.shadowed);
920
+ for (const ref of uses.tagged) unsafe.add(ref.tok.value);
921
+ const patterns = [];
922
+ for (const { tok, list, index } of uses.calls) {
923
+ if (unsafe.has(tok.value)) continue;
924
+ const tag = factories.get(tok.value);
925
+ const call = parseCall(code, list, index + 1);
926
+ if (!call) continue;
927
+ const templateHtml = toHtml(tag, call);
928
+ if (templateHtml === null) continue;
929
+ const start = list[index].start;
930
+ patterns.push({ original: code.slice(start, call.end), tag, templateHtml, start, end: call.end });
931
+ }
932
+ return { hasStaticPatterns: patterns.length > 0, patterns };
933
+ }
934
+
935
+ // src/build/templateCompiler.ts
936
+ var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
937
+ var VOID_ELEMENTS2 = /* @__PURE__ */ new Set([
22
938
  "area",
23
939
  "base",
24
940
  "br",
@@ -57,96 +973,10 @@ var SVG_TAGS = /* @__PURE__ */ new Set([
57
973
  "symbol",
58
974
  "marker"
59
975
  ]);
60
- function findHtmlTemplates(code) {
61
- const results = [];
62
- const tagRegex = /\bhtml\s*`/g;
63
- let match;
64
- while ((match = tagRegex.exec(code)) !== null) {
65
- const start = match.index;
66
- const backtickStart = code.indexOf("`", start + 4);
67
- if (backtickStart === -1) continue;
68
- const parsed = parseTemplateLiteral(code, backtickStart);
69
- if (!parsed) continue;
70
- results.push({
71
- start,
72
- end: parsed.end,
73
- strings: parsed.strings,
74
- exprCount: parsed.exprCount
75
- });
76
- tagRegex.lastIndex = parsed.end;
77
- }
78
- return results;
79
- }
80
- function parseTemplateLiteral(code, openBacktick) {
81
- const strings = [];
82
- let exprCount = 0;
83
- let pos = openBacktick + 1;
84
- let current = "";
85
- while (pos < code.length) {
86
- const ch = code[pos];
87
- if (ch === "`") {
88
- strings.push(current);
89
- return { end: pos + 1, strings, exprCount };
90
- }
91
- if (ch === "$" && pos + 1 < code.length && code[pos + 1] === "{") {
92
- strings.push(current);
93
- current = "";
94
- exprCount++;
95
- pos += 2;
96
- let depth = 1;
97
- while (pos < code.length && depth > 0) {
98
- const c = code[pos];
99
- if (c === "{") depth++;
100
- else if (c === "}") depth--;
101
- else if (c === '"' || c === "'" || c === "`") {
102
- pos = skipString(code, pos);
103
- continue;
104
- }
105
- if (depth > 0) pos++;
106
- }
107
- if (depth !== 0) return null;
108
- pos++;
109
- continue;
110
- }
111
- if (ch === "\\") {
112
- current += code[pos] + (code[pos + 1] || "");
113
- pos += 2;
114
- continue;
115
- }
116
- current += ch;
117
- pos++;
118
- }
119
- return null;
120
- }
121
- function skipString(code, start) {
122
- const quote = code[start];
123
- let pos = start + 1;
124
- while (pos < code.length) {
125
- if (code[pos] === "\\") {
126
- pos += 2;
127
- continue;
128
- }
129
- if (code[pos] === quote) return pos + 1;
130
- if (quote === "`" && code[pos] === "$" && code[pos + 1] === "{") {
131
- pos += 2;
132
- let depth = 1;
133
- while (pos < code.length && depth > 0) {
134
- if (code[pos] === "{") depth++;
135
- else if (code[pos] === "}") depth--;
136
- else if (code[pos] === '"' || code[pos] === "'" || code[pos] === "`") {
137
- pos = skipString(code, pos);
138
- continue;
139
- }
140
- if (depth > 0) pos++;
141
- }
142
- pos++;
143
- continue;
144
- }
145
- pos++;
146
- }
147
- return pos;
148
- }
149
- function parseTemplateToAST(strings) {
976
+ var SVG_NS = "http://www.w3.org/2000/svg";
977
+ var RuntimeParseError = class extends Error {
978
+ };
979
+ function parseTemplate(strings) {
150
980
  const exprCount = strings.length - 1;
151
981
  let template = strings[0];
152
982
  for (let i = 0; i < exprCount; i++) {
@@ -155,26 +985,34 @@ function parseTemplateToAST(strings) {
155
985
  let pos = 0;
156
986
  const len = template.length;
157
987
  function skipWs() {
158
- while (pos < len && /\s/.test(template[pos])) pos++;
988
+ while (pos < len && (template[pos] === " " || template[pos] === " " || template[pos] === "\n" || template[pos] === "\r"))
989
+ pos++;
159
990
  }
160
991
  function tryExprIdx() {
161
- if (template[pos] !== "\0") return -1;
992
+ if (template.charCodeAt(pos) !== 0) return -1;
162
993
  const start = pos;
163
994
  pos++;
164
- let idxStr = "";
165
- while (pos < len && template[pos] !== "\0") idxStr += template[pos++];
995
+ let idx = 0;
996
+ while (pos < len && template.charCodeAt(pos) !== 0) {
997
+ idx = idx * 10 + (template.charCodeAt(pos) - 48);
998
+ pos++;
999
+ }
166
1000
  if (pos < len) pos++;
167
- const idx = Number.parseInt(idxStr, 10);
168
- if (Number.isNaN(idx) || idx < 0 || idx >= exprCount) {
1001
+ if (idx < 0 || idx >= exprCount) {
169
1002
  pos = start;
170
1003
  return -1;
171
1004
  }
172
1005
  return idx;
173
1006
  }
174
1007
  function readTagName() {
175
- let name = "";
176
- while (pos < len && /[a-zA-Z0-9-]/.test(template[pos])) name += template[pos++];
177
- return name;
1008
+ const start = pos;
1009
+ while (pos < len) {
1010
+ const c = template.charCodeAt(pos);
1011
+ if (c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c === 45) {
1012
+ pos++;
1013
+ } else break;
1014
+ }
1015
+ return template.slice(start, pos);
178
1016
  }
179
1017
  function parseAttrValue() {
180
1018
  skipWs();
@@ -182,51 +1020,72 @@ function parseTemplateToAST(strings) {
182
1020
  pos++;
183
1021
  skipWs();
184
1022
  const exprIdx = tryExprIdx();
185
- if (exprIdx >= 0) return { kind: "expr", index: exprIdx };
1023
+ if (exprIdx >= 0) return { kind: "expr", idx: exprIdx };
186
1024
  const quote = template[pos];
187
1025
  if (quote === '"' || quote === "'") {
188
1026
  pos++;
189
- const parts = [];
190
- let current = "";
1027
+ const statics2 = [];
1028
+ const exprs2 = [];
1029
+ let current2 = "";
191
1030
  while (pos < len && template[pos] !== quote) {
192
1031
  const innerIdx = tryExprIdx();
193
1032
  if (innerIdx >= 0) {
194
- if (current) parts.push({ kind: "static", value: current });
195
- current = "";
196
- parts.push({ kind: "expr", index: innerIdx });
1033
+ statics2.push(current2);
1034
+ current2 = "";
1035
+ exprs2.push(innerIdx);
197
1036
  } else {
198
- current += template[pos++];
1037
+ current2 += template[pos++];
199
1038
  }
200
1039
  }
201
1040
  if (pos < len) pos++;
202
- if (current) parts.push({ kind: "static", value: current });
203
- if (parts.length === 1 && parts[0].kind === "static") {
204
- return { kind: "static", value: parts[0].value };
205
- }
206
- if (parts.some((p) => p.kind === "expr")) {
207
- return { kind: "mixed", parts };
1041
+ statics2.push(current2);
1042
+ if (exprs2.length === 0) return { kind: "static", value: statics2[0] };
1043
+ return { kind: "mixed", statics: statics2, exprs: exprs2 };
1044
+ }
1045
+ const statics = [];
1046
+ const exprs = [];
1047
+ let current = "";
1048
+ while (pos < len) {
1049
+ const c = template.charCodeAt(pos);
1050
+ if (c === 32 || c === 9 || c === 10 || c === 13 || c === 62) break;
1051
+ const innerIdx = tryExprIdx();
1052
+ if (innerIdx >= 0) {
1053
+ statics.push(current);
1054
+ current = "";
1055
+ exprs.push(innerIdx);
1056
+ } else {
1057
+ current += template[pos++];
208
1058
  }
209
- return { kind: "static", value: parts.map((p) => p.value).join("") };
210
1059
  }
211
- let val = "";
212
- while (pos < len && !/[\s>/]/.test(template[pos])) val += template[pos++];
213
- return { kind: "static", value: val };
1060
+ statics.push(current);
1061
+ if (exprs.length === 0) return { kind: "static", value: statics[0] };
1062
+ return { kind: "mixed", statics, exprs };
214
1063
  }
215
1064
  function parseAttrs() {
216
1065
  const attrs = [];
217
1066
  while (pos < len) {
218
1067
  skipWs();
219
1068
  if (template[pos] === ">" || template[pos] === "/") break;
220
- let attrName = "";
221
- while (pos < len && /[a-zA-Z0-9\-:_.]/.test(template[pos])) attrName += template[pos++];
1069
+ const attrStart = pos;
1070
+ while (pos < len) {
1071
+ const c = template.charCodeAt(pos);
1072
+ if (c >= 97 && c <= 122 || c >= 65 && c <= 90 || c >= 48 && c <= 57 || c === 45 || c === 58 || c === 95 || c === 46) {
1073
+ pos++;
1074
+ } else break;
1075
+ }
1076
+ const attrName = template.slice(attrStart, pos);
222
1077
  if (!attrName) break;
223
1078
  const val = parseAttrValue();
224
1079
  if (attrName.startsWith("on:")) {
225
- if (val.kind === "expr") {
226
- attrs.push({ name: attrName.slice(3), value: { kind: "event", index: val.index } });
227
- }
1080
+ if (val.kind === "expr") attrs.push({ t: 3, name: attrName.slice(3), idx: val.idx });
1081
+ } else if (val.kind === "bool") {
1082
+ attrs.push({ t: 4, name: attrName });
1083
+ } else if (val.kind === "static") {
1084
+ attrs.push({ t: 0, name: attrName, value: val.value });
1085
+ } else if (val.kind === "expr") {
1086
+ attrs.push({ t: 1, name: attrName, idx: val.idx });
228
1087
  } else {
229
- attrs.push({ name: attrName, value: val });
1088
+ attrs.push({ t: 2, name: attrName, statics: val.statics, exprs: val.exprs });
230
1089
  }
231
1090
  }
232
1091
  return attrs;
@@ -240,40 +1099,67 @@ function parseTemplateToAST(strings) {
240
1099
  const idx = tryExprIdx();
241
1100
  if (idx >= 0) {
242
1101
  const collapsed2 = collapseWs(text);
243
- if (collapsed2) children.push({ kind: "text", value: collapsed2 });
1102
+ if (collapsed2) children.push({ t: 1, value: collapsed2 });
244
1103
  text = "";
245
- children.push({ kind: "expr", index: idx });
1104
+ children.push({ t: 2, idx });
246
1105
  } else {
247
1106
  text += template[pos++];
248
1107
  }
249
1108
  }
250
1109
  const collapsed = collapseWs(text);
251
- if (collapsed) children.push({ kind: "text", value: collapsed });
1110
+ if (collapsed) children.push({ t: 1, value: collapsed });
252
1111
  }
253
1112
  function parseChildren() {
254
1113
  const children = [];
255
1114
  while (pos < len) {
256
1115
  if (template[pos] === "<" && pos + 1 < len && template[pos + 1] === "/") break;
257
1116
  if (template[pos] === "<") {
1117
+ const next = template[pos + 1];
1118
+ if (next === "!") {
1119
+ if (template.startsWith("<!--", pos)) {
1120
+ const end = template.indexOf("-->", pos + 4);
1121
+ pos = end === -1 ? len : end + 3;
1122
+ } else if (template.startsWith("<![CDATA[", pos)) {
1123
+ const end = template.indexOf("]]>", pos + 9);
1124
+ pos = end === -1 ? len : end + 3;
1125
+ } else {
1126
+ const end = template.indexOf(">", pos);
1127
+ pos = end === -1 ? len : end + 1;
1128
+ }
1129
+ continue;
1130
+ }
1131
+ if (next === "?") {
1132
+ const end = template.indexOf(">", pos);
1133
+ pos = end === -1 ? len : end + 1;
1134
+ continue;
1135
+ }
1136
+ if (!(next >= "a" && next <= "z") && !(next >= "A" && next <= "Z")) {
1137
+ children.push({ t: 1, value: "<" });
1138
+ pos++;
1139
+ continue;
1140
+ }
258
1141
  pos++;
259
1142
  const tag = readTagName();
260
1143
  const attrs = parseAttrs();
261
1144
  skipWs();
262
- const isVoid = VOID_ELEMENTS.has(tag);
1145
+ const isVoid = VOID_ELEMENTS2.has(tag);
263
1146
  const isSelfClosing = template[pos] === "/";
264
1147
  if (isSelfClosing) pos++;
265
1148
  if (pos < len) pos++;
266
1149
  if (isVoid || isSelfClosing) {
267
- children.push({ kind: "element", el: { tag, attrs, children: [] } });
1150
+ children.push({ t: 0, el: { tag, svg: SVG_TAGS.has(tag), attrs, children: [] } });
268
1151
  } else {
269
1152
  const inner = parseChildren();
1153
+ if (RAW_TEXT_TAGS.has(tag.toLowerCase()) && inner.some((c) => c.t === 2)) {
1154
+ throw new RuntimeParseError(tag);
1155
+ }
270
1156
  if (template[pos] === "<" && pos + 1 < len && template[pos + 1] === "/") {
271
1157
  pos += 2;
272
1158
  readTagName();
273
1159
  skipWs();
274
1160
  if (pos < len && template[pos] === ">") pos++;
275
1161
  }
276
- children.push({ kind: "element", el: { tag, attrs, children: inner } });
1162
+ children.push({ t: 0, el: { tag, svg: SVG_TAGS.has(tag), attrs, children: inner } });
277
1163
  }
278
1164
  } else {
279
1165
  parseTextChildren(children);
@@ -283,303 +1169,270 @@ function parseTemplateToAST(strings) {
283
1169
  }
284
1170
  return parseChildren();
285
1171
  }
286
- function generateElement(el, valuesVar) {
287
- const tag = el.tag;
288
- const isSvg = SVG_TAGS.has(tag);
289
- const parts = [];
290
- for (const attr of el.attrs) {
291
- const v = attr.value;
292
- switch (v.kind) {
293
- case "static":
294
- parts.push(`${JSON.stringify(attr.name)}: ${JSON.stringify(v.value)}`);
295
- break;
296
- case "expr":
297
- parts.push(`${JSON.stringify(attr.name)}: ${valuesVar}[${v.index}]`);
298
- break;
299
- case "mixed": {
300
- const concat = v.parts.map((p) => p.kind === "static" ? JSON.stringify(p.value) : `String(${valuesVar}[${p.index}])`).join(" + ");
301
- parts.push(`${JSON.stringify(attr.name)}: ${concat}`);
302
- break;
1172
+ var IDL_SYNCED_ATTRS = /* @__PURE__ */ new Set(["value", "checked"]);
1173
+ function generateBody(roots, h) {
1174
+ const lines = [];
1175
+ let n = 0;
1176
+ const q = jsStringLiteral;
1177
+ const P = h.prefix;
1178
+ function genElement(el) {
1179
+ const tag = el.tag.toLowerCase();
1180
+ if (tag === "meta" || tag === "link") return null;
1181
+ for (const attr of el.attrs) {
1182
+ if ((attr.t === 0 || attr.t === 4) && attr.name.toLowerCase() === "srcdoc") return null;
1183
+ }
1184
+ const v = `e${n++}`;
1185
+ h.tags.add(el.tag);
1186
+ if (el.svg) h.svg = true;
1187
+ lines.push(
1188
+ el.svg ? `const ${v} = document.createElementNS(${q(SVG_NS)}, ${q(el.tag)});` : `const ${v} = document.createElement(${q(el.tag)});`
1189
+ );
1190
+ for (const attr of el.attrs) {
1191
+ switch (attr.t) {
1192
+ case 0:
1193
+ lines.push(`${v}.setAttribute(${q(attr.name)}, ${q(attr.value)});`);
1194
+ break;
1195
+ case 4:
1196
+ lines.push(`${v}.setAttribute(${q(attr.name)}, "");`);
1197
+ break;
1198
+ case 1:
1199
+ case 2: {
1200
+ if (IDL_SYNCED_ATTRS.has(attr.name.toLowerCase())) return null;
1201
+ h.used.add("attr");
1202
+ if (attr.t === 1) {
1203
+ lines.push(`${P}attr(${v}, ${q(attr.name)}, v${attr.idx});`);
1204
+ } else {
1205
+ h.used.add("str");
1206
+ let expr = q(attr.statics[0]);
1207
+ for (let j = 0; j < attr.exprs.length; j++) {
1208
+ expr += ` + ${P}str(v${attr.exprs[j]}) + ${q(attr.statics[j + 1])}`;
1209
+ }
1210
+ lines.push(`${P}attr(${v}, ${q(attr.name)}, ${expr});`);
1211
+ }
1212
+ break;
1213
+ }
1214
+ case 3:
1215
+ h.used.add("on");
1216
+ lines.push(`${P}on(${v}, ${q(attr.name)}, v${attr.idx});`);
1217
+ break;
1218
+ }
1219
+ }
1220
+ for (const child of el.children) {
1221
+ if (child.t === 0) {
1222
+ const c = genElement(child.el);
1223
+ if (c === null) return null;
1224
+ lines.push(`${v}.appendChild(${c});`);
1225
+ } else if (child.t === 1) {
1226
+ lines.push(`${v}.appendChild(document.createTextNode(${q(child.value)}));`);
1227
+ } else {
1228
+ h.used.add("child");
1229
+ lines.push(`${P}child(${v}, v${child.idx});`);
303
1230
  }
304
- case "bool":
305
- parts.push(`${JSON.stringify(attr.name)}: true`);
306
- break;
307
- case "event":
308
- break;
309
1231
  }
1232
+ return v;
310
1233
  }
311
- const events = el.attrs.filter((a) => a.value.kind === "event");
312
- if (events.length > 0) {
313
- const eventEntries = events.map((a) => {
314
- const v = a.value;
315
- return `${JSON.stringify(a.name)}: ${valuesVar}[${v.index}]`;
316
- });
317
- parts.push(`on: { ${eventEntries.join(", ")} }`);
1234
+ if (roots.length === 1 && roots[0].t === 0) {
1235
+ const root = genElement(roots[0].el);
1236
+ if (root === null) return null;
1237
+ lines.push(`return ${root};`);
1238
+ return lines.join("\n ");
318
1239
  }
319
- if (el.children.length > 0) {
320
- const childExprs = el.children.map((c) => generateChild(c, valuesVar));
321
- if (childExprs.length === 1) {
322
- parts.push(`nodes: ${childExprs[0]}`);
1240
+ lines.push(`const w = document.createElement("div");`);
1241
+ for (const root of roots) {
1242
+ if (root.t === 0) {
1243
+ const c = genElement(root.el);
1244
+ if (c === null) return null;
1245
+ lines.push(`w.appendChild(${c});`);
1246
+ } else if (root.t === 1) {
1247
+ lines.push(`w.appendChild(document.createTextNode(${q(root.value)}));`);
323
1248
  } else {
324
- parts.push(`nodes: [${childExprs.join(", ")}]`);
1249
+ return null;
325
1250
  }
326
1251
  }
327
- const propsStr = parts.length > 0 ? `{ ${parts.join(", ")} }` : void 0;
328
- if (isSvg) {
329
- return propsStr ? `__sbTagFactory(${JSON.stringify(tag)}, __sbSVG_NS)(${propsStr})` : `__sbTagFactory(${JSON.stringify(tag)}, __sbSVG_NS)({})`;
330
- }
331
- return propsStr ? `${tag}(${propsStr})` : `${tag}({})`;
1252
+ lines.push("return w;");
1253
+ return lines.join("\n ");
332
1254
  }
333
- function generateChild(child, valuesVar) {
334
- switch (child.kind) {
335
- case "element":
336
- return generateElement(child.el, valuesVar);
337
- case "text":
338
- return JSON.stringify(child.value);
339
- case "expr":
340
- return `${valuesVar}[${child.index}]`;
1255
+ function helperSource(h) {
1256
+ const P = h.prefix;
1257
+ const out = [];
1258
+ if (h.used.has("attr")) {
1259
+ out.push(
1260
+ `function ${P}attr(el, name, value) {
1261
+ const teardown = ${P}bindAttrs(el, { [name]: value });
1262
+ if (typeof value === "function") ${P}registerDisposer(el, teardown);
1263
+ }`
1264
+ );
341
1265
  }
342
- }
343
- function compileHtmlTemplates(code) {
344
- const templates = findHtmlTemplates(code);
345
- if (templates.length === 0) {
346
- return { code: null, usedTags: /* @__PURE__ */ new Set(), usesSvg: false, compiledCount: 0 };
347
- }
348
- const usedTags = /* @__PURE__ */ new Set();
349
- let usesSvg = false;
350
- let result = code;
351
- for (let i = templates.length - 1; i >= 0; i--) {
352
- const tmpl = templates[i];
353
- const ast = parseTemplateToAST(tmpl.strings);
354
- collectTags(ast, usedTags);
355
- if (ast.length > 1) usedTags.add("div");
356
- if (Array.from(usedTags).some((t) => SVG_TAGS.has(t))) usesSvg = true;
357
- const valuesVar = "__v";
358
- const childExprs = ast.map((c) => generateChild(c, valuesVar));
359
- const rootExpr = childExprs.length === 1 ? childExprs[0] : `div([${childExprs.join(", ")}])`;
360
- let compiled;
361
- if (tmpl.exprCount === 0) {
362
- compiled = rootExpr;
363
- } else {
364
- const body = rootExpr;
365
- const exprSource = extractExpressions(code, tmpl.start, tmpl.end, tmpl.exprCount);
366
- compiled = `((${valuesVar}) => ${body})([${exprSource.join(", ")}])`;
1266
+ if (h.used.has("str")) {
1267
+ out.push(`function ${P}str(value) {
1268
+ return value == null ? "" : String(value);
1269
+ }`);
1270
+ }
1271
+ if (h.used.has("on")) {
1272
+ out.push(
1273
+ `function ${P}on(el, name, handler) {
1274
+ if (typeof handler === "function") el.addEventListener(name, handler);
1275
+ else if (typeof __SIBU_DEV__ !== "undefined" && __SIBU_DEV__) {
1276
+ console.warn(\`[SibuJS] html: on:\${name} handler is not a function (got \${typeof handler}). Event listener was not attached.\`);
1277
+ }
1278
+ }`
1279
+ );
1280
+ }
1281
+ if (h.used.has("child")) {
1282
+ out.push(
1283
+ `function ${P}child(el, value) {
1284
+ if (typeof value === "function") {
1285
+ const frag = ${P}Fragment([value]);
1286
+ const ph = frag.firstChild;
1287
+ el.appendChild(frag);
1288
+ ${P}registerDisposer(el, () => ${P}dispose(ph));
1289
+ } else if (value instanceof Node) {
1290
+ el.appendChild(value);
1291
+ } else if (Array.isArray(value)) {
1292
+ for (let i = 0; i < value.length; i++) {
1293
+ const item = value[i];
1294
+ if (item instanceof Node) el.appendChild(item);
1295
+ else if (item != null && typeof item !== "boolean") el.appendChild(document.createTextNode(String(item)));
367
1296
  }
368
- result = result.slice(0, tmpl.start) + compiled + result.slice(tmpl.end);
1297
+ } else if (value != null && typeof value !== "boolean") {
1298
+ el.appendChild(document.createTextNode(String(value)));
369
1299
  }
370
- return { code: result, usedTags, usesSvg, compiledCount: templates.length };
1300
+ }`
1301
+ );
1302
+ }
1303
+ return out.join("\n");
371
1304
  }
372
- function collectTags(children, tags) {
1305
+ function importSource(h) {
1306
+ const P = h.prefix;
1307
+ const core = [];
1308
+ if (h.used.has("child")) core.push(`Fragment as ${P}Fragment`, `dispose as ${P}dispose`);
1309
+ if (h.used.has("attr") || h.used.has("child")) core.push(`registerDisposer as ${P}registerDisposer`);
1310
+ if (h.used.has("run")) core.push(`__renderParsedTemplate as ${P}run`);
1311
+ const lines = [];
1312
+ if (core.length > 0) lines.push(`import { ${core.join(", ")} } from "sibujs";`);
1313
+ if (h.used.has("attr")) lines.push(`import { bindAttrs as ${P}bindAttrs } from "sibujs/ui";`);
1314
+ return lines.join("\n");
1315
+ }
1316
+ function collectTags(children, h) {
373
1317
  for (const child of children) {
374
- if (child.kind === "element") {
375
- tags.add(child.el.tag);
376
- collectTags(child.el.children, tags);
377
- }
1318
+ if (child.t !== 0) continue;
1319
+ h.tags.add(child.el.tag);
1320
+ if (child.el.svg) h.svg = true;
1321
+ collectTags(child.el.children, h);
378
1322
  }
379
1323
  }
380
- function extractExpressions(code, templateStart, templateEnd, count) {
381
- const exprs = [];
382
- const backtickStart = code.indexOf("`", templateStart + 4);
383
- let pos = backtickStart + 1;
384
- for (let i = 0; i < count; i++) {
385
- while (pos < templateEnd) {
386
- if (code[pos] === "$" && code[pos + 1] === "{") {
387
- pos += 2;
388
- break;
389
- }
390
- if (code[pos] === "\\") {
391
- pos += 2;
1324
+ function planHtmlTemplates(code) {
1325
+ const plan = {
1326
+ edits: [],
1327
+ append: "",
1328
+ usedTags: /* @__PURE__ */ new Set(),
1329
+ usesSvg: false,
1330
+ compiledCount: 0,
1331
+ skippedCount: 0
1332
+ };
1333
+ if (!code.includes("`") || !code.includes("sibujs")) return plan;
1334
+ const scan = scanModule(code);
1335
+ if (!scan) return plan;
1336
+ const tagNames = /* @__PURE__ */ new Set();
1337
+ for (const decl of scan.imports) {
1338
+ if (!isSibuSource(decl.source)) continue;
1339
+ for (const b of decl.bindings) if (b.imported === "html") tagNames.add(b.local);
1340
+ }
1341
+ if (tagNames.size === 0) return plan;
1342
+ const uses = bindingUses(code, scan, tagNames);
1343
+ if (uses.shadowed.size > 0 || uses.calls.length > 0 || uses.tagged.length === 0) return plan;
1344
+ const sites = new Set(uses.tagged.map((ref) => ref.tok));
1345
+ const h = { prefix: uniquePrefix(code), used: /* @__PURE__ */ new Set(), tags: /* @__PURE__ */ new Set(), svg: false };
1346
+ const functions = [];
1347
+ const compileTemplate = (tmpl) => {
1348
+ const strings = [];
1349
+ for (const qs of tmpl.quasis) {
1350
+ const cooked = cookEscapes(code.slice(qs.start, qs.end));
1351
+ if (cooked === null) {
1352
+ if (tmpl.quasis.length === 1) return null;
1353
+ strings.push("undefined");
392
1354
  continue;
393
1355
  }
394
- pos++;
1356
+ strings.push(cooked);
395
1357
  }
396
- const exprStart = pos;
397
- let depth = 1;
398
- while (pos < templateEnd && depth > 0) {
399
- const c = code[pos];
400
- if (c === "{") depth++;
401
- else if (c === "}") {
402
- depth--;
403
- if (depth === 0) break;
404
- } else if (c === '"' || c === "'" || c === "`") {
405
- pos = skipString(code, pos);
406
- continue;
1358
+ const name = `${h.prefix}t${functions.length}`;
1359
+ const params = tmpl.exprs.map((_, i) => `v${i}`).join(", ");
1360
+ let roots;
1361
+ try {
1362
+ roots = parseTemplate(strings);
1363
+ } catch (err) {
1364
+ if (err instanceof RuntimeParseError) {
1365
+ const message = `html: dynamic \${...} expressions are not allowed inside <${err.message}> (raw-text context). Build the content separately and append it as a Node.`;
1366
+ functions.push(`function ${name}(${params}) {
1367
+ throw new Error(${jsStringLiteral(message)});
1368
+ }`);
1369
+ return name;
407
1370
  }
408
- pos++;
1371
+ throw err;
409
1372
  }
410
- exprs.push(code.slice(exprStart, pos).trim());
411
- pos++;
412
- }
413
- return exprs;
414
- }
415
-
416
- // src/build/staticAnalysis.ts
417
- var HTML_TAGS = /* @__PURE__ */ new Set([
418
- "div",
419
- "span",
420
- "section",
421
- "article",
422
- "header",
423
- "footer",
424
- "nav",
425
- "main",
426
- "aside",
427
- "p",
428
- "h1",
429
- "h2",
430
- "h3",
431
- "h4",
432
- "h5",
433
- "h6",
434
- "blockquote",
435
- "li",
436
- "ol",
437
- "ul",
438
- "pre",
439
- "a",
440
- "b",
441
- "em",
442
- "i",
443
- "strong",
444
- "small",
445
- "code",
446
- "mark",
447
- "img",
448
- "br",
449
- "hr",
450
- "input",
451
- "button",
452
- "form",
453
- "label",
454
- "select",
455
- "textarea",
456
- "option",
457
- "table",
458
- "tbody",
459
- "thead",
460
- "tfoot",
461
- "tr",
462
- "td",
463
- "th",
464
- "details",
465
- "summary",
466
- "dialog"
467
- ]);
468
- var VOID_ELEMENTS2 = /* @__PURE__ */ new Set([
469
- "br",
470
- "hr",
471
- "img",
472
- "input",
473
- "meta",
474
- "link",
475
- "area",
476
- "base",
477
- "col",
478
- "embed",
479
- "param",
480
- "source",
481
- "track",
482
- "wbr"
483
- ]);
484
- function analyzeStaticTemplates(code) {
485
- const patterns = [];
486
- const tagCallRegex = new RegExp(`\\b(${Array.from(HTML_TAGS).join("|")})\\s*\\(\\s*\\{([^}]*)\\}\\s*\\)`, "g");
487
- let match;
488
- while ((match = tagCallRegex.exec(code)) !== null) {
489
- const [fullMatch, tag, propsContent] = match;
490
- const start = match.index;
491
- const end = start + fullMatch.length;
492
- if (isStaticPropsContent(propsContent)) {
493
- const templateHtml = propsToHtml(tag, propsContent);
494
- if (templateHtml) {
495
- patterns.push({ original: fullMatch, tag, templateHtml, start, end });
496
- }
1373
+ const scratch = { prefix: h.prefix, used: /* @__PURE__ */ new Set(), tags: /* @__PURE__ */ new Set(), svg: false };
1374
+ const body = generateBody(roots, scratch);
1375
+ if (body === null) {
1376
+ const tree = JSON.stringify(roots).replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
1377
+ h.used.add("run");
1378
+ collectTags(roots, h);
1379
+ functions.push(
1380
+ `function ${name}(${params}) {
1381
+ return ${h.prefix}run(${name}.tree || (${name}.tree = ${tree}), [${params}]);
1382
+ }`
1383
+ );
1384
+ return name;
497
1385
  }
498
- }
499
- return {
500
- hasStaticPatterns: patterns.length > 0,
501
- patterns
1386
+ for (const u of scratch.used) h.used.add(u);
1387
+ for (const t of scratch.tags) h.tags.add(t);
1388
+ if (scratch.svg) h.svg = true;
1389
+ functions.push(`function ${name}(${params}) {
1390
+ ${body}
1391
+ }`);
1392
+ return name;
502
1393
  };
503
- }
504
- function isStaticPropsContent(propsContent) {
505
- if (/=>|function\s*\(|\bref\b|\bon\s*:/.test(propsContent)) {
506
- return false;
507
- }
508
- const props = propsContent.split(",").map((p) => p.trim()).filter(Boolean);
509
- for (const prop of props) {
510
- const colonIndex = prop.indexOf(":");
511
- if (colonIndex === -1) continue;
512
- const value = prop.substring(colonIndex + 1).trim();
513
- if (!isStaticValue(value)) {
514
- return false;
1394
+ const replaceSite = (tag, tmpl, name) => {
1395
+ const edit = (start, end, before, after) => plan.edits.push({ start, end, text: `${before}${lineBreaksIn(code, start, end)}${after}` });
1396
+ const exprs = tmpl.exprs;
1397
+ if (exprs.length === 0) {
1398
+ edit(tag.start, tmpl.end, `${name}(`, ")");
1399
+ return;
515
1400
  }
516
- }
517
- return true;
518
- }
519
- function isStaticValue(value) {
520
- if (/^["'].*["']$/.test(value)) return true;
521
- if (/^-?\d+(\.\d+)?$/.test(value)) return true;
522
- if (value === "true" || value === "false") return true;
523
- if (value === "null" || value === "undefined") return true;
524
- return false;
525
- }
526
- function propsToHtml(tag, propsContent) {
527
- const attrs = [];
528
- let nodesContent = "";
529
- const props = propsContent.split(",").map((p) => p.trim()).filter(Boolean);
530
- for (const prop of props) {
531
- const colonIndex = prop.indexOf(":");
532
- if (colonIndex === -1) continue;
533
- const key = prop.substring(0, colonIndex).trim();
534
- let value = prop.substring(colonIndex + 1).trim();
535
- if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
536
- value = value.slice(1, -1);
537
- }
538
- if (key === "nodes") {
539
- nodesContent = escapeHtml(value);
540
- } else if (key === "class" || key === "id") {
541
- attrs.push(`${key}="${escapeAttr(value)}"`);
542
- } else if (key !== "on" && key !== "ref" && key !== "style") {
543
- attrs.push(`${key}="${escapeAttr(String(value))}"`);
1401
+ edit(tag.start, exprs[0].start, `${name}((`, "");
1402
+ for (let i = 1; i < exprs.length; i++) edit(exprs[i - 1].end, exprs[i].start, ")", ", (");
1403
+ edit(exprs[exprs.length - 1].end, tmpl.end, "", "))");
1404
+ };
1405
+ const visit = (list) => {
1406
+ for (let i = 0; i < list.length; i++) {
1407
+ const tok = list[i];
1408
+ if (sites.has(tok)) {
1409
+ const tmpl = list[i + 1];
1410
+ for (const e of tmpl.exprs) visit(e.tokens);
1411
+ const name = compileTemplate(tmpl);
1412
+ if (name !== null) {
1413
+ plan.compiledCount++;
1414
+ replaceSite(tok, tmpl, name);
1415
+ } else {
1416
+ plan.skippedCount++;
1417
+ }
1418
+ i++;
1419
+ } else if (tok.type === "template") {
1420
+ for (const e of tok.exprs) visit(e.tokens);
1421
+ }
544
1422
  }
545
- }
546
- const attrStr = attrs.length > 0 ? ` ${attrs.join(" ")}` : "";
547
- if (VOID_ELEMENTS2.has(tag)) {
548
- return `<${tag}${attrStr} />`;
549
- }
550
- return `<${tag}${attrStr}>${nodesContent}</${tag}>`;
551
- }
552
- function escapeHtml(str) {
553
- return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
554
- }
555
- function escapeAttr(str) {
556
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
1423
+ };
1424
+ visit(scan.tokens);
1425
+ if (plan.compiledCount === 0) return { ...plan, edits: [] };
1426
+ const trailer = [importSource(h), helperSource(h), ...functions].filter(Boolean).join("\n");
1427
+ plan.append = `
1428
+ ${trailer}
1429
+ `;
1430
+ plan.usedTags = h.tags;
1431
+ plan.usesSvg = h.svg;
1432
+ return plan;
557
1433
  }
558
1434
 
559
1435
  // src/build/vite.ts
560
- var SVG_TAGS_SET = /* @__PURE__ */ new Set([
561
- "svg",
562
- "circle",
563
- "ellipse",
564
- "g",
565
- "line",
566
- "path",
567
- "polygon",
568
- "polyline",
569
- "rect",
570
- "text",
571
- "tspan",
572
- "defs",
573
- "clipPath",
574
- "mask",
575
- "pattern",
576
- "linearGradient",
577
- "radialGradient",
578
- "stop",
579
- "use",
580
- "symbol",
581
- "marker"
582
- ]);
583
1436
  var DEFAULT_INCLUDE = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"];
584
1437
  var DEFAULT_EXCLUDE = ["node_modules/**", "dist/**", "**/*.test.*", "**/*.spec.*"];
585
1438
  function matchesPattern(filePath, patterns) {
@@ -589,30 +1442,42 @@ function matchesPattern(filePath, patterns) {
589
1442
  return new RegExp(regexStr).test(normalized);
590
1443
  });
591
1444
  }
592
- function injectPureAnnotations(code) {
593
- const sibuFactories = [
594
- "tagFactory",
595
- "context",
596
- "defineComponent",
597
- "withProps",
598
- "withDefaults",
599
- "pure",
600
- "noSideEffect"
601
- ];
602
- let result = code;
603
- for (const factory of sibuFactories) {
604
- const pattern = new RegExp(`(?<!/\\*#__PURE__\\*/\\s*)\\b(${factory})\\s*\\(`, "g");
605
- result = result.replace(pattern, "/*#__PURE__*/ $1(");
1445
+ function devPrologueEdit(code) {
1446
+ let at = 0;
1447
+ if (code.startsWith("#!")) {
1448
+ const nl = code.indexOf("\n");
1449
+ if (nl === -1) return null;
1450
+ at = nl + 1;
606
1451
  }
607
- return result;
1452
+ return {
1453
+ start: at,
1454
+ end: at,
1455
+ text: '/* SibuJS Dev Mode */ if (typeof globalThis !== "undefined") { globalThis.__SIBU_DEV__ = true; } '
1456
+ };
608
1457
  }
609
- function injectDevHelpers(code) {
610
- if (code.includes('from "sibu"') || code.includes("from 'sibu'") || code.includes('from "sibu/') || code.includes("from 'sibu/")) {
611
- return `/* SibuJS Dev Mode */
612
- if (typeof globalThis !== 'undefined') { (globalThis as unknown as Record<string, unknown>).__SIBU_DEV__ = true; }
613
- ${code}`;
614
- }
615
- return code;
1458
+ function staticOptimizationEdits(code) {
1459
+ const analysis = analyzeStaticTemplates(code);
1460
+ if (!analysis.hasStaticPatterns) return null;
1461
+ const P = uniquePrefix(code);
1462
+ const edits = analysis.patterns.map((pattern) => ({
1463
+ start: pattern.start,
1464
+ end: pattern.end,
1465
+ // A call spanning several lines keeps its line breaks.
1466
+ text: `${P}static(${jsStringLiteral(pattern.templateHtml)}${lineBreaksIn(code, pattern.start, pattern.end)})`
1467
+ }));
1468
+ const append = `
1469
+ import { staticTemplate as ${P}staticTemplate } from "sibujs/performance";
1470
+ function ${P}static(markup) {
1471
+ return document.adoptNode(${P}staticTemplate(markup));
1472
+ }
1473
+ `;
1474
+ return { edits, append };
1475
+ }
1476
+ function resolveDevMode(explicit, info) {
1477
+ if (explicit !== void 0) return explicit;
1478
+ if (info?.command === "build") return info.mode === "development";
1479
+ if (info?.command === "serve") return true;
1480
+ return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
616
1481
  }
617
1482
  function sibuVitePlugin(options = {}) {
618
1483
  const {
@@ -621,22 +1486,23 @@ function sibuVitePlugin(options = {}) {
621
1486
  include = DEFAULT_INCLUDE,
622
1487
  exclude = DEFAULT_EXCLUDE,
623
1488
  devMode,
624
- staticOptimize,
1489
+ staticOptimize = false,
625
1490
  compileTemplates
626
1491
  } = options;
627
- const isDevMode = devMode ?? (typeof process !== "undefined" && process.env?.NODE_ENV !== "production");
1492
+ let isDevMode = resolveDevMode(devMode, void 0);
628
1493
  return {
629
1494
  name: "sibu-vite-plugin",
630
1495
  enforce: "pre",
631
- config() {
1496
+ config(_userConfig, env) {
1497
+ isDevMode = resolveDevMode(devMode, env);
632
1498
  return {
633
- // Optimize dependency pre-bundling for sibu
1499
+ // Optimize dependency pre-bundling for sibujs
634
1500
  optimizeDeps: {
635
- include: ["sibu"]
1501
+ include: ["sibujs"]
636
1502
  },
637
- // Ensure sibu is treated correctly for SSR
1503
+ // Ensure sibujs is treated correctly for SSR
638
1504
  ssr: {
639
- noExternal: ["sibu"]
1505
+ noExternal: ["sibujs"]
640
1506
  },
641
1507
  // Define global constants for dead code elimination
642
1508
  define: {
@@ -649,69 +1515,47 @@ function sibuVitePlugin(options = {}) {
649
1515
  }
650
1516
  };
651
1517
  },
1518
+ configResolved(config) {
1519
+ isDevMode = resolveDevMode(devMode, config);
1520
+ },
652
1521
  transform(code, id) {
653
1522
  if (!matchesPattern(id, include) || matchesPattern(id, exclude)) {
654
1523
  return null;
655
1524
  }
656
- let transformed = code;
657
- let modified = false;
658
- if (pureAnnotations) {
659
- const annotated = injectPureAnnotations(transformed);
660
- if (annotated !== transformed) {
661
- transformed = annotated;
662
- modified = true;
663
- }
1525
+ if (!code.includes("sibujs")) return null;
1526
+ if (!scanModule(code)) return null;
1527
+ const edits = [];
1528
+ let append = "";
1529
+ if (isDevMode && importsSibu(code)) {
1530
+ const prologue = devPrologueEdit(code);
1531
+ if (prologue) edits.push(prologue);
664
1532
  }
665
- if (isDevMode) {
666
- const withDevHelpers = injectDevHelpers(transformed);
667
- if (withDevHelpers !== transformed) {
668
- transformed = withDevHelpers;
669
- modified = true;
670
- }
1533
+ if (pureAnnotations) {
1534
+ edits.push(...pureAnnotationEdits(code));
671
1535
  }
672
1536
  const shouldCompile = compileTemplates ?? !isDevMode;
673
- if (shouldCompile && transformed.includes("html`")) {
674
- const compiled = compileHtmlTemplates(transformed);
675
- if (compiled.code) {
676
- const tagImports = Array.from(compiled.usedTags).filter((t) => !SVG_TAGS_SET.has(t));
677
- const needsSvg = compiled.usesSvg;
678
- const imports = [];
679
- if (tagImports.length > 0) {
680
- imports.push(`import { ${tagImports.join(", ")} } from "sibu";`);
681
- }
682
- if (needsSvg) {
683
- imports.push(`import { tagFactory as __sbTagFactory, SVG_NS as __sbSVG_NS } from "sibu";`);
684
- }
685
- const newImports = imports.filter((imp) => !transformed.includes(imp));
686
- if (newImports.length > 0) {
687
- compiled.code = `${newImports.join("\n")}
688
- ${compiled.code}`;
689
- }
690
- transformed = compiled.code;
691
- modified = true;
1537
+ if (shouldCompile) {
1538
+ const plan = planHtmlTemplates(code);
1539
+ if (plan.compiledCount > 0) {
1540
+ edits.push(...plan.edits);
1541
+ append += plan.append;
692
1542
  }
693
1543
  }
694
- const shouldOptimize = staticOptimize ?? !isDevMode;
695
- if (shouldOptimize) {
696
- const analysis = analyzeStaticTemplates(transformed);
697
- if (analysis.hasStaticPatterns) {
698
- const sorted = [...analysis.patterns].sort((a, b) => b.start - a.start);
699
- for (const pattern of sorted) {
700
- const replacement = `staticTemplate(${JSON.stringify(pattern.templateHtml)})`;
701
- transformed = transformed.slice(0, pattern.start) + replacement + transformed.slice(pattern.end);
702
- }
703
- if (!transformed.includes("import") || !transformed.includes("staticTemplate")) {
704
- transformed = `import { staticTemplate } from "sibu";
705
- ${transformed}`;
706
- }
707
- modified = true;
1544
+ if (staticOptimize) {
1545
+ const optimized = staticOptimizationEdits(code);
1546
+ if (optimized) {
1547
+ edits.push(...optimized.edits);
1548
+ append += optimized.append;
708
1549
  }
709
1550
  }
710
- if (!modified) return null;
1551
+ if (edits.length === 0 && append === "") return null;
1552
+ const sorted = normalizeEdits(edits);
1553
+ if (!sorted) return null;
1554
+ const transformed = applyEdits(code, sorted, append);
1555
+ if (transformed === code) return null;
711
1556
  return {
712
1557
  code: transformed,
713
- map: void 0
714
- // Let Vite handle source maps
1558
+ map: editsSourceMap(code, sorted, append, id)
715
1559
  };
716
1560
  },
717
1561
  handleHotUpdate(ctx) {
@@ -770,7 +1614,7 @@ function createViteConfig(options = {}) {
770
1614
  // SSR configuration
771
1615
  ...ssr ? {
772
1616
  ssr: {
773
- noExternal: ["sibu"],
1617
+ noExternal: ["sibujs"],
774
1618
  target: "node"
775
1619
  },
776
1620
  build: {
@@ -787,8 +1631,8 @@ function createViteConfig(options = {}) {
787
1631
  } : {},
788
1632
  // Optimize dependency handling
789
1633
  optimizeDeps: {
790
- include: ["sibu"],
791
- // Force pre-bundling of sibu for faster dev startup
1634
+ include: ["sibujs"],
1635
+ // Force pre-bundling of sibujs for faster dev startup
792
1636
  force: false
793
1637
  },
794
1638
  // Environment variable handling
@@ -811,29 +1655,19 @@ function deepMerge(target, source) {
811
1655
  }
812
1656
 
813
1657
  // src/build/webpack.ts
814
- var PURE_FACTORIES = [
815
- "tagFactory",
816
- "context",
817
- "defineComponent",
818
- "withProps",
819
- "withDefaults",
820
- "pure",
821
- "noSideEffect"
822
- ];
823
1658
  function addPureAnnotations(source) {
824
- let result = source;
825
- for (const factory of PURE_FACTORIES) {
826
- const pattern = new RegExp(`(?<!/\\*#__PURE__\\*/\\s*)\\b(${factory})\\s*\\(`, "g");
827
- result = result.replace(pattern, "/*#__PURE__*/ $1(");
828
- }
829
- return result;
1659
+ return injectPureAnnotations(source);
830
1660
  }
831
1661
  function sibuWebpackPlugin(options = {}) {
832
- const { pureAnnotations = true, devMode } = options;
833
- const isDevMode = devMode ?? (typeof process !== "undefined" && process.env?.NODE_ENV !== "production");
1662
+ const { devMode } = options;
834
1663
  return {
835
1664
  name: "SibuWebpackPlugin",
836
1665
  apply(compiler) {
1666
+ if (options.pureAnnotations === true) {
1667
+ console.warn(
1668
+ '[SibuWebpackPlugin] `pureAnnotations` is not applied by the plugin: webpack needs a loader file. Create sibu-pure-loader.cjs containing `module.exports = require("sibujs/build").createPureAnnotationsLoader();` and add a module rule `{ test: /\\.[cm]?[jt]sx?$/, exclude: /node_modules/, use: "./sibu-pure-loader.cjs" }`.'
1669
+ );
1670
+ }
837
1671
  compiler.hooks?.compilation?.tap("SibuWebpackPlugin", (compilation) => {
838
1672
  const comp = compilation;
839
1673
  if (comp.hooks?.optimizeModules) {
@@ -841,31 +1675,6 @@ function sibuWebpackPlugin(options = {}) {
841
1675
  });
842
1676
  }
843
1677
  });
844
- if (pureAnnotations) {
845
- compiler.hooks?.afterEnvironment?.tap("SibuWebpackPlugin", () => {
846
- if (!compiler.options.module) {
847
- compiler.options.module = { rules: [] };
848
- }
849
- if (!compiler.options.module.rules) {
850
- compiler.options.module.rules = [];
851
- }
852
- compiler.options.module.rules.push({
853
- test: /\.[jt]sx?$/,
854
- exclude: /node_modules/,
855
- enforce: "pre",
856
- use: [
857
- {
858
- loader: {
859
- // Inline loader function
860
- ident: "sibu-pure-annotations-loader",
861
- loader: "__sibu_inline_loader__",
862
- options: {}
863
- }
864
- }
865
- ]
866
- });
867
- });
868
- }
869
1678
  compiler.hooks?.afterResolvers?.tap("SibuWebpackPlugin", () => {
870
1679
  if (!compiler.options.resolve) {
871
1680
  compiler.options.resolve = {};
@@ -877,20 +1686,21 @@ function sibuWebpackPlugin(options = {}) {
877
1686
  compiler.options.resolve.mainFields.unshift("module");
878
1687
  }
879
1688
  });
880
- if (isDevMode) {
881
- compiler.hooks?.done?.tap("SibuWebpackPlugin", (stats) => {
882
- const statsObj = stats;
883
- const info = statsObj?.toJson?.({ modules: false, chunks: false });
884
- if (info) {
885
- console.log(`[SibuWebpackPlugin] Build completed in ${info.time || 0}ms`);
886
- const warnings = info.warnings;
887
- if (warnings?.length) {
888
- console.log(`[SibuWebpackPlugin] ${warnings.length} warning(s)`);
889
- }
1689
+ const tapDoneLogger = () => compiler.hooks?.done?.tap("SibuWebpackPlugin", (stats) => {
1690
+ const statsObj = stats;
1691
+ const info = statsObj?.toJson?.({ modules: false, chunks: false });
1692
+ if (info) {
1693
+ console.log(`[SibuWebpackPlugin] Build completed in ${info.time || 0}ms`);
1694
+ const warnings = info.warnings;
1695
+ if (warnings?.length) {
1696
+ console.log(`[SibuWebpackPlugin] ${warnings.length} warning(s)`);
890
1697
  }
891
- });
892
- }
1698
+ }
1699
+ });
1700
+ if (devMode === true) tapDoneLogger();
893
1701
  compiler.hooks?.environment?.tap("SibuWebpackPlugin", () => {
1702
+ const isDevMode = devMode ?? resolveWebpackDevMode(compiler.options);
1703
+ if (devMode === void 0 && isDevMode) tapDoneLogger();
894
1704
  if (!compiler.options.plugins) {
895
1705
  compiler.options.plugins = [];
896
1706
  }
@@ -898,10 +1708,20 @@ function sibuWebpackPlugin(options = {}) {
898
1708
  __SIBU_DEV__: JSON.stringify(isDevMode)
899
1709
  };
900
1710
  compiler.__sibuDefines = defines;
1711
+ const DefinePlugin = compiler.webpack?.DefinePlugin;
1712
+ if (DefinePlugin) {
1713
+ new DefinePlugin(defines).apply(compiler);
1714
+ }
901
1715
  });
902
1716
  }
903
1717
  };
904
1718
  }
1719
+ function resolveWebpackDevMode(options) {
1720
+ const mode = options.mode;
1721
+ if (mode === "development") return true;
1722
+ if (mode === "production" || mode === void 0) return false;
1723
+ return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
1724
+ }
905
1725
  function createPureAnnotationsLoader() {
906
1726
  return function sibuPureAnnotationsLoader(source) {
907
1727
  return addPureAnnotations(source);
@@ -970,9 +1790,10 @@ function createWebpackConfig(options = {}) {
970
1790
  splitChunks: isDev ? false : {
971
1791
  chunks: "all",
972
1792
  cacheGroups: {
973
- // Separate sibu framework code into its own chunk
1793
+ // Separate sibujs framework code into its own chunk (the package
1794
+ // directory is `sibujs`; matching `sibu` never selected anything)
974
1795
  sibu: {
975
- test: /[\\/]node_modules[\\/]sibu[\\/]/,
1796
+ test: /[\\/]node_modules[\\/]sibujs[\\/]/,
976
1797
  name: "sibu",
977
1798
  chunks: "all",
978
1799
  priority: 20
@@ -1013,7 +1834,23 @@ function createWebpackConfig(options = {}) {
1013
1834
  }
1014
1835
 
1015
1836
  // src/build/cdn.ts
1016
- var PACKAGE_NAME = "sibu";
1837
+ var PACKAGE_NAME = "sibujs";
1838
+ var SUBPATH_ENTRIES = [
1839
+ "data",
1840
+ "browser",
1841
+ "patterns",
1842
+ "motion",
1843
+ "ui",
1844
+ "widgets",
1845
+ "ssr",
1846
+ "devtools",
1847
+ "performance",
1848
+ "ecosystem",
1849
+ "plugins",
1850
+ "build",
1851
+ "testing",
1852
+ "extras"
1853
+ ];
1017
1854
  function registerGlobal() {
1018
1855
  if (typeof window === "undefined") return;
1019
1856
  window.Sibu = { ...index_exports };
@@ -1059,7 +1896,7 @@ var cdnUrls = {
1059
1896
  * @example
1060
1897
  * ```ts
1061
1898
  * cdnUrls.scriptTag('jsdelivr', '1.0.0')
1062
- * // => '<script src="https://cdn.jsdelivr.net/npm/sibu@1.0.0/dist/cdn.global.js"></script>'
1899
+ * // => '<script src="https://cdn.jsdelivr.net/npm/sibujs@1.0.0/dist/cdn.global.js"></script>'
1063
1900
  * ```
1064
1901
  */
1065
1902
  scriptTag: (provider = "jsdelivr", version) => {
@@ -1077,15 +1914,11 @@ function generateImportMap(baseUrl) {
1077
1914
  const base = baseUrl || `https://cdn.jsdelivr.net/npm/${PACKAGE_NAME}@latest`;
1078
1915
  const imports = {
1079
1916
  // Main package entry
1080
- [PACKAGE_NAME]: `${base}/dist/index.js`,
1081
- // Sub-path imports for tree-shaking in browsers
1082
- [`${PACKAGE_NAME}/core`]: `${base}/dist/core/index.js`,
1083
- [`${PACKAGE_NAME}/reactivity`]: `${base}/dist/reactivity/index.js`,
1084
- [`${PACKAGE_NAME}/plugins`]: `${base}/dist/plugins/index.js`,
1085
- [`${PACKAGE_NAME}/components`]: `${base}/dist/components/index.js`,
1086
- [`${PACKAGE_NAME}/testing`]: `${base}/dist/testing/index.js`,
1087
- [`${PACKAGE_NAME}/build`]: `${base}/dist/build/index.js`
1917
+ [PACKAGE_NAME]: `${base}/dist/index.js`
1088
1918
  };
1919
+ for (const entry of SUBPATH_ENTRIES) {
1920
+ imports[`${PACKAGE_NAME}/${entry}`] = `${base}/dist/${entry}.js`;
1921
+ }
1089
1922
  return {
1090
1923
  imports,
1091
1924
  /**
@@ -1168,9 +2001,9 @@ function generateTsConfig(options) {
1168
2001
  if (paths && Object.keys(paths).length > 0) {
1169
2002
  compilerOptions.baseUrl = ".";
1170
2003
  compilerOptions.paths = {
1171
- // Default sibu alias
1172
- sibu: ["node_modules/sibu/dist/index.d.ts"],
1173
- "sibu/*": ["node_modules/sibu/dist/*"],
2004
+ // Default sibujs alias
2005
+ sibujs: ["node_modules/sibujs/dist/index.d.ts"],
2006
+ "sibujs/*": ["node_modules/sibujs/dist/*"],
1174
2007
  // User-provided paths
1175
2008
  ...paths
1176
2009
  };
@@ -2284,6 +3117,19 @@ function generateTypeStubs() {
2284
3117
  };
2285
3118
  }
2286
3119
 
3120
+ // src/build/compileTemplates.ts
3121
+ function compileHtmlTemplates(code) {
3122
+ const plan = planHtmlTemplates(code);
3123
+ const edits = plan.compiledCount > 0 ? normalizeEdits(plan.edits) : null;
3124
+ return {
3125
+ code: edits ? applyEdits(code, edits, plan.append) : null,
3126
+ usedTags: plan.usedTags,
3127
+ usesSvg: plan.usesSvg,
3128
+ compiledCount: edits ? plan.compiledCount : 0,
3129
+ skippedCount: plan.skippedCount
3130
+ };
3131
+ }
3132
+
2287
3133
  // src/build/routeSplitting.ts
2288
3134
  function fileToRoute(relativePath) {
2289
3135
  const basename = relativePath.split("/").pop() || "";
@@ -2339,7 +3185,7 @@ function generateRouteModule(entries, routesDir) {
2339
3185
  (e, i) => `const route${i} = () => import(/* webpackChunkName: "${e.chunkName}" */ "${routesDir}/${e.importPath}");`
2340
3186
  ).join("\n");
2341
3187
  const routes = entries.map((e, i) => ` { path: "${e.path}", component: lazy(route${i}) }`).join(",\n");
2342
- return `import { lazy } from "sibu";
3188
+ return `import { lazy } from "sibujs";
2343
3189
 
2344
3190
  ${imports}
2345
3191