{"version":3,"file":"child-run-CZlxzkj6.mjs","names":[],"sources":["../src/execution/child-run.ts"],"sourcesContent":["import { abortReason } from \"@prodkit/shared/runtime\";\nimport {\n  CLEANUP_FAILURE_MESSAGE,\n  ErrorGroup,\n  TimeoutError,\n  UnhandledException,\n} from \"../errors.js\";\nimport { Result } from \"../result.js\";\nimport { createRunContext, type RunContext } from \"./runtime.js\";\n\nfunction watchParentAbort(\n  parent: AbortSignal,\n  onAbort: (reason: unknown) => void,\n): { detach(): void } {\n  const cascade = () => onAbort(abortReason(parent));\n\n  if (parent.aborted) cascade();\n  else parent.addEventListener(\"abort\", cascade, { once: true });\n\n  return {\n    detach() {\n      parent.removeEventListener(\"abort\", cascade);\n    },\n  };\n}\n\ntype IsolatedChild = {\n  readonly context: RunContext<readonly unknown[]>;\n  abort(reason?: unknown): void;\n  detach(): void;\n};\n\nfunction createIsolatedChild(parent: RunContext<readonly unknown[]>): IsolatedChild {\n  const controller = new AbortController();\n  const watch = watchParentAbort(parent.signal, (reason) => controller.abort(reason));\n\n  return {\n    context: createRunContext(controller.signal, parent.args, parent.extensions),\n    abort(reason) {\n      controller.abort(reason);\n    },\n    detach() {\n      watch.detach();\n    },\n  };\n}\n\ntype FanOutChild = {\n  readonly context: RunContext<readonly unknown[]>;\n  abort(reason?: unknown): void;\n  release(): void;\n};\n\ntype FanOutChildren = {\n  spawn(): FanOutChild;\n  abortActive(reason?: unknown): void;\n  detach(): void;\n};\n\nexport function createFanOutChildren(parent: RunContext<readonly unknown[]>): FanOutChildren {\n  const active = new Set<AbortController>();\n  const watch = watchParentAbort(parent.signal, (reason) => {\n    for (const controller of active) controller.abort(reason);\n  });\n\n  return {\n    spawn() {\n      const controller = new AbortController();\n      active.add(controller);\n      if (parent.signal.aborted) controller.abort(abortReason(parent.signal));\n      return {\n        context: createRunContext(controller.signal, parent.args, parent.extensions),\n        abort(reason) {\n          controller.abort(reason);\n        },\n        release() {\n          active.delete(controller);\n        },\n      };\n    },\n    abortActive(reason) {\n      for (const controller of active) controller.abort(reason);\n    },\n    detach() {\n      watch.detach();\n    },\n  };\n}\n\ntype BoundCancelChild = {\n  readonly context: RunContext<readonly unknown[]>;\n  detach(): void;\n};\n\nfunction normalizeCleanupFailureAfterInterruption<T, E>(\n  drainedResult: Result<T, E>,\n  interruption: unknown,\n  unrelatedFailure: \"prependInterruption\" | \"preserve\",\n): Result<T, E | UnhandledException> | undefined {\n  if (drainedResult.isOk()) return undefined;\n\n  const error = drainedResult.error;\n  if (\n    !UnhandledException.is(error) ||\n    !ErrorGroup.is(error.cause) ||\n    error.cause.message !== CLEANUP_FAILURE_MESSAGE\n  ) {\n    return undefined;\n  }\n\n  const { errors } = error.cause;\n  if (errors.length === 0) return undefined;\n\n  const [first, ...rest] = errors;\n  const isInterruption =\n    first === interruption || (UnhandledException.is(first) && first.cause === interruption);\n  if (!isInterruption && unrelatedFailure === \"preserve\") return undefined;\n  const preservedErrors = isInterruption ? [interruption, ...rest] : [interruption, ...errors];\n\n  return Result.err(\n    new UnhandledException({\n      cause: new ErrorGroup(preservedErrors, error.cause.message),\n    }),\n  );\n}\n\nfunction createBoundCancelChild(\n  boundSignal: AbortSignal,\n  parent: RunContext<readonly unknown[]>,\n): BoundCancelChild {\n  const controller = new AbortController();\n\n  const onBoundAbort = () => {\n    controller.abort(abortReason(boundSignal));\n  };\n\n  const outerWatch = watchParentAbort(parent.signal, (reason) => controller.abort(reason));\n\n  if (boundSignal.aborted) onBoundAbort();\n  else boundSignal.addEventListener(\"abort\", onBoundAbort, { once: true });\n\n  return {\n    context: createRunContext(controller.signal, parent.args, parent.extensions),\n    detach() {\n      boundSignal.removeEventListener(\"abort\", onBoundAbort);\n      outerWatch.detach();\n    },\n  };\n}\n\nexport async function runWithBoundCancel<T, E>(\n  run: (context: RunContext<readonly unknown[]>) => Promise<Result<T, E | UnhandledException>>,\n  boundSignal: AbortSignal,\n  outerContext: RunContext<readonly unknown[]>,\n): Promise<Result<T, E | UnhandledException>> {\n  if (boundSignal.aborted) {\n    return Result.err(new UnhandledException({ cause: abortReason(boundSignal) }));\n  }\n\n  const child = createBoundCancelChild(boundSignal, outerContext);\n  try {\n    const result = await run(child.context);\n    if (!boundSignal.aborted) return result;\n\n    const interruption = abortReason(boundSignal);\n    return normalizeCleanupFailureAfterInterruption(result, interruption, \"preserve\") ?? result;\n  } finally {\n    child.detach();\n  }\n}\n\nexport async function runWithTimeout<T, E>(\n  run: (context: RunContext<readonly unknown[]>) => PromiseLike<Result<T, E>>,\n  timeoutMs: number,\n  outerContext: RunContext<readonly unknown[]>,\n): Promise<Result<T, E | TimeoutError | UnhandledException>> {\n  const child = createIsolatedChild(outerContext);\n  const runPromise = run(child.context);\n  let timeoutId: ReturnType<typeof setTimeout> | undefined;\n  let timeoutError: TimeoutError | undefined;\n  const timeout = new Promise<Result<T, E | TimeoutError>>((resolve) => {\n    timeoutId = setTimeout(() => {\n      timeoutError = new TimeoutError({ timeoutMs });\n      child.abort(timeoutError);\n      resolve(Result.err(timeoutError));\n    }, timeoutMs);\n  });\n\n  const firstResult = await Promise.race([runPromise, timeout]).finally(() => {\n    if (timeoutId !== undefined) clearTimeout(timeoutId);\n    child.detach();\n  });\n\n  if (timeoutError === undefined) {\n    return firstResult;\n  }\n\n  const drainedResult = await runPromise;\n  return (\n    normalizeCleanupFailureAfterInterruption(drainedResult, timeoutError, \"prependInterruption\") ??\n    Result.err(timeoutError)\n  );\n}\n"],"mappings":"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"}