{"version":3,"file":"wait-point-invoker-eiP-IIux.mjs","names":["platform"],"sources":["../src/configure/services/workflow/test-env-key.ts","../src/configure/services/workflow/wait-point-invoker.ts"],"sourcesContent":["/**\n * Typed accessors for the test-time globalThis slot used to pass `env` from\n * `mockWorkflow().setEnv()` (in `@tailor-platform/sdk/vitest`) to\n * `runWorkflowLocally()` job bodies. The slot key is private to this\n * module; callers go through the get/set/clear functions below so both sides\n * share the same access path.\n *\n * Lives in its own file (with no `@/` imports) so `vitest/mock.ts` can load\n * it from nested Vitest configs that do not resolve `@/` aliases.\n * @internal\n */\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { TailorEnv, TailorPrincipal } from \"../../../runtime/types\";\n\nconst SLOT_KEY = \"__tailorWorkflowTestEnv\";\n\ntype AsyncLocalStorageLike<T> = {\n  getStore(): T | undefined;\n  run<R>(store: T, callback: () => R): R;\n};\n\nlet invokerStorage: AsyncLocalStorageLike<TailorPrincipal | null> | undefined;\n\nfunction workflowInvokerStorage(): AsyncLocalStorageLike<TailorPrincipal | null> {\n  if (!invokerStorage) {\n    invokerStorage = new AsyncLocalStorage<TailorPrincipal | null>();\n  }\n  return invokerStorage;\n}\n\n/**\n * Read the test-time env slot.\n * @returns Current env, or `undefined` when unset.\n * @internal\n */\nexport function readWorkflowTestEnv(): TailorEnv | undefined {\n  return (globalThis as unknown as Record<string, TailorEnv | undefined>)[SLOT_KEY];\n}\n\n/**\n * Write the test-time env slot.\n * @param env - Env value to expose to `runWorkflowLocally()` job bodies.\n * @internal\n */\nexport function writeWorkflowTestEnv(env: TailorEnv): void {\n  (globalThis as unknown as Record<string, TailorEnv>)[SLOT_KEY] = env;\n}\n\n/**\n * Clear the test-time env slot.\n * @internal\n */\nexport function clearWorkflowTestEnv(): void {\n  delete (globalThis as unknown as Record<string, unknown>)[SLOT_KEY];\n}\n\nexport function withWorkflowTestInvoker<T>(invoker: TailorPrincipal | null, run: () => T): T {\n  return workflowInvokerStorage().run(invoker, run);\n}\n\ntype RuntimeInvoker = {\n  id: string;\n  type: \"user\" | \"machine_user\";\n  workspaceId: string;\n  attributes?: string[] | TailorPrincipal[\"attributes\"];\n  attributeMap?: TailorPrincipal[\"attributes\"];\n  attributeList?: TailorPrincipal[\"attributeList\"];\n};\n\nfunction readRuntimeInvoker(): TailorPrincipal | null {\n  const runtime = (\n    globalThis as unknown as {\n      tailor?: { context?: { getInvoker?: () => RuntimeInvoker | null } };\n    }\n  ).tailor?.context?.getInvoker;\n  const raw = runtime?.();\n  if (!raw) return null;\n  return {\n    id: raw.id,\n    type: raw.type,\n    workspaceId: raw.workspaceId,\n    attributes: raw.attributeMap ?? (Array.isArray(raw.attributes) ? {} : (raw.attributes ?? {})),\n    attributeList: (raw.attributeList ??\n      (Array.isArray(raw.attributes) ? raw.attributes : [])) as TailorPrincipal[\"attributeList\"],\n  };\n}\n\n// Shallow-copied to isolate against cross-trigger mutation.\nexport function buildJobContext(): { env: TailorEnv; invoker: TailorPrincipal | null } {\n  const storedInvoker = invokerStorage?.getStore();\n  const invoker = storedInvoker === undefined ? readRuntimeInvoker() : storedInvoker;\n  const fromGlobal = readWorkflowTestEnv();\n  if (fromGlobal !== undefined) return { env: { ...fromGlobal }, invoker };\n  return { env: {}, invoker };\n}\n","import type { PlatformWorkflowAPI } from \"#/runtime/workflow\";\n\n// Not re-exported from the workflow barrel: the slot exists so the Vitest mock\n// can intercept parameterized wait points, whose `wait`/`resolve` live on\n// short-lived objects returned by `.with()` rather than on the definition.\nconst WAIT_POINT_INVOKER: unique symbol = Symbol.for(\"tailor-platform/sdk:wait-point-invoker\");\nconst WAIT_POINT_KEY: unique symbol = Symbol.for(\"tailor-platform/sdk:wait-point-key\");\n\n/** Indirection every wait point call routes through, keyed by resolved key. */\nexport interface WaitPointInvoker {\n  wait(key: string, payload: unknown): unknown;\n  resolve(\n    key: string,\n    executionId: string,\n    callback: (payload: unknown) => unknown | Promise<unknown>,\n  ): Promise<void>;\n}\n\nfunction getPlatformWorkflow(): PlatformWorkflowAPI {\n  const platform = globalThis as { tailor?: { workflow?: PlatformWorkflowAPI } };\n  const workflow = platform.tailor?.workflow;\n  if (!workflow) {\n    throw new Error(\n      \"tailor.workflow is not available. Run tests in the `tailor-runtime` Vitest environment, \" +\n        \"or acquire mockWorkflow() from @tailor-platform/sdk/vitest and set a wait/resolve handler.\",\n    );\n  }\n  return workflow;\n}\n\n/**\n * Create the invoker a single wait point definition delegates to.\n * @returns An invoker bound to the platform runtime\n */\nexport function createWaitPointInvoker(): WaitPointInvoker {\n  return {\n    wait(key, payload) {\n      return getPlatformWorkflow().wait(key, payload);\n    },\n    async resolve(key, executionId, callback) {\n      await getPlatformWorkflow().resolve(executionId, key, callback);\n    },\n  };\n}\n\n/**\n * Attach an invoker to a wait point definition so test doubles can intercept it.\n *\n * The slot itself is fixed once attached; a double swaps the invoker's `wait` /\n * `resolve` methods rather than the invoker object.\n * @param target - Wait point definition to attach to\n * @param invoker - Invoker the definition delegates to\n * @returns The same definition\n */\nexport function attachWaitPointInvoker<T extends object>(target: T, invoker: WaitPointInvoker): T {\n  Object.defineProperty(target, WAIT_POINT_INVOKER, {\n    value: invoker,\n    enumerable: false,\n    configurable: false,\n    writable: false,\n  });\n  return target;\n}\n\n/**\n * Read the invoker attached to a wait point definition.\n * @param target - Wait point definition to read from\n * @returns The attached invoker, or undefined when the value is not a wait point\n */\nexport function getWaitPointInvoker(target: object): WaitPointInvoker | undefined {\n  return (target as Record<symbol, WaitPointInvoker | undefined>)[WAIT_POINT_INVOKER];\n}\n\n/**\n * Record the resolved key on a wait point bound by `.with()`.\n * @param target - Bound wait point to attach to\n * @param key - Resolved runtime key\n * @returns The same bound wait point\n */\nexport function attachWaitPointKey<T extends object>(target: T, key: string): T {\n  Object.defineProperty(target, WAIT_POINT_KEY, {\n    value: key,\n    enumerable: false,\n    configurable: false,\n    writable: false,\n  });\n  return target;\n}\n\n/**\n * Read the resolved key recorded on a bound wait point.\n * @param target - Bound wait point to read from\n * @returns The resolved key, or undefined when the value is not a bound wait point\n */\nexport function getWaitPointKey(target: object): string | undefined {\n  return (target as Record<symbol, string | undefined>)[WAIT_POINT_KEY];\n}\n"],"mappings":"qDAcA,MAAM,EAAW,0BAOjB,IAAI,EAEJ,SAAS,wBAAwE,CAI/E,MAHA,CACE,IAAiB,IAAI,EAEhB,CACT,CAOA,SAAgB,qBAA6C,CAC3D,OAAQ,WAAgE,EAC1E,CAOA,SAAgB,qBAAqB,EAAsB,CACzD,WAAqD,GAAY,CACnE,CAMA,SAAgB,sBAA6B,CAC3C,OAAQ,WAAkD,EAC5D,CAEA,SAAgB,wBAA2B,EAAiC,EAAiB,CAC3F,OAAO,uBAAuB,CAAC,CAAC,IAAI,EAAS,CAAG,CAClD,CAWA,SAAS,oBAA6C,CACpD,IAAM,EACJ,WAGA,QAAQ,SAAS,WACb,EAAM,IAAU,EAEtB,OADK,EACE,CACL,GAAI,EAAI,GACR,KAAM,EAAI,KACV,YAAa,EAAI,YACjB,WAAY,EAAI,eAAiB,MAAM,QAAQ,EAAI,UAAU,EAAI,CAAC,EAAK,EAAI,YAAc,CAAC,GAC1F,cAAgB,EAAI,gBACjB,MAAM,QAAQ,EAAI,UAAU,EAAI,EAAI,WAAa,CAAC,EACvD,EARiB,IASnB,CAGA,SAAgB,iBAAuE,CACrF,IAAM,EAAgB,GAAgB,SAAS,EACzC,EAAU,IAAkB,IAAA,GAAY,mBAAmB,EAAI,EAC/D,EAAa,oBAAoB,EAEvC,OADI,IAAe,IAAA,GACZ,CAAE,IAAK,CAAC,EAAG,SAAQ,EADW,CAAE,IAAK,CAAE,GAAG,CAAW,EAAG,SAAQ,CAEzE,CCzFA,MAAM,EAAoC,OAAO,IAAI,wCAAwC,EACvF,EAAgC,OAAO,IAAI,oCAAoC,EAYrF,SAAS,qBAA2C,CAElD,IAAM,EAAWA,WAAS,QAAQ,SAClC,GAAI,CAAC,EACH,MAAU,MACR,oLAEF,EAEF,OAAO,CACT,CAMA,SAAgB,wBAA2C,CACzD,MAAO,CACL,KAAK,EAAK,EAAS,CACjB,OAAO,oBAAoB,CAAC,CAAC,KAAK,EAAK,CAAO,CAChD,EACA,MAAM,QAAQ,EAAK,EAAa,EAAU,CACxC,MAAM,oBAAoB,CAAC,CAAC,QAAQ,EAAa,EAAK,CAAQ,CAChE,CACF,CACF,CAWA,SAAgB,uBAAyC,EAAW,EAA8B,CAOhG,OANA,OAAO,eAAe,EAAQ,EAAoB,CAChD,MAAO,EACP,WAAY,GACZ,aAAc,GACd,SAAU,EACZ,CAAC,EACM,CACT,CAOA,SAAgB,oBAAoB,EAA8C,CAChF,OAAQ,EAAwD,EAClE,CAQA,SAAgB,mBAAqC,EAAW,EAAgB,CAO9E,OANA,OAAO,eAAe,EAAQ,EAAgB,CAC5C,MAAO,EACP,WAAY,GACZ,aAAc,GACd,SAAU,EACZ,CAAC,EACM,CACT,CAOA,SAAgB,gBAAgB,EAAoC,CAClE,OAAQ,EAA8C,EACxD"}