sibujs 4.5.0 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +1 -1
  2. package/dist/browser.cjs +326 -133
  3. package/dist/browser.d.cts +46 -14
  4. package/dist/browser.d.ts +46 -14
  5. package/dist/browser.js +8 -6
  6. package/dist/build.cjs +2094 -1033
  7. package/dist/build.d.cts +133 -44
  8. package/dist/build.d.ts +133 -44
  9. package/dist/build.js +1372 -574
  10. package/dist/cdn.dev.global.js +10 -10
  11. package/dist/cdn.full.dev.global.js +11 -11
  12. package/dist/cdn.full.global.js +10 -10
  13. package/dist/cdn.global.js +10 -10
  14. package/dist/{chunk-2DCGACUU.js → chunk-2BPG2XDA.js} +251 -66
  15. package/dist/{chunk-IXKSNWV5.js → chunk-2INLLLMZ.js} +1 -1
  16. package/dist/{chunk-4PMLNECI.js → chunk-3QWBSL5R.js} +98 -29
  17. package/dist/{chunk-KKLW7YWL.js → chunk-4AWA2PVD.js} +275 -144
  18. package/dist/chunk-5HZXGZ6T.js +24 -0
  19. package/dist/{chunk-PCT43HW3.js → chunk-7LUJQAOJ.js} +1 -1
  20. package/dist/{chunk-5DXA2J44.js → chunk-7XHATCIH.js} +5 -2
  21. package/dist/chunk-BC2SECJD.js +44 -0
  22. package/dist/{chunk-TBYTO6BS.js → chunk-BSY63EM6.js} +136 -80
  23. package/dist/{chunk-FTIR4QW2.js → chunk-DKXRACVN.js} +6 -8
  24. package/dist/{chunk-ONOHFDLG.js → chunk-FNJXNGYZ.js} +3 -3
  25. package/dist/{chunk-XZZOBQAY.js → chunk-FQRUXCEE.js} +6 -5
  26. package/dist/{chunk-NIOYEGBQ.js → chunk-HURREPU2.js} +27 -13
  27. package/dist/chunk-J6FW5TV6.js +233 -0
  28. package/dist/{chunk-UGRX3S57.js → chunk-JWKYU5GV.js} +22 -4
  29. package/dist/chunk-NYNYSPK7.js +318 -0
  30. package/dist/{chunk-RBTPLM32.js → chunk-RUSSKG6G.js} +13 -12
  31. package/dist/{chunk-7LN645I6.js → chunk-SLM3IA34.js} +3 -3
  32. package/dist/{chunk-R25EFXXC.js → chunk-TUCPL2HB.js} +3 -3
  33. package/dist/{chunk-B3WHI2QA.js → chunk-UNWRJRKC.js} +55 -31
  34. package/dist/{chunk-KEISJXBU.js → chunk-UOL2ECCS.js} +44 -17
  35. package/dist/{chunk-RJE2BNI4.js → chunk-VZSG24LS.js} +108 -45
  36. package/dist/{chunk-RIXRAYIU.js → chunk-WEQ3DMVL.js} +10 -4
  37. package/dist/{chunk-3JZ4L5TJ.js → chunk-WOLJZUFQ.js} +354 -90
  38. package/dist/{chunk-S373NSMK.js → chunk-XYV3EDB7.js} +283 -123
  39. package/dist/{chunk-VZKNK2V7.js → chunk-XZR4PXRE.js} +296 -38
  40. package/dist/{chunk-GW3SCCZG.js → chunk-Z3OHK6QT.js} +153 -110
  41. package/dist/{chunk-OMJJM3KM.js → chunk-ZVL7TY4K.js} +287 -130
  42. package/dist/{contracts-DBdg9J_a.d.ts → contracts-CLqzJnOV.d.ts} +36 -17
  43. package/dist/{contracts-DBdg9J_a.d.cts → contracts-CTOJXu-x.d.cts} +36 -17
  44. package/dist/{customElement-OB9CIsc5.d.cts → customElement-MmInOW1U.d.cts} +21 -0
  45. package/dist/{customElement-OB9CIsc5.d.ts → customElement-MmInOW1U.d.ts} +21 -0
  46. package/dist/data.cjs +410 -155
  47. package/dist/data.d.cts +166 -12
  48. package/dist/data.d.ts +166 -12
  49. package/dist/data.js +12 -9
  50. package/dist/devtools.cjs +98 -61
  51. package/dist/devtools.js +7 -8
  52. package/dist/dispose-GEIG2KOF.js +28 -0
  53. package/dist/ecosystem.cjs +372 -126
  54. package/dist/ecosystem.d.cts +20 -3
  55. package/dist/ecosystem.d.ts +20 -3
  56. package/dist/ecosystem.js +12 -12
  57. package/dist/extras.cjs +2366 -909
  58. package/dist/extras.d.cts +11 -9
  59. package/dist/extras.d.ts +11 -9
  60. package/dist/extras.js +39 -28
  61. package/dist/index.cjs +421 -158
  62. package/dist/index.d.cts +213 -171
  63. package/dist/index.d.ts +213 -171
  64. package/dist/index.js +24 -27
  65. package/dist/motion.cjs +118 -44
  66. package/dist/motion.js +5 -5
  67. package/dist/patterns.cjs +344 -53
  68. package/dist/patterns.d.cts +28 -9
  69. package/dist/patterns.d.ts +28 -9
  70. package/dist/patterns.js +8 -8
  71. package/dist/performance.cjs +325 -220
  72. package/dist/performance.d.cts +2 -2
  73. package/dist/performance.d.ts +2 -2
  74. package/dist/performance.js +8 -9
  75. package/dist/plugin-DVgSnTfK.d.cts +112 -0
  76. package/dist/plugin-DVgSnTfK.d.ts +112 -0
  77. package/dist/plugins.cjs +664 -233
  78. package/dist/plugins.d.cts +127 -14
  79. package/dist/plugins.d.ts +127 -14
  80. package/dist/plugins.js +96 -42
  81. package/dist/signal-EotCj4hS.d.cts +110 -0
  82. package/dist/signal-EotCj4hS.d.ts +110 -0
  83. package/dist/{ssr-BiPRdZ6n.d.cts → ssr-Bli9XRW5.d.cts} +5 -0
  84. package/dist/{ssr-BiPRdZ6n.d.ts → ssr-Bli9XRW5.d.ts} +5 -0
  85. package/dist/{ssr-Y7XOEPEN.js → ssr-XOTUASDO.js} +4 -5
  86. package/dist/ssr.cjs +229 -84
  87. package/dist/ssr.d.cts +9 -3
  88. package/dist/ssr.d.ts +9 -3
  89. package/dist/ssr.js +11 -12
  90. package/dist/{startup-BMpaiMhP.d.ts → startup-BLfSeL15.d.cts} +73 -22
  91. package/dist/{startup-BMpaiMhP.d.cts → startup-BLfSeL15.d.ts} +73 -22
  92. package/dist/tagFactory-8qL9LCIx.d.cts +156 -0
  93. package/dist/tagFactory-BL2fymez.d.ts +156 -0
  94. package/dist/testing.cjs +2503 -2191
  95. package/dist/testing.d.cts +56 -5
  96. package/dist/testing.d.ts +56 -5
  97. package/dist/testing.js +580 -307
  98. package/dist/types-CJFViL6Q.d.cts +26 -0
  99. package/dist/types-CJFViL6Q.d.ts +26 -0
  100. package/dist/ui.cjs +732 -329
  101. package/dist/ui.d.cts +41 -7
  102. package/dist/ui.d.ts +41 -7
  103. package/dist/ui.js +151 -56
  104. package/dist/widgets.cjs +267 -291
  105. package/dist/widgets.js +9 -10
  106. package/package.json +4 -2
  107. package/dist/chunk-2WLZ6757.js +0 -149
  108. package/dist/chunk-CCSJMTRN.js +0 -15
  109. package/dist/chunk-QKRPLZ2V.js +0 -108
  110. package/dist/chunk-VUF4ALSW.js +0 -60
  111. package/dist/chunk-WWV3SJ3L.js +0 -131
  112. package/dist/dispose-46BOMMQJ.js +0 -19
  113. package/dist/plugin-D30wlGW5.d.cts +0 -71
  114. package/dist/plugin-D30wlGW5.d.ts +0 -71
  115. package/dist/tagFactory-DVoDpHye.d.cts +0 -215
  116. package/dist/tagFactory-DVoDpHye.d.ts +0 -215
