sibujs 1.5.0 → 2.1.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 +332 -121
- package/dist/browser.d.cts +5 -0
- package/dist/browser.d.ts +5 -0
- package/dist/browser.js +6 -6
- package/dist/build.cjs +1049 -344
- 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-BMPL52BF.js → chunk-3DZP6OIT.js} +118 -66
- package/dist/chunk-3JHCYHWN.js +125 -0
- package/dist/{chunk-CZUGLNJS.js → chunk-45YP72ZQ.js} +3 -3
- package/dist/{chunk-JCDUJN2F.js → chunk-AMK2TYNW.js} +490 -153
- package/dist/{chunk-NHUC2QWH.js → chunk-CWBVQML6.js} +1 -1
- package/dist/{chunk-XHK6BDAJ.js → chunk-DRUZZAK4.js} +25 -8
- package/dist/{chunk-RJ46C3CS.js → chunk-GWWURC5M.js} +71 -20
- package/dist/{chunk-3X2YG6YM.js → chunk-JYD2PWXH.js} +59 -28
- package/dist/{chunk-2BYQDGN3.js → chunk-KGYT6UO6.js} +234 -63
- package/dist/{chunk-5X6PP2UK.js → chunk-LMLD24FC.js} +2 -2
- package/dist/{chunk-M4NLBH4I.js → chunk-LYTCUZ7H.js} +3 -2
- package/dist/{chunk-XUEEGU5O.js → chunk-NASX6ST2.js} +16 -4
- package/dist/{chunk-VQDZK23A.js → chunk-O6EFQ3KT.js} +181 -66
- package/dist/{chunk-BGN5ZMP4.js → chunk-OJ3P4ECI.js} +14 -2
- package/dist/chunk-ON5MMR2J.js +1327 -0
- package/dist/{chunk-SFKNRVCU.js → chunk-P2HSJDDN.js} +135 -79
- package/dist/chunk-QO3WC6FS.js +384 -0
- package/dist/{chunk-WZSPOOER.js → chunk-RDTDJCAB.js} +8 -5
- package/dist/{chunk-7GRNSCFT.js → chunk-TH2ILCYW.js} +312 -185
- package/dist/chunk-UCS6AMJ7.js +79 -0
- package/dist/{chunk-VAPYJN4X.js → chunk-V6C4FADE.js} +93 -23
- package/dist/{chunk-OUZZEE4S.js → chunk-WANSMF2L.js} +17 -11
- package/dist/{chunk-23VV7YD3.js → chunk-WIPZPFBQ.js} +25 -30
- package/dist/chunk-WZA53FXU.js +149 -0
- package/dist/{chunk-BGTHZHJ5.js → chunk-ZAQSMOED.js} +188 -44
- 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 +536 -151
- package/dist/data.d.cts +20 -2
- package/dist/data.d.ts +20 -2
- package/dist/data.js +11 -9
- package/dist/devtools.cjs +613 -266
- package/dist/devtools.d.cts +1 -1
- package/dist/devtools.d.ts +1 -1
- package/dist/devtools.js +12 -6
- package/dist/ecosystem.cjs +602 -197
- package/dist/ecosystem.d.cts +9 -7
- package/dist/ecosystem.d.ts +9 -7
- package/dist/ecosystem.js +12 -11
- package/dist/extras.cjs +3500 -1608
- package/dist/extras.d.cts +9 -9
- package/dist/extras.d.ts +9 -9
- package/dist/extras.js +58 -45
- package/dist/index.cjs +1055 -344
- package/dist/index.d.cts +85 -8
- package/dist/index.d.ts +85 -8
- package/dist/index.js +32 -16
- package/dist/{introspect-BumjnBKr.d.cts → introspect-2TOlQ7oa.d.cts} +25 -3
- package/dist/{introspect-CZrlcaYy.d.ts → introspect-DnIpHQQz.d.ts} +25 -3
- package/dist/motion.cjs +122 -63
- package/dist/motion.js +4 -4
- package/dist/patterns.cjs +450 -110
- package/dist/patterns.d.cts +11 -12
- package/dist/patterns.d.ts +11 -12
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +373 -149
- 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 +729 -301
- 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 +736 -274
- 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 +303 -76
- package/dist/testing.d.cts +17 -4
- package/dist/testing.d.ts +17 -4
- package/dist/testing.js +100 -44
- package/dist/ui.cjs +589 -178
- package/dist/ui.d.cts +1 -1
- package/dist/ui.d.ts +1 -1
- package/dist/ui.js +20 -17
- package/dist/widgets.cjs +1103 -146
- 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-K4G4ZQNR.js +0 -286
- 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/plugins.cjs
CHANGED
|
@@ -26,12 +26,12 @@ function isDev() {
|
|
|
26
26
|
}
|
|
27
27
|
function devAssert(condition, message) {
|
|
28
28
|
if (_isDev && !condition) {
|
|
29
|
-
throw new Error(`[
|
|
29
|
+
throw new Error(`[SibuJS] ${message}`);
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
function devWarn(message) {
|
|
33
33
|
if (_isDev) {
|
|
34
|
-
console.warn(`[
|
|
34
|
+
console.warn(`[SibuJS] ${message}`);
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
var _isDev;
|
|
@@ -47,14 +47,47 @@ function sanitizeUrl(url) {
|
|
|
47
47
|
const trimmed = url.replace(/[\x00-\x20\x7f-\x9f]+/g, "").trim();
|
|
48
48
|
if (!trimmed) return "";
|
|
49
49
|
const lower = trimmed.toLowerCase();
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
let schemeEnd = -1;
|
|
51
|
+
for (let i2 = 0; i2 < lower.length; i2++) {
|
|
52
|
+
const ch = lower.charCodeAt(i2);
|
|
53
|
+
if (ch === 58) {
|
|
54
|
+
schemeEnd = i2;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
52
58
|
}
|
|
59
|
+
if (schemeEnd === -1) return trimmed;
|
|
60
|
+
const scheme = lower.slice(0, schemeEnd + 1);
|
|
61
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return trimmed;
|
|
62
|
+
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
53
63
|
return trimmed;
|
|
54
64
|
}
|
|
65
|
+
function sanitizeSrcset(value) {
|
|
66
|
+
const parts = value.split(",");
|
|
67
|
+
const out = [];
|
|
68
|
+
for (let i2 = 0; i2 < parts.length; i2++) {
|
|
69
|
+
const part = parts[i2].trim();
|
|
70
|
+
if (!part) continue;
|
|
71
|
+
const m = part.match(/^(\S+)(\s+.+)?$/);
|
|
72
|
+
if (!m) continue;
|
|
73
|
+
const safe = sanitizeUrl(m[1]);
|
|
74
|
+
if (!safe) continue;
|
|
75
|
+
out.push(m[2] ? `${safe}${m[2]}` : safe);
|
|
76
|
+
}
|
|
77
|
+
return out.join(", ");
|
|
78
|
+
}
|
|
55
79
|
function sanitizeCSSValue(value) {
|
|
56
|
-
const
|
|
57
|
-
|
|
80
|
+
const decoded = value.replace(/\\([0-9a-fA-F]{1,6})\s?/g, (_m, hex) => {
|
|
81
|
+
const code2 = Number.parseInt(hex, 16);
|
|
82
|
+
if (!Number.isFinite(code2) || code2 < 0 || code2 > 1114111) return "";
|
|
83
|
+
try {
|
|
84
|
+
return String.fromCodePoint(code2);
|
|
85
|
+
} catch {
|
|
86
|
+
return "";
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
const lower = decoded.toLowerCase().replace(/\s+/g, "");
|
|
90
|
+
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")) {
|
|
58
91
|
return "";
|
|
59
92
|
}
|
|
60
93
|
return value;
|
|
@@ -62,11 +95,56 @@ function sanitizeCSSValue(value) {
|
|
|
62
95
|
function isUrlAttribute(attr) {
|
|
63
96
|
return URL_ATTRIBUTES.has(attr);
|
|
64
97
|
}
|
|
65
|
-
var URL_ATTRIBUTES;
|
|
98
|
+
var SAFE_URL_PROTOCOLS, URL_ATTRIBUTES;
|
|
66
99
|
var init_sanitize = __esm({
|
|
67
100
|
"src/utils/sanitize.ts"() {
|
|
68
101
|
"use strict";
|
|
69
|
-
|
|
102
|
+
SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
103
|
+
URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
104
|
+
"href",
|
|
105
|
+
"xlink:href",
|
|
106
|
+
"src",
|
|
107
|
+
"action",
|
|
108
|
+
"formaction",
|
|
109
|
+
"formtarget",
|
|
110
|
+
"cite",
|
|
111
|
+
"poster",
|
|
112
|
+
"background",
|
|
113
|
+
"srcset",
|
|
114
|
+
"ping",
|
|
115
|
+
"data"
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// src/core/ssr-context.ts
|
|
121
|
+
function getSSRStore() {
|
|
122
|
+
if (als) {
|
|
123
|
+
const s2 = als.getStore();
|
|
124
|
+
if (s2) return s2;
|
|
125
|
+
}
|
|
126
|
+
return fallbackStore;
|
|
127
|
+
}
|
|
128
|
+
function isSSR() {
|
|
129
|
+
return getSSRStore().ssr;
|
|
130
|
+
}
|
|
131
|
+
var als, fallbackStore;
|
|
132
|
+
var init_ssr_context = __esm({
|
|
133
|
+
"src/core/ssr-context.ts"() {
|
|
134
|
+
"use strict";
|
|
135
|
+
als = null;
|
|
136
|
+
try {
|
|
137
|
+
if (typeof process !== "undefined" && process.versions && process.versions.node) {
|
|
138
|
+
const req = Function("return typeof require==='function'?require:null")();
|
|
139
|
+
if (req) {
|
|
140
|
+
const mod = req("node:async_hooks");
|
|
141
|
+
als = new mod.AsyncLocalStorage();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
} catch {
|
|
145
|
+
als = null;
|
|
146
|
+
}
|
|
147
|
+
fallbackStore = { ssr: false, suspenseIdCounter: 0 };
|
|
70
148
|
}
|
|
71
149
|
});
|
|
72
150
|
|
|
@@ -100,7 +178,7 @@ function isEventHandlerAttr2(name) {
|
|
|
100
178
|
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
101
179
|
}
|
|
102
180
|
function ssrErrorComment(err) {
|
|
103
|
-
if (
|
|
181
|
+
if (_isDev8) {
|
|
104
182
|
const msg = escapeHtml(err instanceof Error ? err.message : String(err));
|
|
105
183
|
return `<!--SSR error: ${safeCommentText(msg)}-->`;
|
|
106
184
|
}
|
|
@@ -130,10 +208,10 @@ function renderToString(element) {
|
|
|
130
208
|
}
|
|
131
209
|
const tag = element.tagName.toLowerCase();
|
|
132
210
|
if (tag === "script" || tag === "style") {
|
|
133
|
-
return
|
|
211
|
+
return _isDev8 ? `<!--ssr:${tag}-stripped-->` : "";
|
|
134
212
|
}
|
|
135
213
|
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
136
|
-
return
|
|
214
|
+
return _isDev8 ? "<!--ssr:invalid-tag-->" : "";
|
|
137
215
|
}
|
|
138
216
|
let html2 = `<${tag}`;
|
|
139
217
|
for (const attr of Array.from(element.attributes)) {
|
|
@@ -174,9 +252,9 @@ function hydrate(component, container, options = {}) {
|
|
|
174
252
|
const first = mismatches[0];
|
|
175
253
|
if (options.onMismatch) {
|
|
176
254
|
options.onMismatch(first);
|
|
177
|
-
} else if (
|
|
255
|
+
} else if (_isDev8) {
|
|
178
256
|
console.warn(
|
|
179
|
-
`[
|
|
257
|
+
`[SibuJS hydration] ${first.message}
|
|
180
258
|
at ${first.path}
|
|
181
259
|
server: ${first.serverValue}
|
|
182
260
|
client: ${first.clientValue}`
|
|
@@ -184,17 +262,9 @@ function hydrate(component, container, options = {}) {
|
|
|
184
262
|
}
|
|
185
263
|
}
|
|
186
264
|
}
|
|
187
|
-
|
|
265
|
+
container.replaceChildren(clientTree);
|
|
188
266
|
container.setAttribute("data-sibu-hydrated", "true");
|
|
189
267
|
}
|
|
190
|
-
function hydrateNode(serverNode, clientNode) {
|
|
191
|
-
if (!serverNode) return;
|
|
192
|
-
const serverChildren = Array.from(serverNode.children);
|
|
193
|
-
const clientChildren = Array.from(clientNode.children);
|
|
194
|
-
for (let i2 = 0; i2 < Math.min(serverChildren.length, clientChildren.length); i2++) {
|
|
195
|
-
hydrateNode(serverChildren[i2], clientChildren[i2]);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
268
|
function collectMismatches(serverNode, clientNode, path2, out, max = 5) {
|
|
199
269
|
if (out.length >= max) return;
|
|
200
270
|
const nodePath = path2 || clientNode?.tagName?.toLowerCase() || "(root)";
|
|
@@ -372,11 +442,11 @@ async function* renderToStream(element) {
|
|
|
372
442
|
}
|
|
373
443
|
const tag = element.tagName.toLowerCase();
|
|
374
444
|
if (tag === "script" || tag === "style") {
|
|
375
|
-
if (
|
|
445
|
+
if (_isDev8) yield `<!--ssr:${tag}-stripped-->`;
|
|
376
446
|
return;
|
|
377
447
|
}
|
|
378
448
|
if (!/^[a-z][a-z0-9-]*$/i.test(tag)) {
|
|
379
|
-
if (
|
|
449
|
+
if (_isDev8) yield "<!--ssr:invalid-tag-->";
|
|
380
450
|
return;
|
|
381
451
|
}
|
|
382
452
|
let openTag = `<${tag}`;
|
|
@@ -424,12 +494,15 @@ function renderToReadableStream(element) {
|
|
|
424
494
|
controller.enqueue(value);
|
|
425
495
|
}
|
|
426
496
|
},
|
|
427
|
-
cancel() {
|
|
428
|
-
generator.return(void 0);
|
|
497
|
+
async cancel() {
|
|
498
|
+
await generator.return(void 0);
|
|
429
499
|
}
|
|
430
500
|
});
|
|
431
501
|
}
|
|
432
502
|
function island(id, component) {
|
|
503
|
+
if (!SAFE_ID.test(id)) {
|
|
504
|
+
throw new Error(`[SibuJS SSR] island: id must match [A-Za-z0-9_-]+ (got: ${JSON.stringify(id.slice(0, 32))})`);
|
|
505
|
+
}
|
|
433
506
|
const el = component();
|
|
434
507
|
el.setAttribute("data-sibu-island", id);
|
|
435
508
|
return el;
|
|
@@ -442,8 +515,9 @@ function hydrateIslands(container, islands) {
|
|
|
442
515
|
const factory = islands[id];
|
|
443
516
|
if (typeof factory !== "function") continue;
|
|
444
517
|
const clientTree = factory();
|
|
445
|
-
|
|
446
|
-
|
|
518
|
+
clientTree.setAttribute("data-sibu-island", id);
|
|
519
|
+
clientTree.setAttribute("data-sibu-hydrated", "true");
|
|
520
|
+
marker2.replaceWith(clientTree);
|
|
447
521
|
}
|
|
448
522
|
container.setAttribute("data-sibu-hydrated", "partial");
|
|
449
523
|
}
|
|
@@ -460,8 +534,9 @@ function hydrateProgressively(container, islands, options) {
|
|
|
460
534
|
for (const entry of entries) {
|
|
461
535
|
if (entry.isIntersecting) {
|
|
462
536
|
const clientTree = factory();
|
|
463
|
-
|
|
464
|
-
|
|
537
|
+
clientTree.setAttribute("data-sibu-island", id);
|
|
538
|
+
clientTree.setAttribute("data-sibu-hydrated", "true");
|
|
539
|
+
marker2.replaceWith(clientTree);
|
|
465
540
|
observer.disconnect();
|
|
466
541
|
break;
|
|
467
542
|
}
|
|
@@ -478,18 +553,36 @@ function hydrateProgressively(container, islands, options) {
|
|
|
478
553
|
};
|
|
479
554
|
}
|
|
480
555
|
function resetSSRState() {
|
|
481
|
-
suspenseIdCounter = 0;
|
|
556
|
+
getSSRStore().suspenseIdCounter = 0;
|
|
557
|
+
}
|
|
558
|
+
function noop() {
|
|
482
559
|
}
|
|
483
560
|
function ssrSuspense(props) {
|
|
484
|
-
const
|
|
561
|
+
const store = getSSRStore();
|
|
562
|
+
const id = `sibu-sus-${store.suspenseIdCounter++}`;
|
|
563
|
+
const timeoutMs = props.timeoutMs ?? 3e4;
|
|
485
564
|
const fallbackEl = props.fallback();
|
|
486
565
|
const wrapper = document.createElement("div");
|
|
487
566
|
wrapper.setAttribute("data-sibu-suspense-id", id);
|
|
488
567
|
wrapper.appendChild(fallbackEl);
|
|
489
|
-
const
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
568
|
+
const fallbackHtml = renderToString(fallbackEl);
|
|
569
|
+
let timer;
|
|
570
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
571
|
+
timer = setTimeout(() => reject(new Error(`[SibuJS SSR] ssrSuspense timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
572
|
+
});
|
|
573
|
+
const raced = Promise.race([props.content(), timeoutPromise]);
|
|
574
|
+
const promise = raced.then(
|
|
575
|
+
(resolvedEl) => {
|
|
576
|
+
if (timer) clearTimeout(timer);
|
|
577
|
+
return { id, html: renderToString(resolvedEl) };
|
|
578
|
+
},
|
|
579
|
+
(err) => {
|
|
580
|
+
if (timer) clearTimeout(timer);
|
|
581
|
+
if (_isDev8) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
|
|
582
|
+
return { id, html: fallbackHtml };
|
|
583
|
+
}
|
|
584
|
+
);
|
|
585
|
+
promise.catch(noop);
|
|
493
586
|
return { element: wrapper, promise };
|
|
494
587
|
}
|
|
495
588
|
function suspenseSwapScript(id, nonce) {
|
|
@@ -515,14 +608,26 @@ async function* renderToSuspenseStream(element, pendingBoundaries = [], options)
|
|
|
515
608
|
function escapeScriptJson(json) {
|
|
516
609
|
return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
517
610
|
}
|
|
518
|
-
function serializeState(state, nonce) {
|
|
519
|
-
const
|
|
611
|
+
function serializeState(state, nonce, options) {
|
|
612
|
+
const rawJson = JSON.stringify(state);
|
|
613
|
+
const maxBytes = options?.maxBytes ?? DEFAULT_MAX_SSR_BYTES;
|
|
614
|
+
const byteLen = typeof TextEncoder !== "undefined" ? new TextEncoder().encode(rawJson).byteLength : Buffer.byteLength(rawJson, "utf8");
|
|
615
|
+
if (byteLen > maxBytes) {
|
|
616
|
+
throw new Error(`[SibuJS SSR] serializeState: payload (${byteLen} bytes) exceeds maxBytes (${maxBytes})`);
|
|
617
|
+
}
|
|
618
|
+
const json = escapeScriptJson(rawJson);
|
|
520
619
|
const nonceAttr = nonce ? ` nonce="${escapeAttr(nonce)}"` : "";
|
|
521
620
|
return `<script${nonceAttr}>window.${SSR_DATA_ATTR}=${json}</script>`;
|
|
522
621
|
}
|
|
523
622
|
function deserializeState(validate) {
|
|
524
623
|
if (typeof window === "undefined") return void 0;
|
|
525
|
-
|
|
624
|
+
if (_isDev8 && !validate) {
|
|
625
|
+
console.warn(
|
|
626
|
+
"[SibuJS SSR] deserializeState() called without a validate guard \u2014 tampered SSR payloads will not be detected."
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
const w = window;
|
|
630
|
+
const raw = w[SSR_DATA_ATTR];
|
|
526
631
|
if (raw === void 0) return void 0;
|
|
527
632
|
if (validate && !validate(raw)) return void 0;
|
|
528
633
|
return raw;
|
|
@@ -533,13 +638,14 @@ function escapeHtml(str) {
|
|
|
533
638
|
function escapeAttr(str) {
|
|
534
639
|
return str.replace(/&/g, "&").replace(/"/g, """).replace(/'/g, "'").replace(/</g, "<").replace(/>/g, ">");
|
|
535
640
|
}
|
|
536
|
-
var
|
|
641
|
+
var _isDev8, SAFE_ATTR_NAME, URL_ATTRS, VOID_ELEMENTS, SAFE_ID, SAFE_SUSPENSE_ID, SSR_DATA_ATTR, DEFAULT_MAX_SSR_BYTES;
|
|
537
642
|
var init_ssr = __esm({
|
|
538
643
|
"src/platform/ssr.ts"() {
|
|
539
644
|
"use strict";
|
|
540
645
|
init_dev();
|
|
646
|
+
init_ssr_context();
|
|
541
647
|
init_sanitize();
|
|
542
|
-
|
|
648
|
+
_isDev8 = isDev();
|
|
543
649
|
SAFE_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
544
650
|
URL_ATTRS = /* @__PURE__ */ new Set([
|
|
545
651
|
"href",
|
|
@@ -571,9 +677,10 @@ var init_ssr = __esm({
|
|
|
571
677
|
"track",
|
|
572
678
|
"wbr"
|
|
573
679
|
]);
|
|
574
|
-
|
|
680
|
+
SAFE_ID = /^[A-Za-z0-9_-]+$/;
|
|
575
681
|
SAFE_SUSPENSE_ID = /^[A-Za-z0-9_-]+$/;
|
|
576
682
|
SSR_DATA_ATTR = "__SIBU_SSR_DATA__";
|
|
683
|
+
DEFAULT_MAX_SSR_BYTES = 1024 * 1024;
|
|
577
684
|
}
|
|
578
685
|
});
|
|
579
686
|
|
|
@@ -588,6 +695,7 @@ __export(plugins_exports, {
|
|
|
588
695
|
Suspense: () => Suspense,
|
|
589
696
|
Trans: () => Trans,
|
|
590
697
|
VERSION: () => VERSION,
|
|
698
|
+
__removeRouterPagehideHandler: () => __removeRouterPagehideHandler,
|
|
591
699
|
addRoute: () => addRoute,
|
|
592
700
|
afterEach: () => afterEach,
|
|
593
701
|
back: () => back,
|
|
@@ -603,6 +711,7 @@ __export(plugins_exports, {
|
|
|
603
711
|
createMigrationRunner: () => createMigrationRunner,
|
|
604
712
|
createModuleRegistry: () => createModuleRegistry,
|
|
605
713
|
createPlugin: () => createPlugin,
|
|
714
|
+
createPluginRegistry: () => createPluginRegistry,
|
|
606
715
|
createRouter: () => createRouter,
|
|
607
716
|
createSSRCache: () => createSSRCache,
|
|
608
717
|
createSSRRouter: () => createSSRRouter,
|
|
@@ -645,6 +754,7 @@ __export(plugins_exports, {
|
|
|
645
754
|
routerState: () => routerState,
|
|
646
755
|
satisfies: () => satisfies,
|
|
647
756
|
serializeRouteState: () => serializeRouteState,
|
|
757
|
+
setDefaultPluginRegistry: () => setDefaultPluginRegistry,
|
|
648
758
|
setLocale: () => setLocale,
|
|
649
759
|
setRouteTransition: () => setRouteTransition,
|
|
650
760
|
setRoutes: () => setRoutes,
|
|
@@ -655,6 +765,9 @@ __export(plugins_exports, {
|
|
|
655
765
|
});
|
|
656
766
|
module.exports = __toCommonJS(plugins_exports);
|
|
657
767
|
|
|
768
|
+
// src/core/rendering/tagFactory.ts
|
|
769
|
+
init_dev();
|
|
770
|
+
|
|
658
771
|
// src/reactivity/bindAttribute.ts
|
|
659
772
|
init_dev();
|
|
660
773
|
init_sanitize();
|
|
@@ -662,15 +775,28 @@ init_sanitize();
|
|
|
662
775
|
// src/reactivity/track.ts
|
|
663
776
|
init_dev();
|
|
664
777
|
var _isDev2 = isDev();
|
|
665
|
-
var
|
|
666
|
-
var
|
|
778
|
+
var STACK_INITIAL = 32;
|
|
779
|
+
var STACK_SHRINK_THRESHOLD = 128;
|
|
780
|
+
var subscriberStack = new Array(STACK_INITIAL);
|
|
781
|
+
var stackCapacity = STACK_INITIAL;
|
|
667
782
|
var stackTop = -1;
|
|
668
783
|
var currentSubscriber = null;
|
|
669
|
-
var signalSubscribers = /* @__PURE__ */ new WeakMap();
|
|
670
784
|
var SUBS = "__s";
|
|
785
|
+
function syncFastPath(signal2, subs) {
|
|
786
|
+
const size = subs.size;
|
|
787
|
+
if (size === 0) {
|
|
788
|
+
signal2.__f = void 0;
|
|
789
|
+
delete signal2[SUBS];
|
|
790
|
+
} else if (size === 1) {
|
|
791
|
+
signal2.__f = subs.values().next().value;
|
|
792
|
+
} else {
|
|
793
|
+
signal2.__f = void 0;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
671
796
|
var notifyDepth = 0;
|
|
672
797
|
var pendingQueue = [];
|
|
673
798
|
var pendingSet = /* @__PURE__ */ new Set();
|
|
799
|
+
var propagateStack = [];
|
|
674
800
|
function safeInvoke(sub2) {
|
|
675
801
|
try {
|
|
676
802
|
sub2();
|
|
@@ -693,75 +819,133 @@ function track(effectFn, subscriber) {
|
|
|
693
819
|
} finally {
|
|
694
820
|
stackTop--;
|
|
695
821
|
currentSubscriber = stackTop >= 0 ? subscriberStack[stackTop] : null;
|
|
822
|
+
if (stackTop < 0 && stackCapacity > STACK_SHRINK_THRESHOLD) {
|
|
823
|
+
stackCapacity = Math.max(STACK_INITIAL, stackCapacity >>> 1);
|
|
824
|
+
subscriberStack.length = stackCapacity;
|
|
825
|
+
}
|
|
696
826
|
}
|
|
697
827
|
return () => cleanup(subscriber);
|
|
698
828
|
}
|
|
699
829
|
function recordDependency(signal2) {
|
|
700
830
|
if (!currentSubscriber) return;
|
|
701
831
|
const sub2 = currentSubscriber;
|
|
702
|
-
|
|
832
|
+
const epoch = sub2._epoch;
|
|
833
|
+
if (sub2._dep === signal2) {
|
|
834
|
+
sub2._depEpoch = epoch;
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
703
837
|
const deps = sub2._deps;
|
|
704
838
|
if (deps) {
|
|
705
|
-
|
|
706
|
-
deps.add(signal2);
|
|
839
|
+
deps.set(signal2, epoch);
|
|
707
840
|
} else if (sub2._dep !== void 0) {
|
|
708
|
-
const
|
|
709
|
-
set
|
|
710
|
-
set
|
|
711
|
-
sub2._deps =
|
|
841
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
842
|
+
map2.set(sub2._dep, sub2._depEpoch);
|
|
843
|
+
map2.set(signal2, epoch);
|
|
844
|
+
sub2._deps = map2;
|
|
712
845
|
sub2._dep = void 0;
|
|
846
|
+
sub2._depEpoch = void 0;
|
|
713
847
|
} else {
|
|
714
848
|
sub2._dep = signal2;
|
|
849
|
+
sub2._depEpoch = epoch;
|
|
715
850
|
}
|
|
716
|
-
|
|
851
|
+
const sig = signal2;
|
|
852
|
+
let subs = sig[SUBS];
|
|
717
853
|
if (!subs) {
|
|
718
854
|
subs = /* @__PURE__ */ new Set();
|
|
719
|
-
|
|
720
|
-
signal2[SUBS] = subs;
|
|
855
|
+
sig[SUBS] = subs;
|
|
721
856
|
}
|
|
857
|
+
const prevSize = subs.size;
|
|
722
858
|
subs.add(currentSubscriber);
|
|
723
|
-
if (subs.size
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
859
|
+
if (subs.size !== prevSize) {
|
|
860
|
+
if (subs.size === 1) {
|
|
861
|
+
sig.__f = currentSubscriber;
|
|
862
|
+
} else if (sig.__f !== void 0) {
|
|
863
|
+
sig.__f = void 0;
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
var maxSubscriberRepeats = 50;
|
|
868
|
+
var maxDrainIterations = 1e6;
|
|
869
|
+
var drainEpoch = 0;
|
|
870
|
+
function tickRepeat(sub2) {
|
|
871
|
+
const s2 = sub2;
|
|
872
|
+
if (s2._runEpoch !== drainEpoch) {
|
|
873
|
+
s2._runEpoch = drainEpoch;
|
|
874
|
+
s2._runs = 1;
|
|
875
|
+
return false;
|
|
876
|
+
}
|
|
877
|
+
return ++s2._runs > maxSubscriberRepeats;
|
|
878
|
+
}
|
|
879
|
+
function cycleError(sub2) {
|
|
880
|
+
if (typeof console !== "undefined") {
|
|
881
|
+
const name = sub2.__name ?? "<unnamed>";
|
|
882
|
+
console.error(
|
|
883
|
+
`[SibuJS] subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. Breaking to prevent infinite loop.`
|
|
884
|
+
);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
function absoluteDrainError() {
|
|
888
|
+
if (typeof console !== "undefined") {
|
|
889
|
+
console.error(
|
|
890
|
+
`[SibuJS] Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
891
|
+
);
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
function drainQueue() {
|
|
895
|
+
let i2 = 0;
|
|
896
|
+
while (i2 < pendingQueue.length) {
|
|
897
|
+
if (i2 >= maxDrainIterations) {
|
|
898
|
+
absoluteDrainError();
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
901
|
+
const sub2 = pendingQueue[i2++];
|
|
902
|
+
if (tickRepeat(sub2)) {
|
|
903
|
+
cycleError(sub2);
|
|
904
|
+
break;
|
|
905
|
+
}
|
|
906
|
+
pendingSet.delete(sub2);
|
|
907
|
+
safeInvoke(sub2);
|
|
727
908
|
}
|
|
728
909
|
}
|
|
729
910
|
function propagateDirty(sub2) {
|
|
730
911
|
sub2();
|
|
731
|
-
|
|
732
|
-
|
|
912
|
+
const rootSig = sub2._sig;
|
|
913
|
+
if (!rootSig) return;
|
|
914
|
+
const stack = propagateStack;
|
|
915
|
+
const baseLen = stack.length;
|
|
916
|
+
stack.push(rootSig);
|
|
917
|
+
while (stack.length > baseLen) {
|
|
918
|
+
const sig = stack.pop();
|
|
733
919
|
const first = sig.__f;
|
|
734
920
|
if (first) {
|
|
735
921
|
if (first._c) {
|
|
736
922
|
const nSig = first._sig;
|
|
737
|
-
nSig._d
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
if (!pendingSet.has(first)) {
|
|
923
|
+
if (!nSig._d) {
|
|
924
|
+
nSig._d = true;
|
|
925
|
+
stack.push(nSig);
|
|
926
|
+
}
|
|
927
|
+
} else if (!pendingSet.has(first)) {
|
|
742
928
|
pendingSet.add(first);
|
|
743
929
|
pendingQueue.push(first);
|
|
744
930
|
}
|
|
745
|
-
|
|
931
|
+
continue;
|
|
746
932
|
}
|
|
747
933
|
const subs = sig[SUBS];
|
|
748
|
-
if (!subs)
|
|
749
|
-
let nextSig;
|
|
934
|
+
if (!subs) continue;
|
|
750
935
|
for (const s2 of subs) {
|
|
751
936
|
if (s2._c) {
|
|
752
|
-
s2();
|
|
753
937
|
const nSig = s2._sig;
|
|
754
|
-
if (nSig && !
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
938
|
+
if (nSig && !nSig._d) {
|
|
939
|
+
nSig._d = true;
|
|
940
|
+
stack.push(nSig);
|
|
941
|
+
} else if (!nSig) {
|
|
942
|
+
s2();
|
|
758
943
|
}
|
|
759
944
|
} else if (!pendingSet.has(s2)) {
|
|
760
945
|
pendingSet.add(s2);
|
|
761
946
|
pendingQueue.push(s2);
|
|
762
947
|
}
|
|
763
948
|
}
|
|
764
|
-
sig = nextSig;
|
|
765
949
|
}
|
|
766
950
|
}
|
|
767
951
|
function notifySubscribers(signal2) {
|
|
@@ -777,21 +961,22 @@ function notifySubscribers(signal2) {
|
|
|
777
961
|
return;
|
|
778
962
|
}
|
|
779
963
|
notifyDepth++;
|
|
964
|
+
drainEpoch++;
|
|
780
965
|
try {
|
|
781
966
|
if (first._c) {
|
|
782
967
|
propagateDirty(first);
|
|
968
|
+
} else if (tickRepeat(first)) {
|
|
969
|
+
cycleError(first);
|
|
783
970
|
} else {
|
|
784
971
|
safeInvoke(first);
|
|
785
972
|
}
|
|
786
|
-
|
|
787
|
-
while (i2 < pendingQueue.length) {
|
|
788
|
-
safeInvoke(pendingQueue[i2]);
|
|
789
|
-
i2++;
|
|
790
|
-
}
|
|
973
|
+
drainQueue();
|
|
791
974
|
} finally {
|
|
792
|
-
pendingQueue.length = 0;
|
|
793
|
-
pendingSet.clear();
|
|
794
975
|
notifyDepth--;
|
|
976
|
+
if (notifyDepth === 0) {
|
|
977
|
+
pendingQueue.length = 0;
|
|
978
|
+
pendingSet.clear();
|
|
979
|
+
}
|
|
795
980
|
}
|
|
796
981
|
return;
|
|
797
982
|
}
|
|
@@ -809,57 +994,45 @@ function notifySubscribers(signal2) {
|
|
|
809
994
|
return;
|
|
810
995
|
}
|
|
811
996
|
notifyDepth++;
|
|
997
|
+
drainEpoch++;
|
|
812
998
|
try {
|
|
813
|
-
let directCount = 0;
|
|
814
999
|
for (const sub2 of subs) {
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
for (let i3 = 0; i3 < directCount; i3++) {
|
|
823
|
-
if (!pendingQueue[i3]._c) {
|
|
824
|
-
if (!pendingSet.has(pendingQueue[i3])) {
|
|
825
|
-
safeInvoke(pendingQueue[i3]);
|
|
826
|
-
}
|
|
1000
|
+
if (sub2._c) {
|
|
1001
|
+
propagateDirty(sub2);
|
|
1002
|
+
} else if (!pendingSet.has(sub2)) {
|
|
1003
|
+
pendingSet.add(sub2);
|
|
1004
|
+
pendingQueue.push(sub2);
|
|
827
1005
|
}
|
|
828
1006
|
}
|
|
829
|
-
|
|
830
|
-
while (i2 < pendingQueue.length) {
|
|
831
|
-
safeInvoke(pendingQueue[i2]);
|
|
832
|
-
i2++;
|
|
833
|
-
}
|
|
1007
|
+
drainQueue();
|
|
834
1008
|
} finally {
|
|
835
|
-
pendingQueue.length = 0;
|
|
836
|
-
pendingSet.clear();
|
|
837
1009
|
notifyDepth--;
|
|
1010
|
+
if (notifyDepth === 0) {
|
|
1011
|
+
pendingQueue.length = 0;
|
|
1012
|
+
pendingSet.clear();
|
|
1013
|
+
}
|
|
838
1014
|
}
|
|
839
1015
|
}
|
|
840
1016
|
function cleanup(subscriber) {
|
|
841
1017
|
const sub2 = subscriber;
|
|
842
1018
|
const singleDep = sub2._dep;
|
|
843
1019
|
if (singleDep !== void 0) {
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
singleDep.__f = void 0;
|
|
849
|
-
}
|
|
1020
|
+
const sig = singleDep;
|
|
1021
|
+
const subs = sig[SUBS];
|
|
1022
|
+
if (subs?.delete(subscriber)) {
|
|
1023
|
+
syncFastPath(sig, subs);
|
|
850
1024
|
}
|
|
851
1025
|
sub2._dep = void 0;
|
|
1026
|
+
sub2._depEpoch = void 0;
|
|
852
1027
|
return;
|
|
853
1028
|
}
|
|
854
1029
|
const deps = sub2._deps;
|
|
855
1030
|
if (!deps || deps.size === 0) return;
|
|
856
|
-
for (const signal2 of deps) {
|
|
857
|
-
const
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
signal2.__f = void 0;
|
|
862
|
-
}
|
|
1031
|
+
for (const signal2 of deps.keys()) {
|
|
1032
|
+
const sig = signal2;
|
|
1033
|
+
const subs = sig[SUBS];
|
|
1034
|
+
if (subs?.delete(subscriber)) {
|
|
1035
|
+
syncFastPath(sig, subs);
|
|
863
1036
|
}
|
|
864
1037
|
}
|
|
865
1038
|
deps.clear();
|
|
@@ -867,6 +1040,9 @@ function cleanup(subscriber) {
|
|
|
867
1040
|
|
|
868
1041
|
// src/reactivity/bindAttribute.ts
|
|
869
1042
|
var _isDev3 = isDev();
|
|
1043
|
+
function setProp(el, key, val) {
|
|
1044
|
+
el[key] = val;
|
|
1045
|
+
}
|
|
870
1046
|
function isEventHandlerAttr(name) {
|
|
871
1047
|
if (name.length < 3) return false;
|
|
872
1048
|
const lower = name.toLowerCase();
|
|
@@ -892,7 +1068,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
892
1068
|
}
|
|
893
1069
|
if (typeof value === "boolean") {
|
|
894
1070
|
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
895
|
-
el
|
|
1071
|
+
setProp(el, attr, value);
|
|
896
1072
|
} else if (value) {
|
|
897
1073
|
el.setAttribute(attr, "");
|
|
898
1074
|
} else {
|
|
@@ -902,7 +1078,7 @@ function bindAttribute(el, attr, getter) {
|
|
|
902
1078
|
}
|
|
903
1079
|
const str = String(value);
|
|
904
1080
|
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
905
|
-
el
|
|
1081
|
+
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
906
1082
|
} else {
|
|
907
1083
|
el.setAttribute(attr, isUrlAttribute(attr) ? sanitizeUrl(str) : str);
|
|
908
1084
|
}
|
|
@@ -940,24 +1116,29 @@ function bindChildNode(placeholder, getter) {
|
|
|
940
1116
|
let newNodes;
|
|
941
1117
|
if (Array.isArray(result)) {
|
|
942
1118
|
newNodes = [];
|
|
1119
|
+
const seen = /* @__PURE__ */ new Set();
|
|
943
1120
|
for (let i2 = 0; i2 < result.length; i2++) {
|
|
944
1121
|
const item = result[i2];
|
|
945
1122
|
if (item == null || typeof item === "boolean") continue;
|
|
946
|
-
|
|
1123
|
+
const node = item instanceof Node ? item : document.createTextNode(String(item));
|
|
1124
|
+
if (seen.has(node)) {
|
|
1125
|
+
if (_isDev4)
|
|
1126
|
+
devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
1127
|
+
continue;
|
|
1128
|
+
}
|
|
1129
|
+
seen.add(node);
|
|
1130
|
+
newNodes.push(node);
|
|
947
1131
|
}
|
|
948
1132
|
} else {
|
|
949
1133
|
const node = result instanceof Node ? result : document.createTextNode(String(result));
|
|
950
1134
|
newNodes = [node];
|
|
951
1135
|
}
|
|
952
|
-
|
|
953
|
-
if (
|
|
1136
|
+
let reused;
|
|
1137
|
+
if (lastNodes.length > 0 && newNodes.length > 0) {
|
|
1138
|
+
const lastSet = new Set(lastNodes);
|
|
1139
|
+
reused = /* @__PURE__ */ new Set();
|
|
954
1140
|
for (let i2 = 0; i2 < newNodes.length; i2++) {
|
|
955
|
-
|
|
956
|
-
if (newNodes[i2] === lastNodes[j]) {
|
|
957
|
-
reused.add(newNodes[i2]);
|
|
958
|
-
break;
|
|
959
|
-
}
|
|
960
|
-
}
|
|
1141
|
+
if (lastSet.has(newNodes[i2])) reused.add(newNodes[i2]);
|
|
961
1142
|
}
|
|
962
1143
|
}
|
|
963
1144
|
for (let i2 = 0; i2 < lastNodes.length; i2++) {
|
|
@@ -1004,7 +1185,7 @@ function dispose(node) {
|
|
|
1004
1185
|
while (stack.length > 0) {
|
|
1005
1186
|
const current = stack.pop();
|
|
1006
1187
|
order.push(current);
|
|
1007
|
-
const children = current.childNodes;
|
|
1188
|
+
const children = Array.from(current.childNodes);
|
|
1008
1189
|
for (let i2 = 0; i2 < children.length; i2++) {
|
|
1009
1190
|
stack.push(children[i2]);
|
|
1010
1191
|
}
|
|
@@ -1013,8 +1194,10 @@ function dispose(node) {
|
|
|
1013
1194
|
const current = order[i2];
|
|
1014
1195
|
const disposers = elementDisposers.get(current);
|
|
1015
1196
|
if (disposers) {
|
|
1016
|
-
|
|
1017
|
-
|
|
1197
|
+
const snapshot = disposers.slice();
|
|
1198
|
+
elementDisposers.delete(current);
|
|
1199
|
+
if (_isDev5) activeBindingCount -= snapshot.length;
|
|
1200
|
+
for (const d of snapshot) {
|
|
1018
1201
|
try {
|
|
1019
1202
|
d();
|
|
1020
1203
|
} catch (err) {
|
|
@@ -1023,13 +1206,53 @@ function dispose(node) {
|
|
|
1023
1206
|
}
|
|
1024
1207
|
}
|
|
1025
1208
|
}
|
|
1026
|
-
|
|
1209
|
+
let extraPasses = 0;
|
|
1210
|
+
while (extraPasses++ < 8) {
|
|
1211
|
+
const added = elementDisposers.get(current);
|
|
1212
|
+
if (!added || added.length === 0) break;
|
|
1213
|
+
const moreSnapshot = added.slice();
|
|
1214
|
+
elementDisposers.delete(current);
|
|
1215
|
+
if (_isDev5) activeBindingCount -= moreSnapshot.length;
|
|
1216
|
+
for (const d of moreSnapshot) {
|
|
1217
|
+
try {
|
|
1218
|
+
d();
|
|
1219
|
+
} catch (err) {
|
|
1220
|
+
if (_isDev5 && typeof console !== "undefined") {
|
|
1221
|
+
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1027
1226
|
}
|
|
1028
1227
|
}
|
|
1029
1228
|
}
|
|
1030
1229
|
|
|
1031
1230
|
// src/core/rendering/tagFactory.ts
|
|
1032
1231
|
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
1232
|
+
var _isDev6 = isDev();
|
|
1233
|
+
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
1234
|
+
function validateTagName(tag) {
|
|
1235
|
+
const lower = tag.toLowerCase();
|
|
1236
|
+
if (BLOCKED_TAGS.has(lower)) {
|
|
1237
|
+
throw new Error(`tagFactory: refusing to create <${tag}> \u2014 tag is blocked for security reasons.`);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
1241
|
+
"config",
|
|
1242
|
+
"location",
|
|
1243
|
+
"history",
|
|
1244
|
+
"document",
|
|
1245
|
+
"window",
|
|
1246
|
+
"navigator",
|
|
1247
|
+
"name",
|
|
1248
|
+
"top",
|
|
1249
|
+
"parent",
|
|
1250
|
+
"self",
|
|
1251
|
+
"frames"
|
|
1252
|
+
]);
|
|
1253
|
+
function setProp2(el, key, val) {
|
|
1254
|
+
el[key] = val;
|
|
1255
|
+
}
|
|
1033
1256
|
var kebabCache = /* @__PURE__ */ new Map();
|
|
1034
1257
|
function toKebab(prop) {
|
|
1035
1258
|
let cached = kebabCache.get(prop);
|
|
@@ -1154,79 +1377,103 @@ function appendChildren(el, nodes) {
|
|
|
1154
1377
|
}
|
|
1155
1378
|
}
|
|
1156
1379
|
}
|
|
1157
|
-
var tagFactory = (tag, ns) =>
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
if (
|
|
1162
|
-
|
|
1163
|
-
|
|
1380
|
+
var tagFactory = (tag, ns) => {
|
|
1381
|
+
return (first, second) => {
|
|
1382
|
+
validateTagName(tag);
|
|
1383
|
+
const el = ns ? document.createElementNS(ns, tag) : document.createElement(tag);
|
|
1384
|
+
if (first === void 0) return el;
|
|
1385
|
+
if (typeof first === "string") {
|
|
1386
|
+
if (second !== void 0) {
|
|
1387
|
+
el.setAttribute("class", first);
|
|
1388
|
+
appendChildren(el, second);
|
|
1389
|
+
return el;
|
|
1390
|
+
}
|
|
1391
|
+
el.textContent = first;
|
|
1164
1392
|
return el;
|
|
1165
1393
|
}
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1394
|
+
if (typeof first === "number") {
|
|
1395
|
+
el.textContent = String(first);
|
|
1396
|
+
return el;
|
|
1397
|
+
}
|
|
1398
|
+
if (Array.isArray(first) || first instanceof Node || typeof first === "function") {
|
|
1399
|
+
appendChildren(el, first);
|
|
1400
|
+
return el;
|
|
1401
|
+
}
|
|
1402
|
+
const props = first;
|
|
1403
|
+
const pClass = props.class;
|
|
1404
|
+
if (pClass != null) applyClass(el, pClass);
|
|
1405
|
+
const pId = props.id;
|
|
1406
|
+
if (pId != null) {
|
|
1407
|
+
if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
1408
|
+
devWarn(
|
|
1409
|
+
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
1410
|
+
);
|
|
1411
|
+
}
|
|
1412
|
+
el.id = pId;
|
|
1413
|
+
}
|
|
1414
|
+
const pNodes = second !== void 0 ? second : props.nodes;
|
|
1415
|
+
if (pNodes != null) appendChildren(el, pNodes);
|
|
1416
|
+
const pOn = props.on;
|
|
1417
|
+
if (pOn) {
|
|
1418
|
+
for (const ev in pOn) {
|
|
1419
|
+
const handler = pOn[ev];
|
|
1420
|
+
if (typeof handler === "function") {
|
|
1421
|
+
el.addEventListener(ev, handler);
|
|
1422
|
+
} else if (_isDev6) {
|
|
1423
|
+
devWarn(
|
|
1424
|
+
`tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
|
|
1425
|
+
);
|
|
1426
|
+
}
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
const pStyle = props.style;
|
|
1430
|
+
if (pStyle != null) applyStyle(el, pStyle);
|
|
1431
|
+
const pRef = props.ref;
|
|
1432
|
+
if (pRef) pRef.current = el;
|
|
1433
|
+
for (const key in props) {
|
|
1434
|
+
switch (key) {
|
|
1435
|
+
case "class":
|
|
1436
|
+
case "id":
|
|
1437
|
+
case "nodes":
|
|
1438
|
+
case "on":
|
|
1439
|
+
case "style":
|
|
1440
|
+
case "ref":
|
|
1441
|
+
case "onElement":
|
|
1442
|
+
continue;
|
|
1443
|
+
// already handled above / below
|
|
1444
|
+
default: {
|
|
1445
|
+
const value = props[key];
|
|
1446
|
+
if (value == null) continue;
|
|
1447
|
+
const lkey = key.toLowerCase();
|
|
1448
|
+
if (lkey[0] === "o" && lkey[1] === "n") continue;
|
|
1449
|
+
if (typeof value === "function") {
|
|
1450
|
+
registerDisposer(el, bindAttribute(el, key, value));
|
|
1451
|
+
} else if (typeof value === "boolean") {
|
|
1452
|
+
if (key in el && (key === "checked" || key === "disabled" || key === "selected")) {
|
|
1453
|
+
setProp2(el, key, value);
|
|
1454
|
+
} else if (value) {
|
|
1455
|
+
el.setAttribute(key, "");
|
|
1456
|
+
} else {
|
|
1457
|
+
el.removeAttribute(key);
|
|
1458
|
+
}
|
|
1216
1459
|
} else {
|
|
1217
|
-
|
|
1460
|
+
const str = String(value);
|
|
1461
|
+
if (lkey === "srcset") {
|
|
1462
|
+
el.setAttribute(key, sanitizeSrcset(str));
|
|
1463
|
+
} else if (isUrlAttribute(lkey)) {
|
|
1464
|
+
el.setAttribute(key, sanitizeUrl(str));
|
|
1465
|
+
} else {
|
|
1466
|
+
el.setAttribute(key, str);
|
|
1467
|
+
}
|
|
1218
1468
|
}
|
|
1219
|
-
} else {
|
|
1220
|
-
const str = String(value);
|
|
1221
|
-
el.setAttribute(key, isUrlAttribute(key) ? sanitizeUrl(str) : str);
|
|
1222
1469
|
}
|
|
1223
1470
|
}
|
|
1224
1471
|
}
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1472
|
+
if (props.onElement && typeof props.onElement === "function") {
|
|
1473
|
+
props.onElement(el);
|
|
1474
|
+
}
|
|
1475
|
+
return el;
|
|
1476
|
+
};
|
|
1230
1477
|
};
|
|
1231
1478
|
|
|
1232
1479
|
// src/core/rendering/html.ts
|
|
@@ -1379,10 +1626,10 @@ function enqueueBatchedSignal(signal2) {
|
|
|
1379
1626
|
// src/core/signals/signal.ts
|
|
1380
1627
|
init_dev();
|
|
1381
1628
|
var _g = globalThis;
|
|
1382
|
-
var
|
|
1629
|
+
var _isDev7 = isDev();
|
|
1383
1630
|
function signal(initial, options) {
|
|
1384
1631
|
const state = { value: initial };
|
|
1385
|
-
const debugName =
|
|
1632
|
+
const debugName = _isDev7 ? options?.name : void 0;
|
|
1386
1633
|
const equalsFn = options?.equals;
|
|
1387
1634
|
if (debugName) {
|
|
1388
1635
|
state.__name = debugName;
|
|
@@ -1396,7 +1643,7 @@ function signal(initial, options) {
|
|
|
1396
1643
|
function set(next) {
|
|
1397
1644
|
const newValue = typeof next === "function" ? next(state.value) : next;
|
|
1398
1645
|
if (equalsFn ? equalsFn(state.value, newValue) : Object.is(newValue, state.value)) return;
|
|
1399
|
-
if (
|
|
1646
|
+
if (_isDev7) {
|
|
1400
1647
|
const oldValue = state.value;
|
|
1401
1648
|
state.value = newValue;
|
|
1402
1649
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
@@ -1408,7 +1655,7 @@ function signal(initial, options) {
|
|
|
1408
1655
|
notifySubscribers(state);
|
|
1409
1656
|
}
|
|
1410
1657
|
}
|
|
1411
|
-
if (
|
|
1658
|
+
if (_isDev7) {
|
|
1412
1659
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1413
1660
|
if (hook) hook.emit("signal:create", { signal: state, name: debugName, getter: get, initial });
|
|
1414
1661
|
}
|
|
@@ -1445,40 +1692,121 @@ function getAvailableLocales() {
|
|
|
1445
1692
|
|
|
1446
1693
|
// src/core/signals/effect.ts
|
|
1447
1694
|
init_dev();
|
|
1448
|
-
|
|
1449
|
-
// src/core/ssr-context.ts
|
|
1450
|
-
var ssrMode = false;
|
|
1451
|
-
function isSSR() {
|
|
1452
|
-
return ssrMode;
|
|
1453
|
-
}
|
|
1454
|
-
|
|
1455
|
-
// src/core/signals/effect.ts
|
|
1695
|
+
init_ssr_context();
|
|
1456
1696
|
var _g2 = globalThis;
|
|
1457
1697
|
function effect(effectFn, options) {
|
|
1458
1698
|
devAssert(typeof effectFn === "function", "effect: argument must be a function.");
|
|
1459
1699
|
if (isSSR()) return () => {
|
|
1460
1700
|
};
|
|
1461
1701
|
const onError = options?.onError;
|
|
1702
|
+
let userCleanups = [];
|
|
1703
|
+
const onCleanup = (fn) => {
|
|
1704
|
+
userCleanups.push(fn);
|
|
1705
|
+
};
|
|
1706
|
+
const runUserCleanups = () => {
|
|
1707
|
+
if (userCleanups.length === 0) return;
|
|
1708
|
+
const list = userCleanups;
|
|
1709
|
+
userCleanups = [];
|
|
1710
|
+
for (let i2 = list.length - 1; i2 >= 0; i2--) {
|
|
1711
|
+
try {
|
|
1712
|
+
list[i2]();
|
|
1713
|
+
} catch (err) {
|
|
1714
|
+
if (typeof console !== "undefined") {
|
|
1715
|
+
console.warn("[SibuJS effect] onCleanup threw:", err);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
}
|
|
1719
|
+
};
|
|
1720
|
+
const invokeBody = () => effectFn(onCleanup);
|
|
1462
1721
|
const wrappedFn = onError ? () => {
|
|
1463
1722
|
try {
|
|
1464
|
-
|
|
1723
|
+
invokeBody();
|
|
1465
1724
|
} catch (err) {
|
|
1466
1725
|
onError(err);
|
|
1467
1726
|
}
|
|
1468
|
-
} :
|
|
1727
|
+
} : invokeBody;
|
|
1469
1728
|
let cleanupHandle = () => {
|
|
1470
1729
|
};
|
|
1730
|
+
let running = false;
|
|
1731
|
+
let rerunPending = false;
|
|
1732
|
+
const MAX_RERUNS = 100;
|
|
1471
1733
|
const subscriber = () => {
|
|
1472
|
-
|
|
1473
|
-
|
|
1734
|
+
if (running) {
|
|
1735
|
+
rerunPending = true;
|
|
1736
|
+
return;
|
|
1737
|
+
}
|
|
1738
|
+
running = true;
|
|
1739
|
+
try {
|
|
1740
|
+
let reruns = 0;
|
|
1741
|
+
do {
|
|
1742
|
+
rerunPending = false;
|
|
1743
|
+
runUserCleanups();
|
|
1744
|
+
cleanupHandle();
|
|
1745
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
1746
|
+
if (++reruns > MAX_RERUNS) {
|
|
1747
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
1748
|
+
console.error(
|
|
1749
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
1750
|
+
);
|
|
1751
|
+
}
|
|
1752
|
+
rerunPending = false;
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1755
|
+
} while (rerunPending);
|
|
1756
|
+
} finally {
|
|
1757
|
+
running = false;
|
|
1758
|
+
rerunPending = false;
|
|
1759
|
+
}
|
|
1474
1760
|
};
|
|
1475
|
-
|
|
1761
|
+
running = true;
|
|
1762
|
+
try {
|
|
1763
|
+
let reruns = 0;
|
|
1764
|
+
do {
|
|
1765
|
+
rerunPending = false;
|
|
1766
|
+
runUserCleanups();
|
|
1767
|
+
cleanupHandle();
|
|
1768
|
+
cleanupHandle = track(wrappedFn, subscriber);
|
|
1769
|
+
if (++reruns > MAX_RERUNS) {
|
|
1770
|
+
if (_g2.__SIBU_DEV_WARN__ !== false && typeof console !== "undefined") {
|
|
1771
|
+
console.error(
|
|
1772
|
+
`[SibuJS] effect re-requested itself ${MAX_RERUNS}+ times on initial run \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
1773
|
+
);
|
|
1774
|
+
}
|
|
1775
|
+
rerunPending = false;
|
|
1776
|
+
break;
|
|
1777
|
+
}
|
|
1778
|
+
} while (rerunPending);
|
|
1779
|
+
} finally {
|
|
1780
|
+
running = false;
|
|
1781
|
+
rerunPending = false;
|
|
1782
|
+
}
|
|
1476
1783
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1477
1784
|
if (hook) hook.emit("effect:create", { effectFn });
|
|
1785
|
+
let disposed = false;
|
|
1478
1786
|
return () => {
|
|
1787
|
+
if (disposed) return;
|
|
1788
|
+
disposed = true;
|
|
1479
1789
|
const h = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1480
|
-
if (h)
|
|
1481
|
-
|
|
1790
|
+
if (h) {
|
|
1791
|
+
try {
|
|
1792
|
+
h.emit("effect:destroy", { effectFn });
|
|
1793
|
+
} catch {
|
|
1794
|
+
}
|
|
1795
|
+
}
|
|
1796
|
+
try {
|
|
1797
|
+
runUserCleanups();
|
|
1798
|
+
} catch (err) {
|
|
1799
|
+
if (typeof console !== "undefined") {
|
|
1800
|
+
console.warn("[SibuJS effect] onCleanup threw during dispose:", err);
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
try {
|
|
1804
|
+
cleanupHandle();
|
|
1805
|
+
} catch (err) {
|
|
1806
|
+
if (typeof console !== "undefined") {
|
|
1807
|
+
console.warn("[SibuJS effect] dispose threw:", err);
|
|
1808
|
+
}
|
|
1809
|
+
}
|
|
1482
1810
|
};
|
|
1483
1811
|
}
|
|
1484
1812
|
|
|
@@ -1849,9 +2177,11 @@ var ComponentLoader = class {
|
|
|
1849
2177
|
}
|
|
1850
2178
|
return component;
|
|
1851
2179
|
} catch (error) {
|
|
1852
|
-
|
|
2180
|
+
const wrapped = new Error(
|
|
1853
2181
|
`Failed to load component for route "${routePath}": ${error instanceof Error ? error.message : String(error)}`
|
|
1854
2182
|
);
|
|
2183
|
+
wrapped.cause = error;
|
|
2184
|
+
throw wrapped;
|
|
1855
2185
|
}
|
|
1856
2186
|
}
|
|
1857
2187
|
isAsyncComponent(comp) {
|
|
@@ -2037,10 +2367,13 @@ var _SibuRouter = class _SibuRouter {
|
|
|
2037
2367
|
}
|
|
2038
2368
|
if ("redirect" in route2) {
|
|
2039
2369
|
const redirectPath = typeof route2.redirect === "function" ? route2.redirect(to) : route2.redirect;
|
|
2040
|
-
if (typeof redirectPath === "string" && /^https
|
|
2041
|
-
console
|
|
2042
|
-
|
|
2043
|
-
|
|
2370
|
+
if (typeof redirectPath === "string" && /^(https?:)?\/\//i.test(redirectPath)) {
|
|
2371
|
+
if (typeof console !== "undefined") {
|
|
2372
|
+
console.error(
|
|
2373
|
+
`[SibuJS Router] Refusing absolute/protocol-relative redirect "${redirectPath}" \u2014 open-redirect risk.`
|
|
2374
|
+
);
|
|
2375
|
+
}
|
|
2376
|
+
throw new NavigationFailureError("aborted", from, to);
|
|
2044
2377
|
}
|
|
2045
2378
|
if (typeof redirectPath === "string" && !isSafeNavigationTarget(redirectPath)) {
|
|
2046
2379
|
throw new NavigationFailureError("aborted", from, to);
|
|
@@ -2243,6 +2576,7 @@ function createRouter(routesOrOptions, options = {}) {
|
|
|
2243
2576
|
routes = [];
|
|
2244
2577
|
}
|
|
2245
2578
|
globalRouter = new SibuRouter(routes, options);
|
|
2579
|
+
ensureRouterPagehide();
|
|
2246
2580
|
return globalRouter;
|
|
2247
2581
|
}
|
|
2248
2582
|
function setRoutes(routes) {
|
|
@@ -2316,7 +2650,9 @@ function Route() {
|
|
|
2316
2650
|
let currentTopRoute = null;
|
|
2317
2651
|
const cleanupNodes = () => {
|
|
2318
2652
|
[currentNode, loadingNode, errorNode].forEach((node) => {
|
|
2319
|
-
if (node
|
|
2653
|
+
if (!node) return;
|
|
2654
|
+
dispose(node);
|
|
2655
|
+
if (node.parentNode) {
|
|
2320
2656
|
node.parentNode.removeChild(node);
|
|
2321
2657
|
}
|
|
2322
2658
|
});
|
|
@@ -2347,13 +2683,24 @@ function Route() {
|
|
|
2347
2683
|
loadingNode = null;
|
|
2348
2684
|
}
|
|
2349
2685
|
};
|
|
2350
|
-
const showError = (error) => {
|
|
2686
|
+
const showError = (error, routeDef) => {
|
|
2351
2687
|
if (!anchor.parentNode) return;
|
|
2352
2688
|
cleanupNodes();
|
|
2353
2689
|
errorNode = document.createElement("div");
|
|
2354
2690
|
errorNode.className = "route-error";
|
|
2355
2691
|
errorNode.setAttribute("role", "alert");
|
|
2356
2692
|
errorNode.setAttribute("aria-live", "assertive");
|
|
2693
|
+
if (routeDef && "component" in routeDef) {
|
|
2694
|
+
const src = routeDef.component.toString();
|
|
2695
|
+
const importMatch = src.match(/import\(["']([^"']+)["']\)/);
|
|
2696
|
+
if (importMatch) {
|
|
2697
|
+
errorNode.setAttribute("data-component-source", importMatch[1]);
|
|
2698
|
+
}
|
|
2699
|
+
if (routeDef.component.name) {
|
|
2700
|
+
errorNode.setAttribute("data-component-name", routeDef.component.name);
|
|
2701
|
+
}
|
|
2702
|
+
}
|
|
2703
|
+
errorNode.__routeError = error;
|
|
2357
2704
|
const title2 = document.createElement("h3");
|
|
2358
2705
|
title2.textContent = "Route Error";
|
|
2359
2706
|
title2.className = "route-error-title";
|
|
@@ -2364,12 +2711,14 @@ function Route() {
|
|
|
2364
2711
|
retryButton.textContent = "Retry";
|
|
2365
2712
|
retryButton.className = "route-error-retry";
|
|
2366
2713
|
retryButton.type = "button";
|
|
2367
|
-
|
|
2714
|
+
const onRetryClick = () => {
|
|
2368
2715
|
if (globalRouter) {
|
|
2369
2716
|
globalRouter.clearErrorCache();
|
|
2370
2717
|
update();
|
|
2371
2718
|
}
|
|
2372
|
-
}
|
|
2719
|
+
};
|
|
2720
|
+
retryButton.addEventListener("click", onRetryClick);
|
|
2721
|
+
registerDisposer(retryButton, () => retryButton.removeEventListener("click", onRetryClick));
|
|
2373
2722
|
errorNode.appendChild(title2);
|
|
2374
2723
|
errorNode.appendChild(message);
|
|
2375
2724
|
errorNode.appendChild(retryButton);
|
|
@@ -2401,7 +2750,11 @@ function Route() {
|
|
|
2401
2750
|
currentTopRoute = routeDef;
|
|
2402
2751
|
if ("redirect" in routeDef) {
|
|
2403
2752
|
const redirectPath = typeof routeDef.redirect === "function" ? routeDef.redirect(route2) : routeDef.redirect;
|
|
2404
|
-
queueMicrotask(() =>
|
|
2753
|
+
queueMicrotask(() => {
|
|
2754
|
+
globalRouter?.navigate(redirectPath).catch((err) => {
|
|
2755
|
+
if (typeof console !== "undefined") console.error("[router] redirect failed:", err);
|
|
2756
|
+
});
|
|
2757
|
+
});
|
|
2405
2758
|
return;
|
|
2406
2759
|
}
|
|
2407
2760
|
if ("component" in routeDef) {
|
|
@@ -2420,7 +2773,7 @@ function Route() {
|
|
|
2420
2773
|
} catch (error) {
|
|
2421
2774
|
hideLoading();
|
|
2422
2775
|
console.error("[Route] Component error:", error);
|
|
2423
|
-
showError(error instanceof Error ? error : new Error(String(error)));
|
|
2776
|
+
showError(error instanceof Error ? error : new Error(String(error)), routeDef);
|
|
2424
2777
|
}
|
|
2425
2778
|
}
|
|
2426
2779
|
} catch (error) {
|
|
@@ -2440,13 +2793,16 @@ function Route() {
|
|
|
2440
2793
|
await originalUpdate();
|
|
2441
2794
|
routeInitialized = true;
|
|
2442
2795
|
};
|
|
2443
|
-
track(wrappedUpdate);
|
|
2796
|
+
const routeTeardown = track(wrappedUpdate);
|
|
2444
2797
|
if (!routeInitialized) {
|
|
2445
2798
|
queueMicrotask(() => {
|
|
2446
2799
|
if (!routeInitialized && anchor.parentNode) wrappedUpdate();
|
|
2447
2800
|
});
|
|
2448
2801
|
}
|
|
2449
|
-
routeCleanups.push(
|
|
2802
|
+
routeCleanups.push(() => {
|
|
2803
|
+
routeTeardown();
|
|
2804
|
+
cleanupNodes();
|
|
2805
|
+
});
|
|
2450
2806
|
return anchor;
|
|
2451
2807
|
}
|
|
2452
2808
|
function KeepAliveRoute(options) {
|
|
@@ -2475,7 +2831,11 @@ function KeepAliveRoute(options) {
|
|
|
2475
2831
|
const { route: routeDef } = match;
|
|
2476
2832
|
if ("redirect" in routeDef) {
|
|
2477
2833
|
const redirectPath = typeof routeDef.redirect === "function" ? routeDef.redirect(route2) : routeDef.redirect;
|
|
2478
|
-
queueMicrotask(() =>
|
|
2834
|
+
queueMicrotask(() => {
|
|
2835
|
+
globalRouter?.navigate(redirectPath).catch((err) => {
|
|
2836
|
+
if (typeof console !== "undefined") console.error("[router] redirect failed:", err);
|
|
2837
|
+
});
|
|
2838
|
+
});
|
|
2479
2839
|
return;
|
|
2480
2840
|
}
|
|
2481
2841
|
if (!("component" in routeDef)) return;
|
|
@@ -2545,13 +2905,14 @@ function KeepAliveRoute(options) {
|
|
|
2545
2905
|
await update();
|
|
2546
2906
|
initialized = true;
|
|
2547
2907
|
};
|
|
2548
|
-
track(wrappedUpdate);
|
|
2908
|
+
const kaTeardown = track(wrappedUpdate);
|
|
2549
2909
|
if (!initialized) {
|
|
2550
2910
|
queueMicrotask(() => {
|
|
2551
2911
|
if (!initialized && anchor.parentNode) wrappedUpdate();
|
|
2552
2912
|
});
|
|
2553
2913
|
}
|
|
2554
2914
|
routeCleanups.push(() => {
|
|
2915
|
+
kaTeardown();
|
|
2555
2916
|
for (const node of cache.values()) {
|
|
2556
2917
|
dispose(node);
|
|
2557
2918
|
if (node.parentNode) node.parentNode.removeChild(node);
|
|
@@ -2618,12 +2979,18 @@ function RouterLink(props) {
|
|
|
2618
2979
|
}
|
|
2619
2980
|
});
|
|
2620
2981
|
}
|
|
2621
|
-
|
|
2982
|
+
const onLinkClick = (e) => {
|
|
2622
2983
|
if (target || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) {
|
|
2623
2984
|
return;
|
|
2624
2985
|
}
|
|
2625
2986
|
e.preventDefault();
|
|
2626
|
-
globalRouter?.navigate(to, { replace: replace2 })
|
|
2987
|
+
globalRouter?.navigate(to, { replace: replace2 }).catch((err) => {
|
|
2988
|
+
if (typeof console !== "undefined") console.error("[router] link navigate failed:", err);
|
|
2989
|
+
});
|
|
2990
|
+
};
|
|
2991
|
+
link2.addEventListener("click", onLinkClick);
|
|
2992
|
+
registerDisposer(link2, () => {
|
|
2993
|
+
link2.removeEventListener("click", onLinkClick);
|
|
2627
2994
|
});
|
|
2628
2995
|
return link2;
|
|
2629
2996
|
}
|
|
@@ -2734,10 +3101,21 @@ function destroyRouter() {
|
|
|
2734
3101
|
globalRouter = null;
|
|
2735
3102
|
}
|
|
2736
3103
|
}
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
3104
|
+
var _routerPagehideHandler = null;
|
|
3105
|
+
function ensureRouterPagehide() {
|
|
3106
|
+
if (_routerPagehideHandler || typeof window === "undefined") return;
|
|
3107
|
+
_routerPagehideHandler = (event) => {
|
|
3108
|
+
if (event.persisted === false) {
|
|
3109
|
+
destroyRouter();
|
|
3110
|
+
}
|
|
3111
|
+
};
|
|
3112
|
+
window.addEventListener("pagehide", _routerPagehideHandler);
|
|
3113
|
+
}
|
|
3114
|
+
function __removeRouterPagehideHandler() {
|
|
3115
|
+
if (_routerPagehideHandler && typeof window !== "undefined") {
|
|
3116
|
+
window.removeEventListener("pagehide", _routerPagehideHandler);
|
|
3117
|
+
_routerPagehideHandler = null;
|
|
3118
|
+
}
|
|
2741
3119
|
}
|
|
2742
3120
|
function Outlet() {
|
|
2743
3121
|
const anchor = document.createComment("route-outlet-nested");
|
|
@@ -2763,12 +3141,20 @@ function Outlet() {
|
|
|
2763
3141
|
console.error("[Outlet] Failed to render child route:", error);
|
|
2764
3142
|
}
|
|
2765
3143
|
};
|
|
2766
|
-
track(update);
|
|
3144
|
+
const outletTeardown = track(update);
|
|
2767
3145
|
if (!anchor.parentNode) {
|
|
2768
3146
|
queueMicrotask(() => {
|
|
2769
3147
|
if (anchor.parentNode) update();
|
|
2770
3148
|
});
|
|
2771
3149
|
}
|
|
3150
|
+
routeCleanups.push(() => {
|
|
3151
|
+
outletTeardown();
|
|
3152
|
+
if (currentNode) {
|
|
3153
|
+
dispose(currentNode);
|
|
3154
|
+
if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
|
|
3155
|
+
currentNode = null;
|
|
3156
|
+
}
|
|
3157
|
+
});
|
|
2772
3158
|
return anchor;
|
|
2773
3159
|
}
|
|
2774
3160
|
function addRoute(route2, parentPath) {
|
|
@@ -3086,6 +3472,10 @@ function hydrateRouter(routes, options) {
|
|
|
3086
3472
|
if (resolved.component) {
|
|
3087
3473
|
hydrate2(resolved.component, container);
|
|
3088
3474
|
}
|
|
3475
|
+
}).catch((err) => {
|
|
3476
|
+
if (typeof console !== "undefined") {
|
|
3477
|
+
console.error("[SibuJS routerSSR] failed to load hydrate:", err);
|
|
3478
|
+
}
|
|
3089
3479
|
});
|
|
3090
3480
|
}
|
|
3091
3481
|
}
|
|
@@ -3159,83 +3549,117 @@ function escapeAttrLocal(str) {
|
|
|
3159
3549
|
}
|
|
3160
3550
|
|
|
3161
3551
|
// src/plugins/plugin.ts
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
init: [],
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3552
|
+
function createPluginRegistry() {
|
|
3553
|
+
const installedPlugins = /* @__PURE__ */ new Set();
|
|
3554
|
+
const hooks = { init: [], mount: [], unmount: [], error: [] };
|
|
3555
|
+
const provided = /* @__PURE__ */ new Map();
|
|
3556
|
+
const registry = {
|
|
3557
|
+
installedPlugins,
|
|
3558
|
+
hooks,
|
|
3559
|
+
provided,
|
|
3560
|
+
plugin(p2, options) {
|
|
3561
|
+
if (installedPlugins.has(p2.name)) {
|
|
3562
|
+
console.warn(`[Plugin] "${p2.name}" is already installed.`);
|
|
3563
|
+
return;
|
|
3564
|
+
}
|
|
3565
|
+
const ctx = {
|
|
3566
|
+
onInit: (cb) => hooks.init.push(cb),
|
|
3567
|
+
onMount: (cb) => hooks.mount.push(cb),
|
|
3568
|
+
onUnmount: (cb) => hooks.unmount.push(cb),
|
|
3569
|
+
onError: (cb) => hooks.error.push(cb),
|
|
3570
|
+
provide: (key, value) => provided.set(key, value)
|
|
3571
|
+
};
|
|
3572
|
+
const initHooksBefore = hooks.init.length;
|
|
3573
|
+
p2.install(ctx, options);
|
|
3574
|
+
installedPlugins.add(p2.name);
|
|
3575
|
+
const justAdded = hooks.init.slice(initHooksBefore);
|
|
3576
|
+
for (const cb of justAdded) {
|
|
3577
|
+
try {
|
|
3578
|
+
cb();
|
|
3579
|
+
} catch (e) {
|
|
3580
|
+
console.error(`[Plugin] "${p2.name}" init error:`, e);
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
},
|
|
3584
|
+
inject(key, defaultValue) {
|
|
3585
|
+
if (provided.has(key)) return provided.get(key);
|
|
3586
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
3587
|
+
throw new Error(`[Plugin] No provider found for key "${key}"`);
|
|
3588
|
+
},
|
|
3589
|
+
triggerMount(element) {
|
|
3590
|
+
const snapshot = hooks.mount.slice();
|
|
3591
|
+
for (const hook of snapshot) {
|
|
3592
|
+
try {
|
|
3593
|
+
hook(element);
|
|
3594
|
+
} catch (e) {
|
|
3595
|
+
console.error("[Plugin] Mount hook error:", e);
|
|
3596
|
+
}
|
|
3597
|
+
}
|
|
3598
|
+
},
|
|
3599
|
+
triggerUnmount(element) {
|
|
3600
|
+
const snapshot = hooks.unmount.slice();
|
|
3601
|
+
for (const hook of snapshot) {
|
|
3602
|
+
try {
|
|
3603
|
+
hook(element);
|
|
3604
|
+
} catch (e) {
|
|
3605
|
+
console.error("[Plugin] Unmount hook error:", e);
|
|
3606
|
+
}
|
|
3607
|
+
}
|
|
3608
|
+
},
|
|
3609
|
+
triggerError(error) {
|
|
3610
|
+
const snapshot = hooks.error.slice();
|
|
3611
|
+
for (const hook of snapshot) {
|
|
3612
|
+
try {
|
|
3613
|
+
hook(error);
|
|
3614
|
+
} catch (e) {
|
|
3615
|
+
console.error("[Plugin] Error hook error:", e);
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
},
|
|
3619
|
+
reset() {
|
|
3620
|
+
installedPlugins.clear();
|
|
3621
|
+
hooks.init.length = 0;
|
|
3622
|
+
hooks.mount.length = 0;
|
|
3623
|
+
hooks.unmount.length = 0;
|
|
3624
|
+
hooks.error.length = 0;
|
|
3625
|
+
provided.clear();
|
|
3626
|
+
}
|
|
3627
|
+
};
|
|
3628
|
+
return registry;
|
|
3629
|
+
}
|
|
3630
|
+
var defaultRegistry = createPluginRegistry();
|
|
3631
|
+
var defaultRegistryTouched = false;
|
|
3170
3632
|
function createPlugin(name, install) {
|
|
3171
3633
|
return { name, install };
|
|
3172
3634
|
}
|
|
3173
3635
|
function plugin(plugin2, options) {
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
return;
|
|
3177
|
-
}
|
|
3178
|
-
const ctx = {
|
|
3179
|
-
onInit: (cb) => hooks.init.push(cb),
|
|
3180
|
-
onMount: (cb) => hooks.mount.push(cb),
|
|
3181
|
-
onUnmount: (cb) => hooks.unmount.push(cb),
|
|
3182
|
-
onError: (cb) => hooks.error.push(cb),
|
|
3183
|
-
provide: (key, value) => provided.set(key, value)
|
|
3184
|
-
};
|
|
3185
|
-
const initHooksBefore = hooks.init.length;
|
|
3186
|
-
plugin2.install(ctx, options);
|
|
3187
|
-
installedPlugins.add(plugin2.name);
|
|
3188
|
-
for (let i2 = initHooksBefore; i2 < hooks.init.length; i2++) {
|
|
3189
|
-
try {
|
|
3190
|
-
hooks.init[i2]();
|
|
3191
|
-
} catch (e) {
|
|
3192
|
-
console.error(`[Plugin] "${plugin2.name}" init error:`, e);
|
|
3193
|
-
}
|
|
3194
|
-
}
|
|
3636
|
+
defaultRegistryTouched = true;
|
|
3637
|
+
defaultRegistry.plugin(plugin2, options);
|
|
3195
3638
|
}
|
|
3196
3639
|
function inject(key, defaultValue) {
|
|
3197
|
-
|
|
3198
|
-
return provided.get(key);
|
|
3199
|
-
}
|
|
3200
|
-
if (defaultValue !== void 0) {
|
|
3201
|
-
return defaultValue;
|
|
3202
|
-
}
|
|
3203
|
-
throw new Error(`[Plugin] No provider found for key "${key}"`);
|
|
3640
|
+
return defaultRegistry.inject(key, defaultValue);
|
|
3204
3641
|
}
|
|
3205
3642
|
function triggerPluginMount(element) {
|
|
3206
|
-
|
|
3207
|
-
try {
|
|
3208
|
-
hook(element);
|
|
3209
|
-
} catch (e) {
|
|
3210
|
-
console.error("[Plugin] Mount hook error:", e);
|
|
3211
|
-
}
|
|
3212
|
-
}
|
|
3643
|
+
defaultRegistry.triggerMount(element);
|
|
3213
3644
|
}
|
|
3214
3645
|
function triggerPluginUnmount(element) {
|
|
3215
|
-
|
|
3216
|
-
try {
|
|
3217
|
-
hook(element);
|
|
3218
|
-
} catch (e) {
|
|
3219
|
-
console.error("[Plugin] Unmount hook error:", e);
|
|
3220
|
-
}
|
|
3221
|
-
}
|
|
3646
|
+
defaultRegistry.triggerUnmount(element);
|
|
3222
3647
|
}
|
|
3223
3648
|
function triggerPluginError(error) {
|
|
3224
|
-
|
|
3225
|
-
try {
|
|
3226
|
-
hook(error);
|
|
3227
|
-
} catch (e) {
|
|
3228
|
-
console.error("[Plugin] Error hook error:", e);
|
|
3229
|
-
}
|
|
3230
|
-
}
|
|
3649
|
+
defaultRegistry.triggerError(error);
|
|
3231
3650
|
}
|
|
3232
3651
|
function resetPlugins() {
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3652
|
+
defaultRegistry.reset();
|
|
3653
|
+
defaultRegistryTouched = false;
|
|
3654
|
+
}
|
|
3655
|
+
function setDefaultPluginRegistry(registry) {
|
|
3656
|
+
if (defaultRegistryTouched && defaultRegistry.installedPlugins.size > 0) {
|
|
3657
|
+
console.warn(
|
|
3658
|
+
"[Plugin] Replacing default plugin registry while plugins are already installed on the singleton. This may indicate mixed singleton/registry usage."
|
|
3659
|
+
);
|
|
3660
|
+
}
|
|
3661
|
+
defaultRegistry = registry;
|
|
3662
|
+
defaultRegistryTouched = true;
|
|
3239
3663
|
}
|
|
3240
3664
|
|
|
3241
3665
|
// src/plugins/modular.ts
|
|
@@ -3713,7 +4137,8 @@ init_ssr();
|
|
|
3713
4137
|
function preloadCritical(resources) {
|
|
3714
4138
|
if (typeof document === "undefined") return;
|
|
3715
4139
|
for (const resource of resources) {
|
|
3716
|
-
const
|
|
4140
|
+
const safeHref = typeof CSS !== "undefined" && typeof CSS.escape === "function" ? CSS.escape(resource.href) : resource.href.replace(/["\\]/g, "\\$&");
|
|
4141
|
+
const existing = document.querySelector(`link[rel="preload"][href="${safeHref}"]`);
|
|
3717
4142
|
if (existing) continue;
|
|
3718
4143
|
const link2 = document.createElement("link");
|
|
3719
4144
|
link2.rel = "preload";
|
|
@@ -3948,6 +4373,7 @@ function createBootSequence() {
|
|
|
3948
4373
|
Suspense,
|
|
3949
4374
|
Trans,
|
|
3950
4375
|
VERSION,
|
|
4376
|
+
__removeRouterPagehideHandler,
|
|
3951
4377
|
addRoute,
|
|
3952
4378
|
afterEach,
|
|
3953
4379
|
back,
|
|
@@ -3963,6 +4389,7 @@ function createBootSequence() {
|
|
|
3963
4389
|
createMigrationRunner,
|
|
3964
4390
|
createModuleRegistry,
|
|
3965
4391
|
createPlugin,
|
|
4392
|
+
createPluginRegistry,
|
|
3966
4393
|
createRouter,
|
|
3967
4394
|
createSSRCache,
|
|
3968
4395
|
createSSRRouter,
|
|
@@ -4005,6 +4432,7 @@ function createBootSequence() {
|
|
|
4005
4432
|
routerState,
|
|
4006
4433
|
satisfies,
|
|
4007
4434
|
serializeRouteState,
|
|
4435
|
+
setDefaultPluginRegistry,
|
|
4008
4436
|
setLocale,
|
|
4009
4437
|
setRouteTransition,
|
|
4010
4438
|
setRoutes,
|