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/build.cjs
CHANGED
|
@@ -1134,6 +1134,7 @@ __export(index_exports, {
|
|
|
1134
1134
|
footer: () => footer,
|
|
1135
1135
|
form: () => form,
|
|
1136
1136
|
g: () => g,
|
|
1137
|
+
getSSRStore: () => getSSRStore,
|
|
1137
1138
|
getSlot: () => getSlot,
|
|
1138
1139
|
h1: () => h1,
|
|
1139
1140
|
h2: () => h2,
|
|
@@ -1206,6 +1207,7 @@ __export(index_exports, {
|
|
|
1206
1207
|
rp: () => rp,
|
|
1207
1208
|
rt: () => rt,
|
|
1208
1209
|
ruby: () => ruby,
|
|
1210
|
+
runInSSRContext: () => runInSSRContext,
|
|
1209
1211
|
s: () => s,
|
|
1210
1212
|
samp: () => samp,
|
|
1211
1213
|
script: () => script,
|
|
@@ -1231,6 +1233,7 @@ __export(index_exports, {
|
|
|
1231
1233
|
symbol: () => symbol,
|
|
1232
1234
|
table: () => table,
|
|
1233
1235
|
tagFactory: () => tagFactory,
|
|
1236
|
+
takePendingError: () => takePendingError,
|
|
1234
1237
|
tbody: () => tbody,
|
|
1235
1238
|
td: () => td,
|
|
1236
1239
|
template: () => template,
|
|
@@ -1245,6 +1248,7 @@ __export(index_exports, {
|
|
|
1245
1248
|
track: () => track2,
|
|
1246
1249
|
transition: () => transition,
|
|
1247
1250
|
trapFocus: () => trapFocus,
|
|
1251
|
+
trustHTML: () => trustHTML,
|
|
1248
1252
|
tspan: () => tspan,
|
|
1249
1253
|
u: () => u,
|
|
1250
1254
|
ul: () => ul,
|
|
@@ -1266,33 +1270,80 @@ function isDev() {
|
|
|
1266
1270
|
var _isDev = isDev();
|
|
1267
1271
|
function devAssert(condition, message) {
|
|
1268
1272
|
if (_isDev && !condition) {
|
|
1269
|
-
throw new Error(`[
|
|
1273
|
+
throw new Error(`[SibuJS] ${message}`);
|
|
1270
1274
|
}
|
|
1271
1275
|
}
|
|
1272
1276
|
function devWarn(message) {
|
|
1273
1277
|
if (_isDev) {
|
|
1274
|
-
console.warn(`[
|
|
1278
|
+
console.warn(`[SibuJS] ${message}`);
|
|
1275
1279
|
}
|
|
1276
1280
|
}
|
|
1277
1281
|
|
|
1278
1282
|
// src/utils/sanitize.ts
|
|
1283
|
+
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
1279
1284
|
function sanitizeUrl(url) {
|
|
1280
1285
|
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
1281
1286
|
if (!trimmed) return "";
|
|
1282
1287
|
const lower = trimmed.toLowerCase();
|
|
1283
|
-
|
|
1284
|
-
|
|
1288
|
+
let schemeEnd = -1;
|
|
1289
|
+
for (let i2 = 0; i2 < lower.length; i2++) {
|
|
1290
|
+
const ch = lower.charCodeAt(i2);
|
|
1291
|
+
if (ch === 58) {
|
|
1292
|
+
schemeEnd = i2;
|
|
1293
|
+
break;
|
|
1294
|
+
}
|
|
1295
|
+
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
1285
1296
|
}
|
|
1297
|
+
if (schemeEnd === -1) return trimmed;
|
|
1298
|
+
const scheme = lower.slice(0, schemeEnd + 1);
|
|
1299
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return trimmed;
|
|
1300
|
+
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
1286
1301
|
return trimmed;
|
|
1287
1302
|
}
|
|
1303
|
+
function sanitizeSrcset(value) {
|
|
1304
|
+
const parts = value.split(",");
|
|
1305
|
+
const out = [];
|
|
1306
|
+
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
1307
|
+
const part = parts[i2].trim();
|
|
1308
|
+
if (!part) continue;
|
|
1309
|
+
const m = part.match(/^(\S+)(\s+.+)?$/);
|
|
1310
|
+
if (!m) continue;
|
|
1311
|
+
const safe = sanitizeUrl(m[1]);
|
|
1312
|
+
if (!safe) continue;
|
|
1313
|
+
out.push(m[2] ? `${safe}${m[2]}` : safe);
|
|
1314
|
+
}
|
|
1315
|
+
return out.join(", ");
|
|
1316
|
+
}
|
|
1288
1317
|
function sanitizeCSSValue(value) {
|
|
1289
|
-
const
|
|
1290
|
-
|
|
1318
|
+
const decoded = value.replace(/\\([0-9a-fA-F]{1,6})\s?/g, (_m, hex) => {
|
|
1319
|
+
const code2 = Number.parseInt(hex, 16);
|
|
1320
|
+
if (!Number.isFinite(code2) || code2 < 0 || code2 > 1114111) return "";
|
|
1321
|
+
try {
|
|
1322
|
+
return String.fromCodePoint(code2);
|
|
1323
|
+
} catch {
|
|
1324
|
+
return "";
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
const lower = decoded.toLowerCase().replace(/\s+/g, "");
|
|
1328
|
+
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")) {
|
|
1291
1329
|
return "";
|
|
1292
1330
|
}
|
|
1293
1331
|
return value;
|
|
1294
1332
|
}
|
|
1295
|
-
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
1333
|
+
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
1334
|
+
"href",
|
|
1335
|
+
"xlink:href",
|
|
1336
|
+
"src",
|
|
1337
|
+
"action",
|
|
1338
|
+
"formaction",
|
|
1339
|
+
"formtarget",
|
|
1340
|
+
"cite",
|
|
1341
|
+
"poster",
|
|
1342
|
+
"background",
|
|
1343
|
+
"srcset",
|
|
1344
|
+
"ping",
|
|
1345
|
+
"data"
|
|
1346
|
+
]);
|
|
1296
1347
|
function isUrlAttribute(attr) {
|
|
1297
1348
|
return URL_ATTRIBUTES.has(attr);
|
|
1298
1349
|
}
|
|
@@ -1303,11 +1354,11 @@ var subscriberStack = new Array(32);
|
|
|
1303
1354
|
var stackCapacity = 32;
|
|
1304
1355
|
var stackTop = -1;
|
|
1305
1356
|
var currentSubscriber = null;
|
|
1306
|
-
var signalSubscribers = /* @__PURE__ */ new WeakMap();
|
|
1307
1357
|
var SUBS = "__s";
|
|
1308
1358
|
var notifyDepth = 0;
|
|
1309
1359
|
var pendingQueue = [];
|
|
1310
1360
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
1361
|
+
var propagateStack = [];
|
|
1311
1362
|
function safeInvoke(sub2) {
|
|
1312
1363
|
try {
|
|
1313
1364
|
sub2();
|
|
@@ -1317,6 +1368,15 @@ function safeInvoke(sub2) {
|
|
|
1317
1368
|
}
|
|
1318
1369
|
var suspendDepth = 0;
|
|
1319
1370
|
var trackingSuspended = false;
|
|
1371
|
+
function retrack(effectFn, subscriber) {
|
|
1372
|
+
const prev = currentSubscriber;
|
|
1373
|
+
currentSubscriber = subscriber;
|
|
1374
|
+
try {
|
|
1375
|
+
effectFn();
|
|
1376
|
+
} finally {
|
|
1377
|
+
currentSubscriber = prev;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1320
1380
|
function track(effectFn, subscriber) {
|
|
1321
1381
|
if (!subscriber) subscriber = effectFn;
|
|
1322
1382
|
cleanup(subscriber);
|
|
@@ -1384,7 +1444,6 @@ function recordDependency(signal2) {
|
|
|
1384
1444
|
let subs = signal2[SUBS];
|
|
1385
1445
|
if (!subs) {
|
|
1386
1446
|
subs = /* @__PURE__ */ new Set();
|
|
1387
|
-
signalSubscribers.set(signal2, subs);
|
|
1388
1447
|
signal2[SUBS] = subs;
|
|
1389
1448
|
}
|
|
1390
1449
|
subs.add(currentSubscriber);
|
|
@@ -1406,17 +1465,17 @@ function queueSignalNotification(signal2) {
|
|
|
1406
1465
|
}
|
|
1407
1466
|
}
|
|
1408
1467
|
}
|
|
1409
|
-
var
|
|
1468
|
+
var maxDrainIterations = 1e5;
|
|
1410
1469
|
function drainNotificationQueue() {
|
|
1411
1470
|
if (notifyDepth > 0) return;
|
|
1412
1471
|
notifyDepth++;
|
|
1413
1472
|
try {
|
|
1414
1473
|
let i2 = 0;
|
|
1415
1474
|
while (i2 < pendingQueue.length) {
|
|
1416
|
-
if (i2 >=
|
|
1475
|
+
if (i2 >= maxDrainIterations) {
|
|
1417
1476
|
if (typeof console !== "undefined") {
|
|
1418
1477
|
console.error(
|
|
1419
|
-
`[SibuJS] Notification queue exceeded ${
|
|
1478
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
1420
1479
|
);
|
|
1421
1480
|
}
|
|
1422
1481
|
break;
|
|
@@ -1425,47 +1484,52 @@ function drainNotificationQueue() {
|
|
|
1425
1484
|
i2++;
|
|
1426
1485
|
}
|
|
1427
1486
|
} finally {
|
|
1428
|
-
pendingQueue.length = 0;
|
|
1429
|
-
pendingSet.clear();
|
|
1430
1487
|
notifyDepth--;
|
|
1488
|
+
if (notifyDepth === 0) {
|
|
1489
|
+
pendingQueue.length = 0;
|
|
1490
|
+
pendingSet.clear();
|
|
1491
|
+
}
|
|
1431
1492
|
}
|
|
1432
1493
|
}
|
|
1433
1494
|
function propagateDirty(sub2) {
|
|
1434
1495
|
sub2();
|
|
1435
|
-
|
|
1436
|
-
|
|
1496
|
+
const rootSig = sub2._sig;
|
|
1497
|
+
if (!rootSig) return;
|
|
1498
|
+
const stack = propagateStack;
|
|
1499
|
+
const baseLen = stack.length;
|
|
1500
|
+
stack.push(rootSig);
|
|
1501
|
+
while (stack.length > baseLen) {
|
|
1502
|
+
const sig = stack.pop();
|
|
1437
1503
|
const first = sig.__f;
|
|
1438
1504
|
if (first) {
|
|
1439
1505
|
if (first._c) {
|
|
1440
1506
|
const nSig = first._sig;
|
|
1441
|
-
nSig._d
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
if (!pendingSet.has(first)) {
|
|
1507
|
+
if (!nSig._d) {
|
|
1508
|
+
nSig._d = true;
|
|
1509
|
+
stack.push(nSig);
|
|
1510
|
+
}
|
|
1511
|
+
} else if (!pendingSet.has(first)) {
|
|
1446
1512
|
pendingSet.add(first);
|
|
1447
1513
|
pendingQueue.push(first);
|
|
1448
1514
|
}
|
|
1449
|
-
|
|
1515
|
+
continue;
|
|
1450
1516
|
}
|
|
1451
1517
|
const subs = sig[SUBS];
|
|
1452
|
-
if (!subs)
|
|
1453
|
-
let nextSig;
|
|
1518
|
+
if (!subs) continue;
|
|
1454
1519
|
for (const s2 of subs) {
|
|
1455
1520
|
if (s2._c) {
|
|
1456
|
-
s2();
|
|
1457
1521
|
const nSig = s2._sig;
|
|
1458
|
-
if (nSig && !
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1522
|
+
if (nSig && !nSig._d) {
|
|
1523
|
+
nSig._d = true;
|
|
1524
|
+
stack.push(nSig);
|
|
1525
|
+
} else if (!nSig) {
|
|
1526
|
+
s2();
|
|
1462
1527
|
}
|
|
1463
1528
|
} else if (!pendingSet.has(s2)) {
|
|
1464
1529
|
pendingSet.add(s2);
|
|
1465
1530
|
pendingQueue.push(s2);
|
|
1466
1531
|
}
|
|
1467
1532
|
}
|
|
1468
|
-
sig = nextSig;
|
|
1469
1533
|
}
|
|
1470
1534
|
}
|
|
1471
1535
|
function notifySubscribers(signal2) {
|
|
@@ -1489,13 +1553,23 @@ function notifySubscribers(signal2) {
|
|
|
1489
1553
|
}
|
|
1490
1554
|
let i2 = 0;
|
|
1491
1555
|
while (i2 < pendingQueue.length) {
|
|
1556
|
+
if (i2 >= maxDrainIterations) {
|
|
1557
|
+
if (typeof console !== "undefined") {
|
|
1558
|
+
console.error(
|
|
1559
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
break;
|
|
1563
|
+
}
|
|
1492
1564
|
safeInvoke(pendingQueue[i2]);
|
|
1493
1565
|
i2++;
|
|
1494
1566
|
}
|
|
1495
1567
|
} finally {
|
|
1496
|
-
pendingQueue.length = 0;
|
|
1497
|
-
pendingSet.clear();
|
|
1498
1568
|
notifyDepth--;
|
|
1569
|
+
if (notifyDepth === 0) {
|
|
1570
|
+
pendingQueue.length = 0;
|
|
1571
|
+
pendingSet.clear();
|
|
1572
|
+
}
|
|
1499
1573
|
}
|
|
1500
1574
|
return;
|
|
1501
1575
|
}
|
|
@@ -1515,30 +1589,48 @@ function notifySubscribers(signal2) {
|
|
|
1515
1589
|
notifyDepth++;
|
|
1516
1590
|
try {
|
|
1517
1591
|
let directCount = 0;
|
|
1592
|
+
let hasComputedSub = false;
|
|
1518
1593
|
for (const sub2 of subs) {
|
|
1594
|
+
if (sub2._c) hasComputedSub = true;
|
|
1519
1595
|
pendingQueue[directCount++] = sub2;
|
|
1520
1596
|
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1597
|
+
if (!hasComputedSub) {
|
|
1598
|
+
for (let i3 = 0; i3 < directCount; i3++) {
|
|
1599
|
+
safeInvoke(pendingQueue[i3]);
|
|
1524
1600
|
}
|
|
1525
|
-
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1601
|
+
} else {
|
|
1602
|
+
for (let i3 = 0; i3 < directCount; i3++) {
|
|
1603
|
+
if (pendingQueue[i3]._c) {
|
|
1604
|
+
propagateDirty(pendingQueue[i3]);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
for (let i3 = 0; i3 < directCount; i3++) {
|
|
1608
|
+
const sub2 = pendingQueue[i3];
|
|
1609
|
+
if (!sub2._c && !pendingSet.has(sub2)) {
|
|
1610
|
+
pendingSet.add(sub2);
|
|
1611
|
+
safeInvoke(sub2);
|
|
1530
1612
|
}
|
|
1531
1613
|
}
|
|
1532
1614
|
}
|
|
1533
1615
|
let i2 = directCount;
|
|
1534
1616
|
while (i2 < pendingQueue.length) {
|
|
1617
|
+
if (i2 - directCount >= maxDrainIterations) {
|
|
1618
|
+
if (typeof console !== "undefined") {
|
|
1619
|
+
console.error(
|
|
1620
|
+
`[SibuJS] Notification queue exceeded ${maxDrainIterations} iterations \u2014 likely an effect that writes to a signal it reads. Breaking to prevent infinite loop.`
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1623
|
+
break;
|
|
1624
|
+
}
|
|
1535
1625
|
safeInvoke(pendingQueue[i2]);
|
|
1536
1626
|
i2++;
|
|
1537
1627
|
}
|
|
1538
1628
|
} finally {
|
|
1539
|
-
pendingQueue.length = 0;
|
|
1540
|
-
pendingSet.clear();
|
|
1541
1629
|
notifyDepth--;
|
|
1630
|
+
if (notifyDepth === 0) {
|
|
1631
|
+
pendingQueue.length = 0;
|
|
1632
|
+
pendingSet.clear();
|
|
1633
|
+
}
|
|
1542
1634
|
}
|
|
1543
1635
|
}
|
|
1544
1636
|
function cleanup(subscriber) {
|
|
@@ -1549,7 +1641,9 @@ function cleanup(subscriber) {
|
|
|
1549
1641
|
if (subs) {
|
|
1550
1642
|
subs.delete(subscriber);
|
|
1551
1643
|
if (singleDep.__f === subscriber) {
|
|
1552
|
-
singleDep.__f = void 0;
|
|
1644
|
+
singleDep.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
1645
|
+
} else if (subs.size === 1 && singleDep.__f === void 0) {
|
|
1646
|
+
singleDep.__f = subs.values().next().value;
|
|
1553
1647
|
}
|
|
1554
1648
|
}
|
|
1555
1649
|
sub2._dep = void 0;
|
|
@@ -1562,7 +1656,9 @@ function cleanup(subscriber) {
|
|
|
1562
1656
|
if (subs) {
|
|
1563
1657
|
subs.delete(subscriber);
|
|
1564
1658
|
if (signal2.__f === subscriber) {
|
|
1565
|
-
signal2.__f = void 0;
|
|
1659
|
+
signal2.__f = subs.size === 1 ? subs.values().next().value : void 0;
|
|
1660
|
+
} else if (subs.size === 1 && signal2.__f === void 0) {
|
|
1661
|
+
signal2.__f = subs.values().next().value;
|
|
1566
1662
|
}
|
|
1567
1663
|
}
|
|
1568
1664
|
}
|
|
@@ -1571,6 +1667,9 @@ function cleanup(subscriber) {
|
|
|
1571
1667
|
|
|
1572
1668
|
// src/reactivity/bindAttribute.ts
|
|
1573
1669
|
var _isDev3 = isDev();
|
|
1670
|
+
function setProp(el, key, val) {
|
|
1671
|
+
el[key] = val;
|
|
1672
|
+
}
|
|
1574
1673
|
function isEventHandlerAttr(name) {
|
|
1575
1674
|
if (name.length < 3) return false;
|
|
1576
1675
|
const lower = name.toLowerCase();
|
|
@@ -1596,7 +1695,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
1596
1695
|
}
|
|
1597
1696
|
if (typeof value === "boolean") {
|
|
1598
1697
|
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
1599
|
-
el
|
|
1698
|
+
setProp(el, attr, value);
|
|
1600
1699
|
} else if (value) {
|
|
1601
1700
|
el.setAttribute(attr, "");
|
|
1602
1701
|
} else {
|
|
@@ -1606,7 +1705,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
1606
1705
|
}
|
|
1607
1706
|
const str = String(value);
|
|
1608
1707
|
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
1609
|
-
el
|
|
1708
|
+
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
1610
1709
|
} else {
|
|
1611
1710
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
1612
1711
|
}
|
|
@@ -1637,7 +1736,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
1637
1736
|
}
|
|
1638
1737
|
const str = String(value);
|
|
1639
1738
|
if ((name === "value" || name === "checked") && name in el) {
|
|
1640
|
-
el
|
|
1739
|
+
setProp(el, name, name === "checked" ? Boolean(value) : str);
|
|
1641
1740
|
} else {
|
|
1642
1741
|
el.setAttribute(name, isUrlAttribute(name) ? sanitizeUrl(str) : str);
|
|
1643
1742
|
}
|
|
@@ -1680,24 +1779,29 @@ function bindChildNode(placeholder, getter) {
|
|
|
1680
1779
|
let newNodes;
|
|
1681
1780
|
if (Array.isArray(result)) {
|
|
1682
1781
|
newNodes = [];
|
|
1782
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1683
1783
|
for (let i2 = 0; i2 < result.length; i2++) {
|
|
1684
1784
|
const item = result[i2];
|
|
1685
1785
|
if (item == null || typeof item === "boolean") continue;
|
|
1686
|
-
|
|
1786
|
+
const node = item instanceof Node ? item : document.createTextNode(String(item));
|
|
1787
|
+
if (seen.has(node)) {
|
|
1788
|
+
if (_isDev4)
|
|
1789
|
+
devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
1790
|
+
continue;
|
|
1791
|
+
}
|
|
1792
|
+
seen.add(node);
|
|
1793
|
+
newNodes.push(node);
|
|
1687
1794
|
}
|
|
1688
1795
|
} else {
|
|
1689
1796
|
const node = result instanceof Node ? result : document.createTextNode(String(result));
|
|
1690
1797
|
newNodes = [node];
|
|
1691
1798
|
}
|
|
1692
|
-
|
|
1693
|
-
if (
|
|
1799
|
+
let reused;
|
|
1800
|
+
if (lastNodes.length > 0 && newNodes.length > 0) {
|
|
1801
|
+
const lastSet = new Set(lastNodes);
|
|
1802
|
+
reused = /* @__PURE__ */ new Set();
|
|
1694
1803
|
for (let i2 = 0; i2 < newNodes.length; i2++) {
|
|
1695
|
-
|
|
1696
|
-
if (newNodes[i2] === lastNodes[j]) {
|
|
1697
|
-
reused.add(newNodes[i2]);
|
|
1698
|
-
break;
|
|
1699
|
-
}
|
|
1700
|
-
}
|
|
1804
|
+
if (lastSet.has(newNodes[i2])) reused.add(newNodes[i2]);
|
|
1701
1805
|
}
|
|
1702
1806
|
}
|
|
1703
1807
|
for (let i2 = 0; i2 < lastNodes.length; i2++) {
|
|
@@ -1740,7 +1844,7 @@ function dispose(node) {
|
|
|
1740
1844
|
while (stack.length > 0) {
|
|
1741
1845
|
const current = stack.pop();
|
|
1742
1846
|
order.push(current);
|
|
1743
|
-
const children = current.childNodes;
|
|
1847
|
+
const children = Array.from(current.childNodes);
|
|
1744
1848
|
for (let i2 = 0; i2 < children.length; i2++) {
|
|
1745
1849
|
stack.push(children[i2]);
|
|
1746
1850
|
}
|
|
@@ -1749,8 +1853,10 @@ function dispose(node) {
|
|
|
1749
1853
|
const current = order[i2];
|
|
1750
1854
|
const disposers = elementDisposers.get(current);
|
|
1751
1855
|
if (disposers) {
|
|
1752
|
-
|
|
1753
|
-
|
|
1856
|
+
const snapshot = disposers.slice();
|
|
1857
|
+
elementDisposers.delete(current);
|
|
1858
|
+
if (_isDev5) activeBindingCount -= snapshot.length;
|
|
1859
|
+
for (const d of snapshot) {
|
|
1754
1860
|
try {
|
|
1755
1861
|
d();
|
|
1756
1862
|
} catch (err) {
|
|
@@ -1759,7 +1865,23 @@ function dispose(node) {
|
|
|
1759
1865
|
}
|
|
1760
1866
|
}
|
|
1761
1867
|
}
|
|
1762
|
-
|
|
1868
|
+
let extraPasses = 0;
|
|
1869
|
+
while (extraPasses++ < 8) {
|
|
1870
|
+
const added = elementDisposers.get(current);
|
|
1871
|
+
if (!added || added.length === 0) break;
|
|
1872
|
+
const moreSnapshot = added.slice();
|
|
1873
|
+
elementDisposers.delete(current);
|
|
1874
|
+
if (_isDev5) activeBindingCount -= moreSnapshot.length;
|
|
1875
|
+
for (const d of moreSnapshot) {
|
|
1876
|
+
try {
|
|
1877
|
+
d();
|
|
1878
|
+
} catch (err) {
|
|
1879
|
+
if (_isDev5 && typeof console !== "undefined") {
|
|
1880
|
+
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1763
1885
|
}
|
|
1764
1886
|
}
|
|
1765
1887
|
}
|
|
@@ -1775,6 +1897,30 @@ function checkLeaks(warnThreshold = 0) {
|
|
|
1775
1897
|
|
|
1776
1898
|
// src/core/rendering/tagFactory.ts
|
|
1777
1899
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1900
|
+
var _isDev6 = isDev();
|
|
1901
|
+
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
1902
|
+
function validateTagName(tag) {
|
|
1903
|
+
const lower = tag.toLowerCase();
|
|
1904
|
+
if (BLOCKED_TAGS.has(lower)) {
|
|
1905
|
+
throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
1909
|
+
"config",
|
|
1910
|
+
"location",
|
|
1911
|
+
"history",
|
|
1912
|
+
"document",
|
|
1913
|
+
"window",
|
|
1914
|
+
"navigator",
|
|
1915
|
+
"name",
|
|
1916
|
+
"top",
|
|
1917
|
+
"parent",
|
|
1918
|
+
"self",
|
|
1919
|
+
"frames"
|
|
1920
|
+
]);
|
|
1921
|
+
function setProp2(el, key, val) {
|
|
1922
|
+
el[key] = val;
|
|
1923
|
+
}
|
|
1778
1924
|
var kebabCache = /* @__PURE__ */ new Map();
|
|
1779
1925
|
function toKebab(prop) {
|
|
1780
1926
|
let cached = kebabCache.get(prop);
|
|
@@ -1899,79 +2045,103 @@ function appendChildren(el, nodes) {
|
|
|
1899
2045
|
}
|
|
1900
2046
|
}
|
|
1901
2047
|
}
|
|
1902
|
-
var tagFactory = (tag, ns) =>
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
if (
|
|
1907
|
-
|
|
1908
|
-
|
|
2048
|
+
var tagFactory = (tag, ns) => {
|
|
2049
|
+
return (first, second) => {
|
|
2050
|
+
validateTagName(tag);
|
|
2051
|
+
const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
|
|
2052
|
+
if (first === void 0) return el;
|
|
2053
|
+
if (typeof first === "string") {
|
|
2054
|
+
if (second !== void 0) {
|
|
2055
|
+
el.setAttribute("class", first);
|
|
2056
|
+
appendChildren(el, second);
|
|
2057
|
+
return el;
|
|
2058
|
+
}
|
|
2059
|
+
el.textContent = first;
|
|
1909
2060
|
return el;
|
|
1910
2061
|
}
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2062
|
+
if (typeof first === "number") {
|
|
2063
|
+
el.textContent = String(first);
|
|
2064
|
+
return el;
|
|
2065
|
+
}
|
|
2066
|
+
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
2067
|
+
appendChildren(el, first);
|
|
2068
|
+
return el;
|
|
2069
|
+
}
|
|
2070
|
+
const props = first;
|
|
2071
|
+
const pClass = props.class;
|
|
2072
|
+
if (pClass != null) applyClass(el, pClass);
|
|
2073
|
+
const pId = props.id;
|
|
2074
|
+
if (pId != null) {
|
|
2075
|
+
if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
2076
|
+
devWarn(
|
|
2077
|
+
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
2078
|
+
);
|
|
2079
|
+
}
|
|
2080
|
+
el.id = pId;
|
|
2081
|
+
}
|
|
2082
|
+
const pNodes = second !== void 0 ? second : props.nodes;
|
|
2083
|
+
if (pNodes != null) appendChildren(el, pNodes);
|
|
2084
|
+
const pOn = props.on;
|
|
2085
|
+
if (pOn) {
|
|
2086
|
+
for (const ev in pOn) {
|
|
2087
|
+
const handler = pOn[ev];
|
|
2088
|
+
if (typeof handler === "function") {
|
|
2089
|
+
el.addEventListener(ev, handler);
|
|
2090
|
+
} else if (_isDev6) {
|
|
2091
|
+
devWarn(
|
|
2092
|
+
`tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
}
|
|
2097
|
+
const pStyle = props.style;
|
|
2098
|
+
if (pStyle != null) applyStyle(el, pStyle);
|
|
2099
|
+
const pRef = props.ref;
|
|
2100
|
+
if (pRef) pRef.current = el;
|
|
2101
|
+
for (const key in props) {
|
|
2102
|
+
switch (key) {
|
|
2103
|
+
case "class":
|
|
2104
|
+
case "id":
|
|
2105
|
+
case "nodes":
|
|
2106
|
+
case "on":
|
|
2107
|
+
case "style":
|
|
2108
|
+
case "ref":
|
|
2109
|
+
case "onElement":
|
|
2110
|
+
continue;
|
|
2111
|
+
// already handled above / below
|
|
2112
|
+
default: {
|
|
2113
|
+
const value = props[key];
|
|
2114
|
+
if (value == null) continue;
|
|
2115
|
+
const lkey = key.toLowerCase();
|
|
2116
|
+
if (lkey[0] === "o" && lkey[1] === "n") continue;
|
|
2117
|
+
if (typeof value === "function") {
|
|
2118
|
+
registerDisposer(el, bindAttribute(el, key, value));
|
|
2119
|
+
} else if (typeof value === "boolean") {
|
|
2120
|
+
if (key in el && (key === "checked" || key === "disabled" || key === "selected")) {
|
|
2121
|
+
setProp2(el, key, value);
|
|
2122
|
+
} else if (value) {
|
|
2123
|
+
el.setAttribute(key, "");
|
|
2124
|
+
} else {
|
|
2125
|
+
el.removeAttribute(key);
|
|
2126
|
+
}
|
|
1961
2127
|
} else {
|
|
1962
|
-
|
|
2128
|
+
const str = String(value);
|
|
2129
|
+
if (lkey === "srcset") {
|
|
2130
|
+
el.setAttribute(key, sanitizeSrcset(str));
|
|
2131
|
+
} else if (isUrlAttribute(lkey)) {
|
|
2132
|
+
el.setAttribute(key, sanitizeUrl(str));
|
|
2133
|
+
} else {
|
|
2134
|
+
el.setAttribute(key, str);
|
|
2135
|
+
}
|
|
1963
2136
|
}
|
|
1964
|
-
} else {
|
|
1965
|
-
const str = String(value);
|
|
1966
|
-
el.setAttribute(key, isUrlAttribute(key) ? sanitizeUrl(str) : str);
|
|
1967
2137
|
}
|
|
1968
2138
|
}
|
|
1969
2139
|
}
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
2140
|
+
if (props.onElement && typeof props.onElement === "function") {
|
|
2141
|
+
props.onElement(el);
|
|
2142
|
+
}
|
|
2143
|
+
return el;
|
|
2144
|
+
};
|
|
1975
2145
|
};
|
|
1976
2146
|
|
|
1977
2147
|
// src/core/rendering/html.ts
|
|
@@ -2114,6 +2284,8 @@ var marquee = tagFactory("marquee");
|
|
|
2114
2284
|
var customElement = (tagName) => tagFactory(tagName);
|
|
2115
2285
|
|
|
2116
2286
|
// src/core/rendering/htm.ts
|
|
2287
|
+
var _isDev7 = isDev();
|
|
2288
|
+
var RAW_TEXT_TAGS = /* @__PURE__ */ new Set(["script", "style"]);
|
|
2117
2289
|
var VOID_ELEMENTS3 = /* @__PURE__ */ new Set([
|
|
2118
2290
|
"area",
|
|
2119
2291
|
"base",
|
|
@@ -2298,6 +2470,15 @@ function parseTemplate(strings) {
|
|
|
2298
2470
|
children.push({ t: 0, el: { tag, svg: SVG_TAGS2.has(tag), attrs, children: [] } });
|
|
2299
2471
|
} else {
|
|
2300
2472
|
const inner = parseChildren();
|
|
2473
|
+
if (RAW_TEXT_TAGS.has(tag.toLowerCase())) {
|
|
2474
|
+
for (let i2 = 0; i2 < inner.length; i2++) {
|
|
2475
|
+
if (inner[i2].t === 2) {
|
|
2476
|
+
throw new Error(
|
|
2477
|
+
`html: dynamic \${...} expressions are not allowed inside <${tag}> (raw-text context). Build the content separately and append it as a Node.`
|
|
2478
|
+
);
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2301
2482
|
if (template2[pos] === "<" && pos + 1 < len && template2[pos + 1] === "/") {
|
|
2302
2483
|
pos += 2;
|
|
2303
2484
|
readTagName();
|
|
@@ -2324,27 +2505,50 @@ function executeElement(tmpl, values) {
|
|
|
2324
2505
|
break;
|
|
2325
2506
|
case 1: {
|
|
2326
2507
|
const name = attr.name;
|
|
2327
|
-
|
|
2508
|
+
const lname = name.toLowerCase();
|
|
2509
|
+
if (lname[0] === "o" && lname[1] === "n") break;
|
|
2328
2510
|
const val = values[attr.idx];
|
|
2329
2511
|
if (typeof val === "function") {
|
|
2330
2512
|
registerDisposer(el, bindAttribute(el, name, val));
|
|
2331
2513
|
} else if (val != null) {
|
|
2332
2514
|
const str = String(val);
|
|
2333
|
-
|
|
2515
|
+
if (lname === "srcset") {
|
|
2516
|
+
el.setAttribute(name, sanitizeSrcset(str));
|
|
2517
|
+
} else if (isUrlAttribute(lname)) {
|
|
2518
|
+
el.setAttribute(name, sanitizeUrl(str));
|
|
2519
|
+
} else {
|
|
2520
|
+
el.setAttribute(name, str);
|
|
2521
|
+
}
|
|
2334
2522
|
}
|
|
2335
2523
|
break;
|
|
2336
2524
|
}
|
|
2337
2525
|
case 2: {
|
|
2338
2526
|
let val = attr.statics[0];
|
|
2339
2527
|
for (let j = 0; j < attr.exprs.length; j++) {
|
|
2340
|
-
|
|
2528
|
+
const ev = values[attr.exprs[j]];
|
|
2529
|
+
val += (ev == null ? "" : String(ev)) + attr.statics[j + 1];
|
|
2530
|
+
}
|
|
2531
|
+
const lname2 = attr.name.toLowerCase();
|
|
2532
|
+
if (lname2 === "srcset") {
|
|
2533
|
+
el.setAttribute(attr.name, sanitizeSrcset(val));
|
|
2534
|
+
} else if (isUrlAttribute(lname2)) {
|
|
2535
|
+
el.setAttribute(attr.name, sanitizeUrl(val));
|
|
2536
|
+
} else {
|
|
2537
|
+
el.setAttribute(attr.name, val);
|
|
2341
2538
|
}
|
|
2342
|
-
el.setAttribute(attr.name, val);
|
|
2343
2539
|
break;
|
|
2344
2540
|
}
|
|
2345
|
-
case 3:
|
|
2346
|
-
|
|
2541
|
+
case 3: {
|
|
2542
|
+
const fn = values[attr.idx];
|
|
2543
|
+
if (typeof fn === "function") {
|
|
2544
|
+
el.addEventListener(attr.name, fn);
|
|
2545
|
+
} else if (_isDev7) {
|
|
2546
|
+
devWarn(
|
|
2547
|
+
`html: on:${attr.name} handler is not a function (got ${typeof fn}). Event listener was not attached.`
|
|
2548
|
+
);
|
|
2549
|
+
}
|
|
2347
2550
|
break;
|
|
2551
|
+
}
|
|
2348
2552
|
case 4:
|
|
2349
2553
|
el.setAttribute(attr.name, "");
|
|
2350
2554
|
break;
|
|
@@ -2438,7 +2642,7 @@ function html2(strings, ...values) {
|
|
|
2438
2642
|
function mount(component, container) {
|
|
2439
2643
|
if (!container) {
|
|
2440
2644
|
throw new Error(
|
|
2441
|
-
"[
|
|
2645
|
+
"[SibuJS mount] container element not found. Make sure the DOM element exists before calling mount()."
|
|
2442
2646
|
);
|
|
2443
2647
|
}
|
|
2444
2648
|
devAssert(
|
|
@@ -2466,7 +2670,7 @@ function mount(component, container) {
|
|
|
2466
2670
|
}
|
|
2467
2671
|
|
|
2468
2672
|
// src/core/rendering/each.ts
|
|
2469
|
-
var
|
|
2673
|
+
var _isDev8 = isDev();
|
|
2470
2674
|
function resolveNodeChild(child) {
|
|
2471
2675
|
if (typeof child === "function") {
|
|
2472
2676
|
return resolveNodeChild(child());
|
|
@@ -2561,17 +2765,31 @@ function each(getArray, render, options) {
|
|
|
2561
2765
|
node = existing;
|
|
2562
2766
|
} else {
|
|
2563
2767
|
const itemKey = key;
|
|
2564
|
-
const itemGetter = () => getArray()[keyIndexMap.get(itemKey)];
|
|
2768
|
+
const itemGetter = () => untracked(() => getArray()[keyIndexMap.get(itemKey)]);
|
|
2565
2769
|
const indexGetter = () => keyIndexMap.get(itemKey);
|
|
2566
2770
|
try {
|
|
2567
2771
|
node = resolveNodeChild(render(itemGetter, indexGetter));
|
|
2568
2772
|
} catch (err) {
|
|
2569
|
-
if (
|
|
2773
|
+
if (_isDev8) {
|
|
2570
2774
|
devWarn(
|
|
2571
2775
|
`each: render threw for item at index ${i2} (key="${newKeys[i2]}"): ${err instanceof Error ? err.message : String(err)}`
|
|
2572
2776
|
);
|
|
2573
2777
|
}
|
|
2574
2778
|
node = document.createComment(`each:error:${i2}`);
|
|
2779
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2780
|
+
queueMicrotask(() => {
|
|
2781
|
+
try {
|
|
2782
|
+
const target = anchor.parentNode;
|
|
2783
|
+
if (target?.dispatchEvent) {
|
|
2784
|
+
target.dispatchEvent(
|
|
2785
|
+
new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error: errorObj } })
|
|
2786
|
+
);
|
|
2787
|
+
} else if (_isDev8) {
|
|
2788
|
+
devWarn(`each: error not surfaced \u2014 anchor detached: ${errorObj.message}`);
|
|
2789
|
+
}
|
|
2790
|
+
} catch {
|
|
2791
|
+
}
|
|
2792
|
+
});
|
|
2575
2793
|
}
|
|
2576
2794
|
}
|
|
2577
2795
|
workMap.set(key, node);
|
|
@@ -2640,7 +2858,8 @@ function each(getArray, render, options) {
|
|
|
2640
2858
|
workMap = tmp;
|
|
2641
2859
|
initialized = true;
|
|
2642
2860
|
};
|
|
2643
|
-
track(update);
|
|
2861
|
+
const untrack = track(update);
|
|
2862
|
+
registerDisposer(anchor, untrack);
|
|
2644
2863
|
if (!initialized) {
|
|
2645
2864
|
queueMicrotask(() => {
|
|
2646
2865
|
if (!initialized && anchor.parentNode) {
|
|
@@ -2687,7 +2906,9 @@ function Portal(nodes, target) {
|
|
|
2687
2906
|
const anchor = document.createComment("portal");
|
|
2688
2907
|
const container = target || document.body;
|
|
2689
2908
|
let portalContent = null;
|
|
2909
|
+
let disposed = false;
|
|
2690
2910
|
queueMicrotask(() => {
|
|
2911
|
+
if (disposed) return;
|
|
2691
2912
|
try {
|
|
2692
2913
|
portalContent = nodes();
|
|
2693
2914
|
container.appendChild(portalContent);
|
|
@@ -2695,9 +2916,22 @@ function Portal(nodes, target) {
|
|
|
2695
2916
|
if (typeof console !== "undefined") {
|
|
2696
2917
|
console.error("[Portal] Render error:", err);
|
|
2697
2918
|
}
|
|
2919
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2920
|
+
queueMicrotask(() => {
|
|
2921
|
+
try {
|
|
2922
|
+
const target2 = anchor.parentNode;
|
|
2923
|
+
if (target2?.dispatchEvent) {
|
|
2924
|
+
target2.dispatchEvent(
|
|
2925
|
+
new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error: errorObj } })
|
|
2926
|
+
);
|
|
2927
|
+
}
|
|
2928
|
+
} catch {
|
|
2929
|
+
}
|
|
2930
|
+
});
|
|
2698
2931
|
}
|
|
2699
2932
|
});
|
|
2700
2933
|
registerDisposer(anchor, () => {
|
|
2934
|
+
disposed = true;
|
|
2701
2935
|
if (portalContent) {
|
|
2702
2936
|
dispose(portalContent);
|
|
2703
2937
|
portalContent.remove();
|
|
@@ -2737,7 +2971,8 @@ function DynamicComponent(is) {
|
|
|
2737
2971
|
}
|
|
2738
2972
|
container.replaceChildren(el);
|
|
2739
2973
|
}
|
|
2740
|
-
track(render);
|
|
2974
|
+
const untrack = track(render);
|
|
2975
|
+
registerDisposer(container, untrack);
|
|
2741
2976
|
return container;
|
|
2742
2977
|
}
|
|
2743
2978
|
|
|
@@ -2827,11 +3062,16 @@ function KeepAlive(activeKey, cases, options) {
|
|
|
2827
3062
|
const anchor = document.createComment("keep-alive");
|
|
2828
3063
|
const cache2 = /* @__PURE__ */ new Map();
|
|
2829
3064
|
const lruOrder = [];
|
|
2830
|
-
const max = options?.max ??
|
|
3065
|
+
const max = options?.max ?? 10;
|
|
3066
|
+
if (max === 0 && isDev()) {
|
|
3067
|
+
devWarn("KeepAlive: unbounded cache (max: 0). Cached subtrees will never be evicted \u2014 set `max` to bound memory.");
|
|
3068
|
+
}
|
|
2831
3069
|
let currentKey;
|
|
2832
3070
|
let currentNode = null;
|
|
2833
3071
|
let initialized = false;
|
|
3072
|
+
let disposed = false;
|
|
2834
3073
|
const update = () => {
|
|
3074
|
+
if (disposed) return;
|
|
2835
3075
|
const key = activeKey();
|
|
2836
3076
|
const parent = anchor.parentNode;
|
|
2837
3077
|
if (!parent) return;
|
|
@@ -2871,12 +3111,23 @@ function KeepAlive(activeKey, cases, options) {
|
|
|
2871
3111
|
currentNode = node;
|
|
2872
3112
|
initialized = true;
|
|
2873
3113
|
};
|
|
2874
|
-
track(update);
|
|
3114
|
+
const untrack = track(update);
|
|
2875
3115
|
if (!initialized) {
|
|
2876
3116
|
queueMicrotask(() => {
|
|
2877
3117
|
if (!initialized && anchor.parentNode) update();
|
|
2878
3118
|
});
|
|
2879
3119
|
}
|
|
3120
|
+
registerDisposer(anchor, () => {
|
|
3121
|
+
disposed = true;
|
|
3122
|
+
untrack();
|
|
3123
|
+
for (const node of cache2.values()) {
|
|
3124
|
+
dispose(node);
|
|
3125
|
+
if (node.parentNode) node.parentNode.removeChild(node);
|
|
3126
|
+
}
|
|
3127
|
+
cache2.clear();
|
|
3128
|
+
lruOrder.length = 0;
|
|
3129
|
+
currentNode = null;
|
|
3130
|
+
});
|
|
2880
3131
|
return anchor;
|
|
2881
3132
|
}
|
|
2882
3133
|
|
|
@@ -3038,19 +3289,22 @@ function isBatching() {
|
|
|
3038
3289
|
return batchDepth > 0;
|
|
3039
3290
|
}
|
|
3040
3291
|
function flushBatch() {
|
|
3041
|
-
|
|
3042
|
-
|
|
3292
|
+
try {
|
|
3293
|
+
for (const signal2 of pendingSignals) {
|
|
3294
|
+
queueSignalNotification(signal2);
|
|
3295
|
+
}
|
|
3296
|
+
} finally {
|
|
3297
|
+
pendingSignals.clear();
|
|
3043
3298
|
}
|
|
3044
|
-
pendingSignals.clear();
|
|
3045
3299
|
drainNotificationQueue();
|
|
3046
3300
|
}
|
|
3047
3301
|
|
|
3048
3302
|
// src/core/signals/signal.ts
|
|
3049
3303
|
var _g = globalThis;
|
|
3050
|
-
var
|
|
3304
|
+
var _isDev9 = isDev();
|
|
3051
3305
|
function signal(initial, options) {
|
|
3052
3306
|
const state = { value: initial };
|
|
3053
|
-
const debugName =
|
|
3307
|
+
const debugName = _isDev9 ? options?.name : void 0;
|
|
3054
3308
|
const equalsFn = options?.equals;
|
|
3055
3309
|
if (debugName) {
|
|
3056
3310
|
state.__name = debugName;
|
|
@@ -3064,7 +3318,7 @@ function signal(initial, options) {
|
|
|
3064
3318
|
function set(next) {
|
|
3065
3319
|
const newValue = typeof next === "function" ? next(state.value) : next;
|
|
3066
3320
|
if (equalsFn ? equalsFn(state.value, newValue) : Object.is(newValue, state.value)) return;
|
|
3067
|
-
if (
|
|
3321
|
+
if (_isDev9) {
|
|
3068
3322
|
const oldValue = state.value;
|
|
3069
3323
|
state.value = newValue;
|
|
3070
3324
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -3076,7 +3330,7 @@ function signal(initial, options) {
|
|
|
3076
3330
|
notifySubscribers(state);
|
|
3077
3331
|
}
|
|
3078
3332
|
}
|
|
3079
|
-
if (
|
|
3333
|
+
if (_isDev9) {
|
|
3080
3334
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
3081
3335
|
if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
|
|
3082
3336
|
}
|
|
@@ -3084,23 +3338,59 @@ function signal(initial, options) {
|
|
|
3084
3338
|
}
|
|
3085
3339
|
|
|
3086
3340
|
// src/core/ssr-context.ts
|
|
3087
|
-
var
|
|
3341
|
+
var als = null;
|
|
3342
|
+
try {
|
|
3343
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
3344
|
+
const req = Function("return typeof require==='function'?require:null")();
|
|
3345
|
+
if (req) {
|
|
3346
|
+
const mod = req("node:async_hooks");
|
|
3347
|
+
als = new mod.AsyncLocalStorage();
|
|
3348
|
+
}
|
|
3349
|
+
}
|
|
3350
|
+
} catch {
|
|
3351
|
+
als = null;
|
|
3352
|
+
}
|
|
3353
|
+
var fallbackStore = { ssr: false, suspenseIdCounter: 0 };
|
|
3354
|
+
function getSSRStore() {
|
|
3355
|
+
if (als) {
|
|
3356
|
+
const s2 = als.getStore();
|
|
3357
|
+
if (s2) return s2;
|
|
3358
|
+
}
|
|
3359
|
+
return fallbackStore;
|
|
3360
|
+
}
|
|
3088
3361
|
function isSSR() {
|
|
3089
|
-
return
|
|
3362
|
+
return getSSRStore().ssr;
|
|
3090
3363
|
}
|
|
3091
3364
|
function enableSSR() {
|
|
3092
|
-
|
|
3365
|
+
getSSRStore().ssr = true;
|
|
3093
3366
|
}
|
|
3094
3367
|
function disableSSR() {
|
|
3095
|
-
|
|
3368
|
+
getSSRStore().ssr = false;
|
|
3369
|
+
}
|
|
3370
|
+
function runInSSRContext(fn) {
|
|
3371
|
+
const store2 = { ssr: true, suspenseIdCounter: 0 };
|
|
3372
|
+
if (als) {
|
|
3373
|
+
return als.run(store2, fn);
|
|
3374
|
+
}
|
|
3375
|
+
const prevSSR = fallbackStore.ssr;
|
|
3376
|
+
const prevCounter = fallbackStore.suspenseIdCounter;
|
|
3377
|
+
fallbackStore.ssr = true;
|
|
3378
|
+
fallbackStore.suspenseIdCounter = 0;
|
|
3379
|
+
try {
|
|
3380
|
+
return fn();
|
|
3381
|
+
} finally {
|
|
3382
|
+
fallbackStore.ssr = prevSSR;
|
|
3383
|
+
fallbackStore.suspenseIdCounter = prevCounter;
|
|
3384
|
+
}
|
|
3096
3385
|
}
|
|
3097
3386
|
function withSSR(fn) {
|
|
3098
|
-
const
|
|
3099
|
-
|
|
3387
|
+
const store2 = getSSRStore();
|
|
3388
|
+
const wasSSR = store2.ssr;
|
|
3389
|
+
store2.ssr = true;
|
|
3100
3390
|
try {
|
|
3101
3391
|
return fn();
|
|
3102
3392
|
} finally {
|
|
3103
|
-
if (!wasSSR)
|
|
3393
|
+
if (!wasSSR) store2.ssr = false;
|
|
3104
3394
|
}
|
|
3105
3395
|
}
|
|
3106
3396
|
|
|
@@ -3127,26 +3417,86 @@ function effect(effectFn, options) {
|
|
|
3127
3417
|
if (isSSR()) return () => {
|
|
3128
3418
|
};
|
|
3129
3419
|
const onError = options?.onError;
|
|
3420
|
+
let userCleanups = [];
|
|
3421
|
+
const onCleanup2 = (fn) => {
|
|
3422
|
+
userCleanups.push(fn);
|
|
3423
|
+
};
|
|
3424
|
+
const runUserCleanups = () => {
|
|
3425
|
+
if (userCleanups.length === 0) return;
|
|
3426
|
+
const list = userCleanups;
|
|
3427
|
+
userCleanups = [];
|
|
3428
|
+
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
3429
|
+
try {
|
|
3430
|
+
list[i2]();
|
|
3431
|
+
} catch (err) {
|
|
3432
|
+
if (typeof console !== "undefined") {
|
|
3433
|
+
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
3434
|
+
}
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
};
|
|
3438
|
+
const invokeBody = () => effectFn(onCleanup2);
|
|
3130
3439
|
const wrappedFn = onError ? () => {
|
|
3131
3440
|
try {
|
|
3132
|
-
|
|
3441
|
+
invokeBody();
|
|
3133
3442
|
} catch (err) {
|
|
3134
3443
|
onError(err);
|
|
3135
3444
|
}
|
|
3136
|
-
} :
|
|
3445
|
+
} : invokeBody;
|
|
3137
3446
|
let cleanupHandle = () => {
|
|
3138
3447
|
};
|
|
3448
|
+
let running = false;
|
|
3139
3449
|
const subscriber = () => {
|
|
3140
|
-
|
|
3141
|
-
|
|
3450
|
+
if (running) {
|
|
3451
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
3452
|
+
console.warn(
|
|
3453
|
+
"[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."
|
|
3454
|
+
);
|
|
3455
|
+
}
|
|
3456
|
+
return;
|
|
3457
|
+
}
|
|
3458
|
+
running = true;
|
|
3459
|
+
try {
|
|
3460
|
+
runUserCleanups();
|
|
3461
|
+
cleanupHandle();
|
|
3462
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
3463
|
+
} finally {
|
|
3464
|
+
running = false;
|
|
3465
|
+
}
|
|
3142
3466
|
};
|
|
3143
|
-
|
|
3467
|
+
running = true;
|
|
3468
|
+
try {
|
|
3469
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
3470
|
+
} finally {
|
|
3471
|
+
running = false;
|
|
3472
|
+
}
|
|
3144
3473
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
3145
3474
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
3475
|
+
let disposed = false;
|
|
3146
3476
|
return () => {
|
|
3477
|
+
if (disposed) return;
|
|
3478
|
+
disposed = true;
|
|
3147
3479
|
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
3148
|
-
if (h)
|
|
3149
|
-
|
|
3480
|
+
if (h) {
|
|
3481
|
+
try {
|
|
3482
|
+
h.emit("effect:destroy", { effectFn });
|
|
3483
|
+
} catch {
|
|
3484
|
+
}
|
|
3485
|
+
}
|
|
3486
|
+
try {
|
|
3487
|
+
runUserCleanups();
|
|
3488
|
+
} catch (err) {
|
|
3489
|
+
if (typeof console !== "undefined") {
|
|
3490
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
3491
|
+
}
|
|
3492
|
+
}
|
|
3493
|
+
try {
|
|
3494
|
+
cleanupHandle();
|
|
3495
|
+
} catch (err) {
|
|
3496
|
+
if (typeof console !== "undefined") {
|
|
3497
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
3498
|
+
}
|
|
3499
|
+
}
|
|
3150
3500
|
};
|
|
3151
3501
|
}
|
|
3152
3502
|
|
|
@@ -3154,6 +3504,7 @@ function effect(effectFn, options) {
|
|
|
3154
3504
|
function derived(getter, options) {
|
|
3155
3505
|
devAssert(typeof getter === "function", "derived: argument must be a getter function.");
|
|
3156
3506
|
const debugName = options?.name;
|
|
3507
|
+
const equals = options?.equals;
|
|
3157
3508
|
const cs = {};
|
|
3158
3509
|
cs._d = false;
|
|
3159
3510
|
cs._g = getter;
|
|
@@ -3164,8 +3515,14 @@ function derived(getter, options) {
|
|
|
3164
3515
|
markDirty._c = 1;
|
|
3165
3516
|
markDirty._sig = cs;
|
|
3166
3517
|
track(() => {
|
|
3167
|
-
|
|
3168
|
-
|
|
3518
|
+
let threw = true;
|
|
3519
|
+
try {
|
|
3520
|
+
cs._v = getter();
|
|
3521
|
+
cs._d = false;
|
|
3522
|
+
threw = false;
|
|
3523
|
+
} finally {
|
|
3524
|
+
if (threw) cs._d = true;
|
|
3525
|
+
}
|
|
3169
3526
|
}, markDirty);
|
|
3170
3527
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
3171
3528
|
let evaluating = false;
|
|
@@ -3178,11 +3535,16 @@ function derived(getter, options) {
|
|
|
3178
3535
|
if (trackingSuspended) {
|
|
3179
3536
|
if (cs._d) {
|
|
3180
3537
|
evaluating = true;
|
|
3538
|
+
let threw = true;
|
|
3181
3539
|
try {
|
|
3182
|
-
|
|
3183
|
-
|
|
3540
|
+
retrack(() => {
|
|
3541
|
+
cs._v = getter();
|
|
3542
|
+
cs._d = false;
|
|
3543
|
+
threw = false;
|
|
3544
|
+
}, markDirty);
|
|
3184
3545
|
} finally {
|
|
3185
3546
|
evaluating = false;
|
|
3547
|
+
if (threw) cs._d = true;
|
|
3186
3548
|
}
|
|
3187
3549
|
}
|
|
3188
3550
|
return cs._v;
|
|
@@ -3191,13 +3553,17 @@ function derived(getter, options) {
|
|
|
3191
3553
|
if (cs._d) {
|
|
3192
3554
|
const oldValue = cs._v;
|
|
3193
3555
|
evaluating = true;
|
|
3556
|
+
let threw = true;
|
|
3194
3557
|
try {
|
|
3195
|
-
|
|
3558
|
+
retrack(() => {
|
|
3559
|
+
const next = getter();
|
|
3560
|
+
cs._v = equals && cs._v !== void 0 ? equals(cs._v, next) ? cs._v : next : next;
|
|
3196
3561
|
cs._d = false;
|
|
3197
|
-
|
|
3562
|
+
threw = false;
|
|
3198
3563
|
}, markDirty);
|
|
3199
3564
|
} finally {
|
|
3200
3565
|
evaluating = false;
|
|
3566
|
+
if (threw) cs._d = true;
|
|
3201
3567
|
}
|
|
3202
3568
|
if (hook && oldValue !== cs._v) {
|
|
3203
3569
|
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
@@ -3259,7 +3625,7 @@ function store(initialState) {
|
|
|
3259
3625
|
},
|
|
3260
3626
|
set() {
|
|
3261
3627
|
throw new Error(
|
|
3262
|
-
"[
|
|
3628
|
+
"[SibuJS store] Direct mutation is not allowed. Use actions.setState() to update store properties."
|
|
3263
3629
|
);
|
|
3264
3630
|
}
|
|
3265
3631
|
});
|
|
@@ -3273,16 +3639,20 @@ function store(initialState) {
|
|
|
3273
3639
|
const setState = (patch) => {
|
|
3274
3640
|
const current = getSnapshot();
|
|
3275
3641
|
const nextState = typeof patch === "function" ? patch(current) : patch;
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
signals
|
|
3279
|
-
|
|
3642
|
+
batch(() => {
|
|
3643
|
+
Object.entries(nextState).forEach(([key, value]) => {
|
|
3644
|
+
if (key in signals) {
|
|
3645
|
+
signals[key][1](value);
|
|
3646
|
+
}
|
|
3647
|
+
});
|
|
3280
3648
|
});
|
|
3281
3649
|
};
|
|
3282
3650
|
const reset = () => {
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3651
|
+
batch(() => {
|
|
3652
|
+
Object.keys(initialState).forEach((key) => {
|
|
3653
|
+
const setter = signals[key][1];
|
|
3654
|
+
setter(initialState[key]);
|
|
3655
|
+
});
|
|
3286
3656
|
});
|
|
3287
3657
|
};
|
|
3288
3658
|
const subscribe = (callback) => {
|
|
@@ -3416,7 +3786,8 @@ function reactiveArray(initial = []) {
|
|
|
3416
3786
|
function get() {
|
|
3417
3787
|
recordDependency(signal2);
|
|
3418
3788
|
if (snapshot === null) {
|
|
3419
|
-
|
|
3789
|
+
const copy = data2.slice();
|
|
3790
|
+
snapshot = Object.freeze(copy);
|
|
3420
3791
|
}
|
|
3421
3792
|
return snapshot;
|
|
3422
3793
|
}
|
|
@@ -3612,26 +3983,34 @@ function asyncDerived(factory, initial) {
|
|
|
3612
3983
|
effect(() => {
|
|
3613
3984
|
tick();
|
|
3614
3985
|
const currentRun = ++runId;
|
|
3615
|
-
|
|
3616
|
-
|
|
3986
|
+
batch(() => {
|
|
3987
|
+
setLoading(true);
|
|
3988
|
+
setError(null);
|
|
3989
|
+
});
|
|
3617
3990
|
let promise;
|
|
3618
3991
|
try {
|
|
3619
3992
|
promise = factory();
|
|
3620
3993
|
} catch (err) {
|
|
3621
|
-
|
|
3622
|
-
|
|
3994
|
+
batch(() => {
|
|
3995
|
+
setError(err);
|
|
3996
|
+
setLoading(false);
|
|
3997
|
+
});
|
|
3623
3998
|
return;
|
|
3624
3999
|
}
|
|
3625
4000
|
promise.then(
|
|
3626
4001
|
(result) => {
|
|
3627
4002
|
if (currentRun !== runId) return;
|
|
3628
|
-
|
|
3629
|
-
|
|
4003
|
+
batch(() => {
|
|
4004
|
+
setValue(result);
|
|
4005
|
+
setLoading(false);
|
|
4006
|
+
});
|
|
3630
4007
|
},
|
|
3631
4008
|
(err) => {
|
|
3632
4009
|
if (currentRun !== runId) return;
|
|
3633
|
-
|
|
3634
|
-
|
|
4010
|
+
batch(() => {
|
|
4011
|
+
setError(err);
|
|
4012
|
+
setLoading(false);
|
|
4013
|
+
});
|
|
3635
4014
|
}
|
|
3636
4015
|
);
|
|
3637
4016
|
});
|
|
@@ -3658,26 +4037,186 @@ function runMountCallback(callback, hookName, element) {
|
|
|
3658
4037
|
registerDisposer(element, cleanup2);
|
|
3659
4038
|
}
|
|
3660
4039
|
}
|
|
4040
|
+
var mountWatchers = /* @__PURE__ */ new WeakMap();
|
|
4041
|
+
var unmountWatchers = /* @__PURE__ */ new WeakMap();
|
|
4042
|
+
var watchedMountElements = /* @__PURE__ */ new Set();
|
|
4043
|
+
var watchedUnmountElements = /* @__PURE__ */ new Set();
|
|
4044
|
+
var sharedObserver = null;
|
|
4045
|
+
var mutationCounter = 0;
|
|
4046
|
+
var FULL_SWEEP_INTERVAL = 256;
|
|
4047
|
+
function fireMount(el) {
|
|
4048
|
+
const cbs = mountWatchers.get(el);
|
|
4049
|
+
if (!cbs) return;
|
|
4050
|
+
mountWatchers.delete(el);
|
|
4051
|
+
watchedMountElements.delete(el);
|
|
4052
|
+
for (const cb of cbs) {
|
|
4053
|
+
try {
|
|
4054
|
+
cb();
|
|
4055
|
+
} catch {
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
4059
|
+
function fireUnmount(el) {
|
|
4060
|
+
const cbs = unmountWatchers.get(el);
|
|
4061
|
+
if (!cbs) return;
|
|
4062
|
+
queueMicrotask(() => {
|
|
4063
|
+
if (el.isConnected) return;
|
|
4064
|
+
const stillCbs = unmountWatchers.get(el);
|
|
4065
|
+
if (!stillCbs) return;
|
|
4066
|
+
unmountWatchers.delete(el);
|
|
4067
|
+
watchedUnmountElements.delete(el);
|
|
4068
|
+
for (const cb of stillCbs) {
|
|
4069
|
+
try {
|
|
4070
|
+
cb();
|
|
4071
|
+
} catch {
|
|
4072
|
+
}
|
|
4073
|
+
}
|
|
4074
|
+
});
|
|
4075
|
+
}
|
|
4076
|
+
function visitAddedNode(node) {
|
|
4077
|
+
if (watchedMountElements.size === 0) return;
|
|
4078
|
+
if (node.nodeType !== 1) return;
|
|
4079
|
+
const el = node;
|
|
4080
|
+
if (watchedMountElements.has(el) && el.isConnected) {
|
|
4081
|
+
fireMount(el);
|
|
4082
|
+
}
|
|
4083
|
+
if (el.firstElementChild) {
|
|
4084
|
+
for (const watched of Array.from(watchedMountElements)) {
|
|
4085
|
+
if (watched !== el && watched.isConnected && el.contains(watched)) {
|
|
4086
|
+
fireMount(watched);
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
}
|
|
4090
|
+
}
|
|
4091
|
+
function visitRemovedNode(node) {
|
|
4092
|
+
if (watchedUnmountElements.size === 0) return;
|
|
4093
|
+
if (node.nodeType !== 1) return;
|
|
4094
|
+
const el = node;
|
|
4095
|
+
if (watchedUnmountElements.has(el) && !el.isConnected) {
|
|
4096
|
+
fireUnmount(el);
|
|
4097
|
+
}
|
|
4098
|
+
if (el.firstElementChild) {
|
|
4099
|
+
for (const watched of Array.from(watchedUnmountElements)) {
|
|
4100
|
+
if (watched !== el && !watched.isConnected && el.contains(watched)) {
|
|
4101
|
+
fireUnmount(watched);
|
|
4102
|
+
}
|
|
4103
|
+
}
|
|
4104
|
+
}
|
|
4105
|
+
}
|
|
4106
|
+
function fullSweep() {
|
|
4107
|
+
if (watchedMountElements.size > 0) {
|
|
4108
|
+
for (const el of Array.from(watchedMountElements)) {
|
|
4109
|
+
if (el.isConnected) fireMount(el);
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
if (watchedUnmountElements.size > 0) {
|
|
4113
|
+
for (const el of Array.from(watchedUnmountElements)) {
|
|
4114
|
+
if (!el.isConnected) fireUnmount(el);
|
|
4115
|
+
}
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
function ensureObserver() {
|
|
4119
|
+
if (sharedObserver || typeof document === "undefined") return;
|
|
4120
|
+
sharedObserver = new MutationObserver((mutations) => {
|
|
4121
|
+
for (const m of mutations) {
|
|
4122
|
+
if (m.type !== "childList") continue;
|
|
4123
|
+
if (m.addedNodes.length > 0) {
|
|
4124
|
+
for (let i2 = 0; i2 < m.addedNodes.length; i2++) {
|
|
4125
|
+
visitAddedNode(m.addedNodes[i2]);
|
|
4126
|
+
}
|
|
4127
|
+
}
|
|
4128
|
+
if (m.removedNodes.length > 0) {
|
|
4129
|
+
for (let i2 = 0; i2 < m.removedNodes.length; i2++) {
|
|
4130
|
+
visitRemovedNode(m.removedNodes[i2]);
|
|
4131
|
+
}
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4134
|
+
mutationCounter += mutations.length;
|
|
4135
|
+
if (mutationCounter >= FULL_SWEEP_INTERVAL) {
|
|
4136
|
+
mutationCounter = 0;
|
|
4137
|
+
fullSweep();
|
|
4138
|
+
}
|
|
4139
|
+
maybeDisconnectObserver();
|
|
4140
|
+
});
|
|
4141
|
+
sharedObserver.observe(document.body, { childList: true, subtree: true });
|
|
4142
|
+
}
|
|
4143
|
+
function maybeDisconnectObserver() {
|
|
4144
|
+
if (!sharedObserver) return;
|
|
4145
|
+
if (watchedMountElements.size === 0 && watchedUnmountElements.size === 0) {
|
|
4146
|
+
sharedObserver.disconnect();
|
|
4147
|
+
sharedObserver = null;
|
|
4148
|
+
mutationCounter = 0;
|
|
4149
|
+
}
|
|
4150
|
+
}
|
|
4151
|
+
function registerMountWatcher(element, cb) {
|
|
4152
|
+
let list = mountWatchers.get(element);
|
|
4153
|
+
if (!list) {
|
|
4154
|
+
list = [];
|
|
4155
|
+
mountWatchers.set(element, list);
|
|
4156
|
+
}
|
|
4157
|
+
list.push(cb);
|
|
4158
|
+
watchedMountElements.add(element);
|
|
4159
|
+
ensureObserver();
|
|
4160
|
+
return () => {
|
|
4161
|
+
const cbs = mountWatchers.get(element);
|
|
4162
|
+
if (cbs) {
|
|
4163
|
+
const idx = cbs.indexOf(cb);
|
|
4164
|
+
if (idx !== -1) cbs.splice(idx, 1);
|
|
4165
|
+
if (cbs.length === 0) {
|
|
4166
|
+
mountWatchers.delete(element);
|
|
4167
|
+
watchedMountElements.delete(element);
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
maybeDisconnectObserver();
|
|
4171
|
+
};
|
|
4172
|
+
}
|
|
4173
|
+
function registerUnmountWatcher(element, cb) {
|
|
4174
|
+
let list = unmountWatchers.get(element);
|
|
4175
|
+
if (!list) {
|
|
4176
|
+
list = [];
|
|
4177
|
+
unmountWatchers.set(element, list);
|
|
4178
|
+
}
|
|
4179
|
+
list.push(cb);
|
|
4180
|
+
watchedUnmountElements.add(element);
|
|
4181
|
+
ensureObserver();
|
|
4182
|
+
return () => {
|
|
4183
|
+
const cbs = unmountWatchers.get(element);
|
|
4184
|
+
if (cbs) {
|
|
4185
|
+
const idx = cbs.indexOf(cb);
|
|
4186
|
+
if (idx !== -1) cbs.splice(idx, 1);
|
|
4187
|
+
if (cbs.length === 0) {
|
|
4188
|
+
unmountWatchers.delete(element);
|
|
4189
|
+
watchedUnmountElements.delete(element);
|
|
4190
|
+
}
|
|
4191
|
+
}
|
|
4192
|
+
maybeDisconnectObserver();
|
|
4193
|
+
};
|
|
4194
|
+
}
|
|
3661
4195
|
function onMount(callback, element) {
|
|
3662
4196
|
if (typeof document === "undefined") return;
|
|
3663
4197
|
if (element) {
|
|
4198
|
+
let disposed = false;
|
|
4199
|
+
registerDisposer(element, () => {
|
|
4200
|
+
disposed = true;
|
|
4201
|
+
});
|
|
3664
4202
|
if (element.isConnected) {
|
|
3665
|
-
queueMicrotask(() =>
|
|
4203
|
+
queueMicrotask(() => {
|
|
4204
|
+
if (disposed) return;
|
|
4205
|
+
runMountCallback(callback, "onMount", element);
|
|
4206
|
+
});
|
|
3666
4207
|
return;
|
|
3667
4208
|
}
|
|
3668
|
-
const observer = new MutationObserver(() => {
|
|
3669
|
-
if (element.isConnected) {
|
|
3670
|
-
observer.disconnect();
|
|
3671
|
-
runMountCallback(callback, "onMount", element);
|
|
3672
|
-
}
|
|
3673
|
-
});
|
|
3674
|
-
registerDisposer(element, () => observer.disconnect());
|
|
3675
4209
|
queueMicrotask(() => {
|
|
4210
|
+
if (disposed) return;
|
|
3676
4211
|
if (element.isConnected) {
|
|
3677
4212
|
runMountCallback(callback, "onMount", element);
|
|
3678
|
-
|
|
3679
|
-
observer.observe(document.body, { childList: true, subtree: true });
|
|
4213
|
+
return;
|
|
3680
4214
|
}
|
|
4215
|
+
const unregister = registerMountWatcher(element, () => {
|
|
4216
|
+
if (disposed) return;
|
|
4217
|
+
runMountCallback(callback, "onMount", element);
|
|
4218
|
+
});
|
|
4219
|
+
registerDisposer(element, unregister);
|
|
3681
4220
|
});
|
|
3682
4221
|
} else {
|
|
3683
4222
|
queueMicrotask(() => {
|
|
@@ -3686,22 +4225,24 @@ function onMount(callback, element) {
|
|
|
3686
4225
|
}
|
|
3687
4226
|
}
|
|
3688
4227
|
function onUnmount(callback, element) {
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
|
|
4228
|
+
if (typeof document === "undefined") return;
|
|
4229
|
+
let fired = false;
|
|
4230
|
+
const fireOnce = () => {
|
|
4231
|
+
if (fired) return;
|
|
4232
|
+
fired = true;
|
|
4233
|
+
safeCall(callback, "onUnmount");
|
|
4234
|
+
};
|
|
4235
|
+
registerDisposer(element, fireOnce);
|
|
4236
|
+
const startWatching = () => {
|
|
4237
|
+
if (fired) return;
|
|
4238
|
+
const unregister = registerUnmountWatcher(element, fireOnce);
|
|
4239
|
+
registerDisposer(element, unregister);
|
|
3699
4240
|
};
|
|
3700
4241
|
if (element.isConnected) {
|
|
3701
|
-
|
|
4242
|
+
startWatching();
|
|
3702
4243
|
} else {
|
|
3703
4244
|
onMount(() => {
|
|
3704
|
-
|
|
4245
|
+
startWatching();
|
|
3705
4246
|
return void 0;
|
|
3706
4247
|
}, element);
|
|
3707
4248
|
}
|
|
@@ -3713,9 +4254,11 @@ function onCleanup(callback, element) {
|
|
|
3713
4254
|
// src/core/rendering/context.ts
|
|
3714
4255
|
function context(defaultValue) {
|
|
3715
4256
|
const [getValue, setValue] = signal(defaultValue);
|
|
3716
|
-
|
|
4257
|
+
const ctx = {
|
|
3717
4258
|
provide(value) {
|
|
4259
|
+
const previous = getValue();
|
|
3718
4260
|
setValue(value);
|
|
4261
|
+
return () => setValue(previous);
|
|
3719
4262
|
},
|
|
3720
4263
|
use() {
|
|
3721
4264
|
return getValue;
|
|
@@ -3725,8 +4268,18 @@ function context(defaultValue) {
|
|
|
3725
4268
|
},
|
|
3726
4269
|
set(value) {
|
|
3727
4270
|
setValue(value);
|
|
4271
|
+
},
|
|
4272
|
+
withContext(value, fn) {
|
|
4273
|
+
const previous = getValue();
|
|
4274
|
+
setValue(value);
|
|
4275
|
+
try {
|
|
4276
|
+
return fn();
|
|
4277
|
+
} finally {
|
|
4278
|
+
setValue(previous);
|
|
4279
|
+
}
|
|
3728
4280
|
}
|
|
3729
4281
|
};
|
|
4282
|
+
return ctx;
|
|
3730
4283
|
}
|
|
3731
4284
|
|
|
3732
4285
|
// src/core/strict.ts
|
|
@@ -3737,7 +4290,7 @@ function strict(fn) {
|
|
|
3737
4290
|
try {
|
|
3738
4291
|
fn();
|
|
3739
4292
|
} catch (err) {
|
|
3740
|
-
console.warn("[
|
|
4293
|
+
console.warn("[SibuJS strict] second run threw:", err);
|
|
3741
4294
|
}
|
|
3742
4295
|
});
|
|
3743
4296
|
}
|
|
@@ -3753,7 +4306,7 @@ function strictEffect(fn) {
|
|
|
3753
4306
|
try {
|
|
3754
4307
|
secondTeardown = effect(fn);
|
|
3755
4308
|
} catch (err) {
|
|
3756
|
-
console.warn("[
|
|
4309
|
+
console.warn("[SibuJS strictEffect] second run threw:", err);
|
|
3757
4310
|
}
|
|
3758
4311
|
});
|
|
3759
4312
|
return () => {
|
|
@@ -3779,9 +4332,11 @@ function nextTick() {
|
|
|
3779
4332
|
function defer(getter) {
|
|
3780
4333
|
const [value, setValue] = signal(getter());
|
|
3781
4334
|
let pending = false;
|
|
4335
|
+
let disposed = false;
|
|
3782
4336
|
let latest = value();
|
|
3783
4337
|
const flush = () => {
|
|
3784
4338
|
pending = false;
|
|
4339
|
+
if (disposed) return;
|
|
3785
4340
|
setValue(latest);
|
|
3786
4341
|
};
|
|
3787
4342
|
const schedule = () => {
|
|
@@ -3795,11 +4350,17 @@ function defer(getter) {
|
|
|
3795
4350
|
}
|
|
3796
4351
|
});
|
|
3797
4352
|
};
|
|
3798
|
-
track(() => {
|
|
4353
|
+
const teardown = track(() => {
|
|
3799
4354
|
latest = getter();
|
|
3800
4355
|
schedule();
|
|
3801
4356
|
});
|
|
3802
|
-
|
|
4357
|
+
const accessor = (() => value());
|
|
4358
|
+
accessor.dispose = () => {
|
|
4359
|
+
if (disposed) return;
|
|
4360
|
+
disposed = true;
|
|
4361
|
+
teardown();
|
|
4362
|
+
};
|
|
4363
|
+
return accessor;
|
|
3803
4364
|
}
|
|
3804
4365
|
var IDLE_FALLBACK_MS = 16;
|
|
3805
4366
|
function scheduleIdle(fn) {
|
|
@@ -3840,6 +4401,32 @@ function transition() {
|
|
|
3840
4401
|
}
|
|
3841
4402
|
|
|
3842
4403
|
// src/core/rendering/lazy.ts
|
|
4404
|
+
var PENDING_ERROR = "__sibuPendingError";
|
|
4405
|
+
function dispatchPropagate(node, error) {
|
|
4406
|
+
const fire = () => {
|
|
4407
|
+
try {
|
|
4408
|
+
if (!node.parentNode) return false;
|
|
4409
|
+
node.dispatchEvent(new CustomEvent("sibu:error-propagate", { bubbles: true, detail: { error } }));
|
|
4410
|
+
return true;
|
|
4411
|
+
} catch {
|
|
4412
|
+
return false;
|
|
4413
|
+
}
|
|
4414
|
+
};
|
|
4415
|
+
if (node.parentNode && fire()) return;
|
|
4416
|
+
queueMicrotask(() => {
|
|
4417
|
+
if (fire()) return;
|
|
4418
|
+
node[PENDING_ERROR] = error;
|
|
4419
|
+
});
|
|
4420
|
+
}
|
|
4421
|
+
function takePendingError(node) {
|
|
4422
|
+
const rec = node;
|
|
4423
|
+
const err = rec[PENDING_ERROR];
|
|
4424
|
+
if (err instanceof Error) {
|
|
4425
|
+
delete rec[PENDING_ERROR];
|
|
4426
|
+
return err;
|
|
4427
|
+
}
|
|
4428
|
+
return void 0;
|
|
4429
|
+
}
|
|
3843
4430
|
function lazy(importFn) {
|
|
3844
4431
|
let cached = null;
|
|
3845
4432
|
return function LazyComponent() {
|
|
@@ -3856,14 +4443,14 @@ function lazy(importFn) {
|
|
|
3856
4443
|
}).catch((err) => {
|
|
3857
4444
|
if (disposed) return;
|
|
3858
4445
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3859
|
-
|
|
4446
|
+
devWarn(`[SibuJS] lazy() failed to load component: ${errorObj.message}`);
|
|
4447
|
+
container.replaceChildren(div({ class: "sibu-lazy-error" }, `Failed to load component: ${errorObj.message}`));
|
|
4448
|
+
dispatchPropagate(container, errorObj);
|
|
3860
4449
|
});
|
|
3861
4450
|
container.appendChild(span("sibu-lazy-loading", "Loading..."));
|
|
3862
|
-
|
|
3863
|
-
container.remove = () => {
|
|
4451
|
+
registerDisposer(container, () => {
|
|
3864
4452
|
disposed = true;
|
|
3865
|
-
|
|
3866
|
-
};
|
|
4453
|
+
});
|
|
3867
4454
|
return container;
|
|
3868
4455
|
};
|
|
3869
4456
|
}
|
|
@@ -3871,32 +4458,55 @@ function Suspense({ nodes, fallback }) {
|
|
|
3871
4458
|
const container = div({ class: "sibu-suspense" });
|
|
3872
4459
|
const fallbackEl = fallback();
|
|
3873
4460
|
container.appendChild(fallbackEl);
|
|
4461
|
+
let suspenseDisposed = false;
|
|
4462
|
+
let observer = null;
|
|
4463
|
+
registerDisposer(container, () => {
|
|
4464
|
+
suspenseDisposed = true;
|
|
4465
|
+
if (observer) {
|
|
4466
|
+
observer.disconnect();
|
|
4467
|
+
observer = null;
|
|
4468
|
+
}
|
|
4469
|
+
});
|
|
3874
4470
|
queueMicrotask(() => {
|
|
4471
|
+
if (suspenseDisposed) return;
|
|
3875
4472
|
try {
|
|
3876
4473
|
const childEl = nodes();
|
|
3877
4474
|
if (childEl.classList.contains("sibu-lazy")) {
|
|
3878
|
-
|
|
4475
|
+
if (!childEl.querySelector(".sibu-lazy-loading")) {
|
|
4476
|
+
container.replaceChildren(childEl);
|
|
4477
|
+
return;
|
|
4478
|
+
}
|
|
4479
|
+
observer = new MutationObserver(() => {
|
|
4480
|
+
if (suspenseDisposed) return;
|
|
3879
4481
|
const loading = childEl.querySelector(".sibu-lazy-loading");
|
|
3880
4482
|
if (!loading) {
|
|
3881
|
-
observer
|
|
4483
|
+
observer?.disconnect();
|
|
4484
|
+
observer = null;
|
|
3882
4485
|
container.replaceChildren(childEl);
|
|
3883
4486
|
}
|
|
3884
4487
|
});
|
|
3885
4488
|
observer.observe(childEl, { childList: true, subtree: true });
|
|
3886
|
-
if (!childEl.querySelector(".sibu-lazy-loading")) {
|
|
3887
|
-
container.replaceChildren(childEl);
|
|
3888
|
-
}
|
|
3889
4489
|
} else {
|
|
3890
4490
|
container.replaceChildren(childEl);
|
|
3891
4491
|
}
|
|
3892
|
-
} catch {
|
|
4492
|
+
} catch (err) {
|
|
4493
|
+
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
4494
|
+
devWarn(`[SibuJS] Suspense nodes() threw: ${errorObj.message}`);
|
|
4495
|
+
dispatchPropagate(container, errorObj);
|
|
3893
4496
|
}
|
|
3894
4497
|
});
|
|
3895
4498
|
return container;
|
|
3896
4499
|
}
|
|
3897
4500
|
|
|
4501
|
+
// src/platform/ssr.ts
|
|
4502
|
+
var _isDev10 = isDev();
|
|
4503
|
+
function trustHTML(html3) {
|
|
4504
|
+
return html3;
|
|
4505
|
+
}
|
|
4506
|
+
var DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
|
|
4507
|
+
|
|
3898
4508
|
// src/components/ErrorDisplay.ts
|
|
3899
|
-
var
|
|
4509
|
+
var _isDev11 = isDev();
|
|
3900
4510
|
var STYLES = `
|
|
3901
4511
|
.sibu-error-display {
|
|
3902
4512
|
border: 1px solid var(--sibu-err-border, #e5484d);
|
|
@@ -3982,20 +4592,21 @@ var STYLES = `
|
|
|
3982
4592
|
font-weight: 600;
|
|
3983
4593
|
}
|
|
3984
4594
|
.sibu-error-display .sibu-err-copy-btn {
|
|
3985
|
-
background:
|
|
3986
|
-
border: 1px solid
|
|
4595
|
+
background: rgba(0, 0, 0, 0.22);
|
|
4596
|
+
border: 1px solid rgba(255, 255, 255, 0.15);
|
|
3987
4597
|
border-radius: 4px;
|
|
3988
|
-
color:
|
|
4598
|
+
color: rgba(255, 255, 255, 0.85);
|
|
3989
4599
|
cursor: pointer;
|
|
3990
4600
|
padding: 2px 10px;
|
|
3991
|
-
font-size: 0.
|
|
4601
|
+
font-size: 0.78em;
|
|
3992
4602
|
font-family: inherit;
|
|
3993
4603
|
transition: all 0.12s ease;
|
|
4604
|
+
flex-shrink: 0;
|
|
3994
4605
|
}
|
|
3995
4606
|
.sibu-error-display .sibu-err-copy-btn:hover {
|
|
3996
|
-
background:
|
|
3997
|
-
color:
|
|
3998
|
-
border-color:
|
|
4607
|
+
background: rgba(0, 0, 0, 0.35);
|
|
4608
|
+
color: white;
|
|
4609
|
+
border-color: rgba(255, 255, 255, 0.3);
|
|
3999
4610
|
}
|
|
4000
4611
|
|
|
4001
4612
|
.sibu-error-display .sibu-err-stack {
|
|
@@ -4120,21 +4731,25 @@ function normalizeError(err) {
|
|
|
4120
4731
|
cause: null
|
|
4121
4732
|
};
|
|
4122
4733
|
}
|
|
4123
|
-
function buildCopyText(err, meta2) {
|
|
4734
|
+
function buildCopyText(err, meta2, headline) {
|
|
4124
4735
|
const lines = [];
|
|
4736
|
+
lines.push(headline);
|
|
4125
4737
|
lines.push(`[${err.code}] ${err.message}`);
|
|
4126
4738
|
if (err.stack) {
|
|
4127
4739
|
lines.push("");
|
|
4740
|
+
lines.push("Stack Trace:");
|
|
4128
4741
|
lines.push(err.stack);
|
|
4129
4742
|
}
|
|
4130
|
-
|
|
4743
|
+
let cause = err.cause;
|
|
4744
|
+
while (cause) {
|
|
4131
4745
|
lines.push("");
|
|
4132
4746
|
lines.push("Caused by:");
|
|
4133
|
-
lines.push(` [${
|
|
4134
|
-
if (
|
|
4135
|
-
const indented =
|
|
4747
|
+
lines.push(` [${cause.code}] ${cause.message}`);
|
|
4748
|
+
if (cause.stack) {
|
|
4749
|
+
const indented = cause.stack.split("\n").map((l) => ` ${l}`).join("\n");
|
|
4136
4750
|
lines.push(indented);
|
|
4137
4751
|
}
|
|
4752
|
+
cause = cause.cause;
|
|
4138
4753
|
}
|
|
4139
4754
|
if (meta2 && Object.keys(meta2).length > 0) {
|
|
4140
4755
|
lines.push("");
|
|
@@ -4144,9 +4759,13 @@ function buildCopyText(err, meta2) {
|
|
|
4144
4759
|
}
|
|
4145
4760
|
}
|
|
4146
4761
|
lines.push("");
|
|
4147
|
-
lines.push(
|
|
4762
|
+
lines.push("Environment:");
|
|
4763
|
+
lines.push(` Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}`);
|
|
4764
|
+
if (typeof location !== "undefined") {
|
|
4765
|
+
lines.push(` URL: ${location.href}`);
|
|
4766
|
+
}
|
|
4148
4767
|
if (typeof navigator !== "undefined" && navigator.userAgent) {
|
|
4149
|
-
lines.push(`
|
|
4768
|
+
lines.push(` User Agent: ${navigator.userAgent}`);
|
|
4150
4769
|
}
|
|
4151
4770
|
return lines.join("\n");
|
|
4152
4771
|
}
|
|
@@ -4198,7 +4817,7 @@ function ErrorDisplay(props) {
|
|
|
4198
4817
|
injectStyles();
|
|
4199
4818
|
const severity = props.severity ?? "error";
|
|
4200
4819
|
const normalized = normalizeError(props.error);
|
|
4201
|
-
const showDetails = props.alwaysShowDetails ??
|
|
4820
|
+
const showDetails = props.alwaysShowDetails ?? _isDev11;
|
|
4202
4821
|
const headline = props.title ?? normalized.message;
|
|
4203
4822
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
4204
4823
|
const [copyLabel, setCopyLabel] = signal("Copy");
|
|
@@ -4207,7 +4826,7 @@ function ErrorDisplay(props) {
|
|
|
4207
4826
|
nodes: () => copyLabel(),
|
|
4208
4827
|
on: {
|
|
4209
4828
|
click: () => {
|
|
4210
|
-
const text2 = buildCopyText(normalized, props.metadata);
|
|
4829
|
+
const text2 = buildCopyText(normalized, props.metadata, headline);
|
|
4211
4830
|
if (typeof navigator !== "undefined" && navigator.clipboard) {
|
|
4212
4831
|
navigator.clipboard.writeText(text2).then(
|
|
4213
4832
|
() => {
|
|
@@ -4228,6 +4847,7 @@ function ErrorDisplay(props) {
|
|
|
4228
4847
|
nodes: [
|
|
4229
4848
|
code({ class: "sibu-err-icon", nodes: normalized.code }),
|
|
4230
4849
|
h3({ class: "sibu-err-title", nodes: headline }),
|
|
4850
|
+
copyBtn,
|
|
4231
4851
|
span({ class: "sibu-err-timestamp", nodes: timestamp })
|
|
4232
4852
|
]
|
|
4233
4853
|
});
|
|
@@ -4239,25 +4859,12 @@ function ErrorDisplay(props) {
|
|
|
4239
4859
|
nodes: [
|
|
4240
4860
|
div({
|
|
4241
4861
|
class: "sibu-err-section-head",
|
|
4242
|
-
nodes: [span({ nodes: "Stack Trace" })
|
|
4862
|
+
nodes: [span({ nodes: "Stack Trace" })]
|
|
4243
4863
|
}),
|
|
4244
4864
|
renderFrames(normalized.frames)
|
|
4245
4865
|
]
|
|
4246
4866
|
})
|
|
4247
4867
|
);
|
|
4248
|
-
} else if (showDetails) {
|
|
4249
|
-
bodyChildren.push(
|
|
4250
|
-
div({
|
|
4251
|
-
class: "sibu-err-section",
|
|
4252
|
-
nodes: [
|
|
4253
|
-
div({
|
|
4254
|
-
class: "sibu-err-section-head",
|
|
4255
|
-
nodes: [span({ nodes: "Details" }), copyBtn]
|
|
4256
|
-
}),
|
|
4257
|
-
div({ class: "sibu-err-stack", nodes: "(no stack available)" })
|
|
4258
|
-
]
|
|
4259
|
-
})
|
|
4260
|
-
);
|
|
4261
4868
|
}
|
|
4262
4869
|
if (showDetails) {
|
|
4263
4870
|
bodyChildren.push(...renderCauseChain(normalized.cause));
|
|
@@ -4273,37 +4880,6 @@ function ErrorDisplay(props) {
|
|
|
4273
4880
|
})
|
|
4274
4881
|
);
|
|
4275
4882
|
}
|
|
4276
|
-
if (showDetails && typeof navigator !== "undefined" && navigator.userAgent) {
|
|
4277
|
-
bodyChildren.push(
|
|
4278
|
-
div({
|
|
4279
|
-
class: "sibu-err-section",
|
|
4280
|
-
nodes: [
|
|
4281
|
-
div({ class: "sibu-err-section-head", nodes: [span({ nodes: "Environment" })] }),
|
|
4282
|
-
div({
|
|
4283
|
-
class: "sibu-err-meta",
|
|
4284
|
-
nodes: (() => {
|
|
4285
|
-
const dl2 = document.createElement("dl");
|
|
4286
|
-
dl2.className = "sibu-err-meta";
|
|
4287
|
-
const entries = [
|
|
4288
|
-
["User Agent", navigator.userAgent],
|
|
4289
|
-
["URL", typeof location !== "undefined" ? location.href : "(n/a)"],
|
|
4290
|
-
["Timestamp", (/* @__PURE__ */ new Date()).toISOString()]
|
|
4291
|
-
];
|
|
4292
|
-
for (const [k, v] of entries) {
|
|
4293
|
-
const dt2 = document.createElement("dt");
|
|
4294
|
-
dt2.textContent = k;
|
|
4295
|
-
const dd2 = document.createElement("dd");
|
|
4296
|
-
dd2.textContent = v;
|
|
4297
|
-
dl2.appendChild(dt2);
|
|
4298
|
-
dl2.appendChild(dd2);
|
|
4299
|
-
}
|
|
4300
|
-
return dl2;
|
|
4301
|
-
})()
|
|
4302
|
-
})
|
|
4303
|
-
]
|
|
4304
|
-
})
|
|
4305
|
-
);
|
|
4306
|
-
}
|
|
4307
4883
|
const actionButtons = [];
|
|
4308
4884
|
if (props.onRetry) {
|
|
4309
4885
|
actionButtons.push(
|
|
@@ -4498,6 +5074,7 @@ function injectStyles2() {
|
|
|
4498
5074
|
stylesInjected = true;
|
|
4499
5075
|
}
|
|
4500
5076
|
}
|
|
5077
|
+
var FALLBACK_CACHE_MAX = 50;
|
|
4501
5078
|
var fallbackCache = /* @__PURE__ */ new WeakMap();
|
|
4502
5079
|
function getMemoizedFallback(fallbackFn, error, retry) {
|
|
4503
5080
|
let cache2 = fallbackCache.get(fallbackFn);
|
|
@@ -4506,27 +5083,42 @@ function getMemoizedFallback(fallbackFn, error, retry) {
|
|
|
4506
5083
|
fallbackCache.set(fallbackFn, cache2);
|
|
4507
5084
|
}
|
|
4508
5085
|
const key = error.message;
|
|
4509
|
-
|
|
4510
|
-
|
|
5086
|
+
let factory = cache2.get(key);
|
|
5087
|
+
if (factory) {
|
|
5088
|
+
cache2.delete(key);
|
|
5089
|
+
cache2.set(key, factory);
|
|
5090
|
+
} else {
|
|
5091
|
+
factory = () => fallbackFn(error, retry);
|
|
5092
|
+
cache2.set(key, factory);
|
|
5093
|
+
if (cache2.size > FALLBACK_CACHE_MAX) {
|
|
5094
|
+
const oldestKey = cache2.keys().next().value;
|
|
5095
|
+
if (oldestKey !== void 0) cache2.delete(oldestKey);
|
|
5096
|
+
}
|
|
4511
5097
|
}
|
|
4512
|
-
return
|
|
5098
|
+
return factory();
|
|
4513
5099
|
}
|
|
4514
5100
|
function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
4515
5101
|
injectStyles2();
|
|
4516
5102
|
const [error, setError] = signal(null);
|
|
4517
5103
|
const retry = () => {
|
|
4518
5104
|
if (fallback) {
|
|
4519
|
-
|
|
5105
|
+
const cur = error();
|
|
5106
|
+
const inner = fallbackCache.get(fallback);
|
|
5107
|
+
if (cur && inner) inner.delete(cur.message);
|
|
4520
5108
|
}
|
|
4521
5109
|
setError(null);
|
|
4522
5110
|
};
|
|
5111
|
+
let resetKeysTeardown = null;
|
|
4523
5112
|
if (resetKeys && resetKeys.length > 0) {
|
|
4524
5113
|
let initialized = false;
|
|
4525
|
-
effect(() => {
|
|
5114
|
+
resetKeysTeardown = effect(() => {
|
|
4526
5115
|
for (const k of resetKeys) {
|
|
4527
5116
|
try {
|
|
4528
5117
|
k();
|
|
4529
|
-
} catch {
|
|
5118
|
+
} catch (err) {
|
|
5119
|
+
if (typeof console !== "undefined") {
|
|
5120
|
+
console.warn("[SibuJS ErrorBoundary] resetKeys getter threw:", err);
|
|
5121
|
+
}
|
|
4530
5122
|
}
|
|
4531
5123
|
}
|
|
4532
5124
|
if (!initialized) {
|
|
@@ -4539,7 +5131,15 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
|
4539
5131
|
const handleError = (e) => {
|
|
4540
5132
|
const errorObj = e instanceof Error ? e : new Error(String(e));
|
|
4541
5133
|
setError(errorObj);
|
|
4542
|
-
onError
|
|
5134
|
+
if (onError) {
|
|
5135
|
+
try {
|
|
5136
|
+
onError(errorObj);
|
|
5137
|
+
} catch (cbErr) {
|
|
5138
|
+
if (typeof console !== "undefined") {
|
|
5139
|
+
console.error("[SibuJS ErrorBoundary] onError callback threw:", cbErr);
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
4543
5143
|
return errorObj;
|
|
4544
5144
|
};
|
|
4545
5145
|
const defaultFallback = (err, retryFn) => {
|
|
@@ -4591,7 +5191,7 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
|
4591
5191
|
}
|
|
4592
5192
|
}
|
|
4593
5193
|
});
|
|
4594
|
-
|
|
5194
|
+
const propagateListener = (e) => {
|
|
4595
5195
|
if (error()) return;
|
|
4596
5196
|
e.stopPropagation();
|
|
4597
5197
|
const customEvent = e;
|
|
@@ -4599,6 +5199,30 @@ function ErrorBoundary({ nodes, fallback, onError, resetKeys }) {
|
|
|
4599
5199
|
if (propagatedError) {
|
|
4600
5200
|
handleError(propagatedError);
|
|
4601
5201
|
}
|
|
5202
|
+
};
|
|
5203
|
+
container.addEventListener("sibu:error-propagate", propagateListener);
|
|
5204
|
+
onMount(() => {
|
|
5205
|
+
const walker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT);
|
|
5206
|
+
const collected = [];
|
|
5207
|
+
let node = walker.currentNode;
|
|
5208
|
+
while (node) {
|
|
5209
|
+
const pending = takePendingError(node);
|
|
5210
|
+
if (pending) collected.push(pending);
|
|
5211
|
+
node = walker.nextNode();
|
|
5212
|
+
}
|
|
5213
|
+
if (collected.length === 1) {
|
|
5214
|
+
handleError(collected[0]);
|
|
5215
|
+
} else if (collected.length > 1) {
|
|
5216
|
+
const Agg = globalThis.AggregateError;
|
|
5217
|
+
handleError(
|
|
5218
|
+
Agg ? new Agg(collected, `${collected.length} pre-mount errors caught by ErrorBoundary`) : new Error(collected.map((e) => e.message).join("; "))
|
|
5219
|
+
);
|
|
5220
|
+
}
|
|
5221
|
+
return void 0;
|
|
5222
|
+
}, container);
|
|
5223
|
+
registerDisposer(container, () => {
|
|
5224
|
+
if (resetKeysTeardown) resetKeysTeardown();
|
|
5225
|
+
container.removeEventListener("sibu:error-propagate", propagateListener);
|
|
4602
5226
|
});
|
|
4603
5227
|
return container;
|
|
4604
5228
|
}
|