import type { DelegateEvent } from 'delegate-it'; import type Swup from '../Swup.js'; import { Visit } from './Visit.js'; import type { FetchOptions, PageData } from './fetchPage.js'; export interface HookDefinitions { 'animation:out:start': undefined; 'animation:out:await': { skip: boolean; }; 'animation:out:end': undefined; 'animation:in:start': undefined; 'animation:in:await': { skip: boolean; }; 'animation:in:end': undefined; 'animation:skip': undefined; 'cache:clear': undefined; 'cache:set': { page: PageData; }; 'content:replace': { page: PageData; }; 'content:scroll': undefined; 'enable': undefined; 'disable': undefined; 'fetch:request': { url: string; options: FetchOptions; }; 'fetch:error': { url: string; status: number; response: Response; }; 'fetch:timeout': { url: string; }; 'history:popstate': { event: PopStateEvent; }; 'link:click': { el: HTMLAnchorElement; event: DelegateEvent; }; 'link:self': undefined; 'link:anchor': { hash: string; }; 'link:newtab': { href: string; }; 'page:load': { page?: PageData; cache?: boolean; options: FetchOptions; }; 'page:view': { url: string; title: string; }; 'scroll:top': { options: ScrollIntoViewOptions; }; 'scroll:anchor': { hash: string; options: ScrollIntoViewOptions; }; 'visit:start': undefined; 'visit:transition': undefined; 'visit:abort': undefined; 'visit:end': undefined; } export interface HookReturnValues { 'content:scroll': Promise | boolean; 'fetch:request': Promise; 'page:load': Promise; 'scroll:top': boolean; 'scroll:anchor': boolean; } export type HookArguments = HookDefinitions[T]; export type HookName = keyof HookDefinitions; export type HookNameWithModifier = `${HookName}.${HookModifier}`; type HookModifier = 'once' | 'before' | 'replace'; /** A generic hook handler. */ export type HookHandler = ( /** Context about the current visit. */ visit: Visit, /** Local arguments passed into the handler. */ args: HookArguments) => Promise | unknown; /** A default hook handler with an expected return type. */ export type HookDefaultHandler = ( /** Context about the current visit. */ visit: Visit, /** Local arguments passed into the handler. */ args: HookArguments, /** Default handler to be executed. Available if replacing an internal hook handler. */ defaultHandler?: HookDefaultHandler) => T extends keyof HookReturnValues ? HookReturnValues[T] : Promise | unknown; export type Handlers = { [K in HookName]: HookHandler[]; }; export type HookInitOptions = { [K in HookName as K | `${K}.${HookModifier}`]: HookHandler; } & { [K in HookName as K | `${K}.${HookModifier}.${HookModifier}`]: HookHandler; }; /** Unregister a previously registered hook handler. */ export type HookUnregister = () => void; /** Define when and how a hook handler is executed. */ export type HookOptions = { /** Execute the hook once, then remove the handler */ once?: boolean; /** Execute the hook before the internal default handler */ before?: boolean; /** Set a priority for when to execute this hook. Lower numbers execute first. Default: `0` */ priority?: number; /** Replace the internal default handler with this hook handler */ replace?: boolean; }; export type HookRegistration | HookDefaultHandler = HookHandler> = { id: number; hook: T; handler: H; defaultHandler?: HookDefaultHandler; } & HookOptions; type HookEventDetail = { hook: HookName; args: unknown; visit: Visit; }; export type HookEvent = CustomEvent; type HookLedger = Map, HookRegistration>; interface HookRegistry extends Map> { get(key: K): HookLedger | undefined; set(key: K, value: HookLedger): this; } /** * Hook registry. * * Create, trigger and handle hooks. * */ export declare class Hooks { /** Swup instance this registry belongs to */ protected swup: Swup; /** Map of all registered hook handlers. */ protected registry: HookRegistry; protected readonly hooks: HookName[]; constructor(swup: Swup); /** * Create ledgers for all core hooks. */ protected init(): void; /** * Create a new hook type. */ create(hook: string): void; /** * Check if a hook type exists. */ exists(hook: HookName): boolean; /** * Get the ledger with all registrations for a hook. */ protected get(hook: T): HookLedger | undefined; /** * Remove all handlers of all hooks. */ clear(): void; /** * Register a new hook handler. * @param hook Name of the hook to listen for * @param handler The handler function to execute * @param options Object to specify how and when the handler is executed * Available options: * - `once`: Only execute the handler once * - `before`: Execute the handler before the default handler * - `priority`: Specify the order in which the handlers are executed * - `replace`: Replace the default handler with this handler * @returns A function to unregister the handler */ on(hook: T, handler: HookDefaultHandler, options: O & { replace: true; }): HookUnregister; on(hook: T, handler: HookHandler, options: O): HookUnregister; on(hook: T, handler: HookHandler): HookUnregister; /** * Register a new hook handler to run before the default handler. * Shortcut for `hooks.on(hook, handler, { before: true })`. * @param hook Name of the hook to listen for * @param handler The handler function to execute * @param options Any other event options (see `hooks.on()` for details) * @returns A function to unregister the handler * @see on */ before(hook: T, handler: HookHandler, options: HookOptions): HookUnregister; before(hook: T, handler: HookHandler): HookUnregister; /** * Register a new hook handler to replace the default handler. * Shortcut for `hooks.on(hook, handler, { replace: true })`. * @param hook Name of the hook to listen for * @param handler The handler function to execute instead of the default handler * @param options Any other event options (see `hooks.on()` for details) * @returns A function to unregister the handler * @see on */ replace(hook: T, handler: HookDefaultHandler, options: HookOptions): HookUnregister; replace(hook: T, handler: HookDefaultHandler): HookUnregister; /** * Register a new hook handler to run once. * Shortcut for `hooks.on(hook, handler, { once: true })`. * @param hook Name of the hook to listen for * @param handler The handler function to execute * @param options Any other event options (see `hooks.on()` for details) * @see on */ once(hook: T, handler: HookHandler, options: HookOptions): HookUnregister; once(hook: T, handler: HookHandler): HookUnregister; /** * Unregister a hook handler. * @param hook Name of the hook the handler is registered for * @param handler The handler function that was registered. * If omitted, all handlers for the hook will be removed. */ off(hook: T, handler: HookHandler | HookDefaultHandler): void; off(hook: T): void; /** * Trigger a hook asynchronously, executing its default handler and all registered handlers. * Will execute all handlers in order and `await` any `Promise`s they return. * @param hook Name of the hook to trigger * @param visit The visit object this hook belongs to * @param args Arguments to pass to the handler * @param defaultHandler A default implementation of this hook to execute * @returns The resolved return value of the executed default handler */ call(hook: T, visit: Visit | undefined, args: HookArguments, defaultHandler?: HookDefaultHandler): Promise>>>; call(hook: T, args: HookArguments, defaultHandler?: HookDefaultHandler): Promise>>>; /** * Trigger a hook synchronously, executing its default handler and all registered handlers. * Will execute all handlers in order, but will **not** `await` any `Promise`s they return. * @param hook Name of the hook to trigger * @param visit The visit object this hook belongs to * @param args Arguments to pass to the handler * @param defaultHandler A default implementation of this hook to execute * @returns The (possibly unresolved) return value of the executed default handler */ callSync(hook: T, visit: Visit | undefined, args: HookArguments, defaultHandler?: HookDefaultHandler): ReturnType>; callSync(hook: T, args: HookArguments, defaultHandler?: HookDefaultHandler): ReturnType>; /** * Parse the call arguments for call() and callSync() to allow legacy argument order. */ protected parseCallArgs(hook: T, arg1: Visit | HookArguments | undefined, arg2: HookArguments | HookDefaultHandler, arg3?: HookDefaultHandler): [Visit | undefined, HookArguments, HookDefaultHandler | undefined]; /** * Execute the handlers for a hook, in order, as `Promise`s that will be `await`ed. * @param registrations The registrations (handler + options) to execute * @param args Arguments to pass to the handler */ protected run(registrations: HookRegistration>[], visit: Visit | undefined, args: HookArguments, rethrow: true): Promise>>[]>; protected run(registrations: HookRegistration[], visit: Visit | undefined, args: HookArguments): Promise; /** * Execute the handlers for a hook, in order, without `await`ing any returned `Promise`s. * @param registrations The registrations (handler + options) to execute * @param args Arguments to pass to the handler */ protected runSync(registrations: HookRegistration>[], visit: Visit | undefined, args: HookArguments, rethrow: true): ReturnType>[]; protected runSync(registrations: HookRegistration[], visit: Visit | undefined, args: HookArguments): unknown[]; /** * Get all registered handlers for a hook, sorted by priority and registration order. * @param hook Name of the hook * @param defaultHandler The optional default handler of this hook * @returns An object with the handlers sorted into `before` and `after` arrays, * as well as a flag indicating if the original handler was replaced */ protected getHandlers(hook: T, defaultHandler?: HookDefaultHandler): { found: boolean; before: HookRegistration>[]; handler: HookRegistration>[]; after: HookRegistration>[]; replaced: boolean; }; /** * Sort two hook registrations by priority and registration order. * @param a The registration object to compare * @param b The other registration object to compare with * @returns The sort direction */ protected sortRegistrations(a: HookRegistration, b: HookRegistration): number; /** * Dispatch a custom event on the `document` for a hook. Prefixed with `swup:` * @param hook Name of the hook. */ protected dispatchDomEvent(hook: T, visit: Visit | undefined, args?: HookArguments): void; /** * Parse a hook name into the name and any modifiers. * @param hook Name of the hook. */ parseName(hook: HookName | HookNameWithModifier): [HookName, Partial]; } export {}; //# sourceMappingURL=Hooks.d.ts.map