import { type Blocks } from "@peerbit/blocks-interface"; import type { Identity } from "@peerbit/crypto"; import type { Address } from "./address.js"; export declare const logger: import("@libp2p/interface").Logger; type ProgramMergeStrategy = "replace" | "reject" | "reuse"; export type TerminalOperation = "close" | "drop"; export type TerminalBaseCommit = { epoch: number; version: number; type: TerminalOperation; from?: Manageable; result: boolean; releasedParentReferences: number; }; export declare const TERMINAL_BASE_CHECKPOINT: unique symbol; export declare const TERMINAL_BASE_COMMIT: unique symbol; export declare const TERMINAL_BASE_RETRY: unique symbol; export declare const TERMINAL_OUTER_CLEANUP_RETAIN: unique symbol; export declare const TERMINAL_OUTER_CLEANUP_RELEASE: unique symbol; declare const TERMINAL_OPERATION_NOT_STARTED: unique symbol; /** * A terminal-operation precondition rejected the call before any lifecycle or * resource mutation began. Handler leaves the program retryable instead of * retaining this as partially completed cleanup. */ export declare class TerminalOperationNotStartedError extends Error { readonly [TERMINAL_OPERATION_NOT_STARTED] = true; constructor(message: string); static [Symbol.hasInstance](instance: unknown): boolean; } export type ExtractArgs = T extends CanOpen ? Args : never; export type EventOptions = { onBeforeOpen?: (program: Manageable) => Promise | void; onOpen?: (program: Manageable) => Promise | void; onDrop?: (program: Manageable) => Promise | void; onClose?: (program: Manageable) => Promise | void; }; export type OpenOptions>> = { timeout?: number; existing?: ProgramMergeStrategy; mode?: "auto" | "local" | "canonical"; } & ProgramInitializationOptions, T>; export type WithArgs = { args?: Args; }; export type WithParent = { parent?: T; }; export type Closeable = { closed: boolean; close(): Promise; }; type WithNode = { node: { identity: Identity; }; }; export type Addressable = { address: Address; }; export interface Saveable { save(store: Blocks, options?: { format?: string; timeout?: number; skipOnAddress?: boolean; save?: (address: string) => boolean | Promise; }): Promise
; delete(): Promise; } export type CanEmit = { emitEvent: (event: CustomEvent) => void; }; export type CanOpen = { beforeOpen: (client: any, options?: EventOptions) => Promise; open(args?: Args): Promise; afterOpen: () => Promise; }; export type Manageable = Closeable & Addressable & CanOpen & Saveable & CanEmit & { children: Manageable[]; parents: (Manageable | undefined)[]; /** * Programs with terminal work that must happen before `Program.end()` can * fence parent reuse while that work is in progress. */ readonly acceptsParentAttachments?: boolean; /** Base terminal tail/deletion that must be resumed with this operation. */ readonly pendingTerminalOperation?: TerminalOperation; /** A lifecycle callback must not recursively wait for Handler.stop(). */ readonly terminalLifecycleCallbackRunning?: boolean; [TERMINAL_BASE_CHECKPOINT]?: () => number; [TERMINAL_BASE_COMMIT]?: (afterVersion: number, type: TerminalOperation, from?: Manageable) => TerminalBaseCommit | undefined; [TERMINAL_BASE_RETRY]?: (commit: TerminalBaseCommit, operation: () => Promise) => Promise; [TERMINAL_OUTER_CLEANUP_RETAIN]?: () => object; [TERMINAL_OUTER_CLEANUP_RELEASE]?: (lease: object) => void; } & WithNode; export type ProgramInitializationOptions> = {} & WithArgs & WithParent & EventOptions; export declare const addParent: (child: Manageable, parent?: Manageable) => void; /** * Owns lifecycle state for one client. Handler instances do not share address * reservations, so a client must use a single Handler for a program graph. */ export declare class Handler> { readonly properties: { client: { services: { blocks: Blocks; }; stop: () => Promise; }; load: (address: Address, blocks: Blocks, options?: { timeout?: number; }) => Promise; shouldMonitor: (thing: any) => boolean; identity: Identity; getDependencies?: (program: T) => Manageable[]; }; items: Map; private _openQueue; private _openingPromises; private _openingReservations; private _openingReservationsByPromise; private _openingReservationsByAddress; private _parentAttachmentReservations; private _openAdmissions; private _openLifecycleCallbacks; private _terminalLifecycleCallbacks; private _lifecycleMethodInvocations; private _acceptingOpens; private _stopPromise?; private _lifecycleState; private _failedInitializations; private _cleanupResiduals; private _terminalOperationsByProgram; private _terminalOperationsByAddress; private _initializationRollbacks; private _replacementClosures; constructor(properties: { client: { services: { blocks: Blocks; }; stop: () => Promise; }; load: (address: Address, blocks: Blocks, options?: { timeout?: number; }) => Promise; shouldMonitor: (thing: any) => boolean; identity: Identity; getDependencies?: (program: T) => Manageable[]; }); /** * Re-open admissions after the owning client has finished starting all of the * services programs depend on. This is an internal client lifecycle hook, not * a substitute for starting the client itself. * * This is called by the owning client after its services have started. */ start(): void; /** Validate restart eligibility without opening admissions. */ assertCanStart(): void; /** * Stop the handler after admitted lifecycle work drains. * * Lifecycle overrides and callbacks must not await their own handler/client * stop. Immediate reentry is rejected. After user code has yielded, portable * JavaScript runtimes provide no reliable async-call provenance with which to * distinguish self-reentry from an unrelated external stop; schedule stop from * the lifecycle owner instead. A conservatively rejected external stop remains * retryable after the active callback finishes. */ stop(): Promise; /** * Async methods execute synchronously until their first await. Fence that * invocation window so a lifecycle override cannot make stop wait on the very * operation that is awaiting stop. Awaited user callbacks have their own wider * callback fences below. */ private invokeLifecycleMethod; /** * Program.end() can only observe the base implementation's lifetime. A * subclass is still free to do asynchronous cleanup after `super.close()` or * `super.drop()` has returned. Wrap the public, dynamically-dispatched method * on every managed instance so Handler state covers that full outer promise. */ private monitorTerminalOperations; private refreshTerminalOperationWrappers; private runTerminalOperation; private finishOuterTerminalCall; private sameTerminalArgs; private sameParents; private terminalCheckpoint; private terminalCommit; private retryCommittedTerminalCall; private addCleanupResidual; private reserveCleanupResidual; private acquireCleanupReservation; private releaseCleanupReservation; private releaseCleanupResidual; private releaseRetainedTerminalIdentity; private retryCleanupResidual; private finishTerminalOperation; private restoreTerminalOperations; private findMonitoredPrograms; private findMonitoredProgram; private attachExistingProgram; private assertNoTerminalOperation; private assertTerminalGraphCanStart; private waitForTerminalOperations; private closeCompletely; private removeReleasedParentChildReferences; private assertNoFailedInitialization; private stopOnce; private _onProgamClose; private closeForReplacement; private checkProcessExisting; private processParentExisting; private rollbackFailedInitialization; private dependencyGraph; private resolveDependencyAddresses; private cleanupFailedOpeningMonitoring; private releaseOpeningReservation; private reservationContains; private contributeOpeningParticipant; private mergeOpeningReservationGroups; private canShareOpeningReservation; private canOpenAlongsideReservation; private adoptOpeningReservation; private waitForOpeningConflictChange; private assertParentCanOwnOpen; private retainParentAttachment; private releaseParentAttachment; private isReservedNestedUse; private waitForOpeningReservations; private prepareOpeningGraph; private trackOpening; open(storeOrAddress: S | Address | string, options?: OpenOptions): Promise; private openAdmitted; } export {}; //# sourceMappingURL=handler.d.ts.map