sibujs 3.3.1 → 3.3.3

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 (78) hide show
  1. package/dist/browser.cjs +41 -18
  2. package/dist/browser.js +5 -5
  3. package/dist/build.cjs +57 -22
  4. package/dist/build.js +14 -14
  5. package/dist/cdn.global.js +7 -7
  6. package/dist/{chunk-MHBCEJQO.js → chunk-23VT3KZB.js} +2 -2
  7. package/dist/{chunk-WL7BIR6O.js → chunk-25LY5SRH.js} +31 -24
  8. package/dist/{chunk-37BUKSLH.js → chunk-5K6RVA2S.js} +1 -1
  9. package/dist/{chunk-AMIKDMLP.js → chunk-5Y34FWED.js} +17 -6
  10. package/dist/chunk-7ZHH77QA.js +9 -0
  11. package/dist/chunk-CCSJMTRN.js +15 -0
  12. package/dist/{chunk-R3QEDXFS.js → chunk-EX77FXTT.js} +1 -1
  13. package/dist/{chunk-WW6DAGGR.js → chunk-F3HO2MP7.js} +1 -1
  14. package/dist/{chunk-ZUVLC7TM.js → chunk-F7HW2NI5.js} +2 -4
  15. package/dist/{chunk-ULLTNDRA.js → chunk-IEYFHN5V.js} +72 -25
  16. package/dist/{chunk-Z37APKBV.js → chunk-IQN5W7GE.js} +73 -16
  17. package/dist/{chunk-WZG2SZOT.js → chunk-IWFE4AHO.js} +1 -1
  18. package/dist/{chunk-IKLYI3RF.js → chunk-MYXEBADX.js} +53 -23
  19. package/dist/{chunk-6LTFHJQG.js → chunk-QCQQ2N5H.js} +41 -20
  20. package/dist/{chunk-VOVVTOEA.js → chunk-QTOOBABV.js} +22 -5
  21. package/dist/{chunk-LU2MQXQQ.js → chunk-RZKGMHH4.js} +6 -6
  22. package/dist/{chunk-GOJMFRBL.js → chunk-S3NFJO6L.js} +20 -14
  23. package/dist/{chunk-NHKQKKZU.js → chunk-SBPUXWCE.js} +1 -1
  24. package/dist/{chunk-SLMFA3ZZ.js → chunk-TBDTU7UO.js} +2 -2
  25. package/dist/{chunk-4UUMSLSL.js → chunk-TVCCXPU2.js} +5 -5
  26. package/dist/{chunk-TEFZT5PJ.js → chunk-UOMYIAG6.js} +1 -1
  27. package/dist/{chunk-XH2RTYEQ.js → chunk-WFUUT6TG.js} +15 -8
  28. package/dist/{chunk-M5KBNOSJ.js → chunk-WTFMV2RU.js} +70 -59
  29. package/dist/{chunk-3JHCYHWN.js → chunk-WWV3SJ3L.js} +19 -13
  30. package/dist/{chunk-RYMOSG5B.js → chunk-Y35NQNLG.js} +90 -60
  31. package/dist/{chunk-F7FXQ3QS.js → chunk-ZXCZWMZT.js} +1 -1
  32. package/dist/data.cjs +36 -16
  33. package/dist/data.js +8 -7
  34. package/dist/devtools.cjs +91 -35
  35. package/dist/devtools.d.cts +12 -5
  36. package/dist/devtools.d.ts +12 -5
  37. package/dist/devtools.js +7 -6
  38. package/dist/ecosystem.cjs +31 -16
  39. package/dist/ecosystem.js +11 -10
  40. package/dist/extras.cjs +485 -280
  41. package/dist/extras.d.cts +1 -1
  42. package/dist/extras.d.ts +1 -1
  43. package/dist/extras.js +28 -24
  44. package/dist/index.cjs +59 -22
  45. package/dist/index.d.cts +24 -8
  46. package/dist/index.d.ts +24 -8
  47. package/dist/index.js +25 -21
  48. package/dist/motion.cjs +223 -204
  49. package/dist/motion.d.cts +8 -1
  50. package/dist/motion.d.ts +8 -1
  51. package/dist/motion.js +6 -3
  52. package/dist/patterns.cjs +33 -20
  53. package/dist/patterns.d.cts +4 -1
  54. package/dist/patterns.d.ts +4 -1
  55. package/dist/patterns.js +6 -6
  56. package/dist/performance.cjs +90 -70
  57. package/dist/performance.js +8 -7
  58. package/dist/plugins.cjs +207 -144
  59. package/dist/plugins.d.cts +2 -1
  60. package/dist/plugins.d.ts +2 -1
  61. package/dist/plugins.js +178 -124
  62. package/dist/{ssr-6D67RAVB.js → ssr-2PPULEK2.js} +2 -2
  63. package/dist/ssr.cjs +132 -105
  64. package/dist/ssr.d.cts +8 -1
  65. package/dist/ssr.d.ts +8 -1
  66. package/dist/ssr.js +11 -10
  67. package/dist/testing.cjs +38 -18
  68. package/dist/testing.js +19 -8
  69. package/dist/ui.cjs +337 -294
  70. package/dist/ui.d.cts +0 -20
  71. package/dist/ui.d.ts +0 -20
  72. package/dist/ui.js +30 -24
  73. package/dist/widgets.cjs +95 -27
  74. package/dist/widgets.d.cts +6 -1
  75. package/dist/widgets.d.ts +6 -1
  76. package/dist/widgets.js +8 -7
  77. package/package.json +1 -1
  78. package/dist/chunk-YT6HQ6AM.js +0 -14
