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
package/dist/performance.cjs
CHANGED
|
@@ -58,6 +58,94 @@ __export(performance_exports, {
|
|
|
58
58
|
});
|
|
59
59
|
module.exports = __toCommonJS(performance_exports);
|
|
60
60
|
|
|
61
|
+
// src/core/errors.ts
|
|
62
|
+
var ERROR_STATE_KEY = /* @__PURE__ */ Symbol.for("sibujs.runtime-errors.v1");
|
|
63
|
+
function state() {
|
|
64
|
+
const g = globalThis;
|
|
65
|
+
const existing = g[ERROR_STATE_KEY];
|
|
66
|
+
if (existing) return existing;
|
|
67
|
+
const created = { handler: null, handlerDepth: 0 };
|
|
68
|
+
g[ERROR_STATE_KEY] = created;
|
|
69
|
+
return created;
|
|
70
|
+
}
|
|
71
|
+
function normalizeError(value) {
|
|
72
|
+
if (value instanceof Error) return value;
|
|
73
|
+
const message = typeof value === "string" ? value : `Non-Error value thrown: ${safeStringify(value)}`;
|
|
74
|
+
return new Error(message, { cause: value });
|
|
75
|
+
}
|
|
76
|
+
function safeStringify(value) {
|
|
77
|
+
if (typeof value === "symbol") return value.toString();
|
|
78
|
+
try {
|
|
79
|
+
return typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
80
|
+
} catch {
|
|
81
|
+
return Object.prototype.toString.call(value);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
function describe(context) {
|
|
85
|
+
return context.name ? `${context.phase} "${context.name}"` : context.phase;
|
|
86
|
+
}
|
|
87
|
+
var REACTIVE_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
88
|
+
function untrackedRun(fn) {
|
|
89
|
+
const api = globalThis[REACTIVE_REGISTRY_KEY];
|
|
90
|
+
return api?.untracked ? api.untracked(fn) : fn();
|
|
91
|
+
}
|
|
92
|
+
var PROPAGATE_EVENT = "sibu:error-propagate";
|
|
93
|
+
function claimedByBoundary(error, context) {
|
|
94
|
+
const raw = context.node;
|
|
95
|
+
if (!raw || typeof CustomEvent === "undefined") return false;
|
|
96
|
+
const target = resolveEventTarget(raw);
|
|
97
|
+
if (!target) return false;
|
|
98
|
+
try {
|
|
99
|
+
const event = new CustomEvent(PROPAGATE_EVENT, {
|
|
100
|
+
bubbles: true,
|
|
101
|
+
cancelable: true,
|
|
102
|
+
detail: { error, context }
|
|
103
|
+
});
|
|
104
|
+
return target.dispatchEvent(event) === false;
|
|
105
|
+
} catch {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function resolveEventTarget(node) {
|
|
110
|
+
const ELEMENT_NODE = 1;
|
|
111
|
+
let current = node;
|
|
112
|
+
while (current) {
|
|
113
|
+
if (current.nodeType === ELEMENT_NODE && typeof current.dispatchEvent === "function") {
|
|
114
|
+
return current;
|
|
115
|
+
}
|
|
116
|
+
current = current.parentNode;
|
|
117
|
+
}
|
|
118
|
+
const self = node;
|
|
119
|
+
return typeof self.dispatchEvent === "function" ? self : null;
|
|
120
|
+
}
|
|
121
|
+
function defaultReport(error, context) {
|
|
122
|
+
if (typeof console === "undefined") return;
|
|
123
|
+
console.error(`[SibuJS] Uncaught error during ${describe(context)}: ${error.message}`, error);
|
|
124
|
+
}
|
|
125
|
+
function reportError(error, context) {
|
|
126
|
+
const err = normalizeError(error);
|
|
127
|
+
untrackedRun(() => {
|
|
128
|
+
if (claimedByBoundary(err, context)) return;
|
|
129
|
+
const s = state();
|
|
130
|
+
const handler = s.handler;
|
|
131
|
+
if (handler && s.handlerDepth === 0) {
|
|
132
|
+
s.handlerDepth++;
|
|
133
|
+
try {
|
|
134
|
+
handler(error instanceof Error ? error : err, context);
|
|
135
|
+
return;
|
|
136
|
+
} catch (handlerError) {
|
|
137
|
+
if (typeof console !== "undefined") {
|
|
138
|
+
const detail = handlerError instanceof Error ? handlerError.message : String(handlerError);
|
|
139
|
+
console.error(`[SibuJS] runtime error handler itself threw: ${detail}`, handlerError);
|
|
140
|
+
}
|
|
141
|
+
} finally {
|
|
142
|
+
s.handlerDepth--;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
defaultReport(err, context);
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
|
|
61
149
|
// src/utils/globalSingleton.ts
|
|
62
150
|
function globalSingleton(key, create) {
|
|
63
151
|
const g = globalThis;
|
|
@@ -88,28 +176,34 @@ function insertTask(task) {
|
|
|
88
176
|
}
|
|
89
177
|
taskQueue.splice(i, 0, task);
|
|
90
178
|
}
|
|
179
|
+
function runTask(callback) {
|
|
180
|
+
try {
|
|
181
|
+
callback();
|
|
182
|
+
} catch (err) {
|
|
183
|
+
reportError(err, { phase: "scheduler", name: "scheduleUpdate" });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
91
186
|
function processQueue() {
|
|
92
187
|
if (_sched.isProcessing || taskQueue.length === 0) return;
|
|
93
188
|
_sched.isProcessing = true;
|
|
94
189
|
const startTime = performance.now();
|
|
95
190
|
const timeSlice = 5;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
191
|
+
try {
|
|
192
|
+
while (taskQueue.length > 0) {
|
|
193
|
+
const task = taskQueue[0];
|
|
194
|
+
if (task.cancelled) {
|
|
195
|
+
taskQueue.shift();
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (task.priority > Priority.IMMEDIATE && performance.now() - startTime > timeSlice) {
|
|
199
|
+
break;
|
|
200
|
+
}
|
|
99
201
|
taskQueue.shift();
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
if (task.priority > Priority.IMMEDIATE && performance.now() - startTime > timeSlice) {
|
|
103
|
-
break;
|
|
104
|
-
}
|
|
105
|
-
taskQueue.shift();
|
|
106
|
-
try {
|
|
107
|
-
task.callback();
|
|
108
|
-
} catch (e) {
|
|
109
|
-
console.error("[Scheduler] Task error:", e);
|
|
202
|
+
runTask(task.callback);
|
|
110
203
|
}
|
|
204
|
+
} finally {
|
|
205
|
+
_sched.isProcessing = false;
|
|
111
206
|
}
|
|
112
|
-
_sched.isProcessing = false;
|
|
113
207
|
if (taskQueue.length > 0) {
|
|
114
208
|
scheduleFrame();
|
|
115
209
|
}
|
|
@@ -177,11 +271,7 @@ function scheduleUpdate(priority, callback) {
|
|
|
177
271
|
cancelled: false
|
|
178
272
|
};
|
|
179
273
|
if (priority === Priority.IMMEDIATE) {
|
|
180
|
-
|
|
181
|
-
callback();
|
|
182
|
-
} catch (e) {
|
|
183
|
-
console.error("[Scheduler] Immediate task error:", e);
|
|
184
|
-
}
|
|
274
|
+
runTask(callback);
|
|
185
275
|
return () => {
|
|
186
276
|
};
|
|
187
277
|
}
|
|
@@ -201,14 +291,15 @@ function flushScheduler() {
|
|
|
201
291
|
_sched.scheduledHandle = null;
|
|
202
292
|
_sched.scheduledKind = null;
|
|
203
293
|
_sched.microtaskScheduled = false;
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
task.callback
|
|
294
|
+
try {
|
|
295
|
+
while (taskQueue.length > 0) {
|
|
296
|
+
const task = taskQueue.shift();
|
|
297
|
+
if (!task) break;
|
|
298
|
+
if (!task.cancelled) runTask(task.callback);
|
|
209
299
|
}
|
|
300
|
+
} finally {
|
|
301
|
+
_sched.isProcessing = false;
|
|
210
302
|
}
|
|
211
|
-
_sched.isProcessing = false;
|
|
212
303
|
}
|
|
213
304
|
function pendingTasks() {
|
|
214
305
|
return taskQueue.filter((t) => !t.cancelled).length;
|
|
@@ -246,92 +337,99 @@ function devWarn(message) {
|
|
|
246
337
|
}
|
|
247
338
|
}
|
|
248
339
|
|
|
249
|
-
// src/core/
|
|
250
|
-
var
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
function normalizeError(value) {
|
|
260
|
-
if (value instanceof Error) return value;
|
|
261
|
-
const message = typeof value === "string" ? value : `Non-Error value thrown: ${safeStringify(value)}`;
|
|
262
|
-
return new Error(message, { cause: value });
|
|
263
|
-
}
|
|
264
|
-
function safeStringify(value) {
|
|
265
|
-
if (typeof value === "symbol") return value.toString();
|
|
266
|
-
try {
|
|
267
|
-
return typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
268
|
-
} catch {
|
|
269
|
-
return Object.prototype.toString.call(value);
|
|
270
|
-
}
|
|
340
|
+
// src/core/rendering/dispose.ts
|
|
341
|
+
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
342
|
+
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
343
|
+
function reportDrainRunaway(label, executed, remaining) {
|
|
344
|
+
if (typeof console === "undefined") return;
|
|
345
|
+
console.error(
|
|
346
|
+
`[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.`,
|
|
347
|
+
{ executed, remaining }
|
|
348
|
+
);
|
|
271
349
|
}
|
|
272
|
-
|
|
273
|
-
|
|
350
|
+
var activeBindingCount = 0;
|
|
351
|
+
function resolveCapture(capture) {
|
|
352
|
+
let frame = capture;
|
|
353
|
+
while (frame?.closed) frame = frame.forwardTo;
|
|
354
|
+
return frame ?? null;
|
|
355
|
+
}
|
|
356
|
+
var registrationCaptures = [];
|
|
357
|
+
function currentDisposerCapture() {
|
|
358
|
+
return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
359
|
+
}
|
|
360
|
+
function beginDisposerCapture(capture) {
|
|
361
|
+
if (capture === null && registrationCaptures.length === 0) return false;
|
|
362
|
+
registrationCaptures.push(resolveCapture(capture));
|
|
363
|
+
return true;
|
|
274
364
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
const api = globalThis[REACTIVE_REGISTRY_KEY];
|
|
278
|
-
return api?.untracked ? api.untracked(fn) : fn();
|
|
365
|
+
function endDisposerCapture() {
|
|
366
|
+
registrationCaptures.pop();
|
|
279
367
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (!target) return false;
|
|
286
|
-
try {
|
|
287
|
-
const event = new CustomEvent(PROPAGATE_EVENT, {
|
|
288
|
-
bubbles: true,
|
|
289
|
-
cancelable: true,
|
|
290
|
-
detail: { error, context }
|
|
291
|
-
});
|
|
292
|
-
return target.dispatchEvent(event) === false;
|
|
293
|
-
} catch {
|
|
294
|
-
return false;
|
|
368
|
+
function registerDisposer(node, teardown) {
|
|
369
|
+
let disposers = elementDisposers.get(node);
|
|
370
|
+
if (!disposers) {
|
|
371
|
+
disposers = [];
|
|
372
|
+
elementDisposers.set(node, disposers);
|
|
295
373
|
}
|
|
374
|
+
disposers.push(teardown);
|
|
375
|
+
if (DEV) activeBindingCount++;
|
|
376
|
+
const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
|
|
377
|
+
if (capture) capture.entries.push([node, teardown]);
|
|
296
378
|
}
|
|
297
|
-
function
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
while (
|
|
301
|
-
|
|
302
|
-
|
|
379
|
+
function dispose(node) {
|
|
380
|
+
const stack = [node];
|
|
381
|
+
const order = [];
|
|
382
|
+
while (stack.length > 0) {
|
|
383
|
+
const current = stack.pop();
|
|
384
|
+
order.push(current);
|
|
385
|
+
const children = Array.from(current.childNodes);
|
|
386
|
+
for (let i = 0; i < children.length; i++) {
|
|
387
|
+
stack.push(children[i]);
|
|
303
388
|
}
|
|
304
|
-
current = current.parentNode;
|
|
305
389
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
if (
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
if (
|
|
320
|
-
|
|
390
|
+
for (let i = order.length - 1; i >= 0; i--) {
|
|
391
|
+
disposeNodeOwn(order[i]);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
function disposeNodeOwn(node) {
|
|
395
|
+
if (!elementDisposers.has(node)) return;
|
|
396
|
+
let executed = 0;
|
|
397
|
+
let runaway = false;
|
|
398
|
+
while (!runaway) {
|
|
399
|
+
const pending = elementDisposers.get(node);
|
|
400
|
+
if (!pending || pending.length === 0) break;
|
|
401
|
+
const snapshot = pending.slice();
|
|
402
|
+
elementDisposers.delete(node);
|
|
403
|
+
if (DEV) activeBindingCount -= snapshot.length;
|
|
404
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
405
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
406
|
+
const rest = snapshot.slice(i);
|
|
407
|
+
const added = elementDisposers.get(node);
|
|
408
|
+
elementDisposers.set(node, added ? rest.concat(added) : rest);
|
|
409
|
+
if (DEV) activeBindingCount += rest.length;
|
|
410
|
+
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
411
|
+
runaway = true;
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
executed++;
|
|
321
415
|
try {
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
if (typeof console !== "undefined") {
|
|
326
|
-
const detail = handlerError instanceof Error ? handlerError.message : String(handlerError);
|
|
327
|
-
console.error(`[SibuJS] runtime error handler itself threw: ${detail}`, handlerError);
|
|
328
|
-
}
|
|
329
|
-
} finally {
|
|
330
|
-
s.handlerDepth--;
|
|
416
|
+
snapshot[i]();
|
|
417
|
+
} catch (err) {
|
|
418
|
+
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
331
419
|
}
|
|
332
420
|
}
|
|
333
|
-
|
|
334
|
-
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
function replaceChildrenSafely(parent, ...next) {
|
|
424
|
+
for (let i = 0; i < next.length; i++) {
|
|
425
|
+
const node = next[i];
|
|
426
|
+
node.parentNode?.removeChild(node);
|
|
427
|
+
}
|
|
428
|
+
const current = Array.from(parent.childNodes);
|
|
429
|
+
for (let i = 0; i < current.length; i++) {
|
|
430
|
+
dispose(current[i]);
|
|
431
|
+
}
|
|
432
|
+
parent.replaceChildren(...next);
|
|
335
433
|
}
|
|
336
434
|
|
|
337
435
|
// src/reactivity/track-core.ts
|
|
@@ -481,8 +579,18 @@ function untracked(fn) {
|
|
|
481
579
|
var subscriberEpochCounter = 0;
|
|
482
580
|
function retrack(effectFn, subscriber) {
|
|
483
581
|
const prev = currentSubscriber;
|
|
582
|
+
let savedDepth = 0;
|
|
583
|
+
let savedSuspendSub = null;
|
|
584
|
+
if (trackingSuspended) {
|
|
585
|
+
savedDepth = suspendDepth;
|
|
586
|
+
savedSuspendSub = suspendSavedSub;
|
|
587
|
+
suspendDepth = 0;
|
|
588
|
+
suspendSavedSub = null;
|
|
589
|
+
trackingSuspended = false;
|
|
590
|
+
}
|
|
484
591
|
currentSubscriber = subscriber;
|
|
485
592
|
const sub = subscriber;
|
|
593
|
+
if (sub._cap === void 0) sub._cap = currentDisposerCapture();
|
|
486
594
|
const epoch = ++subscriberEpochCounter;
|
|
487
595
|
sub._epoch = epoch;
|
|
488
596
|
sub._structDirty = false;
|
|
@@ -495,6 +603,11 @@ function retrack(effectFn, subscriber) {
|
|
|
495
603
|
effectFn();
|
|
496
604
|
} finally {
|
|
497
605
|
currentSubscriber = prev;
|
|
606
|
+
if (savedDepth !== 0) {
|
|
607
|
+
suspendDepth = savedDepth;
|
|
608
|
+
suspendSavedSub = savedSuspendSub;
|
|
609
|
+
trackingSuspended = true;
|
|
610
|
+
}
|
|
498
611
|
let node = sub.depsHead ?? null;
|
|
499
612
|
while (node !== null) {
|
|
500
613
|
const next = node.subNext;
|
|
@@ -514,11 +627,25 @@ function track(effectFn, subscriber) {
|
|
|
514
627
|
if (!subscriber) return reactiveBinding(effectFn);
|
|
515
628
|
cleanup(subscriber);
|
|
516
629
|
const prev = currentSubscriber;
|
|
630
|
+
let savedDepth = 0;
|
|
631
|
+
let savedSuspendSub = null;
|
|
632
|
+
if (trackingSuspended) {
|
|
633
|
+
savedDepth = suspendDepth;
|
|
634
|
+
savedSuspendSub = suspendSavedSub;
|
|
635
|
+
suspendDepth = 0;
|
|
636
|
+
suspendSavedSub = null;
|
|
637
|
+
trackingSuspended = false;
|
|
638
|
+
}
|
|
517
639
|
currentSubscriber = subscriber;
|
|
518
640
|
try {
|
|
519
641
|
effectFn();
|
|
520
642
|
} finally {
|
|
521
643
|
currentSubscriber = prev;
|
|
644
|
+
if (savedDepth !== 0) {
|
|
645
|
+
suspendDepth = savedDepth;
|
|
646
|
+
suspendSavedSub = savedSuspendSub;
|
|
647
|
+
trackingSuspended = true;
|
|
648
|
+
}
|
|
522
649
|
const sub2 = subscriber;
|
|
523
650
|
for (let n = sub2.depsHead ?? null; n !== null; n = n.subNext) {
|
|
524
651
|
const sig = n.sig;
|
|
@@ -655,7 +782,12 @@ function drainQueue() {
|
|
|
655
782
|
quarantined.add(sub);
|
|
656
783
|
continue;
|
|
657
784
|
}
|
|
658
|
-
|
|
785
|
+
const pushed = beginDisposerCapture(sub._cap ?? null);
|
|
786
|
+
try {
|
|
787
|
+
safeInvoke(sub);
|
|
788
|
+
} finally {
|
|
789
|
+
if (pushed) endDisposerCapture();
|
|
790
|
+
}
|
|
659
791
|
}
|
|
660
792
|
}
|
|
661
793
|
function drainNotificationQueue() {
|
|
@@ -689,8 +821,9 @@ function propagateDirty(sub) {
|
|
|
689
821
|
if (s._c) {
|
|
690
822
|
const nSig = s._sig;
|
|
691
823
|
if (nSig) {
|
|
692
|
-
if (!nSig._d) {
|
|
824
|
+
if (!nSig._d || nSig._f === true) {
|
|
693
825
|
nSig._d = true;
|
|
826
|
+
nSig._f = false;
|
|
694
827
|
stack.push(nSig);
|
|
695
828
|
}
|
|
696
829
|
} else {
|
|
@@ -790,7 +923,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
790
923
|
}
|
|
791
924
|
|
|
792
925
|
// src/reactivity/track.ts
|
|
793
|
-
var _runtimeVersion = true ? "4.
|
|
926
|
+
var _runtimeVersion = true ? "4.6.0" : "dev";
|
|
794
927
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
795
928
|
function resolveReactiveApi() {
|
|
796
929
|
const g = globalThis;
|
|
@@ -1171,72 +1304,6 @@ function uniqueId(suffix) {
|
|
|
1171
1304
|
return suffix ? `${id}-${suffix}` : id;
|
|
1172
1305
|
}
|
|
1173
1306
|
|
|
1174
|
-
// src/core/rendering/dispose.ts
|
|
1175
|
-
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
1176
|
-
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
1177
|
-
function reportDrainRunaway(label, executed, remaining) {
|
|
1178
|
-
if (typeof console === "undefined") return;
|
|
1179
|
-
console.error(
|
|
1180
|
-
`[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.`,
|
|
1181
|
-
{ executed, remaining }
|
|
1182
|
-
);
|
|
1183
|
-
}
|
|
1184
|
-
var activeBindingCount = 0;
|
|
1185
|
-
function dispose(node) {
|
|
1186
|
-
const stack = [node];
|
|
1187
|
-
const order = [];
|
|
1188
|
-
while (stack.length > 0) {
|
|
1189
|
-
const current = stack.pop();
|
|
1190
|
-
order.push(current);
|
|
1191
|
-
const children = Array.from(current.childNodes);
|
|
1192
|
-
for (let i = 0; i < children.length; i++) {
|
|
1193
|
-
stack.push(children[i]);
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
for (let i = order.length - 1; i >= 0; i--) {
|
|
1197
|
-
const current = order[i];
|
|
1198
|
-
if (elementDisposers.has(current)) {
|
|
1199
|
-
let executed = 0;
|
|
1200
|
-
let runaway = false;
|
|
1201
|
-
while (!runaway) {
|
|
1202
|
-
const pending = elementDisposers.get(current);
|
|
1203
|
-
if (!pending || pending.length === 0) break;
|
|
1204
|
-
const snapshot = pending.slice();
|
|
1205
|
-
elementDisposers.delete(current);
|
|
1206
|
-
if (DEV) activeBindingCount -= snapshot.length;
|
|
1207
|
-
for (let i2 = 0; i2 < snapshot.length; i2++) {
|
|
1208
|
-
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
1209
|
-
const rest = snapshot.slice(i2);
|
|
1210
|
-
const added = elementDisposers.get(current);
|
|
1211
|
-
elementDisposers.set(current, added ? rest.concat(added) : rest);
|
|
1212
|
-
if (DEV) activeBindingCount += rest.length;
|
|
1213
|
-
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
1214
|
-
runaway = true;
|
|
1215
|
-
break;
|
|
1216
|
-
}
|
|
1217
|
-
executed++;
|
|
1218
|
-
try {
|
|
1219
|
-
snapshot[i2]();
|
|
1220
|
-
} catch (err) {
|
|
1221
|
-
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
}
|
|
1228
|
-
function replaceChildrenSafely(parent, ...next) {
|
|
1229
|
-
for (let i = 0; i < next.length; i++) {
|
|
1230
|
-
const node = next[i];
|
|
1231
|
-
node.parentNode?.removeChild(node);
|
|
1232
|
-
}
|
|
1233
|
-
const current = Array.from(parent.childNodes);
|
|
1234
|
-
for (let i = 0; i < current.length; i++) {
|
|
1235
|
-
dispose(current[i]);
|
|
1236
|
-
}
|
|
1237
|
-
parent.replaceChildren(...next);
|
|
1238
|
-
}
|
|
1239
|
-
|
|
1240
1307
|
// src/utils/sanitize.ts
|
|
1241
1308
|
function stripControlChars(value) {
|
|
1242
1309
|
return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
|
|
@@ -1337,11 +1404,16 @@ function getDOMPool() {
|
|
|
1337
1404
|
return _defaultPool;
|
|
1338
1405
|
}
|
|
1339
1406
|
var preloadedResources = /* @__PURE__ */ new Set();
|
|
1407
|
+
function hintKey(rel, as, crossorigin, href) {
|
|
1408
|
+
return `${rel}\0${as}\0${crossorigin}\0${href}`;
|
|
1409
|
+
}
|
|
1340
1410
|
function preloadResource(url, type = "fetch") {
|
|
1341
1411
|
const safe = sanitizeUrl(url);
|
|
1342
1412
|
if (!safe) return;
|
|
1343
|
-
|
|
1344
|
-
|
|
1413
|
+
const as = type === "script" || type === "style" || type === "image" ? type : "fetch";
|
|
1414
|
+
const key = hintKey("preload", as, as === "fetch" ? "anonymous" : "", safe);
|
|
1415
|
+
if (preloadedResources.has(key)) return;
|
|
1416
|
+
preloadedResources.add(key);
|
|
1345
1417
|
const link = document.createElement("link");
|
|
1346
1418
|
link.rel = "preload";
|
|
1347
1419
|
link.href = safe;
|
|
@@ -1364,8 +1436,9 @@ function preloadResource(url, type = "fetch") {
|
|
|
1364
1436
|
function prefetch(url) {
|
|
1365
1437
|
const safe = sanitizeUrl(url);
|
|
1366
1438
|
if (!safe) return;
|
|
1367
|
-
|
|
1368
|
-
preloadedResources.
|
|
1439
|
+
const key = hintKey("prefetch", "", "", safe);
|
|
1440
|
+
if (preloadedResources.has(key)) return;
|
|
1441
|
+
preloadedResources.add(key);
|
|
1369
1442
|
const link = document.createElement("link");
|
|
1370
1443
|
link.rel = "prefetch";
|
|
1371
1444
|
link.href = safe;
|
|
@@ -1434,65 +1507,92 @@ function block(factory) {
|
|
|
1434
1507
|
}
|
|
1435
1508
|
|
|
1436
1509
|
// src/performance/normalize.ts
|
|
1510
|
+
function dict(source) {
|
|
1511
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
1512
|
+
if (source) {
|
|
1513
|
+
for (const key of Object.keys(source)) defineOwn(out, key, source[key]);
|
|
1514
|
+
}
|
|
1515
|
+
return out;
|
|
1516
|
+
}
|
|
1517
|
+
function ownGet(obj, key) {
|
|
1518
|
+
return obj !== void 0 && Object.hasOwn(obj, key) ? obj[key] : void 0;
|
|
1519
|
+
}
|
|
1520
|
+
function defineOwn(obj, key, value) {
|
|
1521
|
+
Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
|
|
1522
|
+
}
|
|
1523
|
+
function readEntityId(entity, idKey, typeName) {
|
|
1524
|
+
const raw = entity !== null && typeof entity === "object" && Object.hasOwn(entity, idKey) ? entity[idKey] : void 0;
|
|
1525
|
+
if (typeof raw === "string") return raw;
|
|
1526
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
1527
|
+
throw new TypeError(
|
|
1528
|
+
`[normalize] "${typeName}" entity has no valid "${idKey}" (expected a string or finite number, got ${raw === null ? "null" : typeof raw})`
|
|
1529
|
+
);
|
|
1530
|
+
}
|
|
1437
1531
|
function normalizedStore(schema) {
|
|
1438
1532
|
const idKey = schema.idKey || "id";
|
|
1439
1533
|
const [getState, setState] = signal({
|
|
1440
1534
|
ids: [],
|
|
1441
|
-
entities:
|
|
1535
|
+
entities: dict()
|
|
1442
1536
|
});
|
|
1443
|
-
const idOf = (entity) =>
|
|
1537
|
+
const idOf = (entity) => readEntityId(entity, idKey, schema.name);
|
|
1444
1538
|
function add(entity) {
|
|
1445
1539
|
const id = idOf(entity);
|
|
1446
1540
|
setState((prev) => {
|
|
1447
|
-
const ids = prev.
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
};
|
|
1541
|
+
const ids = Object.hasOwn(prev.entities, id) ? prev.ids : [...prev.ids, id];
|
|
1542
|
+
const entities = dict(prev.entities);
|
|
1543
|
+
defineOwn(entities, id, entity);
|
|
1544
|
+
return { ids, entities };
|
|
1452
1545
|
});
|
|
1453
1546
|
}
|
|
1454
1547
|
function addMany(entities) {
|
|
1548
|
+
const ids = entities.map(idOf);
|
|
1455
1549
|
setState((prev) => {
|
|
1456
1550
|
const nextIds = [...prev.ids];
|
|
1457
|
-
const nextEntities =
|
|
1458
|
-
|
|
1459
|
-
const id =
|
|
1460
|
-
if (!
|
|
1551
|
+
const nextEntities = dict(prev.entities);
|
|
1552
|
+
entities.forEach((entity, i) => {
|
|
1553
|
+
const id = ids[i];
|
|
1554
|
+
if (!Object.hasOwn(nextEntities, id)) {
|
|
1461
1555
|
nextIds.push(id);
|
|
1462
1556
|
}
|
|
1463
|
-
nextEntities
|
|
1464
|
-
}
|
|
1557
|
+
defineOwn(nextEntities, id, entity);
|
|
1558
|
+
});
|
|
1465
1559
|
return { ids: nextIds, entities: nextEntities };
|
|
1466
1560
|
});
|
|
1467
1561
|
}
|
|
1468
1562
|
function get(id) {
|
|
1469
|
-
|
|
1470
|
-
return state2.entities[id];
|
|
1563
|
+
return ownGet(getState().entities, id);
|
|
1471
1564
|
}
|
|
1472
1565
|
function getAll() {
|
|
1473
1566
|
const state2 = getState();
|
|
1474
1567
|
return state2.ids.map((id) => state2.entities[id]);
|
|
1475
1568
|
}
|
|
1476
1569
|
function update(id, partial) {
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1570
|
+
const prev = getState();
|
|
1571
|
+
if (!Object.hasOwn(prev.entities, id)) return;
|
|
1572
|
+
if (partial !== null && typeof partial === "object" && Object.hasOwn(partial, idKey)) {
|
|
1573
|
+
const nextId = readEntityId(partial, idKey, schema.name);
|
|
1574
|
+
if (nextId !== id) {
|
|
1575
|
+
throw new Error(
|
|
1576
|
+
`[normalizedStore] update("${id}") cannot change "${idKey}" to "${nextId}"; remove and re-add the entity instead.`
|
|
1577
|
+
);
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
setState((current) => {
|
|
1581
|
+
const existing = ownGet(current.entities, id);
|
|
1582
|
+
if (!existing) return current;
|
|
1583
|
+
const entities = dict(current.entities);
|
|
1584
|
+
defineOwn(entities, id, { ...existing, ...partial });
|
|
1585
|
+
return { ids: current.ids, entities };
|
|
1487
1586
|
});
|
|
1488
1587
|
}
|
|
1489
1588
|
function remove(id) {
|
|
1490
1589
|
setState((prev) => {
|
|
1491
|
-
if (!prev.entities
|
|
1492
|
-
const
|
|
1590
|
+
if (!Object.hasOwn(prev.entities, id)) return prev;
|
|
1591
|
+
const entities = dict(prev.entities);
|
|
1592
|
+
delete entities[id];
|
|
1493
1593
|
return {
|
|
1494
1594
|
ids: prev.ids.filter((existingId) => existingId !== id),
|
|
1495
|
-
entities
|
|
1595
|
+
entities
|
|
1496
1596
|
};
|
|
1497
1597
|
});
|
|
1498
1598
|
}
|
|
@@ -1503,31 +1603,37 @@ function normalizedStore(schema) {
|
|
|
1503
1603
|
return { add, addMany, get, getAll, update, remove, select, getState };
|
|
1504
1604
|
}
|
|
1505
1605
|
function normalize(data, schema) {
|
|
1506
|
-
const entities =
|
|
1606
|
+
const entities = dict();
|
|
1507
1607
|
function ensureTable(name) {
|
|
1508
|
-
|
|
1509
|
-
|
|
1608
|
+
let table = ownGet(entities, name);
|
|
1609
|
+
if (!table) {
|
|
1610
|
+
table = dict();
|
|
1611
|
+
defineOwn(entities, name, table);
|
|
1510
1612
|
}
|
|
1511
|
-
return
|
|
1613
|
+
return table;
|
|
1512
1614
|
}
|
|
1513
1615
|
function normalizeEntity(entity, entitySchema) {
|
|
1514
1616
|
const entityIdKey = entitySchema.idKey || "id";
|
|
1515
|
-
const id =
|
|
1617
|
+
const id = readEntityId(entity, entityIdKey, entitySchema.name);
|
|
1516
1618
|
const table = ensureTable(entitySchema.name);
|
|
1517
1619
|
const flat = { ...entity };
|
|
1518
1620
|
if (entitySchema.relations) {
|
|
1519
1621
|
for (const [field, relationType] of Object.entries(entitySchema.relations)) {
|
|
1520
|
-
const value = entity[field];
|
|
1622
|
+
const value = Object.hasOwn(entity, field) ? entity[field] : void 0;
|
|
1521
1623
|
if (value == null) continue;
|
|
1522
1624
|
const relSchema = { name: relationType };
|
|
1523
1625
|
if (Array.isArray(value)) {
|
|
1524
|
-
|
|
1626
|
+
defineOwn(
|
|
1627
|
+
flat,
|
|
1628
|
+
field,
|
|
1629
|
+
value.map((item) => normalizeEntity(item, relSchema))
|
|
1630
|
+
);
|
|
1525
1631
|
} else if (typeof value === "object") {
|
|
1526
|
-
flat
|
|
1632
|
+
defineOwn(flat, field, normalizeEntity(value, relSchema));
|
|
1527
1633
|
}
|
|
1528
1634
|
}
|
|
1529
1635
|
}
|
|
1530
|
-
table
|
|
1636
|
+
defineOwn(table, id, flat);
|
|
1531
1637
|
return id;
|
|
1532
1638
|
}
|
|
1533
1639
|
if (Array.isArray(data)) {
|
|
@@ -1538,20 +1644,24 @@ function normalize(data, schema) {
|
|
|
1538
1644
|
return { result, entities };
|
|
1539
1645
|
}
|
|
1540
1646
|
function denormalize(id, entities, schema) {
|
|
1541
|
-
const table = entities
|
|
1647
|
+
const table = ownGet(entities, schema.name);
|
|
1542
1648
|
if (!table) return void 0;
|
|
1543
|
-
const entity = table
|
|
1649
|
+
const entity = ownGet(table, id);
|
|
1544
1650
|
if (!entity) return void 0;
|
|
1545
1651
|
const result = { ...entity };
|
|
1546
1652
|
if (schema.relations) {
|
|
1547
1653
|
for (const [field, relationType] of Object.entries(schema.relations)) {
|
|
1548
|
-
const value = entity
|
|
1654
|
+
const value = ownGet(entity, field);
|
|
1549
1655
|
if (value == null) continue;
|
|
1550
1656
|
const relSchema = { name: relationType };
|
|
1551
1657
|
if (Array.isArray(value)) {
|
|
1552
|
-
|
|
1658
|
+
defineOwn(
|
|
1659
|
+
result,
|
|
1660
|
+
field,
|
|
1661
|
+
value.map((relId) => denormalize(relId, entities, relSchema))
|
|
1662
|
+
);
|
|
1553
1663
|
} else if (typeof value === "string") {
|
|
1554
|
-
result
|
|
1664
|
+
defineOwn(result, field, denormalize(value, entities, relSchema));
|
|
1555
1665
|
}
|
|
1556
1666
|
}
|
|
1557
1667
|
}
|
|
@@ -1761,13 +1871,24 @@ function lazyChunk(id, loader, registry, fallback) {
|
|
|
1761
1871
|
if (fallback) {
|
|
1762
1872
|
container.appendChild(fallback());
|
|
1763
1873
|
}
|
|
1874
|
+
let disposed = false;
|
|
1875
|
+
registerDisposer(container, () => {
|
|
1876
|
+
disposed = true;
|
|
1877
|
+
});
|
|
1764
1878
|
registry.load(id, async () => {
|
|
1765
1879
|
const mod = await loader();
|
|
1766
1880
|
return typeof mod === "function" ? mod : mod.default;
|
|
1767
1881
|
}).then((component) => {
|
|
1882
|
+
if (disposed) return;
|
|
1883
|
+
const node = component();
|
|
1884
|
+
if (disposed) {
|
|
1885
|
+
dispose(node);
|
|
1886
|
+
return;
|
|
1887
|
+
}
|
|
1768
1888
|
clearChildren(container);
|
|
1769
|
-
container.appendChild(
|
|
1889
|
+
container.appendChild(node);
|
|
1770
1890
|
}).catch((err) => {
|
|
1891
|
+
if (disposed) return;
|
|
1771
1892
|
clearChildren(container);
|
|
1772
1893
|
const errorEl = document.createElement("div");
|
|
1773
1894
|
errorEl.textContent = `Failed to load chunk '${id}': ${err.message}`;
|