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
|
@@ -135,45 +135,40 @@ import {
|
|
|
135
135
|
use,
|
|
136
136
|
var_,
|
|
137
137
|
video
|
|
138
|
-
} from "./chunk-
|
|
138
|
+
} from "./chunk-ES2GERY2.js";
|
|
139
|
+
import {
|
|
140
|
+
trustHTML
|
|
141
|
+
} from "./chunk-HYCCIYNS.js";
|
|
139
142
|
import {
|
|
140
143
|
watch
|
|
141
|
-
} from "./chunk-
|
|
144
|
+
} from "./chunk-RRIDJQ5C.js";
|
|
142
145
|
import {
|
|
143
146
|
__resetIdCounter,
|
|
144
147
|
createId
|
|
145
148
|
} from "./chunk-CCSJMTRN.js";
|
|
146
|
-
import {
|
|
147
|
-
trustHTML
|
|
148
|
-
} from "./chunk-EX77FXTT.js";
|
|
149
149
|
import {
|
|
150
150
|
context
|
|
151
|
-
} from "./chunk-
|
|
151
|
+
} from "./chunk-O3QQ3XOL.js";
|
|
152
152
|
import {
|
|
153
153
|
SVG_NS,
|
|
154
154
|
bindChildNode,
|
|
155
155
|
tagFactory
|
|
156
|
-
} from "./chunk-
|
|
156
|
+
} from "./chunk-DQVUBVNX.js";
|
|
157
157
|
import {
|
|
158
158
|
bindAttribute,
|
|
159
|
-
bindDynamic
|
|
160
|
-
|
|
159
|
+
bindDynamic,
|
|
160
|
+
setSafeAttribute
|
|
161
|
+
} from "./chunk-4MFZMLUU.js";
|
|
161
162
|
import {
|
|
162
163
|
derived
|
|
163
|
-
} from "./chunk-
|
|
164
|
+
} from "./chunk-Z2CE42DB.js";
|
|
164
165
|
import {
|
|
165
166
|
globalSingleton
|
|
166
167
|
} from "./chunk-7ZHH77QA.js";
|
|
167
|
-
import {
|
|
168
|
-
isEventHandlerAttr,
|
|
169
|
-
isUrlAttribute,
|
|
170
|
-
sanitizeSrcset,
|
|
171
|
-
sanitizeUrl
|
|
172
|
-
} from "./chunk-L3GAGWCC.js";
|
|
173
168
|
import {
|
|
174
169
|
effect,
|
|
175
170
|
on
|
|
176
|
-
} from "./chunk-
|
|
171
|
+
} from "./chunk-PBQEW5VW.js";
|
|
177
172
|
import {
|
|
178
173
|
disableSSR,
|
|
179
174
|
enableSSR,
|
|
@@ -182,18 +177,22 @@ import {
|
|
|
182
177
|
isSSR,
|
|
183
178
|
runInSSRContext,
|
|
184
179
|
withSSR
|
|
185
|
-
} from "./chunk-
|
|
180
|
+
} from "./chunk-TIRZCERI.js";
|
|
186
181
|
import {
|
|
182
|
+
MAX_DRAIN_TEARDOWNS,
|
|
187
183
|
checkLeaks,
|
|
188
184
|
dispose,
|
|
189
|
-
registerDisposer
|
|
190
|
-
|
|
185
|
+
registerDisposer,
|
|
186
|
+
replaceChildrenSafely,
|
|
187
|
+
reportDrainRunaway,
|
|
188
|
+
unregisterDisposer
|
|
189
|
+
} from "./chunk-DHDZ7IVN.js";
|
|
191
190
|
import {
|
|
192
191
|
batch,
|
|
193
192
|
enqueueBatchedSignal,
|
|
194
193
|
isBatching,
|
|
195
194
|
signal
|
|
196
|
-
} from "./chunk-
|
|
195
|
+
} from "./chunk-W55YHPEP.js";
|
|
197
196
|
import {
|
|
198
197
|
notifySubscribers,
|
|
199
198
|
recordDependency,
|
|
@@ -203,13 +202,17 @@ import {
|
|
|
203
202
|
suspendTracking,
|
|
204
203
|
track,
|
|
205
204
|
untracked
|
|
206
|
-
} from "./chunk-
|
|
205
|
+
} from "./chunk-ACBT6UZS.js";
|
|
207
206
|
import {
|
|
208
207
|
__export,
|
|
209
208
|
devAssert,
|
|
210
209
|
devWarn,
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
getRuntimeErrorHandler,
|
|
211
|
+
isDev,
|
|
212
|
+
normalizeError,
|
|
213
|
+
reportError,
|
|
214
|
+
setRuntimeErrorHandler
|
|
215
|
+
} from "./chunk-VPP2FONR.js";
|
|
213
216
|
|
|
214
217
|
// index.ts
|
|
215
218
|
var index_exports = {};
|
|
@@ -220,6 +223,7 @@ __export(index_exports, {
|
|
|
220
223
|
Fragment: () => Fragment,
|
|
221
224
|
KeepAlive: () => KeepAlive,
|
|
222
225
|
Loading: () => Loading,
|
|
226
|
+
MAX_DRAIN_TEARDOWNS: () => MAX_DRAIN_TEARDOWNS,
|
|
223
227
|
Portal: () => Portal,
|
|
224
228
|
SVG_NS: () => SVG_NS,
|
|
225
229
|
Suspense: () => Suspense,
|
|
@@ -297,6 +301,7 @@ __export(index_exports, {
|
|
|
297
301
|
g: () => g,
|
|
298
302
|
getAction: () => getAction,
|
|
299
303
|
getRequestScopedCache: () => getRequestScopedCache,
|
|
304
|
+
getRuntimeErrorHandler: () => getRuntimeErrorHandler,
|
|
300
305
|
getSSRStore: () => getSSRStore,
|
|
301
306
|
getSlot: () => getSlot,
|
|
302
307
|
h1: () => h1,
|
|
@@ -370,6 +375,9 @@ __export(index_exports, {
|
|
|
370
375
|
registerComponent: () => registerComponent,
|
|
371
376
|
registerDisposer: () => registerDisposer,
|
|
372
377
|
registerIsland: () => registerIsland,
|
|
378
|
+
replaceChildrenSafely: () => replaceChildrenSafely,
|
|
379
|
+
reportDrainRunaway: () => reportDrainRunaway,
|
|
380
|
+
reportError: () => reportError,
|
|
373
381
|
resolveComponent: () => resolveComponent,
|
|
374
382
|
retrack: () => retrack,
|
|
375
383
|
rp: () => rp,
|
|
@@ -383,6 +391,7 @@ __export(index_exports, {
|
|
|
383
391
|
select: () => select,
|
|
384
392
|
setGlobalErrorHandler: () => setGlobalErrorHandler,
|
|
385
393
|
setMaxDrainIterations: () => setMaxDrainIterations,
|
|
394
|
+
setRuntimeErrorHandler: () => setRuntimeErrorHandler,
|
|
386
395
|
show: () => show,
|
|
387
396
|
signal: () => signal,
|
|
388
397
|
slot: () => slot,
|
|
@@ -422,6 +431,7 @@ __export(index_exports, {
|
|
|
422
431
|
u: () => u,
|
|
423
432
|
ul: () => ul,
|
|
424
433
|
unregisterComponent: () => unregisterComponent,
|
|
434
|
+
unregisterDisposer: () => unregisterDisposer,
|
|
425
435
|
unregisterIsland: () => unregisterIsland,
|
|
426
436
|
untracked: () => untracked,
|
|
427
437
|
use: () => use,
|
|
@@ -436,18 +446,14 @@ __export(index_exports, {
|
|
|
436
446
|
// src/core/rendering/lazy.ts
|
|
437
447
|
var PENDING_ERROR = "__sibuPendingError";
|
|
438
448
|
function dispatchPropagate(node, error) {
|
|
439
|
-
const
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
return true;
|
|
444
|
-
} catch {
|
|
445
|
-
return false;
|
|
446
|
-
}
|
|
449
|
+
const report = () => {
|
|
450
|
+
if (!node.parentNode) return false;
|
|
451
|
+
reportError(error, { phase: "render", name: "lazy", node });
|
|
452
|
+
return true;
|
|
447
453
|
};
|
|
448
|
-
if (
|
|
454
|
+
if (report()) return;
|
|
449
455
|
queueMicrotask(() => {
|
|
450
|
-
if (
|
|
456
|
+
if (report()) return;
|
|
451
457
|
node[PENDING_ERROR] = error;
|
|
452
458
|
});
|
|
453
459
|
}
|
|
@@ -472,12 +478,14 @@ function lazy(importFn) {
|
|
|
472
478
|
if (disposed) return;
|
|
473
479
|
cached = mod.default;
|
|
474
480
|
const rendered = cached();
|
|
475
|
-
container
|
|
481
|
+
replaceChildrenSafely(container, rendered);
|
|
476
482
|
}).catch((err) => {
|
|
477
483
|
if (disposed) return;
|
|
478
484
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
479
|
-
|
|
480
|
-
|
|
485
|
+
replaceChildrenSafely(
|
|
486
|
+
container,
|
|
487
|
+
div({ class: "sibu-lazy-error" }, `Failed to load component: ${errorObj.message}`)
|
|
488
|
+
);
|
|
481
489
|
dispatchPropagate(container, errorObj);
|
|
482
490
|
});
|
|
483
491
|
container.appendChild(span("sibu-lazy-loading", "Loading..."));
|
|
@@ -509,7 +517,7 @@ function Suspense({ nodes, fallback }) {
|
|
|
509
517
|
childEl = el;
|
|
510
518
|
if (el.classList.contains("sibu-lazy")) {
|
|
511
519
|
if (!el.querySelector(".sibu-lazy-loading")) {
|
|
512
|
-
container
|
|
520
|
+
replaceChildrenSafely(container, el);
|
|
513
521
|
return;
|
|
514
522
|
}
|
|
515
523
|
observer = new MutationObserver(() => {
|
|
@@ -518,16 +526,15 @@ function Suspense({ nodes, fallback }) {
|
|
|
518
526
|
if (!loading) {
|
|
519
527
|
observer?.disconnect();
|
|
520
528
|
observer = null;
|
|
521
|
-
container
|
|
529
|
+
replaceChildrenSafely(container, el);
|
|
522
530
|
}
|
|
523
531
|
});
|
|
524
532
|
observer.observe(el, { childList: true, subtree: true });
|
|
525
533
|
} else {
|
|
526
|
-
container
|
|
534
|
+
replaceChildrenSafely(container, el);
|
|
527
535
|
}
|
|
528
536
|
} catch (err) {
|
|
529
537
|
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
530
|
-
devWarn(`[SibuJS] Suspense nodes() threw: ${errorObj.message}`);
|
|
531
538
|
dispatchPropagate(container, errorObj);
|
|
532
539
|
}
|
|
533
540
|
});
|
|
@@ -539,7 +546,8 @@ function safeCall(cb, hookName) {
|
|
|
539
546
|
try {
|
|
540
547
|
return cb();
|
|
541
548
|
} catch (err) {
|
|
542
|
-
|
|
549
|
+
const phase = hookName.toLowerCase().includes("unmount") ? "cleanup" : "effect";
|
|
550
|
+
reportError(err, { phase, name: hookName });
|
|
543
551
|
return void 0;
|
|
544
552
|
}
|
|
545
553
|
}
|
|
@@ -970,14 +978,14 @@ function parseStack(stack) {
|
|
|
970
978
|
}
|
|
971
979
|
return frames;
|
|
972
980
|
}
|
|
973
|
-
function
|
|
981
|
+
function normalizeError2(err) {
|
|
974
982
|
if (err instanceof Error) {
|
|
975
983
|
const code2 = err.code ?? err.name ?? "ERROR";
|
|
976
984
|
const message = err.message || "Unknown error";
|
|
977
985
|
const stack = err.stack ?? "";
|
|
978
986
|
const frames = parseStack(stack);
|
|
979
987
|
const rawCause = err.cause;
|
|
980
|
-
const cause = rawCause != null ?
|
|
988
|
+
const cause = rawCause != null ? normalizeError2(rawCause) : null;
|
|
981
989
|
return { code: code2, message, stack, frames, cause };
|
|
982
990
|
}
|
|
983
991
|
return {
|
|
@@ -1073,7 +1081,7 @@ function renderMetadata(meta2) {
|
|
|
1073
1081
|
function ErrorDisplay(props) {
|
|
1074
1082
|
injectStyles();
|
|
1075
1083
|
const severity = props.severity ?? "error";
|
|
1076
|
-
const normalized =
|
|
1084
|
+
const normalized = normalizeError2(props.error);
|
|
1077
1085
|
const showDetails = props.alwaysShowDetails ?? isDev();
|
|
1078
1086
|
const headline = props.title ?? normalized.message;
|
|
1079
1087
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").slice(0, 19);
|
|
@@ -1323,6 +1331,7 @@ var errorBoundaryStyles = `
|
|
|
1323
1331
|
background: #3a3a4e;
|
|
1324
1332
|
}
|
|
1325
1333
|
`;
|
|
1334
|
+
var RESET_KEY_THREW = /* @__PURE__ */ Symbol("sibujs.ErrorBoundary.resetKeyThrew");
|
|
1326
1335
|
var stylesInjected = false;
|
|
1327
1336
|
function injectStyles2() {
|
|
1328
1337
|
if (!stylesInjected && typeof document !== "undefined") {
|
|
@@ -1331,29 +1340,6 @@ function injectStyles2() {
|
|
|
1331
1340
|
stylesInjected = true;
|
|
1332
1341
|
}
|
|
1333
1342
|
}
|
|
1334
|
-
var FALLBACK_CACHE_MAX = 50;
|
|
1335
|
-
var fallbackCache = /* @__PURE__ */ new WeakMap();
|
|
1336
|
-
function getMemoizedFallback(fallbackFn, error, retry) {
|
|
1337
|
-
let cache2 = fallbackCache.get(fallbackFn);
|
|
1338
|
-
if (!cache2) {
|
|
1339
|
-
cache2 = /* @__PURE__ */ new Map();
|
|
1340
|
-
fallbackCache.set(fallbackFn, cache2);
|
|
1341
|
-
}
|
|
1342
|
-
const key = error.message;
|
|
1343
|
-
let factory = cache2.get(key);
|
|
1344
|
-
if (factory) {
|
|
1345
|
-
cache2.delete(key);
|
|
1346
|
-
cache2.set(key, factory);
|
|
1347
|
-
} else {
|
|
1348
|
-
factory = () => fallbackFn(error, retry);
|
|
1349
|
-
cache2.set(key, factory);
|
|
1350
|
-
if (cache2.size > FALLBACK_CACHE_MAX) {
|
|
1351
|
-
const oldestKey = cache2.keys().next().value;
|
|
1352
|
-
if (oldestKey !== void 0) cache2.delete(oldestKey);
|
|
1353
|
-
}
|
|
1354
|
-
}
|
|
1355
|
-
return factory();
|
|
1356
|
-
}
|
|
1357
1343
|
function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
1358
1344
|
const children = typeof optionsOrChildren === "function" ? optionsOrChildren : maybeChildren;
|
|
1359
1345
|
const options = typeof optionsOrChildren === "function" ? {} : optionsOrChildren;
|
|
@@ -1361,43 +1347,61 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
1361
1347
|
injectStyles2();
|
|
1362
1348
|
const [error, setError] = signal(null);
|
|
1363
1349
|
const retry = () => {
|
|
1364
|
-
|
|
1365
|
-
const cur = error();
|
|
1366
|
-
const inner = fallbackCache.get(fallback);
|
|
1367
|
-
if (cur && inner) inner.delete(cur.message);
|
|
1368
|
-
}
|
|
1350
|
+
stopResetKeysWatcher();
|
|
1369
1351
|
setError(null);
|
|
1370
1352
|
};
|
|
1371
1353
|
let resetKeysTeardown = null;
|
|
1372
|
-
|
|
1373
|
-
|
|
1354
|
+
const stopResetKeysWatcher = () => {
|
|
1355
|
+
if (!resetKeysTeardown) return;
|
|
1356
|
+
const teardown = resetKeysTeardown;
|
|
1357
|
+
resetKeysTeardown = null;
|
|
1358
|
+
teardown();
|
|
1359
|
+
};
|
|
1360
|
+
const readResetKeyValues = (keys) => {
|
|
1361
|
+
const values = new Array(keys.length);
|
|
1362
|
+
for (let i2 = 0; i2 < keys.length; i2++) {
|
|
1363
|
+
try {
|
|
1364
|
+
values[i2] = keys[i2]();
|
|
1365
|
+
} catch (err) {
|
|
1366
|
+
reportError(err, { phase: "effect", name: "ErrorBoundary.resetKeys" });
|
|
1367
|
+
values[i2] = RESET_KEY_THREW;
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
return values;
|
|
1371
|
+
};
|
|
1372
|
+
const startResetKeysWatcher = () => {
|
|
1373
|
+
const keys = resetKeys;
|
|
1374
|
+
if (!keys || keys.length === 0) return;
|
|
1375
|
+
stopResetKeysWatcher();
|
|
1376
|
+
let baseline = null;
|
|
1374
1377
|
resetKeysTeardown = effect(() => {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1378
|
+
const current = readResetKeyValues(keys);
|
|
1379
|
+
if (baseline === null) {
|
|
1380
|
+
baseline = current;
|
|
1381
|
+
return;
|
|
1382
|
+
}
|
|
1383
|
+
let changed = current.length !== baseline.length;
|
|
1384
|
+
if (!changed) {
|
|
1385
|
+
for (let i2 = 0; i2 < current.length; i2++) {
|
|
1386
|
+
if (!Object.is(current[i2], baseline[i2])) {
|
|
1387
|
+
changed = true;
|
|
1388
|
+
break;
|
|
1381
1389
|
}
|
|
1382
1390
|
}
|
|
1383
1391
|
}
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
return;
|
|
1387
|
-
}
|
|
1388
|
-
if (error() !== null) retry();
|
|
1392
|
+
baseline = current;
|
|
1393
|
+
if (changed) retry();
|
|
1389
1394
|
});
|
|
1390
|
-
}
|
|
1395
|
+
};
|
|
1391
1396
|
const handleError = (e) => {
|
|
1392
|
-
const errorObj =
|
|
1397
|
+
const errorObj = normalizeError(e);
|
|
1393
1398
|
setError(errorObj);
|
|
1399
|
+
startResetKeysWatcher();
|
|
1394
1400
|
if (onError) {
|
|
1395
1401
|
try {
|
|
1396
1402
|
onError(errorObj);
|
|
1397
1403
|
} catch (cbErr) {
|
|
1398
|
-
|
|
1399
|
-
console.error("[SibuJS ErrorBoundary] onError callback threw:", cbErr);
|
|
1400
|
-
}
|
|
1404
|
+
reportError(cbErr, { phase: "render", name: "ErrorBoundary onError callback" });
|
|
1401
1405
|
}
|
|
1402
1406
|
}
|
|
1403
1407
|
return errorObj;
|
|
@@ -1408,18 +1412,14 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
1408
1412
|
const tryRenderFallback = (err) => {
|
|
1409
1413
|
const fn = fallback || defaultFallback;
|
|
1410
1414
|
try {
|
|
1411
|
-
return
|
|
1415
|
+
return fn(err, retry);
|
|
1412
1416
|
} catch (fallbackError) {
|
|
1413
|
-
const propagateError = fallbackError instanceof Error ? fallbackError : new Error(String(fallbackError));
|
|
1414
1417
|
queueMicrotask(() => {
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
})
|
|
1421
|
-
);
|
|
1422
|
-
}
|
|
1418
|
+
reportError(fallbackError, {
|
|
1419
|
+
phase: "render",
|
|
1420
|
+
name: "ErrorBoundary fallback",
|
|
1421
|
+
node: container.parentNode ? container : void 0
|
|
1422
|
+
});
|
|
1423
1423
|
});
|
|
1424
1424
|
return document.createComment("error-boundary-failed");
|
|
1425
1425
|
}
|
|
@@ -1436,11 +1436,20 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
1436
1436
|
if (result && typeof result.then === "function") {
|
|
1437
1437
|
const asyncContainer = div({ class: "sibu-error-async" });
|
|
1438
1438
|
asyncContainer.appendChild(span({ class: "sibu-lazy-loading", nodes: "Loading..." }));
|
|
1439
|
+
let asyncDisposed = false;
|
|
1440
|
+
registerDisposer(asyncContainer, () => {
|
|
1441
|
+
asyncDisposed = true;
|
|
1442
|
+
});
|
|
1439
1443
|
result.then((el) => {
|
|
1440
|
-
|
|
1444
|
+
if (asyncDisposed) {
|
|
1445
|
+
dispose(el);
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
replaceChildrenSafely(asyncContainer, el);
|
|
1441
1449
|
}).catch((e) => {
|
|
1450
|
+
if (asyncDisposed) return;
|
|
1442
1451
|
const err = handleError(e);
|
|
1443
|
-
asyncContainer
|
|
1452
|
+
replaceChildrenSafely(asyncContainer, tryRenderFallback(err));
|
|
1444
1453
|
});
|
|
1445
1454
|
return asyncContainer;
|
|
1446
1455
|
}
|
|
@@ -1453,12 +1462,12 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
1453
1462
|
});
|
|
1454
1463
|
const propagateListener = (e) => {
|
|
1455
1464
|
if (error()) return;
|
|
1456
|
-
e.stopPropagation();
|
|
1457
1465
|
const customEvent = e;
|
|
1458
1466
|
const propagatedError = customEvent.detail?.error;
|
|
1459
|
-
if (propagatedError)
|
|
1460
|
-
|
|
1461
|
-
|
|
1467
|
+
if (!propagatedError) return;
|
|
1468
|
+
e.preventDefault();
|
|
1469
|
+
e.stopPropagation();
|
|
1470
|
+
handleError(propagatedError);
|
|
1462
1471
|
};
|
|
1463
1472
|
container.addEventListener("sibu:error-propagate", propagateListener);
|
|
1464
1473
|
onMount(() => {
|
|
@@ -1486,7 +1495,7 @@ function ErrorBoundary(optionsOrChildren, maybeChildren) {
|
|
|
1486
1495
|
return void 0;
|
|
1487
1496
|
}, container);
|
|
1488
1497
|
registerDisposer(container, () => {
|
|
1489
|
-
|
|
1498
|
+
stopResetKeysWatcher();
|
|
1490
1499
|
container.removeEventListener("sibu:error-propagate", propagateListener);
|
|
1491
1500
|
});
|
|
1492
1501
|
return container;
|
|
@@ -1836,10 +1845,7 @@ function DynamicComponent(is) {
|
|
|
1836
1845
|
} else {
|
|
1837
1846
|
el = resolveComponent(target);
|
|
1838
1847
|
}
|
|
1839
|
-
|
|
1840
|
-
dispose(child);
|
|
1841
|
-
}
|
|
1842
|
-
container.replaceChildren(el);
|
|
1848
|
+
replaceChildrenSafely(container, el);
|
|
1843
1849
|
}
|
|
1844
1850
|
const untrack = track(render);
|
|
1845
1851
|
registerDisposer(container, untrack);
|
|
@@ -1900,6 +1906,10 @@ function each(getArray, render, options) {
|
|
|
1900
1906
|
let oldLen = 0;
|
|
1901
1907
|
let nodeMap = /* @__PURE__ */ new Map();
|
|
1902
1908
|
let workMap = /* @__PURE__ */ new Map();
|
|
1909
|
+
const pendingRows = [];
|
|
1910
|
+
const pendingItems = [];
|
|
1911
|
+
const pendingIndices = [];
|
|
1912
|
+
let pendingCount = 0;
|
|
1903
1913
|
let newNodes = [];
|
|
1904
1914
|
let newKeysBuf = [];
|
|
1905
1915
|
let isStableBuf = new Uint8Array(0);
|
|
@@ -1909,8 +1919,10 @@ function each(getArray, render, options) {
|
|
|
1909
1919
|
const keyIndexMap = /* @__PURE__ */ new Map();
|
|
1910
1920
|
let initialized = false;
|
|
1911
1921
|
let sentinelInserted = false;
|
|
1922
|
+
let rangeDisposed = false;
|
|
1912
1923
|
const keyFn = options.key;
|
|
1913
1924
|
const update = () => {
|
|
1925
|
+
if (rangeDisposed) return;
|
|
1914
1926
|
const arr = getArray();
|
|
1915
1927
|
const newLen = arr.length;
|
|
1916
1928
|
const parent = anchor.parentNode;
|
|
@@ -1939,49 +1951,44 @@ function each(getArray, render, options) {
|
|
|
1939
1951
|
}
|
|
1940
1952
|
keyIndexMap.set(newKeys[i2], i2);
|
|
1941
1953
|
}
|
|
1954
|
+
pendingCount = 0;
|
|
1942
1955
|
for (let i2 = 0; i2 < newLen; i2++) {
|
|
1943
1956
|
const key = newKeys[i2];
|
|
1944
1957
|
const existing = nodeMap.get(key);
|
|
1945
|
-
let
|
|
1958
|
+
let row;
|
|
1946
1959
|
if (existing !== void 0) {
|
|
1947
|
-
|
|
1960
|
+
row = existing;
|
|
1961
|
+
pendingRows[pendingCount] = row;
|
|
1962
|
+
pendingItems[pendingCount] = arr[i2];
|
|
1963
|
+
pendingIndices[pendingCount] = i2;
|
|
1964
|
+
pendingCount++;
|
|
1948
1965
|
} else {
|
|
1949
|
-
const
|
|
1950
|
-
const
|
|
1951
|
-
|
|
1966
|
+
const [itemGetter, setItem] = signal(arr[i2]);
|
|
1967
|
+
const [indexGetter, setIndex] = signal(i2);
|
|
1968
|
+
let node;
|
|
1952
1969
|
try {
|
|
1953
1970
|
node = resolveNodeChild(render(itemGetter, indexGetter));
|
|
1954
1971
|
} catch (err) {
|
|
1955
|
-
|
|
1956
|
-
devWarn(
|
|
1957
|
-
`each: render threw for item at index ${i2} (key="${newKeys[i2]}"): ${err instanceof Error ? err.message : String(err)}`
|
|
1958
|
-
);
|
|
1959
|
-
}
|
|
1972
|
+
const key2 = newKeys[i2];
|
|
1960
1973
|
node = document.createComment(`each:error:${i2}`);
|
|
1961
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
1962
1974
|
queueMicrotask(() => {
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
);
|
|
1969
|
-
} else if (_isDev) {
|
|
1970
|
-
devWarn(`each: error not surfaced \u2014 anchor detached: ${errorObj.message}`);
|
|
1971
|
-
}
|
|
1972
|
-
} catch {
|
|
1973
|
-
}
|
|
1975
|
+
reportError(err, {
|
|
1976
|
+
phase: "render",
|
|
1977
|
+
name: `each row (key="${String(key2)}")`,
|
|
1978
|
+
node: anchor.parentNode ? anchor : void 0
|
|
1979
|
+
});
|
|
1974
1980
|
});
|
|
1975
1981
|
}
|
|
1982
|
+
row = { node, item: itemGetter, setItem, index: indexGetter, setIndex };
|
|
1976
1983
|
}
|
|
1977
|
-
workMap.set(key,
|
|
1978
|
-
newNodes[i2] = node;
|
|
1984
|
+
workMap.set(key, row);
|
|
1985
|
+
newNodes[i2] = row.node;
|
|
1979
1986
|
}
|
|
1980
|
-
for (const [key,
|
|
1987
|
+
for (const [key, row] of nodeMap) {
|
|
1981
1988
|
if (!workMap.has(key)) {
|
|
1982
|
-
dispose(node);
|
|
1983
|
-
if (node.parentNode) {
|
|
1984
|
-
parent.removeChild(node);
|
|
1989
|
+
dispose(row.node);
|
|
1990
|
+
if (row.node.parentNode) {
|
|
1991
|
+
parent.removeChild(row.node);
|
|
1985
1992
|
}
|
|
1986
1993
|
}
|
|
1987
1994
|
}
|
|
@@ -1990,6 +1997,8 @@ function each(getArray, render, options) {
|
|
|
1990
1997
|
const tmp2 = nodeMap;
|
|
1991
1998
|
nodeMap = workMap;
|
|
1992
1999
|
workMap = tmp2;
|
|
2000
|
+
initialized = true;
|
|
2001
|
+
pendingCount = 0;
|
|
1993
2002
|
return;
|
|
1994
2003
|
}
|
|
1995
2004
|
oldKeyIndex.clear();
|
|
@@ -2039,12 +2048,47 @@ function each(getArray, render, options) {
|
|
|
2039
2048
|
nodeMap = workMap;
|
|
2040
2049
|
workMap = tmp;
|
|
2041
2050
|
initialized = true;
|
|
2051
|
+
flushRowCells();
|
|
2042
2052
|
};
|
|
2053
|
+
function flushRowCells() {
|
|
2054
|
+
if (pendingCount === 0) return;
|
|
2055
|
+
const count = pendingCount;
|
|
2056
|
+
pendingCount = 0;
|
|
2057
|
+
batch(() => {
|
|
2058
|
+
for (let i2 = 0; i2 < count; i2++) {
|
|
2059
|
+
const row = pendingRows[i2];
|
|
2060
|
+
row.setItem(pendingItems[i2]);
|
|
2061
|
+
row.setIndex(pendingIndices[i2]);
|
|
2062
|
+
pendingRows[i2] = void 0;
|
|
2063
|
+
pendingItems[i2] = void 0;
|
|
2064
|
+
}
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2043
2067
|
const untrack = track(update);
|
|
2044
|
-
|
|
2068
|
+
const disposeRange = () => {
|
|
2069
|
+
if (rangeDisposed) return;
|
|
2070
|
+
rangeDisposed = true;
|
|
2071
|
+
untrack();
|
|
2072
|
+
for (const row of nodeMap.values()) {
|
|
2073
|
+
dispose(row.node);
|
|
2074
|
+
row.node.parentNode?.removeChild(row.node);
|
|
2075
|
+
}
|
|
2076
|
+
if (end.parentNode) end.parentNode.removeChild(end);
|
|
2077
|
+
sentinelInserted = false;
|
|
2078
|
+
nodeMap.clear();
|
|
2079
|
+
workMap.clear();
|
|
2080
|
+
keyIndexMap.clear();
|
|
2081
|
+
oldKeyIndex.clear();
|
|
2082
|
+
oldLen = 0;
|
|
2083
|
+
pendingRows.length = 0;
|
|
2084
|
+
pendingItems.length = 0;
|
|
2085
|
+
pendingIndices.length = 0;
|
|
2086
|
+
pendingCount = 0;
|
|
2087
|
+
};
|
|
2088
|
+
registerDisposer(anchor, disposeRange);
|
|
2045
2089
|
if (!initialized) {
|
|
2046
2090
|
queueMicrotask(() => {
|
|
2047
|
-
if (!initialized && anchor.parentNode) {
|
|
2091
|
+
if (!initialized && !rangeDisposed && anchor.parentNode) {
|
|
2048
2092
|
update();
|
|
2049
2093
|
}
|
|
2050
2094
|
});
|
|
@@ -2343,20 +2387,11 @@ function executeElement(tmpl, values) {
|
|
|
2343
2387
|
break;
|
|
2344
2388
|
case 1: {
|
|
2345
2389
|
const name = attr.name;
|
|
2346
|
-
const lname = name.toLowerCase();
|
|
2347
|
-
if (isEventHandlerAttr(name)) break;
|
|
2348
2390
|
const val = values[attr.idx];
|
|
2349
2391
|
if (typeof val === "function") {
|
|
2350
2392
|
registerDisposer(el, bindAttribute(el, name, val));
|
|
2351
|
-
} else
|
|
2352
|
-
|
|
2353
|
-
if (lname === "srcset") {
|
|
2354
|
-
el.setAttribute(name, sanitizeSrcset(str));
|
|
2355
|
-
} else if (isUrlAttribute(lname)) {
|
|
2356
|
-
el.setAttribute(name, sanitizeUrl(str));
|
|
2357
|
-
} else {
|
|
2358
|
-
el.setAttribute(name, str);
|
|
2359
|
-
}
|
|
2393
|
+
} else {
|
|
2394
|
+
setSafeAttribute(el, name, val, { syncValueProperty: false, label: "html" });
|
|
2360
2395
|
}
|
|
2361
2396
|
break;
|
|
2362
2397
|
}
|
|
@@ -2366,14 +2401,7 @@ function executeElement(tmpl, values) {
|
|
|
2366
2401
|
const ev = values[attr.exprs[j]];
|
|
2367
2402
|
val += (ev == null ? "" : String(ev)) + attr.statics[j + 1];
|
|
2368
2403
|
}
|
|
2369
|
-
|
|
2370
|
-
if (lname2 === "srcset") {
|
|
2371
|
-
el.setAttribute(attr.name, sanitizeSrcset(val));
|
|
2372
|
-
} else if (isUrlAttribute(lname2)) {
|
|
2373
|
-
el.setAttribute(attr.name, sanitizeUrl(val));
|
|
2374
|
-
} else {
|
|
2375
|
-
el.setAttribute(attr.name, val);
|
|
2376
|
-
}
|
|
2404
|
+
setSafeAttribute(el, attr.name, val, { syncValueProperty: false, label: "html" });
|
|
2377
2405
|
break;
|
|
2378
2406
|
}
|
|
2379
2407
|
case 3: {
|
|
@@ -2599,20 +2627,12 @@ function Portal(nodes, target) {
|
|
|
2599
2627
|
portalContent = nodes();
|
|
2600
2628
|
container.appendChild(portalContent);
|
|
2601
2629
|
} catch (err) {
|
|
2602
|
-
if (typeof console !== "undefined") {
|
|
2603
|
-
console.error("[Portal] Render error:", err);
|
|
2604
|
-
}
|
|
2605
|
-
const errorObj = err instanceof Error ? err : new Error(String(err));
|
|
2606
2630
|
queueMicrotask(() => {
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
);
|
|
2613
|
-
}
|
|
2614
|
-
} catch {
|
|
2615
|
-
}
|
|
2631
|
+
reportError(err, {
|
|
2632
|
+
phase: "render",
|
|
2633
|
+
name: "Portal",
|
|
2634
|
+
node: anchor.parentNode ? anchor : void 0
|
|
2635
|
+
});
|
|
2616
2636
|
});
|
|
2617
2637
|
}
|
|
2618
2638
|
});
|
|
@@ -2709,9 +2729,10 @@ function array(initial = []) {
|
|
|
2709
2729
|
function reactiveArray(initial = []) {
|
|
2710
2730
|
let data2 = [...initial];
|
|
2711
2731
|
let snapshot = null;
|
|
2712
|
-
const signal2 = {};
|
|
2732
|
+
const signal2 = { __v: 0 };
|
|
2713
2733
|
function notify() {
|
|
2714
2734
|
snapshot = null;
|
|
2735
|
+
signal2.__v++;
|
|
2715
2736
|
if (!enqueueBatchedSignal(signal2)) {
|
|
2716
2737
|
notifySubscribers(signal2);
|
|
2717
2738
|
}
|
|
@@ -2831,17 +2852,34 @@ function asyncDerived(factory, initial) {
|
|
|
2831
2852
|
const [error, setError] = signal(null);
|
|
2832
2853
|
const [tick, setTick] = signal(0);
|
|
2833
2854
|
let runId = 0;
|
|
2834
|
-
|
|
2855
|
+
let disposed = false;
|
|
2856
|
+
let controller = null;
|
|
2857
|
+
const abortInFlight = () => {
|
|
2858
|
+
if (controller === null) return;
|
|
2859
|
+
const c = controller;
|
|
2860
|
+
controller = null;
|
|
2861
|
+
try {
|
|
2862
|
+
c.abort();
|
|
2863
|
+
} catch {
|
|
2864
|
+
}
|
|
2865
|
+
};
|
|
2866
|
+
const stopEffect = effect(() => {
|
|
2835
2867
|
tick();
|
|
2868
|
+
if (disposed) return;
|
|
2869
|
+
abortInFlight();
|
|
2836
2870
|
const currentRun = ++runId;
|
|
2871
|
+
const ac = typeof AbortController !== "undefined" ? new AbortController() : null;
|
|
2872
|
+
controller = ac;
|
|
2837
2873
|
batch(() => {
|
|
2838
2874
|
setLoading(true);
|
|
2839
2875
|
setError(null);
|
|
2840
2876
|
});
|
|
2877
|
+
const stale = () => disposed || currentRun !== runId;
|
|
2841
2878
|
let promise;
|
|
2842
2879
|
try {
|
|
2843
|
-
promise = factory();
|
|
2880
|
+
promise = factory({ signal: ac ? ac.signal : void 0 });
|
|
2844
2881
|
} catch (err) {
|
|
2882
|
+
if (stale()) return;
|
|
2845
2883
|
batch(() => {
|
|
2846
2884
|
setError(err);
|
|
2847
2885
|
setLoading(false);
|
|
@@ -2850,14 +2888,16 @@ function asyncDerived(factory, initial) {
|
|
|
2850
2888
|
}
|
|
2851
2889
|
promise.then(
|
|
2852
2890
|
(result) => {
|
|
2853
|
-
if (
|
|
2891
|
+
if (stale()) return;
|
|
2892
|
+
controller = null;
|
|
2854
2893
|
batch(() => {
|
|
2855
2894
|
setValue(result);
|
|
2856
2895
|
setLoading(false);
|
|
2857
2896
|
});
|
|
2858
2897
|
},
|
|
2859
2898
|
(err) => {
|
|
2860
|
-
if (
|
|
2899
|
+
if (stale()) return;
|
|
2900
|
+
controller = null;
|
|
2861
2901
|
batch(() => {
|
|
2862
2902
|
setError(err);
|
|
2863
2903
|
setLoading(false);
|
|
@@ -2869,7 +2909,16 @@ function asyncDerived(factory, initial) {
|
|
|
2869
2909
|
value,
|
|
2870
2910
|
loading,
|
|
2871
2911
|
error,
|
|
2872
|
-
refresh: () =>
|
|
2912
|
+
refresh: () => {
|
|
2913
|
+
if (disposed) return;
|
|
2914
|
+
setTick((n) => n + 1);
|
|
2915
|
+
},
|
|
2916
|
+
dispose: () => {
|
|
2917
|
+
if (disposed) return;
|
|
2918
|
+
disposed = true;
|
|
2919
|
+
stopEffect();
|
|
2920
|
+
abortInFlight();
|
|
2921
|
+
}
|
|
2873
2922
|
};
|
|
2874
2923
|
}
|
|
2875
2924
|
|
|
@@ -3102,6 +3151,28 @@ function strictEffect(fn) {
|
|
|
3102
3151
|
}
|
|
3103
3152
|
|
|
3104
3153
|
// src/platform/enhance.ts
|
|
3154
|
+
var ENHANCED_ATTR = "data-sibu-enhanced";
|
|
3155
|
+
var enhancementOwner = /* @__PURE__ */ new WeakMap();
|
|
3156
|
+
function drainTeardowns(teardowns, label2) {
|
|
3157
|
+
let executed = 0;
|
|
3158
|
+
while (teardowns.length > 0) {
|
|
3159
|
+
const batch2 = teardowns.splice(0);
|
|
3160
|
+
for (let i2 = 0; i2 < batch2.length; i2++) {
|
|
3161
|
+
if (executed >= MAX_DRAIN_TEARDOWNS) {
|
|
3162
|
+
const remaining = batch2.length - i2 + teardowns.length;
|
|
3163
|
+
teardowns.length = 0;
|
|
3164
|
+
reportDrainRunaway(label2, executed, remaining);
|
|
3165
|
+
return;
|
|
3166
|
+
}
|
|
3167
|
+
executed++;
|
|
3168
|
+
try {
|
|
3169
|
+
batch2[i2]();
|
|
3170
|
+
} catch (err) {
|
|
3171
|
+
if (typeof console !== "undefined") console.error(`[SibuJS ${label2}] teardown error:`, err);
|
|
3172
|
+
}
|
|
3173
|
+
}
|
|
3174
|
+
}
|
|
3175
|
+
}
|
|
3105
3176
|
function resolveTarget(root, target) {
|
|
3106
3177
|
if (target == null) return root;
|
|
3107
3178
|
if (typeof target !== "string") return target;
|
|
@@ -3144,7 +3215,7 @@ function enhance(target, setup) {
|
|
|
3144
3215
|
return () => {
|
|
3145
3216
|
};
|
|
3146
3217
|
}
|
|
3147
|
-
if (root.getAttribute(
|
|
3218
|
+
if (root.getAttribute(ENHANCED_ATTR) === "true") {
|
|
3148
3219
|
if (isDev() && typeof console !== "undefined") {
|
|
3149
3220
|
console.warn("[SibuJS enhance] element is already enhanced; ignoring re-enhance.", root);
|
|
3150
3221
|
}
|
|
@@ -3152,6 +3223,7 @@ function enhance(target, setup) {
|
|
|
3152
3223
|
};
|
|
3153
3224
|
}
|
|
3154
3225
|
const teardowns = [];
|
|
3226
|
+
const owner = /* @__PURE__ */ Symbol("sibujs.enhance");
|
|
3155
3227
|
let disposed = false;
|
|
3156
3228
|
const bind = (target_, fn) => {
|
|
3157
3229
|
const el = resolveTarget(root, target_);
|
|
@@ -3198,11 +3270,7 @@ function enhance(target, setup) {
|
|
|
3198
3270
|
effect(() => {
|
|
3199
3271
|
const v = value();
|
|
3200
3272
|
const next = v == null ? null : String(v);
|
|
3201
|
-
|
|
3202
|
-
if (el.hasAttribute(name)) el.removeAttribute(name);
|
|
3203
|
-
} else if (el.getAttribute(name) !== next) {
|
|
3204
|
-
el.setAttribute(name, next);
|
|
3205
|
-
}
|
|
3273
|
+
setSafeAttribute(el, name, next, { syncValueProperty: false, label: "enhance attr()" });
|
|
3206
3274
|
})
|
|
3207
3275
|
);
|
|
3208
3276
|
});
|
|
@@ -3248,29 +3316,50 @@ function enhance(target, setup) {
|
|
|
3248
3316
|
teardowns.push(fn);
|
|
3249
3317
|
}
|
|
3250
3318
|
};
|
|
3251
|
-
|
|
3319
|
+
let extra;
|
|
3320
|
+
try {
|
|
3321
|
+
extra = setup(ctx);
|
|
3322
|
+
} catch (err) {
|
|
3323
|
+
drainTeardowns(teardowns, "enhance");
|
|
3324
|
+
throw err;
|
|
3325
|
+
}
|
|
3252
3326
|
if (typeof extra === "function") teardowns.push(extra);
|
|
3253
3327
|
const dispose2 = () => {
|
|
3254
3328
|
if (disposed) return;
|
|
3255
3329
|
disposed = true;
|
|
3256
|
-
|
|
3257
|
-
|
|
3258
|
-
|
|
3259
|
-
} catch (err) {
|
|
3260
|
-
if (typeof console !== "undefined") console.error("[SibuJS enhance] teardown error:", err);
|
|
3261
|
-
}
|
|
3330
|
+
if (enhancementOwner.get(root) === owner) {
|
|
3331
|
+
enhancementOwner.delete(root);
|
|
3332
|
+
root.removeAttribute(ENHANCED_ATTR);
|
|
3262
3333
|
}
|
|
3334
|
+
unregisterDisposer(root, dispose2);
|
|
3335
|
+
drainTeardowns(teardowns, "enhance");
|
|
3263
3336
|
};
|
|
3264
3337
|
registerDisposer(root, dispose2);
|
|
3265
|
-
|
|
3338
|
+
enhancementOwner.set(root, owner);
|
|
3339
|
+
root.setAttribute(ENHANCED_ATTR, "true");
|
|
3266
3340
|
return dispose2;
|
|
3267
3341
|
}
|
|
3268
3342
|
function enhanceAll(selector, setup) {
|
|
3269
3343
|
if (typeof document === "undefined") return () => {
|
|
3270
3344
|
};
|
|
3271
|
-
const disposers =
|
|
3345
|
+
const disposers = [];
|
|
3346
|
+
try {
|
|
3347
|
+
for (const el of Array.from(document.querySelectorAll(selector))) {
|
|
3348
|
+
disposers.push(enhance(el, setup));
|
|
3349
|
+
}
|
|
3350
|
+
} catch (err) {
|
|
3351
|
+
for (let i2 = disposers.length - 1; i2 >= 0; i2--) {
|
|
3352
|
+
try {
|
|
3353
|
+
disposers[i2]();
|
|
3354
|
+
} catch (rollbackErr) {
|
|
3355
|
+
if (typeof console !== "undefined") console.error("[SibuJS enhanceAll] rollback error:", rollbackErr);
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
disposers.length = 0;
|
|
3359
|
+
throw err;
|
|
3360
|
+
}
|
|
3272
3361
|
return () => {
|
|
3273
|
-
for (const d of disposers) d();
|
|
3362
|
+
for (const d of disposers.splice(0)) d();
|
|
3274
3363
|
};
|
|
3275
3364
|
}
|
|
3276
3365
|
|
|
@@ -3304,6 +3393,7 @@ function mountIslands(root = typeof document !== "undefined" ? document : null,
|
|
|
3304
3393
|
};
|
|
3305
3394
|
const cancels = [];
|
|
3306
3395
|
const disposers = [];
|
|
3396
|
+
let torndown = false;
|
|
3307
3397
|
for (const el of Array.from(root.querySelectorAll("[data-sibu-island]"))) {
|
|
3308
3398
|
if (el.getAttribute("data-sibu-enhanced") === "true") continue;
|
|
3309
3399
|
const name = el.getAttribute("data-sibu-island") ?? "";
|
|
@@ -3317,17 +3407,23 @@ function mountIslands(root = typeof document !== "undefined" ? document : null,
|
|
|
3317
3407
|
}
|
|
3318
3408
|
let activated = false;
|
|
3319
3409
|
const activate = () => {
|
|
3320
|
-
if (activated) return;
|
|
3410
|
+
if (activated || torndown) return;
|
|
3321
3411
|
activated = true;
|
|
3322
3412
|
const reg = registry.get(name);
|
|
3323
3413
|
if (!reg) return;
|
|
3324
3414
|
resolveSetup(reg).then((setup) => {
|
|
3415
|
+
if (torndown) return;
|
|
3325
3416
|
if (!setup) {
|
|
3326
3417
|
if (typeof console !== "undefined") console.warn(`[SibuJS islands] "${name}" loader produced no setup.`);
|
|
3327
3418
|
return;
|
|
3328
3419
|
}
|
|
3329
3420
|
try {
|
|
3330
|
-
|
|
3421
|
+
const disposeIsland = enhance(el, setup);
|
|
3422
|
+
if (torndown) {
|
|
3423
|
+
disposeIsland();
|
|
3424
|
+
return;
|
|
3425
|
+
}
|
|
3426
|
+
disposers.push(disposeIsland);
|
|
3331
3427
|
el.setAttribute("data-sibu-hydrated", "true");
|
|
3332
3428
|
} catch (err) {
|
|
3333
3429
|
if (typeof console !== "undefined") console.error(`[SibuJS islands] "${name}" failed to mount:`, err);
|
|
@@ -3340,6 +3436,7 @@ function mountIslands(root = typeof document !== "undefined" ? document : null,
|
|
|
3340
3436
|
cancels.push(schedule(strategy, el, activate, options));
|
|
3341
3437
|
}
|
|
3342
3438
|
return () => {
|
|
3439
|
+
torndown = true;
|
|
3343
3440
|
for (const c of cancels.splice(0)) c();
|
|
3344
3441
|
for (const d of disposers.splice(0)) d();
|
|
3345
3442
|
};
|