/** * WeakMap-backed activity registry. * * Metadata is keyed to function references in a WeakMap so that lookup by * function reference is O(1). A separate name index (plain Map) holds strong * references to registered functions, keeping them alive until explicitly * unregistered. When a function is unregistered, removing it from the name * index releases the strong reference and allows the WeakMap entry to be * collected. * * @module core/activity-registry */ import { type DefinitionSchema, type Duration, type RetryPolicy } from './types.ts'; /** * Metadata stored per-activity, keyed to the function reference in a WeakMap. * * @example * ```ts * import { ActivityRegistry, type ActivityMetadata } from '@lostgradient/weft'; * * const registry = new ActivityRegistry(); * const fn = async (input: unknown) => ({ result: input }); * registry.register('processOrder', fn, { queue: 'orders', timeout: '30s' }); * * const meta: ActivityMetadata | undefined = registry.getMetadata(fn); * console.log(meta?.name); // 'processOrder' * console.log(meta?.queue); // 'orders' * ``` */ export interface ActivityMetadata { /** Registered activity name. */ name: string; /** Queue used for activity dispatch. */ queue: string; /** User-facing description for catalog, code generation, and tool surfaces. */ description?: string; /** User-facing grouping tags for catalog and documentation surfaces. */ tags?: ReadonlyArray; /** Optional input schema metadata for introspection; core execution does not validate input against it. */ inputSchema?: DefinitionSchema; /** Optional output schema metadata for introspection; core execution does not validate output against it. */ outputSchema?: DefinitionSchema; /** Retry policy used when the activity fails. */ retry?: RetryPolicy; /** Activity execution timeout. */ timeout?: Duration; /** Whether the activity can be safely repeated. */ idempotent?: boolean; } /** * Optional overrides when registering an activity. * * @example * ```ts * import { ActivityRegistry, type ActivityRegistrationOptions } from '@lostgradient/weft'; * * const options: ActivityRegistrationOptions = { * queue: 'high-priority', * timeout: '60s', * idempotent: true, * }; * * const registry = new ActivityRegistry(); * const fn = async (input: unknown) => input; * registry.register('sendNotification', fn, options); * ``` */ export interface ActivityRegistrationOptions { /** Queue used for activity dispatch. */ queue?: string; /** User-facing description for catalog, code generation, and tool surfaces. */ description?: string; /** User-facing grouping tags for catalog and documentation surfaces. */ tags?: ReadonlyArray; /** Optional input schema metadata for introspection; registration validates metadata shape only. */ inputSchema?: DefinitionSchema; /** Optional output schema metadata for introspection; registration validates metadata shape only. */ outputSchema?: DefinitionSchema; /** Retry policy used when the activity fails. */ retry?: RetryPolicy; /** Activity execution timeout. */ timeout?: Duration; /** Whether the activity can be safely repeated. */ idempotent?: boolean; } export type RegisteredActivityFunction = (input?: unknown, context?: unknown) => unknown; export declare function copyActivityMetadata(metadata: ActivityMetadata): ActivityMetadata; /** * WeakMap-backed registry mapping activity names to their execute functions * and metadata. Used internally by the {@link Engine} to dispatch activities * by name. Call `engine.register(activityDefinition)` rather than * constructing an `ActivityRegistry` directly — the engine manages the * registry lifecycle. * * @example * ```ts * import { ActivityRegistry } from '@lostgradient/weft'; * * const registry = new ActivityRegistry(); * const fn = async (input: unknown) => ({ result: input }); * registry.register('processOrder', fn, { queue: 'orders', timeout: '30s' }); * * const meta = registry.getMetadata(fn); * console.log(meta?.name); // 'processOrder' * console.log(meta?.queue); // 'orders' * ``` */ export declare class ActivityRegistry { #private; constructor(); /** * Register an activity function with associated metadata. * * If `fn` was created via the `activity()` helper, metadata is * auto-extracted from its colocated properties. Explicit `options` * take precedence over auto-extracted values. */ register(name: string, fn: Function, options?: ActivityRegistrationOptions): void; /** Check whether an activity is registered under the given name. */ has(name: string): boolean; /** Resolve a function by its registered name. Returns `undefined` if not found. */ resolve(name: string): RegisteredActivityFunction | undefined; /** Get metadata for a function reference. Returns `undefined` if the function was never registered. */ getMetadata(fn: Function): ActivityMetadata | undefined; /** Get metadata by registered activity name. */ getMetadataByName(name: string): ActivityMetadata | undefined; /** Get catalog metadata for a registered activity name. */ getDefinition(name: string): ActivityMetadata | undefined; /** List catalog metadata for all registered activity names. */ listDefinitions(): ActivityMetadata[]; /** Remove an activity registration by name. */ unregister(name: string): void; /** Iterate over all registered activity names. */ names(): IterableIterator; }