sibujs 3.4.0 → 4.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/LICENSE +21 -21
- package/README.md +118 -15
- package/dist/browser.cjs +410 -101
- package/dist/browser.d.cts +50 -5
- package/dist/browser.d.ts +50 -5
- package/dist/browser.js +8 -6
- package/dist/build.cjs +777 -385
- package/dist/build.js +15 -15
- package/dist/cdn.global.js +11 -7
- package/dist/{chunk-JCO7AHNU.js → chunk-3EKJK5FZ.js} +73 -34
- package/dist/chunk-4MFZMLUU.js +147 -0
- package/dist/chunk-52XFPGSN.js +123 -0
- package/dist/chunk-5INI7D2L.js +194 -0
- package/dist/{chunk-OAVXAFAY.js → chunk-6LG2T7LO.js} +5 -5
- package/dist/{chunk-OOUQUCNN.js → chunk-ACBT6UZS.js} +57 -22
- package/dist/{chunk-F7HW2NI5.js → chunk-AW6HPJ3L.js} +1 -1
- package/dist/chunk-DHDZ7IVN.js +109 -0
- package/dist/{chunk-JNGGM2XE.js → chunk-DQVUBVNX.js} +16 -25
- package/dist/{chunk-AXFWGY32.js → chunk-DR7H6UGM.js} +232 -67
- package/dist/{chunk-WSGLJYFI.js → chunk-E62UADKL.js} +9 -3
- package/dist/{chunk-3Z2NGWQI.js → chunk-ES2GERY2.js} +1 -1
- package/dist/{chunk-S3V6ZXPI.js → chunk-EWEE7NBF.js} +115 -41
- package/dist/{chunk-3DVGCW7O.js → chunk-F64ZPCFE.js} +8 -8
- package/dist/{chunk-APFRCIRI.js → chunk-GCSGGA3Q.js} +295 -198
- package/dist/{chunk-EX77FXTT.js → chunk-HYCCIYNS.js} +228 -51
- package/dist/{chunk-ELXMRSVN.js → chunk-NF3LYCQH.js} +259 -124
- package/dist/chunk-O3QQ3XOL.js +61 -0
- package/dist/{chunk-BUKYCWHX.js → chunk-PBQEW5VW.js} +14 -10
- package/dist/{chunk-H5FI5WDP.js → chunk-RRIDJQ5C.js} +3 -3
- package/dist/{chunk-S3NFJO6L.js → chunk-TIRZCERI.js} +36 -5
- package/dist/{chunk-ODXVQ3CS.js → chunk-VFHIVEPF.js} +309 -188
- package/dist/chunk-VPP2FONR.js +142 -0
- package/dist/{chunk-KZBEVFXZ.js → chunk-W55YHPEP.js} +5 -3
- package/dist/{chunk-FKQG7FTY.js → chunk-WN6WDFCB.js} +4 -4
- package/dist/{chunk-CEBWDD63.js → chunk-WOOMUJFT.js} +228 -86
- package/dist/{chunk-ITWCTZYH.js → chunk-Z2CE42DB.js} +19 -25
- package/dist/{contracts-ey_Qh8ef.d.cts → contracts-Hg6ITAEF.d.cts} +6 -6
- package/dist/{contracts-ey_Qh8ef.d.ts → contracts-Hg6ITAEF.d.ts} +6 -6
- package/dist/{customElement-CPfIrbvg.d.ts → customElement-CKLoO63w.d.cts} +73 -11
- package/dist/{customElement-CPfIrbvg.d.cts → customElement-CKLoO63w.d.ts} +73 -11
- package/dist/data.cjs +483 -205
- package/dist/data.d.cts +139 -7
- package/dist/data.d.ts +139 -7
- package/dist/data.js +9 -9
- package/dist/devtools.cjs +222 -87
- package/dist/devtools.js +8 -8
- package/dist/dispose-4FZ6OFXR.js +19 -0
- package/dist/ecosystem.cjs +419 -175
- package/dist/ecosystem.js +11 -11
- package/dist/extras.cjs +1981 -765
- package/dist/extras.d.cts +7 -7
- package/dist/extras.d.ts +7 -7
- package/dist/extras.js +29 -26
- package/dist/index.cjs +784 -385
- package/dist/index.d.cts +299 -28
- package/dist/index.d.ts +299 -28
- package/dist/index.js +33 -18
- package/dist/motion.cjs +180 -50
- package/dist/motion.d.cts +26 -0
- package/dist/motion.d.ts +26 -0
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +437 -170
- package/dist/patterns.d.cts +60 -13
- package/dist/patterns.d.ts +60 -13
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +333 -148
- package/dist/performance.d.cts +55 -7
- package/dist/performance.d.ts +55 -7
- package/dist/performance.js +9 -9
- package/dist/plugins.cjs +1374 -576
- package/dist/plugins.d.cts +227 -9
- package/dist/plugins.d.ts +227 -9
- package/dist/plugins.js +613 -321
- package/dist/{ssr-D62yFwuw.d.cts → ssr-BiPRdZ6n.d.cts} +44 -15
- package/dist/{ssr-D62yFwuw.d.ts → ssr-BiPRdZ6n.d.ts} +44 -15
- package/dist/{ssr-2PPULEK2.js → ssr-JFP5535P.js} +5 -4
- package/dist/ssr.cjs +1104 -443
- package/dist/ssr.d.cts +230 -20
- package/dist/ssr.d.ts +230 -20
- package/dist/ssr.js +15 -12
- package/dist/{startup-0Qv6aosO.d.cts → startup-BMpaiMhP.d.cts} +1 -1
- package/dist/{startup-0Qv6aosO.d.ts → startup-BMpaiMhP.d.ts} +1 -1
- package/dist/testing.cjs +205 -63
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +8 -10
- package/dist/ui.cjs +640 -199
- package/dist/ui.d.cts +2 -2
- package/dist/ui.d.ts +2 -2
- package/dist/ui.js +10 -10
- package/dist/widgets.cjs +207 -82
- package/dist/widgets.js +9 -9
- package/package.json +12 -7
- package/dist/chunk-5VGSK6D2.js +0 -80
- package/dist/chunk-COY6PUD2.js +0 -34
- package/dist/chunk-K35BAR4P.js +0 -96
- package/dist/chunk-L3GAGWCC.js +0 -111
- package/dist/chunk-RT3IYFN2.js +0 -38
|
@@ -1,59 +1,87 @@
|
|
|
1
|
+
import {
|
|
2
|
+
acquireBase,
|
|
3
|
+
acquireScrollRestorationMode,
|
|
4
|
+
acquireTitle
|
|
5
|
+
} from "./chunk-52XFPGSN.js";
|
|
1
6
|
import {
|
|
2
7
|
div,
|
|
3
8
|
span
|
|
4
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-ES2GERY2.js";
|
|
10
|
+
import {
|
|
11
|
+
STATIC_VALUE_RESOLVER,
|
|
12
|
+
planHeadElementEntry,
|
|
13
|
+
planMetaEntry
|
|
14
|
+
} from "./chunk-HYCCIYNS.js";
|
|
15
|
+
import {
|
|
16
|
+
sanitizeUrl
|
|
17
|
+
} from "./chunk-5INI7D2L.js";
|
|
5
18
|
import {
|
|
6
19
|
globalSingleton
|
|
7
20
|
} from "./chunk-7ZHH77QA.js";
|
|
8
|
-
import {
|
|
9
|
-
isEventHandlerAttr,
|
|
10
|
-
sanitizeUrl,
|
|
11
|
-
stripControlChars
|
|
12
|
-
} from "./chunk-L3GAGWCC.js";
|
|
13
21
|
import {
|
|
14
22
|
effect
|
|
15
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-PBQEW5VW.js";
|
|
16
24
|
import {
|
|
17
|
-
registerDisposer
|
|
18
|
-
|
|
25
|
+
registerDisposer,
|
|
26
|
+
replaceChildrenSafely
|
|
27
|
+
} from "./chunk-DHDZ7IVN.js";
|
|
19
28
|
import {
|
|
20
29
|
batch,
|
|
21
30
|
signal
|
|
22
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-W55YHPEP.js";
|
|
23
32
|
|
|
24
33
|
// src/platform/head.ts
|
|
25
|
-
var HEAD_URL_ATTRS = /* @__PURE__ */ new Set(["href", "src"]);
|
|
26
|
-
function sanitizeHeadAttr(key, value) {
|
|
27
|
-
if (HEAD_URL_ATTRS.has(key)) return sanitizeUrl(value);
|
|
28
|
-
return value;
|
|
29
|
-
}
|
|
30
|
-
function isDangerousRefreshContent(content) {
|
|
31
|
-
const normalized = stripControlChars(content).toLowerCase();
|
|
32
|
-
return normalized.includes("url=javascript:") || normalized.includes("url=data:") || normalized.includes("url=vbscript:") || normalized.includes("url=blob:");
|
|
33
|
-
}
|
|
34
|
-
function getMetaAttr(metaProps, name) {
|
|
35
|
-
for (const k in metaProps) {
|
|
36
|
-
if (k.toLowerCase() === name) return metaProps[k];
|
|
37
|
-
}
|
|
38
|
-
return void 0;
|
|
39
|
-
}
|
|
40
|
-
function isDangerousMetaRefresh(metaProps) {
|
|
41
|
-
const httpEquiv = getMetaAttr(metaProps, "http-equiv");
|
|
42
|
-
if (typeof httpEquiv !== "string") return false;
|
|
43
|
-
if (httpEquiv.toLowerCase() !== "refresh") return false;
|
|
44
|
-
const content = getMetaAttr(metaProps, "content");
|
|
45
|
-
if (typeof content !== "string") return false;
|
|
46
|
-
return isDangerousRefreshContent(content);
|
|
47
|
-
}
|
|
48
|
-
var SAFE_HEAD_ATTR_NAME = /^[A-Za-z_:][-A-Za-z0-9_.:]*$/;
|
|
49
|
-
function isSafeHeadAttr(name) {
|
|
50
|
-
if (!SAFE_HEAD_ATTR_NAME.test(name)) return false;
|
|
51
|
-
if (isEventHandlerAttr(name)) return false;
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
34
|
function escapeScriptJsonLocal(json) {
|
|
55
35
|
return json.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
56
36
|
}
|
|
37
|
+
var CLIENT_RESOLVER = {
|
|
38
|
+
resolveValue: (_name, value) => typeof value === "function" ? String(value()) : String(value),
|
|
39
|
+
isReactiveValue: (value) => typeof value === "function"
|
|
40
|
+
};
|
|
41
|
+
function applyMetaEntry(metaProps, managedElements) {
|
|
42
|
+
let current = null;
|
|
43
|
+
const retract = () => {
|
|
44
|
+
if (!current) return;
|
|
45
|
+
const index = managedElements.indexOf(current);
|
|
46
|
+
if (index !== -1) managedElements.splice(index, 1);
|
|
47
|
+
current.remove();
|
|
48
|
+
current = null;
|
|
49
|
+
};
|
|
50
|
+
const alreadyPublished = (attributes) => {
|
|
51
|
+
if (!current || current.attributes.length !== attributes.size) return false;
|
|
52
|
+
for (const [name, value] of attributes) {
|
|
53
|
+
if (current.getAttribute(name) !== value) return false;
|
|
54
|
+
}
|
|
55
|
+
return true;
|
|
56
|
+
};
|
|
57
|
+
const publish = (attributes) => {
|
|
58
|
+
if (alreadyPublished(attributes)) return;
|
|
59
|
+
const next = document.createElement("meta");
|
|
60
|
+
for (const [name, value] of attributes) next.setAttribute(name, value);
|
|
61
|
+
const index = current ? managedElements.indexOf(current) : -1;
|
|
62
|
+
if (current?.parentNode) {
|
|
63
|
+
current.replaceWith(next);
|
|
64
|
+
} else {
|
|
65
|
+
current?.remove();
|
|
66
|
+
document.head.appendChild(next);
|
|
67
|
+
}
|
|
68
|
+
if (index !== -1) managedElements[index] = next;
|
|
69
|
+
else managedElements.push(next);
|
|
70
|
+
current = next;
|
|
71
|
+
};
|
|
72
|
+
const stopEffect = effect(() => {
|
|
73
|
+
const plan = planMetaEntry(metaProps, CLIENT_RESOLVER);
|
|
74
|
+
if (plan.kind === "drop") {
|
|
75
|
+
retract();
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
publish(plan.attributes);
|
|
79
|
+
});
|
|
80
|
+
return () => {
|
|
81
|
+
stopEffect();
|
|
82
|
+
retract();
|
|
83
|
+
};
|
|
84
|
+
}
|
|
57
85
|
function Head(props) {
|
|
58
86
|
const anchor = document.createComment("sibu-head");
|
|
59
87
|
const managedElements = [];
|
|
@@ -70,78 +98,52 @@ function Head(props) {
|
|
|
70
98
|
cleanup();
|
|
71
99
|
if (props.title) {
|
|
72
100
|
if (typeof props.title === "function") {
|
|
73
|
-
const
|
|
74
|
-
|
|
101
|
+
const getter = props.title;
|
|
102
|
+
let lease = null;
|
|
103
|
+
const stopEffect = effect(() => {
|
|
104
|
+
const next = getter();
|
|
105
|
+
if (lease) lease.set(next);
|
|
106
|
+
else lease = acquireTitle(next);
|
|
107
|
+
});
|
|
108
|
+
effectCleanups.push(() => {
|
|
109
|
+
stopEffect();
|
|
110
|
+
lease?.release();
|
|
111
|
+
lease = null;
|
|
75
112
|
});
|
|
76
|
-
effectCleanups.push(cleanupFn);
|
|
77
113
|
} else {
|
|
78
|
-
|
|
114
|
+
const lease = acquireTitle(props.title);
|
|
115
|
+
effectCleanups.push(() => lease.release());
|
|
79
116
|
}
|
|
80
117
|
}
|
|
81
118
|
if (props.meta) {
|
|
82
119
|
for (const metaProps of props.meta) {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const isRefreshNow = () => {
|
|
86
|
-
const eq = typeof httpEquiv === "function" ? httpEquiv() : httpEquiv;
|
|
87
|
-
return typeof eq === "string" && eq.toLowerCase() === "refresh";
|
|
88
|
-
};
|
|
89
|
-
const el = document.createElement("meta");
|
|
90
|
-
for (const [key, value] of Object.entries(metaProps)) {
|
|
91
|
-
if (!isSafeHeadAttr(key)) continue;
|
|
92
|
-
const isContent = key.toLowerCase() === "content";
|
|
93
|
-
if (typeof value === "function") {
|
|
94
|
-
const cleanupFn = effect(() => {
|
|
95
|
-
const resolved = value();
|
|
96
|
-
if (isContent && isRefreshNow() && isDangerousRefreshContent(resolved)) {
|
|
97
|
-
el.removeAttribute(key);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
el.setAttribute(key, sanitizeHeadAttr(key, resolved));
|
|
101
|
-
});
|
|
102
|
-
effectCleanups.push(cleanupFn);
|
|
103
|
-
} else {
|
|
104
|
-
if (isContent && isRefreshNow() && isDangerousRefreshContent(value)) continue;
|
|
105
|
-
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
document.head.appendChild(el);
|
|
109
|
-
managedElements.push(el);
|
|
120
|
+
const stop = applyMetaEntry(metaProps, managedElements);
|
|
121
|
+
effectCleanups.push(stop);
|
|
110
122
|
}
|
|
111
123
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
if (props.script) {
|
|
124
|
-
for (const scriptProps of props.script) {
|
|
125
|
-
const el = document.createElement("script");
|
|
126
|
-
for (const [key, value] of Object.entries(scriptProps)) {
|
|
127
|
-
if (!isSafeHeadAttr(key)) continue;
|
|
128
|
-
el.setAttribute(key, sanitizeHeadAttr(key, value));
|
|
129
|
-
}
|
|
124
|
+
for (const [tag, entries] of [
|
|
125
|
+
["link", props.link],
|
|
126
|
+
["script", props.script]
|
|
127
|
+
]) {
|
|
128
|
+
if (!entries) continue;
|
|
129
|
+
for (const entryProps of entries) {
|
|
130
|
+
const plan = planHeadElementEntry(entryProps, STATIC_VALUE_RESOLVER);
|
|
131
|
+
if (plan.kind === "drop") continue;
|
|
132
|
+
const el = document.createElement(tag);
|
|
133
|
+
for (const [name, value] of plan.attributes) el.setAttribute(name, value);
|
|
130
134
|
document.head.appendChild(el);
|
|
131
135
|
managedElements.push(el);
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
if (props.base) {
|
|
135
|
-
const
|
|
136
|
-
if (existing) existing.remove();
|
|
137
|
-
const el = document.createElement("base");
|
|
139
|
+
const spec = {};
|
|
138
140
|
if (props.base.href) {
|
|
139
141
|
const safeHref = sanitizeUrl(props.base.href);
|
|
140
|
-
if (safeHref)
|
|
142
|
+
if (safeHref) spec.href = safeHref;
|
|
141
143
|
}
|
|
142
|
-
if (props.base.target)
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
if (props.base.target) spec.target = props.base.target;
|
|
145
|
+
const lease = acquireBase(spec);
|
|
146
|
+
effectCleanups.push(() => lease.release());
|
|
145
147
|
}
|
|
146
148
|
};
|
|
147
149
|
apply();
|
|
@@ -164,7 +166,9 @@ function setCanonical(url) {
|
|
|
164
166
|
link.rel = "canonical";
|
|
165
167
|
document.head.appendChild(link);
|
|
166
168
|
}
|
|
167
|
-
|
|
169
|
+
const safe = sanitizeUrl(url);
|
|
170
|
+
if (safe) link.setAttribute("href", safe);
|
|
171
|
+
else link.removeAttribute("href");
|
|
168
172
|
}
|
|
169
173
|
|
|
170
174
|
// src/platform/worker.ts
|
|
@@ -390,22 +394,34 @@ var instanceCache = globalSingleton(
|
|
|
390
394
|
/* @__PURE__ */ Symbol.for("sibujs.wasm.instanceCache.v1"),
|
|
391
395
|
() => /* @__PURE__ */ new Map()
|
|
392
396
|
);
|
|
397
|
+
var inFlightCache = globalSingleton(
|
|
398
|
+
/* @__PURE__ */ Symbol.for("sibujs.wasm.inFlightCache.v1"),
|
|
399
|
+
() => /* @__PURE__ */ new Map()
|
|
400
|
+
);
|
|
401
|
+
var cacheState = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.wasm.cacheState.v1"), () => ({ generation: 0 }));
|
|
402
|
+
function isCurrentGeneration(generation) {
|
|
403
|
+
return generation === cacheState.generation;
|
|
404
|
+
}
|
|
393
405
|
function wasm(source, config = {}) {
|
|
394
406
|
const [instance, setInstance] = signal(null);
|
|
395
407
|
const [loading, setLoading] = signal(true);
|
|
396
408
|
const [error, setError] = signal(null);
|
|
397
409
|
const cacheKey = config.cacheKey || (typeof source === "string" ? source : void 0);
|
|
410
|
+
let runId = 0;
|
|
398
411
|
async function load() {
|
|
412
|
+
const myRun = ++runId;
|
|
399
413
|
setLoading(true);
|
|
400
414
|
setError(null);
|
|
401
415
|
setInstance(null);
|
|
402
416
|
try {
|
|
403
|
-
const wasmInstance = await
|
|
417
|
+
const wasmInstance = await loadWasmModuleWithOptions(source, { ...config, cacheKey });
|
|
418
|
+
if (myRun !== runId) return;
|
|
404
419
|
setInstance(wasmInstance.exports);
|
|
405
420
|
} catch (err) {
|
|
421
|
+
if (myRun !== runId) return;
|
|
406
422
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
407
423
|
} finally {
|
|
408
|
-
setLoading(false);
|
|
424
|
+
if (myRun === runId) setLoading(false);
|
|
409
425
|
}
|
|
410
426
|
}
|
|
411
427
|
load();
|
|
@@ -418,9 +434,9 @@ function wasm(source, config = {}) {
|
|
|
418
434
|
};
|
|
419
435
|
}
|
|
420
436
|
async function loadWasmModule(source, imports, cacheKey) {
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
437
|
+
return loadWasmModuleWithOptions(source, { imports, cacheKey });
|
|
438
|
+
}
|
|
439
|
+
async function loadWasmModuleWithOptions(source, opts = {}) {
|
|
424
440
|
const key = opts.cacheKey || (typeof source === "string" ? source : void 0);
|
|
425
441
|
if (typeof source === "string") {
|
|
426
442
|
const allowed = opts.allowedOrigins ?? [];
|
|
@@ -440,44 +456,50 @@ async function loadWasmModule(source, imports, cacheKey) {
|
|
|
440
456
|
);
|
|
441
457
|
}
|
|
442
458
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
459
|
+
const generation = cacheState.generation;
|
|
460
|
+
if (!key) return instantiateWasm(source, opts.imports, void 0, generation);
|
|
461
|
+
const cachedInstance = instanceCache.get(key);
|
|
462
|
+
if (cachedInstance) return cachedInstance;
|
|
463
|
+
const inFlight = inFlightCache.get(key);
|
|
464
|
+
if (inFlight) return inFlight;
|
|
465
|
+
const pending = instantiateWasm(source, opts.imports, key, generation).then((instance) => {
|
|
466
|
+
if (isCurrentGeneration(generation)) instanceCache.set(key, instance);
|
|
467
|
+
return instance;
|
|
468
|
+
});
|
|
469
|
+
inFlightCache.set(key, pending);
|
|
470
|
+
void pending.catch(() => {
|
|
471
|
+
}).then(() => {
|
|
472
|
+
if (inFlightCache.get(key) === pending) inFlightCache.delete(key);
|
|
473
|
+
});
|
|
474
|
+
return pending;
|
|
475
|
+
}
|
|
476
|
+
async function instantiateWasm(source, wasmImports, key, generation) {
|
|
450
477
|
const cachedModule = key ? moduleCache.get(key) : void 0;
|
|
451
478
|
if (cachedModule) {
|
|
452
|
-
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
instanceCache.set(key, result.instance);
|
|
462
|
-
}
|
|
463
|
-
return result.instance;
|
|
464
|
-
}
|
|
465
|
-
const response = await fetch(source);
|
|
466
|
-
bytes = await response.arrayBuffer();
|
|
467
|
-
} else if (source instanceof Uint8Array) {
|
|
468
|
-
bytes = source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
|
|
469
|
-
} else {
|
|
470
|
-
bytes = source;
|
|
479
|
+
return WebAssembly.instantiate(cachedModule, wasmImports || {});
|
|
480
|
+
}
|
|
481
|
+
let bytes;
|
|
482
|
+
if (typeof source === "string") {
|
|
483
|
+
if (typeof WebAssembly.instantiateStreaming === "function") {
|
|
484
|
+
const response2 = fetch(source);
|
|
485
|
+
const result = await WebAssembly.instantiateStreaming(response2, wasmImports || {});
|
|
486
|
+
if (key && isCurrentGeneration(generation)) moduleCache.set(key, result.module);
|
|
487
|
+
return result.instance;
|
|
471
488
|
}
|
|
472
|
-
|
|
473
|
-
|
|
489
|
+
const response = await fetch(source);
|
|
490
|
+
bytes = await response.arrayBuffer();
|
|
491
|
+
} else if (source instanceof Uint8Array) {
|
|
492
|
+
bytes = source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
|
|
493
|
+
} else {
|
|
494
|
+
bytes = source;
|
|
474
495
|
}
|
|
475
|
-
const
|
|
476
|
-
if (key)
|
|
477
|
-
return
|
|
496
|
+
const module = await WebAssembly.compile(bytes);
|
|
497
|
+
if (key && isCurrentGeneration(generation)) moduleCache.set(key, module);
|
|
498
|
+
return WebAssembly.instantiate(module, wasmImports || {});
|
|
478
499
|
}
|
|
479
500
|
async function preloadWasm(url, options = {}) {
|
|
480
501
|
if (moduleCache.has(url)) return;
|
|
502
|
+
const generation = cacheState.generation;
|
|
481
503
|
const allowed = options.allowedOrigins ?? [];
|
|
482
504
|
if (allowed.length > 0) {
|
|
483
505
|
let parsed;
|
|
@@ -502,7 +524,7 @@ async function preloadWasm(url, options = {}) {
|
|
|
502
524
|
const bytes = await response.arrayBuffer();
|
|
503
525
|
module = await WebAssembly.compile(bytes);
|
|
504
526
|
}
|
|
505
|
-
moduleCache.set(url, module);
|
|
527
|
+
if (isCurrentGeneration(generation)) moduleCache.set(url, module);
|
|
506
528
|
}
|
|
507
529
|
function createWasmBridge(instance) {
|
|
508
530
|
const exports = instance.exports;
|
|
@@ -542,8 +564,10 @@ function createWasmBridge(instance) {
|
|
|
542
564
|
};
|
|
543
565
|
}
|
|
544
566
|
function clearWasmCache() {
|
|
567
|
+
cacheState.generation++;
|
|
545
568
|
moduleCache.clear();
|
|
546
569
|
instanceCache.clear();
|
|
570
|
+
inFlightCache.clear();
|
|
547
571
|
}
|
|
548
572
|
function isWasmCached(key) {
|
|
549
573
|
return moduleCache.has(key);
|
|
@@ -565,14 +589,13 @@ function createMicroApp(config) {
|
|
|
565
589
|
}
|
|
566
590
|
let mounted = false;
|
|
567
591
|
function mount(component) {
|
|
568
|
-
root.replaceChildren();
|
|
569
592
|
const el = component();
|
|
570
|
-
root
|
|
593
|
+
replaceChildrenSafely(root, el);
|
|
571
594
|
mounted = true;
|
|
572
595
|
}
|
|
573
596
|
function unmount() {
|
|
574
597
|
if (!mounted) return;
|
|
575
|
-
root
|
|
598
|
+
replaceChildrenSafely(root);
|
|
576
599
|
mounted = false;
|
|
577
600
|
}
|
|
578
601
|
return { mount, unmount, element: host };
|
|
@@ -619,18 +642,21 @@ function defineRemoteComponent(name, loader) {
|
|
|
619
642
|
class: "sibu-remote",
|
|
620
643
|
"data-remote-component": name
|
|
621
644
|
});
|
|
622
|
-
container.appendChild(span({ class: "sibu-remote-loading",
|
|
645
|
+
container.appendChild(span({ class: "sibu-remote-loading" }, "Loading..."));
|
|
646
|
+
let disposed = false;
|
|
647
|
+
registerDisposer(container, () => {
|
|
648
|
+
disposed = true;
|
|
649
|
+
});
|
|
623
650
|
loader().then((mod) => {
|
|
624
651
|
cached = mod.default;
|
|
625
|
-
|
|
626
|
-
container
|
|
652
|
+
if (disposed) return;
|
|
653
|
+
replaceChildrenSafely(container, cached());
|
|
627
654
|
}).catch((err) => {
|
|
655
|
+
if (disposed) return;
|
|
628
656
|
const message = err instanceof Error ? err.message : String(err);
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
nodes: `Failed to load remote component "${name}": ${message}`
|
|
633
|
-
})
|
|
657
|
+
replaceChildrenSafely(
|
|
658
|
+
container,
|
|
659
|
+
div({ class: "sibu-remote-error" }, `Failed to load remote component "${name}": ${message}`)
|
|
634
660
|
);
|
|
635
661
|
});
|
|
636
662
|
return container;
|
|
@@ -686,11 +712,16 @@ function serviceWorker(scriptUrl, options) {
|
|
|
686
712
|
const [isReady, setIsReady] = signal(false);
|
|
687
713
|
const [isUpdateAvailable, setIsUpdateAvailable] = signal(false);
|
|
688
714
|
const [error, setError] = signal(null);
|
|
689
|
-
let
|
|
715
|
+
let unregistered = false;
|
|
716
|
+
let unregisterRequested = false;
|
|
717
|
+
let registrationPromise = null;
|
|
718
|
+
let arrivedRegistration = null;
|
|
719
|
+
let pendingUnregister = null;
|
|
690
720
|
let updateFoundHandler = null;
|
|
691
721
|
let stateChangeHandler = null;
|
|
692
722
|
let trackedWorker = null;
|
|
693
723
|
let trackedReg = null;
|
|
724
|
+
const supported = typeof navigator !== "undefined" && !!navigator.serviceWorker;
|
|
694
725
|
function detachListeners() {
|
|
695
726
|
if (trackedReg && updateFoundHandler) {
|
|
696
727
|
trackedReg.removeEventListener("updatefound", updateFoundHandler);
|
|
@@ -703,33 +734,53 @@ function serviceWorker(scriptUrl, options) {
|
|
|
703
734
|
trackedWorker = null;
|
|
704
735
|
trackedReg = null;
|
|
705
736
|
}
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
const newWorker = reg.installing;
|
|
715
|
-
if (newWorker) {
|
|
716
|
-
if (trackedWorker && stateChangeHandler) {
|
|
717
|
-
trackedWorker.removeEventListener("statechange", stateChangeHandler);
|
|
718
|
-
}
|
|
719
|
-
trackedWorker = newWorker;
|
|
720
|
-
stateChangeHandler = () => {
|
|
721
|
-
if (disposed) return;
|
|
722
|
-
if (newWorker.state === "installed" && navigator.serviceWorker.controller) {
|
|
723
|
-
setIsUpdateAvailable(true);
|
|
724
|
-
}
|
|
725
|
-
};
|
|
726
|
-
newWorker.addEventListener("statechange", stateChangeHandler);
|
|
737
|
+
function attachListeners(reg) {
|
|
738
|
+
trackedReg = reg;
|
|
739
|
+
updateFoundHandler = () => {
|
|
740
|
+
if (unregistered) return;
|
|
741
|
+
const newWorker = reg.installing;
|
|
742
|
+
if (newWorker) {
|
|
743
|
+
if (trackedWorker && stateChangeHandler) {
|
|
744
|
+
trackedWorker.removeEventListener("statechange", stateChangeHandler);
|
|
727
745
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
746
|
+
trackedWorker = newWorker;
|
|
747
|
+
stateChangeHandler = () => {
|
|
748
|
+
if (unregistered) return;
|
|
749
|
+
if (newWorker.state === "installed" && navigator.serviceWorker.controller) {
|
|
750
|
+
setIsUpdateAvailable(true);
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
newWorker.addEventListener("statechange", stateChangeHandler);
|
|
754
|
+
}
|
|
755
|
+
};
|
|
756
|
+
reg.addEventListener("updatefound", updateFoundHandler);
|
|
757
|
+
}
|
|
758
|
+
function activate(reg) {
|
|
759
|
+
setRegistration(reg);
|
|
760
|
+
setIsReady(true);
|
|
761
|
+
attachListeners(reg);
|
|
762
|
+
}
|
|
763
|
+
function recoverFailedUnregister() {
|
|
764
|
+
unregisterRequested = false;
|
|
765
|
+
if (!registration() && arrivedRegistration) {
|
|
766
|
+
activate(arrivedRegistration);
|
|
767
|
+
arrivedRegistration = null;
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
function adopt(reg) {
|
|
771
|
+
if (unregisterRequested) {
|
|
772
|
+
arrivedRegistration = reg;
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
activate(reg);
|
|
776
|
+
return reg;
|
|
777
|
+
}
|
|
778
|
+
if (supported) {
|
|
779
|
+
registrationPromise = navigator.serviceWorker.register(scriptUrl, options).then(adopt).catch((err) => {
|
|
780
|
+
if (!unregistered) {
|
|
781
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
782
|
+
}
|
|
783
|
+
return null;
|
|
733
784
|
});
|
|
734
785
|
}
|
|
735
786
|
async function update() {
|
|
@@ -738,19 +789,43 @@ function serviceWorker(scriptUrl, options) {
|
|
|
738
789
|
await reg.update();
|
|
739
790
|
}
|
|
740
791
|
}
|
|
741
|
-
async function
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
const reg = registration();
|
|
745
|
-
if (reg) {
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
792
|
+
async function performUnregister() {
|
|
793
|
+
unregisterRequested = true;
|
|
794
|
+
if (registrationPromise) await registrationPromise.catch(() => null);
|
|
795
|
+
const reg = registration() ?? arrivedRegistration;
|
|
796
|
+
if (!reg) {
|
|
797
|
+
unregisterRequested = false;
|
|
798
|
+
return false;
|
|
799
|
+
}
|
|
800
|
+
let result;
|
|
801
|
+
try {
|
|
802
|
+
result = await reg.unregister();
|
|
803
|
+
} catch (err) {
|
|
804
|
+
recoverFailedUnregister();
|
|
805
|
+
throw err;
|
|
806
|
+
}
|
|
807
|
+
if (result) {
|
|
808
|
+
detachListeners();
|
|
809
|
+
setRegistration(null);
|
|
810
|
+
setIsReady(false);
|
|
811
|
+
setIsUpdateAvailable(false);
|
|
812
|
+
arrivedRegistration = null;
|
|
813
|
+
unregistered = true;
|
|
814
|
+
} else {
|
|
815
|
+
recoverFailedUnregister();
|
|
752
816
|
}
|
|
753
|
-
return
|
|
817
|
+
return result;
|
|
818
|
+
}
|
|
819
|
+
async function unregister() {
|
|
820
|
+
if (!supported || unregistered) return false;
|
|
821
|
+
if (pendingUnregister) return pendingUnregister;
|
|
822
|
+
const request = performUnregister();
|
|
823
|
+
pendingUnregister = request;
|
|
824
|
+
void request.catch(() => {
|
|
825
|
+
}).then(() => {
|
|
826
|
+
if (pendingUnregister === request) pendingUnregister = null;
|
|
827
|
+
});
|
|
828
|
+
return request;
|
|
754
829
|
}
|
|
755
830
|
return { registration, isReady, isUpdateAvailable, error, update, unregister };
|
|
756
831
|
}
|
|
@@ -855,17 +930,39 @@ function createAction(actionFn) {
|
|
|
855
930
|
}
|
|
856
931
|
|
|
857
932
|
// src/platform/scrollRestoration.ts
|
|
933
|
+
var DEFAULT_STATE_KEY = "__sibuScrollKey";
|
|
858
934
|
function scrollRestoration(options) {
|
|
859
935
|
const mode = options?.mode ?? "auto";
|
|
936
|
+
const stateKey = options?.stateKey ?? DEFAULT_STATE_KEY;
|
|
860
937
|
const positions = /* @__PURE__ */ new Map();
|
|
861
938
|
let popstateHandler = null;
|
|
862
939
|
let currentKey = null;
|
|
863
|
-
|
|
940
|
+
if (options?.getKey) {
|
|
941
|
+
try {
|
|
942
|
+
currentKey = options.getKey();
|
|
943
|
+
} catch {
|
|
944
|
+
currentKey = null;
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
const record = (key) => {
|
|
864
948
|
if (typeof window !== "undefined") {
|
|
865
949
|
positions.set(key, { x: window.scrollX, y: window.scrollY });
|
|
866
950
|
}
|
|
867
951
|
currentKey = key;
|
|
868
952
|
};
|
|
953
|
+
const tagCurrentEntry = (key) => {
|
|
954
|
+
if (typeof window === "undefined" || typeof history === "undefined") return;
|
|
955
|
+
try {
|
|
956
|
+
const existing = history.state ?? {};
|
|
957
|
+
if (existing[stateKey] === key) return;
|
|
958
|
+
history.replaceState({ ...existing, [stateKey]: key }, "");
|
|
959
|
+
} catch {
|
|
960
|
+
}
|
|
961
|
+
};
|
|
962
|
+
const save = (key) => {
|
|
963
|
+
record(key);
|
|
964
|
+
if (mode === "auto") tagCurrentEntry(key);
|
|
965
|
+
};
|
|
869
966
|
const restore = (key) => {
|
|
870
967
|
const pos = positions.get(key);
|
|
871
968
|
if (pos && typeof window !== "undefined") {
|
|
@@ -876,11 +973,32 @@ function scrollRestoration(options) {
|
|
|
876
973
|
const getPosition = (key) => {
|
|
877
974
|
return positions.get(key);
|
|
878
975
|
};
|
|
976
|
+
const onNavigation = (key) => {
|
|
977
|
+
if (mode !== "auto") return;
|
|
978
|
+
if (currentKey !== null && currentKey !== key) record(currentKey);
|
|
979
|
+
currentKey = key;
|
|
980
|
+
tagCurrentEntry(key);
|
|
981
|
+
};
|
|
982
|
+
let nativeModeLease = null;
|
|
879
983
|
if (mode === "auto" && typeof window !== "undefined") {
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
984
|
+
nativeModeLease = acquireScrollRestorationMode("manual");
|
|
985
|
+
if (currentKey !== null) tagCurrentEntry(currentKey);
|
|
986
|
+
popstateHandler = (event) => {
|
|
987
|
+
const state = event.state ?? null;
|
|
988
|
+
const rawDestination = state ? state[stateKey] : void 0;
|
|
989
|
+
const destination = typeof rawDestination === "string" ? rawDestination : null;
|
|
990
|
+
let outgoing = currentKey;
|
|
991
|
+
if (outgoing === null && options?.getKey) {
|
|
992
|
+
try {
|
|
993
|
+
outgoing = options.getKey();
|
|
994
|
+
} catch {
|
|
995
|
+
outgoing = null;
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
if (outgoing !== null && outgoing !== destination) {
|
|
999
|
+
record(outgoing);
|
|
883
1000
|
}
|
|
1001
|
+
if (destination !== null) restore(destination);
|
|
884
1002
|
};
|
|
885
1003
|
window.addEventListener("popstate", popstateHandler);
|
|
886
1004
|
}
|
|
@@ -889,9 +1007,11 @@ function scrollRestoration(options) {
|
|
|
889
1007
|
window.removeEventListener("popstate", popstateHandler);
|
|
890
1008
|
popstateHandler = null;
|
|
891
1009
|
}
|
|
1010
|
+
nativeModeLease?.release();
|
|
1011
|
+
nativeModeLease = null;
|
|
892
1012
|
positions.clear();
|
|
893
1013
|
};
|
|
894
|
-
return { save, restore, getPosition, dispose };
|
|
1014
|
+
return { save, restore, onNavigation, getPosition, dispose };
|
|
895
1015
|
}
|
|
896
1016
|
|
|
897
1017
|
// src/platform/routeMiddleware.ts
|
|
@@ -934,6 +1054,7 @@ export {
|
|
|
934
1054
|
createWorkerPool,
|
|
935
1055
|
wasm,
|
|
936
1056
|
loadWasmModule,
|
|
1057
|
+
loadWasmModuleWithOptions,
|
|
937
1058
|
preloadWasm,
|
|
938
1059
|
createWasmBridge,
|
|
939
1060
|
clearWasmCache,
|