@@ -254,11 +254,12 @@ declare function RouterLink(props: {
254
254
  replace?: boolean;
255
255
  activeClass?: string;
256
256
  exactActiveClass?: string;
257
+ /** @deprecated Pass children positionally: `RouterLink(props, children)`. */
257
258
  nodes?: string | Node | (string | Node)[];
258
259
  target?: string;
259
260
  rel?: string;
260
261
  [key: string]: unknown;
261
- }): HTMLElement;
262
+ }, children?: string | Node | (string | Node)[]): HTMLElement;
262
263
  declare function Suspense(props: {
263
264
  fallback?: () => HTMLElement | HTMLElement;
264
265
  nodes: () => HTMLElement | Promise<HTMLElement>;
package/dist/plugins.d.ts CHANGED
@@ -254,11 +254,12 @@ declare function RouterLink(props: {
254
254
  replace?: boolean;
255
255
  activeClass?: string;
256
256
  exactActiveClass?: string;
257
+ /** @deprecated Pass children positionally: `RouterLink(props, children)`. */
257
258
  nodes?: string | Node | (string | Node)[];
258
259
  target?: string;
259
260
  rel?: string;
260
261
  [key: string]: unknown;
261
- }): HTMLElement;
262
+ }, children?: string | Node | (string | Node)[]): HTMLElement;
262
263
  declare function Suspense(props: {
263
264
  fallback?: () => HTMLElement | HTMLElement;
264
265
  nodes: () => HTMLElement | Promise<HTMLElement>;
package/dist/plugins.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  preloadCritical,
19
19
  prerenderRoutes,
20
20
  satisfies
21
- } from "./chunk-ZUVLC7TM.js";
21
+ } from "./chunk-F7HW2NI5.js";
22
22
  import {
23
23
  isUnsafeKey
24
24
  } from "./chunk-H3SRKIYX.js";
@@ -32,21 +32,20 @@ import {
32
32
  triggerPluginError,
33
33
  triggerPluginMount,
34
34
  triggerPluginUnmount
35
- } from "./chunk-3JHCYHWN.js";
35
+ } from "./chunk-WWV3SJ3L.js";
36
+ import {
37
+ globalSingleton
38
+ } from "./chunk-7ZHH77QA.js";
36
39
  import {
37
40
  span
38
- } from "./chunk-37BUKSLH.js";
41
+ } from "./chunk-5K6RVA2S.js";
39
42
  import {
40
43
  escapeScriptJson,
41
44
  isDangerousMetaRefresh,
42
45
  renderToString
43
- } from "./chunk-R3QEDXFS.js";
44
- import "./chunk-LU2MQXQQ.js";
45
- import "./chunk-NHKQKKZU.js";
46
- import {
47
- dispose,
48
- registerDisposer
49
- } from "./chunk-5VGSK6D2.js";
46
+ } from "./chunk-EX77FXTT.js";
47
+ import "./chunk-RZKGMHH4.js";
48
+ import "./chunk-SBPUXWCE.js";
50
49
  import {
51
50
  isUrlAttribute,
52
51
  sanitizeCSSValue,
@@ -55,19 +54,27 @@ import {
55
54
  } from "./chunk-L3GAGWCC.js";
56
55
  import {
57
56
  effect
58
- } from "./chunk-MHBCEJQO.js";
59
- import "./chunk-GOJMFRBL.js";
57
+ } from "./chunk-23VT3KZB.js";
58
+ import "./chunk-S3NFJO6L.js";
59
+ import {
60
+ dispose,
61
+ registerDisposer
62
+ } from "./chunk-5VGSK6D2.js";
60
63
  import {
61
64
  signal
62
- } from "./chunk-WZG2SZOT.js";
65
+ } from "./chunk-IWFE4AHO.js";
63
66
  import {
64
67
  track
65
- } from "./chunk-TEFZT5PJ.js";
68
+ } from "./chunk-UOMYIAG6.js";
66
69
  import "./chunk-COY6PUD2.js";
