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