@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.
- package/LICENSE +1 -1
- package/dist/cdn/core.global.js +2 -2
- package/dist/src/cdn/{chunk-7XM7Q5VR.mjs → chunk-IFONZJWJ.mjs} +93 -2
- package/dist/src/cdn/core.cjs +99 -3
- package/dist/src/cdn/core.mjs +3 -3
- package/dist/src/cdn/{router-VOY43YNM.mjs → router-TU5CPI54.mjs} +1 -1
- package/dist/src/index.cjs +96 -4
- package/dist/src/index.mjs +97 -5
- package/dist/src/lib/client/{chunk-QT3RFKH6.mjs → chunk-AHNP3IWU.mjs} +1 -1
- package/dist/src/lib/client/index.cjs +100 -4
- package/dist/src/lib/client/index.mjs +4 -4
- package/dist/src/lib/client/{router-ADTS55OP.mjs → router-5C6FQJQ4.mjs} +95 -4
- package/dist/src/lib/core.cjs +95 -3
- package/dist/src/lib/core.d.ts +2 -2
- package/dist/src/lib/core.d.ts.map +1 -1
- package/dist/src/lib/core.js +1 -1
- package/dist/src/lib/core.mjs +96 -4
- package/dist/src/lib/i18n/index.cjs +1 -1
- package/dist/src/lib/i18n/index.mjs +1 -1
- package/dist/src/lib/index.cjs +1 -1
- package/dist/src/lib/index.mjs +1 -1
- package/dist/src/lib/jsx-runtime/index.cjs +1 -1
- package/dist/src/lib/jsx-runtime/index.mjs +1 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.cjs +1 -1
- package/dist/src/lib/jsx-runtime/jsx-dev-runtime.mjs +1 -1
- package/dist/src/lib/plugins/index.cjs +1 -1
- package/dist/src/lib/plugins/index.mjs +1 -1
- package/dist/src/lib/render/index.cjs +1 -1
- package/dist/src/lib/render/index.mjs +1 -1
- package/dist/src/lib/render/versions.cjs +1 -1
- package/dist/src/lib/render/versions.mjs +1 -1
- package/dist/src/lib/router/index.cjs +94 -3
- package/dist/src/lib/router/index.d.ts.map +1 -1
- package/dist/src/lib/router/index.js +55 -0
- package/dist/src/lib/router/index.mjs +94 -3
- package/dist/src/lib/router/scroll.cjs +79 -0
- package/dist/src/lib/router/scroll.d.ts +19 -0
- package/dist/src/lib/router/scroll.d.ts.map +1 -0
- package/dist/src/lib/router/scroll.js +68 -0
- package/dist/src/lib/router/scroll.mjs +58 -0
- package/dist/src/lib/server/index.cjs +1 -1
- package/dist/src/lib/server/index.mjs +1 -1
- package/dist/src/lib/storage/index.cjs +1 -1
- package/dist/src/lib/storage/index.mjs +1 -1
- package/dist/src/routes.cjs +1 -1
- package/dist/src/routes.mjs +1 -1
- package/dist/src/utils.cjs +1 -1
- package/dist/src/utils.mjs +1 -1
- package/dist/src/version.generated.cjs +1 -1
- package/dist/src/version.generated.d.ts +1 -1
- package/dist/src/version.generated.js +1 -1
- package/dist/src/version.generated.mjs +1 -1
- package/dist/tsconfig.lib.tsbuildinfo +1 -1
- package/package.json +16 -16
|
@@ -84,6 +84,64 @@ import {
|
|
|
84
84
|
import { createContext as createContext2, useContext as useContext2 } from "@fluixi/reactive/signal";
|
|
85
85
|
import { get } from "@fluixi/utils/object";
|
|
86
86
|
import { deepEqual } from "@fluixi/utils/compare";
|
|
87
|
+
|
|
88
|
+
// src/lib/router/scroll.ts
|
|
89
|
+
var STORE = "fx:scroll";
|
|
90
|
+
var KEEP = 100;
|
|
91
|
+
function keepScroll(initial) {
|
|
92
|
+
const read2 = () => {
|
|
93
|
+
try {
|
|
94
|
+
return JSON.parse(sessionStorage.getItem(STORE) ?? "{}");
|
|
95
|
+
} catch {
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const positions = read2();
|
|
100
|
+
const write = () => {
|
|
101
|
+
const keys = Object.keys(positions);
|
|
102
|
+
for (const key of keys.slice(0, Math.max(0, keys.length - KEEP))) delete positions[key];
|
|
103
|
+
try {
|
|
104
|
+
sessionStorage.setItem(STORE, JSON.stringify(positions));
|
|
105
|
+
} catch {
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
let current = initial.key;
|
|
109
|
+
const save = () => {
|
|
110
|
+
if (current === void 0) return;
|
|
111
|
+
delete positions[current];
|
|
112
|
+
positions[current] = window.scrollY;
|
|
113
|
+
write();
|
|
114
|
+
};
|
|
115
|
+
const restoration = history.scrollRestoration;
|
|
116
|
+
history.scrollRestoration = "manual";
|
|
117
|
+
window.addEventListener("pagehide", save);
|
|
118
|
+
const to = (top) => window.scrollTo({ top, left: 0, behavior: "instant" });
|
|
119
|
+
const toHash = (hash) => {
|
|
120
|
+
if (!hash || hash === "#") return false;
|
|
121
|
+
const target = document.getElementById(decodeURIComponent(hash.slice(1)));
|
|
122
|
+
target?.scrollIntoView({ behavior: "instant" });
|
|
123
|
+
return target !== null;
|
|
124
|
+
};
|
|
125
|
+
return {
|
|
126
|
+
leave: save,
|
|
127
|
+
arrive(location, from) {
|
|
128
|
+
current = location.key;
|
|
129
|
+
if (location.action === "pop" || from === void 0) {
|
|
130
|
+
const y = location.key === void 0 ? void 0 : positions[location.key];
|
|
131
|
+
if (y !== void 0) to(y);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
if (location.action === "replace" && location.pathname === from.pathname) return;
|
|
135
|
+
if (!toHash(location.hash)) to(0);
|
|
136
|
+
},
|
|
137
|
+
dispose() {
|
|
138
|
+
window.removeEventListener("pagehide", save);
|
|
139
|
+
history.scrollRestoration = restoration;
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// src/lib/router/index.ts
|
|
87
145
|
import {
|
|
88
146
|
createRouter as createCoreRouter,
|
|
89
147
|
createBrowserHistory,
|
|
@@ -405,9 +463,20 @@ function renderLayer(m, depth, base) {
|
|
|
405
463
|
return router ? router.trackLoad(result) : result;
|
|
406
464
|
});
|
|
407
465
|
onCleanup(onRevalidate(() => void refetch()));
|
|
466
|
+
let loadedFor = untrack2(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
|
|
467
|
+
createEffect(() => {
|
|
468
|
+
const now = base.matched()[depth];
|
|
469
|
+
if (now?.route !== m.route) return;
|
|
470
|
+
const params = JSON.stringify(now.params ?? {});
|
|
471
|
+
if (params === loadedFor) return;
|
|
472
|
+
loadedFor = params;
|
|
473
|
+
untrack2(() => void refetch());
|
|
474
|
+
});
|
|
408
475
|
data = () => {
|
|
409
476
|
const error = resource.error;
|
|
410
477
|
if (error !== void 0 && error !== null) throw error;
|
|
478
|
+
const r = resource;
|
|
479
|
+
if (r.state === "refreshing") return r.latest;
|
|
411
480
|
return resource();
|
|
412
481
|
};
|
|
413
482
|
Object.defineProperty(data, "loading", { get: () => resource.loading });
|
|
@@ -512,16 +581,19 @@ function buildDefaultNotFound() {
|
|
|
512
581
|
}
|
|
513
582
|
var pendingTransitionMode;
|
|
514
583
|
function Router(props) {
|
|
515
|
-
const
|
|
584
|
+
const history2 = props.history ?? createBrowserHistory();
|
|
516
585
|
const router = createCoreRouter({
|
|
517
586
|
routes: props.routes,
|
|
518
587
|
base: props.base,
|
|
519
|
-
history
|
|
588
|
+
history: history2
|
|
520
589
|
});
|
|
521
590
|
const [state, setState] = createSignal2(router.state());
|
|
522
591
|
const [navigating, setNavigating] = createSignal2(false);
|
|
523
592
|
const [loads, setLoads] = createSignal2(0);
|
|
524
593
|
let navigationId = 0;
|
|
594
|
+
const scroll = history2.window ? keepScroll(router.state().location) : void 0;
|
|
595
|
+
let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
|
|
596
|
+
const [arrived, setArrived] = createSignal2(0);
|
|
525
597
|
const takeMode = () => {
|
|
526
598
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
527
599
|
pendingTransitionMode = void 0;
|
|
@@ -531,6 +603,10 @@ function Router(props) {
|
|
|
531
603
|
const id = ++navigationId;
|
|
532
604
|
const mode = takeMode();
|
|
533
605
|
setNavigating(true);
|
|
606
|
+
if (scroll) {
|
|
607
|
+
scroll.leave();
|
|
608
|
+
arriving = { id, location: next.location, from: untrack2(state).location };
|
|
609
|
+
}
|
|
534
610
|
const prepared = prepareComponents(
|
|
535
611
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
536
612
|
);
|
|
@@ -538,6 +614,7 @@ function Router(props) {
|
|
|
538
614
|
setState(next);
|
|
539
615
|
const flushed = flush();
|
|
540
616
|
if (id === navigationId) setNavigating(false);
|
|
617
|
+
if (scroll) setArrived(id);
|
|
541
618
|
return flushed;
|
|
542
619
|
};
|
|
543
620
|
if (!prepared) {
|
|
@@ -551,6 +628,7 @@ function Router(props) {
|
|
|
551
628
|
});
|
|
552
629
|
onCleanup(() => {
|
|
553
630
|
unsub();
|
|
631
|
+
scroll?.dispose();
|
|
554
632
|
router.destroy();
|
|
555
633
|
navigationId++;
|
|
556
634
|
});
|
|
@@ -573,6 +651,19 @@ function Router(props) {
|
|
|
573
651
|
return result;
|
|
574
652
|
}
|
|
575
653
|
};
|
|
654
|
+
if (scroll) {
|
|
655
|
+
const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
|
|
656
|
+
createEffect(() => {
|
|
657
|
+
const id = arrived();
|
|
658
|
+
if (ctx.isRouting()) return;
|
|
659
|
+
const next = arriving;
|
|
660
|
+
if (!next || next.id !== id || id !== navigationId) return;
|
|
661
|
+
arriving = null;
|
|
662
|
+
nextFrame(() => {
|
|
663
|
+
if (id === navigationId) scroll.arrive(next.location, next.from);
|
|
664
|
+
});
|
|
665
|
+
});
|
|
666
|
+
}
|
|
576
667
|
const root = {
|
|
577
668
|
depth: -1,
|
|
578
669
|
matched,
|
package/dist/src/cdn/core.cjs
CHANGED
|
@@ -184,6 +184,68 @@ var init_transition = __esm({
|
|
|
184
184
|
}
|
|
185
185
|
});
|
|
186
186
|
|
|
187
|
+
// src/lib/router/scroll.ts
|
|
188
|
+
function keepScroll(initial) {
|
|
189
|
+
const read2 = () => {
|
|
190
|
+
try {
|
|
191
|
+
return JSON.parse(sessionStorage.getItem(STORE) ?? "{}");
|
|
192
|
+
} catch {
|
|
193
|
+
return {};
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
const positions = read2();
|
|
197
|
+
const write = () => {
|
|
198
|
+
const keys = Object.keys(positions);
|
|
199
|
+
for (const key of keys.slice(0, Math.max(0, keys.length - KEEP))) delete positions[key];
|
|
200
|
+
try {
|
|
201
|
+
sessionStorage.setItem(STORE, JSON.stringify(positions));
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
let current = initial.key;
|
|
206
|
+
const save = () => {
|
|
207
|
+
if (current === void 0) return;
|
|
208
|
+
delete positions[current];
|
|
209
|
+
positions[current] = window.scrollY;
|
|
210
|
+
write();
|
|
211
|
+
};
|
|
212
|
+
const restoration = history.scrollRestoration;
|
|
213
|
+
history.scrollRestoration = "manual";
|
|
214
|
+
window.addEventListener("pagehide", save);
|
|
215
|
+
const to = (top) => window.scrollTo({ top, left: 0, behavior: "instant" });
|
|
216
|
+
const toHash = (hash) => {
|
|
217
|
+
if (!hash || hash === "#") return false;
|
|
218
|
+
const target = document.getElementById(decodeURIComponent(hash.slice(1)));
|
|
219
|
+
target?.scrollIntoView({ behavior: "instant" });
|
|
220
|
+
return target !== null;
|
|
221
|
+
};
|
|
222
|
+
return {
|
|
223
|
+
leave: save,
|
|
224
|
+
arrive(location, from) {
|
|
225
|
+
current = location.key;
|
|
226
|
+
if (location.action === "pop" || from === void 0) {
|
|
227
|
+
const y = location.key === void 0 ? void 0 : positions[location.key];
|
|
228
|
+
if (y !== void 0) to(y);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
if (location.action === "replace" && location.pathname === from.pathname) return;
|
|
232
|
+
if (!toHash(location.hash)) to(0);
|
|
233
|
+
},
|
|
234
|
+
dispose() {
|
|
235
|
+
window.removeEventListener("pagehide", save);
|
|
236
|
+
history.scrollRestoration = restoration;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
var STORE, KEEP;
|
|
241
|
+
var init_scroll = __esm({
|
|
242
|
+
"src/lib/router/scroll.ts"() {
|
|
243
|
+
"use strict";
|
|
244
|
+
STORE = "fx:scroll";
|
|
245
|
+
KEEP = 100;
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
187
249
|
// src/lib/router/data.ts
|
|
188
250
|
function onRevalidate(listener) {
|
|
189
251
|
revalidationListeners.add(listener);
|
|
@@ -419,9 +481,20 @@ function renderLayer(m, depth, base) {
|
|
|
419
481
|
return router ? router.trackLoad(result) : result;
|
|
420
482
|
});
|
|
421
483
|
(0, import_signal14.onCleanup)(onRevalidate(() => void refetch()));
|
|
484
|
+
let loadedFor = (0, import_signal14.untrack)(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
|
|
485
|
+
(0, import_signal14.createEffect)(() => {
|
|
486
|
+
const now = base.matched()[depth];
|
|
487
|
+
if (now?.route !== m.route) return;
|
|
488
|
+
const params = JSON.stringify(now.params ?? {});
|
|
489
|
+
if (params === loadedFor) return;
|
|
490
|
+
loadedFor = params;
|
|
491
|
+
(0, import_signal14.untrack)(() => void refetch());
|
|
492
|
+
});
|
|
422
493
|
data = () => {
|
|
423
494
|
const error = resource.error;
|
|
424
495
|
if (error !== void 0 && error !== null) throw error;
|
|
496
|
+
const r = resource;
|
|
497
|
+
if (r.state === "refreshing") return r.latest;
|
|
425
498
|
return resource();
|
|
426
499
|
};
|
|
427
500
|
Object.defineProperty(data, "loading", { get: () => resource.loading });
|
|
@@ -525,16 +598,19 @@ function buildDefaultNotFound() {
|
|
|
525
598
|
return el;
|
|
526
599
|
}
|
|
527
600
|
function Router(props) {
|
|
528
|
-
const
|
|
601
|
+
const history2 = props.history ?? (0, import_router.createBrowserHistory)();
|
|
529
602
|
const router = (0, import_router.createRouter)({
|
|
530
603
|
routes: props.routes,
|
|
531
604
|
base: props.base,
|
|
532
|
-
history
|
|
605
|
+
history: history2
|
|
533
606
|
});
|
|
534
607
|
const [state, setState] = (0, import_signal14.createSignal)(router.state());
|
|
535
608
|
const [navigating, setNavigating] = (0, import_signal14.createSignal)(false);
|
|
536
609
|
const [loads, setLoads] = (0, import_signal14.createSignal)(0);
|
|
537
610
|
let navigationId = 0;
|
|
611
|
+
const scroll = history2.window ? keepScroll(router.state().location) : void 0;
|
|
612
|
+
let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
|
|
613
|
+
const [arrived, setArrived] = (0, import_signal14.createSignal)(0);
|
|
538
614
|
const takeMode = () => {
|
|
539
615
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
540
616
|
pendingTransitionMode = void 0;
|
|
@@ -544,6 +620,10 @@ function Router(props) {
|
|
|
544
620
|
const id = ++navigationId;
|
|
545
621
|
const mode = takeMode();
|
|
546
622
|
setNavigating(true);
|
|
623
|
+
if (scroll) {
|
|
624
|
+
scroll.leave();
|
|
625
|
+
arriving = { id, location: next.location, from: (0, import_signal14.untrack)(state).location };
|
|
626
|
+
}
|
|
547
627
|
const prepared = prepareComponents(
|
|
548
628
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
549
629
|
);
|
|
@@ -551,6 +631,7 @@ function Router(props) {
|
|
|
551
631
|
setState(next);
|
|
552
632
|
const flushed = (0, import_signal14.flush)();
|
|
553
633
|
if (id === navigationId) setNavigating(false);
|
|
634
|
+
if (scroll) setArrived(id);
|
|
554
635
|
return flushed;
|
|
555
636
|
};
|
|
556
637
|
if (!prepared) {
|
|
@@ -564,6 +645,7 @@ function Router(props) {
|
|
|
564
645
|
});
|
|
565
646
|
(0, import_signal14.onCleanup)(() => {
|
|
566
647
|
unsub();
|
|
648
|
+
scroll?.dispose();
|
|
567
649
|
router.destroy();
|
|
568
650
|
navigationId++;
|
|
569
651
|
});
|
|
@@ -586,6 +668,19 @@ function Router(props) {
|
|
|
586
668
|
return result;
|
|
587
669
|
}
|
|
588
670
|
};
|
|
671
|
+
if (scroll) {
|
|
672
|
+
const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
|
|
673
|
+
(0, import_signal14.createEffect)(() => {
|
|
674
|
+
const id = arrived();
|
|
675
|
+
if (ctx.isRouting()) return;
|
|
676
|
+
const next = arriving;
|
|
677
|
+
if (!next || next.id !== id || id !== navigationId) return;
|
|
678
|
+
arriving = null;
|
|
679
|
+
nextFrame(() => {
|
|
680
|
+
if (id === navigationId) scroll.arrive(next.location, next.from);
|
|
681
|
+
});
|
|
682
|
+
});
|
|
683
|
+
}
|
|
589
684
|
const root = {
|
|
590
685
|
depth: -1,
|
|
591
686
|
matched,
|
|
@@ -829,6 +924,7 @@ var init_router = __esm({
|
|
|
829
924
|
import_signal15 = require("@fluixi/reactive/signal");
|
|
830
925
|
import_object = require("@fluixi/utils/object");
|
|
831
926
|
import_compare = require("@fluixi/utils/compare");
|
|
927
|
+
init_scroll();
|
|
832
928
|
import_router = require("@fluixi/router");
|
|
833
929
|
init_data();
|
|
834
930
|
import_router2 = require("@fluixi/router");
|
|
@@ -976,7 +1072,7 @@ var import_signal6 = require("@fluixi/reactive/signal");
|
|
|
976
1072
|
var import_dom = require("@fluixi/dom");
|
|
977
1073
|
|
|
978
1074
|
// src/version.generated.ts
|
|
979
|
-
var VERSION = "1.0.0-alpha.
|
|
1075
|
+
var VERSION = "1.0.0-alpha.95";
|
|
980
1076
|
|
|
981
1077
|
// src/lib/render/versions.ts
|
|
982
1078
|
var import_dom2 = require("@fluixi/dom");
|
package/dist/src/cdn/core.mjs
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
useParams,
|
|
21
21
|
useRouter,
|
|
22
22
|
useSearchParams
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-IFONZJWJ.mjs";
|
|
24
24
|
|
|
25
25
|
// src/lib/index.ts
|
|
26
26
|
import {
|
|
@@ -54,7 +54,7 @@ import { createRoot as createRoot2 } from "@fluixi/reactive/signal";
|
|
|
54
54
|
import { registerCoreVersion } from "@fluixi/dom";
|
|
55
55
|
|
|
56
56
|
// src/version.generated.ts
|
|
57
|
-
var VERSION = "1.0.0-alpha.
|
|
57
|
+
var VERSION = "1.0.0-alpha.95";
|
|
58
58
|
|
|
59
59
|
// src/lib/render/versions.ts
|
|
60
60
|
import { stampVersions, warnOnVersionSkew, versions } from "@fluixi/dom";
|
|
@@ -574,7 +574,7 @@ async function startClient(App, options = {}) {
|
|
|
574
574
|
beginAppHydration();
|
|
575
575
|
try {
|
|
576
576
|
if (options.routes && options.routes.length) {
|
|
577
|
-
const { preloadRoutes } = await import("./router-
|
|
577
|
+
const { preloadRoutes } = await import("./router-TU5CPI54.mjs");
|
|
578
578
|
await preloadRoutes(options.routes, window.location.pathname);
|
|
579
579
|
}
|
|
580
580
|
deserializeHydrationData();
|
package/dist/src/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/core v1.0.0-alpha.
|
|
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;
|
|
@@ -71,6 +71,7 @@ __export(index_exports, {
|
|
|
71
71
|
createSignal: () => import_signal18.createSignal,
|
|
72
72
|
createStore: () => import_store.createStore,
|
|
73
73
|
createTheme: () => createTheme,
|
|
74
|
+
css: () => import_dom17.css,
|
|
74
75
|
default: () => core_default,
|
|
75
76
|
deferred: () => deferred,
|
|
76
77
|
delegate: () => import_dom18.delegate,
|
|
@@ -142,7 +143,7 @@ __export(index_exports, {
|
|
|
142
143
|
module.exports = __toCommonJS(index_exports);
|
|
143
144
|
|
|
144
145
|
// src/version.generated.ts
|
|
145
|
-
var VERSION = "1.0.0-alpha.
|
|
146
|
+
var VERSION = "1.0.0-alpha.95";
|
|
146
147
|
|
|
147
148
|
// src/lib/core.ts
|
|
148
149
|
var import_signal18 = require("@fluixi/reactive/signal");
|
|
@@ -1177,6 +1178,64 @@ var import_dom15 = require("@fluixi/dom");
|
|
|
1177
1178
|
var import_signal16 = require("@fluixi/reactive/signal");
|
|
1178
1179
|
var import_object = require("@fluixi/utils/object");
|
|
1179
1180
|
var import_compare = require("@fluixi/utils/compare");
|
|
1181
|
+
|
|
1182
|
+
// src/lib/router/scroll.ts
|
|
1183
|
+
var STORE = "fx:scroll";
|
|
1184
|
+
var KEEP = 100;
|
|
1185
|
+
function keepScroll(initial) {
|
|
1186
|
+
const read3 = () => {
|
|
1187
|
+
try {
|
|
1188
|
+
return JSON.parse(sessionStorage.getItem(STORE) ?? "{}");
|
|
1189
|
+
} catch {
|
|
1190
|
+
return {};
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
const positions = read3();
|
|
1194
|
+
const write = () => {
|
|
1195
|
+
const keys = Object.keys(positions);
|
|
1196
|
+
for (const key of keys.slice(0, Math.max(0, keys.length - KEEP))) delete positions[key];
|
|
1197
|
+
try {
|
|
1198
|
+
sessionStorage.setItem(STORE, JSON.stringify(positions));
|
|
1199
|
+
} catch {
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
let current = initial.key;
|
|
1203
|
+
const save = () => {
|
|
1204
|
+
if (current === void 0) return;
|
|
1205
|
+
delete positions[current];
|
|
1206
|
+
positions[current] = window.scrollY;
|
|
1207
|
+
write();
|
|
1208
|
+
};
|
|
1209
|
+
const restoration = history.scrollRestoration;
|
|
1210
|
+
history.scrollRestoration = "manual";
|
|
1211
|
+
window.addEventListener("pagehide", save);
|
|
1212
|
+
const to = (top) => window.scrollTo({ top, left: 0, behavior: "instant" });
|
|
1213
|
+
const toHash = (hash) => {
|
|
1214
|
+
if (!hash || hash === "#") return false;
|
|
1215
|
+
const target = document.getElementById(decodeURIComponent(hash.slice(1)));
|
|
1216
|
+
target?.scrollIntoView({ behavior: "instant" });
|
|
1217
|
+
return target !== null;
|
|
1218
|
+
};
|
|
1219
|
+
return {
|
|
1220
|
+
leave: save,
|
|
1221
|
+
arrive(location, from) {
|
|
1222
|
+
current = location.key;
|
|
1223
|
+
if (location.action === "pop" || from === void 0) {
|
|
1224
|
+
const y = location.key === void 0 ? void 0 : positions[location.key];
|
|
1225
|
+
if (y !== void 0) to(y);
|
|
1226
|
+
return;
|
|
1227
|
+
}
|
|
1228
|
+
if (location.action === "replace" && location.pathname === from.pathname) return;
|
|
1229
|
+
if (!toHash(location.hash)) to(0);
|
|
1230
|
+
},
|
|
1231
|
+
dispose() {
|
|
1232
|
+
window.removeEventListener("pagehide", save);
|
|
1233
|
+
history.scrollRestoration = restoration;
|
|
1234
|
+
}
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
// src/lib/router/index.ts
|
|
1180
1239
|
var import_router = require("@fluixi/router");
|
|
1181
1240
|
|
|
1182
1241
|
// src/lib/router/data.ts
|
|
@@ -1256,9 +1315,20 @@ function renderLayer(m, depth, base) {
|
|
|
1256
1315
|
return router ? router.trackLoad(result) : result;
|
|
1257
1316
|
});
|
|
1258
1317
|
(0, import_signal15.onCleanup)(onRevalidate(() => void refetch()));
|
|
1318
|
+
let loadedFor = (0, import_signal15.untrack)(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
|
|
1319
|
+
(0, import_signal15.createEffect)(() => {
|
|
1320
|
+
const now = base.matched()[depth];
|
|
1321
|
+
if (now?.route !== m.route) return;
|
|
1322
|
+
const params = JSON.stringify(now.params ?? {});
|
|
1323
|
+
if (params === loadedFor) return;
|
|
1324
|
+
loadedFor = params;
|
|
1325
|
+
(0, import_signal15.untrack)(() => void refetch());
|
|
1326
|
+
});
|
|
1259
1327
|
data = () => {
|
|
1260
1328
|
const error = resource2.error;
|
|
1261
1329
|
if (error !== void 0 && error !== null) throw error;
|
|
1330
|
+
const r = resource2;
|
|
1331
|
+
if (r.state === "refreshing") return r.latest;
|
|
1262
1332
|
return resource2();
|
|
1263
1333
|
};
|
|
1264
1334
|
Object.defineProperty(data, "loading", { get: () => resource2.loading });
|
|
@@ -1363,16 +1433,19 @@ function buildDefaultNotFound() {
|
|
|
1363
1433
|
}
|
|
1364
1434
|
var pendingTransitionMode;
|
|
1365
1435
|
function Router(props) {
|
|
1366
|
-
const
|
|
1436
|
+
const history2 = props.history ?? (0, import_router.createBrowserHistory)();
|
|
1367
1437
|
const router = (0, import_router.createRouter)({
|
|
1368
1438
|
routes: props.routes,
|
|
1369
1439
|
base: props.base,
|
|
1370
|
-
history
|
|
1440
|
+
history: history2
|
|
1371
1441
|
});
|
|
1372
1442
|
const [state, setState] = (0, import_signal15.createSignal)(router.state());
|
|
1373
1443
|
const [navigating, setNavigating] = (0, import_signal15.createSignal)(false);
|
|
1374
1444
|
const [loads, setLoads] = (0, import_signal15.createSignal)(0);
|
|
1375
1445
|
let navigationId = 0;
|
|
1446
|
+
const scroll = history2.window ? keepScroll(router.state().location) : void 0;
|
|
1447
|
+
let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
|
|
1448
|
+
const [arrived, setArrived] = (0, import_signal15.createSignal)(0);
|
|
1376
1449
|
const takeMode = () => {
|
|
1377
1450
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
1378
1451
|
pendingTransitionMode = void 0;
|
|
@@ -1382,6 +1455,10 @@ function Router(props) {
|
|
|
1382
1455
|
const id = ++navigationId;
|
|
1383
1456
|
const mode = takeMode();
|
|
1384
1457
|
setNavigating(true);
|
|
1458
|
+
if (scroll) {
|
|
1459
|
+
scroll.leave();
|
|
1460
|
+
arriving = { id, location: next.location, from: (0, import_signal15.untrack)(state).location };
|
|
1461
|
+
}
|
|
1385
1462
|
const prepared = prepareComponents(
|
|
1386
1463
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
1387
1464
|
);
|
|
@@ -1389,6 +1466,7 @@ function Router(props) {
|
|
|
1389
1466
|
setState(next);
|
|
1390
1467
|
const flushed = (0, import_signal15.flush)();
|
|
1391
1468
|
if (id === navigationId) setNavigating(false);
|
|
1469
|
+
if (scroll) setArrived(id);
|
|
1392
1470
|
return flushed;
|
|
1393
1471
|
};
|
|
1394
1472
|
if (!prepared) {
|
|
@@ -1402,6 +1480,7 @@ function Router(props) {
|
|
|
1402
1480
|
});
|
|
1403
1481
|
(0, import_signal15.onCleanup)(() => {
|
|
1404
1482
|
unsub();
|
|
1483
|
+
scroll?.dispose();
|
|
1405
1484
|
router.destroy();
|
|
1406
1485
|
navigationId++;
|
|
1407
1486
|
});
|
|
@@ -1424,6 +1503,19 @@ function Router(props) {
|
|
|
1424
1503
|
return result;
|
|
1425
1504
|
}
|
|
1426
1505
|
};
|
|
1506
|
+
if (scroll) {
|
|
1507
|
+
const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
|
|
1508
|
+
(0, import_signal15.createEffect)(() => {
|
|
1509
|
+
const id = arrived();
|
|
1510
|
+
if (ctx.isRouting()) return;
|
|
1511
|
+
const next = arriving;
|
|
1512
|
+
if (!next || next.id !== id || id !== navigationId) return;
|
|
1513
|
+
arriving = null;
|
|
1514
|
+
nextFrame(() => {
|
|
1515
|
+
if (id === navigationId) scroll.arrive(next.location, next.from);
|
|
1516
|
+
});
|
|
1517
|
+
});
|
|
1518
|
+
}
|
|
1427
1519
|
const root = {
|
|
1428
1520
|
depth: -1,
|
|
1429
1521
|
matched,
|