{"version":3,"file":"emitter.mjs","names":[],"sources":["../../../../../../../ai/src/workflow/emitter.ts"],"sourcesContent":["import type { WithoutIdentity } from \"../contracts/events/event-identity.type\";\nimport type { WorkflowEventMap } from \"../contracts/events/event-map.type\";\nimport type {\n  WorkflowEventHandler,\n  WorkflowEventHandlers,\n} from \"../contracts/workflow/workflow.contract\";\n\ntype AnyHandler = WorkflowEventHandler<keyof WorkflowEventMap>;\n\n/**\n * The emit surface the workflow engine and step-runner depend on.\n * They never construct run identity themselves — they hand a bare\n * payload to a sink that injects `runId` / `rootRunId` before\n * delegating to the real three-tier `WorkflowEmitter`.\n *\n * `WorkflowEmitter` is factory-scoped (shared across every\n * `execute()`), so it cannot own per-run identity. A per-run sink\n * (see `runScopedEmitter`) closes that gap without touching the ~15\n * `emit` call sites in `engine.ts` / `step-runner.ts`.\n */\nexport interface WorkflowEventSink {\n  emit<K extends keyof WorkflowEventMap>(\n    event: K,\n    payload: WithoutIdentity<WorkflowEventMap[K]>,\n    executionHandlers?: WorkflowEventHandlers,\n  ): void;\n}\n\n/**\n * Three-tier workflow event emitter — factory (definition) → instance →\n * per-execution. All matching handlers fire, in layer order. Handler\n * errors are swallowed so listener bugs can never derail the workflow.\n */\nexport class WorkflowEmitter {\n  private readonly factoryHandlers?: WorkflowEventHandlers;\n  private readonly instanceHandlers = new Map<\n    keyof WorkflowEventMap,\n    Set<AnyHandler>\n  >();\n\n  public constructor(factoryHandlers?: WorkflowEventHandlers) {\n    this.factoryHandlers = factoryHandlers;\n  }\n\n  public on<K extends keyof WorkflowEventMap>(\n    event: K,\n    handler: WorkflowEventHandler<K>,\n  ): () => void {\n    let bucket = this.instanceHandlers.get(event);\n    if (!bucket) {\n      bucket = new Set();\n      this.instanceHandlers.set(event, bucket);\n    }\n    bucket.add(handler as AnyHandler);\n    return () => this.off(event, handler);\n  }\n\n  public off<K extends keyof WorkflowEventMap>(\n    event: K,\n    handler: WorkflowEventHandler<K>,\n  ): void {\n    this.instanceHandlers.get(event)?.delete(handler as AnyHandler);\n  }\n\n  public emit<K extends keyof WorkflowEventMap>(\n    event: K,\n    payload: WorkflowEventMap[K],\n    executionHandlers?: WorkflowEventHandlers,\n  ): void {\n    // Layer 1 — factory\n    invoke(this.factoryHandlers?.[event], payload);\n\n    // Layer 2 — instance (set-based, possibly many handlers)\n    const bucket = this.instanceHandlers.get(event);\n    if (bucket) {\n      for (const handler of bucket) invoke(handler, payload);\n    }\n\n    // Layer 3 — per-execution\n    invoke(executionHandlers?.[event], payload);\n  }\n}\n\nfunction invoke<K extends keyof WorkflowEventMap>(\n  handler: ((payload: WorkflowEventMap[K]) => void) | undefined,\n  payload: WorkflowEventMap[K],\n): void {\n  if (typeof handler !== \"function\") return;\n  try {\n    handler(payload);\n  } catch {\n    // Swallow — listener bugs must not derail workflow execution.\n  }\n}\n"],"mappings":";;;;;;AAiCA,IAAa,kBAAb,MAA6B;CAO3B,AAAO,YAAY,iBAAyC;0CALxB,IAAI,IAGtC;EAGA,KAAK,kBAAkB;CACzB;CAEA,AAAO,GACL,OACA,SACY;EACZ,IAAI,SAAS,KAAK,iBAAiB,IAAI,KAAK;EAC5C,IAAI,CAAC,QAAQ;GACX,yBAAS,IAAI,IAAI;GACjB,KAAK,iBAAiB,IAAI,OAAO,MAAM;EACzC;EACA,OAAO,IAAI,OAAqB;EAChC,aAAa,KAAK,IAAI,OAAO,OAAO;CACtC;CAEA,AAAO,IACL,OACA,SACM;EACN,KAAK,iBAAiB,IAAI,KAAK,CAAC,EAAE,OAAO,OAAqB;CAChE;CAEA,AAAO,KACL,OACA,SACA,mBACM;EAEN,OAAO,KAAK,kBAAkB,QAAQ,OAAO;EAG7C,MAAM,SAAS,KAAK,iBAAiB,IAAI,KAAK;EAC9C,IAAI,QACF,KAAK,MAAM,WAAW,QAAQ,OAAO,SAAS,OAAO;EAIvD,OAAO,oBAAoB,QAAQ,OAAO;CAC5C;AACF;AAEA,SAAS,OACP,SACA,SACM;CACN,IAAI,OAAO,YAAY,YAAY;CACnC,IAAI;EACF,QAAQ,OAAO;CACjB,QAAQ,CAER;AACF"}