/** * DslPlugin: lifecycle, event wiring, price monitor (DSL feature of senpi core). */ import type { DslComponentHealthStatus, DslSystemState } from "../../health/types.js"; import type { DslArchivedClose, DslPositionSummary, DslState, PositionOpenedEvent } from "../../types/dsl/index.js"; import type { DslPluginOptions } from "./options.js"; export type { DslPluginOptions } from "./options.js"; export declare class DslPlugin { private readonly config; private readonly bus; private readonly stateManager; private readonly senpiClient; private readonly ownSenpiClient; private readonly baseDir; private readonly deleteDslsForStrategyImpl; private readonly isSlPlacementInProgress; private readonly adoptPositionImpl; private readonly resizePositionImpl; private readonly placeSlOnAdopt; /** Lazy runtime identity builder; stamps per-trace identity at the dsl.tick seam. */ private readonly identity?; /** Emptied by `stop()`, which is what makes a second `stop()` a no-op rather than a double-off. */ private busSubscriptions; /** * The tick currently in flight, settled INCLUDING its `finally`. Held so `stop()` can be awaited * to a genuine quiescence rather than merely to "no further ticks will be scheduled". */ private inFlightTick; private priceMonitorHandle; private priceMonitorStopped; private notificationSubscriber; private monitorRunning; private tickInFlight; private lastTickStartedAt; private lastTickFinishedAt; private lastTickError; private nextTickAt; private tickAttemptCount; private tickSuccessCount; private tickErrorCount; private constructor(); private static resolveStateManager; private static resolveSenpiClient; private static resolveStrategyStates; /** * Subscribe the five position handlers and RETURN the subscriptions, so `stop()` can release * exactly what it took. * * The wrapped handlers are freshly-created closures, so the reference returned here is the only * thing `off` will ever accept. Previously they were subscribed and discarded, which left the * plugin structurally unable to unsubscribe even had it tried — harmless while nothing ever * rebuilt a plugin on a live bus, and not harmless the moment the update verb does. */ private static wirePositionEventHandlers; private static wrapEventHandler; private static dslStateToPositionSummary; private static dslStateToArchivedClose; static create(options: DslPluginOptions): Promise; /** Cancel exchange SLs and archive all DSL state for the strategy (live files removed; strategy dir kept). */ deleteDslsForStrategy(address: string): Promise; /** * Adopt an orphaned exchange position into DSL (crash-safe reconcile). * Does NOT emit bus position.opened; triggerReason = "adopted"; notification = silent. * placeSl honors placeSlOnAdopt option (default false — monitor places SL on next tick). * Caller opts (the reconcile's tickId) are carried through; placeSl stays plugin-owned. */ adoptPosition(payload: PositionOpenedEvent, opts?: { tickId?: string; }): Promise; /** * Resize: archive stale active DSL state for the position, then adopt fresh. * Close reason for the stale state = RECONCILE_RESIZE. * placeSl honors placeSlOnAdopt option (default false). * Caller opts (the reconcile's tickId) are carried through; placeSl stays plugin-owned. */ resizePosition(payload: PositionOpenedEvent, opts?: { tickId?: string; }): Promise; /** Active DSL positions for this runtime state dir (no runtimeId). */ listActivePositions(): DslPositionSummary[]; /** * Active DSL states, fully typed. * * `getSystemState()` also carries these, but its `positions` is `unknown[]` — the health types are * a wire shape and deliberately loose. A caller that needs a real field off a position (the update * report needs `handoffStatus`, to say which stops the backend ratchet owns) would otherwise have * to cast, which is a claim the compiler cannot check. */ listActiveDslStates(): DslState[]; getPositionState(address: string, asset: string): DslState | undefined; /** * First active DSL state matching asset across strategy addresses (normalized match via StateManager). */ findPositionByAsset(asset: string): { address: string; state: DslState; } | undefined; /** * Archived closes under this recipe baseDir. Optional per-recipe limit; gateway merges globally. */ listArchivedCloses(options?: { address?: string; limit?: number; }): Promise; getHealthStatus(): Promise; getSystemState(): Promise; /** * Tear down and settle. * * Returns a promise that resolves once any tick already in flight has finished. Callers that do * not care may ignore it and the teardown is still synchronous — but a caller REPLACING this * plugin must await, or the outgoing monitor keeps writing state and calling the venue while the * incoming one is already ticking the same positions. The two hold independent `StateManager` * instances, so their per-position key locks are independent too: nothing else serialises them. */ stop(): Promise; private listActiveStates; /** * The async-context bag the monitor tick runs inside, so `dsl.*` events the tick emits carry the * runtime's `senpi.*` identity (the logger stamps it at emit time, see `trackingContext`). The tick * is the one DSL emission origin outside the signal flow — position events already fire in-context. * Identity is per-runtime and stable, so it's resolved once. Returns null when no identity builder * is wired (standalone/test); the tick then runs uninstrumented, which is correct, not a gap. */ private buildTickTrackingContext; private startMonitorLoop; private finishMonitorTick; private deriveHealth; private buildHealthSummary; } //# sourceMappingURL=index.d.ts.map