/** * strategies/lifecycle — who is still using a strategy, and who may stop it. * * A strategy is a plain object a consumer builds and hands to `enable.*`. The * same object can legitimately be handed over more than once: to two runners * (an Agent and the Sequence that contains it), twice to one runner, or to the * same runner again after an unsubscribe — the shipped audit-export example * does exactly that, deliberately, to collect two runs into one hash chain. * * `stop()` is terminal in every adapter we ship: events exported afterwards * are dropped and there is no restart. So "stop it when someone lets go of it" * is wrong — it would silently un-record the second half of that example. This * module holds the one fact that makes stopping safe: * * **how many live subscriptions still point at this strategy.** * * Three laws, and they are the whole module: * * 1. An `Unsubscribe` NEVER stops a strategy. It releases one subscription. * That is the compatibility law: code written before this existed keeps * the behaviour it was written against. * 2. A strategy is stopped only when the last subscription has been released * AND something explicitly asked for teardown (`handle.stop()`, * `agent.shutdown()`). Sharing a strategy therefore cannot produce a * half-stopped pipeline where one runner's shutdown blinds another's. * 3. `stop()` reaches a strategy AT MOST ONCE, ever. Adapters are already * idempotent; this makes the guarantee the framework's rather than the * adapter author's. * * A `WeakMap` keyed on the strategy object holds the count, so nothing here * retains a strategy that the consumer has dropped, and cross-runner sharing * needs no global list. */ import type { BaseStrategy } from './types.js'; /** * `Symbol.asyncDispose` where the runtime has it (Node ≥ 20.4 — every engine * this package supports), and the registered fallback where it does not, so a * handle's disposal method is never keyed on `undefined`. ONE owner, because * two spellings of this key would make `await using` work on a handle and not * on the tracked wrapper around it. */ export declare const ASYNC_DISPOSE: symbol; /** One more live subscription. Called by every `attach*Strategy`. */ export declare function retainStrategy(strategy: BaseStrategy): void; /** * One fewer live subscription. Called by every `Unsubscribe`. * * Deliberately does NOT stop the strategy at zero — see law 1. Idempotent * below zero: calling an unsubscribe twice releases one subscription, not two. */ export declare function releaseStrategy(strategy: BaseStrategy): void; /** Live subscriptions pointing at this strategy. Diagnostic + tests. */ export declare function subscriptionCount(strategy: BaseStrategy): number; /** Has this strategy already been stopped? Diagnostic + tests. */ export declare function isStopped(strategy: BaseStrategy): boolean; /** * Stop the strategy IF nothing is still subscribed to it and it has not been * stopped before. Returns what actually happened, so a caller can say why it * did nothing rather than guessing. * * Errors from the strategy's own `stop()` are swallowed: teardown runs on the * shutdown path, and one vendor's broken `stop()` must not prevent the next * strategy — or the process — from finishing. */ export declare function stopStrategyIfUnused(strategy: BaseStrategy): 'stopped' | 'still-subscribed' | 'already-stopped'; //# sourceMappingURL=lifecycle.d.ts.map