sibujs 4.4.0 → 4.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -0
- package/dist/browser.cjs +339 -130
- package/dist/browser.d.cts +61 -16
- package/dist/browser.d.ts +61 -16
- package/dist/browser.js +8 -6
- package/dist/build.cjs +273 -82
- package/dist/build.js +15 -16
- package/dist/cdn.dev.global.js +12 -12
- package/dist/cdn.full.dev.global.js +11 -11
- package/dist/cdn.full.global.js +10 -10
- package/dist/cdn.global.js +12 -12
- package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
- package/dist/chunk-3ISI6ACU.js +44 -0
- package/dist/{chunk-VCTAEPSB.js → chunk-47M47FOM.js} +11 -3
- package/dist/chunk-5HZXGZ6T.js +24 -0
- package/dist/{chunk-KKLW7YWL.js → chunk-5MT6SJ3P.js} +275 -144
- package/dist/{chunk-3BTTCZ5J.js → chunk-5Q4R7HCL.js} +42 -4
- package/dist/{chunk-ADM46X22.js → chunk-7GQCWFOE.js} +157 -61
- package/dist/{chunk-4Z3SPQ67.js → chunk-7NCARGJW.js} +16 -8
- package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
- package/dist/{chunk-LQFGQNMV.js → chunk-AIF3Z2T7.js} +302 -39
- package/dist/{chunk-UCALUKB5.js → chunk-BAAG6ZTI.js} +98 -29
- package/dist/{chunk-NVNJH22U.js → chunk-D33YTSX5.js} +2 -2
- package/dist/{chunk-M2F7TZHH.js → chunk-DKGBBKOF.js} +136 -80
- package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
- package/dist/{chunk-HFCOH2GN.js → chunk-HYXDKS4N.js} +153 -110
- package/dist/chunk-J6FW5TV6.js +233 -0
- package/dist/{chunk-36S2YPP4.js → chunk-JSXPZCET.js} +1 -1
- package/dist/chunk-NYNYSPK7.js +318 -0
- package/dist/{chunk-HQSEH5F6.js → chunk-ORMZXBKQ.js} +108 -45
- package/dist/{chunk-LYVUX7NT.js → chunk-OXUY2A6L.js} +287 -130
- package/dist/{chunk-6GSIXTWX.js → chunk-PK6FK2G2.js} +187 -66
- package/dist/{chunk-W2EQ7X2L.js → chunk-QE4TTDU3.js} +47 -9
- package/dist/{chunk-XLO7SLIX.js → chunk-SXXVZMKZ.js} +262 -70
- package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
- package/dist/{chunk-RR7M3FHM.js → chunk-UZQ6ALFS.js} +3 -3
- package/dist/{chunk-PNIRUQ4C.js → chunk-VVWPJ543.js} +6 -8
- package/dist/{chunk-7GIHSAWB.js → chunk-XC4MEKGA.js} +3 -3
- package/dist/{chunk-SKPTERHP.js → chunk-XRRZKZYX.js} +55 -31
- package/dist/{contracts-DBdg9J_a.d.cts → contracts-DRIuclVT.d.cts} +10 -2
- package/dist/{contracts-DBdg9J_a.d.ts → contracts-DRIuclVT.d.ts} +10 -2
- package/dist/{customElement-CNZxEB9G.d.ts → customElement-MmInOW1U.d.cts} +59 -10
- package/dist/{customElement-CNZxEB9G.d.cts → customElement-MmInOW1U.d.ts} +59 -10
- package/dist/data.cjs +293 -125
- package/dist/data.d.cts +47 -9
- package/dist/data.d.ts +47 -9
- package/dist/data.js +12 -9
- package/dist/devtools.cjs +121 -58
- package/dist/devtools.js +7 -8
- package/dist/dispose-GEIG2KOF.js +28 -0
- package/dist/ecosystem.cjs +391 -112
- package/dist/ecosystem.d.cts +31 -7
- package/dist/ecosystem.d.ts +31 -7
- package/dist/ecosystem.js +12 -12
- package/dist/extras.cjs +2250 -879
- package/dist/extras.d.cts +10 -9
- package/dist/extras.d.ts +10 -9
- package/dist/extras.js +39 -28
- package/dist/index.cjs +273 -82
- package/dist/index.d.cts +44 -154
- package/dist/index.d.ts +44 -154
- package/dist/index.js +24 -27
- package/dist/motion.cjs +137 -42
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +397 -48
- package/dist/patterns.d.cts +32 -9
- package/dist/patterns.d.ts +32 -9
- package/dist/patterns.js +8 -8
- package/dist/performance.cjs +338 -217
- package/dist/performance.d.cts +2 -2
- package/dist/performance.d.ts +2 -2
- package/dist/performance.js +8 -9
- package/dist/plugin-DVgSnTfK.d.cts +112 -0
- package/dist/plugin-DVgSnTfK.d.ts +112 -0
- package/dist/plugins.cjs +587 -203
- package/dist/plugins.d.cts +3 -3
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +35 -23
- package/dist/signal-EotCj4hS.d.cts +110 -0
- package/dist/signal-EotCj4hS.d.ts +110 -0
- package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
- package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
- package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
- package/dist/ssr.cjs +214 -73
- package/dist/ssr.d.cts +9 -3
- package/dist/ssr.d.ts +9 -3
- package/dist/ssr.js +11 -12
- package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
- package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
- package/dist/tagFactory-DFstCLQV.d.cts +117 -0
- package/dist/tagFactory-DkaNVUNV.d.ts +117 -0
- package/dist/testing.cjs +2481 -2153
- package/dist/testing.d.cts +56 -5
- package/dist/testing.d.ts +56 -5
- package/dist/testing.js +580 -307
- package/dist/ui.cjs +798 -328
- package/dist/ui.d.cts +40 -7
- package/dist/ui.d.ts +40 -7
- package/dist/ui.js +151 -56
- package/dist/widgets.cjs +319 -285
- package/dist/widgets.js +9 -10
- package/package.json +2 -2
- package/dist/chunk-2WLZ6757.js +0 -149
- package/dist/chunk-7NBDXVHS.js +0 -60
- package/dist/chunk-CCSJMTRN.js +0 -15
- package/dist/chunk-QKRPLZ2V.js +0 -108
- package/dist/chunk-WWV3SJ3L.js +0 -131
- package/dist/dispose-46BOMMQJ.js +0 -19
- package/dist/plugin-D30wlGW5.d.cts +0 -71
- package/dist/plugin-D30wlGW5.d.ts +0 -71
- package/dist/tagFactory-Bzupt4Pj.d.cts +0 -55
- package/dist/tagFactory-Bzupt4Pj.d.ts +0 -55
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import {
|
|
2
|
+
globalSingleton
|
|
3
|
+
} from "./chunk-7ZHH77QA.js";
|
|
4
|
+
import {
|
|
5
|
+
adoptThenable
|
|
6
|
+
} from "./chunk-5HZXGZ6T.js";
|
|
7
|
+
import {
|
|
8
|
+
DEV,
|
|
9
|
+
devWarn,
|
|
10
|
+
reportError
|
|
11
|
+
} from "./chunk-NYNYSPK7.js";
|
|
12
|
+
|
|
13
|
+
// src/plugins/plugin.ts
|
|
14
|
+
var CANCELLED_BRAND = /* @__PURE__ */ Symbol.for("sibujs.plugins.installCancelled.v1");
|
|
15
|
+
var _a;
|
|
16
|
+
var PluginInstallCancelledError = class extends Error {
|
|
17
|
+
constructor(pluginName) {
|
|
18
|
+
super(`[Plugin] Installation of "${pluginName}" was cancelled before it was committed (registry reset).`);
|
|
19
|
+
/**
|
|
20
|
+
* Brand, not identity: the default registry is shared across duplicate copies
|
|
21
|
+
* of this module, so the error a caller receives may come from another copy's
|
|
22
|
+
* constructor. `instanceof` is taught to recognise the brand instead.
|
|
23
|
+
*/
|
|
24
|
+
this[_a] = true;
|
|
25
|
+
this.name = "PluginInstallCancelledError";
|
|
26
|
+
this.pluginName = pluginName;
|
|
27
|
+
}
|
|
28
|
+
static [(_a = CANCELLED_BRAND, Symbol.hasInstance)](value) {
|
|
29
|
+
return isPluginInstallCancelledError(value);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
function isPluginInstallCancelledError(value) {
|
|
33
|
+
return typeof value === "object" && value !== null && value[CANCELLED_BRAND] === true;
|
|
34
|
+
}
|
|
35
|
+
function createPluginRegistry() {
|
|
36
|
+
const installedPlugins = /* @__PURE__ */ new Set();
|
|
37
|
+
const hooks = { init: [], mount: [], unmount: [], error: [] };
|
|
38
|
+
const provided = /* @__PURE__ */ new Map();
|
|
39
|
+
const installStack = /* @__PURE__ */ new Set();
|
|
40
|
+
const pendingInstalls = /* @__PURE__ */ new Map();
|
|
41
|
+
let generation = 0;
|
|
42
|
+
const registry = {
|
|
43
|
+
installedPlugins,
|
|
44
|
+
hooks,
|
|
45
|
+
provided,
|
|
46
|
+
/**
|
|
47
|
+
* Install a plugin as a transaction.
|
|
48
|
+
*
|
|
49
|
+
* Hooks and providers registered through `ctx` are staged and committed
|
|
50
|
+
* only if `install()` returns; a throwing install leaves the registry
|
|
51
|
+
* exactly as it found it (and can simply be retried). The plugin is marked
|
|
52
|
+
* installed at commit, before its init hooks run.
|
|
53
|
+
*
|
|
54
|
+
* Each `plugin()` call is its own transaction: a dependency installed by a
|
|
55
|
+
* nested `plugin()` call commits on its own and stays installed even if the
|
|
56
|
+
* outer installation later fails.
|
|
57
|
+
*/
|
|
58
|
+
plugin(p, options) {
|
|
59
|
+
if (installedPlugins.has(p.name)) {
|
|
60
|
+
console.warn(`[Plugin] "${p.name}" is already installed.`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (installStack.has(p.name)) {
|
|
64
|
+
throw new Error(`[Plugin] "${p.name}" is already being installed (recursive installation).`);
|
|
65
|
+
}
|
|
66
|
+
if (pendingInstalls.has(p.name)) {
|
|
67
|
+
throw new Error(`[Plugin] "${p.name}" is already being installed (asynchronous installation in flight).`);
|
|
68
|
+
}
|
|
69
|
+
const staged = { init: [], mount: [], unmount: [], error: [] };
|
|
70
|
+
const stagedProvided = /* @__PURE__ */ new Map();
|
|
71
|
+
let committed = false;
|
|
72
|
+
const myGeneration = generation;
|
|
73
|
+
const stale = () => {
|
|
74
|
+
if (myGeneration === generation) return false;
|
|
75
|
+
if (DEV) devWarn(`plugin: "${p.name}" registered after the registry was reset; the registration was ignored.`);
|
|
76
|
+
return true;
|
|
77
|
+
};
|
|
78
|
+
const target = () => stale() ? null : committed ? hooks : staged;
|
|
79
|
+
const ctx = {
|
|
80
|
+
onInit: (cb) => void target()?.init.push(cb),
|
|
81
|
+
onMount: (cb) => void target()?.mount.push(cb),
|
|
82
|
+
onUnmount: (cb) => void target()?.unmount.push(cb),
|
|
83
|
+
onError: (cb) => void target()?.error.push(cb),
|
|
84
|
+
provide: (key, value) => {
|
|
85
|
+
if (stale()) return;
|
|
86
|
+
(committed ? provided : stagedProvided).set(key, value);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const commit = () => {
|
|
90
|
+
if (myGeneration !== generation) return false;
|
|
91
|
+
hooks.init.push(...staged.init);
|
|
92
|
+
hooks.mount.push(...staged.mount);
|
|
93
|
+
hooks.unmount.push(...staged.unmount);
|
|
94
|
+
hooks.error.push(...staged.error);
|
|
95
|
+
for (const [key, value] of stagedProvided) provided.set(key, value);
|
|
96
|
+
installedPlugins.add(p.name);
|
|
97
|
+
committed = true;
|
|
98
|
+
if (pendingInstalls.get(p.name) === myGeneration) pendingInstalls.delete(p.name);
|
|
99
|
+
for (const cb of staged.init.slice()) {
|
|
100
|
+
try {
|
|
101
|
+
cb();
|
|
102
|
+
} catch (e) {
|
|
103
|
+
console.error(`[Plugin] "${p.name}" init error:`, e);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return true;
|
|
107
|
+
};
|
|
108
|
+
installStack.add(p.name);
|
|
109
|
+
let pending;
|
|
110
|
+
try {
|
|
111
|
+
pending = adoptThenable(p.install(ctx, options));
|
|
112
|
+
} finally {
|
|
113
|
+
installStack.delete(p.name);
|
|
114
|
+
}
|
|
115
|
+
if (!pending) {
|
|
116
|
+
if (!commit()) throw new PluginInstallCancelledError(p.name);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (myGeneration === generation) pendingInstalls.set(p.name, myGeneration);
|
|
120
|
+
const settled = pending.then(
|
|
121
|
+
() => {
|
|
122
|
+
if (commit()) return;
|
|
123
|
+
if (pendingInstalls.get(p.name) === myGeneration) pendingInstalls.delete(p.name);
|
|
124
|
+
throw new PluginInstallCancelledError(p.name);
|
|
125
|
+
},
|
|
126
|
+
(err) => {
|
|
127
|
+
if (pendingInstalls.get(p.name) === myGeneration) pendingInstalls.delete(p.name);
|
|
128
|
+
reportError(err, { phase: "async", name: `plugin(${p.name})` });
|
|
129
|
+
throw err;
|
|
130
|
+
}
|
|
131
|
+
);
|
|
132
|
+
settled.catch(() => {
|
|
133
|
+
});
|
|
134
|
+
return settled;
|
|
135
|
+
},
|
|
136
|
+
inject(key, defaultValue) {
|
|
137
|
+
if (provided.has(key)) return provided.get(key);
|
|
138
|
+
if (defaultValue !== void 0) return defaultValue;
|
|
139
|
+
throw new Error(`[Plugin] No provider found for key "${key}"`);
|
|
140
|
+
},
|
|
141
|
+
triggerMount(element) {
|
|
142
|
+
const snapshot = hooks.mount.slice();
|
|
143
|
+
for (const hook of snapshot) {
|
|
144
|
+
try {
|
|
145
|
+
hook(element);
|
|
146
|
+
} catch (e) {
|
|
147
|
+
console.error("[Plugin] Mount hook error:", e);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
triggerUnmount(element) {
|
|
152
|
+
const snapshot = hooks.unmount.slice();
|
|
153
|
+
for (const hook of snapshot) {
|
|
154
|
+
try {
|
|
155
|
+
hook(element);
|
|
156
|
+
} catch (e) {
|
|
157
|
+
console.error("[Plugin] Unmount hook error:", e);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
triggerError(error) {
|
|
162
|
+
const snapshot = hooks.error.slice();
|
|
163
|
+
for (const hook of snapshot) {
|
|
164
|
+
try {
|
|
165
|
+
hook(error);
|
|
166
|
+
} catch (e) {
|
|
167
|
+
console.error("[Plugin] Error hook error:", e);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
reset() {
|
|
172
|
+
generation++;
|
|
173
|
+
pendingInstalls.clear();
|
|
174
|
+
installedPlugins.clear();
|
|
175
|
+
hooks.init.length = 0;
|
|
176
|
+
hooks.mount.length = 0;
|
|
177
|
+
hooks.unmount.length = 0;
|
|
178
|
+
hooks.error.length = 0;
|
|
179
|
+
provided.clear();
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
return registry;
|
|
183
|
+
}
|
|
184
|
+
var _defaults = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.plugins.defaultRegistry.v1"), () => ({
|
|
185
|
+
registry: createPluginRegistry(),
|
|
186
|
+
touched: false
|
|
187
|
+
}));
|
|
188
|
+
function createPlugin(name, install) {
|
|
189
|
+
return { name, install };
|
|
190
|
+
}
|
|
191
|
+
function plugin(plugin2, options) {
|
|
192
|
+
_defaults.touched = true;
|
|
193
|
+
return _defaults.registry.plugin(plugin2, options);
|
|
194
|
+
}
|
|
195
|
+
function inject(key, defaultValue) {
|
|
196
|
+
return _defaults.registry.inject(key, defaultValue);
|
|
197
|
+
}
|
|
198
|
+
function triggerPluginMount(element) {
|
|
199
|
+
_defaults.registry.triggerMount(element);
|
|
200
|
+
}
|
|
201
|
+
function triggerPluginUnmount(element) {
|
|
202
|
+
_defaults.registry.triggerUnmount(element);
|
|
203
|
+
}
|
|
204
|
+
function triggerPluginError(error) {
|
|
205
|
+
_defaults.registry.triggerError(error);
|
|
206
|
+
}
|
|
207
|
+
function resetPlugins() {
|
|
208
|
+
_defaults.registry.reset();
|
|
209
|
+
_defaults.touched = false;
|
|
210
|
+
}
|
|
211
|
+
function setDefaultPluginRegistry(registry) {
|
|
212
|
+
if (_defaults.touched && _defaults.registry.installedPlugins.size > 0) {
|
|
213
|
+
console.warn(
|
|
214
|
+
"[Plugin] Replacing default plugin registry while plugins are already installed on the singleton. This may indicate mixed singleton/registry usage."
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
_defaults.registry = registry;
|
|
218
|
+
_defaults.touched = true;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export {
|
|
222
|
+
PluginInstallCancelledError,
|
|
223
|
+
isPluginInstallCancelledError,
|
|
224
|
+
createPluginRegistry,
|
|
225
|
+
createPlugin,
|
|
226
|
+
plugin,
|
|
227
|
+
inject,
|
|
228
|
+
triggerPluginMount,
|
|
229
|
+
triggerPluginUnmount,
|
|
230
|
+
triggerPluginError,
|
|
231
|
+
resetPlugins,
|
|
232
|
+
setDefaultPluginRegistry
|
|
233
|
+
};
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
3
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
4
|
+
}) : x)(function(x) {
|
|
5
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
6
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
7
|
+
});
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
// src/core/dev.ts
|
|
14
|
+
var DEV = typeof __SIBU_DEV__ !== "undefined" ? !!__SIBU_DEV__ : typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
|
|
15
|
+
// safe default: off in browser, on in test/dev Node
|
|
16
|
+
typeof process !== "undefined" && process.env?.NODE_ENV !== "production"
|
|
17
|
+
);
|
|
18
|
+
function isDev() {
|
|
19
|
+
if (typeof globalThis.__SIBU_DEV__ !== "undefined") return !!globalThis.__SIBU_DEV__;
|
|
20
|
+
if (typeof __SIBU_DEV__ !== "undefined") return !!__SIBU_DEV__;
|
|
21
|
+
return typeof process !== "undefined" && process.env?.NODE_ENV !== "production";
|
|
22
|
+
}
|
|
23
|
+
function devAssert(condition, message) {
|
|
24
|
+
if ((typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) && !condition) {
|
|
25
|
+
throw new Error(`[SibuJS] ${message}`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function devWarnLazy(build) {
|
|
29
|
+
if (typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) {
|
|
30
|
+
const message = build();
|
|
31
|
+
if (message) console.warn(`[SibuJS] ${message}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function devWarn(message) {
|
|
35
|
+
if (typeof __SIBU_DEV__ !== "undefined" ? __SIBU_DEV__ : DEV) {
|
|
36
|
+
console.warn(`[SibuJS] ${message}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/core/errors.ts
|
|
41
|
+
var ERROR_STATE_KEY = /* @__PURE__ */ Symbol.for("sibujs.runtime-errors.v1");
|
|
42
|
+
function state() {
|
|
43
|
+
const g = globalThis;
|
|
44
|
+
const existing = g[ERROR_STATE_KEY];
|
|
45
|
+
if (existing) return existing;
|
|
46
|
+
const created = { handler: null, handlerDepth: 0 };
|
|
47
|
+
g[ERROR_STATE_KEY] = created;
|
|
48
|
+
return created;
|
|
49
|
+
}
|
|
50
|
+
function setRuntimeErrorHandler(handler) {
|
|
51
|
+
const s = state();
|
|
52
|
+
const prev = s.handler;
|
|
53
|
+
s.handler = handler;
|
|
54
|
+
return prev;
|
|
55
|
+
}
|
|
56
|
+
function getRuntimeErrorHandler() {
|
|
57
|
+
return state().handler;
|
|
58
|
+
}
|
|
59
|
+
function normalizeError(value) {
|
|
60
|
+
if (value instanceof Error) return value;
|
|
61
|
+
const message = typeof value === "string" ? value : `Non-Error value thrown: ${safeStringify(value)}`;
|
|
62
|
+
return new Error(message, { cause: value });
|
|
63
|
+
}
|
|
64
|
+
function safeStringify(value) {
|
|
65
|
+
if (typeof value === "symbol") return value.toString();
|
|
66
|
+
try {
|
|
67
|
+
return typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
68
|
+
} catch {
|
|
69
|
+
return Object.prototype.toString.call(value);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function describe(context) {
|
|
73
|
+
return context.name ? `${context.phase} "${context.name}"` : context.phase;
|
|
74
|
+
}
|
|
75
|
+
var REACTIVE_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
76
|
+
function untrackedRun(fn) {
|
|
77
|
+
const api = globalThis[REACTIVE_REGISTRY_KEY];
|
|
78
|
+
return api?.untracked ? api.untracked(fn) : fn();
|
|
79
|
+
}
|
|
80
|
+
var PROPAGATE_EVENT = "sibu:error-propagate";
|
|
81
|
+
function claimedByBoundary(error, context) {
|
|
82
|
+
const raw = context.node;
|
|
83
|
+
if (!raw || typeof CustomEvent === "undefined") return false;
|
|
84
|
+
const target = resolveEventTarget(raw);
|
|
85
|
+
if (!target) return false;
|
|
86
|
+
try {
|
|
87
|
+
const event = new CustomEvent(PROPAGATE_EVENT, {
|
|
88
|
+
bubbles: true,
|
|
89
|
+
cancelable: true,
|
|
90
|
+
detail: { error, context }
|
|
91
|
+
});
|
|
92
|
+
return target.dispatchEvent(event) === false;
|
|
93
|
+
} catch {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function resolveEventTarget(node) {
|
|
98
|
+
const ELEMENT_NODE = 1;
|
|
99
|
+
let current = node;
|
|
100
|
+
while (current) {
|
|
101
|
+
if (current.nodeType === ELEMENT_NODE && typeof current.dispatchEvent === "function") {
|
|
102
|
+
return current;
|
|
103
|
+
}
|
|
104
|
+
current = current.parentNode;
|
|
105
|
+
}
|
|
106
|
+
const self = node;
|
|
107
|
+
return typeof self.dispatchEvent === "function" ? self : null;
|
|
108
|
+
}
|
|
109
|
+
function defaultReport(error, context) {
|
|
110
|
+
if (typeof console === "undefined") return;
|
|
111
|
+
console.error(`[SibuJS] Uncaught error during ${describe(context)}: ${error.message}`, error);
|
|
112
|
+
}
|
|
113
|
+
function reportError(error, context) {
|
|
114
|
+
const err = normalizeError(error);
|
|
115
|
+
untrackedRun(() => {
|
|
116
|
+
if (claimedByBoundary(err, context)) return;
|
|
117
|
+
const s = state();
|
|
118
|
+
const handler = s.handler;
|
|
119
|
+
if (handler && s.handlerDepth === 0) {
|
|
120
|
+
s.handlerDepth++;
|
|
121
|
+
try {
|
|
122
|
+
handler(error instanceof Error ? error : err, context);
|
|
123
|
+
return;
|
|
124
|
+
} catch (handlerError) {
|
|
125
|
+
if (typeof console !== "undefined") {
|
|
126
|
+
const detail = handlerError instanceof Error ? handlerError.message : String(handlerError);
|
|
127
|
+
console.error(`[SibuJS] runtime error handler itself threw: ${detail}`, handlerError);
|
|
128
|
+
}
|
|
129
|
+
} finally {
|
|
130
|
+
s.handlerDepth--;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
defaultReport(err, context);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// src/core/rendering/dispose.ts
|
|
138
|
+
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
139
|
+
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
140
|
+
function reportDrainRunaway(label, executed, remaining) {
|
|
141
|
+
if (typeof console === "undefined") return;
|
|
142
|
+
console.error(
|
|
143
|
+
`[SibuJS ${label}] runaway cleanup: stopped after running ${executed} teardowns with ${remaining} still queued. Cleanup production did not stabilize before the teardown safety ceiling was reached \u2014 the remaining work was NOT run.`,
|
|
144
|
+
{ executed, remaining }
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
var activeBindingCount = 0;
|
|
148
|
+
function resolveCapture(capture) {
|
|
149
|
+
let frame = capture;
|
|
150
|
+
while (frame?.closed) frame = frame.forwardTo;
|
|
151
|
+
return frame ?? null;
|
|
152
|
+
}
|
|
153
|
+
var registrationCaptures = [];
|
|
154
|
+
function currentDisposerCapture() {
|
|
155
|
+
return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
156
|
+
}
|
|
157
|
+
function beginDisposerCapture(capture) {
|
|
158
|
+
if (capture === null && registrationCaptures.length === 0) return false;
|
|
159
|
+
registrationCaptures.push(resolveCapture(capture));
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
function endDisposerCapture() {
|
|
163
|
+
registrationCaptures.pop();
|
|
164
|
+
}
|
|
165
|
+
function registerDisposer(node, teardown) {
|
|
166
|
+
let disposers = elementDisposers.get(node);
|
|
167
|
+
if (!disposers) {
|
|
168
|
+
disposers = [];
|
|
169
|
+
elementDisposers.set(node, disposers);
|
|
170
|
+
}
|
|
171
|
+
disposers.push(teardown);
|
|
172
|
+
if (DEV) activeBindingCount++;
|
|
173
|
+
const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
174
|
+
if (capture) capture.entries.push([node, teardown]);
|
|
175
|
+
}
|
|
176
|
+
function withDisposerRollback(build) {
|
|
177
|
+
const frame = { entries: [], closed: false };
|
|
178
|
+
const captured = frame.entries;
|
|
179
|
+
registrationCaptures.push(frame);
|
|
180
|
+
let result;
|
|
181
|
+
try {
|
|
182
|
+
result = build();
|
|
183
|
+
} catch (err) {
|
|
184
|
+
let executed = 0;
|
|
185
|
+
try {
|
|
186
|
+
while (captured.length > 0) {
|
|
187
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
188
|
+
reportDrainRunaway("rollback", executed, captured.length);
|
|
189
|
+
break;
|
|
190
|
+
}
|
|
191
|
+
const [node, teardown] = captured.pop();
|
|
192
|
+
if (!unregisterDisposer(node, teardown)) continue;
|
|
193
|
+
executed++;
|
|
194
|
+
try {
|
|
195
|
+
teardown();
|
|
196
|
+
} catch (cleanupErr) {
|
|
197
|
+
reportError(cleanupErr, { phase: "cleanup", name: "disposer" });
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
} finally {
|
|
201
|
+
frame.closed = true;
|
|
202
|
+
captured.length = 0;
|
|
203
|
+
registrationCaptures.pop();
|
|
204
|
+
}
|
|
205
|
+
throw err;
|
|
206
|
+
}
|
|
207
|
+
frame.closed = true;
|
|
208
|
+
registrationCaptures.pop();
|
|
209
|
+
const parent = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
210
|
+
if (parent) {
|
|
211
|
+
for (const entry of captured) {
|
|
212
|
+
if (elementDisposers.get(entry[0])?.includes(entry[1])) parent.entries.push(entry);
|
|
213
|
+
}
|
|
214
|
+
frame.forwardTo = parent;
|
|
215
|
+
}
|
|
216
|
+
captured.length = 0;
|
|
217
|
+
return result;
|
|
218
|
+
}
|
|
219
|
+
function unregisterDisposer(node, teardown) {
|
|
220
|
+
const disposers = elementDisposers.get(node);
|
|
221
|
+
if (!disposers) return false;
|
|
222
|
+
const index = disposers.indexOf(teardown);
|
|
223
|
+
if (index === -1) return false;
|
|
224
|
+
disposers.splice(index, 1);
|
|
225
|
+
if (DEV) activeBindingCount--;
|
|
226
|
+
if (disposers.length === 0) elementDisposers.delete(node);
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
function dispose(node) {
|
|
230
|
+
const stack = [node];
|
|
231
|
+
const order = [];
|
|
232
|
+
while (stack.length > 0) {
|
|
233
|
+
const current = stack.pop();
|
|
234
|
+
order.push(current);
|
|
235
|
+
const children = Array.from(current.childNodes);
|
|
236
|
+
for (let i = 0; i < children.length; i++) {
|
|
237
|
+
stack.push(children[i]);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
241
|
+
disposeNodeOwn(order[i]);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function disposeNodeOwn(node) {
|
|
245
|
+
if (!elementDisposers.has(node)) return;
|
|
246
|
+
let executed = 0;
|
|
247
|
+
let runaway = false;
|
|
248
|
+
while (!runaway) {
|
|
249
|
+
const pending = elementDisposers.get(node);
|
|
250
|
+
if (!pending || pending.length === 0) break;
|
|
251
|
+
const snapshot = pending.slice();
|
|
252
|
+
elementDisposers.delete(node);
|
|
253
|
+
if (DEV) activeBindingCount -= snapshot.length;
|
|
254
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
255
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
256
|
+
const rest = snapshot.slice(i);
|
|
257
|
+
const added = elementDisposers.get(node);
|
|
258
|
+
elementDisposers.set(node, added ? rest.concat(added) : rest);
|
|
259
|
+
if (DEV) activeBindingCount += rest.length;
|
|
260
|
+
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
261
|
+
runaway = true;
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
executed++;
|
|
265
|
+
try {
|
|
266
|
+
snapshot[i]();
|
|
267
|
+
} catch (err) {
|
|
268
|
+
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function replaceChildrenSafely(parent, ...next) {
|
|
274
|
+
for (let i = 0; i < next.length; i++) {
|
|
275
|
+
const node = next[i];
|
|
276
|
+
node.parentNode?.removeChild(node);
|
|
277
|
+
}
|
|
278
|
+
const current = Array.from(parent.childNodes);
|
|
279
|
+
for (let i = 0; i < current.length; i++) {
|
|
280
|
+
dispose(current[i]);
|
|
281
|
+
}
|
|
282
|
+
parent.replaceChildren(...next);
|
|
283
|
+
}
|
|
284
|
+
function checkLeaks(warnThreshold = 0) {
|
|
285
|
+
if (!DEV) return 0;
|
|
286
|
+
if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
|
|
287
|
+
devWarn(
|
|
288
|
+
`checkLeaks: ${activeBindingCount} active DOM bindings detected. Expected \u2264${warnThreshold}. This may indicate a component was removed from the DOM without calling dispose().`
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
return activeBindingCount;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
export {
|
|
295
|
+
__require,
|
|
296
|
+
__export,
|
|
297
|
+
DEV,
|
|
298
|
+
isDev,
|
|
299
|
+
devAssert,
|
|
300
|
+
devWarnLazy,
|
|
301
|
+
devWarn,
|
|
302
|
+
setRuntimeErrorHandler,
|
|
303
|
+
getRuntimeErrorHandler,
|
|
304
|
+
normalizeError,
|
|
305
|
+
reportError,
|
|
306
|
+
MAX_DRAIN_TEARDOWNS,
|
|
307
|
+
reportDrainRunaway,
|
|
308
|
+
currentDisposerCapture,
|
|
309
|
+
beginDisposerCapture,
|
|
310
|
+
endDisposerCapture,
|
|
311
|
+
registerDisposer,
|
|
312
|
+
withDisposerRollback,
|
|
313
|
+
unregisterDisposer,
|
|
314
|
+
dispose,
|
|
315
|
+
disposeNodeOwn,
|
|
316
|
+
replaceChildrenSafely,
|
|
317
|
+
checkLeaks
|
|
318
|
+
};
|