@tanstack/solid-router
Version:
Modern and scalable routing for Solid applications
96 lines • 3.23 kB
JSX
import * as Solid from 'solid-js';
import { getLocationChangeInfo, trimPathRight } from '@tanstack/router-core';
import { isServer } from '@tanstack/router-core/isServer';
import { useRouter } from './useRouter';
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;
}
return;
}
export function Transitioner() {
const router = useRouter();
if (isServer ?? router.isServer) {
return null;
}
let settleCurrent;
router.startTransition = (fn) => {
settleCurrent?.(false);
return new Promise((resolve, reject) => {
const settle = (rendered) => {
if (settleCurrent !== settle) {
return;
}
settleCurrent = undefined;
resolve(rendered);
};
const fail = (cause) => {
if (settleCurrent !== settle) {
return;
}
settleCurrent = undefined;
reject(cause);
};
settleCurrent = settle;
void Solid.startTransition(() => {
// A newer publication may supersede this deferred callback.
if (settleCurrent === settle) {
try {
fn();
}
catch (cause) {
fail(cause);
}
}
}).then(() => settle(true), fail);
});
};
Solid.onCleanup(() => {
settleCurrent?.(false);
});
// Subscribe to location changes
// and try to load the new location
Solid.onMount(() => {
Solid.onCleanup(router.history.subscribe(router.load));
const nextLocation = router.buildLocation({
to: router.latestLocation.pathname,
search: true,
params: true,
hash: true,
state: true,
_includeValidateSearch: true,
});
// Check if the current URL matches the canonical form.
// Compare publicHref (browser-facing URL) consistently with server
// canonicalization.
if (trimPathRight(router.latestLocation.publicHref) !==
trimPathRight(nextLocation.publicHref)) {
router.commitLocation({
...nextLocation,
replace: true,
ignoreBlocker: true,
});
return;
}
if (!getResolvedLocation(router) && !router._tx) {
router.load().catch(console.error);
}
});
return null;
}
export function Rendered() {
const router = useRouter();
Solid.onMount(() => {
const resolvedLocation = getResolvedLocation(router);
if (resolvedLocation) {
router.emit({
type: 'onRendered',
...getLocationChangeInfo(resolvedLocation, resolvedLocation),
});
}
});
return null;
}
//# sourceMappingURL=Transitioner.jsx.map