/** * Shared ingest handler for `POST /signals`. * * Called by the HTTP route (S4) and the gateway-method shim (S6). Contains * all business logic for one ingest item — lookup, validation, execution, and * error translation — so neither transport duplicates logic. */ import type { SignalItem, SignalResult } from "./types.js"; import type { RuntimeHandle } from "../../runtime/run.js"; import type { Logger } from "../../utils/logger.js"; /** * Dependencies injected into {@link ingestSignalsHandler}. * * Keeping deps explicit (rather than closing over module-level state) makes * unit-testing straightforward and keeps the function pure with respect to * side effects outside the deps object. */ export interface IngestSignalsDeps { /** Live runtime handles maintained by the plugin. */ runtimeHandles: Map; /** Logger instance — errors logged at `error`, unexpected throws at `error`. */ logger: Logger; /** * Transport tag forwarded to future tracking events so the telemetry * pipeline can distinguish HTTP-originated ingests from gateway-shim * ingests on the migration dashboard. */ transport: "http" | "gateway"; } /** * Ingest one signal item. * * Looks up the runtime by address, validates handler-level constraints, calls * `RuntimeHandle.ingestExternalScannerData`, and translates all error shapes * into the uniform `{ success: false, code, message }` discriminant. Never * throws — all error paths return a `SignalResult`. * * Validation rules (beyond TypeBox): * - At least one of `asset`, `data`, or `signals` must be present; an item * with none of those fields has nothing to ingest → `INVALID_REQUEST`. * - `data` and `signals` are mutually exclusive → `INVALID_REQUEST`. * (The runtime also enforces this, but we check early to surface a clear * message before the engine lock is acquired.) * * Concurrent top-level items for the same `(address, scanner)` are serialized * here behind `ingestDispatchMutex` (keyed by runtimeId + scanner name — the * engine's one-in-flight guard identity), so callers may submit them without * racing the guard into `UNAVAILABLE`. Nesting signals in `signals[]` is still * valid; different scanners still ingest concurrently. * * @param item A single signal item. * @param deps Injected dependencies. * @returns A resolved `SignalResult` — never rejects. */ export declare function ingestSignalsHandler(item: SignalItem, deps: IngestSignalsDeps): Promise; //# sourceMappingURL=ingest-signals.d.ts.map