import { type BoundMap, type Subscription } from "@knyt/artisan"; import type { LifecycleInterrupt } from "./LifecycleInterrupt.ts"; /** * An object that taps into the lifecycle of a host * * @remarks * * This is used to add lifecycle hooks to the host element. * Lifecycle hooks are methods that are called by the host * at specific points in the element's lifecycle, such as * before the element is updated. * * @beta */ export type LifecycleDelegate
= { /** * A method called by the host when the element is connected to the DOM, * before the element is rendered. * * @remarks * * This is not called during server-side rendering with Knyt Glazier, * as the host is not connected to the DOM in that case. * * If a custom server-side rendering implementation is used, * this method may be called if the host is connected to the DOM. */ hostBeforeMount?: LifecycleDelegate.BeforeMountHook; /** * A method called by the host when the host is mounted. * * @remarks * * This is the equivalent of the `connectedCallback` in a custom element, * and is called when the host is connected to the DOM. */ hostMounted?: LifecycleDelegate.MountedHook; /** * A method called by the host when the host is unmounted. * * @remarks * * This is the equivalent of the `disconnectedCallback` in a custom element, * and is called when the host is disconnected from the DOM. */ hostUnmounted?: LifecycleDelegate.UnmountedHook; /** * Called by the host before rendering a new declaration during an update. * * @remarks * * This hook runs after an update has started and just before a new declaration * is rendered, regardless of the host's connection to the DOM. * * Use this to perform setup or to abort the render if needed. If aborted, * the update cycle completes without rendering a new declaration or changing the DOM. * * This hook is invoked during both server-side and client-side rendering. * * It may be called multiple times before an actual update, such as when several * properties change quickly. Unlike the update itself, this hook is triggered * on every update request and is not debounced or throttled. As such, it should * be used for lightweight operations only. */ hostUpdateRequested?: LifecycleDelegate.UpdateRequestedHook
; /** * A method called by the host when an update is performed on the host. * * @remarks * * This is the equivalent of the `hostUpdate` in a reactive controller, * and is called when an update is performed on the host. */ hostBeforeUpdate?: LifecycleDelegate.BeforeUpdateHook
; /** * A method called by the host when the host is updated. * * @remarks * * This is the equivalent of the `hostUpdated` in a reactive controller, * and is called after the host is updated. */ hostAfterUpdate?: LifecycleDelegate.AfterUpdateHook
;
/**
* Called by the host when the element's lifecycle is interrupted.
*
* @remarks
*
* A lifecycle interruption occurs when the normal flow is halted by
* an external factor. An interruption is not an error, and is distinct
* from aborting an update or mount via an `AbortController`.
*
* Use this hook to perform cleanup or state changes in response to
* an interruption.
*
* Errors thrown here are forwarded to `hostErrorCaptured` handlers.
*/
hostInterrupted?: LifecycleDelegate.InterruptedHook = {
/**
* An `AbortController` that can be used to abort the update operation.
*
* @remarks
*
* This is useful for preventing a component from updating for any reason.
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortController | MDN: AbortController}
*/
abortController: AbortController;
/**
* The properties that have changed since the last update.
*/
changedProperties: BoundMap.Readonly ;
};
/**
* A lifecycle hook that is called by the host before an update
* is performed on the host.
*
* @remarks
*
* The hook may return a promise to indicate that the update
* should be delayed until the promise is resolved.
*/
type BeforeUpdateHook = {
(payload: BeforeUpdatePayload ): void | Promise = {
/**
* An `AbortController` that can be used to abort the update operation.
*
* @remarks
*
* This is useful for preventing a component from updating for any reason.
*
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AbortController | MDN: AbortController}
*/
abortController: AbortController;
/**
* The properties that have changed since the last update request.
*/
changedProperties: BoundMap.Readonly ;
};
/**
* A lifecycle hook that is called by the host
* before the host is updated.
*
* @remarks
*
* The hook may return a promise to indicate that the update should be delayed
* until the promise is resolved.
*/
type UpdateRequestedHook = {
(payload: UpdateRequestedPayload ): void | Promise = {
/**
* The properties that have changed during the last update.
*/
changedProperties: BoundMap.Readonly ;
};
/**
* A lifecycle hook that is called by the host when the host is updated.
*
* @remarks
*
* This is invoked before the `hostUpdated` hook in a reactive controllers.
*/
type AfterUpdateHook = {
(payload: AfterUpdatePayload ): void | Promise = {
/**
* Registers one or more lifecycle hooks to the host instance.
*
* @remarks
* This method allows you to attach a {@link LifecycleDelegate} object, which may implement
* any combination of lifecycle hook methods. The hooks will be invoked at the appropriate
* points in the host's lifecycle, such as before mounting, before updating, after mounting,
* after updating, on unmount, or when an error is captured.
*
* Multiple delegates can be registered; all registered hooks will be called in the order
* they were added. To remove previously registered hooks, use {@link removeDelegate}.
*
* @param input - The lifecycle delegate object containing one or more lifecycle hook methods.
* @see {@link LifecycleDelegate}
*/
addDelegate(input: LifecycleDelegate ): void;
/**
* Removes a previously registered lifecycle delegate from the host instance.
*
* @remarks
* This method detaches the specified {@link LifecycleDelegate} object, preventing its lifecycle
* hook methods from being invoked during the host's lifecycle events. If the delegate was not
* previously registered, this method has no effect.
*
* @param input - The lifecycle delegate object to remove.
* @see {@link addDelegate}
*/
removeDelegate(input: LifecycleDelegate ): void;
};
/**
* Determines whether the input is a {@link LifecycleDelegateHost}.
*
* @public
*/
export declare function isLifecycleDelegateHost(value: unknown): value is LifecycleDelegateHost;
/**
* A basic implementation of the {@link LifecycleDelegateHost} interface.
*
* @internal scope: package
*/
export declare class BasicLifecycleDelegateHost implements LifecycleDelegateHost {
#private;
/**
* Registers a lifecycle delegate to the host instance.
*/
addDelegate(hooks: LifecycleDelegate ): void;
/**
* Removes a previously registered lifecycle delegate from the host instance.
*/
removeDelegate(hooks: LifecycleDelegate ): void;
/**
* Removes all registered lifecycle delegates from the host.
*
* @remarks
*
* This is useful for cleaning up all delegates at once,
* for example when the host is being destroyed or reset.
*
* This method is used during hot module replacement.
*
* @internal scope: workspace
*/
clearDelegates(): void;
addLifecycleHook [K]): Subscription;
/**
* Performs the `hostBeforeMount` lifecycle method for all hooks.
*
* @remarks
*
* This method is called by the host when the element is connected to the DOM,
* before the element is rendered.
* It calls the `hostBeforeMount` method of all hooks in parallel,
* and waits for all of them to complete before returning.
*
* If any hook throws an error, the operation is aborted and the error
* is re-thrown to propagate to the caller.
*/
performBeforeMount(payload: LifecycleDelegate.BeforeMountPayload): void | Promise ): void | Promise ): void;
performAfterUpdate(payload: LifecycleDelegate.AfterUpdatePayload ): void;
performUnmounted(): void;
/**
* Synchronously handles an error that occurs during a lifecycle event.
* Each error handler registered via `onError` will be called in turn
* with the error that occurred.
*
* @returns `true` if the error was handled by at least one error handler
* `false` if the error was not handled by any error handler.
*/
handleError(error: unknown): boolean;
}
/**
* @internal scope: workspace
*/
export declare class LifecycleAdapter extends BasicLifecycleDelegateHost {
/**
* Registers a lifecycle hook to be called before the host is mounted.
*
* @param hostBeforeMount - The callback to invoke before mounting.
* @returns A subscription object that can be used to remove the hook.
*/
onBeforeMount(hostBeforeMount: LifecycleDelegate.BeforeMountHook): Subscription;
/**
* Registers a lifecycle hook to be called after the host is mounted to the DOM.
*
* @param hostMounted - The callback to invoke when the host is mounted.
* @returns A subscription object that can be used to remove the hook.
*/
onMounted(hostMounted: LifecycleDelegate.MountedHook): Subscription;
/**
* Registers a lifecycle hook to be called when an update is requested on the host.
*
* @param hostUpdateRequested - The callback to invoke before updating.
* @returns A subscription object that can be used to remove the hook.
*/
onUpdateRequested(hostUpdateRequested: LifecycleDelegate.UpdateRequestedHook ): Subscription;
/**
* Registers a lifecycle hook to be called before an update is performed on the host.
*
* @param hostBeforeUpdate - The callback to invoke when an update is performed.
* @returns A subscription object that can be used to remove the hook.
*/
onBeforeUpdate(hostBeforeUpdate: LifecycleDelegate.BeforeUpdateHook ): Subscription;
/**
* Registers a lifecycle hook to be called after the host has been updated.
*
* @param hostAfterUpdate - The callback to invoke after the host update is complete.
* @returns A subscription object that can be used to remove the hook.
*/
onAfterUpdate(hostAfterUpdate: LifecycleDelegate.AfterUpdateHook ): Subscription;
/**
* Registers a lifecycle hook to be called when the host's lifecycle is interrupted.
*
* @param hostInterrupted - The callback to invoke when the host's lifecycle is interrupted.
* @returns A subscription object that can be used to remove the hook.
*/
onInterrupted(hostInterrupted: LifecycleDelegate.InterruptedHook