@fluixi/core 1.0.0-alpha.93 → 1.0.0-alpha.95

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 (54) hide show
  1. package/LICENSE +1 -1
  2. package/dist/cdn/core.global.js +2 -2
  3. package/dist/src/cdn/{chunk-7XM7Q5VR.mjs → chunk-IFONZJWJ.mjs} +93 -2
  4. package/dist/src/cdn/core.cjs +99 -3
  5. package/dist/src/cdn/core.mjs +3 -3
  6. package/dist/src/cdn/{router-VOY43YNM.mjs → router-TU5CPI54.mjs} +1 -1
  7. package/dist/src/index.cjs +96 -4
  8. package/dist/src/index.mjs +97 -5
  9. package/dist/src/lib/client/{chunk-QT3RFKH6.mjs → chunk-AHNP3IWU.mjs} +1 -1
  10. package/dist/src/lib/client/index.cjs +100 -4
  11. package/dist/src/lib/client/index.mjs +4 -4
  12. package/dist/src/lib/client/{router-ADTS55OP.mjs → router-5C6FQJQ4.mjs} +95 -4
  13. package/dist/src/lib/core.cjs +95 -3
  14. package/dist/src/lib/core.d.ts +2 -2
  15. package/dist/src/lib/core.d.ts.map +1 -1
  16. package/dist/src/lib/core.js +1 -1
  17. package/dist/src/lib/core.mjs +96 -4
  18. package/dist/src/lib/i18n/index.cjs +1 -1
  19. package/dist/src/lib/i18n/index.mjs +1 -1
  20. package/dist/src/lib/index.cjs +1 -1
  21. package/dist/src/lib/index.mjs +1 -1
  22. package/dist/src/lib/jsx-runtime/index.cjs +1 -1
  23. package/dist/src/lib/jsx-runtime/index.mjs +1 -1
  24. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -1
  25. package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -1
  26. package/dist/src/lib/plugins/index.cjs +1 -1
  27. package/dist/src/lib/plugins/index.mjs +1 -1
  28. package/dist/src/lib/render/index.cjs +1 -1
  29. package/dist/src/lib/render/index.mjs +1 -1
  30. package/dist/src/lib/render/versions.cjs +1 -1
  31. package/dist/src/lib/render/versions.mjs +1 -1
  32. package/dist/src/lib/router/index.cjs +94 -3
  33. package/dist/src/lib/router/index.d.ts.map +1 -1
  34. package/dist/src/lib/router/index.js +55 -0
  35. package/dist/src/lib/router/index.mjs +94 -3
  36. package/dist/src/lib/router/scroll.cjs +79 -0
  37. package/dist/src/lib/router/scroll.d.ts +19 -0
  38. package/dist/src/lib/router/scroll.d.ts.map +1 -0
  39. package/dist/src/lib/router/scroll.js +68 -0
  40. package/dist/src/lib/router/scroll.mjs +58 -0
  41. package/dist/src/lib/server/index.cjs +1 -1
  42. package/dist/src/lib/server/index.mjs +1 -1
  43. package/dist/src/lib/storage/index.cjs +1 -1
  44. package/dist/src/lib/storage/index.mjs +1 -1
  45. package/dist/src/routes.cjs +1 -1
  46. package/dist/src/routes.mjs +1 -1
  47. package/dist/src/utils.cjs +1 -1
  48. package/dist/src/utils.mjs +1 -1
  49. package/dist/src/version.generated.cjs +1 -1
  50. package/dist/src/version.generated.d.ts +1 -1
  51. package/dist/src/version.generated.js +1 -1
  52. package/dist/src/version.generated.mjs +1 -1
  53. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  54. package/package.json +16 -16
