sibujs 1.5.0 → 2.0.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/dist/browser.cjs +238 -69
- package/dist/browser.d.cts +5 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.js +6 -6
- package/dist/build.cjs +916 -292
- package/dist/build.js +15 -13
- package/dist/cdn.global.js +17 -16
- package/dist/chunk-2RA7SHDA.js +65 -0
- package/dist/chunk-2UPRY23K.js +80 -0
- package/dist/chunk-3JHCYHWN.js +125 -0
- package/dist/{chunk-VAPYJN4X.js → chunk-3LR7GLWQ.js} +93 -23
- package/dist/{chunk-RJ46C3CS.js → chunk-3NSGB5JN.js} +71 -20
- package/dist/{chunk-XUEEGU5O.js → chunk-52YJLLRO.js} +16 -4
- package/dist/{chunk-XHK6BDAJ.js → chunk-54EDRCEF.js} +25 -8
- package/dist/chunk-7JDB7I65.js +1327 -0
- package/dist/{chunk-WZSPOOER.js → chunk-CC65Y57T.js} +8 -5
- package/dist/{chunk-23VV7YD3.js → chunk-DFPFITST.js} +25 -30
- package/dist/{chunk-BGN5ZMP4.js → chunk-GTBNNBJ6.js} +14 -2
- package/dist/chunk-HB24TBAF.js +121 -0
- package/dist/{chunk-CZUGLNJS.js → chunk-ITX6OO3F.js} +3 -3
- package/dist/{chunk-BGTHZHJ5.js → chunk-JA6667UN.js} +188 -44
- package/dist/{chunk-7GRNSCFT.js → chunk-JXMMDLBY.js} +306 -183
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-SFKNRVCU.js → chunk-KLRMB5ZS.js} +135 -79
- package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
- package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
- package/dist/{chunk-BMPL52BF.js → chunk-MIUAXB7K.js} +118 -66
- package/dist/{chunk-JCDUJN2F.js → chunk-ND2664SF.js} +486 -153
- package/dist/{chunk-VQDZK23A.js → chunk-O2MNQFLP.js} +181 -66
- package/dist/{chunk-NHUC2QWH.js → chunk-R73P76YZ.js} +1 -1
- package/dist/{chunk-2BYQDGN3.js → chunk-SAHNHTFC.js} +234 -63
- package/dist/chunk-UCS6AMJ7.js +79 -0
- package/dist/{chunk-K4G4ZQNR.js → chunk-VLPPXTYG.js} +84 -38
- package/dist/{chunk-OUZZEE4S.js → chunk-WOMYAHHI.js} +17 -11
- package/dist/{customElement-BL3Uo8dL.d.cts → customElement-CPfIrbvg.d.cts} +14 -10
- package/dist/{customElement-BL3Uo8dL.d.ts → customElement-CPfIrbvg.d.ts} +14 -10
- package/dist/data.cjs +410 -99
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +513 -223
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +12 -6
- package/dist/ecosystem.cjs +475 -144
- package/dist/ecosystem.d.cts +9 -7
- package/dist/ecosystem.d.ts +9 -7
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3355 -1541
- package/dist/extras.d.cts +9 -9
- package/dist/extras.d.ts +9 -9
- package/dist/extras.js +58 -45
- package/dist/index.cjs +920 -292
- package/dist/index.d.cts +71 -8
- package/dist/index.d.ts +71 -8
- package/dist/index.js +28 -16
- package/dist/{introspect-BumjnBKr.d.cts → introspect-BWNjNw64.d.cts} +22 -2
- package/dist/{introspect-CZrlcaYy.d.ts → introspect-cY2pg9pW.d.ts} +22 -2
- package/dist/motion.cjs +77 -34
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +335 -69
- package/dist/patterns.d.cts +11 -12
- package/dist/patterns.d.ts +11 -12
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +279 -108
- package/dist/performance.d.cts +23 -16
- package/dist/performance.d.ts +23 -16
- package/dist/performance.js +13 -8
- package/dist/plugin-D30wlGW5.d.cts +71 -0
- package/dist/plugin-D30wlGW5.d.ts +71 -0
- package/dist/plugins.cjs +635 -260
- package/dist/plugins.d.cts +10 -3
- package/dist/plugins.d.ts +10 -3
- package/dist/plugins.js +106 -38
- package/dist/{ssr-Do_SiVoL.d.cts → ssr-CrVNy6Pa.d.cts} +9 -15
- package/dist/{ssr-Do_SiVoL.d.ts → ssr-CrVNy6Pa.d.ts} +9 -15
- package/dist/{ssr-4PBXAOO3.js → ssr-FXD2PPMC.js} +4 -3
- package/dist/ssr.cjs +642 -222
- package/dist/ssr.d.cts +26 -6
- package/dist/ssr.d.ts +26 -6
- package/dist/ssr.js +12 -11
- package/dist/{tagFactory-DaJ0YWX6.d.cts → tagFactory-S17H2qxu.d.cts} +9 -1
- package/dist/{tagFactory-DaJ0YWX6.d.ts → tagFactory-S17H2qxu.d.ts} +9 -1
- package/dist/testing.cjs +252 -63
- package/dist/testing.d.cts +17 -4
- package/dist/testing.d.ts +17 -4
- package/dist/testing.js +100 -44
- package/dist/ui.cjs +463 -137
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +977 -94
- package/dist/widgets.d.cts +104 -2
- package/dist/widgets.d.ts +104 -2
- package/dist/widgets.js +9 -7
- package/package.json +8 -2
- package/dist/chunk-32DY64NT.js +0 -282
- package/dist/chunk-3AIRKM3B.js +0 -1263
- package/dist/chunk-3ARAQO7B.js +0 -398
- package/dist/chunk-3CRQALYP.js +0 -877
- package/dist/chunk-4EI4AG32.js +0 -482
- package/dist/chunk-4MYMUBRS.js +0 -21
- package/dist/chunk-5ZYQ6KDD.js +0 -154
- package/dist/chunk-6BMPXPUW.js +0 -26
- package/dist/chunk-6HLLIF3K.js +0 -398
- package/dist/chunk-6LSNVCS2.js +0 -937
- package/dist/chunk-6SA3QQES.js +0 -61
- package/dist/chunk-77L6NL3X.js +0 -1097
- package/dist/chunk-7BF6TK55.js +0 -1097
- package/dist/chunk-7TQKR4PP.js +0 -294
- package/dist/chunk-7V26P53V.js +0 -712
- package/dist/chunk-AZ3ISID5.js +0 -298
- package/dist/chunk-B7SWRFUT.js +0 -332
- package/dist/chunk-BTU3TJDS.js +0 -365
- package/dist/chunk-BW3WT46K.js +0 -937
- package/dist/chunk-C6KFWOFV.js +0 -616
- package/dist/chunk-CHF5OHIA.js +0 -61
- package/dist/chunk-CHJ27IGK.js +0 -26
- package/dist/chunk-CMBFNA7L.js +0 -27
- package/dist/chunk-DAHRH4ON.js +0 -331
- package/dist/chunk-DKOHBI74.js +0 -924
- package/dist/chunk-DTCOOBMX.js +0 -725
- package/dist/chunk-EBGIRKQY.js +0 -616
- package/dist/chunk-EUZND3CB.js +0 -27
- package/dist/chunk-EVCZO745.js +0 -365
- package/dist/chunk-EWFVA3TJ.js +0 -282
- package/dist/chunk-F3FA4F32.js +0 -292
- package/dist/chunk-FGOEVHY3.js +0 -60
- package/dist/chunk-G3BOQPVO.js +0 -365
- package/dist/chunk-GCOK2LC3.js +0 -282
- package/dist/chunk-GJPXRJ45.js +0 -37
- package/dist/chunk-HGMJFBC7.js +0 -654
- package/dist/chunk-JAKHTMQU.js +0 -1000
- package/dist/chunk-JCI5M6U6.js +0 -956
- package/dist/chunk-K5ZUMYVS.js +0 -89
- package/dist/chunk-KQPDEVVS.js +0 -398
- package/dist/chunk-L6JRBDNS.js +0 -60
- package/dist/chunk-LA6KQEDU.js +0 -712
- package/dist/chunk-MB6QFH3I.js +0 -2776
- package/dist/chunk-MDVXJWFN.js +0 -304
- package/dist/chunk-MEZVEBPN.js +0 -2008
- package/dist/chunk-MK4ERFYL.js +0 -2249
- package/dist/chunk-MLKGABMK.js +0 -9
- package/dist/chunk-MQ5GOYPH.js +0 -2249
- package/dist/chunk-MYRV7VDM.js +0 -742
- package/dist/chunk-N6IZB6KJ.js +0 -567
- package/dist/chunk-NEKUBFPT.js +0 -60
- package/dist/chunk-NMRUZALC.js +0 -1097
- package/dist/chunk-NYVAC6P5.js +0 -37
- package/dist/chunk-NZIIMDWI.js +0 -84
- package/dist/chunk-OF7UZIVB.js +0 -725
- package/dist/chunk-P3XWXJZU.js +0 -282
- package/dist/chunk-P6W3STU4.js +0 -2249
- package/dist/chunk-PBHF5WKN.js +0 -616
- package/dist/chunk-PDZQY43A.js +0 -616
- package/dist/chunk-PTQJDMRT.js +0 -146
- package/dist/chunk-PZEGYCF5.js +0 -61
- package/dist/chunk-QBMDLBU2.js +0 -975
- package/dist/chunk-QWZG56ET.js +0 -2744
- package/dist/chunk-RQGQSLQK.js +0 -725
- package/dist/chunk-SDLZDHKP.js +0 -107
- package/dist/chunk-TDGZL5CU.js +0 -365
- package/dist/chunk-TNQWPPE6.js +0 -37
- package/dist/chunk-TSOKIX5Z.js +0 -654
- package/dist/chunk-UHNL42EF.js +0 -2730
- package/dist/chunk-UNXCEF6S.js +0 -21
- package/dist/chunk-V2XTI523.js +0 -347
- package/dist/chunk-VAU366PN.js +0 -2241
- package/dist/chunk-VMVDTCXB.js +0 -712
- package/dist/chunk-VQNQZCWJ.js +0 -61
- package/dist/chunk-VRW3FULF.js +0 -725
- package/dist/chunk-WADYRCO2.js +0 -304
- package/dist/chunk-WILQZRO4.js +0 -282
- package/dist/chunk-WR5D4EGH.js +0 -26
- package/dist/chunk-WUHJISPP.js +0 -298
- package/dist/chunk-XYU6TZOW.js +0 -182
- package/dist/chunk-Y6GP4QGG.js +0 -276
- package/dist/chunk-YECR7UIA.js +0 -347
- package/dist/chunk-YUTWTI4B.js +0 -654
- package/dist/chunk-Z65KYU7I.js +0 -26
- package/dist/chunk-Z6POF5YC.js +0 -975
- package/dist/chunk-ZBJP6WFL.js +0 -482
- package/dist/chunk-ZD6OAMTH.js +0 -277
- package/dist/chunk-ZWKZCBO6.js +0 -317
- package/dist/contracts-DDrwxvJ-.d.cts +0 -245
- package/dist/contracts-DDrwxvJ-.d.ts +0 -245
- package/dist/contracts-DOrhwbke.d.cts +0 -245
- package/dist/contracts-DOrhwbke.d.ts +0 -245
- package/dist/contracts-xo5ckdRP.d.cts +0 -240
- package/dist/contracts-xo5ckdRP.d.ts +0 -240
- package/dist/customElement-BKQfbSZQ.d.cts +0 -262
- package/dist/customElement-BKQfbSZQ.d.ts +0 -262
- package/dist/customElement-D2DJp_xn.d.cts +0 -313
- package/dist/customElement-D2DJp_xn.d.ts +0 -313
- package/dist/customElement-yz8uyk-0.d.cts +0 -308
- package/dist/customElement-yz8uyk-0.d.ts +0 -308
- package/dist/introspect-Cb0zgpi2.d.cts +0 -477
- package/dist/introspect-Y2xNXGSf.d.ts +0 -477
- package/dist/plugin-Bek4RhJY.d.cts +0 -43
- package/dist/plugin-Bek4RhJY.d.ts +0 -43
- package/dist/ssr-3RXHP5ES.js +0 -38
- package/dist/ssr-6GIMY5MX.js +0 -38
- package/dist/ssr-BA6sxxUd.d.cts +0 -135
- package/dist/ssr-BA6sxxUd.d.ts +0 -135
- package/dist/ssr-WKUPVSSK.js +0 -36
- package/dist/tagFactory-Dl8QCLga.d.cts +0 -23
- package/dist/tagFactory-Dl8QCLga.d.ts +0 -23
package/dist/index.cjs
CHANGED
|
@@ -99,6 +99,7 @@ __export(index_exports, {
|
|
|
99
99
|
footer: () => footer,
|
|
100
100
|
form: () => form,
|
|
101
101
|
g: () => g,
|
|
102
|
+
getSSRStore: () => getSSRStore,
|
|
102
103
|
getSlot: () => getSlot,
|
|
103
104
|
h1: () => h1,
|
|
104
105
|
h2: () => h2,
|
|
@@ -171,6 +172,7 @@ __export(index_exports, {
|
|
|
171
172
|
rp: () => rp,
|
|
172
173
|
rt: () => rt,
|
|
173
174
|
ruby: () => ruby,
|
|
175
|
+
runInSSRContext: () => runInSSRContext,
|
|
174
176
|
s: () => s,
|
|
175
177
|
samp: () => samp,
|
|
176
178
|
script: () => script,
|
|
@@ -196,6 +198,7 @@ __export(index_exports, {
|
|
|
196
198
|
symbol: () => symbol,
|
|
197
199
|
table: () => table,
|
|
198
200
|
tagFactory: () => tagFactory,
|
|
201
|
+
takePendingError: () => takePendingError,
|
|
199
202
|
tbody: () => tbody,
|
|
200
203
|
td: () => td,
|
|
201
204
|
template: () => template,
|
|
@@ -210,6 +213,7 @@ __export(index_exports, {
|
|
|
210
213
|
track: () => track2,
|
|
211
214
|
transition: () => transition,
|
|
212
215
|
trapFocus: () => trapFocus,
|
|
216
|
+
trustHTML: () => trustHTML,
|
|
213
217
|
tspan: () => tspan,
|
|
214
218
|
u: () => u,
|
|
215
219
|
ul: () => ul,
|
|
@@ -232,33 +236,80 @@ function isDev() {
|
|
|
232
236
|
var _isDev = isDev();
|
|
233
237
|
function devAssert(condition, message) {
|
|
234
238
|
if (_isDev && !condition) {
|
|
235
|
-
throw new Error(`[
|
|
239
|
+
throw new Error(`[SibuJS] ${message}`);
|
|
236
240
|
}
|
|
237
241
|
}
|
|
238
242
|
function devWarn(message) {
|
|
239
243
|
if (_isDev) {
|
|
240
|
-
console.warn(`[
|
|
244
|
+
console.warn(`[SibuJS] ${message}`);
|
|
241
245
|
}
|
|
242
246
|
}
|
|
243
247
|
|
|
244
248
|
// src/utils/sanitize.ts
|
|
249
|
+
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
245
250
|
function sanitizeUrl(url) {
|
|
246
251
|
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
247
252
|
if (!trimmed) return "";
|
|
248
253
|
const lower = trimmed.toLowerCase();
|
|
249
|
-
|
|
250
|
-
|
|
254
|
+
let schemeEnd = -1;
|
|
255
|
+
for (let i2 = 0; i2 < lower.length; i2++) {
|
|
256
|
+
const ch = lower.charCodeAt(i2);
|
|
257
|
+
if (ch === 58) {
|
|
258
|
+
schemeEnd = i2;
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
251
262
|
}
|
|
263
|
+
if (schemeEnd === -1) return trimmed;
|
|
264
|
+
const scheme = lower.slice(0, schemeEnd + 1);
|
|
265
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return trimmed;
|
|
266
|
+
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
252
267
|
return trimmed;
|
|
253
268
|
}
|
|
269
|
+
function sanitizeSrcset(value) {
|
|
270
|
+
const parts = value.split(",");
|
|
271
|
+
const out = [];
|
|
272
|
+
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
273
|
+
const part = parts[i2].trim();
|
|
274
|
+
if (!part) continue;
|
|
275
|
+
const m = part.match(/^(\S+)(\s+.+)?$/);
|
|
276
|
+
if (!m) continue;
|
|
277
|
+
const safe = sanitizeUrl(m[1]);
|
|
278
|
+
if (!safe) continue;
|
|
279
|
+
out.push(m[2] ? `${safe}${m[2]}` : safe);
|
|
280
|
+
}
|
|
281
|
+
return out.join(", ");
|
|
282
|
+
}
|
|
254
283
|
function sanitizeCSSValue(value) {
|
|
255
|
-
const
|
|
256
|
-
|
|
284
|
+
const decoded = value.replace(/\\([0-9a-fA-F]{1,6})\s?/g, (_m, hex) => {
|
|
285
|
+
const code2 = Number.parseInt(hex, 16);
|
|
286
|
+
if (!Number.isFinite(code2) || code2 < 0 || code2 > 1114111) return "";
|
|
287
|
+
try {
|
|
288
|
+
return String.fromCodePoint(code2);
|
|
289
|
+
} catch {
|
|
290
|
+
return "";
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
const lower = decoded.toLowerCase().replace(/\s+/g, "");
|
|
294
|
+
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("vbscript:") || lower.includes("-moz-binding") || lower.includes("behavior:") || lower.includes("@import") || lower.includes("image-set(") || lower.includes("filter:progid")) {
|
|
257
295
|
return "";
|
|
258
296
|
}
|
|
259
297
|
return value;
|
|
260
298
|
}
|
|
261
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
299
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
300
|
+
"href",
|
|
301
|
+
"xlink:href",
|
|
302
|
+
"src",
|
|
303
|
+
"action",
|
|
304
|
+
"formaction",
|
|
305
|
+
"formtarget",
|
|
306
|
+
"cite",
|
|
307
|
+
"poster",
|
|
308
|
+
"background",
|
|
309
|
+
"srcset",
|
|
310
|
+
"ping",
|
|
311
|
+
"data"
|
|
312
|
+
]);
|
|
262
313
|
function isUrlAttribute(attr) {
|
|
263
314
|
return URL_ATTRIBUTES.has(attr);
|
|
264
315
|
}
|
|
@@ -269,11 +320,11 @@ var subscriberStack = new Array(32);
|
|
|
269
320
|
var stackCapacity = 32;
|
|
270
321
|
var stackTop = -1;
|
|
271
322
|
var currentSubscriber = null;
|
|
272
|
-
var signalSubscribers = /* @__PURE__ */ new WeakMap();
|
|
273
323
|
var SUBS = "__s";
|
|
274
324
|
var notifyDepth = 0;
|
|
275
325
|
var pendingQueue = [];
|
|
276
326
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
327
|
+
var propagateStack = [];
|
|
277
328
|
function safeInvoke(sub2) {
|
|
278
329
|
try {
|
|
279
330
|
sub2();
|
|
@@ -283,6 +334,15 @@ function safeInvoke(sub2) {
|
|
|
283
334
|
}
|
|
284
335
|
var suspendDepth = 0;
|
|
285
336
|
var trackingSuspended = false;
|
|
337
|
+
function retrack(effectFn, subscriber) {
|
|
338
|
+
const prev = currentSubscriber;
|
|
339
|
+
currentSubscriber = subscriber;
|
|
340
|
+
try {
|
|
341
|
+
effectFn();
|
|
342
|
+
} finally {
|
|
343
|
+
currentSubscriber = prev;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
286
346
|
function track(effectFn, subscriber) {
|
|
287
347
|
if (!subscriber) subscriber = effectFn;
|
|
288
348
|
cleanup(subscriber);
|
|
@@ -350,7 +410,6 @@ function recordDependency(signal2) {
|
|
|
350
410
|
let subs = signal2[SUBS];
|
|
351
411
|
if (!subs) {
|
|
352
412
|
subs = /* @__PURE__ */ new Set();
|
|
353
|
-
signalSubscribers.set(signal2, subs);
|
|
354
413
|
signal2[SUBS] = subs;
|
|
355
414
|
}
|
|
356
415
|
subs.add(currentSubscriber);
|
|
@@ -372,17 +431,17 @@ function queueSignalNotification(signal2) {
|
|
|
372
431
|
}
|
|
373
432
|
}
|
|
374
433
|
}
|
|
375
|
-
var
|
|
434
|
+
var maxDrainIterations = 1e5;
|
|
376
435
|
function drainNotificationQueue() {
|
|
377
436
|
if (notifyDepth > 0) return;
|
|
378
437
|
notifyDepth++;
|
|
379
438
|
try {
|
|
380
439
|
let i2 = 0;
|
|
381
440
|
while (i2 < pendingQueue.length) {
|
|
382
|
-
if (i2 >=
|
|
441
|
+
if (i2 >= maxDrainIterations) {
|
|
383
442
|
if (typeof console !== "undefined") {
|
|
384
443
|
console.error(
|
|
385
|
-
`[SibuJS] Notification queue exceeded ${
|
|
444
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
386
445
|
);
|
|
387
446
|
}
|
|
388
447
|
break;
|
|
@@ -391,47 +450,52 @@ function drainNotificationQueue() {
|
|
|
391
450
|
i2++;
|
|
392
451
|
}
|
|
393
452
|
} finally {
|
|
394
|
-
pendingQueue.length = 0;
|
|
395
|
-
pendingSet.clear();
|
|
396
453
|
notifyDepth--;
|
|
454
|
+
if (notifyDepth === 0) {
|
|
455
|
+
pendingQueue.length = 0;
|
|
456
|
+
pendingSet.clear();
|
|
457
|
+
}
|
|
397
458
|
}
|
|
398
459
|
}
|
|
399
460
|
function propagateDirty(sub2) {
|
|
400
461
|
sub2();
|
|
401
|
-
|
|
402
|
-
|
|
462
|
+
const rootSig = sub2._sig;
|
|
463
|
+
if (!rootSig) return;
|
|
464
|
+
const stack = propagateStack;
|
|
465
|
+
const baseLen = stack.length;
|
|
466
|
+
stack.push(rootSig);
|
|
467
|
+
while (stack.length > baseLen) {
|
|
468
|
+
const sig = stack.pop();
|
|
403
469
|
const first = sig.__f;
|
|
404
470
|
if (first) {
|
|
405
471
|
if (first._c) {
|
|
406
472
|
const nSig = first._sig;
|
|
407
|
-
nSig._d
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
if (!pendingSet.has(first)) {
|
|
473
|
+
if (!nSig._d) {
|
|
474
|
+
nSig._d = true;
|
|
475
|
+
stack.push(nSig);
|
|
476
|
+
}
|
|
477
|
+
} else if (!pendingSet.has(first)) {
|
|
412
478
|
pendingSet.add(first);
|
|
413
479
|
pendingQueue.push(first);
|
|
414
480
|
}
|
|
415
|
-
|
|
481
|
+
continue;
|
|
416
482
|
}
|
|
417
483
|
const subs = sig[SUBS];
|
|
418
|
-
if (!subs)
|
|
419
|
-
let nextSig;
|
|
484
|
+
if (!subs) continue;
|
|
420
485
|
for (const s2 of subs) {
|
|
421
486
|
if (s2._c) {
|
|
422
|
-
s2();
|
|
423
487
|
const nSig = s2._sig;
|
|
424
|
-
if (nSig && !
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
488
|
+
if (nSig && !nSig._d) {
|
|
489
|
+
nSig._d = true;
|
|
490
|
+
stack.push(nSig);
|
|
491
|
+
} else if (!nSig) {
|
|
492
|
+
s2();
|
|
428
493
|
}
|
|
429
494
|
} else if (!pendingSet.has(s2)) {
|
|
430
495
|
pendingSet.add(s2);
|
|
431
496
|
pendingQueue.push(s2);
|
|
432
497
|
}
|
|
433
498
|
}
|
|
434
|
-
sig = nextSig;
|
|
435
499
|
}
|
|
436
500
|
}
|
|
437
501
|
function notifySubscribers(signal2) {
|
|
@@ -455,13 +519,23 @@ function notifySubscribers(signal2) {
|
|
|
455
519
|
}
|
|
456
520
|
let i2 = 0;
|
|
457
521
|
while (i2 < pendingQueue.length) {
|
|
522
|
+
if (i2 >= maxDrainIterations) {
|
|
523
|
+
if (typeof console !== "undefined") {
|
|
524
|
+
console.error(
|
|
525
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
break;
|
|
529
|
+
}
|
|
458
530
|
safeInvoke(pendingQueue[i2]);
|
|
459
531
|
i2++;
|
|
460
532
|
}
|
|
461
533
|
} finally {
|
|
462
|
-
pendingQueue.length = 0;
|
|
463
|
-
pendingSet.clear();
|
|
464
534
|
notifyDepth--;
|
|
535
|
+
if (notifyDepth === 0) {
|
|
536
|
+
pendingQueue.length = 0;
|
|
537
|
+
pendingSet.clear();
|
|
538
|
+
}
|
|
465
539
|
}
|
|
466
540
|
return;
|
|
467
541
|
}
|
|
@@ -481,30 +555,48 @@ function notifySubscribers(signal2) {
|
|
|
481
555
|
notifyDepth++;
|
|
482
556
|
try {
|
|
483
557
|
let directCount = 0;
|
|
558
|
+
let hasComputedSub = false;
|
|
484
559
|
for (const sub2 of subs) {
|
|
560
|
+
if (sub2._c) hasComputedSub = true;
|
|
485
561
|
pendingQueue[directCount++] = sub2;
|
|
486
562
|
}
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
563
|
+
if (!hasComputedSub) {
|
|
564
|
+
for (let i3 = 0; i3 < directCount; i3++) {
|
|
565
|
+
safeInvoke(pendingQueue[i3]);
|
|
490
566
|
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
567
|
+
} else {
|
|
568
|
+
for (let i3 = 0; i3 < directCount; i3++) {
|
|
569
|
+
if (pendingQueue[i3]._c) {
|
|
570
|
+
propagateDirty(pendingQueue[i3]);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
for (let i3 = 0; i3 < directCount; i3++) {
|
|
574
|
+
const sub2 = pendingQueue[i3];
|
|
575
|
+
if (!sub2._c && !pendingSet.has(sub2)) {
|
|
576
|
+
pendingSet.add(sub2);
|
|
577
|
+
safeInvoke(sub2);
|
|
496
578
|
}
|
|
497
579
|
}
|
|
498
580
|
}
|
|
499
581
|
let i2 = directCount;
|
|
500
582
|
while (i2 < pendingQueue.length) {
|
|
583
|
+
if (i2 - directCount >= maxDrainIterations) {
|
|
584
|
+
if (typeof console !== "undefined") {
|
|
585
|
+
console.error(
|
|
586
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
break;
|
|
590
|
+
}
|
|
501
591
|
safeInvoke(pendingQueue[i2]);
|
|
502
592
|
i2++;
|
|
503
593
|
}
|
|
504
594
|
} finally {
|
|
505
|
-
pendingQueue.length = 0;
|
|
506
|
-
pendingSet.clear();
|
|
507
595
|
notifyDepth--;
|
|
596
|
+
if (notifyDepth === 0) {
|
|
597
|
+
pendingQueue.length = 0;
|
|
598
|
+
pendingSet.clear();
|
|
599
|
+
}
|
|
508
600
|
}
|
|
509
601
|
}
|
|
510
602
|
function cleanup(subscriber) {
|
|
@@ -515,7 +607,9 @@ function cleanup(subscriber) {
|
|
|
515
607
|
if (subs) {
|
|
516
608
|
subs.delete(subscriber);
|
|
517
609
|
if (singleDep.__f === subscriber) {
|
|
518
|
-
singleDep.__f = void 0;
|
|
610
|
+
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
611
|
+
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
612
|
+
singleDep.__f = subs.values().next().value;
|
|
519
613
|
}
|
|
520
614
|
}
|
|
521
615
|
sub2._dep = void 0;
|
|
@@ -528,7 +622,9 @@ function cleanup(subscriber) {
|
|
|
528
622
|
if (subs) {
|
|
529
623
|
subs.delete(subscriber);
|
|
530
624
|
if (signal2.__f === subscriber) {
|
|
531
|
-
signal2.__f = void 0;
|
|
625
|
+
signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
626
|
+
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
627
|
+
signal2.__f = subs.values().next().value;
|
|
532
628
|
}
|
|
533
629
|
}
|
|
534
630
|
}
|
|
@@ -537,6 +633,9 @@ function cleanup(subscriber) {
|
|
|
537
633
|
|
|
538
634
|
// src/reactivity/bindAttribute.ts
|
|
539
635
|
var _isDev3 = isDev();
|
|
636
|
+
function setProp(el, key, val) {
|
|
637
|
+
el[key] = val;
|
|
638
|
+
}
|
|
540
639
|
function isEventHandlerAttr(name) {
|
|
541
640
|
if (name.length < 3) return false;
|
|
542
641
|
const lower = name.toLowerCase();
|
|
@@ -562,7 +661,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
562
661
|
}
|
|
563
662
|
if (typeof value === "boolean") {
|
|
564
663
|
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
565
|
-
el
|
|
664
|
+
setProp(el, attr, value);
|
|
566
665
|
} else if (value) {
|
|
567
666
|
el.setAttribute(attr, "");
|
|
568
667
|
} else {
|
|
@@ -572,7 +671,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
572
671
|
}
|
|
573
672
|
const str = String(value);
|
|
574
673
|
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
575
|
-
el
|
|
674
|
+
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
576
675
|
} else {
|
|
577
676
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
578
677
|
}
|
|
@@ -603,7 +702,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
603
702
|
}
|
|
604
703
|
const str = String(value);
|
|
605
704
|
if ((name === "value" || name === "checked") && name in el) {
|
|
606
|
-
el
|
|
705
|
+
setProp(el, name, name === "checked" ? Boolean(value) : str);
|
|
607
706
|
} else {
|
|
608
707
|
el.setAttribute(name, isUrlAttribute(name) ? sanitizeUrl(str) : str);
|
|
609
708
|
}
|
|
@@ -646,24 +745,29 @@ function bindChildNode(placeholder, getter) {
|
|
|
646
745
|
let newNodes;
|
|
647
746
|
if (Array.isArray(result)) {
|
|
648
747
|
newNodes = [];
|
|
748
|
+
const seen = /* @__PURE__ */ new Set();
|
|
649
749
|
for (let i2 = 0; i2 < result.length; i2++) {
|
|
650
750
|
const item = result[i2];
|
|
651
751
|
if (item == null || typeof item === "boolean") continue;
|
|
652
|
-
|
|
752
|
+
const node = item instanceof Node ? item : document.createTextNode(String(item));
|
|
753
|
+
if (seen.has(node)) {
|
|
754
|
+
if (_isDev4)
|
|
755
|
+
devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
756
|
+
continue;
|
|
757
|
+
}
|
|
758
|
+
seen.add(node);
|
|
759
|
+
newNodes.push(node);
|
|
653
760
|
}
|
|
654
761
|
} else {
|
|
655
762
|
const node = result instanceof Node ? result : document.createTextNode(String(result));
|
|
656
763
|
newNodes = [node];
|
|
657
764
|
}
|
|
658
|
-
|
|
659
|
-
if (
|
|
765
|
+
let reused;
|
|
766
|
+
if (lastNodes.length > 0 && newNodes.length > 0) {
|
|
767
|
+
const lastSet = new Set(lastNodes);
|
|
768
|
+
reused = /* @__PURE__ */ new Set();
|
|
660
769
|
for (let i2 = 0; i2 < newNodes.length; i2++) {
|
|
661
|
-
|
|
662
|
-
if (newNodes[i2] === lastNodes[j]) {
|
|
663
|
-
reused.add(newNodes[i2]);
|
|
664
|
-
break;
|
|
665
|
-
}
|
|
666
|
-
}
|
|
770
|
+
if (lastSet.has(newNodes[i2])) reused.add(newNodes[i2]);
|
|
667
771
|
}
|
|
668
772
|
}
|
|
669
773
|
for (let i2 = 0; i2 < lastNodes.length; i2++) {
|
|
@@ -706,7 +810,7 @@ function dispose(node) {
|
|
|
706
810
|
while (stack.length > 0) {
|
|
707
811
|
const current = stack.pop();
|
|
708
812
|
order.push(current);
|
|
709
|
-
const children = current.childNodes;
|
|
813
|
+
const children = Array.from(current.childNodes);
|
|
710
814
|
for (let i2 = 0; i2 < children.length; i2++) {
|
|
711
815
|
stack.push(children[i2]);
|
|
712
816
|
}
|
|
@@ -715,8 +819,10 @@ function dispose(node) {
|
|
|
715
819
|
const current = order[i2];
|
|
716
820
|
const disposers = elementDisposers.get(current);
|
|
717
821
|
if (disposers) {
|
|
718
|
-
|
|
719
|
-
|
|
822
|
+
const snapshot = disposers.slice();
|
|
823
|
+
elementDisposers.delete(current);
|
|
824
|
+
if (_isDev5) activeBindingCount -= snapshot.length;
|
|
825
|
+
for (const d of snapshot) {
|
|
720
826
|
try {
|
|
721
827
|
d();
|
|
722
828
|
} catch (err) {
|
|
@@ -725,7 +831,23 @@ function dispose(node) {
|
|
|
725
831
|
}
|
|
726
832
|
}
|
|
727
833
|
}
|
|
728
|
-
|
|
834
|
+
let extraPasses = 0;
|
|
835
|
+
while (extraPasses++ < 8) {
|
|
836
|
+
const added = elementDisposers.get(current);
|
|
837
|
+
if (!added || added.length === 0) break;
|
|
838
|
+
const moreSnapshot = added.slice();
|
|
839
|
+
elementDisposers.delete(current);
|
|
840
|
+
if (_isDev5) activeBindingCount -= moreSnapshot.length;
|
|
841
|
+
for (const d of moreSnapshot) {
|
|
842
|
+
try {
|
|
843
|
+
d();
|
|
844
|
+
} catch (err) {
|
|
845
|
+
if (_isDev5 && typeof console !== "undefined") {
|
|
846
|
+
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
}
|
|
729
851
|
}
|
|
730
852
|
}
|
|
731
853
|
}
|
|
@@ -741,6 +863,30 @@ function checkLeaks(warnThreshold = 0) {
|
|
|
741
863
|
|
|
742
864
|
// src/core/rendering/tagFactory.ts
|
|
743
865
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
866
|
+
var _isDev6 = isDev();
|
|
867
|
+
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
868
|
+
function validateTagName(tag) {
|
|
869
|
+
const lower = tag.toLowerCase();
|
|
870
|
+
if (BLOCKED_TAGS.has(lower)) {
|
|
871
|
+
throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
875
|
+
"config",
|
|
876
|
+
"location",
|
|
877
|
+
"history",
|
|
878
|
+
"document",
|
|
879
|
+
"window",
|
|
880
|
+
"navigator",
|
|
881
|
+
"name",
|
|
882
|
+
"top",
|
|
883
|
+
"parent",
|
|
884
|
+
"self",
|
|
885
|
+
"frames"
|
|
886
|
+
]);
|
|
887
|
+
function setProp2(el, key, val) {
|
|
888
|
+
el[key] = val;
|
|
889
|
+
}
|
|
744
890
|
var kebabCache = /* @__PURE__ */ new Map();
|
|
745
891
|
function toKebab(prop) {
|
|
746
892
|
let cached = kebabCache.get(prop);
|
|
@@ -865,79 +1011,103 @@ function appendChildren(el, nodes) {
|
|
|
865
1011
|
}
|
|
866
1012
|
}
|
|
867
1013
|
}
|
|
868
|
-
var tagFactory = (tag, ns) =>
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
if (
|
|
873
|
-
|
|
874
|
-
|
|
1014
|
+
var tagFactory = (tag, ns) => {
|
|
1015
|
+
return (first, second) => {
|
|
1016
|
+
validateTagName(tag);
|
|
1017
|
+
const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
|
|
1018
|
+
if (first === void 0) return el;
|
|
1019
|
+
if (typeof first === "string") {
|
|
1020
|
+
if (second !== void 0) {
|
|
1021
|
+
el.setAttribute("class", first);
|
|
1022
|
+
appendChildren(el, second);
|
|
1023
|
+
return el;
|
|
1024
|
+
}
|
|
1025
|
+
el.textContent = first;
|
|
875
1026
|
return el;
|
|
876
1027
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
1028
|
+
if (typeof first === "number") {
|
|
1029
|
+
el.textContent = String(first);
|
|
1030
|
+
return el;
|
|
1031
|
+
}
|
|
1032
|
+
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
1033
|
+
appendChildren(el, first);
|
|
1034
|
+
return el;
|
|
1035
|
+
}
|
|
1036
|
+
const props = first;
|
|
1037
|
+
const pClass = props.class;
|
|
1038
|
+
if (pClass != null) applyClass(el, pClass);
|
|
1039
|
+
const pId = props.id;
|
|
1040
|
+
if (pId != null) {
|
|
1041
|
+
if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
1042
|
+
devWarn(
|
|
1043
|
+
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
1044
|
+
);
|
|
1045
|
+
}
|
|
1046
|
+
el.id = pId;
|
|
1047
|
+
}
|
|
1048
|
+
const pNodes = second !== void 0 ? second : props.nodes;
|
|
1049
|
+
if (pNodes != null) appendChildren(el, pNodes);
|
|
1050
|
+
const pOn = props.on;
|
|
1051
|
+
if (pOn) {
|
|
1052
|
+
for (const ev in pOn) {
|
|
1053
|
+
const handler = pOn[ev];
|
|
1054
|
+
if (typeof handler === "function") {
|
|
1055
|
+
el.addEventListener(ev, handler);
|
|
1056
|
+
} else if (_isDev6) {
|
|
1057
|
+
devWarn(
|
|
1058
|
+
`tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
|
|
1059
|
+
);
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
const pStyle = props.style;
|
|
1064
|
+
if (pStyle != null) applyStyle(el, pStyle);
|
|
1065
|
+
const pRef = props.ref;
|
|
1066
|
+
if (pRef) pRef.current = el;
|
|
1067
|
+
for (const key in props) {
|
|
1068
|
+
switch (key) {
|
|
1069
|
+
case "class":
|
|
1070
|
+
case "id":
|
|
1071
|
+
case "nodes":
|
|
1072
|
+
case "on":
|
|
1073
|
+
case "style":
|
|
1074
|
+
case "ref":
|
|
1075
|
+
case "onElement":
|
|
1076
|
+
continue;
|
|
1077
|
+
// already handled above / below
|
|
1078
|
+
default: {
|
|
1079
|
+
const value = props[key];
|
|
1080
|
+
if (value == null) continue;
|
|
1081
|
+
const lkey = key.toLowerCase();
|
|
1082
|
+
if (lkey[0] === "o" && lkey[1] === "n") continue;
|
|
1083
|
+
if (typeof value === "function") {
|
|
1084
|
+
registerDisposer(el, bindAttribute(el, key, value));
|
|
1085
|
+
} else if (typeof value === "boolean") {
|
|
1086
|
+
if (key in el && (key === "checked" || key === "disabled" || key === "selected")) {
|
|
1087
|
+
setProp2(el, key, value);
|
|
1088
|
+
} else if (value) {
|
|
1089
|
+
el.setAttribute(key, "");
|
|
1090
|
+
} else {
|
|
1091
|
+
el.removeAttribute(key);
|
|
1092
|
+
}
|
|
927
1093
|
} else {
|
|
928
|
-
|
|
1094
|
+
const str = String(value);
|
|
1095
|
+
if (lkey === "srcset") {
|
|
1096
|
+
el.setAttribute(key, sanitizeSrcset(str));
|
|
1097
|
+
} else if (isUrlAttribute(lkey)) {
|
|
1098
|
+
el.setAttribute(key, sanitizeUrl(str));
|
|
1099
|
+
} else {
|
|
1100
|
+
el.setAttribute(key, str);
|
|
1101
|
+
}
|
|
929
1102
|
}
|
|
930
|
-
} else {
|
|
931
|
-
const str = String(value);
|
|
932
|
-
el.setAttribute(key, isUrlAttribute(key) ? sanitizeUrl(str) : str);
|
|
933
1103
|
}
|
|
934
1104
|
}
|
|
935
1105
|
}
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1106
|
+
if (props.onElement && typeof props.onElement === "function") {
|
|
1107
|
+
props.onElement(el);
|
|
1108
|
+
}
|
|
1109
|
+
return el;
|
|
1110
|
+
};
|
|
941
1111
|
};
|
|
942
1112
|
|
|
943
1113
|
// src/core/rendering/html.ts
|
|
@@ -1080,6 +1250,8 @@ var marquee = tagFactory("marquee");
|
|
|
1080
1250
|
var customElement = (tagName) => tagFactory(tagName);
|
|
1081
1251
|
|
|
1082
1252
|
// src/core/rendering/htm.ts
|
|
1253
|
+
var _isDev7 = isDev();
|
|
1254
|
+
var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
|
|
1083
1255
|
var VOID_ELEMENTS = /* @__PURE__ */ new Set([
|
|
1084
1256
|
"area",
|
|
1085
1257
|
"base",
|
|
@@ -1264,6 +1436,15 @@ function parseTemplate(strings) {
|
|
|
1264
1436
|
children.push({ t: 0, el: { tag, svg: SVG_TAGS.has(tag), attrs, children: [] } });
|
|
1265
1437
|
} else {
|
|
1266
1438
|
const inner = parseChildren();
|
|
1439
|
+
if (RAW_TEXT_TAGS.has(tag.toLowerCase())) {
|
|
1440
|
+
for (let i2 = 0; i2 < inner.length; i2++) {
|
|
1441
|
+
if (inner[i2].t === 2) {
|
|
1442
|
+
throw new Error(
|
|
1443
|
+
`html: dynamic \${...} expressions are not allowed inside <${tag}> (raw-text context). Build the content separately and append it as a Node.`
|
|
1444
|
+
);
|
|
1445
|
+
}
|
|
1446
|
+
}
|
|
1447
|
+
}
|
|
1267
1448
|
if (template2[pos] === "<" && pos + 1 < len && template2[pos + 1] === "/") {
|
|
1268
1449
|
pos += 2;
|
|
1269
1450
|
readTagName();
|
|
@@ -1290,27 +1471,50 @@ function executeElement(tmpl, values) {
|
|
|
1290
1471
|
break;
|
|
1291
1472
|
case 1: {
|
|
1292
1473
|
const name = attr.name;
|
|
1293
|
-
|
|
1474
|
+
const lname = name.toLowerCase();
|
|
1475
|
+
if (lname[0] === "o" && lname[1] === "n") break;
|
|
1294
1476
|
const val = values[attr.idx];
|
|
1295
1477
|
if (typeof val === "function") {
|
|
1296
1478
|
registerDisposer(el, bindAttribute(el, name, val));
|
|
1297
1479
|
} else if (val != null) {
|
|
1298
1480
|
const str = String(val);
|
|
1299
|
-
|
|
1481
|
+
if (lname === "srcset") {
|
|
1482
|
+
el.setAttribute(name, sanitizeSrcset(str));
|
|
1483
|
+
} else if (isUrlAttribute(lname)) {
|
|
1484
|
+
el.setAttribute(name, sanitizeUrl(str));
|
|
1485
|
+
} else {
|
|
1486
|
+
el.setAttribute(name, str);
|
|
1487
|
+
}
|
|
1300
1488
|
}
|
|
1301
1489
|
break;
|
|
1302
1490
|
}
|
|
1303
1491
|
case 2: {
|
|
1304
1492
|
let val = attr.statics[0];
|
|
1305
1493
|
for (let j = 0; j < attr.exprs.length; j++) {
|
|
1306
|
-
|
|
1494
|
+
const ev = values[attr.exprs[j]];
|
|
1495
|
+
val += (ev == null ? "" : String(ev)) + attr.statics[j + 1];
|
|
1496
|
+
}
|
|
1497
|
+
const lname2 = attr.name.toLowerCase();
|
|
1498
|
+
if (lname2 === "srcset") {
|
|
1499
|
+
el.setAttribute(attr.name, sanitizeSrcset(val));
|
|
1500
|
+
} else if (isUrlAttribute(lname2)) {
|
|
1501
|
+
el.setAttribute(attr.name, sanitizeUrl(val));
|
|
1502
|
+
} else {
|
|
1503
|
+
el.setAttribute(attr.name, val);
|
|
1307
1504
|
}
|
|
1308
|
-
el.setAttribute(attr.name, val);
|
|
1309
1505
|
break;
|
|
1310
1506
|
}
|
|
1311
|
-
case 3:
|
|
1312
|
-
|
|
1507
|
+
case 3: {
|
|
1508
|
+
const fn = values[attr.idx];
|
|
1509
|
+
if (typeof fn === "function") {
|
|
1510
|
+
el.addEventListener(attr.name, fn);
|
|
1511
|
+
} else if (_isDev7) {
|
|
1512
|
+
devWarn(
|
|
1513
|
+
`html: on:${attr.name} handler is not a function (got ${typeof fn}). Event listener was not attached.`
|
|
1514
|
+
);
|
|
1515
|
+
}
|
|
1313
1516
|
break;
|
|
1517
|
+
}
|
|
1314
1518
|
case 4:
|
|
1315
1519
|
el.setAttribute(attr.name, "");
|
|
1316
1520
|
break;
|
|
@@ -1404,7 +1608,7 @@ function html2(strings, ...values) {
|
|
|
1404
1608
|
function mount(component, container) {
|
|
1405
1609
|
if (!container) {
|
|
1406
1610
|
throw new Error(
|
|
1407
|
-
"[
|
|
1611
|
+
"[SibuJS mount] container element not found. Make sure the DOM element exists before calling mount()."
|
|
1408
1612
|
);
|
|
1409
1613
|
}
|
|
1410
1614
|
devAssert(
|
|
@@ -1432,7 +1636,7 @@ function mount(component, container) {
|
|
|
1432
1636
|
}
|
|
1433
1637
|
|
|
1434
1638
|
// src/core/rendering/each.ts
|
|
1435
|
-
var
|
|
1639
|
+
var _isDev8 = isDev();
|
|
1436
1640
|
function resolveNodeChild(child) {
|
|
1437
1641
|
if (typeof child === "function") {
|
|
1438
1642
|
return resolveNodeChild(child());
|
|
@@ -1527,17 +1731,31 @@ function each(getArray, render, options) {
|
|
|
1527
1731
|
node = existing;
|
|
1528
1732
|
} else {
|
|
1529
1733
|
const itemKey = key;
|
|
1530
|
-
const itemGetter = () => getArray()[keyIndexMap.get(itemKey)];
|
|
1734
|
+
const itemGetter = () => untracked(() => getArray()[keyIndexMap.get(itemKey)]);
|
|
1531
1735
|
const indexGetter = () => keyIndexMap.get(itemKey);
|
|
1532
1736
|
try {
|
|
1533
1737
|
node = resolveNodeChild(render(itemGetter, indexGetter));
|
|
1534
1738
|
} catch (err) {
|
|
1535
|
-
if (
|
|
1739
|
+
if (_isDev8) {
|
|
1536
1740
|
devWarn(
|
|
1537
1741
|
`each: render threw for item at index ${i2} (key="${newKeys[i2]}"): ${err instanceof Error ? err.message : String(err)}`
|
|
1538
1742
|
);
|
|
1539
1743
|
}
|
|
1540
1744
|
node = document.createComment(`each:error:${i2}`);
|
|
1745
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1746
|
+
queueMicrotask(() => {
|
|
1747
|
+
try {
|
|
1748
|
+
const target = anchor.parentNode;
|
|
1749
|
+
if (target?.dispatchEvent) {
|
|
1750
|
+
target.dispatchEvent(
|
|
1751
|
+
new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error: errorObj } })
|
|
1752
|
+
);
|
|
1753
|
+
} else if (_isDev8) {
|
|
1754
|
+
devWarn(`each: error not surfaced \u2014 anchor detached: ${errorObj.message}`);
|
|
1755
|
+
}
|
|
1756
|
+
} catch {
|
|
1757
|
+
}
|
|
1758
|
+
});
|
|
1541
1759
|
}
|
|
1542
1760
|
}
|
|
1543
1761
|
workMap.set(key, node);
|
|
@@ -1606,7 +1824,8 @@ function each(getArray, render, options) {
|
|
|
1606
1824
|
workMap = tmp;
|
|
1607
1825
|
initialized = true;
|
|
1608
1826
|
};
|
|
1609
|
-
track(update);
|
|
1827
|
+
const untrack = track(update);
|
|
1828
|
+
registerDisposer(anchor, untrack);
|
|
1610
1829
|
if (!initialized) {
|
|
1611
1830
|
queueMicrotask(() => {
|
|
1612
1831
|
if (!initialized && anchor.parentNode) {
|
|
@@ -1653,7 +1872,9 @@ function Portal(nodes, target) {
|
|
|
1653
1872
|
const anchor = document.createComment("portal");
|
|
1654
1873
|
const container = target || document.body;
|
|
1655
1874
|
let portalContent = null;
|
|
1875
|
+
let disposed = false;
|
|
1656
1876
|
queueMicrotask(() => {
|
|
1877
|
+
if (disposed) return;
|
|
1657
1878
|
try {
|
|
1658
1879
|
portalContent = nodes();
|
|
1659
1880
|
container.appendChild(portalContent);
|
|
@@ -1661,9 +1882,22 @@ function Portal(nodes, target) {
|
|
|
1661
1882
|
if (typeof console !== "undefined") {
|
|
1662
1883
|
console.error("[Portal] Render error:", err);
|
|
1663
1884
|
}
|
|
1885
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1886
|
+
queueMicrotask(() => {
|
|
1887
|
+
try {
|
|
1888
|
+
const target2 = anchor.parentNode;
|
|
1889
|
+
if (target2?.dispatchEvent) {
|
|
1890
|
+
target2.dispatchEvent(
|
|
1891
|
+
new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error: errorObj } })
|
|
1892
|
+
);
|
|
1893
|
+
}
|
|
1894
|
+
} catch {
|
|
1895
|
+
}
|
|
1896
|
+
});
|
|
1664
1897
|
}
|
|
1665
1898
|
});
|
|
1666
1899
|
registerDisposer(anchor, () => {
|
|
1900
|
+
disposed = true;
|
|
1667
1901
|
if (portalContent) {
|
|
1668
1902
|
dispose(portalContent);
|
|
1669
1903
|
portalContent.remove();
|
|
@@ -1703,7 +1937,8 @@ function DynamicComponent(is) {
|
|
|
1703
1937
|
}
|
|
1704
1938
|
container.replaceChildren(el);
|
|
1705
1939
|
}
|
|
1706
|
-
track(render);
|
|
1940
|
+
const untrack = track(render);
|
|
1941
|
+
registerDisposer(container, untrack);
|
|
1707
1942
|
return container;
|
|
1708
1943
|
}
|
|
1709
1944
|
|
|
@@ -1793,11 +2028,16 @@ function KeepAlive(activeKey, cases, options) {
|
|
|
1793
2028
|
const anchor = document.createComment("keep-alive");
|
|
1794
2029
|
const cache2 = /* @__PURE__ */ new Map();
|
|
1795
2030
|
const lruOrder = [];
|
|
1796
|
-
const max = options?.max ??
|
|
2031
|
+
const max = options?.max ?? 10;
|
|
2032
|
+
if (max === 0 && isDev()) {
|
|
2033
|
+
devWarn("KeepAlive: unbounded cache (max: 0). Cached subtrees will never be evicted \u2014 set `max` to bound memory.");
|
|
2034
|
+
}
|
|
1797
2035
|
let currentKey;
|
|
1798
2036
|
let currentNode = null;
|
|
1799
2037
|
let initialized = false;
|
|
2038
|
+
let disposed = false;
|
|
1800
2039
|
const update = () => {
|
|
2040
|
+
if (disposed) return;
|
|
1801
2041
|
const key = activeKey();
|
|
1802
2042
|
const parent = anchor.parentNode;
|
|
1803
2043
|
if (!parent) return;
|
|
@@ -1837,12 +2077,23 @@ function KeepAlive(activeKey, cases, options) {
|
|
|
1837
2077
|
currentNode = node;
|
|
1838
2078
|
initialized = true;
|
|
1839
2079
|
};
|
|
1840
|
-
track(update);
|
|
2080
|
+
const untrack = track(update);
|
|
1841
2081
|
if (!initialized) {
|
|
1842
2082
|
queueMicrotask(() => {
|
|
1843
2083
|
if (!initialized && anchor.parentNode) update();
|
|
1844
2084
|
});
|
|
1845
2085
|
}
|
|
2086
|
+
registerDisposer(anchor, () => {
|
|
2087
|
+
disposed = true;
|
|
2088
|
+
untrack();
|
|
2089
|
+
for (const node of cache2.values()) {
|
|
2090
|
+
dispose(node);
|
|
2091
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
2092
|
+
}
|
|
2093
|
+
cache2.clear();
|
|
2094
|
+
lruOrder.length = 0;
|
|
2095
|
+
currentNode = null;
|
|
2096
|
+
});
|
|
1846
2097
|
return anchor;
|
|
1847
2098
|
}
|
|
1848
2099
|
|
|
@@ -2004,19 +2255,22 @@ function isBatching() {
|
|
|
2004
2255
|
return batchDepth > 0;
|
|
2005
2256
|
}
|
|
2006
2257
|
function flushBatch() {
|
|
2007
|
-
|
|
2008
|
-
|
|
2258
|
+
try {
|
|
2259
|
+
for (const signal2 of pendingSignals) {
|
|
2260
|
+
queueSignalNotification(signal2);
|
|
2261
|
+
}
|
|
2262
|
+
} finally {
|
|
2263
|
+
pendingSignals.clear();
|
|
2009
2264
|
}
|
|
2010
|
-
pendingSignals.clear();
|
|
2011
2265
|
drainNotificationQueue();
|
|
2012
2266
|
}
|
|
2013
2267
|
|
|
2014
2268
|
// src/core/signals/signal.ts
|
|
2015
2269
|
var _g = globalThis;
|
|
2016
|
-
var
|
|
2270
|
+
var _isDev9 = isDev();
|
|
2017
2271
|
function signal(initial, options) {
|
|
2018
2272
|
const state = { value: initial };
|
|
2019
|
-
const debugName =
|
|
2273
|
+
const debugName = _isDev9 ? options?.name : void 0;
|
|
2020
2274
|
const equalsFn = options?.equals;
|
|
2021
2275
|
if (debugName) {
|
|
2022
2276
|
state.__name = debugName;
|
|
@@ -2030,7 +2284,7 @@ function signal(initial, options) {
|
|
|
2030
2284
|
function set(next) {
|
|
2031
2285
|
const newValue = typeof next === "function" ? next(state.value) : next;
|
|
2032
2286
|
if (equalsFn ? equalsFn(state.value, newValue) : Object.is(newValue, state.value)) return;
|
|
2033
|
-
if (
|
|
2287
|
+
if (_isDev9) {
|
|
2034
2288
|
const oldValue = state.value;
|
|
2035
2289
|
state.value = newValue;
|
|
2036
2290
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -2042,7 +2296,7 @@ function signal(initial, options) {
|
|
|
2042
2296
|
notifySubscribers(state);
|
|
2043
2297
|
}
|
|
2044
2298
|
}
|
|
2045
|
-
if (
|
|
2299
|
+
if (_isDev9) {
|
|
2046
2300
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2047
2301
|
if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
|
|
2048
2302
|
}
|
|
@@ -2050,23 +2304,59 @@ function signal(initial, options) {
|
|
|
2050
2304
|
}
|
|
2051
2305
|
|
|
2052
2306
|
// src/core/ssr-context.ts
|
|
2053
|
-
var
|
|
2307
|
+
var als = null;
|
|
2308
|
+
try {
|
|
2309
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
2310
|
+
const req = Function("return typeof require==='function'?require:null")();
|
|
2311
|
+
if (req) {
|
|
2312
|
+
const mod = req("node:async_hooks");
|
|
2313
|
+
als = new mod.AsyncLocalStorage();
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
} catch {
|
|
2317
|
+
als = null;
|
|
2318
|
+
}
|
|
2319
|
+
var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
|
|
2320
|
+
function getSSRStore() {
|
|
2321
|
+
if (als) {
|
|
2322
|
+
const s2 = als.getStore();
|
|
2323
|
+
if (s2) return s2;
|
|
2324
|
+
}
|
|
2325
|
+
return fallbackStore;
|
|
2326
|
+
}
|
|
2054
2327
|
function isSSR() {
|
|
2055
|
-
return
|
|
2328
|
+
return getSSRStore().ssr;
|
|
2056
2329
|
}
|
|
2057
2330
|
function enableSSR() {
|
|
2058
|
-
|
|
2331
|
+
getSSRStore().ssr = true;
|
|
2059
2332
|
}
|
|
2060
2333
|
function disableSSR() {
|
|
2061
|
-
|
|
2334
|
+
getSSRStore().ssr = false;
|
|
2335
|
+
}
|
|
2336
|
+
function runInSSRContext(fn) {
|
|
2337
|
+
const store2 = { ssr: true, suspenseIdCounter: 0 };
|
|
2338
|
+
if (als) {
|
|
2339
|
+
return als.run(store2, fn);
|
|
2340
|
+
}
|
|
2341
|
+
const prevSSR = fallbackStore.ssr;
|
|
2342
|
+
const prevCounter = fallbackStore.suspenseIdCounter;
|
|
2343
|
+
fallbackStore.ssr = true;
|
|
2344
|
+
fallbackStore.suspenseIdCounter = 0;
|
|
2345
|
+
try {
|
|
2346
|
+
return fn();
|
|
2347
|
+
} finally {
|
|
2348
|
+
fallbackStore.ssr = prevSSR;
|
|
2349
|
+
fallbackStore.suspenseIdCounter = prevCounter;
|
|
2350
|
+
}
|
|
2062
2351
|
}
|
|
2063
2352
|
function withSSR(fn) {
|
|
2064
|
-
const
|
|
2065
|
-
|
|
2353
|
+
const store2 = getSSRStore();
|
|
2354
|
+
const wasSSR = store2.ssr;
|
|
2355
|
+
store2.ssr = true;
|
|
2066
2356
|
try {
|
|
2067
2357
|
return fn();
|
|
2068
2358
|
} finally {
|
|
2069
|
-
if (!wasSSR)
|
|
2359
|
+
if (!wasSSR) store2.ssr = false;
|
|
2070
2360
|
}
|
|
2071
2361
|
}
|
|
2072
2362
|
|
|
@@ -2093,26 +2383,86 @@ function effect(effectFn, options) {
|
|
|
2093
2383
|
if (isSSR()) return () => {
|
|
2094
2384
|
};
|
|
2095
2385
|
const onError = options?.onError;
|
|
2386
|
+
let userCleanups = [];
|
|
2387
|
+
const onCleanup2 = (fn) => {
|
|
2388
|
+
userCleanups.push(fn);
|
|
2389
|
+
};
|
|
2390
|
+
const runUserCleanups = () => {
|
|
2391
|
+
if (userCleanups.length === 0) return;
|
|
2392
|
+
const list = userCleanups;
|
|
2393
|
+
userCleanups = [];
|
|
2394
|
+
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
2395
|
+
try {
|
|
2396
|
+
list[i2]();
|
|
2397
|
+
} catch (err) {
|
|
2398
|
+
if (typeof console !== "undefined") {
|
|
2399
|
+
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
2400
|
+
}
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
};
|
|
2404
|
+
const invokeBody = () => effectFn(onCleanup2);
|
|
2096
2405
|
const wrappedFn = onError ? () => {
|
|
2097
2406
|
try {
|
|
2098
|
-
|
|
2407
|
+
invokeBody();
|
|
2099
2408
|
} catch (err) {
|
|
2100
2409
|
onError(err);
|
|
2101
2410
|
}
|
|
2102
|
-
} :
|
|
2411
|
+
} : invokeBody;
|
|
2103
2412
|
let cleanupHandle = () => {
|
|
2104
2413
|
};
|
|
2414
|
+
let running = false;
|
|
2105
2415
|
const subscriber = () => {
|
|
2106
|
-
|
|
2107
|
-
|
|
2416
|
+
if (running) {
|
|
2417
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
2418
|
+
console.warn(
|
|
2419
|
+
"[SibuJS] effect re-entered itself while running \u2014 the triggering update will be ignored. Wrap mutual writes in `batch()` or split the effect to avoid this."
|
|
2420
|
+
);
|
|
2421
|
+
}
|
|
2422
|
+
return;
|
|
2423
|
+
}
|
|
2424
|
+
running = true;
|
|
2425
|
+
try {
|
|
2426
|
+
runUserCleanups();
|
|
2427
|
+
cleanupHandle();
|
|
2428
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
2429
|
+
} finally {
|
|
2430
|
+
running = false;
|
|
2431
|
+
}
|
|
2108
2432
|
};
|
|
2109
|
-
|
|
2433
|
+
running = true;
|
|
2434
|
+
try {
|
|
2435
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
2436
|
+
} finally {
|
|
2437
|
+
running = false;
|
|
2438
|
+
}
|
|
2110
2439
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2111
2440
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
2441
|
+
let disposed = false;
|
|
2112
2442
|
return () => {
|
|
2443
|
+
if (disposed) return;
|
|
2444
|
+
disposed = true;
|
|
2113
2445
|
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2114
|
-
if (h)
|
|
2115
|
-
|
|
2446
|
+
if (h) {
|
|
2447
|
+
try {
|
|
2448
|
+
h.emit("effect:destroy", { effectFn });
|
|
2449
|
+
} catch {
|
|
2450
|
+
}
|
|
2451
|
+
}
|
|
2452
|
+
try {
|
|
2453
|
+
runUserCleanups();
|
|
2454
|
+
} catch (err) {
|
|
2455
|
+
if (typeof console !== "undefined") {
|
|
2456
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
try {
|
|
2460
|
+
cleanupHandle();
|
|
2461
|
+
} catch (err) {
|
|
2462
|
+
if (typeof console !== "undefined") {
|
|
2463
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
2464
|
+
}
|
|
2465
|
+
}
|
|
2116
2466
|
};
|
|
2117
2467
|
}
|
|
2118
2468
|
|
|
@@ -2120,6 +2470,7 @@ function effect(effectFn, options) {
|
|
|
2120
2470
|
function derived(getter, options) {
|
|
2121
2471
|
devAssert(typeof getter === "function", "derived: argument must be a getter function.");
|
|
2122
2472
|
const debugName = options?.name;
|
|
2473
|
+
const equals = options?.equals;
|
|
2123
2474
|
const cs = {};
|
|
2124
2475
|
cs._d = false;
|
|
2125
2476
|
cs._g = getter;
|
|
@@ -2130,8 +2481,14 @@ function derived(getter, options) {
|
|
|
2130
2481
|
markDirty._c = 1;
|
|
2131
2482
|
markDirty._sig = cs;
|
|
2132
2483
|
track(() => {
|
|
2133
|
-
|
|
2134
|
-
|
|
2484
|
+
let threw = true;
|
|
2485
|
+
try {
|
|
2486
|
+
cs._v = getter();
|
|
2487
|
+
cs._d = false;
|
|
2488
|
+
threw = false;
|
|
2489
|
+
} finally {
|
|
2490
|
+
if (threw) cs._d = true;
|
|
2491
|
+
}
|
|
2135
2492
|
}, markDirty);
|
|
2136
2493
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2137
2494
|
let evaluating = false;
|
|
@@ -2144,11 +2501,16 @@ function derived(getter, options) {
|
|
|
2144
2501
|
if (trackingSuspended) {
|
|
2145
2502
|
if (cs._d) {
|
|
2146
2503
|
evaluating = true;
|
|
2504
|
+
let threw = true;
|
|
2147
2505
|
try {
|
|
2148
|
-
|
|
2149
|
-
|
|
2506
|
+
retrack(() => {
|
|
2507
|
+
cs._v = getter();
|
|
2508
|
+
cs._d = false;
|
|
2509
|
+
threw = false;
|
|
2510
|
+
}, markDirty);
|
|
2150
2511
|
} finally {
|
|
2151
2512
|
evaluating = false;
|
|
2513
|
+
if (threw) cs._d = true;
|
|
2152
2514
|
}
|
|
2153
2515
|
}
|
|
2154
2516
|
return cs._v;
|
|
@@ -2157,13 +2519,17 @@ function derived(getter, options) {
|
|
|
2157
2519
|
if (cs._d) {
|
|
2158
2520
|
const oldValue = cs._v;
|
|
2159
2521
|
evaluating = true;
|
|
2522
|
+
let threw = true;
|
|
2160
2523
|
try {
|
|
2161
|
-
|
|
2524
|
+
retrack(() => {
|
|
2525
|
+
const next = getter();
|
|
2526
|
+
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
2162
2527
|
cs._d = false;
|
|
2163
|
-
|
|
2528
|
+
threw = false;
|
|
2164
2529
|
}, markDirty);
|
|
2165
2530
|
} finally {
|
|
2166
2531
|
evaluating = false;
|
|
2532
|
+
if (threw) cs._d = true;
|
|
2167
2533
|
}
|
|
2168
2534
|
if (hook && oldValue !== cs._v) {
|
|
2169
2535
|
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
@@ -2225,7 +2591,7 @@ function store(initialState) {
|
|
|
2225
2591
|
},
|
|
2226
2592
|
set() {
|
|
2227
2593
|
throw new Error(
|
|
2228
|
-
"[
|
|
2594
|
+
"[SibuJS store] Direct mutation is not allowed. Use actions.setState() to update store properties."
|
|
2229
2595
|
);
|
|
2230
2596
|
}
|
|
2231
2597
|
});
|
|
@@ -2239,16 +2605,20 @@ function store(initialState) {
|
|
|
2239
2605
|
const setState = (patch) => {
|
|
2240
2606
|
const current = getSnapshot();
|
|
2241
2607
|
const nextState = typeof patch === "function" ? patch(current) : patch;
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
signals
|
|
2245
|
-
|
|
2608
|
+
batch(() => {
|
|
2609
|
+
Object.entries(nextState).forEach(([key, value]) => {
|
|
2610
|
+
if (key in signals) {
|
|
2611
|
+
signals[key][1](value);
|
|
2612
|
+
}
|
|
2613
|
+
});
|
|
2246
2614
|
});
|
|
2247
2615
|
};
|
|
2248
2616
|
const reset = () => {
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2617
|
+
batch(() => {
|
|
2618
|
+
Object.keys(initialState).forEach((key) => {
|
|
2619
|
+
const setter = signals[key][1];
|
|
2620
|
+
setter(initialState[key]);
|
|
2621
|
+
});
|
|
2252
2622
|
});
|
|
2253
2623
|
};
|
|
2254
2624
|
const subscribe = (callback) => {
|
|
@@ -2382,7 +2752,8 @@ function reactiveArray(initial = []) {
|
|
|
2382
2752
|
function get() {
|
|
2383
2753
|
recordDependency(signal2);
|
|
2384
2754
|
if (snapshot === null) {
|
|
2385
|
-
|
|
2755
|
+
const copy = data2.slice();
|
|
2756
|
+
snapshot = Object.freeze(copy);
|
|
2386
2757
|
}
|
|
2387
2758
|
return snapshot;
|
|
2388
2759
|
}
|
|
@@ -2578,26 +2949,34 @@ function asyncDerived(factory, initial) {
|
|
|
2578
2949
|
effect(() => {
|
|
2579
2950
|
tick();
|
|
2580
2951
|
const currentRun = ++runId;
|
|
2581
|
-
|
|
2582
|
-
|
|
2952
|
+
batch(() => {
|
|
2953
|
+
setLoading(true);
|
|
2954
|
+
setError(null);
|
|
2955
|
+
});
|
|
2583
2956
|
let promise;
|
|
2584
2957
|
try {
|
|
2585
2958
|
promise = factory();
|
|
2586
2959
|
} catch (err) {
|
|
2587
|
-
|
|
2588
|
-
|
|
2960
|
+
batch(() => {
|
|
2961
|
+
setError(err);
|
|
2962
|
+
setLoading(false);
|
|
2963
|
+
});
|
|
2589
2964
|
return;
|
|
2590
2965
|
}
|
|
2591
2966
|
promise.then(
|
|
2592
2967
|
(result) => {
|
|
2593
2968
|
if (currentRun !== runId) return;
|
|
2594
|
-
|
|
2595
|
-
|
|
2969
|
+
batch(() => {
|
|
2970
|
+
setValue(result);
|
|
2971
|
+
setLoading(false);
|
|
2972
|
+
});
|
|
2596
2973
|
},
|
|
2597
2974
|
(err) => {
|
|
2598
2975
|
if (currentRun !== runId) return;
|
|
2599
|
-
|
|
2600
|
-
|
|
2976
|
+
batch(() => {
|
|
2977
|
+
setError(err);
|
|
2978
|
+
setLoading(false);
|
|
2979
|
+
});
|
|
2601
2980
|
}
|
|
2602
2981
|
);
|
|
2603
2982
|
});
|
|
@@ -2624,26 +3003,186 @@ function runMountCallback(callback, hookName, element) {
|
|
|
2624
3003
|
registerDisposer(element, cleanup2);
|
|
2625
3004
|
}
|
|
2626
3005
|
}
|
|
3006
|
+
var mountWatchers = /* @__PURE__ */ new WeakMap();
|
|
3007
|
+
var unmountWatchers = /* @__PURE__ */ new WeakMap();
|
|
3008
|
+
var watchedMountElements = /* @__PURE__ */ new Set();
|
|
3009
|
+
var watchedUnmountElements = /* @__PURE__ */ new Set();
|
|
3010
|
+
var sharedObserver = null;
|
|
3011
|
+
var mutationCounter = 0;
|
|
3012
|
+
var FULL_SWEEP_INTERVAL = 256;
|
|
3013
|
+
function fireMount(el) {
|
|
3014
|
+
const cbs = mountWatchers.get(el);
|
|
3015
|
+
if (!cbs) return;
|
|
3016
|
+
mountWatchers.delete(el);
|
|
3017
|
+
watchedMountElements.delete(el);
|
|
3018
|
+
for (const cb of cbs) {
|
|
3019
|
+
try {
|
|
3020
|
+
cb();
|
|
3021
|
+
} catch {
|
|
3022
|
+
}
|
|
3023
|
+
}
|
|
3024
|
+
}
|
|
3025
|
+
function fireUnmount(el) {
|
|
3026
|
+
const cbs = unmountWatchers.get(el);
|
|
3027
|
+
if (!cbs) return;
|
|
3028
|
+
queueMicrotask(() => {
|
|
3029
|
+
if (el.isConnected) return;
|
|
3030
|
+
const stillCbs = unmountWatchers.get(el);
|
|
3031
|
+
if (!stillCbs) return;
|
|
3032
|
+
unmountWatchers.delete(el);
|
|
3033
|
+
watchedUnmountElements.delete(el);
|
|
3034
|
+
for (const cb of stillCbs) {
|
|
3035
|
+
try {
|
|
3036
|
+
cb();
|
|
3037
|
+
} catch {
|
|
3038
|
+
}
|
|
3039
|
+
}
|
|
3040
|
+
});
|
|
3041
|
+
}
|
|
3042
|
+
function visitAddedNode(node) {
|
|
3043
|
+
if (watchedMountElements.size === 0) return;
|
|
3044
|
+
if (node.nodeType !== 1) return;
|
|
3045
|
+
const el = node;
|
|
3046
|
+
if (watchedMountElements.has(el) && el.isConnected) {
|
|
3047
|
+
fireMount(el);
|
|
3048
|
+
}
|
|
3049
|
+
if (el.firstElementChild) {
|
|
3050
|
+
for (const watched of Array.from(watchedMountElements)) {
|
|
3051
|
+
if (watched !== el && watched.isConnected && el.contains(watched)) {
|
|
3052
|
+
fireMount(watched);
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
function visitRemovedNode(node) {
|
|
3058
|
+
if (watchedUnmountElements.size === 0) return;
|
|
3059
|
+
if (node.nodeType !== 1) return;
|
|
3060
|
+
const el = node;
|
|
3061
|
+
if (watchedUnmountElements.has(el) && !el.isConnected) {
|
|
3062
|
+
fireUnmount(el);
|
|
3063
|
+
}
|
|
3064
|
+
if (el.firstElementChild) {
|
|
3065
|
+
for (const watched of Array.from(watchedUnmountElements)) {
|
|
3066
|
+
if (watched !== el && !watched.isConnected && el.contains(watched)) {
|
|
3067
|
+
fireUnmount(watched);
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
}
|
|
3071
|
+
}
|
|
3072
|
+
function fullSweep() {
|
|
3073
|
+
if (watchedMountElements.size > 0) {
|
|
3074
|
+
for (const el of Array.from(watchedMountElements)) {
|
|
3075
|
+
if (el.isConnected) fireMount(el);
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
if (watchedUnmountElements.size > 0) {
|
|
3079
|
+
for (const el of Array.from(watchedUnmountElements)) {
|
|
3080
|
+
if (!el.isConnected) fireUnmount(el);
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
}
|
|
3084
|
+
function ensureObserver() {
|
|
3085
|
+
if (sharedObserver || typeof document === "undefined") return;
|
|
3086
|
+
sharedObserver = new MutationObserver((mutations) => {
|
|
3087
|
+
for (const m of mutations) {
|
|
3088
|
+
if (m.type !== "childList") continue;
|
|
3089
|
+
if (m.addedNodes.length > 0) {
|
|
3090
|
+
for (let i2 = 0; i2 < m.addedNodes.length; i2++) {
|
|
3091
|
+
visitAddedNode(m.addedNodes[i2]);
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
if (m.removedNodes.length > 0) {
|
|
3095
|
+
for (let i2 = 0; i2 < m.removedNodes.length; i2++) {
|
|
3096
|
+
visitRemovedNode(m.removedNodes[i2]);
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
}
|
|
3100
|
+
mutationCounter += mutations.length;
|
|
3101
|
+
if (mutationCounter >= FULL_SWEEP_INTERVAL) {
|
|
3102
|
+
mutationCounter = 0;
|
|
3103
|
+
fullSweep();
|
|
3104
|
+
}
|
|
3105
|
+
maybeDisconnectObserver();
|
|
3106
|
+
});
|
|
3107
|
+
sharedObserver.observe(document.body, { childList: true, subtree: true });
|
|
3108
|
+
}
|
|
3109
|
+
function maybeDisconnectObserver() {
|
|
3110
|
+
if (!sharedObserver) return;
|
|
3111
|
+
if (watchedMountElements.size === 0 && watchedUnmountElements.size === 0) {
|
|
3112
|
+
sharedObserver.disconnect();
|
|
3113
|
+
sharedObserver = null;
|
|
3114
|
+
mutationCounter = 0;
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
function registerMountWatcher(element, cb) {
|
|
3118
|
+
let list = mountWatchers.get(element);
|
|
3119
|
+
if (!list) {
|
|
3120
|
+
list = [];
|
|
3121
|
+
mountWatchers.set(element, list);
|
|
3122
|
+
}
|
|
3123
|
+
list.push(cb);
|
|
3124
|
+
watchedMountElements.add(element);
|
|
3125
|
+
ensureObserver();
|
|
3126
|
+
return () => {
|
|
3127
|
+
const cbs = mountWatchers.get(element);
|
|
3128
|
+
if (cbs) {
|
|
3129
|
+
const idx = cbs.indexOf(cb);
|
|
3130
|
+
if (idx !== -1) cbs.splice(idx, 1);
|
|
3131
|
+
if (cbs.length === 0) {
|
|
3132
|
+
mountWatchers.delete(element);
|
|
3133
|
+
watchedMountElements.delete(element);
|
|
3134
|
+
}
|
|
3135
|
+
}
|
|
3136
|
+
maybeDisconnectObserver();
|
|
3137
|
+
};
|
|
3138
|
+
}
|
|
3139
|
+
function registerUnmountWatcher(element, cb) {
|
|
3140
|
+
let list = unmountWatchers.get(element);
|
|
3141
|
+
if (!list) {
|
|
3142
|
+
list = [];
|
|
3143
|
+
unmountWatchers.set(element, list);
|
|
3144
|
+
}
|
|
3145
|
+
list.push(cb);
|
|
3146
|
+
watchedUnmountElements.add(element);
|
|
3147
|
+
ensureObserver();
|
|
3148
|
+
return () => {
|
|
3149
|
+
const cbs = unmountWatchers.get(element);
|
|
3150
|
+
if (cbs) {
|
|
3151
|
+
const idx = cbs.indexOf(cb);
|
|
3152
|
+
if (idx !== -1) cbs.splice(idx, 1);
|
|
3153
|
+
if (cbs.length === 0) {
|
|
3154
|
+
unmountWatchers.delete(element);
|
|
3155
|
+
watchedUnmountElements.delete(element);
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
maybeDisconnectObserver();
|
|
3159
|
+
};
|
|
3160
|
+
}
|
|
2627
3161
|
function onMount(callback, element) {
|
|
2628
3162
|
if (typeof document === "undefined") return;
|
|
2629
3163
|
if (element) {
|
|
3164
|
+
let disposed = false;
|
|
3165
|
+
registerDisposer(element, () => {
|
|
3166
|
+
disposed = true;
|
|
3167
|
+
});
|
|
2630
3168
|
if (element.isConnected) {
|
|
2631
|
-
queueMicrotask(() =>
|
|
3169
|
+
queueMicrotask(() => {
|
|
3170
|
+
if (disposed) return;
|
|
3171
|
+
runMountCallback(callback, "onMount", element);
|
|
3172
|
+
});
|
|
2632
3173
|
return;
|
|
2633
3174
|
}
|
|
2634
|
-
const observer = new MutationObserver(() => {
|
|
2635
|
-
if (element.isConnected) {
|
|
2636
|
-
observer.disconnect();
|
|
2637
|
-
runMountCallback(callback, "onMount", element);
|
|
2638
|
-
}
|
|
2639
|
-
});
|
|
2640
|
-
registerDisposer(element, () => observer.disconnect());
|
|
2641
3175
|
queueMicrotask(() => {
|
|
3176
|
+
if (disposed) return;
|
|
2642
3177
|
if (element.isConnected) {
|
|
2643
3178
|
runMountCallback(callback, "onMount", element);
|
|
2644
|
-
|
|
2645
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
3179
|
+
return;
|
|
2646
3180
|
}
|
|
3181
|
+
const unregister = registerMountWatcher(element, () => {
|
|
3182
|
+
if (disposed) return;
|
|
3183
|
+
runMountCallback(callback, "onMount", element);
|
|
3184
|
+
});
|
|
3185
|
+
registerDisposer(element, unregister);
|
|
2647
3186
|
});
|
|
2648
3187
|
} else {
|
|
2649
3188
|
queueMicrotask(() => {
|
|
@@ -2652,22 +3191,24 @@ function onMount(callback, element) {
|
|
|
2652
3191
|
}
|
|
2653
3192
|
}
|
|
2654
3193
|
function onUnmount(callback, element) {
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
3194
|
+
if (typeof document === "undefined") return;
|
|
3195
|
+
let fired = false;
|
|
3196
|
+
const fireOnce = () => {
|
|
3197
|
+
if (fired) return;
|
|
3198
|
+
fired = true;
|
|
3199
|
+
safeCall(callback, "onUnmount");
|
|
3200
|
+
};
|
|
3201
|
+
registerDisposer(element, fireOnce);
|
|
3202
|
+
const startWatching = () => {
|
|
3203
|
+
if (fired) return;
|
|
3204
|
+
const unregister = registerUnmountWatcher(element, fireOnce);
|
|
3205
|
+
registerDisposer(element, unregister);
|
|
2665
3206
|
};
|
|
2666
3207
|
if (element.isConnected) {
|
|
2667
|
-
|
|
3208
|
+
startWatching();
|
|
2668
3209
|
} else {
|
|
2669
3210
|
onMount(() => {
|
|
2670
|
-
|
|
3211
|
+
startWatching();
|
|
2671
3212
|
return void 0;
|
|
2672
3213
|
}, element);
|
|
2673
3214
|
}
|
|
@@ -2679,9 +3220,11 @@ function onCleanup(callback, element) {
|
|
|
2679
3220
|
// src/core/rendering/context.ts
|
|
2680
3221
|
function context(defaultValue) {
|
|
2681
3222
|
const [getValue, setValue] = signal(defaultValue);
|
|
2682
|
-
|
|
3223
|
+
const ctx = {
|
|
2683
3224
|
provide(value) {
|
|
3225
|
+
const previous = getValue();
|
|
2684
3226
|
setValue(value);
|
|
3227
|
+
return () => setValue(previous);
|
|
2685
3228
|
},
|
|
2686
3229
|
use() {
|
|
2687
3230
|
return getValue;
|
|
@@ -2691,8 +3234,18 @@ function context(defaultValue) {
|
|
|
2691
3234
|
},
|
|
2692
3235
|
set(value) {
|
|
2693
3236
|
setValue(value);
|
|
3237
|
+
},
|
|
3238
|
+
withContext(value, fn) {
|
|
3239
|
+
const previous = getValue();
|
|
3240
|
+
setValue(value);
|
|
3241
|
+
try {
|
|
3242
|
+
return fn();
|
|
3243
|
+
} finally {
|
|
3244
|
+
setValue(previous);
|
|
3245
|
+
}
|
|
2694
3246
|
}
|
|
2695
3247
|
};
|
|
3248
|
+
return ctx;
|
|
2696
3249
|
}
|
|
2697
3250
|
|
|
2698
3251
|
// src/core/strict.ts
|
|
@@ -2703,7 +3256,7 @@ function strict(fn) {
|
|
|
2703
3256
|
try {
|
|
2704
3257
|
fn();
|
|
2705
3258
|
} catch (err) {
|
|
2706
|
-
console.warn("[
|
|
3259
|
+
console.warn("[SibuJS strict] second run threw:", err);
|
|
2707
3260
|
}
|
|
2708
3261
|
});
|
|
2709
3262
|
}
|
|
@@ -2719,7 +3272,7 @@ function strictEffect(fn) {
|
|
|
2719
3272
|
try {
|
|
2720
3273
|
secondTeardown = effect(fn);
|
|
2721
3274
|
} catch (err) {
|
|
2722
|
-
console.warn("[
|
|
3275
|
+
console.warn("[SibuJS strictEffect] second run threw:", err);
|
|
2723
3276
|
}
|
|
2724
3277
|
});
|
|
2725
3278
|
return () => {
|
|
@@ -2745,9 +3298,11 @@ function nextTick() {
|
|
|
2745
3298
|
function defer(getter) {
|
|
2746
3299
|
const [value, setValue] = signal(getter());
|
|
2747
3300
|
let pending = false;
|
|
3301
|
+
let disposed = false;
|
|
2748
3302
|
let latest = value();
|
|
2749
3303
|
const flush = () => {
|
|
2750
3304
|
pending = false;
|
|
3305
|
+
if (disposed) return;
|
|
2751
3306
|
setValue(latest);
|
|
2752
3307
|
};
|
|
2753
3308
|
const schedule = () => {
|
|
@@ -2761,11 +3316,17 @@ function defer(getter) {
|
|
|
2761
3316
|
}
|
|
2762
3317
|
});
|
|
2763
3318
|
};
|
|
2764
|
-
track(() => {
|
|
3319
|
+
const teardown = track(() => {
|
|
2765
3320
|
latest = getter();
|
|
2766
3321
|
schedule();
|
|
2767
3322
|
});
|
|
2768
|
-
|
|
3323
|
+
const accessor = (() => value());
|
|
3324
|
+
accessor.dispose = () => {
|
|
3325
|
+
if (disposed) return;
|
|
3326
|
+
disposed = true;
|
|
3327
|
+
teardown();
|
|
3328
|
+
};
|
|
3329
|
+
return accessor;
|
|
2769
3330
|
}
|
|
2770
3331
|
var IDLE_FALLBACK_MS = 16;
|
|
2771
3332
|
function scheduleIdle(fn) {
|
|
@@ -2806,6 +3367,32 @@ function transition() {
|
|
|
2806
3367
|
}
|
|
2807
3368
|
|
|
2808
3369
|
// src/core/rendering/lazy.ts
|
|
3370
|
+
var PENDING_ERROR = "__sibuPendingError";
|
|
3371
|
+
function dispatchPropagate(node, error) {
|
|
3372
|
+
const fire = () => {
|
|
3373
|
+
try {
|
|
3374
|
+
if (!node.parentNode) return false;
|
|
3375
|
+
node.dispatchEvent(new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error } }));
|
|
3376
|
+
return true;
|
|
3377
|
+
} catch {
|
|
3378
|
+
return false;
|
|
3379
|
+
}
|
|
3380
|
+
};
|
|
3381
|
+
if (node.parentNode && fire()) return;
|
|
3382
|
+
queueMicrotask(() => {
|
|
3383
|
+
if (fire()) return;
|
|
3384
|
+
node[PENDING_ERROR] = error;
|
|
3385
|
+
});
|
|
3386
|
+
}
|
|
3387
|
+
function takePendingError(node) {
|
|
3388
|
+
const rec = node;
|
|
3389
|
+
const err = rec[PENDING_ERROR];
|
|
3390
|
+
if (err instanceof Error) {
|
|
3391
|
+
delete rec[PENDING_ERROR];
|
|
3392
|
+
return err;
|
|
3393
|
+
}
|
|
3394
|
+
return void 0;
|
|
3395
|
+
}
|
|
2809
3396
|
function lazy(importFn) {
|
|
2810
3397
|
let cached = null;
|
|
2811
3398
|
return function LazyComponent() {
|
|
@@ -2822,14 +3409,14 @@ function lazy(importFn) {
|
|
|
2822
3409
|
}).catch((err) => {
|
|
2823
3410
|
if (disposed) return;
|
|
2824
3411
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2825
|
-
|
|
3412
|
+
devWarn(`[SibuJS] lazy() failed to load component: ${errorObj.message}`);
|
|
3413
|
+
container.replaceChildren(div({ class: "sibu-lazy-error" }, `Failed to load component: ${errorObj.message}`));
|
|
3414
|
+
dispatchPropagate(container, errorObj);
|
|
2826
3415
|
});
|
|
2827
3416
|
container.appendChild(span("sibu-lazy-loading", "Loading..."));
|
|
2828
|
-
|
|
2829
|
-
container.remove = () => {
|
|
3417
|
+
registerDisposer(container, () => {
|
|
2830
3418
|
disposed = true;
|
|
2831
|
-
|
|
2832
|
-
};
|
|
3419
|
+
});
|
|
2833
3420
|
return container;
|
|
2834
3421
|
};
|
|
2835
3422
|
}
|
|
@@ -2837,32 +3424,55 @@ function Suspense({ nodes, fallback }) {
|
|
|
2837
3424
|
const container = div({ class: "sibu-suspense" });
|
|
2838
3425
|
const fallbackEl = fallback();
|
|
2839
3426
|
container.appendChild(fallbackEl);
|
|
3427
|
+
let suspenseDisposed = false;
|
|
3428
|
+
let observer = null;
|
|
3429
|
+
registerDisposer(container, () => {
|
|
3430
|
+
suspenseDisposed = true;
|
|
3431
|
+
if (observer) {
|
|
3432
|
+
observer.disconnect();
|
|
3433
|
+
observer = null;
|
|
3434
|
+
}
|
|
3435
|
+
});
|
|
2840
3436
|
queueMicrotask(() => {
|
|
3437
|
+
if (suspenseDisposed) return;
|
|
2841
3438
|
try {
|
|
2842
3439
|
const childEl = nodes();
|
|
2843
3440
|
if (childEl.classList.contains("sibu-lazy")) {
|
|
2844
|
-
|
|
3441
|
+
if (!childEl.querySelector(".sibu-lazy-loading")) {
|
|
3442
|
+
container.replaceChildren(childEl);
|
|
3443
|
+
return;
|
|
3444
|
+
}
|
|
3445
|
+
observer = new MutationObserver(() => {
|
|
3446
|
+
if (suspenseDisposed) return;
|
|
2845
3447
|
const loading = childEl.querySelector(".sibu-lazy-loading");
|
|
2846
3448
|
if (!loading) {
|
|
2847
|
-
observer
|
|
3449
|
+
observer?.disconnect();
|
|
3450
|
+
observer = null;
|
|
2848
3451
|
container.replaceChildren(childEl);
|
|
2849
3452
|
}
|
|
2850
3453
|
});
|
|
2851
3454
|
observer.observe(childEl, { childList: true, subtree: true });
|
|
2852
|
-
if (!childEl.querySelector(".sibu-lazy-loading")) {
|
|
2853
|
-
container.replaceChildren(childEl);
|
|
2854
|
-
}
|
|
2855
3455
|
} else {
|
|
2856
3456
|
container.replaceChildren(childEl);
|
|
2857
3457
|
}
|
|
2858
|
-
} catch {
|
|
3458
|
+
} catch (err) {
|
|
3459
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3460
|
+
devWarn(`[SibuJS] Suspense nodes() threw: ${errorObj.message}`);
|
|
3461
|
+
dispatchPropagate(container, errorObj);
|
|
2859
3462
|
}
|
|
2860
3463
|
});
|
|
2861
3464
|
return container;
|
|
2862
3465
|
}
|
|
2863
3466
|
|
|
3467
|
+
// src/platform/ssr.ts
|
|
3468
|
+
var _isDev10 = isDev();
|
|
3469
|
+
function trustHTML(html3) {
|
|
3470
|
+
return html3;
|
|
3471
|
+
}
|
|
3472
|
+
var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
|
|
3473
|
+
|
|
2864
3474
|
// src/components/ErrorDisplay.ts
|
|
2865
|
-
var
|
|
3475
|
+
var _isDev11 = isDev();
|
|
2866
3476
|
var STYLES = `
|
|
2867
3477
|
.sibu-error-display {
|
|
2868
3478
|
border: 1px solid var(--sibu-err-border, #e5484d);
|
|
@@ -2948,20 +3558,21 @@ var STYLES = `
|
|
|
2948
3558
|
font-weight: 600;
|
|
2949
3559
|
}
|
|
2950
3560
|
.sibu-error-display .sibu-err-copy-btn {
|
|
2951
|
-
background:
|
|
2952
|
-
border: 1px solid
|
|
3561
|
+
background: rgba(0, 0, 0, 0.22);
|
|
3562
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
2953
3563
|
border-radius: 4px;
|
|
2954
|
-
color:
|
|
3564
|
+
color: rgba(255, 255, 255, 0.85);
|
|
2955
3565
|
cursor: pointer;
|
|
2956
3566
|
padding: 2px 10px;
|
|
2957
|
-
font-size: 0.
|
|
3567
|
+
font-size: 0.78em;
|
|
2958
3568
|
font-family: inherit;
|
|
2959
3569
|
transition: all 0.12s ease;
|
|
3570
|
+
flex-shrink: 0;
|
|
2960
3571
|
}
|
|
2961
3572
|
.sibu-error-display .sibu-err-copy-btn:hover {
|
|
2962
|
-
background:
|
|
2963
|
-
color:
|
|
2964
|
-
border-color:
|
|
3573
|
+
background: rgba(0, 0, 0, 0.35);
|
|
3574
|
+
color: white;
|
|
3575
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
2965
3576
|
}
|
|
2966
3577
|
|
|
2967
3578
|
.sibu-error-display .sibu-err-stack {
|
|
@@ -3086,21 +3697,25 @@ function normalizeError(err) {
|
|
|
3086
3697
|
cause: null
|
|
3087
3698
|
};
|
|
3088
3699
|
}
|
|
3089
|
-
function buildCopyText(err, meta2) {
|
|
3700
|
+
function buildCopyText(err, meta2, headline) {
|
|
3090
3701
|
const lines = [];
|
|
3702
|
+
lines.push(headline);
|
|
3091
3703
|
lines.push(`[${err.code}] ${err.message}`);
|
|
3092
3704
|
if (err.stack) {
|
|
3093
3705
|
lines.push("");
|
|
3706
|
+
lines.push("Stack Trace:");
|
|
3094
3707
|
lines.push(err.stack);
|
|
3095
3708
|
}
|
|
3096
|
-
|
|
3709
|
+
let cause = err.cause;
|
|
3710
|
+
while (cause) {
|
|
3097
3711
|
lines.push("");
|
|
3098
3712
|
lines.push("Caused by:");
|
|
3099
|
-
lines.push(` [${
|
|
3100
|
-
if (
|
|
3101
|
-
const indented =
|
|
3713
|
+
lines.push(` [${cause.code}] ${cause.message}`);
|
|
3714
|
+
if (cause.stack) {
|
|
3715
|
+
const indented = cause.stack.split("\n").map((l) => ` ${l}`).join("\n");
|
|
3102
3716
|
lines.push(indented);
|
|
3103
3717
|
}
|
|
3718
|
+
cause = cause.cause;
|
|
3104
3719
|
}
|
|
3105
3720
|
if (meta2 && Object.keys(meta2).length > 0) {
|
|
3106
3721
|
lines.push("");
|
|
@@ -3110,9 +3725,13 @@ function buildCopyText(err, meta2) {
|
|
|
3110
3725
|
}
|
|
3111
3726
|
}
|
|
3112
3727
|
lines.push("");
|
|
3113
|
-
lines.push(
|
|
3728
|
+
lines.push("Environment:");
|
|
3729
|
+
lines.push(` Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
3730
|
+
if (typeof location !== "undefined") {
|
|
3731
|
+
lines.push(` URL: ${location.href}`);
|
|
3732
|
+
}
|
|
3114
3733
|
if (typeof navigator !== "undefined" && navigator.userAgent) {
|
|
3115
|
-
lines.push(`
|
|
3734
|
+
lines.push(` User Agent: ${navigator.userAgent}`);
|
|
3116
3735
|
}
|
|
3117
3736
|
return lines.join("\n");
|
|
3118
3737
|
}
|
|
@@ -3164,7 +3783,7 @@ function ErrorDisplay(props) {
|
|
|
3164
3783
|
injectStyles();
|
|
3165
3784
|
const severity = props.severity ?? "error";
|
|
3166
3785
|
const normalized = normalizeError(props.error);
|
|
3167
|
-
const showDetails = props.alwaysShowDetails ??
|
|
3786
|
+
const showDetails = props.alwaysShowDetails ?? _isDev11;
|
|
3168
3787
|
const headline = props.title ?? normalized.message;
|
|
3169
3788
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
3170
3789
|
const [copyLabel, setCopyLabel] = signal("Copy");
|
|
@@ -3173,7 +3792,7 @@ function ErrorDisplay(props) {
|
|
|
3173
3792
|
nodes: () => copyLabel(),
|
|
3174
3793
|
on: {
|
|
3175
3794
|
click: () => {
|
|
3176
|
-
const text2 = buildCopyText(normalized, props.metadata);
|
|
3795
|
+
const text2 = buildCopyText(normalized, props.metadata, headline);
|
|
3177
3796
|
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
3178
3797
|
navigator.clipboard.writeText(text2).then(
|
|
3179
3798
|
() => {
|
|
@@ -3194,6 +3813,7 @@ function ErrorDisplay(props) {
|
|
|
3194
3813
|
nodes: [
|
|
3195
3814
|
code({ class: "sibu-err-icon", nodes: normalized.code }),
|
|
3196
3815
|
h3({ class: "sibu-err-title", nodes: headline }),
|
|
3816
|
+
copyBtn,
|
|
3197
3817
|
span({ class: "sibu-err-timestamp", nodes: timestamp })
|
|
3198
3818
|
]
|
|
3199
3819
|
});
|
|
@@ -3205,25 +3825,12 @@ function ErrorDisplay(props) {
|
|
|
3205
3825
|
nodes: [
|
|
3206
3826
|
div({
|
|
3207
3827
|
class: "sibu-err-section-head",
|
|
3208
|
-
nodes: [span({ nodes: "Stack Trace" })
|
|
3828
|
+
nodes: [span({ nodes: "Stack Trace" })]
|
|
3209
3829
|
}),
|
|
3210
3830
|
renderFrames(normalized.frames)
|
|
3211
3831
|
]
|
|
3212
3832
|
})
|
|
3213
3833
|
);
|
|
3214
|
-
} else if (showDetails) {
|
|
3215
|
-
bodyChildren.push(
|
|
3216
|
-
div({
|
|
3217
|
-
class: "sibu-err-section",
|
|
3218
|
-
nodes: [
|
|
3219
|
-
div({
|
|
3220
|
-
class: "sibu-err-section-head",
|
|
3221
|
-
nodes: [span({ nodes: "Details" }), copyBtn]
|
|
3222
|
-
}),
|
|
3223
|
-
div({ class: "sibu-err-stack", nodes: "(no stack available)" })
|
|
3224
|
-
]
|
|
3225
|
-
})
|
|
3226
|
-
);
|
|
3227
3834
|
}
|
|
3228
3835
|
if (showDetails) {
|
|
3229
3836
|
bodyChildren.push(...renderCauseChain(normalized.cause));
|
|
@@ -3239,37 +3846,6 @@ function ErrorDisplay(props) {
|
|
|
3239
3846
|
})
|
|
3240
3847
|
);
|
|
3241
3848
|
}
|
|
3242
|
-
if (showDetails && typeof navigator !== "undefined" && navigator.userAgent) {
|
|
3243
|
-
bodyChildren.push(
|
|
3244
|
-
div({
|
|
3245
|
-
class: "sibu-err-section",
|
|
3246
|
-
nodes: [
|
|
3247
|
-
div({ class: "sibu-err-section-head", nodes: [span({ nodes: "Environment" })] }),
|
|
3248
|
-
div({
|
|
3249
|
-
class: "sibu-err-meta",
|
|
3250
|
-
nodes: (() => {
|
|
3251
|
-
const dl2 = document.createElement("dl");
|
|
3252
|
-
dl2.className = "sibu-err-meta";
|
|
3253
|
-
const entries = [
|
|
3254
|
-
["User Agent", navigator.userAgent],
|
|
3255
|
-
["URL", typeof location !== "undefined" ? location.href : "(n/a)"],
|
|
3256
|
-
["Timestamp", (/* @__PURE__ */ new Date()).toISOString()]
|
|
3257
|
-
];
|
|
3258
|
-
for (const [k, v] of entries) {
|
|
3259
|
-
const dt2 = document.createElement("dt");
|
|
3260
|
-
dt2.textContent = k;
|
|
3261
|
-
const dd2 = document.createElement("dd");
|
|
3262
|
-
dd2.textContent = v;
|
|
3263
|
-
dl2.appendChild(dt2);
|
|
3264
|
-
dl2.appendChild(dd2);
|
|
3265
|
-
}
|
|
3266
|
-
return dl2;
|
|
3267
|
-
})()
|
|
3268
|
-
})
|
|
3269
|
-
]
|
|
3270
|
-
})
|
|
3271
|
-
);
|
|
3272
|
-
}
|
|
3273
3849
|
const actionButtons = [];
|
|
3274
3850
|
if (props.onRetry) {
|
|
3275
3851
|
actionButtons.push(
|
|
@@ -3464,6 +4040,7 @@ function injectStyles2() {
|
|
|
3464
4040
|
stylesInjected = true;
|
|
3465
4041
|
}
|
|
3466
4042
|
}
|
|
4043
|
+
var FALLBACK_CACHE_MAX = 50;
|
|
3467
4044
|
var fallbackCache = /* @__PURE__ */ new WeakMap();
|
|
3468
4045
|
function getMemoizedFallback(fallbackFn, error, retry) {
|
|
3469
4046
|
let cache2 = fallbackCache.get(fallbackFn);
|
|
@@ -3472,27 +4049,42 @@ function getMemoizedFallback(fallbackFn, error, retry) {
|
|
|
3472
4049
|
fallbackCache.set(fallbackFn, cache2);
|
|
3473
4050
|
}
|
|
3474
4051
|
const key = error.message;
|
|
3475
|
-
|
|
3476
|
-
|
|
4052
|
+
let factory = cache2.get(key);
|
|
4053
|
+
if (factory) {
|
|
4054
|
+
cache2.delete(key);
|
|
4055
|
+
cache2.set(key, factory);
|
|
4056
|
+
} else {
|
|
4057
|
+
factory = () => fallbackFn(error, retry);
|
|
4058
|
+
cache2.set(key, factory);
|
|
4059
|
+
if (cache2.size > FALLBACK_CACHE_MAX) {
|
|
4060
|
+
const oldestKey = cache2.keys().next().value;
|
|
4061
|
+
if (oldestKey !== void 0) cache2.delete(oldestKey);
|
|
4062
|
+
}
|
|
3477
4063
|
}
|
|
3478
|
-
return
|
|
4064
|
+
return factory();
|
|
3479
4065
|
}
|
|
3480
4066
|
function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
3481
4067
|
injectStyles2();
|
|
3482
4068
|
const [error, setError] = signal(null);
|
|
3483
4069
|
const retry = () => {
|
|
3484
4070
|
if (fallback) {
|
|
3485
|
-
|
|
4071
|
+
const cur = error();
|
|
4072
|
+
const inner = fallbackCache.get(fallback);
|
|
4073
|
+
if (cur && inner) inner.delete(cur.message);
|
|
3486
4074
|
}
|
|
3487
4075
|
setError(null);
|
|
3488
4076
|
};
|
|
4077
|
+
let resetKeysTeardown = null;
|
|
3489
4078
|
if (resetKeys && resetKeys.length > 0) {
|
|
3490
4079
|
let initialized = false;
|
|
3491
|
-
effect(() => {
|
|
4080
|
+
resetKeysTeardown = effect(() => {
|
|
3492
4081
|
for (const k of resetKeys) {
|
|
3493
4082
|
try {
|
|
3494
4083
|
k();
|
|
3495
|
-
} catch {
|
|
4084
|
+
} catch (err) {
|
|
4085
|
+
if (typeof console !== "undefined") {
|
|
4086
|
+
console.warn("[SibuJS ErrorBoundary] resetKeys getter threw:", err);
|
|
4087
|
+
}
|
|
3496
4088
|
}
|
|
3497
4089
|
}
|
|
3498
4090
|
if (!initialized) {
|
|
@@ -3505,7 +4097,15 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
|
3505
4097
|
const handleError = (e) => {
|
|
3506
4098
|
const errorObj = e instanceof Error ? e : new Error(String(e));
|
|
3507
4099
|
setError(errorObj);
|
|
3508
|
-
onError
|
|
4100
|
+
if (onError) {
|
|
4101
|
+
try {
|
|
4102
|
+
onError(errorObj);
|
|
4103
|
+
} catch (cbErr) {
|
|
4104
|
+
if (typeof console !== "undefined") {
|
|
4105
|
+
console.error("[SibuJS ErrorBoundary] onError callback threw:", cbErr);
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
}
|
|
3509
4109
|
return errorObj;
|
|
3510
4110
|
};
|
|
3511
4111
|
const defaultFallback = (err, retryFn) => {
|
|
@@ -3557,7 +4157,7 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
|
3557
4157
|
}
|
|
3558
4158
|
}
|
|
3559
4159
|
});
|
|
3560
|
-
|
|
4160
|
+
const propagateListener = (e) => {
|
|
3561
4161
|
if (error()) return;
|
|
3562
4162
|
e.stopPropagation();
|
|
3563
4163
|
const customEvent = e;
|
|
@@ -3565,6 +4165,30 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
|
3565
4165
|
if (propagatedError) {
|
|
3566
4166
|
handleError(propagatedError);
|
|
3567
4167
|
}
|
|
4168
|
+
};
|
|
4169
|
+
container.addEventListener("sibu:error-propagate", propagateListener);
|
|
4170
|
+
onMount(() => {
|
|
4171
|
+
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT);
|
|
4172
|
+
const collected = [];
|
|
4173
|
+
let node = walker.currentNode;
|
|
4174
|
+
while (node) {
|
|
4175
|
+
const pending = takePendingError(node);
|
|
4176
|
+
if (pending) collected.push(pending);
|
|
4177
|
+
node = walker.nextNode();
|
|
4178
|
+
}
|
|
4179
|
+
if (collected.length === 1) {
|
|
4180
|
+
handleError(collected[0]);
|
|
4181
|
+
} else if (collected.length > 1) {
|
|
4182
|
+
const Agg = globalThis.AggregateError;
|
|
4183
|
+
handleError(
|
|
4184
|
+
Agg ? new Agg(collected, `${collected.length} pre-mount errors caught by ErrorBoundary`) : new Error(collected.map((e) => e.message).join("; "))
|
|
4185
|
+
);
|
|
4186
|
+
}
|
|
4187
|
+
return void 0;
|
|
4188
|
+
}, container);
|
|
4189
|
+
registerDisposer(container, () => {
|
|
4190
|
+
if (resetKeysTeardown) resetKeysTeardown();
|
|
4191
|
+
container.removeEventListener("sibu:error-propagate", propagateListener);
|
|
3568
4192
|
});
|
|
3569
4193
|
return container;
|
|
3570
4194
|
}
|
|
@@ -3740,6 +4364,7 @@ function Loading(props = {}) {
|
|
|
3740
4364
|
footer,
|
|
3741
4365
|
form,
|
|
3742
4366
|
g,
|
|
4367
|
+
getSSRStore,
|
|
3743
4368
|
getSlot,
|
|
3744
4369
|
h1,
|
|
3745
4370
|
h2,
|
|
@@ -3812,6 +4437,7 @@ function Loading(props = {}) {
|
|
|
3812
4437
|
rp,
|
|
3813
4438
|
rt,
|
|
3814
4439
|
ruby,
|
|
4440
|
+
runInSSRContext,
|
|
3815
4441
|
s,
|
|
3816
4442
|
samp,
|
|
3817
4443
|
script,
|
|
@@ -3837,6 +4463,7 @@ function Loading(props = {}) {
|
|
|
3837
4463
|
symbol,
|
|
3838
4464
|
table,
|
|
3839
4465
|
tagFactory,
|
|
4466
|
+
takePendingError,
|
|
3840
4467
|
tbody,
|
|
3841
4468
|
td,
|
|
3842
4469
|
template,
|
|
@@ -3851,6 +4478,7 @@ function Loading(props = {}) {
|
|
|
3851
4478
|
track,
|
|
3852
4479
|
transition,
|
|
3853
4480
|
trapFocus,
|
|
4481
|
+
trustHTML,
|
|
3854
4482
|
tspan,
|
|
3855
4483
|
u,
|
|
3856
4484
|
ul,
|