@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
package/dist/src/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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
|
|
|
3
3
|
// src/version.generated.ts
|
|
4
|
-
var VERSION = "1.0.0-alpha.
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
2
|
-
import "./chunk-
|
|
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.
|
|
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-
|
|
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.
|
|
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-
|
|
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
|
|
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,
|