@@ -1,7 +1,7 @@
1
- /*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/core v1.0.0-alpha.95 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/version.generated.ts
4
- var VERSION = "1.0.0-alpha.93";
4
+ var VERSION = "1.0.0-alpha.95";
5
5
 
6
6
  // src/lib/core.ts
7
7
  import {
@@ -1126,6 +1126,64 @@ import {
1126
1126
  import { createContext as createContext5, useContext as useContext5 } from "@fluixi/reactive/signal";
1127
1127
  import { get } from "@fluixi/utils/object";
1128
1128
  import { deepEqual } from "@fluixi/utils/compare";
1129
+
1130
+ // src/lib/router/scroll.ts
1131
+ var STORE = "fx:scroll";
1132
+ var KEEP = 100;
1133
+ function keepScroll(initial) {
1134
+ const read3 = () => {
1135
+ try {
1136
+ return JSON.parse(sessionStorage.getItem(STORE) ?? "{}");
1137
+ } catch {
1138
+ return {};
1139
+ }
1140
+ };
1141
+ const positions = read3();
1142
+ const write = () => {
1143
+ const keys = Object.keys(positions);
1144
+ for (const key of keys.slice(0, Math.max(0, keys.length - KEEP))) delete positions[key];
1145
+ try {
1146
+ sessionStorage.setItem(STORE, JSON.stringify(positions));
1147
+ } catch {
1148
+ }
1149
+ };
1150
+ let current = initial.key;
1151
+ const save = () => {
1152
+ if (current === void 0) return;
1153
+ delete positions[current];
1154
+ positions[current] = window.scrollY;
1155
+ write();
1156
+ };
1157
+ const restoration = history.scrollRestoration;
1158
+ history.scrollRestoration = "manual";
1159
+ window.addEventListener("pagehide", save);
1160
+ const to = (top) => window.scrollTo({ top, left: 0, behavior: "instant" });
1161
+ const toHash = (hash) => {
1162
+ if (!hash || hash === "#") return false;
1163
+ const target = document.getElementById(decodeURIComponent(hash.slice(1)));
1164
+ target?.scrollIntoView({ behavior: "instant" });
1165
+ return target !== null;
1166
+ };
1167
+ return {
1168
+ leave: save,
1169
+ arrive(location, from) {
1170
+ current = location.key;
1171
+ if (location.action === "pop" || from === void 0) {
1172
+ const y = location.key === void 0 ? void 0 : positions[location.key];
1173
+ if (y !== void 0) to(y);
1174
+ return;
1175
+ }
1176
+ if (location.action === "replace" && location.pathname === from.pathname) return;
1177
+ if (!toHash(location.hash)) to(0);
1178
+ },
1179
+ dispose() {
1180
+ window.removeEventListener("pagehide", save);
1181
+ history.scrollRestoration = restoration;
1182
+ }
1183
+ };
1184
+ }
1185
+
1186
+ // src/lib/router/index.ts
1129
1187
  import {
1130
1188
  createRouter as createCoreRouter,
1131
1189
  createBrowserHistory,
@@ -1218,9 +1276,20 @@ function renderLayer(m, depth, base) {
1218
1276
  return router ? router.trackLoad(result) : result;
1219
1277
  });
1220
1278
  onCleanup4(onRevalidate(() => void refetch()));
1279
+ let loadedFor = untrack4(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
1280
+ createEffect4(() => {
1281
+ const now = base.matched()[depth];
1282
+ if (now?.route !== m.route) return;
1283
+ const params = JSON.stringify(now.params ?? {});
1284
+ if (params === loadedFor) return;
1285
+ loadedFor = params;
1286
+ untrack4(() => void refetch());
1287
+ });
1221
1288
  data = () => {
1222
1289
  const error = resource2.error;
1223
1290
  if (error !== void 0 && error !== null) throw error;
1291
+ const r = resource2;
1292
+ if (r.state === "refreshing") return r.latest;
1224
1293
  return resource2();
1225
1294
  };
1226
1295
  Object.defineProperty(data, "loading", { get: () => resource2.loading });
@@ -1325,16 +1394,19 @@ function buildDefaultNotFound() {
1325
1394
  }
1326
1395
  var pendingTransitionMode;
1327
1396
  function Router(props) {
1328
- const history = props.history ?? createBrowserHistory();
1397
+ const history2 = props.history ?? createBrowserHistory();
1329
1398
  const router = createCoreRouter({
1330
1399
  routes: props.routes,
1331
1400
  base: props.base,
1332
- history
1401
+ history: history2
1333
1402
  });
1334
1403
  const [state, setState] = createSignal8(router.state());
1335
1404
  const [navigating, setNavigating] = createSignal8(false);
1336
1405
  const [loads, setLoads] = createSignal8(0);
1337
1406
  let navigationId = 0;
1407
+ const scroll = history2.window ? keepScroll(router.state().location) : void 0;
1408
+ let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
1409
+ const [arrived, setArrived] = createSignal8(0);
1338
1410
  const takeMode = () => {
1339
1411
  const mode = pendingTransitionMode ?? (props.transition ?? "auto");
1340
1412
  pendingTransitionMode = void 0;
@@ -1344,6 +1416,10 @@ function Router(props) {
1344
1416
  const id = ++navigationId;
1345
1417
  const mode = takeMode();
1346
1418
  setNavigating(true);
1419
+ if (scroll) {
1420
+ scroll.leave();
1421
+ arriving = { id, location: next.location, from: untrack4(state).location };
1422
+ }
1347
1423
  const prepared = prepareComponents(
1348
1424
  (next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
1349
1425
  );
@@ -1351,6 +1427,7 @@ function Router(props) {
1351
1427
  setState(next);
1352
1428
  const flushed = flush();
1353
1429
  if (id === navigationId) setNavigating(false);
1430
+ if (scroll) setArrived(id);
1354
1431
  return flushed;
1355
1432
  };
1356
1433
  if (!prepared) {
@@ -1364,6 +1441,7 @@ function Router(props) {
1364
1441
  });
1365
1442
  onCleanup4(() => {
1366
1443
  unsub();
1444
+ scroll?.dispose();
1367
1445
  router.destroy();
1368
1446
  navigationId++;
1369
1447
  });
@@ -1386,6 +1464,19 @@ function Router(props) {
1386
1464
  return result;
1387
1465
  }
1388
1466
  };
1467
+ if (scroll) {
1468
+ const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
1469
+ createEffect4(() => {
1470
+ const id = arrived();
1471
+ if (ctx.isRouting()) return;
1472
+ const next = arriving;
1473
+ if (!next || next.id !== id || id !== navigationId) return;
1474
+ arriving = null;
1475
+ nextFrame(() => {
1476
+ if (id === navigationId) scroll.arrive(next.location, next.from);
1477
+ });
1478
+ });
1479
+ }
1389
1480
  const root = {
1390
1481
  depth: -1,
1391
1482
  matched,
@@ -1499,7 +1590,7 @@ function Link(props) {
1499
1590
  }
1500
1591
 
1501
1592
  // src/lib/core.ts
1502
- import { html, svg } from "@fluixi/dom";
1593
+ import { html, svg, css } from "@fluixi/dom";
1503
1594
  import {
1504
1595
  query,
1505
1596
  queryAll,
@@ -1647,6 +1738,7 @@ export {
1647
1738
  createSignal9 as createSignal,
1648
1739
  createStore,
1649
1740
  createTheme,
1741
+ css,
1650
1742
  core_default as default,
1651
1743
  deferred,
1652
1744
  delegate,
@@ -1,4 +1,4 @@
1
- /*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/core v1.0.0-alpha.95 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
 
3
3
  // src/lib/render/lazy.ts
4
4
  import { createComponent } from "@fluixi/dom";
@@ -1,4 +1,4 @@
1
- /*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/core v1.0.0-alpha.95 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  "use strict";
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -124,6 +124,68 @@ var init_transition = __esm({
124
124
  }
125
125
  });
126
126
 
127
+ // src/lib/router/scroll.ts
128
+ function keepScroll(initial) {
129
+ const read2 = () => {
130
+ try {
131
+ return JSON.parse(sessionStorage.getItem(STORE) ?? "{}");
132
+ } catch {
133
+ return {};
134
+ }
135
+ };
136
+ const positions = read2();
137
+ const write = () => {
138
+ const keys = Object.keys(positions);
139
+ for (const key of keys.slice(0, Math.max(0, keys.length - KEEP))) delete positions[key];
140
+ try {
141
+ sessionStorage.setItem(STORE, JSON.stringify(positions));
142
+ } catch {
143
+ }
144
+ };
145
+ let current = initial.key;
146
+ const save = () => {
147
+ if (current === void 0) return;
148
+ delete positions[current];
149
+ positions[current] = window.scrollY;
150
+ write();
151
+ };
152
+ const restoration = history.scrollRestoration;
153
+ history.scrollRestoration = "manual";
154
+ window.addEventListener("pagehide", save);
155
+ const to = (top) => window.scrollTo({ top, left: 0, behavior: "instant" });
156
+ const toHash = (hash) => {
157
+ if (!hash || hash === "#") return false;
158
+ const target = document.getElementById(decodeURIComponent(hash.slice(1)));
159
+ target?.scrollIntoView({ behavior: "instant" });
160
+ return target !== null;
161
+ };
162
+ return {
163
+ leave: save,
164
+ arrive(location, from) {
165
+ current = location.key;
166
+ if (location.action === "pop" || from === void 0) {
167
+ const y = location.key === void 0 ? void 0 : positions[location.key];
168
+ if (y !== void 0) to(y);
169
+ return;
170
+ }
171
+ if (location.action === "replace" && location.pathname === from.pathname) return;
172
+ if (!toHash(location.hash)) to(0);
173
+ },
174
+ dispose() {
175
+ window.removeEventListener("pagehide", save);
176
+ history.scrollRestoration = restoration;
177
+ }
178
+ };
179
+ }
180
+ var STORE, KEEP;
181
+ var init_scroll = __esm({
182
+ "src/lib/router/scroll.ts"() {
183
+ "use strict";
184
+ STORE = "fx:scroll";
185
+ KEEP = 100;
186
+ }
187
+ });
188
+
127
189
  // src/lib/context/context.ts
128
190
  function createContext3(defaultValue, name) {
129
191
  const context = (0, import_signal7.createContext)(defaultValue, name);
@@ -389,9 +451,20 @@ function renderLayer(m, depth, base) {
389
451
  return router ? router.trackLoad(result) : result;
390
452
  });
391
453
  (0, import_signal10.onCleanup)(onRevalidate(() => void refetch()));
454
+ let loadedFor = (0, import_signal10.untrack)(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
455
+ (0, import_signal10.createEffect)(() => {
456
+ const now = base.matched()[depth];
457
+ if (now?.route !== m.route) return;
458
+ const params = JSON.stringify(now.params ?? {});
459
+ if (params === loadedFor) return;
460
+ loadedFor = params;
461
+ (0, import_signal10.untrack)(() => void refetch());
462
+ });
392
463
  data = () => {
393
464
  const error = resource.error;
394
465
  if (error !== void 0 && error !== null) throw error;
466
+ const r = resource;
467
+ if (r.state === "refreshing") return r.latest;
395
468
  return resource();
396
469
  };
397
470
  Object.defineProperty(data, "loading", { get: () => resource.loading });
@@ -495,16 +568,19 @@ function buildDefaultNotFound() {
495
568
  return el;
496
569
  }
497
570
  function Router(props) {
498
- const history = props.history ?? (0, import_router.createBrowserHistory)();
571
+ const history2 = props.history ?? (0, import_router.createBrowserHistory)();
499
572
  const router = (0, import_router.createRouter)({
500
573
  routes: props.routes,
501
574
  base: props.base,
502
- history
575
+ history: history2
503
576
  });
504
577
  const [state, setState] = (0, import_signal10.createSignal)(router.state());
505
578
  const [navigating, setNavigating] = (0, import_signal10.createSignal)(false);
506
579
  const [loads, setLoads] = (0, import_signal10.createSignal)(0);
507
580
  let navigationId = 0;
581
+ const scroll = history2.window ? keepScroll(router.state().location) : void 0;
582
+ let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
583
+ const [arrived, setArrived] = (0, import_signal10.createSignal)(0);
508
584
  const takeMode = () => {
509
585
  const mode = pendingTransitionMode ?? (props.transition ?? "auto");
510
586
  pendingTransitionMode = void 0;
@@ -514,6 +590,10 @@ function Router(props) {
514
590
  const id = ++navigationId;
515
591
  const mode = takeMode();
516
592
  setNavigating(true);
593
+ if (scroll) {
594
+ scroll.leave();
595
+ arriving = { id, location: next.location, from: (0, import_signal10.untrack)(state).location };
596
+ }
517
597
  const prepared = prepareComponents(
518
598
  (next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
519
599
  );
@@ -521,6 +601,7 @@ function Router(props) {
521
601
  setState(next);
522
602
  const flushed = (0, import_signal10.flush)();
523
603
  if (id === navigationId) setNavigating(false);
604
+ if (scroll) setArrived(id);
524
605
  return flushed;
525
606
  };
526
607
  if (!prepared) {
@@ -534,6 +615,7 @@ function Router(props) {
534
615
  });
535
616
  (0, import_signal10.onCleanup)(() => {
536
617
  unsub();
618
+ scroll?.dispose();
537
619
  router.destroy();
538
620
  navigationId++;
539
621
  });
@@ -556,6 +638,19 @@ function Router(props) {
556
638
  return result;
557
639
  }
558
640
  };
641
+ if (scroll) {
642
+ const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
643
+ (0, import_signal10.createEffect)(() => {
644
+ const id = arrived();
645
+ if (ctx.isRouting()) return;
646
+ const next = arriving;
647
+ if (!next || next.id !== id || id !== navigationId) return;
648
+ arriving = null;
649
+ nextFrame(() => {
650
+ if (id === navigationId) scroll.arrive(next.location, next.from);
651
+ });
652
+ });
653
+ }
559
654
  const root = {
560
655
  depth: -1,
561
656
  matched,
@@ -799,6 +894,7 @@ var init_router = __esm({
799
894
  import_signal11 = require("@fluixi/reactive/signal");
800
895
  import_object = require("@fluixi/utils/object");
801
896
  import_compare = require("@fluixi/utils/compare");
897
+ init_scroll();
802
898
  import_router = require("@fluixi/router");
803
899
  init_data();
804
900
  import_router2 = require("@fluixi/router");
@@ -847,7 +943,7 @@ var import_dom13 = require("@fluixi/dom");
847
943
  var import_dom = require("@fluixi/dom");
848
944
 
849
945
  // src/version.generated.ts
850
- var VERSION = "1.0.0-alpha.93";
946
+ var VERSION = "1.0.0-alpha.95";
851
947
 
852
948
  // src/lib/render/versions.ts
853
949
  var import_dom2 = require("@fluixi/dom");
@@ -1,5 +1,5 @@
1
- /*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
- import "./chunk-QT3RFKH6.mjs";
1
+ /*! @fluixi/core v1.0.0-alpha.95 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
+ import "./chunk-AHNP3IWU.mjs";
3
3
 
4
4
  // src/lib/client/index.ts
5
5
  import {
@@ -15,7 +15,7 @@ import {
15
15
  import { registerCoreVersion } from "@fluixi/dom";
16
16
 
17
17
  // src/version.generated.ts
18
- var VERSION = "1.0.0-alpha.93";
18
+ var VERSION = "1.0.0-alpha.95";
19
19
 
20
20
  // src/lib/render/versions.ts
21
21
  import { stampVersions, warnOnVersionSkew, versions } from "@fluixi/dom";
@@ -246,7 +246,7 @@ async function startClient(App, options = {}) {
246
246
  beginAppHydration();
247
247
  try {
248
248
  if (options.routes && options.routes.length) {
249
- const { preloadRoutes } = await import("./router-ADTS55OP.mjs");
249
+ const { preloadRoutes } = await import("./router-5C6FQJQ4.mjs");
250
250
  await preloadRoutes(options.routes, window.location.pathname);
251
251
  }
252
252
  deserializeHydrationData();
@@ -1,7 +1,7 @@
1
- /*! @fluixi/core v1.0.0-alpha.93 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
1
+ /*! @fluixi/core v1.0.0-alpha.95 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
2
2
  import {
3
3
  lazy
4
- } from "./chunk-QT3RFKH6.mjs";
4
+ } from "./chunk-AHNP3IWU.mjs";
5
5
 
6
6
  // src/lib/router/index.ts
7
7
  import {
@@ -75,6 +75,64 @@ import {
75
75
  import { createContext as createContext2, useContext as useContext2 } from "@fluixi/reactive/signal";
76
76
  import { get } from "@fluixi/utils/object";
77
77
  import { deepEqual } from "@fluixi/utils/compare";
78
+
79
+ // src/lib/router/scroll.ts
80
+ var STORE = "fx:scroll";
81
+ var KEEP = 100;
82
+ function keepScroll(initial) {
83
+ const read2 = () => {
84
+ try {
85
+ return JSON.parse(sessionStorage.getItem(STORE) ?? "{}");
86
+ } catch {
87
+ return {};
88
+ }
89
+ };
90
+ const positions = read2();
91
+ const write = () => {
92
+ const keys = Object.keys(positions);
93
+ for (const key of keys.slice(0, Math.max(0, keys.length - KEEP))) delete positions[key];
94
+ try {
95
+ sessionStorage.setItem(STORE, JSON.stringify(positions));
96
+ } catch {
97
+ }
98
+ };
99
+ let current = initial.key;
100
+ const save = () => {
101
+ if (current === void 0) return;
102
+ delete positions[current];
103
+ positions[current] = window.scrollY;
104
+ write();
105
+ };
106
+ const restoration = history.scrollRestoration;
107
+ history.scrollRestoration = "manual";
108
+ window.addEventListener("pagehide", save);
109
+ const to = (top) => window.scrollTo({ top, left: 0, behavior: "instant" });
110
+ const toHash = (hash) => {
111
+ if (!hash || hash === "#") return false;
112
+ const target = document.getElementById(decodeURIComponent(hash.slice(1)));
113
+ target?.scrollIntoView({ behavior: "instant" });
114
+ return target !== null;
115
+ };
116
+ return {
117
+ leave: save,
118
+ arrive(location, from) {
119
+ current = location.key;
120
+ if (location.action === "pop" || from === void 0) {
121
+ const y = location.key === void 0 ? void 0 : positions[location.key];
122
+ if (y !== void 0) to(y);
123
+ return;
124
+ }
125
+ if (location.action === "replace" && location.pathname === from.pathname) return;
126
+ if (!toHash(location.hash)) to(0);
127
+ },
128
+ dispose() {
129
+ window.removeEventListener("pagehide", save);
130
+ history.scrollRestoration = restoration;
131
+ }
132
+ };
133
+ }
134
+
135
+ // src/lib/router/index.ts
78
136
  import {
79
137
  createRouter as createCoreRouter,
80
138
  createBrowserHistory,
@@ -316,9 +374,20 @@ function renderLayer(m, depth, base) {
316
374
  return router ? router.trackLoad(result) : result;
317
375
  });
318
376
  onCleanup(onRevalidate(() => void refetch()));
377
+ let loadedFor = untrack(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
378
+ createEffect(() => {
379
+ const now = base.matched()[depth];
380
+ if (now?.route !== m.route) return;
381
+ const params = JSON.stringify(now.params ?? {});
382
+ if (params === loadedFor) return;
383
+ loadedFor = params;
384
+ untrack(() => void refetch());
385
+ });
319
386
  data = () => {
320
387
  const error = resource.error;
321
388
  if (error !== void 0 && error !== null) throw error;
389
+ const r = resource;
390
+ if (r.state === "refreshing") return r.latest;
322
391
  return resource();
323
392
  };
324
393
  Object.defineProperty(data, "loading", { get: () => resource.loading });
@@ -423,16 +492,19 @@ function buildDefaultNotFound() {
423
492
  }
424
493
  var pendingTransitionMode;
425
494
  function Router(props) {
426
- const history = props.history ?? createBrowserHistory();
495
+ const history2 = props.history ?? createBrowserHistory();
427
496
  const router = createCoreRouter({
428
497
  routes: props.routes,
429
498
  base: props.base,
430
- history
499
+ history: history2
431
500
  });
432
501
  const [state, setState] = createSignal2(router.state());
433
502
  const [navigating, setNavigating] = createSignal2(false);
434
503
  const [loads, setLoads] = createSignal2(0);
435
504
  let navigationId = 0;
505
+ const scroll = history2.window ? keepScroll(router.state().location) : void 0;
506
+ let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
507
+ const [arrived, setArrived] = createSignal2(0);
436
508
  const takeMode = () => {
437
509
  const mode = pendingTransitionMode ?? (props.transition ?? "auto");
438
510
  pendingTransitionMode = void 0;
@@ -442,6 +514,10 @@ function Router(props) {
442
514
  const id = ++navigationId;
443
515
  const mode = takeMode();
444
516
  setNavigating(true);
517
+ if (scroll) {
518
+ scroll.leave();
519
+ arriving = { id, location: next.location, from: untrack(state).location };
520
+ }
445
521
  const prepared = prepareComponents(
446
522
  (next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
447
523
  );
@@ -449,6 +525,7 @@ function Router(props) {
449
525
  setState(next);
450
526
  const flushed = flush();
451
527
  if (id === navigationId) setNavigating(false);
528
+ if (scroll) setArrived(id);
452
529
  return flushed;
453
530
  };
454
531
  if (!prepared) {
@@ -462,6 +539,7 @@ function Router(props) {
462
539
  });
463
540
  onCleanup(() => {
464
541
  unsub();
542
+ scroll?.dispose();
465
543
  router.destroy();
466
544
  navigationId++;
467
545
  });
@@ -484,6 +562,19 @@ function Router(props) {
484
562
  return result;
485
563
  }
486
564
  };
565
+ if (scroll) {
566
+ const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
567
+ createEffect(() => {
568
+ const id = arrived();
569
+ if (ctx.isRouting()) return;
570
+ const next = arriving;
571
+ if (!next || next.id !== id || id !== navigationId) return;
572
+ arriving = null;
573
+ nextFrame(() => {
574
+ if (id === navigationId) scroll.arrive(next.location, next.from);
575
+ });
576
+ });
577
+ }
487
578
  const root = {
488
579
  depth: -1,
489
580
  matched,