sibujs 3.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +118 -15
- package/dist/browser.cjs +410 -101
- package/dist/browser.d.cts +50 -5
- package/dist/browser.d.ts +50 -5
- package/dist/browser.js +8 -6
- package/dist/build.cjs +777 -385
- package/dist/build.js +15 -15
- package/dist/cdn.global.js +11 -7
- package/dist/{chunk-JCO7AHNU.js → chunk-3EKJK5FZ.js} +73 -34
- package/dist/chunk-4MFZMLUU.js +147 -0
- package/dist/chunk-52XFPGSN.js +123 -0
- package/dist/chunk-5INI7D2L.js +194 -0
- package/dist/{chunk-OAVXAFAY.js → chunk-6LG2T7LO.js} +5 -5
- package/dist/{chunk-OOUQUCNN.js → chunk-ACBT6UZS.js} +57 -22
- package/dist/{chunk-F7HW2NI5.js → chunk-AW6HPJ3L.js} +1 -1
- package/dist/chunk-DHDZ7IVN.js +109 -0
- package/dist/{chunk-JNGGM2XE.js → chunk-DQVUBVNX.js} +16 -25
- package/dist/{chunk-AXFWGY32.js → chunk-DR7H6UGM.js} +232 -67
- package/dist/{chunk-WSGLJYFI.js → chunk-E62UADKL.js} +9 -3
- package/dist/{chunk-3Z2NGWQI.js → chunk-ES2GERY2.js} +1 -1
- package/dist/{chunk-S3V6ZXPI.js → chunk-EWEE7NBF.js} +115 -41
- package/dist/{chunk-3DVGCW7O.js → chunk-F64ZPCFE.js} +8 -8
- package/dist/{chunk-APFRCIRI.js → chunk-GCSGGA3Q.js} +295 -198
- package/dist/{chunk-EX77FXTT.js → chunk-HYCCIYNS.js} +228 -51
- package/dist/{chunk-ELXMRSVN.js → chunk-NF3LYCQH.js} +259 -124
- package/dist/chunk-O3QQ3XOL.js +61 -0
- package/dist/{chunk-BUKYCWHX.js → chunk-PBQEW5VW.js} +14 -10
- package/dist/{chunk-H5FI5WDP.js → chunk-RRIDJQ5C.js} +3 -3
- package/dist/{chunk-S3NFJO6L.js → chunk-TIRZCERI.js} +36 -5
- package/dist/{chunk-ODXVQ3CS.js → chunk-VFHIVEPF.js} +309 -188
- package/dist/chunk-VPP2FONR.js +142 -0
- package/dist/{chunk-KZBEVFXZ.js → chunk-W55YHPEP.js} +5 -3
- package/dist/{chunk-FKQG7FTY.js → chunk-WN6WDFCB.js} +4 -4
- package/dist/{chunk-CEBWDD63.js → chunk-WOOMUJFT.js} +228 -86
- package/dist/{chunk-ITWCTZYH.js → chunk-Z2CE42DB.js} +19 -25
- package/dist/{contracts-ey_Qh8ef.d.cts → contracts-Hg6ITAEF.d.cts} +6 -6
- package/dist/{contracts-ey_Qh8ef.d.ts → contracts-Hg6ITAEF.d.ts} +6 -6
- package/dist/{customElement-CPfIrbvg.d.ts → customElement-CKLoO63w.d.cts} +73 -11
- package/dist/{customElement-CPfIrbvg.d.cts → customElement-CKLoO63w.d.ts} +73 -11
- package/dist/data.cjs +483 -205
- package/dist/data.d.cts +139 -7
- package/dist/data.d.ts +139 -7
- package/dist/data.js +9 -9
- package/dist/devtools.cjs +222 -87
- package/dist/devtools.js +8 -8
- package/dist/dispose-4FZ6OFXR.js +19 -0
- package/dist/ecosystem.cjs +419 -175
- package/dist/ecosystem.js +11 -11
- package/dist/extras.cjs +1981 -765
- package/dist/extras.d.cts +7 -7
- package/dist/extras.d.ts +7 -7
- package/dist/extras.js +29 -26
- package/dist/index.cjs +784 -385
- package/dist/index.d.cts +299 -28
- package/dist/index.d.ts +299 -28
- package/dist/index.js +33 -18
- package/dist/motion.cjs +180 -50
- package/dist/motion.d.cts +26 -0
- package/dist/motion.d.ts +26 -0
- package/dist/motion.js +5 -5
- package/dist/patterns.cjs +437 -170
- package/dist/patterns.d.cts +60 -13
- package/dist/patterns.d.ts +60 -13
- package/dist/patterns.js +7 -7
- package/dist/performance.cjs +333 -148
- package/dist/performance.d.cts +55 -7
- package/dist/performance.d.ts +55 -7
- package/dist/performance.js +9 -9
- package/dist/plugins.cjs +1374 -576
- package/dist/plugins.d.cts +227 -9
- package/dist/plugins.d.ts +227 -9
- package/dist/plugins.js +613 -321
- package/dist/{ssr-D62yFwuw.d.cts → ssr-BiPRdZ6n.d.cts} +44 -15
- package/dist/{ssr-D62yFwuw.d.ts → ssr-BiPRdZ6n.d.ts} +44 -15
- package/dist/{ssr-2PPULEK2.js → ssr-JFP5535P.js} +5 -4
- package/dist/ssr.cjs +1104 -443
- package/dist/ssr.d.cts +230 -20
- package/dist/ssr.d.ts +230 -20
- package/dist/ssr.js +15 -12
- package/dist/{startup-0Qv6aosO.d.cts → startup-BMpaiMhP.d.cts} +1 -1
- package/dist/{startup-0Qv6aosO.d.ts → startup-BMpaiMhP.d.ts} +1 -1
- package/dist/testing.cjs +205 -63
- package/dist/testing.d.cts +1 -1
- package/dist/testing.d.ts +1 -1
- package/dist/testing.js +8 -10
- package/dist/ui.cjs +640 -199
- package/dist/ui.d.cts +2 -2
- package/dist/ui.d.ts +2 -2
- package/dist/ui.js +10 -10
- package/dist/widgets.cjs +207 -82
- package/dist/widgets.js +9 -9
- package/package.json +12 -7
- package/dist/chunk-5VGSK6D2.js +0 -80
- package/dist/chunk-COY6PUD2.js +0 -34
- package/dist/chunk-K35BAR4P.js +0 -96
- package/dist/chunk-L3GAGWCC.js +0 -111
- package/dist/chunk-RT3IYFN2.js +0 -38
package/dist/index.cjs
CHANGED
|
@@ -26,8 +26,9 @@ __export(index_exports, {
|
|
|
26
26
|
Fragment: () => Fragment,
|
|
27
27
|
KeepAlive: () => KeepAlive,
|
|
28
28
|
Loading: () => Loading,
|
|
29
|
+
MAX_DRAIN_TEARDOWNS: () => MAX_DRAIN_TEARDOWNS,
|
|
29
30
|
Portal: () => Portal,
|
|
30
|
-
SVG_NS: () =>
|
|
31
|
+
SVG_NS: () => SVG_NS2,
|
|
31
32
|
Suspense: () => Suspense,
|
|
32
33
|
__resetIdCounter: () => __resetIdCounter,
|
|
33
34
|
a: () => a,
|
|
@@ -103,6 +104,7 @@ __export(index_exports, {
|
|
|
103
104
|
g: () => g,
|
|
104
105
|
getAction: () => getAction,
|
|
105
106
|
getRequestScopedCache: () => getRequestScopedCache,
|
|
107
|
+
getRuntimeErrorHandler: () => getRuntimeErrorHandler,
|
|
106
108
|
getSSRStore: () => getSSRStore,
|
|
107
109
|
getSlot: () => getSlot,
|
|
108
110
|
h1: () => h1,
|
|
@@ -176,6 +178,9 @@ __export(index_exports, {
|
|
|
176
178
|
registerComponent: () => registerComponent,
|
|
177
179
|
registerDisposer: () => registerDisposer,
|
|
178
180
|
registerIsland: () => registerIsland,
|
|
181
|
+
replaceChildrenSafely: () => replaceChildrenSafely,
|
|
182
|
+
reportDrainRunaway: () => reportDrainRunaway,
|
|
183
|
+
reportError: () => reportError,
|
|
179
184
|
resolveComponent: () => resolveComponent,
|
|
180
185
|
retrack: () => retrack2,
|
|
181
186
|
rp: () => rp,
|
|
@@ -189,6 +194,7 @@ __export(index_exports, {
|
|
|
189
194
|
select: () => select,
|
|
190
195
|
setGlobalErrorHandler: () => setGlobalErrorHandler,
|
|
191
196
|
setMaxDrainIterations: () => setMaxDrainIterations2,
|
|
197
|
+
setRuntimeErrorHandler: () => setRuntimeErrorHandler,
|
|
192
198
|
show: () => show,
|
|
193
199
|
signal: () => signal,
|
|
194
200
|
slot: () => slot,
|
|
@@ -228,6 +234,7 @@ __export(index_exports, {
|
|
|
228
234
|
u: () => u,
|
|
229
235
|
ul: () => ul,
|
|
230
236
|
unregisterComponent: () => unregisterComponent,
|
|
237
|
+
unregisterDisposer: () => unregisterDisposer,
|
|
231
238
|
unregisterIsland: () => unregisterIsland,
|
|
232
239
|
untracked: () => untracked2,
|
|
233
240
|
use: () => use,
|
|
@@ -240,6 +247,103 @@ __export(index_exports, {
|
|
|
240
247
|
});
|
|
241
248
|
module.exports = __toCommonJS(index_exports);
|
|
242
249
|
|
|
250
|
+
// src/core/errors.ts
|
|
251
|
+
var ERROR_STATE_KEY = /* @__PURE__ */ Symbol.for("sibujs.runtime-errors.v1");
|
|
252
|
+
function state() {
|
|
253
|
+
const g2 = globalThis;
|
|
254
|
+
const existing = g2[ERROR_STATE_KEY];
|
|
255
|
+
if (existing) return existing;
|
|
256
|
+
const created = { handler: null, handlerDepth: 0 };
|
|
257
|
+
g2[ERROR_STATE_KEY] = created;
|
|
258
|
+
return created;
|
|
259
|
+
}
|
|
260
|
+
function setRuntimeErrorHandler(handler) {
|
|
261
|
+
const s2 = state();
|
|
262
|
+
const prev = s2.handler;
|
|
263
|
+
s2.handler = handler;
|
|
264
|
+
return prev;
|
|
265
|
+
}
|
|
266
|
+
function getRuntimeErrorHandler() {
|
|
267
|
+
return state().handler;
|
|
268
|
+
}
|
|
269
|
+
function normalizeError(value) {
|
|
270
|
+
if (value instanceof Error) return value;
|
|
271
|
+
const message = typeof value === "string" ? value : `Non-Error value thrown: ${safeStringify(value)}`;
|
|
272
|
+
return new Error(message, { cause: value });
|
|
273
|
+
}
|
|
274
|
+
function safeStringify(value) {
|
|
275
|
+
if (typeof value === "symbol") return value.toString();
|
|
276
|
+
try {
|
|
277
|
+
return typeof value === "object" && value !== null ? JSON.stringify(value) : String(value);
|
|
278
|
+
} catch {
|
|
279
|
+
return Object.prototype.toString.call(value);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
function describe(context2) {
|
|
283
|
+
return context2.name ? `${context2.phase} "${context2.name}"` : context2.phase;
|
|
284
|
+
}
|
|
285
|
+
var REACTIVE_REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
286
|
+
function untrackedRun(fn) {
|
|
287
|
+
const api = globalThis[REACTIVE_REGISTRY_KEY];
|
|
288
|
+
return api?.untracked ? api.untracked(fn) : fn();
|
|
289
|
+
}
|
|
290
|
+
var PROPAGATE_EVENT = "sibu:error-propagate";
|
|
291
|
+
function claimedByBoundary(error, context2) {
|
|
292
|
+
const raw = context2.node;
|
|
293
|
+
if (!raw || typeof CustomEvent === "undefined") return false;
|
|
294
|
+
const target = resolveEventTarget(raw);
|
|
295
|
+
if (!target) return false;
|
|
296
|
+
try {
|
|
297
|
+
const event = new CustomEvent(PROPAGATE_EVENT, {
|
|
298
|
+
bubbles: true,
|
|
299
|
+
cancelable: true,
|
|
300
|
+
detail: { error, context: context2 }
|
|
301
|
+
});
|
|
302
|
+
return target.dispatchEvent(event) === false;
|
|
303
|
+
} catch {
|
|
304
|
+
return false;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
function resolveEventTarget(node) {
|
|
308
|
+
const ELEMENT_NODE = 1;
|
|
309
|
+
let current = node;
|
|
310
|
+
while (current) {
|
|
311
|
+
if (current.nodeType === ELEMENT_NODE && typeof current.dispatchEvent === "function") {
|
|
312
|
+
return current;
|
|
313
|
+
}
|
|
314
|
+
current = current.parentNode;
|
|
315
|
+
}
|
|
316
|
+
const self = node;
|
|
317
|
+
return typeof self.dispatchEvent === "function" ? self : null;
|
|
318
|
+
}
|
|
319
|
+
function defaultReport(error, context2) {
|
|
320
|
+
if (typeof console === "undefined") return;
|
|
321
|
+
console.error(`[SibuJS] Uncaught error during ${describe(context2)}: ${error.message}`, error);
|
|
322
|
+
}
|
|
323
|
+
function reportError(error, context2) {
|
|
324
|
+
const err = normalizeError(error);
|
|
325
|
+
untrackedRun(() => {
|
|
326
|
+
if (claimedByBoundary(err, context2)) return;
|
|
327
|
+
const s2 = state();
|
|
328
|
+
const handler = s2.handler;
|
|
329
|
+
if (handler && s2.handlerDepth === 0) {
|
|
330
|
+
s2.handlerDepth++;
|
|
331
|
+
try {
|
|
332
|
+
handler(error instanceof Error ? error : err, context2);
|
|
333
|
+
return;
|
|
334
|
+
} catch (handlerError) {
|
|
335
|
+
if (typeof console !== "undefined") {
|
|
336
|
+
const detail = handlerError instanceof Error ? handlerError.message : String(handlerError);
|
|
337
|
+
console.error(`[SibuJS] runtime error handler itself threw: ${detail}`, handlerError);
|
|
338
|
+
}
|
|
339
|
+
} finally {
|
|
340
|
+
s2.handlerDepth--;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
defaultReport(err, context2);
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
243
347
|
// src/core/dev.ts
|
|
244
348
|
function isDev() {
|
|
245
349
|
return typeof globalThis.__SIBU_DEV__ !== "undefined" ? !!globalThis.__SIBU_DEV__ : (
|
|
@@ -264,6 +368,14 @@ function devWarn(message) {
|
|
|
264
368
|
|
|
265
369
|
// src/core/rendering/dispose.ts
|
|
266
370
|
var elementDisposers = /* @__PURE__ */ new WeakMap();
|
|
371
|
+
var MAX_DRAIN_TEARDOWNS = 1e4;
|
|
372
|
+
function reportDrainRunaway(label2, executed, remaining) {
|
|
373
|
+
if (typeof console === "undefined") return;
|
|
374
|
+
console.error(
|
|
375
|
+
`[SibuJS ${label2}] 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.`,
|
|
376
|
+
{ executed, remaining }
|
|
377
|
+
);
|
|
378
|
+
}
|
|
267
379
|
var _isDev2 = isDev();
|
|
268
380
|
var activeBindingCount = 0;
|
|
269
381
|
function registerDisposer(node, teardown) {
|
|
@@ -275,6 +387,15 @@ function registerDisposer(node, teardown) {
|
|
|
275
387
|
disposers.push(teardown);
|
|
276
388
|
if (_isDev2) activeBindingCount++;
|
|
277
389
|
}
|
|
390
|
+
function unregisterDisposer(node, teardown) {
|
|
391
|
+
const disposers = elementDisposers.get(node);
|
|
392
|
+
if (!disposers) return;
|
|
393
|
+
const index = disposers.indexOf(teardown);
|
|
394
|
+
if (index === -1) return;
|
|
395
|
+
disposers.splice(index, 1);
|
|
396
|
+
if (_isDev2) activeBindingCount--;
|
|
397
|
+
if (disposers.length === 0) elementDisposers.delete(node);
|
|
398
|
+
}
|
|
278
399
|
function dispose(node) {
|
|
279
400
|
const stack = [node];
|
|
280
401
|
const order = [];
|
|
@@ -288,40 +409,47 @@ function dispose(node) {
|
|
|
288
409
|
}
|
|
289
410
|
for (let i2 = order.length - 1; i2 >= 0; i2--) {
|
|
290
411
|
const current = order[i2];
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
d();
|
|
299
|
-
} catch (err) {
|
|
300
|
-
if (_isDev2 && typeof console !== "undefined") {
|
|
301
|
-
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
let extraPasses = 0;
|
|
306
|
-
while (extraPasses++ < 8) {
|
|
307
|
-
const added = elementDisposers.get(current);
|
|
308
|
-
if (!added || added.length === 0) break;
|
|
309
|
-
const moreSnapshot = added.slice();
|
|
412
|
+
if (elementDisposers.has(current)) {
|
|
413
|
+
let executed = 0;
|
|
414
|
+
let runaway = false;
|
|
415
|
+
while (!runaway) {
|
|
416
|
+
const pending = elementDisposers.get(current);
|
|
417
|
+
if (!pending || pending.length === 0) break;
|
|
418
|
+
const snapshot = pending.slice();
|
|
310
419
|
elementDisposers.delete(current);
|
|
311
|
-
if (_isDev2) activeBindingCount -=
|
|
312
|
-
for (
|
|
420
|
+
if (_isDev2) activeBindingCount -= snapshot.length;
|
|
421
|
+
for (let i3 = 0; i3 < snapshot.length; i3++) {
|
|
422
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
423
|
+
const rest = snapshot.slice(i3);
|
|
424
|
+
const added = elementDisposers.get(current);
|
|
425
|
+
elementDisposers.set(current, added ? rest.concat(added) : rest);
|
|
426
|
+
if (_isDev2) activeBindingCount += rest.length;
|
|
427
|
+
reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
|
|
428
|
+
runaway = true;
|
|
429
|
+
break;
|
|
430
|
+
}
|
|
431
|
+
executed++;
|
|
313
432
|
try {
|
|
314
|
-
|
|
433
|
+
snapshot[i3]();
|
|
315
434
|
} catch (err) {
|
|
316
|
-
|
|
317
|
-
console.warn("[SibuJS] Disposer threw during cleanup:", err);
|
|
318
|
-
}
|
|
435
|
+
reportError(err, { phase: "cleanup", name: "disposer" });
|
|
319
436
|
}
|
|
320
437
|
}
|
|
321
438
|
}
|
|
322
439
|
}
|
|
323
440
|
}
|
|
324
441
|
}
|
|
442
|
+
function replaceChildrenSafely(parent, ...next) {
|
|
443
|
+
for (let i2 = 0; i2 < next.length; i2++) {
|
|
444
|
+
const node = next[i2];
|
|
445
|
+
node.parentNode?.removeChild(node);
|
|
446
|
+
}
|
|
447
|
+
const current = Array.from(parent.childNodes);
|
|
448
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
449
|
+
dispose(current[i2]);
|
|
450
|
+
}
|
|
451
|
+
parent.replaceChildren(...next);
|
|
452
|
+
}
|
|
325
453
|
function checkLeaks(warnThreshold = 0) {
|
|
326
454
|
if (!_isDev2) return 0;
|
|
327
455
|
if (warnThreshold > 0 && activeBindingCount > warnThreshold) {
|
|
@@ -342,10 +470,12 @@ function isEventHandlerAttr(name) {
|
|
|
342
470
|
return lower[0] === "o" && lower[1] === "n" && lower.charCodeAt(2) >= 97 && lower.charCodeAt(2) <= 122;
|
|
343
471
|
}
|
|
344
472
|
var SAFE_URL_PROTOCOLS = ["http:", "https:", "mailto:", "tel:", "ftp:"];
|
|
473
|
+
var OUTER_TRIM = /^[\x00-\x20\x7f-\x9f]+|[\x00-\x20\x7f-\x9f]+$/g;
|
|
345
474
|
function sanitizeUrl(url) {
|
|
346
|
-
const
|
|
347
|
-
if (!
|
|
348
|
-
const
|
|
475
|
+
const probe = stripControlChars(url).trim();
|
|
476
|
+
if (!probe) return "";
|
|
477
|
+
const output2 = url.replace(OUTER_TRIM, "");
|
|
478
|
+
const lower = probe.toLowerCase();
|
|
349
479
|
let schemeEnd = -1;
|
|
350
480
|
for (let i2 = 0; i2 < lower.length; i2++) {
|
|
351
481
|
const ch = lower.charCodeAt(i2);
|
|
@@ -355,12 +485,13 @@ function sanitizeUrl(url) {
|
|
|
355
485
|
}
|
|
356
486
|
if (ch === 47 || ch === 63 || ch === 35) break;
|
|
357
487
|
}
|
|
358
|
-
if (schemeEnd === -1) return
|
|
488
|
+
if (schemeEnd === -1) return output2;
|
|
359
489
|
const scheme = lower.slice(0, schemeEnd + 1);
|
|
360
|
-
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return
|
|
490
|
+
if (!/^[a-z][a-z0-9+.-]*:$/.test(scheme)) return output2;
|
|
361
491
|
if (SAFE_URL_PROTOCOLS.indexOf(scheme) === -1) return "";
|
|
362
|
-
return
|
|
492
|
+
return output2;
|
|
363
493
|
}
|
|
494
|
+
var SRCSET_DESCRIPTOR = /^\s+\d+(\.\d+)?[wx]$/;
|
|
364
495
|
function sanitizeSrcset(value) {
|
|
365
496
|
const parts = value.split(",");
|
|
366
497
|
const out = [];
|
|
@@ -369,6 +500,7 @@ function sanitizeSrcset(value) {
|
|
|
369
500
|
if (!part) continue;
|
|
370
501
|
const m = part.match(/^(\S+)(\s+.+)?$/);
|
|
371
502
|
if (!m) continue;
|
|
503
|
+
if (m[2] !== void 0 && !SRCSET_DESCRIPTOR.test(m[2])) continue;
|
|
372
504
|
const safe = sanitizeUrl(m[1]);
|
|
373
505
|
if (!safe) continue;
|
|
374
506
|
out.push(m[2] ? `${safe}${m[2]}` : safe);
|
|
@@ -376,23 +508,83 @@ function sanitizeSrcset(value) {
|
|
|
376
508
|
return out.join(", ");
|
|
377
509
|
}
|
|
378
510
|
var CSS_DANGER_GATE = /[(:@\\]/;
|
|
511
|
+
function isCssWhitespace(ch) {
|
|
512
|
+
return ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f";
|
|
513
|
+
}
|
|
514
|
+
function isHexDigit(ch) {
|
|
515
|
+
return ch >= "0" && ch <= "9" || ch >= "a" && ch <= "f" || ch >= "A" && ch <= "F";
|
|
516
|
+
}
|
|
517
|
+
function decodeCssEscapes(value) {
|
|
518
|
+
let out = "";
|
|
519
|
+
for (let i2 = 0; i2 < value.length; i2++) {
|
|
520
|
+
const ch = value[i2];
|
|
521
|
+
if (ch !== "\\") {
|
|
522
|
+
out += ch;
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
if (i2 + 1 >= value.length) break;
|
|
526
|
+
const next = value[i2 + 1];
|
|
527
|
+
if (next === "\n" || next === "\f") {
|
|
528
|
+
i2 += 1;
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
if (next === "\r") {
|
|
532
|
+
i2 += value[i2 + 2] === "\n" ? 2 : 1;
|
|
533
|
+
continue;
|
|
534
|
+
}
|
|
535
|
+
if (isHexDigit(next)) {
|
|
536
|
+
let hex = "";
|
|
537
|
+
let j = i2 + 1;
|
|
538
|
+
while (j < value.length && hex.length < 6 && isHexDigit(value[j])) {
|
|
539
|
+
hex += value[j];
|
|
540
|
+
j++;
|
|
541
|
+
}
|
|
542
|
+
if (j < value.length && isCssWhitespace(value[j])) {
|
|
543
|
+
j += value[j] === "\r" && value[j + 1] === "\n" ? 2 : 1;
|
|
544
|
+
}
|
|
545
|
+
const code2 = Number.parseInt(hex, 16);
|
|
546
|
+
const invalid = code2 === 0 || code2 > 1114111 || code2 >= 55296 && code2 <= 57343;
|
|
547
|
+
out += invalid ? "\uFFFD" : String.fromCodePoint(code2);
|
|
548
|
+
i2 = j - 1;
|
|
549
|
+
continue;
|
|
550
|
+
}
|
|
551
|
+
out += next;
|
|
552
|
+
i2 += 1;
|
|
553
|
+
}
|
|
554
|
+
return out;
|
|
555
|
+
}
|
|
379
556
|
function sanitizeCSSValue(value) {
|
|
380
557
|
if (!CSS_DANGER_GATE.test(value)) return value;
|
|
381
|
-
const
|
|
382
|
-
|
|
383
|
-
if (!Number.isFinite(code2) || code2 < 0 || code2 > 1114111) return "";
|
|
384
|
-
try {
|
|
385
|
-
return String.fromCodePoint(code2);
|
|
386
|
-
} catch {
|
|
387
|
-
return "";
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
const lower = decoded.toLowerCase().replace(/\s+/g, "");
|
|
558
|
+
const normalized = value.includes("\\") ? decodeCssEscapes(value) : value;
|
|
559
|
+
const lower = normalized.toLowerCase().replace(/\s+/g, "");
|
|
391
560
|
if (lower.includes("url(") || lower.includes("expression(") || lower.includes("javascript:") || lower.includes("vbscript:") || lower.includes("-moz-binding") || lower.includes("behavior:") || lower.includes("@import") || lower.includes("image-set(") || lower.includes("filter:progid")) {
|
|
392
561
|
return "";
|
|
393
562
|
}
|
|
394
563
|
return value;
|
|
395
564
|
}
|
|
565
|
+
function sanitizeStyleAttribute(cssText) {
|
|
566
|
+
const input2 = String(cssText);
|
|
567
|
+
if (input2.trim() === "") return "";
|
|
568
|
+
if (typeof document === "undefined") {
|
|
569
|
+
return sanitizeCSSValue(input2) === "" ? "" : input2;
|
|
570
|
+
}
|
|
571
|
+
const probe = document.createElement("div");
|
|
572
|
+
try {
|
|
573
|
+
probe.style.cssText = input2;
|
|
574
|
+
} catch {
|
|
575
|
+
return "";
|
|
576
|
+
}
|
|
577
|
+
const declarations = [];
|
|
578
|
+
for (let i2 = 0; i2 < probe.style.length; i2++) {
|
|
579
|
+
const property = probe.style[i2];
|
|
580
|
+
const value = probe.style.getPropertyValue(property);
|
|
581
|
+
if (sanitizeCSSValue(value) === "") continue;
|
|
582
|
+
if (sanitizeCSSValue(`${property}:${value}`) === "") continue;
|
|
583
|
+
const priority = probe.style.getPropertyPriority(property);
|
|
584
|
+
declarations.push(`${property}: ${value}${priority ? ` !${priority}` : ""}`);
|
|
585
|
+
}
|
|
586
|
+
return declarations.join("; ");
|
|
587
|
+
}
|
|
396
588
|
var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
397
589
|
"href",
|
|
398
590
|
"xlink:href",
|
|
@@ -405,20 +597,101 @@ var URL_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
|
405
597
|
"background",
|
|
406
598
|
"srcset",
|
|
407
599
|
"ping",
|
|
408
|
-
"data"
|
|
600
|
+
"data",
|
|
601
|
+
// `<html manifest>` is a URL sink too. It was carried only by the SSR
|
|
602
|
+
// serializers' private copy of this set; folding that copy into this one would
|
|
603
|
+
// otherwise have silently dropped its coverage.
|
|
604
|
+
"manifest"
|
|
409
605
|
]);
|
|
410
|
-
|
|
411
|
-
|
|
606
|
+
var HTML_CONTENT_ATTRIBUTES = /* @__PURE__ */ new Set(["srcdoc"]);
|
|
607
|
+
function isHtmlContentAttribute(name) {
|
|
608
|
+
return HTML_CONTENT_ATTRIBUTES.has(name.toLowerCase());
|
|
412
609
|
}
|
|
413
610
|
function sanitizeAttributeString(attr, value) {
|
|
414
611
|
const lower = attr.toLowerCase();
|
|
415
612
|
if (lower === "srcset") return sanitizeSrcset(value);
|
|
416
613
|
if (URL_ATTRIBUTES.has(lower)) return sanitizeUrl(value);
|
|
614
|
+
if (lower === "style") return sanitizeStyleAttribute(value);
|
|
417
615
|
return value;
|
|
418
616
|
}
|
|
419
617
|
|
|
420
|
-
// src/
|
|
618
|
+
// src/utils/setSafeAttribute.ts
|
|
421
619
|
var _isDev3 = isDev();
|
|
620
|
+
var HTML_NS = "http://www.w3.org/1999/xhtml";
|
|
621
|
+
var SVG_NS = "http://www.w3.org/2000/svg";
|
|
622
|
+
var XLINK_NS = "http://www.w3.org/1999/xlink";
|
|
623
|
+
var XML_NS = "http://www.w3.org/XML/1998/namespace";
|
|
624
|
+
var BOOLEAN_IDL_ATTRS = /* @__PURE__ */ new Set(["checked", "disabled", "selected"]);
|
|
625
|
+
function isHtmlElement(el) {
|
|
626
|
+
return el.namespaceURI === null || el.namespaceURI === HTML_NS;
|
|
627
|
+
}
|
|
628
|
+
function setProp(el, key, val) {
|
|
629
|
+
el[key] = val;
|
|
630
|
+
}
|
|
631
|
+
function namespaceFor(el, name) {
|
|
632
|
+
if (el.namespaceURI !== SVG_NS) return null;
|
|
633
|
+
const lower = name.toLowerCase();
|
|
634
|
+
if (lower.startsWith("xlink:")) return XLINK_NS;
|
|
635
|
+
if (lower.startsWith("xml:")) return XML_NS;
|
|
636
|
+
return null;
|
|
637
|
+
}
|
|
638
|
+
function setSafeAttribute(el, name, value, options = {}) {
|
|
639
|
+
const ns = namespaceFor(el, name);
|
|
640
|
+
const localName = ns ? name.slice(name.indexOf(":") + 1) : name;
|
|
641
|
+
if (isEventHandlerAttr(name)) {
|
|
642
|
+
if (_isDev3) {
|
|
643
|
+
devWarn(
|
|
644
|
+
`${options.label ?? "setSafeAttribute"}: refusing to set event-handler attribute "${name}". Its value would be evaluated as JavaScript. Use on:{ ${name.slice(2)}: fn } instead.`
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
648
|
+
else el.removeAttribute(name);
|
|
649
|
+
return false;
|
|
650
|
+
}
|
|
651
|
+
if (value == null) {
|
|
652
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
653
|
+
else el.removeAttribute(name);
|
|
654
|
+
return true;
|
|
655
|
+
}
|
|
656
|
+
if (isHtmlContentAttribute(name)) {
|
|
657
|
+
if (_isDev3) {
|
|
658
|
+
devWarn(
|
|
659
|
+
`${options.label ?? "setSafeAttribute"}: refusing to set "${name}". The browser parses this attribute as a nested HTML document, so a generic string value cannot be made safe \u2014 attribute escaping is undone before the parse. Build the frame's content another way.`
|
|
660
|
+
);
|
|
661
|
+
}
|
|
662
|
+
if (ns) el.removeAttributeNS(ns, localName);
|
|
663
|
+
else el.removeAttribute(name);
|
|
664
|
+
return false;
|
|
665
|
+
}
|
|
666
|
+
const html3 = isHtmlElement(el);
|
|
667
|
+
const idlName = html3 ? name.toLowerCase() : name;
|
|
668
|
+
if (typeof value === "boolean") {
|
|
669
|
+
if (html3 && BOOLEAN_IDL_ATTRS.has(idlName) && idlName in el) {
|
|
670
|
+
setProp(el, idlName, value);
|
|
671
|
+
} else if (value) {
|
|
672
|
+
if (ns) el.setAttributeNS(ns, name, "");
|
|
673
|
+
else el.setAttribute(name, "");
|
|
674
|
+
} else if (ns) {
|
|
675
|
+
el.removeAttributeNS(ns, localName);
|
|
676
|
+
} else {
|
|
677
|
+
el.removeAttribute(name);
|
|
678
|
+
}
|
|
679
|
+
return true;
|
|
680
|
+
}
|
|
681
|
+
const str = String(value);
|
|
682
|
+
if (options.syncValueProperty !== false && html3 && (idlName === "value" || idlName === "checked") && idlName in el) {
|
|
683
|
+
setProp(el, idlName, idlName === "checked" ? Boolean(value) : str);
|
|
684
|
+
return true;
|
|
685
|
+
}
|
|
686
|
+
const safe = sanitizeAttributeString(name, str);
|
|
687
|
+
const current = ns ? el.getAttributeNS(ns, localName) : el.getAttribute(name);
|
|
688
|
+
if (current === safe) return true;
|
|
689
|
+
if (ns) el.setAttributeNS(ns, name, safe);
|
|
690
|
+
else el.setAttribute(name, safe);
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// src/reactivity/track-core.ts
|
|
422
695
|
var POOL_MAX = 4096;
|
|
423
696
|
var nodePool = [];
|
|
424
697
|
function createNode() {
|
|
@@ -426,6 +699,7 @@ function createNode() {
|
|
|
426
699
|
sig: null,
|
|
427
700
|
sub: null,
|
|
428
701
|
epoch: 0,
|
|
702
|
+
depVersion: 0,
|
|
429
703
|
sigPrev: null,
|
|
430
704
|
sigNext: null,
|
|
431
705
|
subPrev: null,
|
|
@@ -510,8 +784,27 @@ function safeInvoke(sub2) {
|
|
|
510
784
|
try {
|
|
511
785
|
sub2();
|
|
512
786
|
} catch (err) {
|
|
513
|
-
|
|
787
|
+
const s2 = sub2;
|
|
788
|
+
reportError(err, { phase: s2._errorPhase ?? "effect", name: s2.__name, node: s2._errorNode });
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
function depsChanged(sub2) {
|
|
792
|
+
let node = sub2.depsHead ?? null;
|
|
793
|
+
if (node === null) return true;
|
|
794
|
+
while (node !== null) {
|
|
795
|
+
const sig = node.sig;
|
|
796
|
+
if (sig === null) return true;
|
|
797
|
+
if (sig._d === true && sig._validate !== void 0) {
|
|
798
|
+
try {
|
|
799
|
+
sig._validate();
|
|
800
|
+
} catch {
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
if (node.depVersion !== sig.__v) return true;
|
|
805
|
+
node = node.subNext;
|
|
514
806
|
}
|
|
807
|
+
return false;
|
|
515
808
|
}
|
|
516
809
|
var suspendDepth = 0;
|
|
517
810
|
var trackingSuspended = false;
|
|
@@ -593,7 +886,7 @@ function track(effectFn, subscriber) {
|
|
|
593
886
|
const sub2 = subscriber;
|
|
594
887
|
return sub2._dispose ?? (sub2._dispose = () => cleanup(subscriber));
|
|
595
888
|
}
|
|
596
|
-
function reactiveBinding(commit) {
|
|
889
|
+
function reactiveBinding(commit, ownerNode) {
|
|
597
890
|
const run = () => {
|
|
598
891
|
const s2 = subscriber;
|
|
599
892
|
if (s2._disposed || s2._reentrant) return;
|
|
@@ -609,13 +902,17 @@ function reactiveBinding(commit) {
|
|
|
609
902
|
subscriber.depsTail = null;
|
|
610
903
|
subscriber._epoch = 0;
|
|
611
904
|
subscriber._structDirty = false;
|
|
905
|
+
subscriber._hasComputedDep = false;
|
|
612
906
|
subscriber._runEpoch = 0;
|
|
613
907
|
subscriber._runs = 0;
|
|
614
908
|
subscriber._reentrant = false;
|
|
615
909
|
subscriber._disposed = false;
|
|
910
|
+
subscriber._errorPhase = "binding";
|
|
911
|
+
subscriber._errorNode = ownerNode;
|
|
616
912
|
run();
|
|
617
913
|
return subscriber._dispose ?? (subscriber._dispose = () => {
|
|
618
914
|
subscriber._disposed = true;
|
|
915
|
+
subscriber._errorNode = void 0;
|
|
619
916
|
cleanup(subscriber);
|
|
620
917
|
});
|
|
621
918
|
}
|
|
@@ -627,9 +924,12 @@ function recordDependency(signal2) {
|
|
|
627
924
|
const active = sig.__activeNode ?? null;
|
|
628
925
|
if (active !== null && active.sub === sub2) {
|
|
629
926
|
active.epoch = epoch;
|
|
927
|
+
active.depVersion = sig.__v ?? Number.NaN;
|
|
630
928
|
return;
|
|
631
929
|
}
|
|
930
|
+
if (sig._validate !== void 0) sub2._hasComputedDep = true;
|
|
632
931
|
const node = allocNode(signal2, sub2, epoch);
|
|
932
|
+
node.depVersion = sig.__v ?? Number.NaN;
|
|
633
933
|
node.prevActive = active;
|
|
634
934
|
sig.__activeNode = node;
|
|
635
935
|
linkSub(sub2, node);
|
|
@@ -648,9 +948,10 @@ function cleanup(subscriber) {
|
|
|
648
948
|
node = next;
|
|
649
949
|
}
|
|
650
950
|
}
|
|
651
|
-
var maxSubscriberRepeats =
|
|
951
|
+
var maxSubscriberRepeats = 1e3;
|
|
652
952
|
var maxDrainIterations = 1e6;
|
|
653
953
|
var drainEpoch = 0;
|
|
954
|
+
var quarantined = /* @__PURE__ */ new Set();
|
|
654
955
|
function setMaxSubscriberRepeats(n) {
|
|
655
956
|
const prev = maxSubscriberRepeats;
|
|
656
957
|
if (Number.isFinite(n) && n > 0) maxSubscriberRepeats = Math.floor(n);
|
|
@@ -672,19 +973,21 @@ function tickRepeat(sub2) {
|
|
|
672
973
|
return s2._runs > maxSubscriberRepeats;
|
|
673
974
|
}
|
|
674
975
|
function cycleError(sub2) {
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
`
|
|
679
|
-
)
|
|
680
|
-
|
|
976
|
+
const name = sub2.__name ?? "<unnamed>";
|
|
977
|
+
reportError(
|
|
978
|
+
new Error(
|
|
979
|
+
`subscriber "${name}" fired more than ${maxSubscriberRepeats} times \u2014 likely a write-reads-self cycle between effects/signals. This subscriber is quarantined for the rest of this update; other pending work still runs.`
|
|
980
|
+
),
|
|
981
|
+
{ phase: "scheduler", name }
|
|
982
|
+
);
|
|
681
983
|
}
|
|
682
984
|
function absoluteDrainError() {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
`
|
|
686
|
-
)
|
|
687
|
-
|
|
985
|
+
reportError(
|
|
986
|
+
new Error(
|
|
987
|
+
`Notification drain exceeded ${maxDrainIterations} iterations \u2014 absolute safety net tripped. Breaking to prevent infinite loop.`
|
|
988
|
+
),
|
|
989
|
+
{ phase: "scheduler" }
|
|
990
|
+
);
|
|
688
991
|
}
|
|
689
992
|
function drainQueue() {
|
|
690
993
|
let i2 = 0;
|
|
@@ -694,11 +997,14 @@ function drainQueue() {
|
|
|
694
997
|
break;
|
|
695
998
|
}
|
|
696
999
|
const sub2 = pendingQueue[i2++];
|
|
1000
|
+
pendingSet.delete(sub2);
|
|
1001
|
+
if (quarantined.size > 0 && quarantined.has(sub2)) continue;
|
|
1002
|
+
if (sub2._hasComputedDep === true && !depsChanged(sub2)) continue;
|
|
697
1003
|
if (tickRepeat(sub2)) {
|
|
698
1004
|
cycleError(sub2);
|
|
699
|
-
|
|
1005
|
+
quarantined.add(sub2);
|
|
1006
|
+
continue;
|
|
700
1007
|
}
|
|
701
|
-
pendingSet.delete(sub2);
|
|
702
1008
|
safeInvoke(sub2);
|
|
703
1009
|
}
|
|
704
1010
|
}
|
|
@@ -713,6 +1019,7 @@ function drainNotificationQueue() {
|
|
|
713
1019
|
if (notifyDepth === 0) {
|
|
714
1020
|
pendingQueue.length = 0;
|
|
715
1021
|
pendingSet.clear();
|
|
1022
|
+
if (quarantined.size > 0) quarantined.clear();
|
|
716
1023
|
}
|
|
717
1024
|
}
|
|
718
1025
|
}
|
|
@@ -806,6 +1113,7 @@ function notifySubscribers(signal2) {
|
|
|
806
1113
|
if (notifyDepth === 0) {
|
|
807
1114
|
pendingQueue.length = 0;
|
|
808
1115
|
pendingSet.clear();
|
|
1116
|
+
if (quarantined.size > 0) quarantined.clear();
|
|
809
1117
|
}
|
|
810
1118
|
}
|
|
811
1119
|
}
|
|
@@ -833,7 +1141,7 @@ function forEachSubscriber(signal2, visit) {
|
|
|
833
1141
|
|
|
834
1142
|
// src/reactivity/track.ts
|
|
835
1143
|
var _isDev4 = isDev();
|
|
836
|
-
var _runtimeVersion = true ? "
|
|
1144
|
+
var _runtimeVersion = true ? "4.0.0" : "dev";
|
|
837
1145
|
var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
|
|
838
1146
|
function resolveReactiveApi() {
|
|
839
1147
|
const g2 = globalThis;
|
|
@@ -890,16 +1198,9 @@ var getSubscriberDeps2 = API.getSubscriberDeps;
|
|
|
890
1198
|
var forEachSubscriber2 = API.forEachSubscriber;
|
|
891
1199
|
|
|
892
1200
|
// src/reactivity/bindAttribute.ts
|
|
893
|
-
var _isDev5 = isDev();
|
|
894
|
-
function setProp(el, key, val) {
|
|
895
|
-
el[key] = val;
|
|
896
|
-
}
|
|
897
1201
|
function bindAttribute(el, attr, getter) {
|
|
898
1202
|
if (isEventHandlerAttr(attr)) {
|
|
899
|
-
|
|
900
|
-
devWarn(
|
|
901
|
-
`bindAttribute: refusing to bind event-handler attribute "${attr}". Use on:{ ${attr.slice(2)}: fn } instead.`
|
|
902
|
-
);
|
|
1203
|
+
setSafeAttribute(el, attr, "", { label: `bindAttribute("${attr}")` });
|
|
903
1204
|
return () => {
|
|
904
1205
|
};
|
|
905
1206
|
}
|
|
@@ -908,28 +1209,12 @@ function bindAttribute(el, attr, getter) {
|
|
|
908
1209
|
try {
|
|
909
1210
|
value = getter();
|
|
910
1211
|
} catch (err) {
|
|
911
|
-
|
|
912
|
-
devWarn(`bindAttribute: getter for "${attr}" threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
1212
|
+
reportError(err, { phase: "binding", name: `bindAttribute("${attr}")`, node: el });
|
|
913
1213
|
return;
|
|
914
1214
|
}
|
|
915
|
-
|
|
916
|
-
if (attr in el && (attr === "checked" || attr === "disabled" || attr === "selected")) {
|
|
917
|
-
setProp(el, attr, value);
|
|
918
|
-
} else if (value) {
|
|
919
|
-
el.setAttribute(attr, "");
|
|
920
|
-
} else {
|
|
921
|
-
el.removeAttribute(attr);
|
|
922
|
-
}
|
|
923
|
-
return;
|
|
924
|
-
}
|
|
925
|
-
const str = String(value);
|
|
926
|
-
if ((attr === "value" || attr === "checked") && attr in el) {
|
|
927
|
-
setProp(el, attr, attr === "checked" ? Boolean(value) : str);
|
|
928
|
-
} else {
|
|
929
|
-
el.setAttribute(attr, sanitizeAttributeString(attr, str));
|
|
930
|
-
}
|
|
1215
|
+
setSafeAttribute(el, attr, value, { label: `bindAttribute("${attr}")` });
|
|
931
1216
|
}
|
|
932
|
-
return reactiveBinding2(commit);
|
|
1217
|
+
return reactiveBinding2(commit, el);
|
|
933
1218
|
}
|
|
934
1219
|
function bindDynamic(el, nameGetter, valueGetter) {
|
|
935
1220
|
let prevName = null;
|
|
@@ -938,29 +1223,24 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
938
1223
|
try {
|
|
939
1224
|
name = typeof nameGetter === "function" ? nameGetter() : nameGetter;
|
|
940
1225
|
} catch (err) {
|
|
941
|
-
|
|
1226
|
+
reportError(err, { phase: "binding", name: "bindDynamic (name getter)", node: el });
|
|
942
1227
|
return;
|
|
943
1228
|
}
|
|
944
1229
|
let value;
|
|
945
1230
|
try {
|
|
946
1231
|
value = typeof valueGetter === "function" ? valueGetter() : valueGetter;
|
|
947
1232
|
} catch (err) {
|
|
948
|
-
|
|
1233
|
+
reportError(err, { phase: "binding", name: "bindDynamic (value getter)", node: el });
|
|
949
1234
|
return;
|
|
950
1235
|
}
|
|
951
|
-
if (isEventHandlerAttr(name)) return;
|
|
952
1236
|
if (prevName !== null && prevName !== name) {
|
|
953
1237
|
el.removeAttribute(prevName);
|
|
1238
|
+
prevName = null;
|
|
954
1239
|
}
|
|
955
|
-
|
|
956
|
-
if ((name === "value" || name === "checked") && name in el) {
|
|
957
|
-
setProp(el, name, name === "checked" ? Boolean(value) : str);
|
|
958
|
-
} else {
|
|
959
|
-
el.setAttribute(name, sanitizeAttributeString(name, str));
|
|
960
|
-
}
|
|
1240
|
+
if (!setSafeAttribute(el, name, value, { label: "bindDynamic" })) return;
|
|
961
1241
|
prevName = name;
|
|
962
1242
|
}
|
|
963
|
-
const teardown = reactiveBinding2(commit);
|
|
1243
|
+
const teardown = reactiveBinding2(commit, el);
|
|
964
1244
|
return () => {
|
|
965
1245
|
teardown();
|
|
966
1246
|
if (prevName !== null) {
|
|
@@ -970,7 +1250,7 @@ function bindDynamic(el, nameGetter, valueGetter) {
|
|
|
970
1250
|
}
|
|
971
1251
|
|
|
972
1252
|
// src/reactivity/bindChildNode.ts
|
|
973
|
-
var
|
|
1253
|
+
var _isDev5 = isDev();
|
|
974
1254
|
function bindChildNode(placeholder, getter) {
|
|
975
1255
|
let lastNodes = [];
|
|
976
1256
|
function commit() {
|
|
@@ -978,7 +1258,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
978
1258
|
try {
|
|
979
1259
|
result = getter();
|
|
980
1260
|
} catch (err) {
|
|
981
|
-
|
|
1261
|
+
reportError(err, { phase: "binding", name: "bindChildNode", node: placeholder });
|
|
982
1262
|
return;
|
|
983
1263
|
}
|
|
984
1264
|
if (result == null || typeof result === "boolean") {
|
|
@@ -1004,7 +1284,7 @@ function bindChildNode(placeholder, getter) {
|
|
|
1004
1284
|
if (item == null || typeof item === "boolean") continue;
|
|
1005
1285
|
const node = item instanceof Node ? item : document.createTextNode(String(item));
|
|
1006
1286
|
if (seen.has(node)) {
|
|
1007
|
-
if (
|
|
1287
|
+
if (_isDev5)
|
|
1008
1288
|
devWarn("bindChildNode: duplicate node reference in array \u2014 only the first occurrence is rendered.");
|
|
1009
1289
|
continue;
|
|
1010
1290
|
}
|
|
@@ -1039,12 +1319,12 @@ function bindChildNode(placeholder, getter) {
|
|
|
1039
1319
|
}
|
|
1040
1320
|
lastNodes = newNodes;
|
|
1041
1321
|
}
|
|
1042
|
-
return reactiveBinding2(commit);
|
|
1322
|
+
return reactiveBinding2(commit, placeholder);
|
|
1043
1323
|
}
|
|
1044
1324
|
|
|
1045
1325
|
// src/core/rendering/tagFactory.ts
|
|
1046
|
-
var
|
|
1047
|
-
var
|
|
1326
|
+
var SVG_NS2 = "http://www.w3.org/2000/svg";
|
|
1327
|
+
var _isDev6 = isDev();
|
|
1048
1328
|
var BLOCKED_TAGS = /* @__PURE__ */ new Set(["script", "iframe", "object", "embed", "frame", "frameset"]);
|
|
1049
1329
|
function isBlockedTag(tag) {
|
|
1050
1330
|
return BLOCKED_TAGS.has(tag.toLowerCase());
|
|
@@ -1062,9 +1342,6 @@ var CLOBBER_RISKY_IDS = /* @__PURE__ */ new Set([
|
|
|
1062
1342
|
"self",
|
|
1063
1343
|
"frames"
|
|
1064
1344
|
]);
|
|
1065
|
-
function setProp2(el, key, val) {
|
|
1066
|
-
el[key] = val;
|
|
1067
|
-
}
|
|
1068
1345
|
function looksLikeClassList(s2) {
|
|
1069
1346
|
const t = s2.trim();
|
|
1070
1347
|
if (!t) return false;
|
|
@@ -1088,13 +1365,13 @@ function toKebab(prop) {
|
|
|
1088
1365
|
function applyStyle(el, style2) {
|
|
1089
1366
|
if (typeof style2 === "function") {
|
|
1090
1367
|
const teardown = track2(() => {
|
|
1091
|
-
el.setAttribute("style", style2());
|
|
1368
|
+
el.setAttribute("style", sanitizeStyleAttribute(String(style2())));
|
|
1092
1369
|
});
|
|
1093
1370
|
registerDisposer(el, teardown);
|
|
1094
1371
|
return;
|
|
1095
1372
|
}
|
|
1096
1373
|
if (typeof style2 === "string") {
|
|
1097
|
-
el.setAttribute("style", style2);
|
|
1374
|
+
el.setAttribute("style", sanitizeStyleAttribute(style2));
|
|
1098
1375
|
return;
|
|
1099
1376
|
}
|
|
1100
1377
|
const htmlEl = el;
|
|
@@ -1215,7 +1492,7 @@ var tagFactory = (tag, ns) => {
|
|
|
1215
1492
|
appendChildren(el, second);
|
|
1216
1493
|
return el;
|
|
1217
1494
|
}
|
|
1218
|
-
if (
|
|
1495
|
+
if (_isDev6 && looksLikeClassList(first)) {
|
|
1219
1496
|
devWarn(
|
|
1220
1497
|
`tagFactory: lone string "${first}" looks like a class list but is being rendered as TEXT. For a class, use ${tag}({ class: "${first}" }) \u2014 or ${tag}("${first}", children) to set the class AND add children.`
|
|
1221
1498
|
);
|
|
@@ -1236,7 +1513,7 @@ var tagFactory = (tag, ns) => {
|
|
|
1236
1513
|
if (pClass != null) applyClass(el, pClass);
|
|
1237
1514
|
const pId = props.id;
|
|
1238
1515
|
if (pId != null) {
|
|
1239
|
-
if (
|
|
1516
|
+
if (_isDev6 && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
|
|
1240
1517
|
devWarn(
|
|
1241
1518
|
`tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
|
|
1242
1519
|
);
|
|
@@ -1251,7 +1528,7 @@ var tagFactory = (tag, ns) => {
|
|
|
1251
1528
|
const handler = pOn[ev];
|
|
1252
1529
|
if (typeof handler === "function") {
|
|
1253
1530
|
el.addEventListener(ev, handler);
|
|
1254
|
-
} else if (
|
|
1531
|
+
} else if (_isDev6) {
|
|
1255
1532
|
devWarn(
|
|
1256
1533
|
`tagFactory: on.${ev} handler is not a function (got ${typeof handler}). Event listener was not attached.`
|
|
1257
1534
|
);
|
|
@@ -1279,16 +1556,8 @@ var tagFactory = (tag, ns) => {
|
|
|
1279
1556
|
if (isEventHandlerAttr(key)) continue;
|
|
1280
1557
|
if (typeof value === "function") {
|
|
1281
1558
|
registerDisposer(el, bindAttribute(el, key, value));
|
|
1282
|
-
} else if (typeof value === "boolean") {
|
|
1283
|
-
if (key in el && (key === "checked" || key === "disabled" || key === "selected")) {
|
|
1284
|
-
setProp2(el, key, value);
|
|
1285
|
-
} else if (value) {
|
|
1286
|
-
el.setAttribute(key, "");
|
|
1287
|
-
} else {
|
|
1288
|
-
el.removeAttribute(key);
|
|
1289
|
-
}
|
|
1290
1559
|
} else {
|
|
1291
|
-
el
|
|
1560
|
+
setSafeAttribute(el, key, value, { syncValueProperty: false, label: "tagFactory" });
|
|
1292
1561
|
}
|
|
1293
1562
|
}
|
|
1294
1563
|
}
|
|
@@ -1373,7 +1642,7 @@ var param = tagFactory("param");
|
|
|
1373
1642
|
var picture = tagFactory("picture");
|
|
1374
1643
|
var portal = tagFactory("portal");
|
|
1375
1644
|
var source = tagFactory("source");
|
|
1376
|
-
var svg = tagFactory("svg",
|
|
1645
|
+
var svg = tagFactory("svg", SVG_NS2);
|
|
1377
1646
|
var math = tagFactory("math");
|
|
1378
1647
|
var canvas = tagFactory("canvas");
|
|
1379
1648
|
var noscript = tagFactory("noscript");
|
|
@@ -1414,26 +1683,26 @@ var base = tagFactory("base");
|
|
|
1414
1683
|
var link = tagFactory("link");
|
|
1415
1684
|
var meta = tagFactory("meta");
|
|
1416
1685
|
var style = tagFactory("style");
|
|
1417
|
-
var circle = tagFactory("circle",
|
|
1418
|
-
var ellipse = tagFactory("ellipse",
|
|
1419
|
-
var g = tagFactory("g",
|
|
1420
|
-
var line = tagFactory("line",
|
|
1421
|
-
var path = tagFactory("path",
|
|
1422
|
-
var polygon = tagFactory("polygon",
|
|
1423
|
-
var polyline = tagFactory("polyline",
|
|
1424
|
-
var rect = tagFactory("rect",
|
|
1425
|
-
var text = tagFactory("text",
|
|
1426
|
-
var tspan = tagFactory("tspan",
|
|
1427
|
-
var defs = tagFactory("defs",
|
|
1428
|
-
var clipPath = tagFactory("clipPath",
|
|
1429
|
-
var mask = tagFactory("mask",
|
|
1430
|
-
var pattern = tagFactory("pattern",
|
|
1431
|
-
var linearGradient = tagFactory("linearGradient",
|
|
1432
|
-
var radialGradient = tagFactory("radialGradient",
|
|
1433
|
-
var stop = tagFactory("stop",
|
|
1434
|
-
var use = tagFactory("use",
|
|
1435
|
-
var symbol = tagFactory("symbol",
|
|
1436
|
-
var marker = tagFactory("marker",
|
|
1686
|
+
var circle = tagFactory("circle", SVG_NS2);
|
|
1687
|
+
var ellipse = tagFactory("ellipse", SVG_NS2);
|
|
1688
|
+
var g = tagFactory("g", SVG_NS2);
|
|
1689
|
+
var line = tagFactory("line", SVG_NS2);
|
|
1690
|
+
var path = tagFactory("path", SVG_NS2);
|
|
1691
|
+
var polygon = tagFactory("polygon", SVG_NS2);
|
|
1692
|
+
var polyline = tagFactory("polyline", SVG_NS2);
|
|
1693
|
+
var rect = tagFactory("rect", SVG_NS2);
|
|
1694
|
+
var text = tagFactory("text", SVG_NS2);
|
|
1695
|
+
var tspan = tagFactory("tspan", SVG_NS2);
|
|
1696
|
+
var defs = tagFactory("defs", SVG_NS2);
|
|
1697
|
+
var clipPath = tagFactory("clipPath", SVG_NS2);
|
|
1698
|
+
var mask = tagFactory("mask", SVG_NS2);
|
|
1699
|
+
var pattern = tagFactory("pattern", SVG_NS2);
|
|
1700
|
+
var linearGradient = tagFactory("linearGradient", SVG_NS2);
|
|
1701
|
+
var radialGradient = tagFactory("radialGradient", SVG_NS2);
|
|
1702
|
+
var stop = tagFactory("stop", SVG_NS2);
|
|
1703
|
+
var use = tagFactory("use", SVG_NS2);
|
|
1704
|
+
var symbol = tagFactory("symbol", SVG_NS2);
|
|
1705
|
+
var marker = tagFactory("marker", SVG_NS2);
|
|
1437
1706
|
var center = tagFactory("center");
|
|
1438
1707
|
var font = tagFactory("font");
|
|
1439
1708
|
var marquee = tagFactory("marquee");
|
|
@@ -1442,18 +1711,14 @@ var customElement = (tagName) => tagFactory(tagName);
|
|
|
1442
1711
|
// src/core/rendering/lazy.ts
|
|
1443
1712
|
var PENDING_ERROR = "__sibuPendingError";
|
|
1444
1713
|
function dispatchPropagate(node, error) {
|
|
1445
|
-
const
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
return true;
|
|
1450
|
-
} catch {
|
|
1451
|
-
return false;
|
|
1452
|
-
}
|
|
1714
|
+
const report = () => {
|
|
1715
|
+
if (!node.parentNode) return false;
|
|
1716
|
+
reportError(error, { phase: "render", name: "lazy", node });
|
|
1717
|
+
return true;
|
|
1453
1718
|
};
|
|
1454
|
-
if (
|
|
1719
|
+
if (report()) return;
|
|
1455
1720
|
queueMicrotask(() => {
|
|
1456
|
-
if (
|
|
1721
|
+
if (report()) return;
|
|
1457
1722
|
node[PENDING_ERROR] = error;
|
|
1458
1723
|
});
|
|
1459
1724
|
}
|
|
@@ -1478,12 +1743,14 @@ function lazy(importFn) {
|
|
|
1478
1743
|
if (disposed) return;
|
|
1479
1744
|
cached = mod.default;
|
|
1480
1745
|
const rendered = cached();
|
|
1481
|
-
container
|
|
1746
|
+
replaceChildrenSafely(container, rendered);
|
|
1482
1747
|
}).catch((err) => {
|
|
1483
1748
|
if (disposed) return;
|
|
1484
1749
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1485
|
-
|
|
1486
|
-
|
|
1750
|
+
replaceChildrenSafely(
|
|
1751
|
+
container,
|
|
1752
|
+
div({ class: "sibu-lazy-error" }, `Failed to load component: ${errorObj.message}`)
|
|
1753
|
+
);
|
|
1487
1754
|
dispatchPropagate(container, errorObj);
|
|
1488
1755
|
});
|
|
1489
1756
|
container.appendChild(span("sibu-lazy-loading", "Loading..."));
|
|
@@ -1515,7 +1782,7 @@ function Suspense({ nodes, fallback }) {
|
|
|
1515
1782
|
childEl = el;
|
|
1516
1783
|
if (el.classList.contains("sibu-lazy")) {
|
|
1517
1784
|
if (!el.querySelector(".sibu-lazy-loading")) {
|
|
1518
|
-
container
|
|
1785
|
+
replaceChildrenSafely(container, el);
|
|
1519
1786
|
return;
|
|
1520
1787
|
}
|
|
1521
1788
|
observer = new MutationObserver(() => {
|
|
@@ -1524,16 +1791,15 @@ function Suspense({ nodes, fallback }) {
|
|
|
1524
1791
|
if (!loading) {
|
|
1525
1792
|
observer?.disconnect();
|
|
1526
1793
|
observer = null;
|
|
1527
|
-
container
|
|
1794
|
+
replaceChildrenSafely(container, el);
|
|
1528
1795
|
}
|
|
1529
1796
|
});
|
|
1530
1797
|
observer.observe(el, { childList: true, subtree: true });
|
|
1531
1798
|
} else {
|
|
1532
|
-
container
|
|
1799
|
+
replaceChildrenSafely(container, el);
|
|
1533
1800
|
}
|
|
1534
1801
|
} catch (err) {
|
|
1535
1802
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1536
|
-
devWarn(`[SibuJS] Suspense nodes() threw: ${errorObj.message}`);
|
|
1537
1803
|
dispatchPropagate(container, errorObj);
|
|
1538
1804
|
}
|
|
1539
1805
|
});
|
|
@@ -1545,7 +1811,8 @@ function safeCall(cb, hookName) {
|
|
|
1545
1811
|
try {
|
|
1546
1812
|
return cb();
|
|
1547
1813
|
} catch (err) {
|
|
1548
|
-
|
|
1814
|
+
const phase = hookName.toLowerCase().includes("unmount") ? "cleanup" : "effect";
|
|
1815
|
+
reportError(err, { phase, name: hookName });
|
|
1549
1816
|
return void 0;
|
|
1550
1817
|
}
|
|
1551
1818
|
}
|
|
@@ -1779,20 +2046,35 @@ function detectSSRShared() {
|
|
|
1779
2046
|
const getBuiltin = process.getBuiltinModule;
|
|
1780
2047
|
if (typeof getBuiltin === "function") {
|
|
1781
2048
|
mod = getBuiltin("node:async_hooks");
|
|
1782
|
-
} else {
|
|
1783
|
-
|
|
1784
|
-
if (req) mod = req("node:async_hooks");
|
|
2049
|
+
} else if (typeof require === "function") {
|
|
2050
|
+
mod = require("async_hooks");
|
|
1785
2051
|
}
|
|
1786
2052
|
if (mod) detected = new mod.AsyncLocalStorage();
|
|
1787
2053
|
}
|
|
1788
2054
|
} catch {
|
|
1789
2055
|
detected = null;
|
|
1790
2056
|
}
|
|
1791
|
-
return {
|
|
2057
|
+
return {
|
|
2058
|
+
als: detected,
|
|
2059
|
+
fallbackStore: { ssr: false, suspenseIdCounter: 0, locale: void 0 },
|
|
2060
|
+
fallbackDepth: 0
|
|
2061
|
+
};
|
|
1792
2062
|
}
|
|
1793
2063
|
var _shared = globalThis[SSR_KEY] ?? (globalThis[SSR_KEY] = detectSSRShared());
|
|
1794
2064
|
var als = _shared.als;
|
|
1795
2065
|
var fallbackStore = _shared.fallbackStore;
|
|
2066
|
+
_shared.fallbackDepth ?? (_shared.fallbackDepth = 0);
|
|
2067
|
+
var _alsWarned = false;
|
|
2068
|
+
function warnMissingAsyncLocalStorage() {
|
|
2069
|
+
if (_alsWarned || als) return;
|
|
2070
|
+
const isNode = typeof process !== "undefined" && !!process.versions?.node;
|
|
2071
|
+
if (!isNode) return;
|
|
2072
|
+
_alsWarned = true;
|
|
2073
|
+
const version = process.versions.node;
|
|
2074
|
+
devWarn(
|
|
2075
|
+
`SSR request isolation is UNAVAILABLE on this runtime (Node ${version}). AsyncLocalStorage could not be loaded, so concurrent requests share one SSR store: request state and the query cache can bleed between them. Node >= 22.3 is required for isolated SSR under ESM; the CommonJS build works on older versions. A fully synchronous render is unaffected.`
|
|
2076
|
+
);
|
|
2077
|
+
}
|
|
1796
2078
|
function getSSRStore() {
|
|
1797
2079
|
if (als) {
|
|
1798
2080
|
const s2 = als.getStore();
|
|
@@ -1821,19 +2103,25 @@ function disableSSR() {
|
|
|
1821
2103
|
getSSRStore().ssr = false;
|
|
1822
2104
|
}
|
|
1823
2105
|
function runInSSRContext(fn) {
|
|
1824
|
-
const store2 = { ssr: true, suspenseIdCounter: 0 };
|
|
2106
|
+
const store2 = { ssr: true, suspenseIdCounter: 0, locale: void 0 };
|
|
1825
2107
|
if (als) {
|
|
1826
2108
|
return als.run(store2, fn);
|
|
1827
2109
|
}
|
|
2110
|
+
warnMissingAsyncLocalStorage();
|
|
1828
2111
|
const prevSSR = fallbackStore.ssr;
|
|
1829
2112
|
const prevCounter = fallbackStore.suspenseIdCounter;
|
|
2113
|
+
const prevLocale = fallbackStore.locale;
|
|
1830
2114
|
fallbackStore.ssr = true;
|
|
1831
2115
|
fallbackStore.suspenseIdCounter = 0;
|
|
2116
|
+
fallbackStore.locale = void 0;
|
|
2117
|
+
_shared.fallbackDepth++;
|
|
1832
2118
|
try {
|
|
1833
2119
|
return fn();
|
|
1834
2120
|
} finally {
|
|
2121
|
+
_shared.fallbackDepth--;
|
|
1835
2122
|
fallbackStore.ssr = prevSSR;
|
|
1836
2123
|
fallbackStore.suspenseIdCounter = prevCounter;
|
|
2124
|
+
fallbackStore.locale = prevLocale;
|
|
1837
2125
|
}
|
|
1838
2126
|
}
|
|
1839
2127
|
function withSSR(fn) {
|
|
@@ -1874,7 +2162,7 @@ function flushUserCleanups(ctx) {
|
|
|
1874
2162
|
try {
|
|
1875
2163
|
list[i2]();
|
|
1876
2164
|
} catch (err) {
|
|
1877
|
-
|
|
2165
|
+
reportError(err, { phase: "cleanup" });
|
|
1878
2166
|
}
|
|
1879
2167
|
}
|
|
1880
2168
|
}
|
|
@@ -1887,11 +2175,12 @@ function drainReruns(ctx) {
|
|
|
1887
2175
|
} while (ctx.rerunPending && ++reruns <= MAX_RERUNS);
|
|
1888
2176
|
if (ctx.rerunPending) {
|
|
1889
2177
|
ctx.rerunPending = false;
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
`
|
|
1893
|
-
)
|
|
1894
|
-
|
|
2178
|
+
reportError(
|
|
2179
|
+
new Error(
|
|
2180
|
+
`effect re-requested itself ${MAX_RERUNS}+ times \u2014 likely a write-reads-self cycle. Breaking to prevent infinite loop.`
|
|
2181
|
+
),
|
|
2182
|
+
{ phase: "effect" }
|
|
2183
|
+
);
|
|
1895
2184
|
}
|
|
1896
2185
|
}
|
|
1897
2186
|
function disposeEffect(ctx) {
|
|
@@ -1968,6 +2257,8 @@ function effect(effectFn, options) {
|
|
|
1968
2257
|
sub2.depsTail = null;
|
|
1969
2258
|
sub2._epoch = 0;
|
|
1970
2259
|
sub2._structDirty = false;
|
|
2260
|
+
sub2._hasComputedDep = false;
|
|
2261
|
+
sub2._errorPhase = "effect";
|
|
1971
2262
|
sub2._runEpoch = 0;
|
|
1972
2263
|
sub2._runs = 0;
|
|
1973
2264
|
ctx.subscriber = sub2;
|
|
@@ -2036,70 +2327,72 @@ var isBatching = API2.isBatching;
|
|
|
2036
2327
|
|
|
2037
2328
|
// src/core/signals/signal.ts
|
|
2038
2329
|
var _g2 = globalThis;
|
|
2039
|
-
var
|
|
2330
|
+
var _isDev7 = isDev();
|
|
2040
2331
|
function signal(initial, options) {
|
|
2041
|
-
const
|
|
2332
|
+
const state2 = {
|
|
2042
2333
|
value: initial,
|
|
2043
2334
|
__v: 0,
|
|
2044
2335
|
__sc: 0,
|
|
2045
2336
|
subsHead: null,
|
|
2046
2337
|
subsTail: null,
|
|
2047
2338
|
__activeNode: null,
|
|
2048
|
-
__name: void 0
|
|
2339
|
+
__name: void 0,
|
|
2340
|
+
_d: false,
|
|
2341
|
+
_validate: void 0
|
|
2049
2342
|
};
|
|
2050
|
-
const debugName =
|
|
2343
|
+
const debugName = _isDev7 ? options?.name : void 0;
|
|
2051
2344
|
const equalsFn = options?.equals;
|
|
2052
|
-
if (debugName)
|
|
2345
|
+
if (debugName) state2.__name = debugName;
|
|
2053
2346
|
function get() {
|
|
2054
|
-
recordDependency2(
|
|
2055
|
-
return
|
|
2347
|
+
recordDependency2(state2);
|
|
2348
|
+
return state2.value;
|
|
2056
2349
|
}
|
|
2057
|
-
get.__signal =
|
|
2350
|
+
get.__signal = state2;
|
|
2058
2351
|
if (debugName) get.__name = debugName;
|
|
2059
2352
|
let set;
|
|
2060
2353
|
if (equalsFn) {
|
|
2061
2354
|
set = (next) => {
|
|
2062
|
-
const prev =
|
|
2355
|
+
const prev = state2.value;
|
|
2063
2356
|
const newValue = typeof next === "function" ? next(prev) : next;
|
|
2064
2357
|
if (equalsFn(prev, newValue)) return;
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
if (
|
|
2358
|
+
state2.value = newValue;
|
|
2359
|
+
state2.__v++;
|
|
2360
|
+
if (_isDev7) {
|
|
2068
2361
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2069
|
-
if (hook) hook.emit("signal:update", { signal:
|
|
2362
|
+
if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
2070
2363
|
}
|
|
2071
|
-
if (!enqueueBatchedSignal(
|
|
2072
|
-
notifySubscribers2(
|
|
2364
|
+
if (!enqueueBatchedSignal(state2)) {
|
|
2365
|
+
notifySubscribers2(state2);
|
|
2073
2366
|
}
|
|
2074
2367
|
};
|
|
2075
|
-
} else if (
|
|
2368
|
+
} else if (_isDev7) {
|
|
2076
2369
|
set = (next) => {
|
|
2077
|
-
const prev =
|
|
2370
|
+
const prev = state2.value;
|
|
2078
2371
|
const newValue = typeof next === "function" ? next(prev) : next;
|
|
2079
2372
|
if (Object.is(newValue, prev)) return;
|
|
2080
|
-
|
|
2081
|
-
|
|
2373
|
+
state2.value = newValue;
|
|
2374
|
+
state2.__v++;
|
|
2082
2375
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2083
|
-
if (hook) hook.emit("signal:update", { signal:
|
|
2084
|
-
if (!enqueueBatchedSignal(
|
|
2085
|
-
notifySubscribers2(
|
|
2376
|
+
if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
|
|
2377
|
+
if (!enqueueBatchedSignal(state2)) {
|
|
2378
|
+
notifySubscribers2(state2);
|
|
2086
2379
|
}
|
|
2087
2380
|
};
|
|
2088
2381
|
} else {
|
|
2089
2382
|
set = (next) => {
|
|
2090
|
-
const prev =
|
|
2383
|
+
const prev = state2.value;
|
|
2091
2384
|
const newValue = typeof next === "function" ? next(prev) : next;
|
|
2092
2385
|
if (Object.is(newValue, prev)) return;
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
if (!enqueueBatchedSignal(
|
|
2096
|
-
notifySubscribers2(
|
|
2386
|
+
state2.value = newValue;
|
|
2387
|
+
state2.__v++;
|
|
2388
|
+
if (!enqueueBatchedSignal(state2)) {
|
|
2389
|
+
notifySubscribers2(state2);
|
|
2097
2390
|
}
|
|
2098
2391
|
};
|
|
2099
2392
|
}
|
|
2100
|
-
if (
|
|
2393
|
+
if (_isDev7) {
|
|
2101
2394
|
const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
2102
|
-
if (hook) hook.emit("signal:create", { signal:
|
|
2395
|
+
if (hook) hook.emit("signal:create", { signal: state2, name: debugName, getter: get, initial });
|
|
2103
2396
|
}
|
|
2104
2397
|
return [get, set];
|
|
2105
2398
|
}
|
|
@@ -2311,14 +2604,14 @@ function parseStack(stack) {
|
|
|
2311
2604
|
}
|
|
2312
2605
|
return frames;
|
|
2313
2606
|
}
|
|
2314
|
-
function
|
|
2607
|
+
function normalizeError2(err) {
|
|
2315
2608
|
if (err instanceof Error) {
|
|
2316
2609
|
const code2 = err.code ?? err.name ?? "ERROR";
|
|
2317
2610
|
const message = err.message || "Unknown error";
|
|
2318
2611
|
const stack = err.stack ?? "";
|
|
2319
2612
|
const frames = parseStack(stack);
|
|
2320
2613
|
const rawCause = err.cause;
|
|
2321
|
-
const cause = rawCause != null ?
|
|
2614
|
+
const cause = rawCause != null ? normalizeError2(rawCause) : null;
|
|
2322
2615
|
return { code: code2, message, stack, frames, cause };
|
|
2323
2616
|
}
|
|
2324
2617
|
return {
|
|
@@ -2414,7 +2707,7 @@ function renderMetadata(meta2) {
|
|
|
2414
2707
|
function ErrorDisplay(props) {
|
|
2415
2708
|
injectStyles();
|
|
2416
2709
|
const severity = props.severity ?? "error";
|
|
2417
|
-
const normalized =
|
|
2710
|
+
const normalized = normalizeError2(props.error);
|
|
2418
2711
|
const showDetails = props.alwaysShowDetails ?? isDev();
|
|
2419
2712
|
const headline = props.title ?? normalized.message;
|
|
2420
2713
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
@@ -2664,6 +2957,7 @@ var errorBoundaryStyles = `
|
|
|
2664
2957
|
background: #3a3a4e;
|
|
2665
2958
|
}
|
|
2666
2959
|
`;
|
|
2960
|
+
var RESET_KEY_THREW = /* @__PURE__ */ Symbol("sibujs.ErrorBoundary.resetKeyThrew");
|
|
2667
2961
|
var stylesInjected = false;
|
|
2668
2962
|
function injectStyles2() {
|
|
2669
2963
|
if (!stylesInjected && typeof document !== "undefined") {
|
|
@@ -2672,29 +2966,6 @@ function injectStyles2() {
|
|
|
2672
2966
|
stylesInjected = true;
|
|
2673
2967
|
}
|
|
2674
2968
|
}
|
|
2675
|
-
var FALLBACK_CACHE_MAX = 50;
|
|
2676
|
-
var fallbackCache = /* @__PURE__ */ new WeakMap();
|
|
2677
|
-
function getMemoizedFallback(fallbackFn, error, retry) {
|
|
2678
|
-
let cache2 = fallbackCache.get(fallbackFn);
|
|
2679
|
-
if (!cache2) {
|
|
2680
|
-
cache2 = /* @__PURE__ */ new Map();
|
|
2681
|
-
fallbackCache.set(fallbackFn, cache2);
|
|
2682
|
-
}
|
|
2683
|
-
const key = error.message;
|
|
2684
|
-
let factory = cache2.get(key);
|
|
2685
|
-
if (factory) {
|
|
2686
|
-
cache2.delete(key);
|
|
2687
|
-
cache2.set(key, factory);
|
|
2688
|
-
} else {
|
|
2689
|
-
factory = () => fallbackFn(error, retry);
|
|
2690
|
-
cache2.set(key, factory);
|
|
2691
|
-
if (cache2.size > FALLBACK_CACHE_MAX) {
|
|
2692
|
-
const oldestKey = cache2.keys().next().value;
|
|
2693
|
-
if (oldestKey !== void 0) cache2.delete(oldestKey);
|
|
2694
|
-
}
|
|
2695
|
-
}
|
|
2696
|
-
return factory();
|
|
2697
|
-
}
|
|
2698
2969
|
function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
2699
2970
|
const children = typeof optionsOrChildren === "function" ? optionsOrChildren : maybeChildren;
|
|
2700
2971
|
const options = typeof optionsOrChildren === "function" ? {} : optionsOrChildren;
|
|
@@ -2702,43 +2973,61 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
2702
2973
|
injectStyles2();
|
|
2703
2974
|
const [error, setError] = signal(null);
|
|
2704
2975
|
const retry = () => {
|
|
2705
|
-
|
|
2706
|
-
const cur = error();
|
|
2707
|
-
const inner = fallbackCache.get(fallback);
|
|
2708
|
-
if (cur && inner) inner.delete(cur.message);
|
|
2709
|
-
}
|
|
2976
|
+
stopResetKeysWatcher();
|
|
2710
2977
|
setError(null);
|
|
2711
2978
|
};
|
|
2712
2979
|
let resetKeysTeardown = null;
|
|
2713
|
-
|
|
2714
|
-
|
|
2980
|
+
const stopResetKeysWatcher = () => {
|
|
2981
|
+
if (!resetKeysTeardown) return;
|
|
2982
|
+
const teardown = resetKeysTeardown;
|
|
2983
|
+
resetKeysTeardown = null;
|
|
2984
|
+
teardown();
|
|
2985
|
+
};
|
|
2986
|
+
const readResetKeyValues = (keys) => {
|
|
2987
|
+
const values = new Array(keys.length);
|
|
2988
|
+
for (let i2 = 0; i2 < keys.length; i2++) {
|
|
2989
|
+
try {
|
|
2990
|
+
values[i2] = keys[i2]();
|
|
2991
|
+
} catch (err) {
|
|
2992
|
+
reportError(err, { phase: "effect", name: "ErrorBoundary.resetKeys" });
|
|
2993
|
+
values[i2] = RESET_KEY_THREW;
|
|
2994
|
+
}
|
|
2995
|
+
}
|
|
2996
|
+
return values;
|
|
2997
|
+
};
|
|
2998
|
+
const startResetKeysWatcher = () => {
|
|
2999
|
+
const keys = resetKeys;
|
|
3000
|
+
if (!keys || keys.length === 0) return;
|
|
3001
|
+
stopResetKeysWatcher();
|
|
3002
|
+
let baseline = null;
|
|
2715
3003
|
resetKeysTeardown = effect(() => {
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
3004
|
+
const current = readResetKeyValues(keys);
|
|
3005
|
+
if (baseline === null) {
|
|
3006
|
+
baseline = current;
|
|
3007
|
+
return;
|
|
3008
|
+
}
|
|
3009
|
+
let changed = current.length !== baseline.length;
|
|
3010
|
+
if (!changed) {
|
|
3011
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
3012
|
+
if (!Object.is(current[i2], baseline[i2])) {
|
|
3013
|
+
changed = true;
|
|
3014
|
+
break;
|
|
2722
3015
|
}
|
|
2723
3016
|
}
|
|
2724
3017
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
return;
|
|
2728
|
-
}
|
|
2729
|
-
if (error() !== null) retry();
|
|
3018
|
+
baseline = current;
|
|
3019
|
+
if (changed) retry();
|
|
2730
3020
|
});
|
|
2731
|
-
}
|
|
3021
|
+
};
|
|
2732
3022
|
const handleError = (e) => {
|
|
2733
|
-
const errorObj =
|
|
3023
|
+
const errorObj = normalizeError(e);
|
|
2734
3024
|
setError(errorObj);
|
|
3025
|
+
startResetKeysWatcher();
|
|
2735
3026
|
if (onError) {
|
|
2736
3027
|
try {
|
|
2737
3028
|
onError(errorObj);
|
|
2738
3029
|
} catch (cbErr) {
|
|
2739
|
-
|
|
2740
|
-
console.error("[SibuJS ErrorBoundary] onError callback threw:", cbErr);
|
|
2741
|
-
}
|
|
3030
|
+
reportError(cbErr, { phase: "render", name: "ErrorBoundary onError callback" });
|
|
2742
3031
|
}
|
|
2743
3032
|
}
|
|
2744
3033
|
return errorObj;
|
|
@@ -2749,18 +3038,14 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
2749
3038
|
const tryRenderFallback = (err) => {
|
|
2750
3039
|
const fn = fallback || defaultFallback;
|
|
2751
3040
|
try {
|
|
2752
|
-
return
|
|
3041
|
+
return fn(err, retry);
|
|
2753
3042
|
} catch (fallbackError) {
|
|
2754
|
-
const propagateError = fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError));
|
|
2755
3043
|
queueMicrotask(() => {
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
})
|
|
2762
|
-
);
|
|
2763
|
-
}
|
|
3044
|
+
reportError(fallbackError, {
|
|
3045
|
+
phase: "render",
|
|
3046
|
+
name: "ErrorBoundary fallback",
|
|
3047
|
+
node: container.parentNode ? container : void 0
|
|
3048
|
+
});
|
|
2764
3049
|
});
|
|
2765
3050
|
return document.createComment("error-boundary-failed");
|
|
2766
3051
|
}
|
|
@@ -2777,11 +3062,20 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
2777
3062
|
if (result && typeof result.then === "function") {
|
|
2778
3063
|
const asyncContainer = div({ class: "sibu-error-async" });
|
|
2779
3064
|
asyncContainer.appendChild(span({ class: "sibu-lazy-loading", nodes: "Loading..." }));
|
|
3065
|
+
let asyncDisposed = false;
|
|
3066
|
+
registerDisposer(asyncContainer, () => {
|
|
3067
|
+
asyncDisposed = true;
|
|
3068
|
+
});
|
|
2780
3069
|
result.then((el) => {
|
|
2781
|
-
|
|
3070
|
+
if (asyncDisposed) {
|
|
3071
|
+
dispose(el);
|
|
3072
|
+
return;
|
|
3073
|
+
}
|
|
3074
|
+
replaceChildrenSafely(asyncContainer, el);
|
|
2782
3075
|
}).catch((e) => {
|
|
3076
|
+
if (asyncDisposed) return;
|
|
2783
3077
|
const err = handleError(e);
|
|
2784
|
-
asyncContainer
|
|
3078
|
+
replaceChildrenSafely(asyncContainer, tryRenderFallback(err));
|
|
2785
3079
|
});
|
|
2786
3080
|
return asyncContainer;
|
|
2787
3081
|
}
|
|
@@ -2794,12 +3088,12 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
2794
3088
|
});
|
|
2795
3089
|
const propagateListener = (e) => {
|
|
2796
3090
|
if (error()) return;
|
|
2797
|
-
e.stopPropagation();
|
|
2798
3091
|
const customEvent = e;
|
|
2799
3092
|
const propagatedError = customEvent.detail?.error;
|
|
2800
|
-
if (propagatedError)
|
|
2801
|
-
|
|
2802
|
-
|
|
3093
|
+
if (!propagatedError) return;
|
|
3094
|
+
e.preventDefault();
|
|
3095
|
+
e.stopPropagation();
|
|
3096
|
+
handleError(propagatedError);
|
|
2803
3097
|
};
|
|
2804
3098
|
container.addEventListener("sibu:error-propagate", propagateListener);
|
|
2805
3099
|
onMount(() => {
|
|
@@ -2827,7 +3121,7 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
2827
3121
|
return void 0;
|
|
2828
3122
|
}, container);
|
|
2829
3123
|
registerDisposer(container, () => {
|
|
2830
|
-
|
|
3124
|
+
stopResetKeysWatcher();
|
|
2831
3125
|
container.removeEventListener("sibu:error-propagate", propagateListener);
|
|
2832
3126
|
});
|
|
2833
3127
|
return container;
|
|
@@ -3077,10 +3371,18 @@ function setGlobalErrorHandler(handler) {
|
|
|
3077
3371
|
}
|
|
3078
3372
|
|
|
3079
3373
|
// src/core/rendering/context.ts
|
|
3374
|
+
var _isDev8 = isDev();
|
|
3080
3375
|
function context(defaultValue) {
|
|
3081
3376
|
const [getValue, setValue] = signal(defaultValue);
|
|
3377
|
+
const warnIfSSR = (method) => {
|
|
3378
|
+
if (!_isDev8 || !isSSR()) return;
|
|
3379
|
+
devWarn(
|
|
3380
|
+
`context.${method}() called during SSR. SibuJS context() is application-global \u2014 it is NOT isolated per request, so a concurrent request can observe this value. Do not use context() for request-specific SSR data; pass it explicitly or use request-scoped storage instead.`
|
|
3381
|
+
);
|
|
3382
|
+
};
|
|
3082
3383
|
const ctx = {
|
|
3083
3384
|
provide(value) {
|
|
3385
|
+
warnIfSSR("provide");
|
|
3084
3386
|
const previous = getValue();
|
|
3085
3387
|
setValue(value);
|
|
3086
3388
|
return () => setValue(previous);
|
|
@@ -3092,13 +3394,21 @@ function context(defaultValue) {
|
|
|
3092
3394
|
return getValue();
|
|
3093
3395
|
},
|
|
3094
3396
|
set(value) {
|
|
3397
|
+
warnIfSSR("set");
|
|
3095
3398
|
setValue(value);
|
|
3096
3399
|
},
|
|
3097
3400
|
withContext(value, fn) {
|
|
3401
|
+
warnIfSSR("withContext");
|
|
3098
3402
|
const previous = getValue();
|
|
3099
3403
|
setValue(value);
|
|
3100
3404
|
try {
|
|
3101
|
-
|
|
3405
|
+
const result = fn();
|
|
3406
|
+
if (_isDev8 && result !== null && typeof result?.then === "function") {
|
|
3407
|
+
devWarn(
|
|
3408
|
+
"context.withContext() received an async callback. Scoping is synchronous only \u2014 the previous value is restored as soon as the callback returns its promise, so anything after an `await` runs outside the scope."
|
|
3409
|
+
);
|
|
3410
|
+
}
|
|
3411
|
+
return result;
|
|
3102
3412
|
} finally {
|
|
3103
3413
|
setValue(previous);
|
|
3104
3414
|
}
|
|
@@ -3219,10 +3529,7 @@ function DynamicComponent(is) {
|
|
|
3219
3529
|
} else {
|
|
3220
3530
|
el = resolveComponent(target);
|
|
3221
3531
|
}
|
|
3222
|
-
|
|
3223
|
-
dispose(child);
|
|
3224
|
-
}
|
|
3225
|
-
container.replaceChildren(el);
|
|
3532
|
+
replaceChildrenSafely(container, el);
|
|
3226
3533
|
}
|
|
3227
3534
|
const untrack = track2(render);
|
|
3228
3535
|
registerDisposer(container, untrack);
|
|
@@ -3283,6 +3590,10 @@ function each(getArray, render, options) {
|
|
|
3283
3590
|
let oldLen = 0;
|
|
3284
3591
|
let nodeMap = /* @__PURE__ */ new Map();
|
|
3285
3592
|
let workMap = /* @__PURE__ */ new Map();
|
|
3593
|
+
const pendingRows = [];
|
|
3594
|
+
const pendingItems = [];
|
|
3595
|
+
const pendingIndices = [];
|
|
3596
|
+
let pendingCount = 0;
|
|
3286
3597
|
let newNodes = [];
|
|
3287
3598
|
let newKeysBuf = [];
|
|
3288
3599
|
let isStableBuf = new Uint8Array(0);
|
|
@@ -3292,8 +3603,10 @@ function each(getArray, render, options) {
|
|
|
3292
3603
|
const keyIndexMap = /* @__PURE__ */ new Map();
|
|
3293
3604
|
let initialized = false;
|
|
3294
3605
|
let sentinelInserted = false;
|
|
3606
|
+
let rangeDisposed = false;
|
|
3295
3607
|
const keyFn = options.key;
|
|
3296
3608
|
const update = () => {
|
|
3609
|
+
if (rangeDisposed) return;
|
|
3297
3610
|
const arr = getArray();
|
|
3298
3611
|
const newLen = arr.length;
|
|
3299
3612
|
const parent = anchor.parentNode;
|
|
@@ -3322,49 +3635,44 @@ function each(getArray, render, options) {
|
|
|
3322
3635
|
}
|
|
3323
3636
|
keyIndexMap.set(newKeys[i2], i2);
|
|
3324
3637
|
}
|
|
3638
|
+
pendingCount = 0;
|
|
3325
3639
|
for (let i2 = 0; i2 < newLen; i2++) {
|
|
3326
3640
|
const key = newKeys[i2];
|
|
3327
3641
|
const existing = nodeMap.get(key);
|
|
3328
|
-
let
|
|
3642
|
+
let row;
|
|
3329
3643
|
if (existing !== void 0) {
|
|
3330
|
-
|
|
3644
|
+
row = existing;
|
|
3645
|
+
pendingRows[pendingCount] = row;
|
|
3646
|
+
pendingItems[pendingCount] = arr[i2];
|
|
3647
|
+
pendingIndices[pendingCount] = i2;
|
|
3648
|
+
pendingCount++;
|
|
3331
3649
|
} else {
|
|
3332
|
-
const
|
|
3333
|
-
const
|
|
3334
|
-
|
|
3650
|
+
const [itemGetter, setItem] = signal(arr[i2]);
|
|
3651
|
+
const [indexGetter, setIndex] = signal(i2);
|
|
3652
|
+
let node;
|
|
3335
3653
|
try {
|
|
3336
3654
|
node = resolveNodeChild(render(itemGetter, indexGetter));
|
|
3337
3655
|
} catch (err) {
|
|
3338
|
-
|
|
3339
|
-
devWarn(
|
|
3340
|
-
`each: render threw for item at index ${i2} (key="${newKeys[i2]}"): ${err instanceof Error ? err.message : String(err)}`
|
|
3341
|
-
);
|
|
3342
|
-
}
|
|
3656
|
+
const key2 = newKeys[i2];
|
|
3343
3657
|
node = document.createComment(`each:error:${i2}`);
|
|
3344
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3345
3658
|
queueMicrotask(() => {
|
|
3346
|
-
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
);
|
|
3352
|
-
} else if (_isDev9) {
|
|
3353
|
-
devWarn(`each: error not surfaced \u2014 anchor detached: ${errorObj.message}`);
|
|
3354
|
-
}
|
|
3355
|
-
} catch {
|
|
3356
|
-
}
|
|
3659
|
+
reportError(err, {
|
|
3660
|
+
phase: "render",
|
|
3661
|
+
name: `each row (key="${String(key2)}")`,
|
|
3662
|
+
node: anchor.parentNode ? anchor : void 0
|
|
3663
|
+
});
|
|
3357
3664
|
});
|
|
3358
3665
|
}
|
|
3666
|
+
row = { node, item: itemGetter, setItem, index: indexGetter, setIndex };
|
|
3359
3667
|
}
|
|
3360
|
-
workMap.set(key,
|
|
3361
|
-
newNodes[i2] = node;
|
|
3668
|
+
workMap.set(key, row);
|
|
3669
|
+
newNodes[i2] = row.node;
|
|
3362
3670
|
}
|
|
3363
|
-
for (const [key,
|
|
3671
|
+
for (const [key, row] of nodeMap) {
|
|
3364
3672
|
if (!workMap.has(key)) {
|
|
3365
|
-
dispose(node);
|
|
3366
|
-
if (node.parentNode) {
|
|
3367
|
-
parent.removeChild(node);
|
|
3673
|
+
dispose(row.node);
|
|
3674
|
+
if (row.node.parentNode) {
|
|
3675
|
+
parent.removeChild(row.node);
|
|
3368
3676
|
}
|
|
3369
3677
|
}
|
|
3370
3678
|
}
|
|
@@ -3373,6 +3681,8 @@ function each(getArray, render, options) {
|
|
|
3373
3681
|
const tmp2 = nodeMap;
|
|
3374
3682
|
nodeMap = workMap;
|
|
3375
3683
|
workMap = tmp2;
|
|
3684
|
+
initialized = true;
|
|
3685
|
+
pendingCount = 0;
|
|
3376
3686
|
return;
|
|
3377
3687
|
}
|
|
3378
3688
|
oldKeyIndex.clear();
|
|
@@ -3422,12 +3732,47 @@ function each(getArray, render, options) {
|
|
|
3422
3732
|
nodeMap = workMap;
|
|
3423
3733
|
workMap = tmp;
|
|
3424
3734
|
initialized = true;
|
|
3735
|
+
flushRowCells();
|
|
3425
3736
|
};
|
|
3737
|
+
function flushRowCells() {
|
|
3738
|
+
if (pendingCount === 0) return;
|
|
3739
|
+
const count = pendingCount;
|
|
3740
|
+
pendingCount = 0;
|
|
3741
|
+
batch(() => {
|
|
3742
|
+
for (let i2 = 0; i2 < count; i2++) {
|
|
3743
|
+
const row = pendingRows[i2];
|
|
3744
|
+
row.setItem(pendingItems[i2]);
|
|
3745
|
+
row.setIndex(pendingIndices[i2]);
|
|
3746
|
+
pendingRows[i2] = void 0;
|
|
3747
|
+
pendingItems[i2] = void 0;
|
|
3748
|
+
}
|
|
3749
|
+
});
|
|
3750
|
+
}
|
|
3426
3751
|
const untrack = track2(update);
|
|
3427
|
-
|
|
3752
|
+
const disposeRange = () => {
|
|
3753
|
+
if (rangeDisposed) return;
|
|
3754
|
+
rangeDisposed = true;
|
|
3755
|
+
untrack();
|
|
3756
|
+
for (const row of nodeMap.values()) {
|
|
3757
|
+
dispose(row.node);
|
|
3758
|
+
row.node.parentNode?.removeChild(row.node);
|
|
3759
|
+
}
|
|
3760
|
+
if (end.parentNode) end.parentNode.removeChild(end);
|
|
3761
|
+
sentinelInserted = false;
|
|
3762
|
+
nodeMap.clear();
|
|
3763
|
+
workMap.clear();
|
|
3764
|
+
keyIndexMap.clear();
|
|
3765
|
+
oldKeyIndex.clear();
|
|
3766
|
+
oldLen = 0;
|
|
3767
|
+
pendingRows.length = 0;
|
|
3768
|
+
pendingItems.length = 0;
|
|
3769
|
+
pendingIndices.length = 0;
|
|
3770
|
+
pendingCount = 0;
|
|
3771
|
+
};
|
|
3772
|
+
registerDisposer(anchor, disposeRange);
|
|
3428
3773
|
if (!initialized) {
|
|
3429
3774
|
queueMicrotask(() => {
|
|
3430
|
-
if (!initialized && anchor.parentNode) {
|
|
3775
|
+
if (!initialized && !rangeDisposed && anchor.parentNode) {
|
|
3431
3776
|
update();
|
|
3432
3777
|
}
|
|
3433
3778
|
});
|
|
@@ -3717,7 +4062,7 @@ function parseTemplate(strings) {
|
|
|
3717
4062
|
return parseChildren();
|
|
3718
4063
|
}
|
|
3719
4064
|
function executeElement(tmpl, values) {
|
|
3720
|
-
const el = tmpl.svg ? document.createElementNS(
|
|
4065
|
+
const el = tmpl.svg ? document.createElementNS(SVG_NS2, tmpl.tag) : document.createElement(tmpl.tag);
|
|
3721
4066
|
for (let i2 = 0; i2 < tmpl.attrs.length; i2++) {
|
|
3722
4067
|
const attr = tmpl.attrs[i2];
|
|
3723
4068
|
switch (attr.t) {
|
|
@@ -3726,20 +4071,11 @@ function executeElement(tmpl, values) {
|
|
|
3726
4071
|
break;
|
|
3727
4072
|
case 1: {
|
|
3728
4073
|
const name = attr.name;
|
|
3729
|
-
const lname = name.toLowerCase();
|
|
3730
|
-
if (isEventHandlerAttr(name)) break;
|
|
3731
4074
|
const val = values[attr.idx];
|
|
3732
4075
|
if (typeof val === "function") {
|
|
3733
4076
|
registerDisposer(el, bindAttribute(el, name, val));
|
|
3734
|
-
} else
|
|
3735
|
-
|
|
3736
|
-
if (lname === "srcset") {
|
|
3737
|
-
el.setAttribute(name, sanitizeSrcset(str));
|
|
3738
|
-
} else if (isUrlAttribute(lname)) {
|
|
3739
|
-
el.setAttribute(name, sanitizeUrl(str));
|
|
3740
|
-
} else {
|
|
3741
|
-
el.setAttribute(name, str);
|
|
3742
|
-
}
|
|
4077
|
+
} else {
|
|
4078
|
+
setSafeAttribute(el, name, val, { syncValueProperty: false, label: "html" });
|
|
3743
4079
|
}
|
|
3744
4080
|
break;
|
|
3745
4081
|
}
|
|
@@ -3749,14 +4085,7 @@ function executeElement(tmpl, values) {
|
|
|
3749
4085
|
const ev = values[attr.exprs[j]];
|
|
3750
4086
|
val += (ev == null ? "" : String(ev)) + attr.statics[j + 1];
|
|
3751
4087
|
}
|
|
3752
|
-
|
|
3753
|
-
if (lname2 === "srcset") {
|
|
3754
|
-
el.setAttribute(attr.name, sanitizeSrcset(val));
|
|
3755
|
-
} else if (isUrlAttribute(lname2)) {
|
|
3756
|
-
el.setAttribute(attr.name, sanitizeUrl(val));
|
|
3757
|
-
} else {
|
|
3758
|
-
el.setAttribute(attr.name, val);
|
|
3759
|
-
}
|
|
4088
|
+
setSafeAttribute(el, attr.name, val, { syncValueProperty: false, label: "html" });
|
|
3760
4089
|
break;
|
|
3761
4090
|
}
|
|
3762
4091
|
case 3: {
|
|
@@ -3982,20 +4311,12 @@ function Portal(nodes, target) {
|
|
|
3982
4311
|
portalContent = nodes();
|
|
3983
4312
|
container.appendChild(portalContent);
|
|
3984
4313
|
} catch (err) {
|
|
3985
|
-
if (typeof console !== "undefined") {
|
|
3986
|
-
console.error("[Portal] Render error:", err);
|
|
3987
|
-
}
|
|
3988
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
3989
4314
|
queueMicrotask(() => {
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
|
|
3995
|
-
);
|
|
3996
|
-
}
|
|
3997
|
-
} catch {
|
|
3998
|
-
}
|
|
4315
|
+
reportError(err, {
|
|
4316
|
+
phase: "render",
|
|
4317
|
+
name: "Portal",
|
|
4318
|
+
node: anchor.parentNode ? anchor : void 0
|
|
4319
|
+
});
|
|
3999
4320
|
});
|
|
4000
4321
|
}
|
|
4001
4322
|
});
|
|
@@ -4092,9 +4413,10 @@ function array(initial = []) {
|
|
|
4092
4413
|
function reactiveArray(initial = []) {
|
|
4093
4414
|
let data2 = [...initial];
|
|
4094
4415
|
let snapshot = null;
|
|
4095
|
-
const signal2 = {};
|
|
4416
|
+
const signal2 = { __v: 0 };
|
|
4096
4417
|
function notify() {
|
|
4097
4418
|
snapshot = null;
|
|
4419
|
+
signal2.__v++;
|
|
4098
4420
|
if (!enqueueBatchedSignal(signal2)) {
|
|
4099
4421
|
notifySubscribers2(signal2);
|
|
4100
4422
|
}
|
|
@@ -4214,17 +4536,34 @@ function asyncDerived(factory, initial) {
|
|
|
4214
4536
|
const [error, setError] = signal(null);
|
|
4215
4537
|
const [tick, setTick] = signal(0);
|
|
4216
4538
|
let runId = 0;
|
|
4217
|
-
|
|
4539
|
+
let disposed = false;
|
|
4540
|
+
let controller = null;
|
|
4541
|
+
const abortInFlight = () => {
|
|
4542
|
+
if (controller === null) return;
|
|
4543
|
+
const c = controller;
|
|
4544
|
+
controller = null;
|
|
4545
|
+
try {
|
|
4546
|
+
c.abort();
|
|
4547
|
+
} catch {
|
|
4548
|
+
}
|
|
4549
|
+
};
|
|
4550
|
+
const stopEffect = effect(() => {
|
|
4218
4551
|
tick();
|
|
4552
|
+
if (disposed) return;
|
|
4553
|
+
abortInFlight();
|
|
4219
4554
|
const currentRun = ++runId;
|
|
4555
|
+
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
4556
|
+
controller = ac;
|
|
4220
4557
|
batch(() => {
|
|
4221
4558
|
setLoading(true);
|
|
4222
4559
|
setError(null);
|
|
4223
4560
|
});
|
|
4561
|
+
const stale = () => disposed || currentRun !== runId;
|
|
4224
4562
|
let promise;
|
|
4225
4563
|
try {
|
|
4226
|
-
promise = factory();
|
|
4564
|
+
promise = factory({ signal: ac ? ac.signal : void 0 });
|
|
4227
4565
|
} catch (err) {
|
|
4566
|
+
if (stale()) return;
|
|
4228
4567
|
batch(() => {
|
|
4229
4568
|
setError(err);
|
|
4230
4569
|
setLoading(false);
|
|
@@ -4233,14 +4572,16 @@ function asyncDerived(factory, initial) {
|
|
|
4233
4572
|
}
|
|
4234
4573
|
promise.then(
|
|
4235
4574
|
(result) => {
|
|
4236
|
-
if (
|
|
4575
|
+
if (stale()) return;
|
|
4576
|
+
controller = null;
|
|
4237
4577
|
batch(() => {
|
|
4238
4578
|
setValue(result);
|
|
4239
4579
|
setLoading(false);
|
|
4240
4580
|
});
|
|
4241
4581
|
},
|
|
4242
4582
|
(err) => {
|
|
4243
|
-
if (
|
|
4583
|
+
if (stale()) return;
|
|
4584
|
+
controller = null;
|
|
4244
4585
|
batch(() => {
|
|
4245
4586
|
setError(err);
|
|
4246
4587
|
setLoading(false);
|
|
@@ -4252,7 +4593,16 @@ function asyncDerived(factory, initial) {
|
|
|
4252
4593
|
value,
|
|
4253
4594
|
loading,
|
|
4254
4595
|
error,
|
|
4255
|
-
refresh: () =>
|
|
4596
|
+
refresh: () => {
|
|
4597
|
+
if (disposed) return;
|
|
4598
|
+
setTick((n) => n + 1);
|
|
4599
|
+
},
|
|
4600
|
+
dispose: () => {
|
|
4601
|
+
if (disposed) return;
|
|
4602
|
+
disposed = true;
|
|
4603
|
+
stopEffect();
|
|
4604
|
+
abortInFlight();
|
|
4605
|
+
}
|
|
4256
4606
|
};
|
|
4257
4607
|
}
|
|
4258
4608
|
|
|
@@ -4372,6 +4722,21 @@ function derived(getter, options) {
|
|
|
4372
4722
|
}, markDirty);
|
|
4373
4723
|
const hook = globalThis.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
|
|
4374
4724
|
let evaluating = false;
|
|
4725
|
+
const validate = () => {
|
|
4726
|
+
if (!cs._d) return;
|
|
4727
|
+
const oldValue = cs._v;
|
|
4728
|
+
evaluating = true;
|
|
4729
|
+
try {
|
|
4730
|
+
retrack2(recompute, markDirty);
|
|
4731
|
+
if (!Object.is(oldValue, cs._v)) cs.__v++;
|
|
4732
|
+
} finally {
|
|
4733
|
+
evaluating = false;
|
|
4734
|
+
}
|
|
4735
|
+
if (hook && !Object.is(oldValue, cs._v)) {
|
|
4736
|
+
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
4737
|
+
}
|
|
4738
|
+
};
|
|
4739
|
+
cs._validate = validate;
|
|
4375
4740
|
function computedGetter() {
|
|
4376
4741
|
if (evaluating) {
|
|
4377
4742
|
throw new Error(
|
|
@@ -4379,32 +4744,11 @@ function derived(getter, options) {
|
|
|
4379
4744
|
);
|
|
4380
4745
|
}
|
|
4381
4746
|
if (isTrackingSuspended2()) {
|
|
4382
|
-
if (cs._d)
|
|
4383
|
-
const prev = cs._v;
|
|
4384
|
-
evaluating = true;
|
|
4385
|
-
try {
|
|
4386
|
-
retrack2(recompute, markDirty);
|
|
4387
|
-
if (!Object.is(prev, cs._v)) cs.__v++;
|
|
4388
|
-
} finally {
|
|
4389
|
-
evaluating = false;
|
|
4390
|
-
}
|
|
4391
|
-
}
|
|
4747
|
+
if (cs._d) validate();
|
|
4392
4748
|
return cs._v;
|
|
4393
4749
|
}
|
|
4750
|
+
if (cs._d) validate();
|
|
4394
4751
|
recordDependency2(cs);
|
|
4395
|
-
if (cs._d) {
|
|
4396
|
-
const oldValue = cs._v;
|
|
4397
|
-
evaluating = true;
|
|
4398
|
-
try {
|
|
4399
|
-
retrack2(recompute, markDirty);
|
|
4400
|
-
if (!Object.is(oldValue, cs._v)) cs.__v++;
|
|
4401
|
-
} finally {
|
|
4402
|
-
evaluating = false;
|
|
4403
|
-
}
|
|
4404
|
-
if (hook && oldValue !== cs._v) {
|
|
4405
|
-
hook.emit("computed:update", { signal: cs, oldValue, newValue: cs._v });
|
|
4406
|
-
}
|
|
4407
|
-
}
|
|
4408
4752
|
return cs._v;
|
|
4409
4753
|
}
|
|
4410
4754
|
if (debugName) {
|
|
@@ -4594,6 +4938,28 @@ function strictEffect(fn) {
|
|
|
4594
4938
|
}
|
|
4595
4939
|
|
|
4596
4940
|
// src/platform/enhance.ts
|
|
4941
|
+
var ENHANCED_ATTR = "data-sibu-enhanced";
|
|
4942
|
+
var enhancementOwner = /* @__PURE__ */ new WeakMap();
|
|
4943
|
+
function drainTeardowns(teardowns, label2) {
|
|
4944
|
+
let executed = 0;
|
|
4945
|
+
while (teardowns.length > 0) {
|
|
4946
|
+
const batch2 = teardowns.splice(0);
|
|
4947
|
+
for (let i2 = 0; i2 < batch2.length; i2++) {
|
|
4948
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
4949
|
+
const remaining = batch2.length - i2 + teardowns.length;
|
|
4950
|
+
teardowns.length = 0;
|
|
4951
|
+
reportDrainRunaway(label2, executed, remaining);
|
|
4952
|
+
return;
|
|
4953
|
+
}
|
|
4954
|
+
executed++;
|
|
4955
|
+
try {
|
|
4956
|
+
batch2[i2]();
|
|
4957
|
+
} catch (err) {
|
|
4958
|
+
if (typeof console !== "undefined") console.error(`[SibuJS ${label2}] teardown error:`, err);
|
|
4959
|
+
}
|
|
4960
|
+
}
|
|
4961
|
+
}
|
|
4962
|
+
}
|
|
4597
4963
|
function resolveTarget(root, target) {
|
|
4598
4964
|
if (target == null) return root;
|
|
4599
4965
|
if (typeof target !== "string") return target;
|
|
@@ -4636,7 +5002,7 @@ function enhance(target, setup) {
|
|
|
4636
5002
|
return () => {
|
|
4637
5003
|
};
|
|
4638
5004
|
}
|
|
4639
|
-
if (root.getAttribute(
|
|
5005
|
+
if (root.getAttribute(ENHANCED_ATTR) === "true") {
|
|
4640
5006
|
if (isDev() && typeof console !== "undefined") {
|
|
4641
5007
|
console.warn("[SibuJS enhance] element is already enhanced; ignoring re-enhance.", root);
|
|
4642
5008
|
}
|
|
@@ -4644,6 +5010,7 @@ function enhance(target, setup) {
|
|
|
4644
5010
|
};
|
|
4645
5011
|
}
|
|
4646
5012
|
const teardowns = [];
|
|
5013
|
+
const owner = /* @__PURE__ */ Symbol("sibujs.enhance");
|
|
4647
5014
|
let disposed = false;
|
|
4648
5015
|
const bind = (target_, fn) => {
|
|
4649
5016
|
const el = resolveTarget(root, target_);
|
|
@@ -4690,11 +5057,7 @@ function enhance(target, setup) {
|
|
|
4690
5057
|
effect(() => {
|
|
4691
5058
|
const v = value();
|
|
4692
5059
|
const next = v == null ? null : String(v);
|
|
4693
|
-
|
|
4694
|
-
if (el.hasAttribute(name)) el.removeAttribute(name);
|
|
4695
|
-
} else if (el.getAttribute(name) !== next) {
|
|
4696
|
-
el.setAttribute(name, next);
|
|
4697
|
-
}
|
|
5060
|
+
setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()" });
|
|
4698
5061
|
})
|
|
4699
5062
|
);
|
|
4700
5063
|
});
|
|
@@ -4721,10 +5084,10 @@ function enhance(target, setup) {
|
|
|
4721
5084
|
});
|
|
4722
5085
|
});
|
|
4723
5086
|
},
|
|
4724
|
-
model: (t,
|
|
5087
|
+
model: (t, state2, options) => {
|
|
4725
5088
|
bind(t, (el) => {
|
|
4726
5089
|
const control = el;
|
|
4727
|
-
const [get, set] =
|
|
5090
|
+
const [get, set] = state2;
|
|
4728
5091
|
const evt = options?.event ?? (control instanceof HTMLSelectElement || control instanceof HTMLInputElement && (control.type === "checkbox" || control.type === "radio") ? "change" : "input");
|
|
4729
5092
|
teardowns.push(
|
|
4730
5093
|
effect(() => {
|
|
@@ -4740,29 +5103,50 @@ function enhance(target, setup) {
|
|
|
4740
5103
|
teardowns.push(fn);
|
|
4741
5104
|
}
|
|
4742
5105
|
};
|
|
4743
|
-
|
|
5106
|
+
let extra;
|
|
5107
|
+
try {
|
|
5108
|
+
extra = setup(ctx);
|
|
5109
|
+
} catch (err) {
|
|
5110
|
+
drainTeardowns(teardowns, "enhance");
|
|
5111
|
+
throw err;
|
|
5112
|
+
}
|
|
4744
5113
|
if (typeof extra === "function") teardowns.push(extra);
|
|
4745
5114
|
const dispose2 = () => {
|
|
4746
5115
|
if (disposed) return;
|
|
4747
5116
|
disposed = true;
|
|
4748
|
-
|
|
4749
|
-
|
|
4750
|
-
|
|
4751
|
-
} catch (err) {
|
|
4752
|
-
if (typeof console !== "undefined") console.error("[SibuJS enhance] teardown error:", err);
|
|
4753
|
-
}
|
|
5117
|
+
if (enhancementOwner.get(root) === owner) {
|
|
5118
|
+
enhancementOwner.delete(root);
|
|
5119
|
+
root.removeAttribute(ENHANCED_ATTR);
|
|
4754
5120
|
}
|
|
5121
|
+
unregisterDisposer(root, dispose2);
|
|
5122
|
+
drainTeardowns(teardowns, "enhance");
|
|
4755
5123
|
};
|
|
4756
5124
|
registerDisposer(root, dispose2);
|
|
4757
|
-
|
|
5125
|
+
enhancementOwner.set(root, owner);
|
|
5126
|
+
root.setAttribute(ENHANCED_ATTR, "true");
|
|
4758
5127
|
return dispose2;
|
|
4759
5128
|
}
|
|
4760
5129
|
function enhanceAll(selector, setup) {
|
|
4761
5130
|
if (typeof document === "undefined") return () => {
|
|
4762
5131
|
};
|
|
4763
|
-
const disposers =
|
|
5132
|
+
const disposers = [];
|
|
5133
|
+
try {
|
|
5134
|
+
for (const el of Array.from(document.querySelectorAll(selector))) {
|
|
5135
|
+
disposers.push(enhance(el, setup));
|
|
5136
|
+
}
|
|
5137
|
+
} catch (err) {
|
|
5138
|
+
for (let i2 = disposers.length - 1; i2 >= 0; i2--) {
|
|
5139
|
+
try {
|
|
5140
|
+
disposers[i2]();
|
|
5141
|
+
} catch (rollbackErr) {
|
|
5142
|
+
if (typeof console !== "undefined") console.error("[SibuJS enhanceAll] rollback error:", rollbackErr);
|
|
5143
|
+
}
|
|
5144
|
+
}
|
|
5145
|
+
disposers.length = 0;
|
|
5146
|
+
throw err;
|
|
5147
|
+
}
|
|
4764
5148
|
return () => {
|
|
4765
|
-
for (const d of disposers) d();
|
|
5149
|
+
for (const d of disposers.splice(0)) d();
|
|
4766
5150
|
};
|
|
4767
5151
|
}
|
|
4768
5152
|
|
|
@@ -4802,6 +5186,7 @@ function mountIslands(root = typeof document !== "undefined" ? document : null,
|
|
|
4802
5186
|
};
|
|
4803
5187
|
const cancels = [];
|
|
4804
5188
|
const disposers = [];
|
|
5189
|
+
let torndown = false;
|
|
4805
5190
|
for (const el of Array.from(root.querySelectorAll("[data-sibu-island]"))) {
|
|
4806
5191
|
if (el.getAttribute("data-sibu-enhanced") === "true") continue;
|
|
4807
5192
|
const name = el.getAttribute("data-sibu-island") ?? "";
|
|
@@ -4815,17 +5200,23 @@ function mountIslands(root = typeof document !== "undefined" ? document : null,
|
|
|
4815
5200
|
}
|
|
4816
5201
|
let activated = false;
|
|
4817
5202
|
const activate = () => {
|
|
4818
|
-
if (activated) return;
|
|
5203
|
+
if (activated || torndown) return;
|
|
4819
5204
|
activated = true;
|
|
4820
5205
|
const reg = registry.get(name);
|
|
4821
5206
|
if (!reg) return;
|
|
4822
5207
|
resolveSetup(reg).then((setup) => {
|
|
5208
|
+
if (torndown) return;
|
|
4823
5209
|
if (!setup) {
|
|
4824
5210
|
if (typeof console !== "undefined") console.warn(`[SibuJS islands] "${name}" loader produced no setup.`);
|
|
4825
5211
|
return;
|
|
4826
5212
|
}
|
|
4827
5213
|
try {
|
|
4828
|
-
|
|
5214
|
+
const disposeIsland = enhance(el, setup);
|
|
5215
|
+
if (torndown) {
|
|
5216
|
+
disposeIsland();
|
|
5217
|
+
return;
|
|
5218
|
+
}
|
|
5219
|
+
disposers.push(disposeIsland);
|
|
4829
5220
|
el.setAttribute("data-sibu-hydrated", "true");
|
|
4830
5221
|
} catch (err) {
|
|
4831
5222
|
if (typeof console !== "undefined") console.error(`[SibuJS islands] "${name}" failed to mount:`, err);
|
|
@@ -4838,6 +5229,7 @@ function mountIslands(root = typeof document !== "undefined" ? document : null,
|
|
|
4838
5229
|
cancels.push(schedule(strategy, el, activate, options));
|
|
4839
5230
|
}
|
|
4840
5231
|
return () => {
|
|
5232
|
+
torndown = true;
|
|
4841
5233
|
for (const c of cancels.splice(0)) c();
|
|
4842
5234
|
for (const d of disposers.splice(0)) d();
|
|
4843
5235
|
};
|
|
@@ -5013,6 +5405,7 @@ function nextTick() {
|
|
|
5013
5405
|
Fragment,
|
|
5014
5406
|
KeepAlive,
|
|
5015
5407
|
Loading,
|
|
5408
|
+
MAX_DRAIN_TEARDOWNS,
|
|
5016
5409
|
Portal,
|
|
5017
5410
|
SVG_NS,
|
|
5018
5411
|
Suspense,
|
|
@@ -5090,6 +5483,7 @@ function nextTick() {
|
|
|
5090
5483
|
g,
|
|
5091
5484
|
getAction,
|
|
5092
5485
|
getRequestScopedCache,
|
|
5486
|
+
getRuntimeErrorHandler,
|
|
5093
5487
|
getSSRStore,
|
|
5094
5488
|
getSlot,
|
|
5095
5489
|
h1,
|
|
@@ -5163,6 +5557,9 @@ function nextTick() {
|
|
|
5163
5557
|
registerComponent,
|
|
5164
5558
|
registerDisposer,
|
|
5165
5559
|
registerIsland,
|
|
5560
|
+
replaceChildrenSafely,
|
|
5561
|
+
reportDrainRunaway,
|
|
5562
|
+
reportError,
|
|
5166
5563
|
resolveComponent,
|
|
5167
5564
|
retrack,
|
|
5168
5565
|
rp,
|
|
@@ -5176,6 +5573,7 @@ function nextTick() {
|
|
|
5176
5573
|
select,
|
|
5177
5574
|
setGlobalErrorHandler,
|
|
5178
5575
|
setMaxDrainIterations,
|
|
5576
|
+
setRuntimeErrorHandler,
|
|
5179
5577
|
show,
|
|
5180
5578
|
signal,
|
|
5181
5579
|
slot,
|
|
@@ -5215,6 +5613,7 @@ function nextTick() {
|
|
|
5215
5613
|
u,
|
|
5216
5614
|
ul,
|
|
5217
5615
|
unregisterComponent,
|
|
5616
|
+
unregisterDisposer,
|
|
5218
5617
|
unregisterIsland,
|
|
5219
5618
|
untracked,
|
|
5220
5619
|
use,
|