/** * vapor-chamber - Command Bus for Vue Vapor * ~3.6 KB brotli core; full bundle ~10-20 KB depending on imports (see * docs/BUNDLE-SIZES.md) — DevTools loaded dynamically */ /** * Severity level for bus diagnostics. * - `'error'`: dispatch failed, result.ok === false * - `'warn'`: recoverable issue, dispatch may succeed (e.g. naming violation) * - `'info'`: informational (e.g. handler overwrite, circuit breaker state change) */ export type BusSeverity = 'error' | 'warn' | 'info'; /** * Emitter tag — which subsystem produced the diagnostic. * Allows filtering/routing in logging and monitoring. */ export type BusEmitter = 'core' | 'plugin' | 'hook' | 'listener' | 'transport' | 'form' | 'schema' | 'workflow' | 'test'; /** * Structured error code enum. Every error in vapor-chamber has a unique code. * * Naming: `VC_{EMITTER}_{DESCRIPTION}` — VC = vapor-chamber prefix. * * @example * if (result.error instanceof BusError) { * switch (result.error.code) { * case 'VC_CORE_NO_HANDLER': // register a handler * case 'VC_CORE_BEFORE_CANCEL': // a beforeHook threw * case 'VC_PLUGIN_CIRCUIT_OPEN': // circuit breaker tripped * } * } */ export type BusErrorCode = 'VC_CORE_NO_HANDLER' | 'VC_CORE_HANDLER_THREW' | 'VC_CORE_BEFORE_CANCEL' | 'VC_CORE_NAMING_VIOLATION' | 'VC_CORE_HANDLER_OVERWRITE' | 'VC_CORE_REQUEST_TIMEOUT' | 'VC_CORE_THROTTLED' | 'VC_CORE_MAX_DEPTH' | 'VC_CORE_SEALED' | 'VC_CORE_ABORTED' | 'VC_PLUGIN_CIRCUIT_OPEN' | 'VC_PLUGIN_RATE_LIMITED' | 'VC_PLUGIN_CACHE_MISS' | 'VC_VALIDATION_FAILED' | 'VC_WORKFLOW_STEP_FAILED' | 'VC_WORKFLOW_COMPENSATE_FAILED' | 'VC_HOOK_ERROR' | 'VC_LISTENER_ERROR' | 'VC_UNKNOWN'; /** * BusError — structured error with machine-readable code, severity, and emitter. * * Extends native Error so it works everywhere errors work (catch, result.error, etc.). * The `code` field enables switch-based handling, the `severity` enables log filtering, * and the `emitter` enables source-based routing. * * @example * const result = bus.dispatch('missing', {}); * if (!result.ok && result.error instanceof BusError) { * console.log(result.error.code); // 'VC_CORE_NO_HANDLER' * console.log(result.error.severity); // 'error' * console.log(result.error.emitter); // 'core' * console.log(result.error.action); // 'missing' * } */ export declare class BusError extends Error { /** Machine-readable error code for switch/lookup. */ readonly code: BusErrorCode; /** Severity: error, warn, or info. */ readonly severity: BusSeverity; /** Which subsystem produced this error. */ readonly emitter: BusEmitter; /** The action name involved (if applicable). */ readonly action?: string; /** Additional context (e.g. retryIn for throttle, threshold for circuit breaker). */ readonly context?: Record; constructor(code: BusErrorCode, message: string, opts?: { severity?: BusSeverity; emitter?: BusEmitter; action?: string; context?: Record; cause?: Error; }); } /** * BusError codes that mark transient failures — safe to retry. * * Deliberately a tiny standalone set (not a registry lookup): the full * ERROR_CODE_REGISTRY lives in the schema/LLM layer, which retry() consumers * must not pull into their bundles. tests/schema.test.ts asserts this set * stays in sync with the registry's `retryable: true` entries. * * @example * if (result.error instanceof BusError && RETRYABLE_CODES.has(result.error.code)) { * // transient — safe to re-dispatch * } */ export declare const RETRYABLE_CODES: ReadonlySet; /** Automatic metadata stamped on every command. */ export type CommandMeta = { /** Monotonic timestamp (Date.now()) at dispatch time. */ ts: number; /** Unique command ID (crypto.randomUUID or fallback). */ id: string; /** ID of the command that caused this one (set manually via payload.__causationId). */ causationId?: string; /** Correlation ID for tracing a chain of commands (propagates from parent). */ correlationId?: string; /** * Idempotency key stamped by the `idempotent` plugin. Transports (e.g. the * HTTP bridge) forward it as an `Idempotency-Key` header so the backend can * reject duplicate writes. Not set by default — only when `idempotent` runs. */ idempotencyKey?: string; /** * Where the command originated. `undefined` (the default) means local user * code called dispatch directly. The core never sets this field — dispatchers * that proxy external traffic (bridges, sync layers, replay tooling, agent * endpoints) stamp it post-hoc via plugins so downstream plugins, hooks, and * listeners can distinguish local intent from mirrored or machine-driven * commands (e.g. skip re-broadcasting a `'sync'` command, or audit-log * everything marked `'agent'`). * * Well-known values: `'user'`, `'remote'`, `'sync'`, `'replay'`, `'agent'` — * but any string is accepted for custom origins. * * @example * bus.use((cmd, next) => { * if (cmd.meta?.origin === 'agent') console.info('LLM-driven:', cmd.action); * return next(); * }); */ origin?: 'user' | 'remote' | 'sync' | 'replay' | 'agent' | (string & {}); }; export type Command = { action: A; target: T; payload?: P; /** Auto-stamped metadata — timestamp, unique id, correlation/causation tracing. * Always present on commands from dispatch/query/emit. Optional on manually constructed commands. */ meta?: CommandMeta; /** * AbortSignal forwarded by `bus.dispatch(..., { signal })`. Async handlers * may listen to `cmd.signal.aborted` / `cmd.signal.addEventListener('abort', ...)` * to short-circuit work; transport plugins (HTTP) auto-propagate it to the * underlying fetch / xhr. Sync bus paths ignore this field — sync dispatch * is atomic and not cancelable. */ signal?: AbortSignal; }; /** Optional per-dispatch options. Currently: `{ signal }` for cancellation. */ export type DispatchOptions = { /** Abort the dispatch before it starts (if already aborted) or signal async * handlers and transports to cancel mid-flight. Async bus only. */ signal?: AbortSignal; }; /** * Result of a dispatch/query — a discriminated union on `ok`. * * `if (result.ok)` narrows away `error`; on the failure arm `error` is a * guaranteed `Error` (no `!` or `?.` needed). `value` stays optional on the * success arm because void commands legitimately produce no value. */ export type CommandResult = { ok: true; value?: V; error?: undefined; } | { ok: false; error: Error; value?: undefined; }; export type Handler = (cmd: Command) => R; export type AsyncHandler = (cmd: Command) => Promise; export type Plugin = (cmd: Command, next: () => CommandResult) => CommandResult; export type AsyncPlugin = (cmd: Command, next: () => CommandResult | Promise) => CommandResult | Promise; export type Hook = (cmd: Command, result: CommandResult) => void; export type AsyncHook = (cmd: Command, result: CommandResult) => void | Promise; /** Fires before the handler runs. Throw to cancel the dispatch (returns `{ ok: false }`). */ export type BeforeHook = (cmd: Command) => void; /** Fires before the handler runs on an async bus. Throw or reject to cancel. */ export type AsyncBeforeHook = (cmd: Command) => void | Promise; /** Options for plugin registration. Higher priority runs first (outermost). Default: 0. */ export type PluginOptions = { priority?: number; }; /** Batch dispatch input */ export type BatchCommand = { action: string; target: any; payload?: any; }; /** Options for batch dispatch */ export type BatchOptions = { continueOnError?: boolean; /** * All-or-nothing semantics: if any command fails, automatically run the * registered undo handler for every command that already succeeded (in reverse order). * Requires undo handlers to be registered via `register(action, handler, { undo })`. * Commands without an undo handler are skipped during rollback. * Mutually exclusive with `continueOnError`. */ transactional?: boolean; /** * AbortSignal applied to the whole batch. Aborting before the batch starts * skips it entirely; aborting mid-flight stops further commands from * dispatching (the in-flight one runs to completion since per-command * abort already happened or is the handler's responsibility) and the * batch result is `{ ok: false, error: AbortError, results: [...partial] }`. * Async bus only — sync `dispatchBatch` accepts the option for type * uniformity but ignores it. */ signal?: AbortSignal; }; /** Result of a batch dispatch */ export type BatchResult = { ok: boolean; results: CommandResult[]; error?: Error; /** Number of commands that completed successfully */ successCount: number; /** Number of commands that failed */ failCount: number; /** Results of undo handlers run during transactional rollback (reverse order). Only present when `transactional: true` and a command failed. */ rollbacks?: CommandResult[]; }; /** * Dead letter mode — what to do when a command has no registered handler. * - `'error'` (default): returns `{ ok: false, error }` * - `'throw'`: throws the error * - `'ignore'`: returns `{ ok: true, value: undefined }` * - `'buffer'`: queue the command (per action, FIFO) and replay it — in order — * the moment a handler for that action is `register()`-ed. Built for * lazy/async wiring where a command can be dispatched before its handler * exists (e.g. Astro/island hydration, code-split panels): the click isn't * lost, it fires when the handler arrives. The synchronous dispatch returns * `{ ok: true, value: undefined }` (the real handler runs later). `query` * never buffers (it must return a value) — it falls back to `'error'`. * Bounded by `bufferLimit` (drop-oldest + dev warning on overflow). * - function: called with the command, return value used as result */ export type DeadLetterMode = 'error' | 'throw' | 'ignore' | 'buffer' | ((cmd: Command) => CommandResult); /** * Naming convention configuration. * Enforces a regex pattern on action names at register and dispatch time. */ export type NamingConvention = { /** Regex pattern that action names must match */ pattern: RegExp; /** What to do on violation: 'warn' logs, 'throw' throws, 'ignore' skips */ onViolation?: 'warn' | 'throw' | 'ignore'; }; /** Per-command registration options */ export type RegisterOptions = { /** Throttle this handler: execute immediately, then block for N ms. */ throttle?: number; /** Inverse handler for undo support. Called with the original command. */ undo?: Handler; }; export type CommandBusOptions = { onMissing?: DeadLetterMode; /** Enforce naming convention on action names */ naming?: NamingConvention; /** * Max commands buffered per action when `onMissing: 'buffer'`. When exceeded, * the oldest queued command for that action is dropped (with a dev warning). * Default: 256. */ bufferLimit?: number; /** * Max age (ms) a buffered command may wait for its handler when * `onMissing: 'buffer'`. Expired entries are reaped lazily — on the next * buffer push for that action and at flush time — so a handler that never * arrives (e.g. an island that fails to hydrate) cannot pin stale commands * in memory indefinitely. Default: no TTL (entries wait until `bufferLimit` * pushes them out). */ bufferTTL?: number; /** * Called when `onMissing: 'buffer'` drops a queued command — either because * the per-action queue hit `bufferLimit` (oldest dropped) or because the * entry outlived `bufferTTL`. Use for observability: without this, drops are * only visible as dev-mode console warnings. */ onBufferOverflow?: (action: string, dropped: { target: any; payload: any; }) => void; }; /** Listener callback for on() subscriptions (wildcard-capable) */ export type Listener = (cmd: Command, result: CommandResult) => void; /** * Typed command map — define action names, target, payload, and result shapes. * Use with createCommandBus() for type-safe dispatch and register. * * @example * type AppCommands = { * cartAdd: { target: { id: number }; payload: { qty: number }; result: void }; * cartClear: { target: {}; result: number }; * }; * const bus = createCommandBus(); * bus.dispatch('cartAdd', { id: 1 }, { qty: 2 }); // fully typed */ export type CommandMap = Record; /** Extract the target type for action A from a CommandMap. Used in typed bus interfaces. */ export type TargetOf = M[A] extends { target: infer T; } ? T : any; /** Extract the payload type for action A from a CommandMap. */ export type PayloadOf = M[A] extends { payload: infer P; } ? P : any; /** Extract the result type for action A from a CommandMap. */ export type ResultOf = M[A] extends { result: infer R; } ? R : any; /** * Structural base interface for both sync and async buses. * Use this as the parameter type in utilities (createChamber, createWorkflow, etc.) * to avoid `as any` casts when working with either bus variant. */ export interface BaseBus { dispatch(action: string, target: any, payload?: any, options?: DispatchOptions): any; /** Read-only dispatch — skips beforeHooks, runs handler + plugins, fires afterHooks. No mutation intent. */ query(action: string, target: any, payload?: any): any; /** Fire a domain event — notifies on() listeners, no handler required, no result returned. */ emit(event: string, data?: any): void; register(action: string, handler: any, options?: RegisterOptions): () => void; use(plugin: any, options?: PluginOptions): () => void; /** Subscribe before dispatch. Throw to cancel (returns `{ ok: false }`). */ onBefore(hook: any): () => void; onAfter(hook: any): () => void; on(pattern: string, listener: Listener): () => void; once(pattern: string, listener: Listener): () => void; /** Remove all `on()` listeners matching the given pattern, or all listeners if omitted. */ offAll(pattern?: string): void; hasHandler(action: string): boolean; /** Returns all registered action names. Useful for introspection and DevTools. */ registeredActions(): string[]; clear(): void; /** Full teardown — calls clear() and cancels all pending timers/requests. Use in SSR or component-scoped buses. */ dispose(): void; /** * Seal the bus — prevents further register(), use(), onBefore(), onAfter(), respond() calls. * Dispatch, query, emit, on(), once() still work — seal protects the handler/plugin topology, * not the observation layer. Listeners via on()/once() can still subscribe after seal. * Call after app initialization to lock down the graph in production. Throws BusError * with code 'VC_CORE_SEALED' on any mutation attempt. Cleared by clear() for HMR compat. */ seal(): void; /** Returns true if the bus has been sealed. */ isSealed(): boolean; } export interface CommandBus extends BaseBus { /** * Sync dispatch. The optional `options.signal` is accepted for type * compatibility with `AsyncCommandBus` but **ignored at runtime** — sync * dispatches are atomic and not cancelable. Pass a signal here only if * you also use the async bus and want a uniform call site. */ dispatch(action: A, target: TargetOf, payload?: PayloadOf, options?: DispatchOptions): CommandResult>; /** Read-only dispatch — skips beforeHooks (no mutation gating), runs handler + plugins, fires afterHooks. */ query(action: A, target: TargetOf, payload?: PayloadOf): CommandResult>; /** Fire a domain event — notifies on() listeners, no handler required, no result. */ emit(event: string, data?: any): void; dispatchBatch(commands: BatchCommand[], options?: BatchOptions): BatchResult; register(action: A, handler: (cmd: Command, PayloadOf>) => ResultOf, options?: RegisterOptions): () => void; use(plugin: Plugin, options?: PluginOptions): () => void; /** Subscribe before dispatch. Throw to cancel — dispatch returns `{ ok: false }`. */ onBefore(hook: BeforeHook): () => void; onAfter(hook: Hook): () => void; on(pattern: string, listener: Listener): () => void; /** Subscribe to the first matching command only; auto-unsubscribes after it fires. */ once(pattern: string, listener: Listener): () => void; offAll(pattern?: string): void; request(action: A, target: TargetOf, payload?: PayloadOf, options?: { timeout?: number; signal?: AbortSignal; }): Promise>>; respond(action: string, handler: (cmd: Command) => any | Promise): () => void; /** Returns true if a handler is registered for the given action. */ hasHandler(action: string): boolean; /** Returns all registered action names. */ registeredActions(): string[]; /** * @internal Used by the history plugin to retrieve an undo handler registered alongside * a command handler. Do not call this from application code — it will be moved to a * plugin-private channel in a future release. */ getUndoHandler(action: string): Handler | undefined; /** Remove all handlers, plugins, hooks, and listeners. Useful for testing and HMR. */ clear(): void; /** Freeze configuration — rejects register/use/clear after sealing. */ seal(): void; /** Returns true if the bus is sealed. */ isSealed(): boolean; /** Clean teardown — clears state, cancels timers, marks bus as disposed. */ dispose(): void; } export interface AsyncCommandBus extends BaseBus { /** * Async dispatch with optional `AbortSignal`. If `options.signal` is already * aborted at call time, resolves immediately with `{ ok: false, error: AbortError }` * without invoking the handler. If aborted mid-flight, the handler observes * `cmd.signal.aborted === true`; HTTP transport plugins propagate the signal * to the underlying fetch automatically. */ dispatch(action: A, target: TargetOf, payload?: PayloadOf, options?: DispatchOptions): Promise>>; /** Read-only dispatch — skips beforeHooks (no mutation gating), runs handler + plugins, fires afterHooks. */ query(action: A, target: TargetOf, payload?: PayloadOf): Promise>>; /** Fire a domain event — notifies on() listeners, no handler required, no result. */ emit(event: string, data?: any): void; dispatchBatch(commands: BatchCommand[], options?: BatchOptions): Promise; register(action: A, handler: (cmd: Command, PayloadOf>) => Promise>, options?: RegisterOptions): () => void; use(plugin: AsyncPlugin, options?: PluginOptions): () => void; /** Subscribe before dispatch. Throw or reject to cancel — dispatch returns `{ ok: false }`. */ onBefore(hook: AsyncBeforeHook): () => void; onAfter(hook: AsyncHook): () => void; on(pattern: string, listener: Listener): () => void; /** Subscribe to the first matching command only; auto-unsubscribes after it fires. */ once(pattern: string, listener: Listener): () => void; offAll(pattern?: string): void; request(action: A, target: TargetOf, payload?: PayloadOf, options?: { timeout?: number; signal?: AbortSignal; }): Promise>>; respond(action: string, handler: (cmd: Command) => any | Promise): () => void; /** Returns true if a handler is registered for the given action. */ hasHandler(action: string): boolean; /** Returns all registered action names. */ registeredActions(): string[]; /** * @internal Used by the history plugin to retrieve an undo handler registered alongside * a command handler. Do not call this from application code — it will be moved to a * plugin-private channel in a future release. */ getUndoHandler(action: string): Handler | undefined; /** Remove all handlers, plugins, hooks, and listeners. Useful for testing and HMR. */ clear(): void; /** Freeze configuration — rejects register/use/clear after sealing. */ seal(): void; /** Returns true if the bus is sealed. */ isSealed(): boolean; /** Clean teardown — clears state, cancels timers, marks bus as disposed. */ dispose(): void; } /** * Swap the unique-ID generator. Call once at app setup if you need a different * format (e.g. `crypto.randomUUID` for distributed tracing). * * @example * import { configureUid } from 'vapor-chamber'; * configureUid(() => crypto.randomUUID()); */ export declare function configureUid(fn: () => string): void; export declare function matchesPattern(pattern: string, action: string): boolean; /** * Run every collected disposer in insertion order, then empty the list so a * second call is a no-op (idempotent teardown). Shared by the composables' * `dispose()` and the chamber/install + history-plugin cleanups. Cold path * (runs at unmount/disposal, never per dispatch) — a plain loop, no closure. * * No try/catch by design — settled, do not "harden". Every disposer collected * here is an internal `register`/`on`/`use`/`respond` unsub (`Map.delete` / * `Array.splice`); none can throw. A throw would mean corrupted internal state, * which should surface loudly during teardown, not be swallowed. */ export declare function disposeAll(fns: Array<() => void>): void; /** * Stable string key for a (action, target) pair. Handles circular refs safely. * Useful for cache invalidation integration (e.g. TanStack Query). */ export declare function commandKey(action: string, target: any): string; /** * CommandPool — pre-allocates Command objects in a circular buffer to * eliminate garbage collection pauses during dispatch bursts. When the * pool is exhausted, it wraps around and reuses the oldest slot. * * **Important**: The pool is a standalone utility — `bus.dispatch()` still * creates its own Command internally and stamps `meta` (ts, id, correlationId). * Pooled commands do NOT have `meta` set. Use `pool.acquire()` for the action/target/payload, * then pass those values to `bus.dispatch(cmd.action, cmd.target, cmd.payload)`. * The bus will create its own internal command with proper metadata. * * Thread-safety note: single-threaded JS means no locking required. * * @example * const pool = createCommandPool(64); * const cmd = pool.acquire('cartAdd', cart, { id: 1 }); * bus.dispatch(cmd.action, cmd.target, cmd.payload); // bus stamps its own meta * * pool.stats(); // { size: 64, acquired: 1, cursor: 1 } * pool.reset(); // Reset cursor and clear all slots */ export interface CommandPool { /** Acquire a command object from the pool. Reuses slots in a circular fashion. */ acquire(action: string, target: any, payload?: any): Command; /** Current pool statistics. */ stats(): { size: number; acquired: number; cursor: number; }; /** Reset the pool — clears all slots and resets cursor. */ reset(): void; /** Pool capacity. */ readonly size: number; } export declare function createCommandPool(size?: number): CommandPool; export declare function buildRunner(plugins: Plugin[]): (cmd: Command, execute: () => CommandResult) => CommandResult; /** * Create a synchronous command bus. * * @example * // Basic usage * const bus = createCommandBus(); * bus.register('cart/add', (cmd) => addToCart(cmd.target, cmd.payload)); * const result = bus.dispatch('cart/add', { id: 1 }, { qty: 2 }); * if (result.ok) console.log('Added:', result.value); * * @example * // Type-safe with CommandMap * type App = { * 'cart/add': { target: { id: number }; payload: { qty: number }; result: void }; * }; * const bus = createCommandBus(); * bus.dispatch('cart/add', { id: 1 }, { qty: 2 }); // fully typed * * @example * // With plugins, hooks, and listeners * const bus = createCommandBus(); * bus.use(logger()); // plugin wraps every dispatch * bus.onBefore((cmd) => { }); // runs before handler, throw to cancel * bus.onAfter((cmd, res) => { }); // runs after handler * bus.on('cart/*', (cmd, res) => { }); // wildcard listener */ export declare function createCommandBus(options?: CommandBusOptions): CommandBus; /** * Build a stable AbortError result. Prefers a user-provided explicit reason * (e.g. `ac.abort(new MyError('cancelled'))`) over the lib's BusError, but * falls back to BusError for the default `ac.abort()` case so consumers can * switch on `error.code === 'VC_CORE_ABORTED'`. * * After-hooks still fire from the caller, so observability is intact. * * @internal — also used by transports.ts for mid-flight signal handling. */ export declare function abortedResult(action: string, signal: AbortSignal): CommandResult; /** * Create an asynchronous command bus. Handlers return Promises. * * @example * const bus = createAsyncCommandBus(); * bus.register('user/fetch', async (cmd) => { * const user = await fetch(`/api/users/${cmd.target.id}`).then(r => r.json()); * return user; * }); * const result = await bus.dispatch('user/fetch', { id: 42 }); * if (result.ok) console.log(result.value); // { name: 'Alice', ... } */ export declare function createAsyncCommandBus(options?: CommandBusOptions): AsyncCommandBus; /** * Unseal a sealed bus. **Dev/HMR only** — if your production code never imports * `unsealBus`, it gets tree-shaken out entirely, making `seal()` irreversible. * * @example * // vite-hmr.ts * import { unsealBus } from 'vapor-chamber'; * if (import.meta.hot) { * unsealBus(bus); * bus.clear(); * // re-register handlers... * bus.seal(); * } */ export declare function unsealBus(bus: BaseBus): void; /** * Complete snapshot of a bus's internal topology. * Returned by `inspectBus()` for debugging, DevTools, and ops diagnostics. * * @example * import { inspectBus } from 'vapor-chamber'; * const info = inspectBus(bus); * console.log(info.actions); // ['cartAdd', 'cartRemove'] * console.log(info.undoActions); // ['cartAdd'] — only these can rollback * console.log(info.pluginCount); // 3 * console.log(info.sealed); // true */ export type BusInspection = { /** All registered action names. */ actions: string[]; /** Actions that have undo handlers registered. */ undoActions: string[]; /** Actions that have respond() handlers registered. */ responderActions: string[]; /** Number of installed plugins. */ pluginCount: number; /** Plugin priorities in execution order (highest first). */ pluginPriorities: number[]; /** Number of beforeHooks. */ beforeHookCount: number; /** Number of afterHooks. */ afterHookCount: number; /** Pattern listeners: each entry is the pattern string. */ listenerPatterns: string[]; /** Whether the bus is sealed. */ sealed: boolean; /** Current nested dispatch depth (0 when idle). */ dispatchDepth: number; /** Number of active throttle timers on this bus instance. */ activeTimers: number; }; /** * Inspect a bus's full topology. **Dev/debug only** — if your production code * never imports `inspectBus`, it gets tree-shaken out entirely. * * Returns a plain snapshot object — safe to serialize, log, or send to DevTools. * * @example * import { inspectBus } from 'vapor-chamber'; * const info = inspectBus(bus); * console.table(info); * * // Check if all checkout actions have undo handlers * const missing = info.actions.filter(a => !info.undoActions.includes(a)); * if (missing.length) console.warn('Missing undo for:', missing); */ export declare function inspectBus(bus: BaseBus): BusInspection; //# sourceMappingURL=command-bus.d.ts.map