import { ArgsOf } from '@typed/lambda' import { createSubscription, Subscription } from '@typed/subscription' import { HistoryEnv } from './types' export function wrapInSubscription( historyEnv: HistoryEnv, ): HistoryEnv & { readonly subscription: Subscription> } { const subscription = createSubscription>() const history = wrapHistory(historyEnv, subscription) return { ...historyEnv, history, subscription, } } function wrapHistory( { history, location }: HistoryEnv, subscription: Subscription, ): History { const pushState = (...args: ArgsOf) => { history.pushState(...args) onChange() } const replaceState = (...args: ArgsOf) => { history.replaceState(...args) onChange() } const back = () => { history.back() onChange() } const forward = () => { history.forward() onChange() } const go = (amount: number) => { history.go(amount) onChange() } const updatedHistory = { pushState, replaceState, back, forward, go, get length() { return history.length }, set scrollRestoration(mode: History['scrollRestoration']) { history.scrollRestoration = mode }, get scrollRestoration() { return history.scrollRestoration }, get state() { return history.state }, } function onChange() { subscription.publish({ history: updatedHistory, location }) } return updatedHistory }