Import
import { makeNavigationCore } from "@typed/navigation";Signatures
export declare const makeNavigationCore: (origin: string, base: string, state: RefSubject.RefSubject<NavigationState, never, never>, commit: (before: BeforeNavigationEvent, runHandlers: (destination: Destination) => Effect.Effect<void>) => Effect.Effect<Destination, NavigationError>) => Effect.Effect<{
origin: string;
base: string;
entries: RefSubject.Computed<readonly {
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}[], never, never>;
currentEntry: RefSubject.Computed<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, never, never>;
transition: RefSubject.Filtered<{
readonly type: "push" | "replace" | "reload" | "traverse";
readonly from: {
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
};
readonly to: {
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
readonly key?: string | undefined;
};
readonly info?: unknown;
}, never, never>;
canGoBack: RefSubject.Computed<boolean, never, never>;
canGoForward: RefSubject.Computed<boolean, never, never>;
navigate: (pathOrUrl: string | URL, options?: NavigationNavigateOptions | undefined) => Effect.Effect<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, NavigationError, never>;
back: (options?: {
readonly info?: unknown;
} | undefined) => Effect.Effect<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, NavigationError, never>;
forward: (options?: {
readonly info?: unknown;
} | undefined) => Effect.Effect<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, NavigationError, never>;
traverseTo: (key: string, options?: {
readonly info?: unknown;
} | undefined) => Effect.Effect<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, NavigationError, never>;
reload: (options?: NavigationReloadOptions | undefined) => Effect.Effect<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, NavigationError, never>;
onBeforeNavigation: <R = never, R2 = never>(handler: BeforeNavigationHandler<R, R2>) => Effect.Effect<void, never, R | R2 | Scope.Scope>;
onNavigation: <R = never, R2 = never>(handler: NavigationHandler<R, R2>) => Effect.Effect<void, never, R | R2 | Scope.Scope>;
updateCurrentEntry: (options: {
readonly state: unknown;
}) => Effect.Effect<{
readonly id: string;
readonly key: string;
readonly url: URL;
readonly state: unknown;
readonly sameDocument: boolean;
}, NavigationError, never>;
}, never, Scope.Scope>;Why
Browser and memory providers must agree on ordering: publish the transition, run before handlers sequentially, follow redirect/cancel control flow, commit, update state, clear the transition, then run post-commit handlers. Centralizing that protocol prevents backend drift.
Ownership and lifetime
The calling Layer owns the supplied state and returned service. Handler registration captures its
Effect context and unregisters when its Scope closes. Redirects are capped at ten; malformed URLs,
backend failures, and redirect cycles surface as NavigationError. Interruption clears a still-
current transition through normal Effect cleanup.
Examples
import { makeNavigationCore, type NavigationState } from "@typed/navigation/_core"
import type { RefSubject } from "@typed/fx"
import * as Effect from "effect/Effect"
import type { BeforeNavigationEvent, Destination } from "@typed/navigation/model"
declare const state: RefSubject.RefSubject<NavigationState>
declare const commit: (
event: BeforeNavigationEvent,
runHandlers: (destination: Destination) => Effect.Effect<void>
) => Effect.Effect<Destination, never>
const NavigationLive = makeNavigationCore("https://example.com", "/", state, commit)Other public imports
These import paths expose the same declaration. Each page retains its own public name and signature.