67
70
 
68
71
  // src/plugins/i18n.ts
69
- var [currentLocale, setLocaleInternal] = signal("en");
70
- var locales = {};
72
+ var _i18n = globalSingleton(/* @__PURE__ */ Symbol.for("sibujs.i18n.v1"), () => ({
73
+ locale: signal("en"),
74
+ locales: {}
75
+ }));
76
+ var [currentLocale, setLocaleInternal] = _i18n.locale;
77
+ var locales = _i18n.locales;
71
78
  function setLocale(locale) {
72
79
  setLocaleInternal(locale);
73
80
  }
@@ -170,14 +177,39 @@ var NavigationController = class {
170
177
  return this.currentController !== null;
171
178
  }
172
179
  };
173
- var RouteMatcher = class {
180
+ var RouteMatcher = class _RouteMatcher {
174
181
  constructor(routes) {
175
182
  this.routeTrie = /* @__PURE__ */ new Map();
176
183
  this.parentChain = /* @__PURE__ */ new Map();
177
184
  this.namedRoutes = /* @__PURE__ */ new Map();
178
185
  this.compiledPatterns = new LRUCache(50);
186
+ // Pattern routes (those with params/wildcards) ordered most-specific-first,
187
+ // rebuilt lazily after any mutation. Static full paths are served by the
188
+ // exact-match map and excluded here.
189
+ this.patternOrder = null;
179
190
  this.buildIndex(routes);
180
191
  }
192
+ // Specificity per segment: static (2) > param `:x` (1) > wildcard `*` (0).
193
+ static specificity(path) {
194
+ return path.split("/").filter(Boolean).map((seg) => seg.startsWith(":") ? 1 : seg.includes("*") ? 0 : 2);
195
+ }
196
+ getPatternOrder() {
197
+ if (this.patternOrder) return this.patternOrder;
198
+ const patterns = [...this.routeTrie].filter(([p]) => p.includes(":") || p.includes("*"));
199
+ patterns.sort(([a], [b]) => {
200
+ const ka = _RouteMatcher.specificity(a);
201
+ const kb = _RouteMatcher.specificity(b);
202
+ const len = Math.max(ka.length, kb.length);
203
+ for (let i = 0; i < len; i++) {
204
+ const va = ka[i] ?? -1;
205
+ const vb = kb[i] ?? -1;
206
+ if (va !== vb) return vb - va;
207
+ }
208
+ return 0;
209
+ });
210
+ this.patternOrder = patterns;
211
+ return patterns;
212
+ }
181
213
  buildIndex(routes, parentPath = "", ancestors = []) {
182
214
  for (const route2 of routes) {
183
215
  const fullPath = parentPath + route2.path;
@@ -204,7 +236,7 @@ var RouteMatcher = class {
204
236
  if (exactMatch) {
205
237
  return { route: exactMatch, params: {}, matched: this.parentChain.get(path) || [exactMatch] };
206
238
  }
207
- for (const [routePath, route2] of this.routeTrie) {
239
+ for (const [routePath, route2] of this.getPatternOrder()) {
208
240
  const match = this.matchPattern(path, routePath);
209
241
  if (match) {
210
242
  return { route: route2, params: match.params, matched: this.parentChain.get(routePath) || [route2] };
@@ -276,9 +308,11 @@ var RouteMatcher = class {
276
308
  this.parentChain.clear();
277
309
  this.namedRoutes.clear();
278
310
  this.compiledPatterns.clear();
311
+ this.patternOrder = null;
279
312
  this.buildIndex(routes);
280
313
  }
281
314
  addRoute(route2, parentPath = "") {
315
+ this.patternOrder = null;
282
316
  const fullPath = parentPath + route2.path;
283
317
  const parentAncestors = this.parentChain.get(parentPath) || [];
284
318
  const chain = [...parentAncestors, route2];
@@ -293,6 +327,7 @@ var RouteMatcher = class {
293
327
  }
294
328
  removeRoute(path) {
295
329
  this.compiledPatterns.clear();
330
+ this.patternOrder = null;
296
331
  const root = this.routeTrie.get(path);
297
332
  if (!root) return;
298
333
  const removed = /* @__PURE__ */ new Set();
@@ -559,14 +594,16 @@ var _SibuRouter = class _SibuRouter {
559
594
  this.initialize();
560
595
  }
561
596
  initialize() {
562
- if (this.options.mode === "history") {
563
- const popstateHandler = () => this.handleLocationChange(true);
564
- window.addEventListener("popstate", popstateHandler);
565
- this.cleanup.push(() => window.removeEventListener("popstate", popstateHandler));
566
- } else {
567
- const hashHandler = () => this.handleLocationChange(true);
568
- window.addEventListener("hashchange", hashHandler);
569
- this.cleanup.push(() => window.removeEventListener("hashchange", hashHandler));
597
+ if (typeof window !== "undefined") {
598
+ if (this.options.mode === "history") {
599
+ const popstateHandler = () => this.handleLocationChange(true);
600
+ window.addEventListener("popstate", popstateHandler);
601
+ this.cleanup.push(() => window.removeEventListener("popstate", popstateHandler));
602
+ } else {
603
+ const hashHandler = () => this.handleLocationChange(true);
604
+ window.addEventListener("hashchange", hashHandler);
605
+ this.cleanup.push(() => window.removeEventListener("hashchange", hashHandler));
606
+ }
570
607
  }
571
608
  queueMicrotask(() => {
572
609
  this.handleLocationChange(true);
@@ -864,7 +901,8 @@ var NavigationFailureError = class extends Error {
864
901
  };
865
902
  }
866
903
  };
867
- var globalRouter = null;
904
+ var ROUTER_KEY = /* @__PURE__ */ Symbol.for("sibujs.router.v1");
905
+ var _routerRef = globalThis[ROUTER_KEY] ?? (globalThis[ROUTER_KEY] = { current: null });
868
906
  function normalizeRoutes(routes) {
869
907
  return routes.map((route2) => {
870
908
  const normalizedChildren = route2.children && route2.children.length > 0 ? normalizeRoutes(route2.children) : route2.children;
@@ -884,8 +922,8 @@ function normalizeRoutes(routes) {
884
922
  });
885
923
  }
886
924
  function createRouter(routesOrOptions, options = {}) {
887
- if (globalRouter) {
888
- globalRouter.destroy();
925
+ if (_routerRef.current) {
926
+ _routerRef.current.destroy();
889
927
  }
890
928
  let routes;
891
929
  if (Array.isArray(routesOrOptions)) {
@@ -894,69 +932,69 @@ function createRouter(routesOrOptions, options = {}) {
894
932
  options = routesOrOptions;
895
933
  routes = [];
896
934
  }
897
- globalRouter = new SibuRouter(routes, options);
935
+ _routerRef.current = new SibuRouter(routes, options);
898
936
  ensureRouterPagehide();
899
- return globalRouter;
937
+ return _routerRef.current;
900
938
  }
901
939
  function setRoutes(routes) {
902
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
903
- globalRouter.updateRoutes(normalizeRoutes(routes));
940
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
941
+ _routerRef.current.updateRoutes(normalizeRoutes(routes));
904
942
  }
905
943
  function route() {
906
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
907
- return globalRouter.currentRoute;
944
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
945
+ return _routerRef.current.currentRoute;
908
946
  }
909
947
  function router() {
910
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
948
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
911
949
  return {
912
- currentRoute: globalRouter.currentRoute,
913
- isReady: globalRouter.isReady,
914
- isNavigating: globalRouter.isNavigating,
915
- push: (to) => globalRouter?.push(to),
916
- replace: (to) => globalRouter?.replace(to),
917
- go: (delta) => globalRouter?.go(delta),
918
- back: () => globalRouter?.back(),
919
- forward: () => globalRouter?.forward(),
920
- beforeEach: (guard) => globalRouter?.beforeEach(guard),
921
- beforeResolve: (guard) => globalRouter?.beforeResolve(guard),
922
- afterEach: (hook) => globalRouter?.afterEach(hook)
950
+ currentRoute: _routerRef.current.currentRoute,
951
+ isReady: _routerRef.current.isReady,
952
+ isNavigating: _routerRef.current.isNavigating,
953
+ push: (to) => _routerRef.current?.push(to),
954
+ replace: (to) => _routerRef.current?.replace(to),
955
+ go: (delta) => _routerRef.current?.go(delta),
956
+ back: () => _routerRef.current?.back(),
957
+ forward: () => _routerRef.current?.forward(),
958
+ beforeEach: (guard) => _routerRef.current?.beforeEach(guard),
959
+ beforeResolve: (guard) => _routerRef.current?.beforeResolve(guard),
960
+ afterEach: (hook) => _routerRef.current?.afterEach(hook)
923
961
  };
924
962
  }
925
963
  function navigate(to, options) {
926
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
927
- return globalRouter.navigate(to, options);
964
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
965
+ return _routerRef.current.navigate(to, options);
928
966
  }
929
967
  function push(to) {
930
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
931
- return globalRouter.push(to);
968
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
969
+ return _routerRef.current.push(to);
932
970
  }
933
971
  function replace(to) {
934
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
935
- return globalRouter.replace(to);
972
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
973
+ return _routerRef.current.replace(to);
936
974
  }
937
975
  function go(delta) {
938
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
939
- globalRouter.go(delta);
976
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
977
+ _routerRef.current.go(delta);
940
978
  }
941
979
  function back() {
942
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
943
- globalRouter.back();
980
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
981
+ _routerRef.current.back();
944
982
  }
945
983
  function forward() {
946
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
947
- globalRouter.forward();
984
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
985
+ _routerRef.current.forward();
948
986
  }
949
987
  function beforeEach(guard) {
950
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
951
- return globalRouter.beforeEach(guard);
988
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
989
+ return _routerRef.current.beforeEach(guard);
952
990
  }
953
991
  function beforeResolve(guard) {
954
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
955
- return globalRouter.beforeResolve(guard);
992
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
993
+ return _routerRef.current.beforeResolve(guard);
956
994
  }
957
995
  function afterEach(hook) {
958
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
959
- return globalRouter.afterEach(hook);
996
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
997
+ return _routerRef.current.afterEach(hook);
960
998
  }
961
999
  var routeCleanups = [];
962
1000
  function Route() {
@@ -1030,8 +1068,8 @@ function Route() {
1030
1068
  retryButton.className = "route-error-retry";
1031
1069
  retryButton.type = "button";
1032
1070
  const onRetryClick = () => {
1033
- if (globalRouter) {
1034
- globalRouter.clearErrorCache();
1071
+ if (_routerRef.current) {
1072
+ _routerRef.current.clearErrorCache();
1035
1073
  update();
1036
1074
  }
1037
1075
  };
@@ -1043,11 +1081,11 @@ function Route() {
1043
1081
  anchor.parentNode.insertBefore(errorNode, anchor.nextSibling);
1044
1082
  };
1045
1083
  const update = async () => {
1046
- if (!globalRouter) return;
1084
+ if (!_routerRef.current) return;
1047
1085
  const seq = ++navSeq;
1048
- const route2 = globalRouter.currentRoute;
1086
+ const route2 = _routerRef.current.currentRoute;
1049
1087
  try {
1050
- const match = globalRouter["matcher"].match(route2.path);
1088
+ const match = _routerRef.current["matcher"].match(route2.path);
1051
1089
  if (!match) {
1052
1090
  currentTopRoute = null;
1053
1091
  cleanupNodes();
@@ -1060,7 +1098,7 @@ function Route() {
1060
1098
  if ("redirect" in routeDef) {
1061
1099
  const redirectPath = typeof routeDef.redirect === "function" ? routeDef.redirect(route2) : routeDef.redirect;
1062
1100
  queueMicrotask(() => {
1063
- globalRouter?.navigate(redirectPath).catch((err) => {
1101
+ _routerRef.current?.navigate(redirectPath).catch((err) => {
1064
1102
  if (typeof console !== "undefined") console.error("[router] redirect failed:", err);
1065
1103
  });
1066
1104
  });
@@ -1072,7 +1110,7 @@ function Route() {
1072
1110
  if (isAsync) {
1073
1111
  showLoading();
1074
1112
  }
1075
- const component = await globalRouter.loadComponent(routeDef, route2.path);
1113
+ const component = await _routerRef.current.loadComponent(routeDef, route2.path);
1076
1114
  if (seq !== navSeq) return;
1077
1115
  const node = component();
1078
1116
  if (node && anchor.parentNode) {
@@ -1106,18 +1144,23 @@ function Route() {
1106
1144
  if (!routeInitialized && anchor.parentNode) wrappedUpdate();
1107
1145
  });
1108
1146
  }
1109
- routeCleanups.push(() => {
1147
+ let routeTorn = false;
1148
+ const routeCleanup = () => {
1149
+ if (routeTorn) return;
1150
+ routeTorn = true;
1110
1151
  routeTeardown();
1111
1152
  cleanupNodes();
1112
- });
1153
+ };
1154
+ registerDisposer(anchor, routeCleanup);
1155
+ routeCleanups.push(routeCleanup);
1113
1156
  return anchor;
1114
1157
  }
1115
1158
  function KeepAliveRoute(options) {
1116
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1159
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1117
1160
  const anchor = document.createComment("keep-alive-route");
1118
1161
  const cache = /* @__PURE__ */ new Map();
1119
1162
  const lruOrder = [];
1120
- const routerOpts = globalRouter["options"];
1163
+ const routerOpts = _routerRef.current["options"];
1121
1164
  const keepAliveOpt = routerOpts.keepAlive;
1122
1165
  const maxCache = options?.max ?? (typeof keepAliveOpt === "number" ? keepAliveOpt : 20);
1123
1166
  const includeNames = options?.include ?? (Array.isArray(keepAliveOpt) ? keepAliveOpt : void 0);
@@ -1127,19 +1170,19 @@ function KeepAliveRoute(options) {
1127
1170
  let isUpdating = false;
1128
1171
  let pendingUpdate = false;
1129
1172
  const update = async () => {
1130
- if (!globalRouter) return;
1173
+ if (!_routerRef.current) return;
1131
1174
  if (isUpdating) {
1132
1175
  pendingUpdate = true;
1133
1176
  return;
1134
1177
  }
1135
- const route2 = globalRouter.currentRoute;
1136
- const match = globalRouter["matcher"].match(route2.path);
1178
+ const route2 = _routerRef.current.currentRoute;
1179
+ const match = _routerRef.current["matcher"].match(route2.path);
1137
1180
  if (!match) return;
1138
1181
  const { route: routeDef } = match;
1139
1182
  if ("redirect" in routeDef) {
1140
1183
  const redirectPath = typeof routeDef.redirect === "function" ? routeDef.redirect(route2) : routeDef.redirect;
1141
1184
  queueMicrotask(() => {
1142
- globalRouter?.navigate(redirectPath).catch((err) => {
1185
+ _routerRef.current?.navigate(redirectPath).catch((err) => {
1143
1186
  if (typeof console !== "undefined") console.error("[router] redirect failed:", err);
1144
1187
  });
1145
1188
  });
@@ -1172,9 +1215,9 @@ function KeepAliveRoute(options) {
1172
1215
  }
1173
1216
  lruOrder.push(cacheKey);
1174
1217
  } else {
1175
- const component = await globalRouter.loadComponent(routeDef, route2.path);
1218
+ const component = await _routerRef.current.loadComponent(routeDef, route2.path);
1176
1219
  const node = component();
1177
- if (!node || route2.path !== globalRouter.currentRoute.path) {
1220
+ if (!node || route2.path !== _routerRef.current.currentRoute.path) {
1178
1221
  isUpdating = false;
1179
1222
  return;
1180
1223
  }
@@ -1219,7 +1262,10 @@ function KeepAliveRoute(options) {
1219
1262
  if (!initialized && anchor.parentNode) wrappedUpdate();
1220
1263
  });
1221
1264
  }
1222
- routeCleanups.push(() => {
1265
+ let kaTorn = false;
1266
+ const kaCleanup = () => {
1267
+ if (kaTorn) return;
1268
+ kaTorn = true;
1223
1269
  kaTeardown();
1224
1270
  for (const node of cache.values()) {
1225
1271
  dispose(node);
@@ -1229,15 +1275,18 @@ function KeepAliveRoute(options) {
1229
1275
  lruOrder.length = 0;
1230
1276
  if (currentNode?.parentNode) currentNode.parentNode.removeChild(currentNode);
1231
1277
  currentNode = null;
1232
- });
1278
+ };
1279
+ registerDisposer(anchor, kaCleanup);
1280
+ routeCleanups.push(kaCleanup);
1233
1281
  return anchor;
1234
1282
  }
1235
- function RouterLink(props) {
1236
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1283
+ function RouterLink(props, children) {
1284
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1237
1285
  const { to, replace: replace2 = false, activeClass, exactActiveClass, nodes, target, rel, class: classAttr, ...attrs } = props;
1286
+ const content = children !== void 0 ? children : nodes;
1238
1287
  const baseClass = typeof classAttr === "string" ? classAttr : "";
1239
- const routeGetter = globalRouter.routeGetter;
1240
- const rawHref = globalRouter["resolvePath"](to);
1288
+ const routeGetter = _routerRef.current.routeGetter;
1289
+ const rawHref = _routerRef.current["resolvePath"](to);
1241
1290
  const href = isSafeNavigationTarget(rawHref) ? rawHref : "#";
1242
1291
  const hrefPath = href.split("?")[0].split("#")[0];
1243
1292
  const link = document.createElement("a");
@@ -1252,7 +1301,7 @@ function RouterLink(props) {
1252
1301
  } else if (rel) {
1253
1302
  link.rel = rel;
1254
1303
  }
1255
- const options = globalRouter["options"];
1304
+ const options = _routerRef.current["options"];
1256
1305
  const effectCleanup = effect(() => {
1257
1306
  const route2 = routeGetter();
1258
1307
  const isActive = route2.path.startsWith(hrefPath);
@@ -1284,12 +1333,12 @@ function RouterLink(props) {
1284
1333
  }
1285
1334
  }
1286
1335
  });
1287
- if (typeof nodes === "string") {
1288
- link.textContent = nodes;
1289
- } else if (nodes instanceof Node) {
1290
- link.appendChild(nodes);
1291
- } else if (Array.isArray(nodes)) {
1292
- nodes.forEach((child) => {
1336
+ if (typeof content === "string") {
1337
+ link.textContent = content;
1338
+ } else if (content instanceof Node) {
1339
+ link.appendChild(content);
1340
+ } else if (Array.isArray(content)) {
1341
+ content.forEach((child) => {
1293
1342
  if (typeof child === "string") {
1294
1343
  link.appendChild(document.createTextNode(child));
1295
1344
  } else if (child instanceof Node) {
@@ -1302,7 +1351,7 @@ function RouterLink(props) {
1302
1351
  return;
1303
1352
  }
1304
1353
  e.preventDefault();
1305
- globalRouter?.navigate(to, { replace: replace2 }).catch((err) => {
1354
+ _routerRef.current?.navigate(to, { replace: replace2 }).catch((err) => {
1306
1355
  if (typeof console !== "undefined") console.error("[router] link navigate failed:", err);
1307
1356
  });
1308
1357
  };
@@ -1388,35 +1437,35 @@ function lazy(importFn) {
1388
1437
  return importFn;
1389
1438
  }
1390
1439
  async function preloadRoute(to) {
1391
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1392
- const path = globalRouter["resolvePath"](to);
1393
- const match = globalRouter["matcher"].match(path.split("?")[0].split("#")[0]);
1440
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1441
+ const path = _routerRef.current["resolvePath"](to);
1442
+ const match = _routerRef.current["matcher"].match(path.split("?")[0].split("#")[0]);
1394
1443
  if (match && "component" in match.route) {
1395
1444
  try {
1396
- await globalRouter.loadComponent(match.route, path);
1445
+ await _routerRef.current.loadComponent(match.route, path);
1397
1446
  } catch (error) {
1398
1447
  console.warn("[Router] Preload failed:", error);
1399
1448
  }
1400
1449
  }
1401
1450
  }
1402
1451
  function hasRoute(name) {
1403
- if (!globalRouter) return false;
1404
- return globalRouter["matcher"].findByName(name) !== null;
1452
+ if (!_routerRef.current) return false;
1453
+ return _routerRef.current["matcher"].findByName(name) !== null;
1405
1454
  }
1406
1455
  function getRouteInfo(name) {
1407
- if (!globalRouter) return null;
1408
- return globalRouter["matcher"].findByName(name);
1456
+ if (!_routerRef.current) return null;
1457
+ return _routerRef.current["matcher"].findByName(name);
1409
1458
  }
1410
1459
  function buildURL(to) {
1411
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1412
- return globalRouter["resolvePath"](to);
1460
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1461
+ return _routerRef.current["resolvePath"](to);
1413
1462
  }
1414
1463
  function destroyRouter() {
1415
1464
  for (const fn of routeCleanups) fn();
1416
1465
  routeCleanups.length = 0;
1417
- if (globalRouter) {
1418
- globalRouter.destroy();
1419
- globalRouter = null;
1466
+ if (_routerRef.current) {
1467
+ _routerRef.current.destroy();
1468
+ _routerRef.current = null;
1420
1469
  }
1421
1470
  }
1422
1471
  var _routerPagehideHandler = null;
@@ -1449,9 +1498,9 @@ function Outlet() {
1449
1498
  currentChild = null;
1450
1499
  };
1451
1500
  const update = async () => {
1452
- if (!globalRouter) return;
1501
+ if (!_routerRef.current) return;
1453
1502
  const seq = ++navSeq;
1454
- const route2 = globalRouter.currentRoute;
1503
+ const route2 = _routerRef.current.currentRoute;
1455
1504
  if (route2.matched.length < 2) {
1456
1505
  clearCurrent();
1457
1506
  return;
@@ -1464,7 +1513,7 @@ function Outlet() {
1464
1513
  if (childRoute === currentChild && currentNode) return;
1465
1514
  try {
1466
1515
  const cacheKey = `${route2.path}\0${childRoute.path}`;
1467
- const component = await globalRouter.loadComponent(childRoute, cacheKey);
1516
+ const component = await _routerRef.current.loadComponent(childRoute, cacheKey);
1468
1517
  if (seq !== navSeq) return;
1469
1518
  const node = component();
1470
1519
  if (node && anchor.parentNode) {
@@ -1484,27 +1533,32 @@ function Outlet() {
1484
1533
  if (anchor.parentNode) update();
1485
1534
  });
1486
1535
  }
1487
- routeCleanups.push(() => {
1536
+ let outletTorn = false;
1537
+ const outletCleanup = () => {
1538
+ if (outletTorn) return;
1539
+ outletTorn = true;
1488
1540
  outletTeardown();
1489
1541
  if (currentNode) {
1490
1542
  dispose(currentNode);
1491
1543
  if (currentNode.parentNode) currentNode.parentNode.removeChild(currentNode);
1492
1544
  currentNode = null;
1493
1545
  }
1494
- });
1546
+ };
1547
+ registerDisposer(anchor, outletCleanup);
1548
+ routeCleanups.push(outletCleanup);
1495
1549
  return anchor;
1496
1550
  }
1497
1551
  function addRoute(route2, parentPath) {
1498
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1499
- globalRouter.addRoute(route2, parentPath);
1552
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1553
+ _routerRef.current.addRoute(route2, parentPath);
1500
1554
  }
1501
1555
  function removeRoute(path) {
1502
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1503
- globalRouter.removeRoute(path);
1556
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1557
+ _routerRef.current.removeRoute(path);
1504
1558
  }
1505
1559
  function routerState() {
1506
- if (!globalRouter) throw new Error("Router not initialized. Call createRouter() first.");
1507
- const router2 = globalRouter;
1560
+ if (!_routerRef.current) throw new Error("Router not initialized. Call createRouter() first.");
1561
+ const router2 = _routerRef.current;
1508
1562
  return {
1509
1563
  currentPath: () => router2.currentRoute.path,
1510
1564
  params: () => router2.currentRoute.params,
@@ -1518,12 +1572,12 @@ function routerState() {
1518
1572
  var routerPlugins = [];
1519
1573
  function routerPlugin(plugin2) {
1520
1574
  routerPlugins.push(plugin2);
1521
- if (globalRouter?.isReady && plugin2.onReady) {
1575
+ if (_routerRef.current?.isReady && plugin2.onReady) {
1522
1576
  plugin2.onReady();
1523
1577
  }
1524
1578
  let removeGuard = null;
1525
- if (globalRouter && plugin2.onNavigate) {
1526
- removeGuard = globalRouter.afterEach((to, from) => {
1579
+ if (_routerRef.current && plugin2.onNavigate) {
1580
+ removeGuard = _routerRef.current.afterEach((to, from) => {
1527
1581
  plugin2.onNavigate?.(to, from);
1528
1582
  });
1529
1583
  }
@@ -1800,7 +1854,7 @@ function hydrateRouter(routes, options) {
1800
1854
  if (container && serverState.path) {
1801
1855
  const resolved = resolveServerRoute(serverState.path, routes);
1802
1856
  if (resolved.component) {
1803
- import("./ssr-6D67RAVB.js").then(({ hydrate }) => {
1857
+ import("./ssr-2PPULEK2.js").then(({ hydrate }) => {
1804
1858
  if (resolved.component) {
1805
1859
  hydrate(resolved.component, container);
1806
1860
  }
@@ -17,9 +17,9 @@ import {
17
17
  ssrSuspense,
18
18
  suspenseSwapScript,
19
19
  trustHTML
20
- } from "./chunk-R3QEDXFS.js";
20
+ } from "./chunk-EX77FXTT.js";
21
21
  import "./chunk-L3GAGWCC.js";
22
- import "./chunk-GOJMFRBL.js";
22
+ import "./chunk-S3NFJO6L.js";
23
23
  import "./chunk-COY6PUD2.js";
24
24
  export {
25
25
  collectStream,