@tanstack/solid-router
Version:
Modern and scalable routing for Solid applications
120 lines (119 loc) • 4.5 kB
JavaScript
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
const require_useRouter = require("./useRouter.cjs");
let _tanstack_router_core = require("@tanstack/router-core");
let solid_js = require("solid-js");
solid_js = require_runtime.__toESM(solid_js, 1);
let _tanstack_router_core_isServer = require("@tanstack/router-core/isServer");
//#region src/Transitioner.tsx
/**
* Solid's observe tier (`OBSERVE` is defined on the dev and observe builds,
* undefined in production) attributes what the user waited on to the
* navigation that caused it. The rule for every router is the same: wrap the
* write whose landing is the destination showing, and pass `at` when the
* request predates that write. Here that write is the match publish inside
* `startTransition` — the loaders were awaited in router-core before it —
* so the ref names the destination route from the expected matches and
* dates from the history change that started the load. The pending offer
* (`offerPending`, a match with `status: 'pending'`) is not the destination
* and is published undeclared; the initial load and a same-location reload
* are not navigations.
*/
function describeNavigation(router, expected, at) {
if (expected.some((match) => match.status === "pending")) return;
const to = router.latestLocation;
const from = router.stores.resolvedLocation.get();
if (!from || from.href === to.href) return;
const leaf = expected[expected.length - 1];
const ref = {
kind: "navigation",
name: leaf?.fullPath || to.pathname,
to: to.pathname,
from: from.pathname
};
if (leaf && Object.keys(leaf.params).length) ref.params = leaf.params;
if (at !== void 0) ref.at = at;
return ref;
}
function getResolvedLocation(router) {
const resolvedLocation = router.stores.resolvedLocation.get();
if (resolvedLocation?.href === router.latestLocation.href && resolvedLocation.state.__TSR_key === router.latestLocation.state.__TSR_key) return resolvedLocation;
}
function Transitioner() {
const router = require_useRouter.useRouter();
const acks = [];
let committed;
const isCommitted = (expected) => !!committed && committed.length === expected.length && expected.every((match, index) => committed[index] === match);
let requestedAt;
router.startTransition = (fn, expectedMatches) => {
if (_tanstack_router_core_isServer.isServer ?? router.isServer) {
fn();
return Promise.resolve(true);
}
return new Promise((resolve) => {
const ack = [expectedMatches, resolve];
acks.push(ack);
let publish = fn;
if (solid_js.OBSERVE !== void 0) {
const ref = describeNavigation(router, expectedMatches, requestedAt);
if (ref !== void 0) {
requestedAt = void 0;
const observe = solid_js.OBSERVE;
publish = () => observe.attribution.withOrigin(ref, fn);
}
}
solid_js.runWithOwner(null, publish);
try {
solid_js.flush();
} catch {}
if (acks.includes(ack) && isCommitted(expectedMatches)) {
acks.splice(acks.indexOf(ack), 1);
resolve(true);
}
});
};
solid_js.createEffect(() => router.stores.matches.get(), (current) => {
committed = current;
if (acks.length) for (const [expected, resolve] of acks.splice(0)) resolve(isCommitted(expected));
});
solid_js.onSettled(() => {
const unsub = router.history.subscribe(() => {
requestedAt ??= performance.now();
queueMicrotask(() => router.load().catch(console.error));
});
router.updateLatestLocation();
const nextLocation = router.buildLocation({
to: router.latestLocation.pathname,
search: true,
params: true,
hash: true,
state: true,
_includeValidateSearch: true
});
if ((0, _tanstack_router_core.trimPathRight)(router.latestLocation.publicHref) !== (0, _tanstack_router_core.trimPathRight)(nextLocation.publicHref)) {
router.commitLocation({
...nextLocation,
replace: true,
ignoreBlocker: true
});
return unsub;
}
if (!getResolvedLocation(router) && !router._tx) queueMicrotask(() => router.load().catch(console.error));
return unsub;
});
return null;
}
function Rendered() {
const router = require_useRouter.useRouter();
solid_js.onSettled(() => {
const resolvedLocation = getResolvedLocation(router);
if (resolvedLocation) router.emit({
type: "onRendered",
...(0, _tanstack_router_core.getLocationChangeInfo)(resolvedLocation, resolvedLocation)
});
});
return null;
}
//#endregion
exports.Rendered = Rendered;
exports.Transitioner = Transitioner;
//# sourceMappingURL=Transitioner.cjs.map