{"version":3,"file":"timeout.cjs","names":[],"sources":["../../../src/pregel/utils/timeout.ts"],"sourcesContent":["/**\n * Configuration for timing out node attempts.\n *\n * A timeout applies to a single attempt of a node/task. When a node has a\n * {@link RetryPolicy}, the timer resets for each retry attempt.\n *\n * Timeouts are expressed in **milliseconds**, matching other LangGraph.js\n * durations (e.g. {@link RetryPolicy} intervals and `stepTimeout`).\n *\n * @remarks\n * Cooperative cancellation: timeouts rely on aborting the node's\n * {@link AbortSignal} and dropping its buffered writes. A node that ignores its\n * `signal` and performs blocking work cannot be interrupted mid-operation, but\n * its writes are still discarded and `NodeTimeoutError` is raised.\n */\nexport type TimeoutPolicy = {\n  /**\n   * Hard wall-clock cap (in milliseconds) for a single node attempt.\n   *\n   * This timeout is never refreshed by progress signals or\n   * `runtime.heartbeat()`.\n   */\n  runTimeout?: number;\n\n  /**\n   * Maximum time (in milliseconds) a single node attempt may go without\n   * observable progress before timing out.\n   *\n   * Refreshed by writes, custom stream writer calls, child-task scheduling,\n   * LangChain callback events emitted under the node's run, and explicit\n   * `runtime.heartbeat()` calls (see {@link TimeoutPolicy.refreshOn}).\n   */\n  idleTimeout?: number;\n\n  /**\n   * Which signals refresh {@link TimeoutPolicy.idleTimeout}.\n   *\n   * - `\"auto\"` (default): refreshes on standard graph progress signals and\n   *   explicit heartbeats.\n   * - `\"heartbeat\"`: refreshes only on explicit `runtime.heartbeat()` calls.\n   */\n  refreshOn?: \"auto\" | \"heartbeat\";\n};\n\nfunction _coerceTimeoutMs(\n  value: number | undefined,\n  field: string\n): number | undefined {\n  if (value === undefined || value === null) {\n    return undefined;\n  }\n  if (typeof value !== \"number\" || Number.isNaN(value) || value <= 0) {\n    throw new Error(`${field} must be greater than 0`);\n  }\n  return value;\n}\n\n/**\n * Normalize a timeout value into a {@link TimeoutPolicy} with positive\n * millisecond fields, or `undefined` if no timeout is configured.\n *\n * A bare number (or `undefined`) is treated as a hard {@link\n * TimeoutPolicy.runTimeout}. Throws if any configured timeout is not greater\n * than 0, or if `refreshOn` is not `\"auto\"` or `\"heartbeat\"`.\n *\n * @internal\n */\nexport function coerceTimeoutPolicy(\n  value?: number | TimeoutPolicy\n): TimeoutPolicy | undefined {\n  if (value === undefined || value === null) {\n    return undefined;\n  }\n\n  const policy: TimeoutPolicy =\n    typeof value === \"number\" ? { runTimeout: value } : value;\n\n  const refreshOn = policy.refreshOn ?? \"auto\";\n  if (refreshOn !== \"auto\" && refreshOn !== \"heartbeat\") {\n    throw new Error('refreshOn must be \"auto\" or \"heartbeat\"');\n  }\n\n  const runTimeout = _coerceTimeoutMs(policy.runTimeout, \"runTimeout\");\n  const idleTimeout = _coerceTimeoutMs(policy.idleTimeout, \"idleTimeout\");\n\n  if (runTimeout === undefined && idleTimeout === undefined) {\n    return undefined;\n  }\n\n  return { runTimeout, idleTimeout, refreshOn };\n}\n"],"mappings":";AA4CA,SAAS,iBACP,OACA,OACoB;AACpB,KAAI,UAAU,KAAA,KAAa,UAAU,KACnC;AAEF,KAAI,OAAO,UAAU,YAAY,OAAO,MAAM,MAAM,IAAI,SAAS,EAC/D,OAAM,IAAI,MAAM,GAAG,MAAM,yBAAyB;AAEpD,QAAO;;;;;;;;;;;;AAaT,SAAgB,oBACd,OAC2B;AAC3B,KAAI,UAAU,KAAA,KAAa,UAAU,KACnC;CAGF,MAAM,SACJ,OAAO,UAAU,WAAW,EAAE,YAAY,OAAO,GAAG;CAEtD,MAAM,YAAY,OAAO,aAAa;AACtC,KAAI,cAAc,UAAU,cAAc,YACxC,OAAM,IAAI,MAAM,8CAA0C;CAG5D,MAAM,aAAa,iBAAiB,OAAO,YAAY,aAAa;CACpE,MAAM,cAAc,iBAAiB,OAAO,aAAa,cAAc;AAEvE,KAAI,eAAe,KAAA,KAAa,gBAAgB,KAAA,EAC9C;AAGF,QAAO;EAAE;EAAY;EAAa;EAAW"}