@powerhousedao/reactor 6.2.3-dev.23 → 6.2.3-dev.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. package/dist/{build-worker-executor-DUjyF4NM.js → build-worker-executor-DxmDJ4QQ.js} +24 -8
  2. package/dist/build-worker-executor-DxmDJ4QQ.js.map +1 -0
  3. package/dist/{document-indexer-CQzTEE1o.js → document-indexer-Dn9RB0sg.js} +3 -3
  4. package/dist/{document-indexer-CQzTEE1o.js.map → document-indexer-Dn9RB0sg.js.map} +1 -1
  5. package/dist/{drive-container-types-CS5IxDiA.js → drive-container-types-Be5-EY9W.js} +843 -144
  6. package/dist/drive-container-types-Be5-EY9W.js.map +1 -0
  7. package/dist/entry.js +10 -5
  8. package/dist/entry.js.map +1 -1
  9. package/dist/index.d.ts +1951 -1805
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +203 -99
  12. package/dist/index.js.map +1 -1
  13. package/dist/projection-entry.js +4 -4
  14. package/dist/{projection-shard-manager-CUo4bF4O.js → projection-shard-manager-mQhfVipO.js} +2 -2
  15. package/dist/{projection-shard-manager-CUo4bF4O.js.map → projection-shard-manager-mQhfVipO.js.map} +1 -1
  16. package/dist/{types-DMKLa0Ok.js → types-DxDCmtId.js} +3 -2
  17. package/dist/types-DxDCmtId.js.map +1 -0
  18. package/dist/{worker-g03lNM42.js → worker-BDVzCtuf.js} +2 -2
  19. package/dist/{worker-g03lNM42.js.map → worker-BDVzCtuf.js.map} +1 -1
  20. package/dist/{worker-handle-CrERzl8s.js → worker-handle-B3p-nuqG.js} +14 -9
  21. package/dist/worker-handle-B3p-nuqG.js.map +1 -0
  22. package/package.json +6 -7
  23. package/dist/build-worker-executor-DUjyF4NM.js.map +0 -1
  24. package/dist/drive-container-types-CS5IxDiA.js.map +0 -1
  25. package/dist/types-DMKLa0Ok.js.map +0 -1
  26. package/dist/worker-handle-CrERzl8s.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"types-DMKLa0Ok.js","names":[],"sources":["../src/events/types.ts"],"sourcesContent":["import type { OperationWithContext } from \"@powerhousedao/shared/document-model\";\nimport type { Job } from \"../queue/types.js\";\nimport type { JobMeta } from \"../shared/types.js\";\n\n/**\n * Describes a function to unsubscribe from an event.\n */\nexport type Unsubscribe = () => void;\n\n/**\n * A subscriber is a function that is called when an event is emitted.\n *\n * It is passed the event type and the data.\n * It can return a promise or a value.\n * If it returns a promise, the event bus will wait for the promise to resolve before calling the next subscriber.\n * If it throws an error, the event bus will reject with an aggregate error of all errors.\n *\n * @param type - The type of event to emit.\n * @param data - The data to pass to the subscriber.\n */\nexport type Subscriber = (type: number, data: any) => void | Promise<void>;\n\n/**\n * Custom error class that aggregates multiple errors from event subscribers.\n */\nexport class EventBusAggregateError extends Error {\n public readonly errors: any[];\n\n constructor(errors: unknown[]) {\n const message = `EventBus emit failed with ${errors.length} error(s): ${errors\n .map((e) => {\n if (e && typeof e === \"object\" && \"message\" in e) {\n return (e as Error).message;\n }\n return String(e);\n })\n .join(\"; \")}`;\n super(message);\n\n this.name = \"EventBusAggregateError\";\n this.errors = errors;\n }\n}\n\n/**\n * Event types for reactor lifecycle events.\n */\nexport const ReactorEventTypes = {\n JOB_PENDING: 10001,\n JOB_RUNNING: 10002,\n JOB_WRITE_READY: 10003,\n JOB_READ_READY: 10004,\n JOB_FAILED: 10005,\n READMODEL_BATCH_COMPLETED: 10006,\n READMODEL_INDEXED: 10007,\n MODEL_LOADED: 10008,\n} as const;\n\n/**\n * Stage within ReadModelCoordinator.runChain. Used as a dimension on\n * stage-attribution events and histograms.\n */\nexport type ReadModelStage = \"pre_ready\" | \"emit\" | \"post_ready\";\n\n/**\n * Stage in which an individual read model ran. The emit stage does not\n * involve a read model so it is excluded from this discriminant.\n */\nexport type ReadModelIndexingStage = \"pre_ready\" | \"post_ready\";\n\n/**\n * Emitted after the resolver loads a model on demand, so peers load it too.\n */\nexport type ModelLoadedEvent = {\n documentType: string;\n};\n\n/**\n * Event emitted when a job is registered and waiting to be executed.\n */\nexport type JobPendingEvent = {\n jobId: string;\n jobMeta: JobMeta;\n};\n\n/**\n * Event emitted when a job starts executing.\n */\nexport type JobRunningEvent = {\n jobId: string;\n jobMeta: JobMeta;\n};\n\n/**\n * Event emitted when operations are written to IOperationStore.\n * Contains the operations directly to avoid round-trip queries.\n */\nexport type JobWriteReadyEvent = {\n jobId: string;\n operations: OperationWithContext[];\n jobMeta: JobMeta;\n /**\n * The ids of the actions the caller submitted with this job. `operations`\n * can also carry operations the job merely moved into a new position, so a\n * consumer reporting back to the caller needs this to tell the two apart.\n * Absent on jobs that carry no submitted actions.\n */\n submittedActionIds?: string[];\n /**\n * Maps documentId to the collection IDs it belongs to.\n * Used by SyncManager to route operations only to remotes\n * whose collection contains the document.\n */\n collectionMemberships?: Record<string, string[]>;\n};\n\n/**\n * Event emitted after all read models have finished processing operations.\n * This event fires after JOB_WRITE_READY and guarantees that:\n * - All read models (DocumentView, DocumentIndexer, etc.) have indexed the operations\n * - All consistency trackers have been updated with the new operation indices\n * - Queries without consistency tokens will now see the updated data\n *\n * This event is useful for:\n * - Test synchronization (knowing when read models are ready)\n * - Observability (measuring read model latency)\n * - Event-driven workflows (triggering downstream processes)\n */\nexport type JobReadReadyEvent = {\n jobId: string;\n operations: OperationWithContext[];\n};\n\n/**\n * Event emitted when a job fails with an unrecoverable error.\n * This event allows the JobAwaiter and other subscribers to react to job failures\n * without polling.\n */\nexport type JobFailedEvent = {\n jobId: string;\n error: Error;\n job?: Job;\n};\n\n/**\n * Event emitted once per batch processed by ReadModelCoordinator.runChain,\n * after all three projection stages complete. Carries per-stage wall times,\n * the chain wait time, and the batch size so projection cost can be\n * attributed by an observer.\n */\nexport type ReadModelBatchCompletedEvent = {\n jobId: string;\n batchSize: number;\n chainWaitDurationMs: number;\n preReadyDurationMs: number;\n emitDurationMs: number;\n postReadyDurationMs: number;\n};\n\n/**\n * Event emitted once per individual read model per batch and stage, after\n * that read model's indexOperations call resolves (or rejects). Lets\n * observers attribute projection cost to a specific read model.\n */\nexport type ReadModelIndexedEvent = {\n jobId: string;\n readModelName: string;\n stage: ReadModelIndexingStage;\n durationMs: number;\n operationCount: number;\n success: boolean;\n};\n"],"mappings":";;;;AAyBA,IAAa,yBAAb,cAA4C,MAAM;CAChD;CAEA,YAAY,QAAmB;EAC7B,MAAM,UAAU,6BAA6B,OAAO,OAAO,aAAa,OACrE,KAAK,MAAM;AACV,OAAI,KAAK,OAAO,MAAM,YAAY,aAAa,EAC7C,QAAQ,EAAY;AAEtB,UAAO,OAAO,EAAE;IAChB,CACD,KAAK,KAAK;AACb,QAAM,QAAQ;AAEd,OAAK,OAAO;AACZ,OAAK,SAAS;;;;;;AAOlB,MAAa,oBAAoB;CAC/B,aAAa;CACb,aAAa;CACb,iBAAiB;CACjB,gBAAgB;CAChB,YAAY;CACZ,2BAA2B;CAC3B,mBAAmB;CACnB,cAAc;CACf"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"worker-handle-CrERzl8s.js","names":[],"sources":["../src/executor/worker/worker-handle.ts"],"sourcesContent":["/**\n * Parent-side IPC wrapper around a single executor worker.\n *\n * Implements {@link IExecutorWorker} on top of an injectable\n * {@link IWorkerTransport}. The handle owns one worker's lifecycle (init ->\n * ready -> execute/result rounds -> abort/shutdown -> terminate) and bounds\n * its in-flight slot to a single job — `SimpleJobExecutor` is single-threaded\n * inside the worker, and concurrent dispatches would race its caches.\n *\n * @see Executor Worker Pool Design wiki page\n * (Powerhouse board wiki id: d400d711-f07e-4389-a226-4e9fdd4fa8ba)\n */\n\nimport type { ILogger } from \"document-model\";\nimport { randomUUID } from \"node:crypto\";\nimport type {\n IExecutorWorker,\n WorkerExecutionOutcome,\n WorkerInFlightSnapshot,\n} from \"../interfaces.js\";\nimport type { Job } from \"../../queue/types.js\";\nimport type { JobExecutorConfig } from \"../types.js\";\nimport { fromErrorInfo } from \"./error-info.js\";\nimport {\n WorkerAbortTimeoutError,\n WorkerBusyError,\n WorkerExitedError,\n WorkerInitFailedError,\n WorkerLoadModelFailedError,\n WorkerShutdownTimeoutError,\n} from \"./errors.js\";\nimport type { ForwardingPoolInstrumentation } from \"../../storage/pool-instrumentation.js\";\nimport type {\n DbConfig,\n HeartbeatMessage,\n LogMessage,\n MetricsMessage,\n ModelLoadFailedMessage,\n ModelLoadedMessage,\n ModelManifestEntry,\n PoolAcquireSamplesMessage,\n ResultMessage,\n SignatureVerifierSpec,\n WorkerMessage,\n WorkerPoolConfig,\n} from \"./protocol.js\";\nimport type { IWorkerTransport, WorkerTransportListener } from \"./transport.js\";\n\nconst DEFAULT_ABORT_GRACE_MS = 5_000;\nconst DEFAULT_SHUTDOWN_GRACE_MS = 5_000;\n\n/**\n * Payload the parent ships in the `init` message (everything except the\n * envelope fields the handle fills in itself).\n */\nexport type WorkerInitPayload = {\n poolConfig: WorkerPoolConfig;\n db: DbConfig;\n /** Omitted = the worker performs no executor-side signature verification. */\n signatureVerifier?: SignatureVerifierSpec;\n models: ModelManifestEntry[];\n /** Omitted = the worker builds its executor with the built-in defaults. */\n executorConfig?: JobExecutorConfig;\n};\n\nexport type WorkerHandleOptions = {\n workerId: string;\n index: number;\n transport: IWorkerTransport;\n initPayload: WorkerInitPayload;\n logger: ILogger;\n /** Grace period before an outstanding `abort` escalates to terminate. */\n abortGraceMs?: number;\n /** Default grace period applied to graceful `shutdown` when not overridden. */\n defaultShutdownGraceMs?: number;\n /**\n * Forwarding instrumentation the host registers per worker. The handle\n * pumps `pool-acquire-samples` messages into this object so the host's\n * OpenTelemetry instrumentation records acquire-wait latencies as if the\n * worker's pool were local.\n */\n poolInstrumentation?: ForwardingPoolInstrumentation;\n};\n\ntype PendingEntry =\n | {\n kind: \"init\";\n resolve: () => void;\n reject: (err: Error) => void;\n }\n | {\n kind: \"execute\";\n jobId: string;\n resolve: (outcome: WorkerExecutionOutcome) => void;\n reject: (err: Error) => void;\n }\n | {\n kind: \"shutdown\";\n resolve: () => void;\n reject: (err: Error) => void;\n }\n | {\n kind: \"load-model\";\n documentType: string;\n version: string;\n resolve: () => void;\n reject: (err: Error) => void;\n };\n\ntype Phase = \"fresh\" | \"starting\" | \"ready\" | \"shutting-down\" | \"terminated\";\n\nexport class WorkerHandle implements IExecutorWorker {\n readonly workerId: string;\n readonly index: number;\n\n private readonly transport: IWorkerTransport;\n private readonly initPayload: WorkerInitPayload;\n private readonly logger: ILogger;\n private readonly abortGraceMs: number;\n private readonly defaultShutdownGraceMs: number;\n private readonly poolInstrumentation?: ForwardingPoolInstrumentation;\n\n private readonly pending = new Map<string, PendingEntry>();\n private inFlight: { correlationId: string; jobId: string } | null = null;\n private phase: Phase = \"fresh\";\n private lastExitError: Error | null = null;\n private lastCorrelationId: string | null = null;\n private abortTimer: NodeJS.Timeout | null = null;\n private lastHeartbeatAt: number | null = null;\n private lastMetrics: {\n counters: Record<string, number>;\n gauges: Record<string, number>;\n timestamp: number;\n } | null = null;\n\n private readonly onMessage: WorkerTransportListener<\"message\">;\n private readonly onError: WorkerTransportListener<\"error\">;\n private readonly onExit: WorkerTransportListener<\"exit\">;\n\n constructor(options: WorkerHandleOptions) {\n this.workerId = options.workerId;\n this.index = options.index;\n this.transport = options.transport;\n this.initPayload = options.initPayload;\n this.logger = options.logger;\n this.abortGraceMs = options.abortGraceMs ?? DEFAULT_ABORT_GRACE_MS;\n this.defaultShutdownGraceMs =\n options.defaultShutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS;\n this.poolInstrumentation = options.poolInstrumentation;\n\n this.onMessage = (msg) => this.handleMessage(msg);\n this.onError = (err) => this.handleTransportError(err);\n this.onExit = (code) => this.handleExit(code);\n\n this.transport.on(\"message\", this.onMessage);\n this.transport.on(\"error\", this.onError);\n this.transport.on(\"exit\", this.onExit);\n }\n\n public async start(): Promise<void> {\n if (this.phase !== \"fresh\") {\n throw new WorkerInitFailedError(\n this.workerId,\n `cannot start worker in phase ${this.phase}`,\n );\n }\n this.phase = \"starting\";\n const correlationId = this.nextCorrelationId();\n const ready = new Promise<void>((resolve, reject) => {\n this.pending.set(correlationId, {\n kind: \"init\",\n resolve,\n reject,\n });\n });\n this.transport.postMessage({\n type: \"init\",\n correlationId,\n workerId: this.workerId,\n poolConfig: this.initPayload.poolConfig,\n db: this.initPayload.db,\n signatureVerifier: this.initPayload.signatureVerifier,\n models: this.initPayload.models,\n executorConfig: this.initPayload.executorConfig,\n });\n await ready;\n this.phase = \"ready\";\n }\n\n public execute(\n job: Job,\n signal?: AbortSignal,\n ): Promise<WorkerExecutionOutcome> {\n if (this.phase === \"terminated\") {\n return Promise.reject(\n this.lastExitError ??\n new WorkerExitedError(this.workerId, -1, this.lastCorrelationId),\n );\n }\n if (this.phase !== \"ready\") {\n return Promise.reject(\n new WorkerInitFailedError(\n this.workerId,\n `worker not ready (phase=${this.phase})`,\n ),\n );\n }\n if (this.inFlight !== null) {\n return Promise.reject(new WorkerBusyError(this.workerId, job.id));\n }\n\n const correlationId = this.nextCorrelationId();\n this.lastCorrelationId = correlationId;\n this.inFlight = { correlationId, jobId: job.id };\n\n let abortListener: (() => void) | null = null;\n const detachSignal = () => {\n if (signal && abortListener) {\n signal.removeEventListener(\"abort\", abortListener);\n abortListener = null;\n }\n };\n\n const promise = new Promise<WorkerExecutionOutcome>((resolve, reject) => {\n this.pending.set(correlationId, {\n kind: \"execute\",\n jobId: job.id,\n resolve: (outcome) => {\n detachSignal();\n resolve(outcome);\n },\n reject: (err) => {\n detachSignal();\n reject(err);\n },\n });\n });\n\n if (signal) {\n if (signal.aborted) {\n this.abort(correlationId, \"aborted before dispatch\");\n } else {\n abortListener = () => this.abort(correlationId, \"caller signal\");\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n }\n\n this.transport.postMessage({\n type: \"execute\",\n correlationId,\n job,\n });\n\n return promise;\n }\n\n public abort(correlationId: string, reason?: string): void {\n if (this.phase === \"terminated\") {\n return;\n }\n if (!this.inFlight || this.inFlight.correlationId !== correlationId) {\n return;\n }\n if (this.abortTimer) {\n return;\n }\n this.transport.postMessage({\n type: \"abort\",\n correlationId: this.nextCorrelationId(),\n targetCorrelationId: correlationId,\n reason,\n });\n this.abortTimer = setTimeout(() => {\n this.abortTimer = null;\n const entry = this.pending.get(correlationId);\n if (!entry || entry.kind !== \"execute\") {\n return;\n }\n const err = new WorkerAbortTimeoutError(\n this.workerId,\n correlationId,\n this.abortGraceMs,\n );\n this.failPending(correlationId, err);\n this.inFlight = null;\n void this.forceTerminate(err);\n }, this.abortGraceMs);\n }\n\n public async shutdown(graceful: boolean, graceMs?: number): Promise<void> {\n if (this.phase === \"terminated\") {\n return;\n }\n if (!graceful) {\n this.phase = \"shutting-down\";\n await this.forceTerminate(null);\n return;\n }\n\n const effectiveGrace = graceMs ?? this.defaultShutdownGraceMs;\n this.phase = \"shutting-down\";\n const correlationId = this.nextCorrelationId();\n const drained = new Promise<void>((resolve, reject) => {\n this.pending.set(correlationId, {\n kind: \"shutdown\",\n resolve,\n reject,\n });\n });\n this.transport.postMessage({\n type: \"shutdown\",\n correlationId,\n graceMs: effectiveGrace,\n });\n\n let timer!: NodeJS.Timeout;\n const timeout = new Promise<void>((_, reject) => {\n timer = setTimeout(() => {\n reject(new WorkerShutdownTimeoutError(this.workerId, effectiveGrace));\n }, effectiveGrace);\n });\n\n try {\n await Promise.race([drained, timeout]);\n } catch (err) {\n this.logger.warn(\n `worker ${this.workerId} shutdown timed out after ${effectiveGrace}ms`,\n err,\n );\n } finally {\n clearTimeout(timer);\n }\n\n await this.forceTerminate(null);\n }\n\n public loadModel(\n entry: ModelManifestEntry,\n signal?: AbortSignal,\n ): Promise<void> {\n if (this.phase === \"terminated\") {\n return Promise.reject(\n this.lastExitError ??\n new WorkerExitedError(this.workerId, -1, this.lastCorrelationId),\n );\n }\n if (this.phase !== \"ready\") {\n return Promise.reject(\n new WorkerInitFailedError(\n this.workerId,\n `worker not ready (phase=${this.phase})`,\n ),\n );\n }\n\n const correlationId = this.nextCorrelationId();\n let abortListener: (() => void) | null = null;\n const detachSignal = () => {\n if (signal && abortListener) {\n signal.removeEventListener(\"abort\", abortListener);\n abortListener = null;\n }\n };\n\n const promise = new Promise<void>((resolve, reject) => {\n this.pending.set(correlationId, {\n kind: \"load-model\",\n documentType: entry.documentType,\n version: entry.version,\n resolve: () => {\n detachSignal();\n resolve();\n },\n reject: (err) => {\n detachSignal();\n reject(err);\n },\n });\n });\n\n if (signal) {\n if (signal.aborted) {\n this.failPending(\n correlationId,\n new WorkerLoadModelFailedError(\n this.workerId,\n entry.documentType,\n entry.version,\n \"aborted before dispatch\",\n ),\n );\n return promise;\n }\n abortListener = () => {\n this.failPending(\n correlationId,\n new WorkerLoadModelFailedError(\n this.workerId,\n entry.documentType,\n entry.version,\n \"caller signal\",\n ),\n );\n };\n signal.addEventListener(\"abort\", abortListener, { once: true });\n }\n\n this.transport.postMessage({\n type: \"load-model\",\n correlationId,\n model: entry,\n });\n\n return promise;\n }\n\n public isIdle(): boolean {\n return this.inFlight === null && this.phase === \"ready\";\n }\n\n public getInFlight(): WorkerInFlightSnapshot | null {\n if (!this.inFlight) {\n return null;\n }\n return {\n correlationId: this.inFlight.correlationId,\n jobId: this.inFlight.jobId,\n };\n }\n\n private nextCorrelationId(): string {\n return randomUUID();\n }\n\n private handleMessage(msg: WorkerMessage): void {\n switch (msg.type) {\n case \"ready\":\n this.handleReady(msg.correlationId);\n return;\n case \"result\":\n this.handleResult(msg);\n return;\n case \"model-loaded\":\n this.handleModelLoaded(msg);\n return;\n case \"model-load-failed\":\n this.handleModelLoadFailed(msg);\n return;\n case \"log\":\n this.handleLog(msg);\n return;\n case \"heartbeat\":\n this.handleHeartbeat(msg);\n return;\n case \"metrics\":\n this.handleMetrics(msg);\n return;\n case \"pool-acquire-samples\":\n this.handlePoolAcquireSamples(msg);\n return;\n default: {\n const exhaustive: never = msg;\n void exhaustive;\n }\n }\n }\n\n private handlePoolAcquireSamples(msg: PoolAcquireSamplesMessage): void {\n if (!this.poolInstrumentation) {\n return;\n }\n this.poolInstrumentation.updateStats({\n size: msg.size,\n idle: msg.idle,\n waiting: msg.waiting,\n });\n this.poolInstrumentation.pushSamples(msg.durations);\n }\n\n private handleReady(correlationId: string): void {\n const entry = this.pending.get(correlationId);\n if (!entry || entry.kind !== \"init\") {\n return;\n }\n this.pending.delete(correlationId);\n entry.resolve();\n }\n\n private handleResult(msg: ResultMessage): void {\n const entry = this.pending.get(msg.correlationId);\n if (!entry || entry.kind !== \"execute\") {\n return;\n }\n this.pending.delete(msg.correlationId);\n if (this.inFlight?.correlationId === msg.correlationId) {\n this.inFlight = null;\n }\n if (this.abortTimer) {\n clearTimeout(this.abortTimer);\n this.abortTimer = null;\n }\n\n const outcome: WorkerExecutionOutcome = msg.error\n ? {\n result: {\n ...msg.result,\n success: false,\n error: fromErrorInfo(msg.error),\n },\n }\n : {\n result: msg.result,\n writeReady: msg.writeReady,\n };\n entry.resolve(outcome);\n\n if (this.phase === \"shutting-down\") {\n const shutdownEntry = [...this.pending.values()].find(\n (e) => e.kind === \"shutdown\",\n );\n if (shutdownEntry) {\n shutdownEntry.resolve();\n }\n }\n }\n\n private handleModelLoaded(msg: ModelLoadedMessage): void {\n const entry = this.pending.get(msg.correlationId);\n if (!entry || entry.kind !== \"load-model\") {\n return;\n }\n this.pending.delete(msg.correlationId);\n entry.resolve();\n }\n\n private handleModelLoadFailed(msg: ModelLoadFailedMessage): void {\n const entry = this.pending.get(msg.correlationId);\n if (!entry || entry.kind !== \"load-model\") {\n return;\n }\n this.pending.delete(msg.correlationId);\n entry.reject(\n new WorkerLoadModelFailedError(\n this.workerId,\n msg.documentType,\n msg.version,\n msg.error.message,\n { cause: fromErrorInfo(msg.error) },\n ),\n );\n }\n\n private handleLog(msg: LogMessage): void {\n const args = msg.args;\n switch (msg.level) {\n case \"debug\":\n this.logger.debug(msg.message, ...args);\n return;\n case \"info\":\n this.logger.info(msg.message, ...args);\n return;\n case \"warn\":\n this.logger.warn(msg.message, ...args);\n return;\n case \"error\":\n this.logger.error(msg.message, ...args);\n return;\n default: {\n const exhaustive: never = msg.level;\n void exhaustive;\n }\n }\n }\n\n private handleHeartbeat(msg: HeartbeatMessage): void {\n this.lastHeartbeatAt = msg.timestamp;\n }\n\n private handleMetrics(msg: MetricsMessage): void {\n this.lastMetrics = {\n counters: msg.counters,\n gauges: msg.gauges,\n timestamp: msg.timestamp,\n };\n }\n\n private handleTransportError(err: Error): void {\n this.logger.error(\n `worker ${this.workerId} transport error: ${err.message}`,\n err,\n );\n }\n\n private handleExit(code: number): void {\n if (this.phase === \"terminated\") {\n return;\n }\n const wasGraceful = this.phase === \"shutting-down\" && code === 0;\n this.phase = \"terminated\";\n const err = wasGraceful\n ? null\n : new WorkerExitedError(this.workerId, code, this.lastCorrelationId);\n this.lastExitError = err;\n if (this.abortTimer) {\n clearTimeout(this.abortTimer);\n this.abortTimer = null;\n }\n this.detachTransportListeners();\n this.drainPending(err);\n this.inFlight = null;\n }\n\n private detachTransportListeners(): void {\n this.transport.off(\"message\", this.onMessage);\n this.transport.off(\"error\", this.onError);\n this.transport.off(\"exit\", this.onExit);\n }\n\n private drainPending(err: Error | null): void {\n for (const [, entry] of this.pending) {\n if (err) {\n entry.reject(err);\n } else if (entry.kind === \"shutdown\") {\n entry.resolve();\n } else if (entry.kind === \"init\") {\n entry.reject(new WorkerInitFailedError(this.workerId, \"worker exited\"));\n } else if (entry.kind === \"load-model\") {\n entry.reject(\n new WorkerLoadModelFailedError(\n this.workerId,\n entry.documentType,\n entry.version,\n \"worker exited before responding\",\n ),\n );\n } else {\n entry.reject(\n new WorkerExitedError(this.workerId, 0, this.lastCorrelationId),\n );\n }\n }\n this.pending.clear();\n }\n\n private failPending(correlationId: string, err: Error): void {\n const entry = this.pending.get(correlationId);\n if (!entry) {\n return;\n }\n this.pending.delete(correlationId);\n entry.reject(err);\n }\n\n private async forceTerminate(reason: Error | null): Promise<void> {\n if (this.phase === \"terminated\") {\n return;\n }\n try {\n await this.transport.terminate();\n } catch (err) {\n this.logger.warn(\n `worker ${this.workerId} terminate threw: ${(err as Error).message}`,\n );\n }\n const phaseAfter = this.phase as Phase;\n if (phaseAfter === \"terminated\") {\n return;\n }\n this.phase = \"terminated\";\n this.lastExitError = reason;\n this.detachTransportListeners();\n this.drainPending(reason);\n this.inFlight = null;\n }\n}\n"],"mappings":"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"}