@tanstack/solid-router
Version:
Modern and scalable routing for Solid applications
128 lines (127 loc) • 4.66 kB
JavaScript
const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
let solid_js = require("solid-js");
solid_js = require_runtime.__toESM(solid_js, 1);
//#region src/observe.ts
var requests = /* @__PURE__ */ new WeakMap();
var held = /* @__PURE__ */ new WeakSet();
/**
* Records the navigation being requested now — a `commitLocation`, or a
* blocker's `proceed` — for the history change it causes to answer. The
* history may notify after awaiting its blockers, the interaction gone from
* the stack by then; a later request replaces this one.
*/
function noteRequest(router) {
const observe = solid_js.OBSERVE;
if (observe === void 0) return;
held.delete(router);
requests.set(router, {
at: performance.now(),
interaction: observe.attribution.currentOrigin()
});
}
/** A blocker is deciding on the noted request: keep it past the commit. */
function holdRequest(router) {
if (requests.has(router)) held.add(router);
}
/**
* The commit that noted the request has returned. Without a blocker
* holding it, the history has notified by then — or never will: the same
* location reloads without a history change.
*/
function releaseRequest(router) {
if (!held.has(router)) requests.delete(router);
}
/** Forgets the noted request: a blocker stopped the navigation it made. */
function dropRequest(router) {
held.delete(router);
requests.delete(router);
}
/** The request noted for the history change being notified, if any. */
function takeRequest(router) {
const request = requests.get(router);
dropRequest(router);
return request;
}
/**
* The route `pathname` matches — its `fullPath` (`/users/$id`) and the raw
* params it bound — or, when no route matches it (a not-found, by the rule
* `matchRoutes` applies), the pathname itself and no params.
*/
function describeRoute(router, pathname) {
const [, rawParams, route] = router.getMatchedRoutes(pathname);
if (!route || route.path !== "/" && rawParams["**"]) return { name: pathname };
const { "**": _, ...params } = rawParams;
return Object.keys(params).length ? {
name: route.fullPath,
params
} : { name: route.fullPath };
}
/**
* The navigation a match publish lands: the latest location, from `from`
* (the location shown, or the arrival while the first page is still
* loading). Nothing when the publish reloads the location it came from.
* `request` dates it from the request and joins it to the interaction that
* asked, both gone by the time the loaders resolve and the publish runs; the
* key's presence declares the interaction, `undefined` included.
*
* One ref per destination, to be opened nested, as `@solidjs/router`
* declares a navigation sent elsewhere while pending (a redirect, or
* another navigation): the first names the destination requested, and each
* `hops` entry is abandoned by a `redirect: n` ref the engine folds onto it,
* keeping the request's time and interaction and listing the abandoned
* destinations in `redirects`.
*/
function describeNavigation(router, request, from, hops) {
const to = router.latestLocation;
if (!from || from.href === to.href && !hops.length) return;
return [...hops.map((hop) => hop.location), to].map((location, index) => {
const ref = {
kind: "navigation",
...describeRoute(router, location.pathname),
to: location.href
};
if (index) {
ref.redirect = index;
ref.at = hops[index - 1].at;
} else {
ref.from = from.href;
ref.at = request.at;
ref.interaction = request.interaction;
}
return ref;
});
}
/**
* The route the document arrived on, declared around the work that
* establishes the router's initial match, since a fresh document has no
* publish to wrap. On the client the engine opens it at the time origin and
* settles it as that work returns (the first `"navigation"` record,
* `initial: true`); on the server the same call names the request's
* `"render"` record (`RenderEvent.route`). The fields are getters of
* `location`, read at settle: the canonical location the client committed,
* or the one a server load resolved.
*/
function describeInitial(router, location) {
return {
kind: "navigation",
initial: true,
get to() {
return location().href;
},
get name() {
return describeRoute(router, location().pathname).name;
},
get params() {
return describeRoute(router, location().pathname).params;
}
};
}
//#endregion
exports.describeInitial = describeInitial;
exports.describeNavigation = describeNavigation;
exports.dropRequest = dropRequest;
exports.holdRequest = holdRequest;
exports.noteRequest = noteRequest;
exports.releaseRequest = releaseRequest;
exports.takeRequest = takeRequest;
//# sourceMappingURL=observe.cjs.map