sibujs 4.5.0 → 4.7.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 +1 -1
- package/dist/browser.cjs +326 -133
- package/dist/browser.d.cts +46 -14
- package/dist/browser.d.ts +46 -14
- package/dist/browser.js +8 -6
- package/dist/build.cjs +2094 -1033
- package/dist/build.d.cts +133 -44
- package/dist/build.d.ts +133 -44
- package/dist/build.js +1372 -574
- package/dist/cdn.dev.global.js +10 -10
- package/dist/cdn.full.dev.global.js +11 -11
- package/dist/cdn.full.global.js +10 -10
- package/dist/cdn.global.js +10 -10
- package/dist/{chunk-2DCGACUU.js → chunk-2BPG2XDA.js} +251 -66
- package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
- package/dist/{chunk-4PMLNECI.js → chunk-3QWBSL5R.js} +98 -29
- package/dist/{chunk-KKLW7YWL.js → chunk-4AWA2PVD.js} +275 -144
- package/dist/chunk-5HZXGZ6T.js +24 -0
- package/dist/{chunk-PCT43HW3.js → chunk-7LUJQAOJ.js} +1 -1
- package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
- package/dist/chunk-BC2SECJD.js +44 -0
- package/dist/{chunk-TBYTO6BS.js → chunk-BSY63EM6.js} +136 -80
- package/dist/{chunk-FTIR4QW2.js → chunk-DKXRACVN.js} +6 -8
- package/dist/{chunk-ONOHFDLG.js → chunk-FNJXNGYZ.js} +3 -3
- package/dist/{chunk-XZZOBQAY.js → chunk-FQRUXCEE.js} +6 -5
- package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
- package/dist/chunk-J6FW5TV6.js +233 -0
- package/dist/{chunk-UGRX3S57.js → chunk-JWKYU5GV.js} +22 -4
- package/dist/chunk-NYNYSPK7.js +318 -0
- package/dist/{chunk-RBTPLM32.js → chunk-RUSSKG6G.js} +13 -12
- package/dist/{chunk-7LN645I6.js → chunk-SLM3IA34.js} +3 -3
- package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
- package/dist/{chunk-B3WHI2QA.js → chunk-UNWRJRKC.js} +55 -31
- package/dist/{chunk-KEISJXBU.js → chunk-UOL2ECCS.js} +44 -17
- package/dist/{chunk-RJE2BNI4.js → chunk-VZSG24LS.js} +108 -45
- package/dist/{chunk-RIXRAYIU.js → chunk-WEQ3DMVL.js} +10 -4
- package/dist/{chunk-3JZ4L5TJ.js → chunk-WOLJZUFQ.js} +354 -90
- package/dist/{chunk-S373NSMK.js → chunk-XYV3EDB7.js} +283 -123
- package/dist/{chunk-VZKNK2V7.js → chunk-XZR4PXRE.js} +296 -38
- package/dist/{chunk-GW3SCCZG.js → chunk-Z3OHK6QT.js} +153 -110
- package/dist/{chunk-OMJJM3KM.js → chunk-ZVL7TY4K.js} +287 -130
- package/dist/{contracts-DBdg9J_a.d.ts → contracts-CLqzJnOV.d.ts} +36 -17
- package/dist/{contracts-DBdg9J_a.d.cts → contracts-CTOJXu-x.d.cts} +36 -17
- package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
- package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
- package/dist/data.cjs +410 -155
- package/dist/data.d.cts +166 -12
- package/dist/data.d.ts +166 -12
- package/dist/data.js +12 -9
- package/dist/devtools.cjs +98 -61
- package/dist/devtools.js +7 -8
- package/dist/dispose-GEIG2KOF.js +28 -0
- package/dist/ecosystem.cjs +372 -126
- package/dist/ecosystem.d.cts +20 -3
- package/dist/ecosystem.d.ts +20 -3
- package/dist/ecosystem.js +12 -12
- package/dist/extras.cjs +2366 -909
- package/dist/extras.d.cts +11 -9
- package/dist/extras.d.ts +11 -9
- package/dist/extras.js +39 -28
- package/dist/index.cjs +421 -158
- package/dist/index.d.cts +213 -171
- package/dist/index.d.ts +213 -171
- package/dist/index.js +24 -27
- package/dist/motion.cjs +118 -44
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +344 -53
- package/dist/patterns.d.cts +28 -9
- package/dist/patterns.d.ts +28 -9
- package/dist/patterns.js +8 -8
- package/dist/performance.cjs +325 -220
- 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 +664 -233
- package/dist/plugins.d.cts +127 -14
- package/dist/plugins.d.ts +127 -14
- package/dist/plugins.js +96 -42
- 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 +229 -84
- 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-8qL9LCIx.d.cts +156 -0
- package/dist/tagFactory-BL2fymez.d.ts +156 -0
- package/dist/testing.cjs +2503 -2191
- package/dist/testing.d.cts +56 -5
- package/dist/testing.d.ts +56 -5
- package/dist/testing.js +580 -307
- package/dist/types-CJFViL6Q.d.cts +26 -0
- package/dist/types-CJFViL6Q.d.ts +26 -0
- package/dist/ui.cjs +732 -329
- package/dist/ui.d.cts +41 -7
- package/dist/ui.d.ts +41 -7
- package/dist/ui.js +151 -56
- package/dist/widgets.cjs +267 -291
- package/dist/widgets.js +9 -10
- package/package.json +4 -2
- package/dist/chunk-2WLZ6757.js +0 -149
- package/dist/chunk-CCSJMTRN.js +0 -15
- package/dist/chunk-QKRPLZ2V.js +0 -108
- package/dist/chunk-VUF4ALSW.js +0 -60
- 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-DVoDpHye.d.cts +0 -215
- package/dist/tagFactory-DVoDpHye.d.ts +0 -215
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
|
|
@@ -492,6 +590,7 @@ function retrack(effectFn, subscriber) {
|
|
|
492
590
|
}
|
|
493
591
|
currentSubscriber = subscriber;
|
|
494
592
|
const sub = subscriber;
|
|
593
|
+
if (sub._cap === void 0) sub._cap = currentDisposerCapture();
|
|
495
594
|
const epoch = ++subscriberEpochCounter;
|
|
496
595
|
sub._epoch = epoch;
|
|
497
596
|
sub._structDirty = false;
|
|
@@ -683,7 +782,12 @@ function drainQueue() {
|
|
|
683
782
|
quarantined.add(sub);
|
|
684
783
|
continue;
|
|
685
784
|
}
|
|
686
|
-
|
|
785
|
+
const pushed = beginDisposerCapture(sub._cap ?? null);
|
|
786
|
+
try {
|
|
787
|
+
safeInvoke(sub);
|
|
788
|
+
} finally {
|
|
789
|
+
if (pushed) endDisposerCapture();
|
|
790
|
+
}
|
|
687
791
|
}
|
|
688
792
|
}
|
|
689
793
|
function drainNotificationQueue() {
|
|
@@ -819,7 +923,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
819
923
|
}
|
|
820
924
|
|
|
821
925
|
// src/reactivity/track.ts
|
|
822
|
-
var _runtimeVersion = true ? "4.
|
|
926
|
+
var _runtimeVersion = true ? "4.7.0" : "dev";
|
|
823
927
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
824
928
|
function resolveReactiveApi() {
|
|
825
929
|
const g = globalThis;
|
|
@@ -875,6 +979,14 @@ var getSubscriberCount2 = API.getSubscriberCount;
|
|
|
875
979
|
var getSubscriberDeps2 = API.getSubscriberDeps;
|
|
876
980
|
var forEachSubscriber2 = API.forEachSubscriber;
|
|
877
981
|
|
|
982
|
+
// src/core/devtoolsHook.ts
|
|
983
|
+
function emitDevtools(hook, event, payload) {
|
|
984
|
+
try {
|
|
985
|
+
hook.emit(event, payload);
|
|
986
|
+
} catch {
|
|
987
|
+
}
|
|
988
|
+
}
|
|
989
|
+
|
|
878
990
|
// src/core/ssr-context.ts
|
|
879
991
|
var SSR_KEY = /* @__PURE__ */ Symbol.for("sibujs.ssr.v1");
|
|
880
992
|
function detectSSRShared() {
|
|
@@ -1029,12 +1141,17 @@ function effect(effectFn, options) {
|
|
|
1029
1141
|
try {
|
|
1030
1142
|
retrack2(ctx.bodyFn, ctx.subscriber);
|
|
1031
1143
|
if (ctx.rerunPending) drainReruns(ctx);
|
|
1144
|
+
} catch (err) {
|
|
1145
|
+
ctx.disposed = true;
|
|
1146
|
+
if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
|
|
1147
|
+
cleanup2(ctx.subscriber);
|
|
1148
|
+
throw err;
|
|
1032
1149
|
} finally {
|
|
1033
1150
|
ctx.running = false;
|
|
1034
1151
|
ctx.rerunPending = false;
|
|
1035
1152
|
}
|
|
1036
1153
|
const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1037
|
-
if (hook) hook
|
|
1154
|
+
if (hook) emitDevtools(hook, "effect:create", { effectFn });
|
|
1038
1155
|
return () => disposeEffect(ctx);
|
|
1039
1156
|
}
|
|
1040
1157
|
|
|
@@ -1121,7 +1238,7 @@ function signal(initial, options) {
|
|
|
1121
1238
|
state2.__v++;
|
|
1122
1239
|
if (DEV) {
|
|
1123
1240
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1124
|
-
if (hook) hook
|
|
1241
|
+
if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
1125
1242
|
}
|
|
1126
1243
|
if (!enqueueBatchedSignal(state2)) {
|
|
1127
1244
|
notifySubscribers2(state2);
|
|
@@ -1135,7 +1252,7 @@ function signal(initial, options) {
|
|
|
1135
1252
|
state2.value = newValue;
|
|
1136
1253
|
state2.__v++;
|
|
1137
1254
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1138
|
-
if (hook) hook
|
|
1255
|
+
if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
1139
1256
|
if (!enqueueBatchedSignal(state2)) {
|
|
1140
1257
|
notifySubscribers2(state2);
|
|
1141
1258
|
}
|
|
@@ -1154,7 +1271,7 @@ function signal(initial, options) {
|
|
|
1154
1271
|
}
|
|
1155
1272
|
if (DEV) {
|
|
1156
1273
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
1157
|
-
if (hook) hook
|
|
1274
|
+
if (hook) emitDevtools(hook, "signal:create", { signal: state2, name: debugName, getter: get, initial });
|
|
1158
1275
|
}
|
|
1159
1276
|
return [get, set];
|
|
1160
1277
|
}
|
|
@@ -1200,72 +1317,6 @@ function uniqueId(suffix) {
|
|
|
1200
1317
|
return suffix ? `${id}-${suffix}` : id;
|
|
1201
1318
|
}
|
|
1202
1319
|
|
|
1203
|
-
// src/core/rendering/dispose.ts
|
|
1204
|
-
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
1205
|
-
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
1206
|
-
function reportDrainRunaway(label, executed, remaining) {
|
|
1207
|
-
if (typeof console === "undefined") return;
|
|
1208
|
-
console.error(
|
|
1209
|
-
`[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.`,
|
|
1210
|
-
{ executed, remaining }
|
|
1211
|
-
);
|
|
1212
|
-
}
|
|
1213
|
-
var activeBindingCount = 0;
|
|
1214
|
-
function dispose(node) {
|
|
1215
|
-
const stack = [node];
|
|
1216
|
-
const order = [];
|
|
1217
|
-
while (stack.length > 0) {
|
|
1218
|
-
const current = stack.pop();
|
|
1219
|
-
order.push(current);
|
|
1220
|
-
const children = Array.from(current.childNodes);
|
|
1221
|
-
for (let i = 0; i < children.length; i++) {
|
|
1222
|
-
stack.push(children[i]);
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
for (let i = order.length - 1; i >= 0; i--) {
|
|
1226
|
-
const current = order[i];
|
|
1227
|
-
if (elementDisposers.has(current)) {
|
|
1228
|
-
let executed = 0;
|
|
1229
|
-
let runaway = false;
|
|
1230
|
-
while (!runaway) {
|
|
1231
|
-
const pending = elementDisposers.get(current);
|
|
1232
|
-
if (!pending || pending.length === 0) break;
|
|
1233
|
-
const snapshot = pending.slice();
|
|
1234
|
-
elementDisposers.delete(current);
|
|
1235
|
-
if (DEV) activeBindingCount -= snapshot.length;
|
|
1236
|
-
for (let i2 = 0; i2 < snapshot.length; i2++) {
|
|
1237
|
-
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
1238
|
-
const rest = snapshot.slice(i2);
|
|
1239
|
-
const added = elementDisposers.get(current);
|
|
1240
|
-
elementDisposers.set(current, added ? rest.concat(added) : rest);
|
|
1241
|
-
if (DEV) activeBindingCount += rest.length;
|
|
1242
|
-
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
1243
|
-
runaway = true;
|
|
1244
|
-
break;
|
|
1245
|
-
}
|
|
1246
|
-
executed++;
|
|
1247
|
-
try {
|
|
1248
|
-
snapshot[i2]();
|
|
1249
|
-
} catch (err) {
|
|
1250
|
-
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
function replaceChildrenSafely(parent, ...next) {
|
|
1258
|
-
for (let i = 0; i < next.length; i++) {
|
|
1259
|
-
const node = next[i];
|
|
1260
|
-
node.parentNode?.removeChild(node);
|
|
1261
|
-
}
|
|
1262
|
-
const current = Array.from(parent.childNodes);
|
|
1263
|
-
for (let i = 0; i < current.length; i++) {
|
|
1264
|
-
dispose(current[i]);
|
|
1265
|
-
}
|
|
1266
|
-
parent.replaceChildren(...next);
|
|
1267
|
-
}
|
|
1268
|
-
|
|
1269
1320
|
// src/utils/sanitize.ts
|
|
1270
1321
|
function stripControlChars(value) {
|
|
1271
1322
|
return value.replace(/[\x00-\x20\x7f-\x9f]+/g, "");
|
|
@@ -1366,11 +1417,16 @@ function getDOMPool() {
|
|
|
1366
1417
|
return _defaultPool;
|
|
1367
1418
|
}
|
|
1368
1419
|
var preloadedResources = /* @__PURE__ */ new Set();
|
|
1420
|
+
function hintKey(rel, as, crossorigin, href) {
|
|
1421
|
+
return `${rel}\0${as}\0${crossorigin}\0${href}`;
|
|
1422
|
+
}
|
|
1369
1423
|
function preloadResource(url, type = "fetch") {
|
|
1370
1424
|
const safe = sanitizeUrl(url);
|
|
1371
1425
|
if (!safe) return;
|
|
1372
|
-
|
|
1373
|
-
|
|
1426
|
+
const as = type === "script" || type === "style" || type === "image" ? type : "fetch";
|
|
1427
|
+
const key = hintKey("preload", as, as === "fetch" ? "anonymous" : "", safe);
|
|
1428
|
+
if (preloadedResources.has(key)) return;
|
|
1429
|
+
preloadedResources.add(key);
|
|
1374
1430
|
const link = document.createElement("link");
|
|
1375
1431
|
link.rel = "preload";
|
|
1376
1432
|
link.href = safe;
|
|
@@ -1393,8 +1449,9 @@ function preloadResource(url, type = "fetch") {
|
|
|
1393
1449
|
function prefetch(url) {
|
|
1394
1450
|
const safe = sanitizeUrl(url);
|
|
1395
1451
|
if (!safe) return;
|
|
1396
|
-
|
|
1397
|
-
preloadedResources.
|
|
1452
|
+
const key = hintKey("prefetch", "", "", safe);
|
|
1453
|
+
if (preloadedResources.has(key)) return;
|
|
1454
|
+
preloadedResources.add(key);
|
|
1398
1455
|
const link = document.createElement("link");
|
|
1399
1456
|
link.rel = "prefetch";
|
|
1400
1457
|
link.href = safe;
|
|
@@ -1463,65 +1520,92 @@ function block(factory) {
|
|
|
1463
1520
|
}
|
|
1464
1521
|
|
|
1465
1522
|
// src/performance/normalize.ts
|
|
1523
|
+
function dict(source) {
|
|
1524
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
1525
|
+
if (source) {
|
|
1526
|
+
for (const key of Object.keys(source)) defineOwn(out, key, source[key]);
|
|
1527
|
+
}
|
|
1528
|
+
return out;
|
|
1529
|
+
}
|
|
1530
|
+
function ownGet(obj, key) {
|
|
1531
|
+
return obj !== void 0 && Object.hasOwn(obj, key) ? obj[key] : void 0;
|
|
1532
|
+
}
|
|
1533
|
+
function defineOwn(obj, key, value) {
|
|
1534
|
+
Object.defineProperty(obj, key, { value, writable: true, enumerable: true, configurable: true });
|
|
1535
|
+
}
|
|
1536
|
+
function readEntityId(entity, idKey, typeName) {
|
|
1537
|
+
const raw = entity !== null && typeof entity === "object" && Object.hasOwn(entity, idKey) ? entity[idKey] : void 0;
|
|
1538
|
+
if (typeof raw === "string") return raw;
|
|
1539
|
+
if (typeof raw === "number" && Number.isFinite(raw)) return String(raw);
|
|
1540
|
+
throw new TypeError(
|
|
1541
|
+
`[normalize] "${typeName}" entity has no valid "${idKey}" (expected a string or finite number, got ${raw === null ? "null" : typeof raw})`
|
|
1542
|
+
);
|
|
1543
|
+
}
|
|
1466
1544
|
function normalizedStore(schema) {
|
|
1467
1545
|
const idKey = schema.idKey || "id";
|
|
1468
1546
|
const [getState, setState] = signal({
|
|
1469
1547
|
ids: [],
|
|
1470
|
-
entities:
|
|
1548
|
+
entities: dict()
|
|
1471
1549
|
});
|
|
1472
|
-
const idOf = (entity) =>
|
|
1550
|
+
const idOf = (entity) => readEntityId(entity, idKey, schema.name);
|
|
1473
1551
|
function add(entity) {
|
|
1474
1552
|
const id = idOf(entity);
|
|
1475
1553
|
setState((prev) => {
|
|
1476
|
-
const ids = prev.
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
};
|
|
1554
|
+
const ids = Object.hasOwn(prev.entities, id) ? prev.ids : [...prev.ids, id];
|
|
1555
|
+
const entities = dict(prev.entities);
|
|
1556
|
+
defineOwn(entities, id, entity);
|
|
1557
|
+
return { ids, entities };
|
|
1481
1558
|
});
|
|
1482
1559
|
}
|
|
1483
1560
|
function addMany(entities) {
|
|
1561
|
+
const ids = entities.map(idOf);
|
|
1484
1562
|
setState((prev) => {
|
|
1485
1563
|
const nextIds = [...prev.ids];
|
|
1486
|
-
const nextEntities =
|
|
1487
|
-
|
|
1488
|
-
const id =
|
|
1489
|
-
if (!
|
|
1564
|
+
const nextEntities = dict(prev.entities);
|
|
1565
|
+
entities.forEach((entity, i) => {
|
|
1566
|
+
const id = ids[i];
|
|
1567
|
+
if (!Object.hasOwn(nextEntities, id)) {
|
|
1490
1568
|
nextIds.push(id);
|
|
1491
1569
|
}
|
|
1492
|
-
nextEntities
|
|
1493
|
-
}
|
|
1570
|
+
defineOwn(nextEntities, id, entity);
|
|
1571
|
+
});
|
|
1494
1572
|
return { ids: nextIds, entities: nextEntities };
|
|
1495
1573
|
});
|
|
1496
1574
|
}
|
|
1497
1575
|
function get(id) {
|
|
1498
|
-
|
|
1499
|
-
return state2.entities[id];
|
|
1576
|
+
return ownGet(getState().entities, id);
|
|
1500
1577
|
}
|
|
1501
1578
|
function getAll() {
|
|
1502
1579
|
const state2 = getState();
|
|
1503
1580
|
return state2.ids.map((id) => state2.entities[id]);
|
|
1504
1581
|
}
|
|
1505
1582
|
function update(id, partial) {
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1583
|
+
const prev = getState();
|
|
1584
|
+
if (!Object.hasOwn(prev.entities, id)) return;
|
|
1585
|
+
if (partial !== null && typeof partial === "object" && Object.hasOwn(partial, idKey)) {
|
|
1586
|
+
const nextId = readEntityId(partial, idKey, schema.name);
|
|
1587
|
+
if (nextId !== id) {
|
|
1588
|
+
throw new Error(
|
|
1589
|
+
`[normalizedStore] update("${id}") cannot change "${idKey}" to "${nextId}"; remove and re-add the entity instead.`
|
|
1590
|
+
);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
setState((current) => {
|
|
1594
|
+
const existing = ownGet(current.entities, id);
|
|
1595
|
+
if (!existing) return current;
|
|
1596
|
+
const entities = dict(current.entities);
|
|
1597
|
+
defineOwn(entities, id, { ...existing, ...partial });
|
|
1598
|
+
return { ids: current.ids, entities };
|
|
1516
1599
|
});
|
|
1517
1600
|
}
|
|
1518
1601
|
function remove(id) {
|
|
1519
1602
|
setState((prev) => {
|
|
1520
|
-
if (!prev.entities
|
|
1521
|
-
const
|
|
1603
|
+
if (!Object.hasOwn(prev.entities, id)) return prev;
|
|
1604
|
+
const entities = dict(prev.entities);
|
|
1605
|
+
delete entities[id];
|
|
1522
1606
|
return {
|
|
1523
1607
|
ids: prev.ids.filter((existingId) => existingId !== id),
|
|
1524
|
-
entities
|
|
1608
|
+
entities
|
|
1525
1609
|
};
|
|
1526
1610
|
});
|
|
1527
1611
|
}
|
|
@@ -1532,31 +1616,37 @@ function normalizedStore(schema) {
|
|
|
1532
1616
|
return { add, addMany, get, getAll, update, remove, select, getState };
|
|
1533
1617
|
}
|
|
1534
1618
|
function normalize(data, schema) {
|
|
1535
|
-
const entities =
|
|
1619
|
+
const entities = dict();
|
|
1536
1620
|
function ensureTable(name) {
|
|
1537
|
-
|
|
1538
|
-
|
|
1621
|
+
let table = ownGet(entities, name);
|
|
1622
|
+
if (!table) {
|
|
1623
|
+
table = dict();
|
|
1624
|
+
defineOwn(entities, name, table);
|
|
1539
1625
|
}
|
|
1540
|
-
return
|
|
1626
|
+
return table;
|
|
1541
1627
|
}
|
|
1542
1628
|
function normalizeEntity(entity, entitySchema) {
|
|
1543
1629
|
const entityIdKey = entitySchema.idKey || "id";
|
|
1544
|
-
const id =
|
|
1630
|
+
const id = readEntityId(entity, entityIdKey, entitySchema.name);
|
|
1545
1631
|
const table = ensureTable(entitySchema.name);
|
|
1546
1632
|
const flat = { ...entity };
|
|
1547
1633
|
if (entitySchema.relations) {
|
|
1548
1634
|
for (const [field, relationType] of Object.entries(entitySchema.relations)) {
|
|
1549
|
-
const value = entity[field];
|
|
1635
|
+
const value = Object.hasOwn(entity, field) ? entity[field] : void 0;
|
|
1550
1636
|
if (value == null) continue;
|
|
1551
1637
|
const relSchema = { name: relationType };
|
|
1552
1638
|
if (Array.isArray(value)) {
|
|
1553
|
-
|
|
1639
|
+
defineOwn(
|
|
1640
|
+
flat,
|
|
1641
|
+
field,
|
|
1642
|
+
value.map((item) => normalizeEntity(item, relSchema))
|
|
1643
|
+
);
|
|
1554
1644
|
} else if (typeof value === "object") {
|
|
1555
|
-
flat
|
|
1645
|
+
defineOwn(flat, field, normalizeEntity(value, relSchema));
|
|
1556
1646
|
}
|
|
1557
1647
|
}
|
|
1558
1648
|
}
|
|
1559
|
-
table
|
|
1649
|
+
defineOwn(table, id, flat);
|
|
1560
1650
|
return id;
|
|
1561
1651
|
}
|
|
1562
1652
|
if (Array.isArray(data)) {
|
|
@@ -1567,20 +1657,24 @@ function normalize(data, schema) {
|
|
|
1567
1657
|
return { result, entities };
|
|
1568
1658
|
}
|
|
1569
1659
|
function denormalize(id, entities, schema) {
|
|
1570
|
-
const table = entities
|
|
1660
|
+
const table = ownGet(entities, schema.name);
|
|
1571
1661
|
if (!table) return void 0;
|
|
1572
|
-
const entity = table
|
|
1662
|
+
const entity = ownGet(table, id);
|
|
1573
1663
|
if (!entity) return void 0;
|
|
1574
1664
|
const result = { ...entity };
|
|
1575
1665
|
if (schema.relations) {
|
|
1576
1666
|
for (const [field, relationType] of Object.entries(schema.relations)) {
|
|
1577
|
-
const value = entity
|
|
1667
|
+
const value = ownGet(entity, field);
|
|
1578
1668
|
if (value == null) continue;
|
|
1579
1669
|
const relSchema = { name: relationType };
|
|
1580
1670
|
if (Array.isArray(value)) {
|
|
1581
|
-
|
|
1671
|
+
defineOwn(
|
|
1672
|
+
result,
|
|
1673
|
+
field,
|
|
1674
|
+
value.map((relId) => denormalize(relId, entities, relSchema))
|
|
1675
|
+
);
|
|
1582
1676
|
} else if (typeof value === "string") {
|
|
1583
|
-
result
|
|
1677
|
+
defineOwn(result, field, denormalize(value, entities, relSchema));
|
|
1584
1678
|
}
|
|
1585
1679
|
}
|
|
1586
1680
|
}
|
|
@@ -1790,13 +1884,24 @@ function lazyChunk(id, loader, registry, fallback) {
|
|
|
1790
1884
|
if (fallback) {
|
|
1791
1885
|
container.appendChild(fallback());
|
|
1792
1886
|
}
|
|
1887
|
+
let disposed = false;
|
|
1888
|
+
registerDisposer(container, () => {
|
|
1889
|
+
disposed = true;
|
|
1890
|
+
});
|
|
1793
1891
|
registry.load(id, async () => {
|
|
1794
1892
|
const mod = await loader();
|
|
1795
1893
|
return typeof mod === "function" ? mod : mod.default;
|
|
1796
1894
|
}).then((component) => {
|
|
1895
|
+
if (disposed) return;
|
|
1896
|
+
const node = component();
|
|
1897
|
+
if (disposed) {
|
|
1898
|
+
dispose(node);
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1797
1901
|
clearChildren(container);
|
|
1798
|
-
container.appendChild(
|
|
1902
|
+
container.appendChild(node);
|
|
1799
1903
|
}).catch((err) => {
|
|
1904
|
+
if (disposed) return;
|
|
1800
1905
|
clearChildren(container);
|
|
1801
1906
|
const errorEl = document.createElement("div");
|
|
1802
1907
|
errorEl.textContent = `Failed to load chunk '${id}': ${err.message}`;
|