package/dist/plugins.cjs CHANGED
@@ -382,12 +382,17 @@ var init_sanitize = __esm({
382
382
  var dispose_exports = {};
383
383
  __export(dispose_exports, {
384
384
  MAX_DRAIN_TEARDOWNS: () => MAX_DRAIN_TEARDOWNS,
385
+ beginDisposerCapture: () => beginDisposerCapture,
385
386
  checkLeaks: () => checkLeaks,
387
+ currentDisposerCapture: () => currentDisposerCapture,
386
388
  dispose: () => dispose,
389
+ disposeNodeOwn: () => disposeNodeOwn,
390
+ endDisposerCapture: () => endDisposerCapture,
387
391
  registerDisposer: () => registerDisposer,
388
392
  replaceChildrenSafely: () => replaceChildrenSafely,
389
393
  reportDrainRunaway: () => reportDrainRunaway,
390
- unregisterDisposer: () => unregisterDisposer
394
+ unregisterDisposer: () => unregisterDisposer,
395
+ withDisposerRollback: () => withDisposerRollback
391
396
  });
392
397
  function reportDrainRunaway(label2, executed, remaining) {
393
398
  if (typeof console === "undefined") return;
@@ -396,6 +401,22 @@ function reportDrainRunaway(label2, executed, remaining) {
396
401
  { executed, remaining }
397
402
  );
398
403
  }
404
+ function resolveCapture(capture) {
405
+ let frame = capture;
406
+ while (frame?.closed) frame = frame.forwardTo;
407
+ return frame ?? null;
408
+ }
409
+ function currentDisposerCapture() {
410
+ return resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
411
+ }
412
+ function beginDisposerCapture(capture) {
413
+ if (capture === null && registrationCaptures.length === 0) return false;
414
+ registrationCaptures.push(resolveCapture(capture));
415
+ return true;
416
+ }
417
+ function endDisposerCapture() {
418
+ registrationCaptures.pop();
419
+ }
399
420
  function registerDisposer(node, teardown) {
400
421
  let disposers = elementDisposers.get(node);
401
422
  if (!disposers) {
@@ -404,15 +425,61 @@ function registerDisposer(node, teardown) {
404
425
  }
405
426
  disposers.push(teardown);
406
427
  if (DEV) activeBindingCount++;
428
+ const capture = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
429
+ if (capture) capture.entries.push([node, teardown]);
430
+ }
431
+ function withDisposerRollback(build) {
432
+ const frame = { entries: [], closed: false };
433
+ const captured = frame.entries;
434
+ registrationCaptures.push(frame);
435
+ let result;
436
+ try {
437
+ result = build();
438
+ } catch (err) {
439
+ let executed = 0;
440
+ try {
441
+ while (captured.length > 0) {
442
+ if (executed >= MAX_DRAIN_TEARDOWNS) {
443
+ reportDrainRunaway("rollback", executed, captured.length);
444
+ break;
445
+ }
446
+ const [node, teardown] = captured.pop();
447
+ if (!unregisterDisposer(node, teardown)) continue;
448
+ executed++;
449
+ try {
450
+ teardown();
451
+ } catch (cleanupErr) {
452
+ reportError(cleanupErr, { phase: "cleanup", name: "disposer" });
453
+ }
454
+ }
455
+ } finally {
456
+ frame.closed = true;
457
+ captured.length = 0;
458
+ registrationCaptures.pop();
459
+ }
460
+ throw err;
461
+ }
462
+ frame.closed = true;
463
+ registrationCaptures.pop();
464
+ const parent = resolveCapture(registrationCaptures[registrationCaptures.length - 1]);
465
+ if (parent) {
466
+ for (const entry of captured) {
467
+ if (elementDisposers.get(entry[0])?.includes(entry[1])) parent.entries.push(entry);
468
+ }
469
+ frame.forwardTo = parent;
470
+ }
471
+ captured.length = 0;
472
+ return result;
407
473
  }
408
474
  function unregisterDisposer(node, teardown) {
409
475
  const disposers = elementDisposers.get(node);
410
- if (!disposers) return;
476
+ if (!disposers) return false;
411
477
  const index = disposers.indexOf(teardown);
412
- if (index === -1) return;
478
+ if (index === -1) return false;
413
479
  disposers.splice(index, 1);
414
480
  if (DEV) activeBindingCount--;
415
481
  if (disposers.length === 0) elementDisposers.delete(node);
482
+ return true;
416
483
  }
417
484
  function dispose(node) {
418
485
  const stack = [node];
@@ -426,33 +493,34 @@ function dispose(node) {
426
493
  }
427
494
  }
428
495
  for (let i2 = order.length - 1; i2 >= 0; i2--) {
429
- const current = order[i2];
430
- if (elementDisposers.has(current)) {
431
- let executed = 0;
432
- let runaway = false;
433
- while (!runaway) {
434
- const pending = elementDisposers.get(current);
435
- if (!pending || pending.length === 0) break;
436
- const snapshot = pending.slice();
437
- elementDisposers.delete(current);
438
- if (DEV) activeBindingCount -= snapshot.length;
439
- for (let i3 = 0; i3 < snapshot.length; i3++) {
440
- if (executed >= MAX_DRAIN_TEARDOWNS) {
441
- const rest = snapshot.slice(i3);
442
- const added = elementDisposers.get(current);
443
- elementDisposers.set(current, added ? rest.concat(added) : rest);
444
- if (DEV) activeBindingCount += rest.length;
445
- reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
446
- runaway = true;
447
- break;
448
- }
449
- executed++;
450
- try {
451
- snapshot[i3]();
452
- } catch (err) {
453
- reportError(err, { phase: "cleanup", name: "disposer" });
454
- }
455
- }
496
+ disposeNodeOwn(order[i2]);
497
+ }
498
+ }
499
+ function disposeNodeOwn(node) {
500
+ if (!elementDisposers.has(node)) return;
501
+ let executed = 0;
502
+ let runaway = false;
503
+ while (!runaway) {
504
+ const pending = elementDisposers.get(node);
505
+ if (!pending || pending.length === 0) break;
506
+ const snapshot = pending.slice();
507
+ elementDisposers.delete(node);
508
+ if (DEV) activeBindingCount -= snapshot.length;
509
+ for (let i2 = 0; i2 < snapshot.length; i2++) {
510
+ if (executed >= MAX_DRAIN_TEARDOWNS) {
511
+ const rest = snapshot.slice(i2);
512
+ const added = elementDisposers.get(node);
513
+ elementDisposers.set(node, added ? rest.concat(added) : rest);
514
+ if (DEV) activeBindingCount += rest.length;
515
+ reportDrainRunaway("dispose", executed, rest.length + (added?.length ?? 0));
516
+ runaway = true;
517
+ break;
518
+ }
519
+ executed++;
520
+ try {
521
+ snapshot[i2]();
522
+ } catch (err) {
523
+ reportError(err, { phase: "cleanup", name: "disposer" });
456
524
  }
457
525
  }
458
526
  }
@@ -477,7 +545,7 @@ function checkLeaks(warnThreshold = 0) {
477
545
  }
478
546
  return activeBindingCount;
479
547
  }
480
- var elementDisposers, MAX_DRAIN_TEARDOWNS, activeBindingCount;
548
+ var elementDisposers, MAX_DRAIN_TEARDOWNS, activeBindingCount, registrationCaptures;
481
549
  var init_dispose = __esm({
482
550
  "src/core/rendering/dispose.ts"() {
483
551
  "use strict";
@@ -486,6 +554,7 @@ var init_dispose = __esm({
486
554
  elementDisposers = /* @__PURE__ */ new WeakMap();
487
555
  MAX_DRAIN_TEARDOWNS = 1e4;
488
556
  activeBindingCount = 0;
557
+ registrationCaptures = [];
489
558
  }
490
559
  });
491
560
 
@@ -985,7 +1054,7 @@ function renderToDocument(component, options = {}) {
985
1054
  <head>
986
1055
  <meta charset="UTF-8" />
987
1056
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
988
- ${options.title ? `<title>${escapeHtml(options.title)}</title>` : ""}
1057
+ ${options.title != null ? `<title>${escapeHtml(options.title)}</title>` : ""}
989
1058
  ${metaTags}
990
1059
  ${linkTags}
991
1060
  ${options.headExtra || ""}
@@ -1159,16 +1228,32 @@ function ssrSuspense(props) {
1159
1228
  const timeoutPromise = new Promise((_, reject) => {
1160
1229
  timer = setTimeout(() => reject(new Error(`[SibuJS SSR] ssrSuspense timed out after ${timeoutMs}ms`)), timeoutMs);
1161
1230
  });
1162
- const raced = Promise.race([props.content(), timeoutPromise]);
1231
+ let contentPromise;
1232
+ try {
1233
+ contentPromise = Promise.resolve(props.content());
1234
+ } catch (err) {
1235
+ contentPromise = Promise.reject(err);
1236
+ }
1237
+ const toFallback = (err) => {
1238
+ if (DEV) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
1239
+ return { id, html: fallbackHtml };
1240
+ };
1241
+ const clearTimer = () => {
1242
+ if (timer !== void 0) clearTimeout(timer);
1243
+ };
1244
+ const raced = Promise.race([contentPromise, timeoutPromise]);
1163
1245
  const promise = raced.then(
1164
1246
  (resolvedEl) => {
1165
- if (timer) clearTimeout(timer);
1166
- return { id, html: renderToString(resolvedEl) };
1247
+ clearTimer();
1248
+ try {
1249
+ return { id, html: renderToString(resolvedEl) };
1250
+ } catch (err) {
1251
+ return toFallback(err);
1252
+ }
1167
1253
  },
1168
1254
  (err) => {
1169
- if (timer) clearTimeout(timer);
1170
- if (DEV) console.warn("[SibuJS SSR] ssrSuspense rejected:", err);
1171
- return { id, html: fallbackHtml };
1255
+ clearTimer();
1256
+ return toFallback(err);
1172
1257
  }
1173
1258
  );
1174
1259
  promise.catch(noop);
@@ -1265,7 +1350,9 @@ var init_ssr = __esm({
1265
1350
  var plugins_exports = {};
1266
1351
  __export(plugins_exports, {
1267
1352
  KeepAliveRoute: () => KeepAliveRoute,
1353
+ MigrationStorageError: () => MigrationStorageError,
1268
1354
  Outlet: () => Outlet,
1355
+ PluginInstallCancelledError: () => PluginInstallCancelledError,
1269
1356
  Route: () => Route,
1270
1357
  RouterLink: () => RouterLink,
1271
1358
  SibuRouter: () => SibuRouter,
@@ -1309,6 +1396,7 @@ __export(plugins_exports, {
1309
1396
  healthCheck: () => healthCheck,
1310
1397
  hydrateRouter: () => hydrateRouter,
1311
1398
  inject: () => inject,
1399
+ isPluginInstallCancelledError: () => isPluginInstallCancelledError,
1312
1400
  lazy: () => lazy,
1313
1401
  lazyModule: () => lazyModule,
1314
1402
  navigate: () => navigate,
@@ -1337,6 +1425,7 @@ __export(plugins_exports, {
1337
1425
  setRouteTransition: () => setRouteTransition,
1338
1426
  setRoutes: () => setRoutes,
1339
1427
  t: () => t,
1428
+ translated: () => translated,
1340
1429
  triggerPluginError: () => triggerPluginError,
1341
1430
  triggerPluginMount: () => triggerPluginMount,
1342
1431
  triggerPluginUnmount: () => triggerPluginUnmount
@@ -1440,6 +1529,7 @@ init_dev();
1440
1529
 
1441
1530
  // src/reactivity/track-core.ts
1442
1531
  init_errors();
1532
+ init_dispose();
1443
1533
  var POOL_MAX = 4096;
1444
1534
  var nodePool = [];
1445
1535
  function createNode() {
@@ -1597,6 +1687,7 @@ function retrack(effectFn, subscriber) {
1597
1687
  }
1598
1688
  currentSubscriber = subscriber;
1599
1689
  const sub2 = subscriber;
1690
+ if (sub2._cap === void 0) sub2._cap = currentDisposerCapture();
1600
1691
  const epoch = ++subscriberEpochCounter;
1601
1692
  sub2._epoch = epoch;
1602
1693
  sub2._structDirty = false;
@@ -1788,7 +1879,12 @@ function drainQueue() {
1788
1879
  quarantined.add(sub2);
1789
1880
  continue;
1790
1881
  }
1791
- safeInvoke(sub2);
1882
+ const pushed = beginDisposerCapture(sub2._cap ?? null);
1883
+ try {
1884
+ safeInvoke(sub2);
1885
+ } finally {
1886
+ if (pushed) endDisposerCapture();
1887
+ }
1792
1888
  }
1793
1889
  }
1794
1890
  function drainNotificationQueue() {
@@ -1924,7 +2020,7 @@ function forEachSubscriber(signal2, visit) {
1924
2020
  }
1925
2021
 
1926
2022
  // src/reactivity/track.ts
1927
- var _runtimeVersion = true ? "4.5.0" : "dev";
2023
+ var _runtimeVersion = true ? "4.7.0" : "dev";
1928
2024
  var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("sibujs.reactive.v1");
1929
2025
  function resolveReactiveApi() {
1930
2026
  const g2 = globalThis;
@@ -2208,8 +2304,34 @@ function toKebab(prop) {
2208
2304
  }
2209
2305
  function applyStyle(el, style2) {
2210
2306
  if (typeof style2 === "function") {
2307
+ const getter = style2;
2308
+ let written = [];
2309
+ let wroteString = false;
2211
2310
  const teardown = reactiveBinding2(() => {
2212
- el.setAttribute("style", sanitizeStyleAttribute(String(style2()), { element: el }));
2311
+ const value = getter();
2312
+ if (value === null || typeof value !== "object") {
2313
+ written = [];
2314
+ wroteString = true;
2315
+ el.setAttribute("style", sanitizeStyleAttribute(String(value), { element: el }));
2316
+ return;
2317
+ }
2318
+ const decl = el.style;
2319
+ if (wroteString) {
2320
+ el.removeAttribute("style");
2321
+ wroteString = false;
2322
+ }
2323
+ const next = [];
2324
+ for (const prop in value) {
2325
+ const val = value[prop];
2326
+ if (val == null) continue;
2327
+ const name = toKebab(prop);
2328
+ next.push(name);
2329
+ decl.setProperty(name, sanitizeCSSValue(String(val), { property: name, element: el }));
2330
+ }
2331
+ for (let i2 = 0; i2 < written.length; i2++) {
2332
+ if (next.indexOf(written[i2]) === -1) decl.removeProperty(written[i2]);
2333
+ }
2334
+ written = next;
2213
2335
  }, el);
2214
2336
  registerDisposer(el, teardown);
2215
2337
  return;
@@ -2235,7 +2357,7 @@ function applyStyle(el, style2) {
2235
2357
  }
2236
2358
  function resolveClassValue(cls) {
2237
2359
  if (typeof cls === "string") return cls;
2238
- if (typeof cls === "function") return cls();
2360
+ if (typeof cls === "function") return cls() || "";
2239
2361
  if (!cls) return "";
2240
2362
  let out = "";
2241
2363
  for (const name in cls) {
@@ -2252,7 +2374,9 @@ function applyClass(el, cls) {
2252
2374
  }
2253
2375
  if (typeof cls === "function") {
2254
2376
  const teardown = reactiveBinding2(() => {
2255
- el.setAttribute("class", cls());
2377
+ const value = cls();
2378
+ if (value == null || value === false) el.removeAttribute("class");
2379
+ else el.setAttribute("class", value);
2256
2380
  }, el);
2257
2381
  registerDisposer(el, teardown);
2258
2382
  return;
@@ -2334,7 +2458,7 @@ function appendChildren(el, nodes) {
2334
2458
  }
2335
2459
  }
2336
2460
  }
2337
- var tagFactory = (tag, ns) => {
2461
+ function tagFactory(tag, ns) {
2338
2462
  const blocked = isBlockedTag(tag);
2339
2463
  return (first, second) => {
2340
2464
  if (blocked) {
@@ -2383,7 +2507,9 @@ var tagFactory = (tag, ns) => {
2383
2507
  const pClass = props.class;
2384
2508
  if (pClass != null) applyClass(el, pClass);
2385
2509
  const pId = props.id;
2386
- if (pId != null) {
2510
+ if (typeof pId === "function") {
2511
+ registerDisposer(el, bindAttribute(el, "id", pId));
2512
+ } else if (pId != null) {
2387
2513
  if (DEV && typeof pId === "string" && CLOBBER_RISKY_IDS.has(pId.toLowerCase())) {
2388
2514
  devWarn(
2389
2515
  `tagFactory: element id="${pId}" matches a common global and may cause DOM clobbering. Avoid setting ids from untrusted input.`
@@ -2433,12 +2559,10 @@ var tagFactory = (tag, ns) => {
2433
2559
  }
2434
2560
  }
2435
2561
  }
2436
- if (props.onElement && typeof props.onElement === "function") {
2437
- props.onElement(el);
2438
- }
2562
+ if (typeof props.onElement === "function") props.onElement(el);
2439
2563
  return el;
2440
2564
  };
2441
- };
2565
+ }
2442
2566
 
2443
2567
  // src/core/rendering/html.ts
2444
2568
  var html = tagFactory("html");
@@ -2630,6 +2754,16 @@ var isBatching = API2.isBatching;
2630
2754
 
2631
2755
  // src/core/signals/signal.ts
2632
2756
  init_dev();
2757
+
2758
+ // src/core/devtoolsHook.ts
2759
+ function emitDevtools(hook, event, payload) {
2760
+ try {
2761
+ hook.emit(event, payload);
2762
+ } catch {
2763
+ }
2764
+ }
2765
+
2766
+ // src/core/signals/signal.ts
2633
2767
  var _g = globalThis;
2634
2768
  function signal(initial, options) {
2635
2769
  const state2 = {
@@ -2662,7 +2796,7 @@ function signal(initial, options) {
2662
2796
  state2.__v++;
2663
2797
  if (DEV) {
2664
2798
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2665
- if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
2799
+ if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
2666
2800
  }
2667
2801
  if (!enqueueBatchedSignal(state2)) {
2668
2802
  notifySubscribers2(state2);
@@ -2676,7 +2810,7 @@ function signal(initial, options) {
2676
2810
  state2.value = newValue;
2677
2811
  state2.__v++;
2678
2812
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2679
- if (hook) hook.emit("signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
2813
+ if (hook) emitDevtools(hook, "signal:update", { signal: state2, name: debugName, oldValue: prev, newValue });
2680
2814
  if (!enqueueBatchedSignal(state2)) {
2681
2815
  notifySubscribers2(state2);
2682
2816
  }
@@ -2695,7 +2829,7 @@ function signal(initial, options) {
2695
2829
  }
2696
2830
  if (DEV) {
2697
2831
  const hook = _g.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2698
- if (hook) hook.emit("signal:create", { signal: state2, name: debugName, getter: get, initial });
2832
+ if (hook) emitDevtools(hook, "signal:create", { signal: state2, name: debugName, getter: get, initial });
2699
2833
  }
2700
2834
  return [get, set];
2701
2835
  }
@@ -2712,14 +2846,20 @@ function globalSingleton(key, create) {
2712
2846
  // src/plugins/i18n.ts
2713
2847
  var _i18n = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.i18n.v1"), () => ({
2714
2848
  locale: signal("en"),
2715
- locales: /* @__PURE__ */ Object.create(null)
2849
+ locales: /* @__PURE__ */ Object.create(null),
2850
+ revision: signal(0)
2716
2851
  }));
2717
2852
  var [clientLocale, setClientLocale] = _i18n.locale;
2718
2853
  var locales = _i18n.locales;
2854
+ var [revision, setRevision] = _i18n.revision ?? (_i18n.revision = signal(0));
2719
2855
  function dictionaryFor(locale) {
2720
2856
  return Object.hasOwn(locales, locale) ? locales[locale] : void 0;
2721
2857
  }
2858
+ function trackDictionaries() {
2859
+ if (!getRequestStore()) revision();
2860
+ }
2722
2861
  function lookup(key) {
2862
+ trackDictionaries();
2723
2863
  const dictionary = dictionaryFor(getLocale());
2724
2864
  if (dictionary === void 0 || !Object.hasOwn(dictionary, key)) return void 0;
2725
2865
  const message = dictionary[key];
@@ -2749,18 +2889,29 @@ function registerTranslations(locale, messages) {
2749
2889
  enumerable: true,
2750
2890
  configurable: true
2751
2891
  });
2892
+ setRevision((n) => n + 1);
2893
+ }
2894
+ function resolveParam(params, name) {
2895
+ if (!Object.hasOwn(params, name)) return "";
2896
+ const raw = params[name];
2897
+ const value = typeof raw === "function" ? raw() : raw;
2898
+ return value == null ? "" : String(value);
2752
2899
  }
2753
2900
  function t(key, params) {
2754
2901
  const message = lookup(key) ?? key;
2755
- return params ? message.replace(/\{(\w+)\}/g, (_, p2) => String(params[p2] ?? "")) : message;
2902
+ return params ? message.replace(/\{(\w+)\}/g, (_, p2) => resolveParam(params, p2)) : message;
2903
+ }
2904
+ function translated(key, params) {
2905
+ return () => t(key, params);
2756
2906
  }
2757
2907
  function Trans(key, params) {
2758
- return span(() => t(key, params));
2908
+ return span(translated(key, params));
2759
2909
  }
2760
2910
  function hasTranslation(key) {
2761
2911
  return lookup(key) !== void 0;
2762
2912
  }
2763
2913
  function getAvailableLocales() {
2914
+ trackDictionaries();
2764
2915
  return Object.keys(locales);
2765
2916
  }
2766
2917
 
@@ -2886,17 +3037,31 @@ function effect(effectFn, options) {
2886
3037
  try {
2887
3038
  retrack2(ctx.bodyFn, ctx.subscriber);
2888
3039
  if (ctx.rerunPending) drainReruns(ctx);
3040
+ } catch (err) {
3041
+ ctx.disposed = true;
3042
+ if (ctx.userCleanups.length > 0) flushUserCleanups(ctx);
3043
+ cleanup2(ctx.subscriber);
3044
+ throw err;
2889
3045
  } finally {
2890
3046
  ctx.running = false;
2891
3047
  ctx.rerunPending = false;
2892
3048
  }
2893
3049
  const hook = _g2.__SIBU_DEVTOOLS_GLOBAL_HOOK__;
2894
- if (hook) hook.emit("effect:create", { effectFn });
3050
+ if (hook) emitDevtools(hook, "effect:create", { effectFn });
2895
3051
  return () => disposeEffect(ctx);
2896
3052
  }
2897
3053
 
2898
3054
  // src/plugins/router.ts
2899
3055
  init_sanitize();
3056
+ function splitRouteUrl(url) {
3057
+ const hashIndex = url.indexOf("#");
3058
+ const beforeHash = hashIndex === -1 ? url : url.slice(0, hashIndex);
3059
+ const hash = hashIndex === -1 ? "" : url.slice(hashIndex + 1);
3060
+ const queryIndex = beforeHash.indexOf("?");
3061
+ const path2 = queryIndex === -1 ? beforeHash : beforeHash.slice(0, queryIndex);
3062
+ const query = queryIndex === -1 ? "" : beforeHash.slice(queryIndex + 1);
3063
+ return { path: path2, query, hash };
3064
+ }
2900
3065
  function classifyNavigationTarget(path2) {
2901
3066
  if (path2 === "") return "internal";
2902
3067
  const normalized = stripControlChars(path2).replace(/\\/g, "/");
@@ -3615,8 +3780,7 @@ var _SibuRouter = class _SibuRouter {
3615
3780
  return (path2 || "/") + window.location.search + window.location.hash;
3616
3781
  }
3617
3782
  createRouteContext(fullPath) {
3618
- const [pathWithQuery, hash = ""] = fullPath.split("#");
3619
- const [path2, queryString = ""] = pathWithQuery.split("?");
3783
+ const { path: path2, query: queryString, hash } = splitRouteUrl(fullPath);
3620
3784
  const query = Object.fromEntries(new URLSearchParams(queryString));
3621
3785
  const match = this.matcher.match(path2 || "/");
3622
3786
  const params = match?.params || {};
@@ -4058,6 +4222,30 @@ function afterEach(hook) {
4058
4222
  return _routerRef.current.afterEach(hook);
4059
4223
  }
4060
4224
  var routeCleanups = [];
4225
+ var ownParamNamesCache = /* @__PURE__ */ new WeakMap();
4226
+ function ownParamNames(record) {
4227
+ const cached = ownParamNamesCache.get(record);
4228
+ if (cached) return cached;
4229
+ const aliases = record.alias == null ? [] : Array.isArray(record.alias) ? record.alias : [record.alias];
4230
+ const names = /* @__PURE__ */ new Set();
4231
+ for (const pattern2 of [record.path, ...aliases]) {
4232
+ for (const m of pattern2.matchAll(/\/:([^/]+)/g)) {
4233
+ names.add(m[1].endsWith("?") ? m[1].slice(0, -1) : m[1]);
4234
+ }
4235
+ }
4236
+ const result = [...names];
4237
+ ownParamNamesCache.set(record, result);
4238
+ return result;
4239
+ }
4240
+ function instanceKey(owner, records, route2) {
4241
+ const custom = owner.key;
4242
+ if (custom) return untracked2(() => String(custom(route2)));
4243
+ const parts = [];
4244
+ for (const record of records) {
4245
+ for (const name of ownParamNames(record)) parts.push(name, route2.params[name] ?? null);
4246
+ }
4247
+ return JSON.stringify(parts);
4248
+ }
4061
4249
  function Route() {
4062
4250
  const anchor = document.createComment("route-outlet");
4063
4251
  let currentNode = null;
@@ -4065,6 +4253,7 @@ function Route() {
4065
4253
  let errorNode = null;
4066
4254
  let navSeq = 0;
4067
4255
  let currentTopRoute = null;
4256
+ let currentKey = null;
4068
4257
  let routeTorn = false;
4069
4258
  const commitTarget = (seq) => routeTorn || seq !== navSeq ? null : anchor.parentNode;
4070
4259
  const release = (node) => {
@@ -4156,11 +4345,13 @@ function Route() {
4156
4345
  const match = _routerRef.current["matcher"].match(route2.path);
4157
4346
  if (!match) {
4158
4347
  currentTopRoute = null;
4348
+ currentKey = null;
4159
4349
  cleanupNodes();
4160
4350
  return;
4161
4351
  }
4162
4352
  const routeDef = match.matched[0] || match.route;
4163
- if (routeDef === currentTopRoute && currentNode) {
4353
+ const key = instanceKey(routeDef, [routeDef], route2);
4354
+ if (routeDef === currentTopRoute && key === currentKey && currentNode) {
4164
4355
  return;
4165
4356
  }
4166
4357
  if ("redirect" in routeDef) {
@@ -4188,6 +4379,7 @@ function Route() {
4188
4379
  }
4189
4380
  if (node) {
4190
4381
  currentTopRoute = routeDef;
4382
+ currentKey = key;
4191
4383
  cleanupNodes();
4192
4384
  parent.insertBefore(node, anchor.nextSibling);
4193
4385
  currentNode = node;
@@ -4225,6 +4417,7 @@ function Route() {
4225
4417
  routeTeardown();
4226
4418
  cleanupNodes();
4227
4419
  currentTopRoute = null;
4420
+ currentKey = null;
4228
4421
  };
4229
4422
  registerDisposer(anchor, routeCleanup);
4230
4423
  routeCleanups.push(routeCleanup);
@@ -4363,8 +4556,7 @@ function RouterLink(props, children) {
4363
4556
  const rawHref = _routerRef.current["resolvePath"](to);
4364
4557
  const kind = classifyNavigationTarget(rawHref);
4365
4558
  const href = kind === "unsafe" ? "#" : rawHref;
4366
- const [hrefBeforeHash, hrefHash = ""] = href.split("#");
4367
- const [hrefPathRaw, hrefQueryRaw = ""] = hrefBeforeHash.split("?");
4559
+ const { path: hrefPathRaw, query: hrefQueryRaw, hash: hrefHash } = splitRouteUrl(href);
4368
4560
  const targetPath = normalizePathname(hrefPathRaw);
4369
4561
  const targetQuery = normalizeQuery(hrefQueryRaw);
4370
4562
  const link2 = document.createElement("a");
@@ -4412,19 +4604,7 @@ function RouterLink(props, children) {
4412
4604
  }
4413
4605
  }
4414
4606
  });
4415
- if (typeof content === "string") {
4416
- link2.textContent = content;
4417
- } else if (content instanceof Node) {
4418
- link2.appendChild(content);
4419
- } else if (Array.isArray(content)) {
4420
- content.forEach((child) => {
4421
- if (typeof child === "string") {
4422
- link2.appendChild(document.createTextNode(child));
4423
- } else if (child instanceof Node) {
4424
- link2.appendChild(child);
4425
- }
4426
- });
4427
- }
4607
+ if (content !== void 0) appendChildren(link2, content);
4428
4608
  const onLinkClick = (e) => {
4429
4609
  if (e.defaultPrevented || target || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey || e.button !== 0) {
4430
4610
  return;
@@ -4586,6 +4766,7 @@ function Outlet() {
4586
4766
  const anchor = document.createComment("route-outlet-nested");
4587
4767
  let currentNode = null;
4588
4768
  let currentChild = null;
4769
+ let currentKey = null;
4589
4770
  let navSeq = 0;
4590
4771
  let outletTorn = false;
4591
4772
  const clearCurrent = () => {
@@ -4595,6 +4776,7 @@ function Outlet() {
4595
4776
  currentNode = null;
4596
4777
  }
4597
4778
  currentChild = null;
4779
+ currentKey = null;
4598
4780
  };
4599
4781
  const commitTarget = (seq) => outletTorn || seq !== navSeq ? null : anchor.parentNode;
4600
4782
  const release = (node) => {
@@ -4615,7 +4797,8 @@ function Outlet() {
4615
4797
  clearCurrent();
4616
4798
  return;
4617
4799
  }
4618
- if (childRoute === currentChild && currentNode) return;
4800
+ const key = instanceKey(childRoute, route2.matched.slice(1), route2);
4801
+ if (childRoute === currentChild && key === currentKey && currentNode) return;
4619
4802
  try {
4620
4803
  const cacheKey = `${route2.path}\0${childRoute.path}`;
4621
4804
  const plan = await _routerRef.current.loadPlan(childRoute, cacheKey);
@@ -4631,6 +4814,7 @@ function Outlet() {
4631
4814
  parent.insertBefore(node, anchor.nextSibling);
4632
4815
  currentNode = node;
4633
4816
  currentChild = childRoute;
4817
+ currentKey = key;
4634
4818
  } catch (error) {
4635
4819
  if (outletTorn || seq !== navSeq) return;
4636
4820
  console.error("[Outlet] Failed to render child route:", error);
@@ -4653,6 +4837,7 @@ function Outlet() {
4653
4837
  currentNode = null;
4654
4838
  }
4655
4839
  currentChild = null;
4840
+ currentKey = null;
4656
4841
  };
4657
4842
  registerDisposer(anchor, outletCleanup);
4658
4843
  routeCleanups.push(outletCleanup);
@@ -5005,37 +5190,152 @@ function escapeAttrLocal(str) {
5005
5190
  }
5006
5191
 
5007
5192
  // src/plugins/plugin.ts
5193
+ init_dev();
5194
+ init_errors();
5195
+
5196
+ // src/utils/adoptThenable.ts
5197
+ function adoptThenable(value) {
5198
+ if (value === null || typeof value !== "object" && typeof value !== "function") return null;
5199
+ let then;
5200
+ try {
5201
+ then = value.then;
5202
+ } catch (error) {
5203
+ return Promise.reject(error);
5204
+ }
5205
+ if (typeof then !== "function") return null;
5206
+ return new Promise((resolve, reject) => {
5207
+ queueMicrotask(() => {
5208
+ try {
5209
+ Reflect.apply(then, value, [resolve, reject]);
5210
+ } catch (error) {
5211
+ reject(error);
5212
+ }
5213
+ });
5214
+ });
5215
+ }
5216
+
5217
+ // src/plugins/plugin.ts
5218
+ var CANCELLED_BRAND = /* @__PURE__ */ Symbol.for("sibujs.plugins.installCancelled.v1");
5219
+ var _a;
5220
+ var PluginInstallCancelledError = class extends Error {
5221
+ constructor(pluginName) {
5222
+ super(`[Plugin] Installation of "${pluginName}" was cancelled before it was committed (registry reset).`);
5223
+ /**
5224
+ * Brand, not identity: the default registry is shared across duplicate copies
5225
+ * of this module, so the error a caller receives may come from another copy's
5226
+ * constructor. `instanceof` is taught to recognise the brand instead.
5227
+ */
5228
+ this[_a] = true;
5229
+ this.name = "PluginInstallCancelledError";
5230
+ this.pluginName = pluginName;
5231
+ }
5232
+ static [(_a = CANCELLED_BRAND, Symbol.hasInstance)](value) {
5233
+ return isPluginInstallCancelledError(value);
5234
+ }
5235
+ };
5236
+ function isPluginInstallCancelledError(value) {
5237
+ return typeof value === "object" && value !== null && value[CANCELLED_BRAND] === true;
5238
+ }
5008
5239
  function createPluginRegistry() {
5009
5240
  const installedPlugins = /* @__PURE__ */ new Set();
5010
5241
  const hooks = { init: [], mount: [], unmount: [], error: [] };
5011
5242
  const provided = /* @__PURE__ */ new Map();
5243
+ const installStack = /* @__PURE__ */ new Set();
5244
+ const pendingInstalls = /* @__PURE__ */ new Map();
5245
+ let generation = 0;
5012
5246
  const registry = {
5013
5247
  installedPlugins,
5014
5248
  hooks,
5015
5249
  provided,
5250
+ /**
5251
+ * Install a plugin as a transaction.
5252
+ *
5253
+ * Hooks and providers registered through `ctx` are staged and committed
5254
+ * only if `install()` returns; a throwing install leaves the registry
5255
+ * exactly as it found it (and can simply be retried). The plugin is marked
5256
+ * installed at commit, before its init hooks run.
5257
+ *
5258
+ * Each `plugin()` call is its own transaction: a dependency installed by a
5259
+ * nested `plugin()` call commits on its own and stays installed even if the
5260
+ * outer installation later fails.
5261
+ */
5016
5262
  plugin(p2, options) {
5017
5263
  if (installedPlugins.has(p2.name)) {
5018
5264
  console.warn(`[Plugin] "${p2.name}" is already installed.`);
5019
5265
  return;
5020
5266
  }
5267
+ if (installStack.has(p2.name)) {
5268
+ throw new Error(`[Plugin] "${p2.name}" is already being installed (recursive installation).`);
5269
+ }
5270
+ if (pendingInstalls.has(p2.name)) {
5271
+ throw new Error(`[Plugin] "${p2.name}" is already being installed (asynchronous installation in flight).`);
5272
+ }
5273
+ const staged = { init: [], mount: [], unmount: [], error: [] };
5274
+ const stagedProvided = /* @__PURE__ */ new Map();
5275
+ let committed = false;
5276
+ const myGeneration = generation;
5277
+ const stale = () => {
5278
+ if (myGeneration === generation) return false;
5279
+ if (DEV) devWarn(`plugin: "${p2.name}" registered after the registry was reset; the registration was ignored.`);
5280
+ return true;
5281
+ };
5282
+ const target = () => stale() ? null : committed ? hooks : staged;
5021
5283
  const ctx = {
5022
- onInit: (cb) => hooks.init.push(cb),
5023
- onMount: (cb) => hooks.mount.push(cb),
5024
- onUnmount: (cb) => hooks.unmount.push(cb),
5025
- onError: (cb) => hooks.error.push(cb),
5026
- provide: (key, value) => provided.set(key, value)
5284
+ onInit: (cb) => void target()?.init.push(cb),
5285
+ onMount: (cb) => void target()?.mount.push(cb),
5286
+ onUnmount: (cb) => void target()?.unmount.push(cb),
5287
+ onError: (cb) => void target()?.error.push(cb),
5288
+ provide: (key, value) => {
5289
+ if (stale()) return;
5290
+ (committed ? provided : stagedProvided).set(key, value);
5291
+ }
5027
5292
  };
5028
- const initHooksBefore = hooks.init.length;
5029
- p2.install(ctx, options);
5030
- installedPlugins.add(p2.name);
5031
- const justAdded = hooks.init.slice(initHooksBefore);
5032
- for (const cb of justAdded) {
5033
- try {
5034
- cb();
5035
- } catch (e) {
5036
- console.error(`[Plugin] "${p2.name}" init error:`, e);
5293
+ const commit = () => {
5294
+ if (myGeneration !== generation) return false;
5295
+ hooks.init.push(...staged.init);
5296
+ hooks.mount.push(...staged.mount);
5297
+ hooks.unmount.push(...staged.unmount);
5298
+ hooks.error.push(...staged.error);
5299
+ for (const [key, value] of stagedProvided) provided.set(key, value);
5300
+ installedPlugins.add(p2.name);
5301
+ committed = true;
5302
+ if (pendingInstalls.get(p2.name) === myGeneration) pendingInstalls.delete(p2.name);
5303
+ for (const cb of staged.init.slice()) {
5304
+ try {
5305
+ cb();
5306
+ } catch (e) {
5307
+ console.error(`[Plugin] "${p2.name}" init error:`, e);
5308
+ }
5037
5309
  }
5310
+ return true;
5311
+ };
5312
+ installStack.add(p2.name);
5313
+ let pending;
5314
+ try {
5315
+ pending = adoptThenable(p2.install(ctx, options));
5316
+ } finally {
5317
+ installStack.delete(p2.name);
5038
5318
  }
5319
+ if (!pending) {
5320
+ if (!commit()) throw new PluginInstallCancelledError(p2.name);
5321
+ return;
5322
+ }
5323
+ if (myGeneration === generation) pendingInstalls.set(p2.name, myGeneration);
5324
+ const settled = pending.then(
5325
+ () => {
5326
+ if (commit()) return;
5327
+ if (pendingInstalls.get(p2.name) === myGeneration) pendingInstalls.delete(p2.name);
5328
+ throw new PluginInstallCancelledError(p2.name);
5329
+ },
5330
+ (err) => {
5331
+ if (pendingInstalls.get(p2.name) === myGeneration) pendingInstalls.delete(p2.name);
5332
+ reportError(err, { phase: "async", name: `plugin(${p2.name})` });
5333
+ throw err;
5334
+ }
5335
+ );
5336
+ settled.catch(() => {
5337
+ });
5338
+ return settled;
5039
5339
  },
5040
5340
  inject(key, defaultValue) {
5041
5341
  if (provided.has(key)) return provided.get(key);
@@ -5073,6 +5373,8 @@ function createPluginRegistry() {
5073
5373
  }
5074
5374
  },
5075
5375
  reset() {
5376
+ generation++;
5377
+ pendingInstalls.clear();
5076
5378
  installedPlugins.clear();
5077
5379
  hooks.init.length = 0;
5078
5380
  hooks.mount.length = 0;
@@ -5092,7 +5394,7 @@ function createPlugin(name, install) {
5092
5394
  }
5093
5395
  function plugin(plugin2, options) {
5094
5396
  _defaults.touched = true;
5095
- _defaults.registry.plugin(plugin2, options);
5397
+ return _defaults.registry.plugin(plugin2, options);
5096
5398
  }
5097
5399
  function inject(key, defaultValue) {
5098
5400
  return _defaults.registry.inject(key, defaultValue);
@@ -5123,35 +5425,44 @@ function setDefaultPluginRegistry(registry) {
5123
5425
  // src/plugins/modular.ts
5124
5426
  function createModuleRegistry() {
5125
5427
  const modules = /* @__PURE__ */ new Map();
5126
- function resolveInternal(name, stack) {
5428
+ const resolving = [];
5429
+ function resolveInternal(name) {
5127
5430
  const entry = modules.get(name);
5128
5431
  if (!entry) {
5129
5432
  throw new Error(`[ModuleRegistry] Module "${name}" is not registered.`);
5130
5433
  }
5131
- if (entry.loaded) {
5434
+ if (entry.state === "loaded") {
5132
5435
  return entry.value;
5133
5436
  }
5134
- if (stack.has(name)) {
5135
- const cycle = [...stack, name].join(" -> ");
5437
+ if (entry.state === "resolving") {
5438
+ const cycle = [...resolving.slice(resolving.indexOf(name)), name].join(" -> ");
5136
5439
  throw new Error(`[ModuleRegistry] Circular dependency detected: ${cycle}`);
5137
5440
  }
5138
- stack.add(name);
5139
- for (const dep of entry.deps) {
5140
- resolveInternal(dep, stack);
5441
+ entry.state = "resolving";
5442
+ resolving.push(name);
5443
+ try {
5444
+ for (const dep of entry.deps) {
5445
+ resolveInternal(dep);
5446
+ }
5447
+ entry.value = entry.factory();
5448
+ entry.state = "loaded";
5449
+ return entry.value;
5450
+ } catch (err) {
5451
+ entry.state = "unloaded";
5452
+ entry.value = void 0;
5453
+ throw err;
5454
+ } finally {
5455
+ resolving.pop();
5141
5456
  }
5142
- stack.delete(name);
5143
- entry.value = entry.factory();
5144
- entry.loaded = true;
5145
- return entry.value;
5146
5457
  }
5147
5458
  return {
5148
5459
  /** Register a module with its factory function and optional dependencies */
5149
5460
  register(name, factory, deps = []) {
5150
- modules.set(name, { factory, deps, loaded: false });
5461
+ modules.set(name, { factory, deps, state: "unloaded" });
5151
5462
  },
5152
5463
  /** Resolve a module, loading its dependencies first */
5153
5464
  resolve(name) {
5154
- return resolveInternal(name, /* @__PURE__ */ new Set());
5465
+ return resolveInternal(name);
5155
5466
  },
5156
5467
  /** Check if a module is registered */
5157
5468
  has(name) {
@@ -5186,7 +5497,7 @@ function createModuleRegistry() {
5186
5497
  /** Reset all loaded modules back to unloaded state (useful for testing) */
5187
5498
  reset() {
5188
5499
  for (const entry of modules.values()) {
5189
- entry.loaded = false;
5500
+ entry.state = "unloaded";
5190
5501
  entry.value = void 0;
5191
5502
  }
5192
5503
  }
@@ -5214,46 +5525,83 @@ function createBundle(modules) {
5214
5525
  function lazyModule(loader) {
5215
5526
  let cached;
5216
5527
  let loadedFlag = false;
5217
- const handle = {
5528
+ let inFlight = null;
5529
+ return {
5218
5530
  get loaded() {
5219
5531
  return loadedFlag;
5220
5532
  },
5221
- async get() {
5222
- if (loadedFlag) return cached;
5223
- cached = await loader();
5224
- loadedFlag = true;
5225
- return cached;
5533
+ get() {
5534
+ if (loadedFlag) return Promise.resolve(cached);
5535
+ if (inFlight) return inFlight;
5536
+ let started;
5537
+ try {
5538
+ started = Promise.resolve(loader());
5539
+ } catch (err) {
5540
+ started = Promise.reject(err);
5541
+ }
5542
+ const attempt = started.then(
5543
+ (value) => {
5544
+ cached = value;
5545
+ loadedFlag = true;
5546
+ if (inFlight === attempt) inFlight = null;
5547
+ return value;
5548
+ },
5549
+ (err) => {
5550
+ if (inFlight === attempt) inFlight = null;
5551
+ throw err;
5552
+ }
5553
+ );
5554
+ inFlight = attempt;
5555
+ return attempt;
5226
5556
  }
5227
5557
  };
5228
- return handle;
5229
5558
  }
5559
+ var MODULE_ENTRY_POINTS = {
5560
+ main: "./index.ts",
5561
+ data: "./data.ts",
5562
+ browser: "./browser.ts",
5563
+ patterns: "./patterns.ts",
5564
+ motion: "./motion.ts",
5565
+ ui: "./ui.ts",
5566
+ widgets: "./widgets.ts",
5567
+ ssr: "./ssr.ts",
5568
+ devtools: "./devtools.ts",
5569
+ performance: "./performance.ts",
5570
+ ecosystem: "./ecosystem.ts",
5571
+ plugins: "./plugins.ts",
5572
+ build: "./build.ts",
5573
+ testing: "./testing.ts",
5574
+ extras: "./extras.ts"
5575
+ };
5576
+ var CDN_ENTRY_POINTS = {
5577
+ cdn: "./dist/cdn.global.js",
5578
+ "cdn-dev": "./dist/cdn.dev.global.js",
5579
+ "cdn-full": "./dist/cdn.full.global.js",
5580
+ "cdn-full-dev": "./dist/cdn.full.dev.global.js"
5581
+ };
5230
5582
  var packageInfo = {
5231
- name: "sibu",
5232
- version: "1.0.0",
5233
- entryPoints: {
5234
- main: "./index.ts",
5235
- core: "./src/core/html.ts",
5236
- hooks: "./src/core/signals/signal.ts",
5237
- router: "./src/plugins/router.ts",
5238
- i18n: "./src/plugins/i18n.ts",
5239
- testing: "./src/testing/index.ts",
5240
- ssr: "./src/core/ssr.ts"
5241
- },
5583
+ name: "sibujs",
5584
+ version: true ? "4.7.0" : "dev",
5585
+ entryPoints: MODULE_ENTRY_POINTS,
5242
5586
  /**
5243
- * Generate a package.json `exports` map for Node.js subpath exports.
5244
- * Maps each entry point to its import, require, and types paths.
5587
+ * Generate the package.json `exports` map. Module entries resolve to the
5588
+ * `.js` (ESM), `.cjs` and `.d.ts` files tsup emits into `dist/`; CDN entries
5589
+ * resolve to their prebuilt global script.
5245
5590
  */
5246
5591
  generateExportsMap() {
5247
5592
  const exportsMap = {};
5248
- for (const [name, sourcePath] of Object.entries(this.entryPoints)) {
5593
+ for (const [name, sourcePath] of Object.entries(MODULE_ENTRY_POINTS)) {
5249
5594
  const distPath = sourcePath.replace(/^\.\//, "./dist/").replace(/\.ts$/, "");
5250
5595
  const subpath = name === "main" ? "." : `./${name}`;
5251
5596
  exportsMap[subpath] = {
5252
- import: `${distPath}.mjs`,
5253
- require: `${distPath}.cjs`,
5254
- types: `${distPath}.d.ts`
5597
+ types: `${distPath}.d.ts`,
5598
+ import: `${distPath}.js`,
5599
+ require: `${distPath}.cjs`
5255
5600
  };
5256
5601
  }
5602
+ for (const [name, file] of Object.entries(CDN_ENTRY_POINTS)) {
5603
+ exportsMap[`./${name}`] = { default: file };
5604
+ }
5257
5605
  return exportsMap;
5258
5606
  }
5259
5607
  };
@@ -5378,29 +5726,26 @@ var env = {
5378
5726
  };
5379
5727
 
5380
5728
  // src/plugins/versioning.ts
5381
- var VERSION = "1.0.0";
5729
+ var VERSION = true ? "4.7.0" : "dev";
5730
+ var NUM = "(?:0|[1-9]\\d*)";
5731
+ var PRE_ID = `(?:${NUM}|\\d*[a-zA-Z-][0-9a-zA-Z-]*)`;
5732
+ var BUILD_ID = "[0-9a-zA-Z-]+";
5733
+ var SEMVER_PATTERN = new RegExp(
5734
+ `^(${NUM})(?:\\.(${NUM})(?:\\.(${NUM})(?:-(${PRE_ID}(?:\\.${PRE_ID})*))?(?:\\+(${BUILD_ID}(?:\\.${BUILD_ID})*))?)?)?$`
5735
+ );
5382
5736
  function parseSemVer(version) {
5383
- const trimmed = version.trim().replace(/^v/i, "");
5384
- const prereleaseIndex = trimmed.indexOf("-");
5385
- let main2;
5386
- let prerelease;
5387
- if (prereleaseIndex !== -1) {
5388
- main2 = trimmed.slice(0, prereleaseIndex);
5389
- prerelease = trimmed.slice(prereleaseIndex + 1);
5390
- } else {
5391
- main2 = trimmed;
5392
- }
5393
- const parts = main2.split(".");
5394
- const major = parseInt(parts[0], 10);
5395
- const minor = parseInt(parts[1] || "0", 10);
5396
- const patch = parseInt(parts[2] || "0", 10);
5397
- if (Number.isNaN(major) || Number.isNaN(minor) || Number.isNaN(patch)) {
5737
+ const trimmed = String(version).trim().replace(/^v/i, "");
5738
+ const match = SEMVER_PATTERN.exec(trimmed);
5739
+ if (!match) {
5398
5740
  throw new Error(`[Versioning] Invalid semver string: "${version}"`);
5399
5741
  }
5400
- const result = { major, minor, patch };
5401
- if (prerelease !== void 0) {
5402
- result.prerelease = prerelease;
5403
- }
5742
+ const result = {
5743
+ major: Number(match[1]),
5744
+ minor: match[2] === void 0 ? 0 : Number(match[2]),
5745
+ patch: match[3] === void 0 ? 0 : Number(match[3])
5746
+ };
5747
+ if (match[4] !== void 0) result.prerelease = match[4];
5748
+ if (match[5] !== void 0) result.build = match[5];
5404
5749
  return result;
5405
5750
  }
5406
5751
  function compareSemVer(a2, b2) {
@@ -5483,82 +5828,154 @@ function satisfies(version, range) {
5483
5828
  const target = parseSemVer(exactStr);
5484
5829
  return compareSemVer(v, target) === 0;
5485
5830
  }
5831
+ var MigrationStorageError = class extends Error {
5832
+ constructor(version, cause) {
5833
+ const reason = cause instanceof Error ? cause.message : String(cause);
5834
+ super(`[Versioning] Migration ${version} completed, but recording it in storage failed: ${reason}`);
5835
+ this.name = "MigrationStorageError";
5836
+ this.version = version;
5837
+ this.cause = cause;
5838
+ }
5839
+ };
5840
+ var _migrationQueues = globalSingleton(
5841
+ /* @__PURE__ */ Symbol.for("sibujs.migrationQueues.v1"),
5842
+ () => /* @__PURE__ */ new WeakMap()
5843
+ );
5844
+ var NO_STORAGE = {};
5486
5845
  function createMigrationRunner(config) {
5487
5846
  const storageKey = config.storageKey || "__sibu_migration_version__";
5488
5847
  const sortedMigrations = [...config.migrations].sort((a2, b2) => compareSemVer(a2.version, b2.version));
5489
5848
  function getStorage() {
5849
+ if (config.storage) return config.storage;
5490
5850
  try {
5491
5851
  return typeof localStorage !== "undefined" ? localStorage : null;
5492
5852
  } catch {
5493
5853
  return null;
5494
5854
  }
5495
5855
  }
5856
+ function getAppliedVersion() {
5857
+ const storage = getStorage();
5858
+ if (!storage) return null;
5859
+ return storage.getItem(storageKey);
5860
+ }
5861
+ function getPending() {
5862
+ const appliedVersion = getAppliedVersion();
5863
+ if (!appliedVersion) {
5864
+ return sortedMigrations.filter((m) => compareSemVer(m.version, config.currentVersion) <= 0);
5865
+ }
5866
+ return sortedMigrations.filter(
5867
+ (m) => compareSemVer(m.version, appliedVersion) > 0 && compareSemVer(m.version, config.currentVersion) <= 0
5868
+ );
5869
+ }
5870
+ function writeApplied(version, migrationVersion) {
5871
+ const storage = getStorage();
5872
+ if (!storage) return;
5873
+ try {
5874
+ if (version === null) storage.removeItem(storageKey);
5875
+ else storage.setItem(storageKey, version);
5876
+ } catch (e) {
5877
+ throw new MigrationStorageError(migrationVersion, e);
5878
+ }
5879
+ }
5880
+ function serialize(operation) {
5881
+ const identity = getStorage() ?? NO_STORAGE;
5882
+ let queues = _migrationQueues.get(identity);
5883
+ if (!queues) {
5884
+ queues = /* @__PURE__ */ new Map();
5885
+ _migrationQueues.set(identity, queues);
5886
+ }
5887
+ const run = (queues.get(storageKey) ?? Promise.resolve()).then(operation, operation);
5888
+ const tail = run.then(
5889
+ () => void 0,
5890
+ () => void 0
5891
+ );
5892
+ queues.set(storageKey, tail);
5893
+ const settled = queues;
5894
+ tail.then(() => {
5895
+ if (settled.get(storageKey) === tail) settled.delete(storageKey);
5896
+ });
5897
+ return run;
5898
+ }
5496
5899
  return {
5497
5900
  /** Get the last applied migration version from storage */
5498
- getAppliedVersion() {
5499
- const storage = getStorage();
5500
- if (!storage) return null;
5501
- return storage.getItem(storageKey);
5502
- },
5901
+ getAppliedVersion,
5503
5902
  /** Get pending migrations that haven't been applied */
5504
- getPending() {
5505
- const appliedVersion = this.getAppliedVersion();
5506
- if (!appliedVersion) {
5507
- return sortedMigrations.filter((m) => compareSemVer(m.version, config.currentVersion) <= 0);
5508
- }
5509
- return sortedMigrations.filter(
5510
- (m) => compareSemVer(m.version, appliedVersion) > 0 && compareSemVer(m.version, config.currentVersion) <= 0
5511
- );
5512
- },
5513
- /** Run all pending migrations in order */
5514
- async migrate() {
5515
- const pending = this.getPending();
5516
- const applied = [];
5517
- const errors = [];
5518
- for (const migration of pending) {
5903
+ getPending,
5904
+ /**
5905
+ * Run all pending migrations in order. Concurrent calls (and calls racing
5906
+ * `rollback()`) run one after another, each recomputing what is pending —
5907
+ * on this runner and on every other runner in this realm sharing its
5908
+ * storage and storage key.
5909
+ */
5910
+ migrate() {
5911
+ return serialize(async () => {
5912
+ const applied = [];
5913
+ const errors = [];
5914
+ let pending;
5519
5915
  try {
5520
- await migration.up();
5521
- applied.push(migration.version);
5522
- const storage = getStorage();
5523
- if (storage) {
5524
- storage.setItem(storageKey, migration.version);
5525
- }
5916
+ pending = getPending();
5526
5917
  } catch (e) {
5527
5918
  errors.push({
5528
- version: migration.version,
5919
+ version: getAppliedVersion() ?? "",
5529
5920
  error: e instanceof Error ? e : new Error(String(e))
5530
5921
  });
5531
- break;
5922
+ return { applied, errors };
5532
5923
  }
5533
- }
5534
- return { applied, errors };
5924
+ for (const migration of pending) {
5925
+ try {
5926
+ await migration.up();
5927
+ } catch (e) {
5928
+ errors.push({
5929
+ version: migration.version,
5930
+ error: e instanceof Error ? e : new Error(String(e))
5931
+ });
5932
+ break;
5933
+ }
5934
+ applied.push(migration.version);
5935
+ try {
5936
+ writeApplied(migration.version, migration.version);
5937
+ } catch (e) {
5938
+ errors.push({ version: migration.version, error: e });
5939
+ break;
5940
+ }
5941
+ }
5942
+ return { applied, errors };
5943
+ });
5535
5944
  },
5536
- /** Rollback to a specific version */
5537
- async rollback(targetVersion) {
5538
- const appliedVersion = this.getAppliedVersion();
5539
- const rolledBack = [];
5540
- if (!appliedVersion) {
5541
- return { rolledBack };
5542
- }
5543
- const toRollback = sortedMigrations.filter((m) => compareSemVer(m.version, targetVersion) > 0 && compareSemVer(m.version, appliedVersion) <= 0).reverse();
5544
- for (const migration of toRollback) {
5545
- if (!migration.down) {
5546
- throw new Error(
5547
- `[Versioning] Migration ${migration.version} ("${migration.description}") does not have a down() function and cannot be rolled back.`
5548
- );
5945
+ /**
5946
+ * Rollback to a specific version.
5947
+ *
5948
+ * The applied version is checkpointed after EVERY successful `down()`, so a
5949
+ * rollback that fails part-way leaves storage describing what is actually
5950
+ * still applied, and a retry does not repeat completed `down()` steps.
5951
+ * Throws the failing `down()`'s error, a missing-`down()` error, or a
5952
+ * {@link MigrationStorageError} if a checkpoint cannot be written.
5953
+ */
5954
+ rollback(targetVersion) {
5955
+ return serialize(async () => {
5956
+ const appliedVersion = getAppliedVersion();
5957
+ const rolledBack = [];
5958
+ if (!appliedVersion) {
5959
+ return { rolledBack };
5549
5960
  }
5550
- await migration.down();
5551
- rolledBack.push(migration.version);
5552
- }
5553
- const storage = getStorage();
5554
- if (storage) {
5555
- if (targetVersion === "0.0.0") {
5556
- storage.removeItem(storageKey);
5557
- } else {
5558
- storage.setItem(storageKey, targetVersion);
5961
+ const toRollback = sortedMigrations.filter((m) => compareSemVer(m.version, targetVersion) > 0 && compareSemVer(m.version, appliedVersion) <= 0).reverse();
5962
+ for (const migration of toRollback) {
5963
+ if (!migration.down) {
5964
+ throw new Error(
5965
+ `[Versioning] Migration ${migration.version} ("${migration.description}") does not have a down() function and cannot be rolled back.`
5966
+ );
5967
+ }
5559
5968
  }
5560
- }
5561
- return { rolledBack };
5969
+ for (const migration of toRollback) {
5970
+ await migration.down();
5971
+ rolledBack.push(migration.version);
5972
+ const index = sortedMigrations.indexOf(migration);
5973
+ const previous = index > 0 ? sortedMigrations[index - 1].version : null;
5974
+ writeApplied(previous, migration.version);
5975
+ }
5976
+ writeApplied(targetVersion === "0.0.0" ? null : targetVersion, targetVersion);
5977
+ return { rolledBack };
5978
+ });
5562
5979
  }
5563
5980
  };
5564
5981
  }
@@ -5589,6 +6006,7 @@ function extractRangeTarget(range) {
5589
6006
  }
5590
6007
 
5591
6008
  // src/plugins/startup.ts
6009
+ init_errors();
5592
6010
  init_ssr();
5593
6011
  function preloadCritical(resources) {
5594
6012
  if (typeof document === "undefined") return;
@@ -5609,28 +6027,43 @@ function preloadCritical(resources) {
5609
6027
  document.head.appendChild(link2);
5610
6028
  }
5611
6029
  }
5612
- function prerenderRoutes(routes, options) {
5613
- const maxCacheSize = options?.maxCacheSize ?? 50;
5614
- const cacheTTL = options?.cacheTTL ?? 0;
5615
- const cache = /* @__PURE__ */ new Map();
5616
- function isValid(entry) {
5617
- if (cacheTTL === 0) return true;
5618
- return Date.now() - entry.timestamp < cacheTTL;
6030
+ function assertCacheSize(name, value) {
6031
+ if (!Number.isInteger(value) || value < 0) {
6032
+ throw new RangeError(`[Startup] ${name} must be a non-negative integer, got ${value}`);
5619
6033
  }
5620
- function evictOldest() {
5621
- if (cache.size < maxCacheSize) return;
6034
+ }
6035
+ function makeRoomFor(cache, key, maxSize, isValid) {
6036
+ if (maxSize === 0) return false;
6037
+ if (cache.has(key)) return true;
6038
+ if (cache.size < maxSize) return true;
6039
+ for (const [k, entry] of cache) {
6040
+ if (!isValid(entry)) cache.delete(k);
6041
+ }
6042
+ while (cache.size >= maxSize) {
5622
6043
  let oldestKey = null;
5623
6044
  let oldestTime = Infinity;
5624
- for (const [key, entry] of cache) {
6045
+ for (const [k, entry] of cache) {
5625
6046
  if (entry.timestamp < oldestTime) {
5626
6047
  oldestTime = entry.timestamp;
5627
- oldestKey = key;
6048
+ oldestKey = k;
5628
6049
  }
5629
6050
  }
5630
- if (oldestKey) cache.delete(oldestKey);
6051
+ if (oldestKey === null) break;
6052
+ cache.delete(oldestKey);
6053
+ }
6054
+ return true;
6055
+ }
6056
+ function prerenderRoutes(routes, options) {
6057
+ const maxCacheSize = options?.maxCacheSize ?? 50;
6058
+ const cacheTTL = options?.cacheTTL ?? 0;
6059
+ assertCacheSize("maxCacheSize", maxCacheSize);
6060
+ const cache = /* @__PURE__ */ new Map();
6061
+ function isValid(entry) {
6062
+ if (cacheTTL === 0) return true;
6063
+ return Date.now() - entry.timestamp < cacheTTL;
5631
6064
  }
5632
6065
  for (const route2 of routes) {
5633
- evictOldest();
6066
+ if (!makeRoomFor(cache, route2.path, maxCacheSize, isValid)) break;
5634
6067
  const html2 = renderToString(route2.component());
5635
6068
  cache.set(route2.path, { html: html2, timestamp: Date.now() });
5636
6069
  }
@@ -5682,6 +6115,7 @@ function prerenderRoutes(routes, options) {
5682
6115
  function createSSRCache(config) {
5683
6116
  const maxSize = config?.maxSize ?? 100;
5684
6117
  const defaultTTL = config?.defaultTTL ?? 6e4;
6118
+ assertCacheSize("maxSize", maxSize);
5685
6119
  const cache = /* @__PURE__ */ new Map();
5686
6120
  let hits = 0;
5687
6121
  let misses = 0;
@@ -5689,18 +6123,6 @@ function createSSRCache(config) {
5689
6123
  if (entry.ttl === 0) return true;
5690
6124
  return Date.now() - entry.timestamp < entry.ttl;
5691
6125
  }
5692
- function evictOldest() {
5693
- if (cache.size < maxSize) return;
5694
- let oldestKey = null;
5695
- let oldestTime = Infinity;
5696
- for (const [key, entry] of cache) {
5697
- if (entry.timestamp < oldestTime) {
5698
- oldestTime = entry.timestamp;
5699
- oldestKey = key;
5700
- }
5701
- }
5702
- if (oldestKey) cache.delete(oldestKey);
5703
- }
5704
6126
  return {
5705
6127
  /** Get cached HTML for a key, or undefined if not cached or expired */
5706
6128
  get(key) {
@@ -5719,7 +6141,7 @@ function createSSRCache(config) {
5719
6141
  },
5720
6142
  /** Cache an HTML string with an optional TTL override */
5721
6143
  set(key, html2, ttl) {
5722
- evictOldest();
6144
+ if (!makeRoomFor(cache, key, maxSize, isValid)) return;
5723
6145
  cache.set(key, {
5724
6146
  html: html2,
5725
6147
  timestamp: Date.now(),
@@ -5752,25 +6174,30 @@ function createSSRCache(config) {
5752
6174
  }
5753
6175
  };
5754
6176
  }
6177
+ var DEFER_IDLE_TIMEOUT_MS = 2e3;
5755
6178
  function deferNonCritical(tasks) {
5756
6179
  if (tasks.length === 0) return;
5757
- const schedule = typeof requestIdleCallback !== "undefined" ? requestIdleCallback : (cb) => setTimeout(cb, 1);
6180
+ const schedule = typeof requestIdleCallback !== "undefined" ? (cb) => {
6181
+ requestIdleCallback(cb, { timeout: DEFER_IDLE_TIMEOUT_MS });
6182
+ } : (cb) => {
6183
+ setTimeout(cb, 1);
6184
+ };
5758
6185
  const queue = [...tasks];
5759
6186
  let index = 0;
5760
6187
  function processNext(deadline) {
6188
+ let ranOne = false;
5761
6189
  while (index < queue.length) {
5762
- if (deadline && deadline.timeRemaining() < 1) {
6190
+ if (ranOne && deadline && deadline.timeRemaining() < 1) {
5763
6191
  schedule(processNext);
5764
6192
  return;
5765
6193
  }
5766
6194
  try {
5767
6195
  queue[index]();
5768
6196
  } catch (e) {
5769
- if (typeof console !== "undefined") {
5770
- console.error("[Startup] Deferred task failed:", e);
5771
- }
6197
+ reportError(e, { phase: "scheduler", name: "deferNonCritical" });
5772
6198
  }
5773
6199
  index++;
6200
+ ranOne = true;
5774
6201
  }
5775
6202
  }
5776
6203
  schedule(processNext);
@@ -5822,7 +6249,9 @@ function createBootSequence() {
5822
6249
  // Annotate the CommonJS export names for ESM import in node:
5823
6250
  0 && (module.exports = {
5824
6251
  KeepAliveRoute,
6252
+ MigrationStorageError,
5825
6253
  Outlet,
6254
+ PluginInstallCancelledError,
5826
6255
  Route,
5827
6256
  RouterLink,
5828
6257
  SibuRouter,
@@ -5866,6 +6295,7 @@ function createBootSequence() {
5866
6295
  healthCheck,
5867
6296
  hydrateRouter,
5868
6297
  inject,
6298
+ isPluginInstallCancelledError,
5869
6299
  lazy,
5870
6300
  lazyModule,
5871
6301
  navigate,
@@ -5894,6 +6324,7 @@ function createBootSequence() {
5894
6324
  setRouteTransition,
5895
6325
  setRoutes,
5896
6326
  t,
6327
+ translated,
5897
6328
  triggerPluginError,
5898
6329
  triggerPluginMount,
5899
6330
  triggerPluginUnmount