@fluixi/core 1.0.0-alpha.94 → 1.0.0-alpha.96
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-RKBFEFZP.mjs} +125 -10
- package/dist/src/cdn/core.cjs +132 -12
- package/dist/src/cdn/core.mjs +4 -4
- package/dist/src/cdn/{router-VOY43YNM.mjs → router-V2THK27H.mjs} +3 -3
- package/dist/src/index.cjs +122 -7
- package/dist/src/index.mjs +122 -7
- package/dist/src/lib/client/{chunk-TSXM2PNY.mjs → chunk-RNRJHQFG.mjs} +1 -1
- package/dist/src/lib/client/index.cjs +133 -13
- package/dist/src/lib/client/index.d.ts.map +1 -1
- package/dist/src/lib/client/index.js +4 -1
- package/dist/src/lib/client/index.mjs +5 -5
- package/dist/src/lib/client/{router-BDVPLLYX.mjs → router-F3Y4BIVJ.mjs} +127 -12
- package/dist/src/lib/core.cjs +121 -6
- package/dist/src/lib/core.mjs +121 -6
- 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/isomorphic.cjs +1 -1
- package/dist/src/lib/isomorphic.d.ts +5 -0
- package/dist/src/lib/isomorphic.d.ts.map +1 -1
- package/dist/src/lib/isomorphic.js +1 -1
- package/dist/src/lib/isomorphic.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/data.cjs +4 -4
- package/dist/src/lib/router/data.d.ts.map +1 -1
- package/dist/src/lib/router/data.js +9 -8
- package/dist/src/lib/router/data.mjs +4 -4
- package/dist/src/lib/router/index.cjs +126 -11
- package/dist/src/lib/router/index.d.ts +8 -5
- package/dist/src/lib/router/index.d.ts.map +1 -1
- package/dist/src/lib/router/index.js +94 -7
- package/dist/src/lib/router/index.mjs +126 -11
- 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.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/core v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.96 | (c) 2026 Ibrahima Touré and Fluixi contributors | MIT */
|
|
2
2
|
"use strict";
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -143,7 +143,7 @@ __export(index_exports, {
|
|
|
143
143
|
module.exports = __toCommonJS(index_exports);
|
|
144
144
|
|
|
145
145
|
// src/version.generated.ts
|
|
146
|
-
var VERSION = "1.0.0-alpha.
|
|
146
|
+
var VERSION = "1.0.0-alpha.96";
|
|
147
147
|
|
|
148
148
|
// src/lib/core.ts
|
|
149
149
|
var import_signal18 = require("@fluixi/reactive/signal");
|
|
@@ -763,7 +763,7 @@ function createIsomorphicStore(key, options) {
|
|
|
763
763
|
}
|
|
764
764
|
return initPromise;
|
|
765
765
|
};
|
|
766
|
-
return { value, fields, set, setField, ensureInit, key };
|
|
766
|
+
return { value, fields, set, setField, ensureInit, key, seeded };
|
|
767
767
|
}
|
|
768
768
|
|
|
769
769
|
// src/lib/env/index.ts
|
|
@@ -1178,6 +1178,64 @@ var import_dom15 = require("@fluixi/dom");
|
|
|
1178
1178
|
var import_signal16 = require("@fluixi/reactive/signal");
|
|
1179
1179
|
var import_object = require("@fluixi/utils/object");
|
|
1180
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
|
|
1181
1239
|
var import_router = require("@fluixi/router");
|
|
1182
1240
|
|
|
1183
1241
|
// src/lib/router/data.ts
|
|
@@ -1252,14 +1310,49 @@ function renderLayer(m, depth, base) {
|
|
|
1252
1310
|
});
|
|
1253
1311
|
});
|
|
1254
1312
|
};
|
|
1313
|
+
let readsLocation;
|
|
1255
1314
|
const [resource2, { refetch }] = (0, import_signal15.createResource)(() => {
|
|
1256
|
-
const
|
|
1315
|
+
const params = (0, import_signal15.untrack)(base.params);
|
|
1316
|
+
const location = (0, import_signal15.untrack)(base.location);
|
|
1317
|
+
readsLocation = false;
|
|
1318
|
+
const result = loader(
|
|
1319
|
+
{
|
|
1320
|
+
params: () => params,
|
|
1321
|
+
location: () => {
|
|
1322
|
+
readsLocation = true;
|
|
1323
|
+
return location;
|
|
1324
|
+
}
|
|
1325
|
+
},
|
|
1326
|
+
owner,
|
|
1327
|
+
() => cancelled,
|
|
1328
|
+
trackDeps
|
|
1329
|
+
);
|
|
1257
1330
|
return router ? router.trackLoad(result) : result;
|
|
1258
1331
|
});
|
|
1259
|
-
(0, import_signal15.onCleanup)(
|
|
1332
|
+
(0, import_signal15.onCleanup)(
|
|
1333
|
+
onRevalidate(() => {
|
|
1334
|
+
if ((0, import_signal15.untrack)(() => base.matched()[depth]?.route) !== m.route) return;
|
|
1335
|
+
void refetch();
|
|
1336
|
+
})
|
|
1337
|
+
);
|
|
1338
|
+
let loadedFor = (0, import_signal15.untrack)(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
|
|
1339
|
+
let searchedFor = (0, import_signal15.untrack)(() => base.location().search);
|
|
1340
|
+
(0, import_signal15.createEffect)(() => {
|
|
1341
|
+
const now = base.matched()[depth];
|
|
1342
|
+
const search = base.location().search;
|
|
1343
|
+
if (now?.route !== m.route) return;
|
|
1344
|
+
const params = JSON.stringify(now.params ?? {});
|
|
1345
|
+
const paramsMoved = params !== loadedFor;
|
|
1346
|
+
const searchMoved = readsLocation !== false && search !== searchedFor;
|
|
1347
|
+
loadedFor = params;
|
|
1348
|
+
searchedFor = search;
|
|
1349
|
+
if (paramsMoved || searchMoved) (0, import_signal15.untrack)(() => void refetch());
|
|
1350
|
+
});
|
|
1260
1351
|
data = () => {
|
|
1261
1352
|
const error = resource2.error;
|
|
1262
1353
|
if (error !== void 0 && error !== null) throw error;
|
|
1354
|
+
const r = resource2;
|
|
1355
|
+
if (r.state === "refreshing") return r.latest;
|
|
1263
1356
|
return resource2();
|
|
1264
1357
|
};
|
|
1265
1358
|
Object.defineProperty(data, "loading", { get: () => resource2.loading });
|
|
@@ -1364,16 +1457,19 @@ function buildDefaultNotFound() {
|
|
|
1364
1457
|
}
|
|
1365
1458
|
var pendingTransitionMode;
|
|
1366
1459
|
function Router(props) {
|
|
1367
|
-
const
|
|
1460
|
+
const history2 = props.history ?? (0, import_router.createBrowserHistory)();
|
|
1368
1461
|
const router = (0, import_router.createRouter)({
|
|
1369
1462
|
routes: props.routes,
|
|
1370
1463
|
base: props.base,
|
|
1371
|
-
history
|
|
1464
|
+
history: history2
|
|
1372
1465
|
});
|
|
1373
1466
|
const [state, setState] = (0, import_signal15.createSignal)(router.state());
|
|
1374
1467
|
const [navigating, setNavigating] = (0, import_signal15.createSignal)(false);
|
|
1375
1468
|
const [loads, setLoads] = (0, import_signal15.createSignal)(0);
|
|
1376
1469
|
let navigationId = 0;
|
|
1470
|
+
const scroll = history2.window ? keepScroll(router.state().location) : void 0;
|
|
1471
|
+
let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
|
|
1472
|
+
const [arrived, setArrived] = (0, import_signal15.createSignal)(0);
|
|
1377
1473
|
const takeMode = () => {
|
|
1378
1474
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
1379
1475
|
pendingTransitionMode = void 0;
|
|
@@ -1383,6 +1479,10 @@ function Router(props) {
|
|
|
1383
1479
|
const id = ++navigationId;
|
|
1384
1480
|
const mode = takeMode();
|
|
1385
1481
|
setNavigating(true);
|
|
1482
|
+
if (scroll) {
|
|
1483
|
+
scroll.leave();
|
|
1484
|
+
arriving = { id, location: next.location, from: (0, import_signal15.untrack)(state).location };
|
|
1485
|
+
}
|
|
1386
1486
|
const prepared = prepareComponents(
|
|
1387
1487
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
1388
1488
|
);
|
|
@@ -1390,6 +1490,7 @@ function Router(props) {
|
|
|
1390
1490
|
setState(next);
|
|
1391
1491
|
const flushed = (0, import_signal15.flush)();
|
|
1392
1492
|
if (id === navigationId) setNavigating(false);
|
|
1493
|
+
if (scroll) setArrived(id);
|
|
1393
1494
|
return flushed;
|
|
1394
1495
|
};
|
|
1395
1496
|
if (!prepared) {
|
|
@@ -1403,6 +1504,7 @@ function Router(props) {
|
|
|
1403
1504
|
});
|
|
1404
1505
|
(0, import_signal15.onCleanup)(() => {
|
|
1405
1506
|
unsub();
|
|
1507
|
+
scroll?.dispose();
|
|
1406
1508
|
router.destroy();
|
|
1407
1509
|
navigationId++;
|
|
1408
1510
|
});
|
|
@@ -1425,6 +1527,19 @@ function Router(props) {
|
|
|
1425
1527
|
return result;
|
|
1426
1528
|
}
|
|
1427
1529
|
};
|
|
1530
|
+
if (scroll) {
|
|
1531
|
+
const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
|
|
1532
|
+
(0, import_signal15.createEffect)(() => {
|
|
1533
|
+
const id = arrived();
|
|
1534
|
+
if (ctx.isRouting()) return;
|
|
1535
|
+
const next = arriving;
|
|
1536
|
+
if (!next || next.id !== id || id !== navigationId) return;
|
|
1537
|
+
arriving = null;
|
|
1538
|
+
nextFrame(() => {
|
|
1539
|
+
if (id === navigationId) scroll.arrive(next.location, next.from);
|
|
1540
|
+
});
|
|
1541
|
+
});
|
|
1542
|
+
}
|
|
1428
1543
|
const root = {
|
|
1429
1544
|
depth: -1,
|
|
1430
1545
|
matched,
|
package/dist/src/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
/*! @fluixi/core v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.96 | (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.96";
|
|
5
5
|
|
|
6
6
|
// src/lib/core.ts
|
|
7
7
|
import {
|
|
@@ -690,7 +690,7 @@ function createIsomorphicStore(key, options) {
|
|
|
690
690
|
}
|
|
691
691
|
return initPromise;
|
|
692
692
|
};
|
|
693
|
-
return { value, fields, set, setField, ensureInit, key };
|
|
693
|
+
return { value, fields, set, setField, ensureInit, key, seeded };
|
|
694
694
|
}
|
|
695
695
|
|
|
696
696
|
// src/lib/env/index.ts
|
|
@@ -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,
|
|
@@ -1213,14 +1271,49 @@ function renderLayer(m, depth, base) {
|
|
|
1213
1271
|
});
|
|
1214
1272
|
});
|
|
1215
1273
|
};
|
|
1274
|
+
let readsLocation;
|
|
1216
1275
|
const [resource2, { refetch }] = createResource5(() => {
|
|
1217
|
-
const
|
|
1276
|
+
const params = untrack4(base.params);
|
|
1277
|
+
const location = untrack4(base.location);
|
|
1278
|
+
readsLocation = false;
|
|
1279
|
+
const result = loader(
|
|
1280
|
+
{
|
|
1281
|
+
params: () => params,
|
|
1282
|
+
location: () => {
|
|
1283
|
+
readsLocation = true;
|
|
1284
|
+
return location;
|
|
1285
|
+
}
|
|
1286
|
+
},
|
|
1287
|
+
owner,
|
|
1288
|
+
() => cancelled,
|
|
1289
|
+
trackDeps
|
|
1290
|
+
);
|
|
1218
1291
|
return router ? router.trackLoad(result) : result;
|
|
1219
1292
|
});
|
|
1220
|
-
onCleanup4(
|
|
1293
|
+
onCleanup4(
|
|
1294
|
+
onRevalidate(() => {
|
|
1295
|
+
if (untrack4(() => base.matched()[depth]?.route) !== m.route) return;
|
|
1296
|
+
void refetch();
|
|
1297
|
+
})
|
|
1298
|
+
);
|
|
1299
|
+
let loadedFor = untrack4(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
|
|
1300
|
+
let searchedFor = untrack4(() => base.location().search);
|
|
1301
|
+
createEffect4(() => {
|
|
1302
|
+
const now = base.matched()[depth];
|
|
1303
|
+
const search = base.location().search;
|
|
1304
|
+
if (now?.route !== m.route) return;
|
|
1305
|
+
const params = JSON.stringify(now.params ?? {});
|
|
1306
|
+
const paramsMoved = params !== loadedFor;
|
|
1307
|
+
const searchMoved = readsLocation !== false && search !== searchedFor;
|
|
1308
|
+
loadedFor = params;
|
|
1309
|
+
searchedFor = search;
|
|
1310
|
+
if (paramsMoved || searchMoved) untrack4(() => void refetch());
|
|
1311
|
+
});
|
|
1221
1312
|
data = () => {
|
|
1222
1313
|
const error = resource2.error;
|
|
1223
1314
|
if (error !== void 0 && error !== null) throw error;
|
|
1315
|
+
const r = resource2;
|
|
1316
|
+
if (r.state === "refreshing") return r.latest;
|
|
1224
1317
|
return resource2();
|
|
1225
1318
|
};
|
|
1226
1319
|
Object.defineProperty(data, "loading", { get: () => resource2.loading });
|
|
@@ -1325,16 +1418,19 @@ function buildDefaultNotFound() {
|
|
|
1325
1418
|
}
|
|
1326
1419
|
var pendingTransitionMode;
|
|
1327
1420
|
function Router(props) {
|
|
1328
|
-
const
|
|
1421
|
+
const history2 = props.history ?? createBrowserHistory();
|
|
1329
1422
|
const router = createCoreRouter({
|
|
1330
1423
|
routes: props.routes,
|
|
1331
1424
|
base: props.base,
|
|
1332
|
-
history
|
|
1425
|
+
history: history2
|
|
1333
1426
|
});
|
|
1334
1427
|
const [state, setState] = createSignal8(router.state());
|
|
1335
1428
|
const [navigating, setNavigating] = createSignal8(false);
|
|
1336
1429
|
const [loads, setLoads] = createSignal8(0);
|
|
1337
1430
|
let navigationId = 0;
|
|
1431
|
+
const scroll = history2.window ? keepScroll(router.state().location) : void 0;
|
|
1432
|
+
let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
|
|
1433
|
+
const [arrived, setArrived] = createSignal8(0);
|
|
1338
1434
|
const takeMode = () => {
|
|
1339
1435
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
1340
1436
|
pendingTransitionMode = void 0;
|
|
@@ -1344,6 +1440,10 @@ function Router(props) {
|
|
|
1344
1440
|
const id = ++navigationId;
|
|
1345
1441
|
const mode = takeMode();
|
|
1346
1442
|
setNavigating(true);
|
|
1443
|
+
if (scroll) {
|
|
1444
|
+
scroll.leave();
|
|
1445
|
+
arriving = { id, location: next.location, from: untrack4(state).location };
|
|
1446
|
+
}
|
|
1347
1447
|
const prepared = prepareComponents(
|
|
1348
1448
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
1349
1449
|
);
|
|
@@ -1351,6 +1451,7 @@ function Router(props) {
|
|
|
1351
1451
|
setState(next);
|
|
1352
1452
|
const flushed = flush();
|
|
1353
1453
|
if (id === navigationId) setNavigating(false);
|
|
1454
|
+
if (scroll) setArrived(id);
|
|
1354
1455
|
return flushed;
|
|
1355
1456
|
};
|
|
1356
1457
|
if (!prepared) {
|
|
@@ -1364,6 +1465,7 @@ function Router(props) {
|
|
|
1364
1465
|
});
|
|
1365
1466
|
onCleanup4(() => {
|
|
1366
1467
|
unsub();
|
|
1468
|
+
scroll?.dispose();
|
|
1367
1469
|
router.destroy();
|
|
1368
1470
|
navigationId++;
|
|
1369
1471
|
});
|
|
@@ -1386,6 +1488,19 @@ function Router(props) {
|
|
|
1386
1488
|
return result;
|
|
1387
1489
|
}
|
|
1388
1490
|
};
|
|
1491
|
+
if (scroll) {
|
|
1492
|
+
const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
|
|
1493
|
+
createEffect4(() => {
|
|
1494
|
+
const id = arrived();
|
|
1495
|
+
if (ctx.isRouting()) return;
|
|
1496
|
+
const next = arriving;
|
|
1497
|
+
if (!next || next.id !== id || id !== navigationId) return;
|
|
1498
|
+
arriving = null;
|
|
1499
|
+
nextFrame(() => {
|
|
1500
|
+
if (id === navigationId) scroll.arrive(next.location, next.from);
|
|
1501
|
+
});
|
|
1502
|
+
});
|
|
1503
|
+
}
|
|
1389
1504
|
const root = {
|
|
1390
1505
|
depth: -1,
|
|
1391
1506
|
matched,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @fluixi/core v1.0.0-alpha.
|
|
1
|
+
/*! @fluixi/core v1.0.0-alpha.96 | (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);
|
|
@@ -225,7 +287,8 @@ function getSubmissionsSignal(url) {
|
|
|
225
287
|
}
|
|
226
288
|
function action(fn, name, options = {}) {
|
|
227
289
|
const actionUrl = name || fn.name || "action";
|
|
228
|
-
const submit = async (
|
|
290
|
+
const submit = async (...args) => {
|
|
291
|
+
const input = args.length > 1 ? args : args[0];
|
|
229
292
|
const [, setSubmission] = getSubmissionSignal(actionUrl);
|
|
230
293
|
const [, setSubmissions] = getSubmissionsSignal(actionUrl);
|
|
231
294
|
let entry;
|
|
@@ -240,11 +303,10 @@ function action(fn, name, options = {}) {
|
|
|
240
303
|
};
|
|
241
304
|
const retry = () => {
|
|
242
305
|
drop2();
|
|
243
|
-
return submit(
|
|
306
|
+
return submit(...args);
|
|
244
307
|
};
|
|
245
308
|
entry = {
|
|
246
309
|
input,
|
|
247
|
-
// Approximate type for tracking
|
|
248
310
|
pending: true,
|
|
249
311
|
clear,
|
|
250
312
|
retry
|
|
@@ -252,7 +314,7 @@ function action(fn, name, options = {}) {
|
|
|
252
314
|
setSubmission(entry);
|
|
253
315
|
setSubmissions((list) => [...list, entry]);
|
|
254
316
|
try {
|
|
255
|
-
const result = await fn(
|
|
317
|
+
const result = await fn(...args);
|
|
256
318
|
setSubmission({
|
|
257
319
|
input,
|
|
258
320
|
result,
|
|
@@ -326,7 +388,7 @@ var init_data = __esm({
|
|
|
326
388
|
var router_exports = {};
|
|
327
389
|
__export(router_exports, {
|
|
328
390
|
A: () => A,
|
|
329
|
-
|
|
391
|
+
ActionForm: () => ActionForm,
|
|
330
392
|
Link: () => Link,
|
|
331
393
|
Outlet: () => Outlet,
|
|
332
394
|
Redirect: () => Redirect,
|
|
@@ -384,14 +446,49 @@ function renderLayer(m, depth, base) {
|
|
|
384
446
|
});
|
|
385
447
|
});
|
|
386
448
|
};
|
|
449
|
+
let readsLocation;
|
|
387
450
|
const [resource, { refetch }] = (0, import_signal10.createResource)(() => {
|
|
388
|
-
const
|
|
451
|
+
const params = (0, import_signal10.untrack)(base.params);
|
|
452
|
+
const location = (0, import_signal10.untrack)(base.location);
|
|
453
|
+
readsLocation = false;
|
|
454
|
+
const result = loader(
|
|
455
|
+
{
|
|
456
|
+
params: () => params,
|
|
457
|
+
location: () => {
|
|
458
|
+
readsLocation = true;
|
|
459
|
+
return location;
|
|
460
|
+
}
|
|
461
|
+
},
|
|
462
|
+
owner,
|
|
463
|
+
() => cancelled,
|
|
464
|
+
trackDeps
|
|
465
|
+
);
|
|
389
466
|
return router ? router.trackLoad(result) : result;
|
|
390
467
|
});
|
|
391
|
-
(0, import_signal10.onCleanup)(
|
|
468
|
+
(0, import_signal10.onCleanup)(
|
|
469
|
+
onRevalidate(() => {
|
|
470
|
+
if ((0, import_signal10.untrack)(() => base.matched()[depth]?.route) !== m.route) return;
|
|
471
|
+
void refetch();
|
|
472
|
+
})
|
|
473
|
+
);
|
|
474
|
+
let loadedFor = (0, import_signal10.untrack)(() => JSON.stringify(base.matched()[depth]?.params ?? {}));
|
|
475
|
+
let searchedFor = (0, import_signal10.untrack)(() => base.location().search);
|
|
476
|
+
(0, import_signal10.createEffect)(() => {
|
|
477
|
+
const now = base.matched()[depth];
|
|
478
|
+
const search = base.location().search;
|
|
479
|
+
if (now?.route !== m.route) return;
|
|
480
|
+
const params = JSON.stringify(now.params ?? {});
|
|
481
|
+
const paramsMoved = params !== loadedFor;
|
|
482
|
+
const searchMoved = readsLocation !== false && search !== searchedFor;
|
|
483
|
+
loadedFor = params;
|
|
484
|
+
searchedFor = search;
|
|
485
|
+
if (paramsMoved || searchMoved) (0, import_signal10.untrack)(() => void refetch());
|
|
486
|
+
});
|
|
392
487
|
data = () => {
|
|
393
488
|
const error = resource.error;
|
|
394
489
|
if (error !== void 0 && error !== null) throw error;
|
|
490
|
+
const r = resource;
|
|
491
|
+
if (r.state === "refreshing") return r.latest;
|
|
395
492
|
return resource();
|
|
396
493
|
};
|
|
397
494
|
Object.defineProperty(data, "loading", { get: () => resource.loading });
|
|
@@ -495,16 +592,19 @@ function buildDefaultNotFound() {
|
|
|
495
592
|
return el;
|
|
496
593
|
}
|
|
497
594
|
function Router(props) {
|
|
498
|
-
const
|
|
595
|
+
const history2 = props.history ?? (0, import_router.createBrowserHistory)();
|
|
499
596
|
const router = (0, import_router.createRouter)({
|
|
500
597
|
routes: props.routes,
|
|
501
598
|
base: props.base,
|
|
502
|
-
history
|
|
599
|
+
history: history2
|
|
503
600
|
});
|
|
504
601
|
const [state, setState] = (0, import_signal10.createSignal)(router.state());
|
|
505
602
|
const [navigating, setNavigating] = (0, import_signal10.createSignal)(false);
|
|
506
603
|
const [loads, setLoads] = (0, import_signal10.createSignal)(0);
|
|
507
604
|
let navigationId = 0;
|
|
605
|
+
const scroll = history2.window ? keepScroll(router.state().location) : void 0;
|
|
606
|
+
let arriving = scroll ? { id: 0, location: router.state().location, from: void 0 } : null;
|
|
607
|
+
const [arrived, setArrived] = (0, import_signal10.createSignal)(0);
|
|
508
608
|
const takeMode = () => {
|
|
509
609
|
const mode = pendingTransitionMode ?? (props.transition ?? "auto");
|
|
510
610
|
pendingTransitionMode = void 0;
|
|
@@ -514,6 +614,10 @@ function Router(props) {
|
|
|
514
614
|
const id = ++navigationId;
|
|
515
615
|
const mode = takeMode();
|
|
516
616
|
setNavigating(true);
|
|
617
|
+
if (scroll) {
|
|
618
|
+
scroll.leave();
|
|
619
|
+
arriving = { id, location: next.location, from: (0, import_signal10.untrack)(state).location };
|
|
620
|
+
}
|
|
517
621
|
const prepared = prepareComponents(
|
|
518
622
|
(next.match?.matched ?? []).map((m) => m.component).filter(Boolean)
|
|
519
623
|
);
|
|
@@ -521,6 +625,7 @@ function Router(props) {
|
|
|
521
625
|
setState(next);
|
|
522
626
|
const flushed = (0, import_signal10.flush)();
|
|
523
627
|
if (id === navigationId) setNavigating(false);
|
|
628
|
+
if (scroll) setArrived(id);
|
|
524
629
|
return flushed;
|
|
525
630
|
};
|
|
526
631
|
if (!prepared) {
|
|
@@ -534,6 +639,7 @@ function Router(props) {
|
|
|
534
639
|
});
|
|
535
640
|
(0, import_signal10.onCleanup)(() => {
|
|
536
641
|
unsub();
|
|
642
|
+
scroll?.dispose();
|
|
537
643
|
router.destroy();
|
|
538
644
|
navigationId++;
|
|
539
645
|
});
|
|
@@ -556,6 +662,19 @@ function Router(props) {
|
|
|
556
662
|
return result;
|
|
557
663
|
}
|
|
558
664
|
};
|
|
665
|
+
if (scroll) {
|
|
666
|
+
const nextFrame = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (fn) => setTimeout(fn, 0);
|
|
667
|
+
(0, import_signal10.createEffect)(() => {
|
|
668
|
+
const id = arrived();
|
|
669
|
+
if (ctx.isRouting()) return;
|
|
670
|
+
const next = arriving;
|
|
671
|
+
if (!next || next.id !== id || id !== navigationId) return;
|
|
672
|
+
arriving = null;
|
|
673
|
+
nextFrame(() => {
|
|
674
|
+
if (id === navigationId) scroll.arrive(next.location, next.from);
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
}
|
|
559
678
|
const root = {
|
|
560
679
|
depth: -1,
|
|
561
680
|
matched,
|
|
@@ -751,7 +870,7 @@ function Link(props) {
|
|
|
751
870
|
if (linkChildren != null) (0, import_dom12.insert)(a, linkChildren);
|
|
752
871
|
return a;
|
|
753
872
|
}
|
|
754
|
-
function
|
|
873
|
+
function ActionForm(props) {
|
|
755
874
|
const action2 = props.action;
|
|
756
875
|
const cls = props.className ?? props.class;
|
|
757
876
|
const url = action2.url ?? "";
|
|
@@ -799,6 +918,7 @@ var init_router = __esm({
|
|
|
799
918
|
import_signal11 = require("@fluixi/reactive/signal");
|
|
800
919
|
import_object = require("@fluixi/utils/object");
|
|
801
920
|
import_compare = require("@fluixi/utils/compare");
|
|
921
|
+
init_scroll();
|
|
802
922
|
import_router = require("@fluixi/router");
|
|
803
923
|
init_data();
|
|
804
924
|
import_router2 = require("@fluixi/router");
|
|
@@ -847,7 +967,7 @@ var import_dom13 = require("@fluixi/dom");
|
|
|
847
967
|
var import_dom = require("@fluixi/dom");
|
|
848
968
|
|
|
849
969
|
// src/version.generated.ts
|
|
850
|
-
var VERSION = "1.0.0-alpha.
|
|
970
|
+
var VERSION = "1.0.0-alpha.96";
|
|
851
971
|
|
|
852
972
|
// src/lib/render/versions.ts
|
|
853
973
|
var import_dom2 = require("@fluixi/dom");
|
|
@@ -1053,7 +1173,7 @@ async function startClient(App, options = {}) {
|
|
|
1053
1173
|
}
|
|
1054
1174
|
deserializeHydrationData();
|
|
1055
1175
|
setHydrating(true);
|
|
1056
|
-
(0, import_dom13.hydrate)(rootOf(App), container);
|
|
1176
|
+
(0, import_dom13.hydrate)(() => rootOf(App), container);
|
|
1057
1177
|
replayEvents();
|
|
1058
1178
|
} finally {
|
|
1059
1179
|
(0, import_dom13.endAppHydration)();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,uBAAuB,CAAC;AAgB/B;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,SAAS,EAAE,WAAW,GAAG,IAAI,QAOlE;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAChB;AAoBD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,EACzB,OAAO,GAAE,kBAAuB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/lib/client/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,OAAO,uBAAuB,CAAC;AAgB/B;;;;;;;;;;GAUG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,EAAE,SAAS,EAAE,WAAW,GAAG,IAAI,QAOlE;AAED,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5B,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC;CAChB;AAoBD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,EACzB,OAAO,GAAE,kBAAuB,iBAiFjC"}
|