awaitly 1.35.0 → 2.0.0

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 (241) hide show
  1. package/dist/{duration.d.ts → di-BDlT7InM.d.cts} +15 -1
  2. package/dist/{duration.d.cts → di-BbFFfO8y.d.ts} +15 -1
  3. package/dist/errors-DtXvrCiO.d.cts +708 -0
  4. package/dist/errors-DtXvrCiO.d.ts +708 -0
  5. package/dist/index.cjs +4594 -1
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.d.cts +1970 -141
  8. package/dist/index.d.ts +1970 -141
  9. package/dist/index.js +4398 -1
  10. package/dist/index.js.map +1 -1
  11. package/dist/result.cjs +641 -1
  12. package/dist/result.cjs.map +1 -1
  13. package/dist/result.d.cts +29 -4
  14. package/dist/result.d.ts +29 -4
  15. package/dist/result.js +561 -1
  16. package/dist/result.js.map +1 -1
  17. package/dist/testing.cjs +4202 -8
  18. package/dist/testing.cjs.map +1 -1
  19. package/dist/testing.d.cts +2 -6
  20. package/dist/testing.d.ts +2 -6
  21. package/dist/testing.js +4154 -8
  22. package/dist/testing.js.map +1 -1
  23. package/dist/{run-entry-DGs0tySr.d.cts → types-B8NfNRGX.d.ts} +1078 -1502
  24. package/dist/{run-entry-BOuNyVoO.d.ts → types-BZ2f4MRR.d.cts} +1078 -1502
  25. package/dist/workflow.cjs +7096 -6
  26. package/dist/workflow.cjs.map +1 -1
  27. package/dist/workflow.d.cts +3346 -22
  28. package/dist/workflow.d.ts +3346 -22
  29. package/dist/workflow.js +6929 -6
  30. package/dist/workflow.js.map +1 -1
  31. package/package.json +3 -168
  32. package/dist/adapters.cjs +0 -7
  33. package/dist/adapters.cjs.map +0 -1
  34. package/dist/adapters.d.cts +0 -179
  35. package/dist/adapters.d.ts +0 -179
  36. package/dist/adapters.js +0 -7
  37. package/dist/adapters.js.map +0 -1
  38. package/dist/batch.cjs +0 -7
  39. package/dist/batch.cjs.map +0 -1
  40. package/dist/batch.d.cts +0 -200
  41. package/dist/batch.d.ts +0 -200
  42. package/dist/batch.js +0 -7
  43. package/dist/batch.js.map +0 -1
  44. package/dist/bind-deps.cjs +0 -2
  45. package/dist/bind-deps.cjs.map +0 -1
  46. package/dist/bind-deps.d.cts +0 -28
  47. package/dist/bind-deps.d.ts +0 -28
  48. package/dist/bind-deps.js +0 -2
  49. package/dist/bind-deps.js.map +0 -1
  50. package/dist/cache.cjs +0 -2
  51. package/dist/cache.cjs.map +0 -1
  52. package/dist/cache.d.cts +0 -269
  53. package/dist/cache.d.ts +0 -269
  54. package/dist/cache.js +0 -2
  55. package/dist/cache.js.map +0 -1
  56. package/dist/circuit-breaker.cjs +0 -7
  57. package/dist/circuit-breaker.cjs.map +0 -1
  58. package/dist/circuit-breaker.d.cts +0 -211
  59. package/dist/circuit-breaker.d.ts +0 -211
  60. package/dist/circuit-breaker.js +0 -7
  61. package/dist/circuit-breaker.js.map +0 -1
  62. package/dist/conditional.cjs +0 -2
  63. package/dist/conditional.cjs.map +0 -1
  64. package/dist/conditional.d.cts +0 -252
  65. package/dist/conditional.d.ts +0 -252
  66. package/dist/conditional.js +0 -2
  67. package/dist/conditional.js.map +0 -1
  68. package/dist/core.cjs +0 -7
  69. package/dist/core.cjs.map +0 -1
  70. package/dist/core.d.cts +0 -5
  71. package/dist/core.d.ts +0 -5
  72. package/dist/core.js +0 -7
  73. package/dist/core.js.map +0 -1
  74. package/dist/di-By77n4Fa.d.ts +0 -15
  75. package/dist/di-OJfsohf-.d.cts +0 -15
  76. package/dist/diagnostics.cjs +0 -8
  77. package/dist/diagnostics.cjs.map +0 -1
  78. package/dist/diagnostics.d.cts +0 -68
  79. package/dist/diagnostics.d.ts +0 -68
  80. package/dist/diagnostics.js +0 -8
  81. package/dist/diagnostics.js.map +0 -1
  82. package/dist/durable.cjs +0 -11
  83. package/dist/durable.cjs.map +0 -1
  84. package/dist/durable.d.cts +0 -9
  85. package/dist/durable.d.ts +0 -9
  86. package/dist/durable.js +0 -11
  87. package/dist/durable.js.map +0 -1
  88. package/dist/duration.cjs +0 -2
  89. package/dist/duration.cjs.map +0 -1
  90. package/dist/duration.js +0 -2
  91. package/dist/duration.js.map +0 -1
  92. package/dist/engine.cjs +0 -11
  93. package/dist/engine.cjs.map +0 -1
  94. package/dist/engine.d.cts +0 -115
  95. package/dist/engine.d.ts +0 -115
  96. package/dist/engine.js +0 -11
  97. package/dist/engine.js.map +0 -1
  98. package/dist/errors.cjs +0 -2
  99. package/dist/errors.cjs.map +0 -1
  100. package/dist/errors.d.cts +0 -361
  101. package/dist/errors.d.ts +0 -361
  102. package/dist/errors.js +0 -2
  103. package/dist/errors.js.map +0 -1
  104. package/dist/fetch.cjs +0 -7
  105. package/dist/fetch.cjs.map +0 -1
  106. package/dist/fetch.d.cts +0 -86
  107. package/dist/fetch.d.ts +0 -86
  108. package/dist/fetch.js +0 -7
  109. package/dist/fetch.js.map +0 -1
  110. package/dist/flow.cjs +0 -7
  111. package/dist/flow.cjs.map +0 -1
  112. package/dist/flow.d.cts +0 -163
  113. package/dist/flow.d.ts +0 -163
  114. package/dist/flow.js +0 -7
  115. package/dist/flow.js.map +0 -1
  116. package/dist/functional.cjs +0 -2
  117. package/dist/functional.cjs.map +0 -1
  118. package/dist/functional.d.cts +0 -444
  119. package/dist/functional.d.ts +0 -444
  120. package/dist/functional.js +0 -2
  121. package/dist/functional.js.map +0 -1
  122. package/dist/guards-4sV7mTqj.d.cts +0 -72
  123. package/dist/guards-BIX05ALH.d.ts +0 -72
  124. package/dist/hitl-DFn4Xa_l.d.cts +0 -468
  125. package/dist/hitl-DU5VpKq7.d.ts +0 -468
  126. package/dist/hitl.cjs +0 -7
  127. package/dist/hitl.cjs.map +0 -1
  128. package/dist/hitl.d.cts +0 -442
  129. package/dist/hitl.d.ts +0 -442
  130. package/dist/hitl.js +0 -7
  131. package/dist/hitl.js.map +0 -1
  132. package/dist/index-CnvBryQB.d.ts +0 -417
  133. package/dist/index-DEZEf8Fs.d.cts +0 -417
  134. package/dist/match-entry-DjI2bLpD.d.cts +0 -209
  135. package/dist/match-entry-DjI2bLpD.d.ts +0 -209
  136. package/dist/match.cjs +0 -2
  137. package/dist/match.cjs.map +0 -1
  138. package/dist/match.d.cts +0 -1
  139. package/dist/match.d.ts +0 -1
  140. package/dist/match.js +0 -2
  141. package/dist/match.js.map +0 -1
  142. package/dist/otel.cjs +0 -2
  143. package/dist/otel.cjs.map +0 -1
  144. package/dist/otel.d.cts +0 -188
  145. package/dist/otel.d.ts +0 -188
  146. package/dist/otel.js +0 -2
  147. package/dist/otel.js.map +0 -1
  148. package/dist/persistence-entry-B-8PjnSR.d.cts +0 -831
  149. package/dist/persistence-entry-D8zRkLiT.d.ts +0 -831
  150. package/dist/persistence.cjs +0 -2
  151. package/dist/persistence.cjs.map +0 -1
  152. package/dist/persistence.d.cts +0 -7
  153. package/dist/persistence.d.ts +0 -7
  154. package/dist/persistence.js +0 -2
  155. package/dist/persistence.js.map +0 -1
  156. package/dist/policies.cjs +0 -2
  157. package/dist/policies.cjs.map +0 -1
  158. package/dist/policies.d.cts +0 -379
  159. package/dist/policies.d.ts +0 -379
  160. package/dist/policies.js +0 -2
  161. package/dist/policies.js.map +0 -1
  162. package/dist/ratelimit.cjs +0 -7
  163. package/dist/ratelimit.cjs.map +0 -1
  164. package/dist/ratelimit.d.cts +0 -458
  165. package/dist/ratelimit.d.ts +0 -458
  166. package/dist/ratelimit.js +0 -7
  167. package/dist/ratelimit.js.map +0 -1
  168. package/dist/reliability.cjs +0 -11
  169. package/dist/reliability.cjs.map +0 -1
  170. package/dist/reliability.d.cts +0 -11
  171. package/dist/reliability.d.ts +0 -11
  172. package/dist/reliability.js +0 -11
  173. package/dist/reliability.js.map +0 -1
  174. package/dist/resolver.cjs +0 -7
  175. package/dist/resolver.cjs.map +0 -1
  176. package/dist/resolver.d.cts +0 -68
  177. package/dist/resolver.d.ts +0 -68
  178. package/dist/resolver.js +0 -7
  179. package/dist/resolver.js.map +0 -1
  180. package/dist/resource.cjs +0 -7
  181. package/dist/resource.cjs.map +0 -1
  182. package/dist/resource.d.cts +0 -174
  183. package/dist/resource.d.ts +0 -174
  184. package/dist/resource.js +0 -7
  185. package/dist/resource.js.map +0 -1
  186. package/dist/result/retry.cjs +0 -2
  187. package/dist/result/retry.cjs.map +0 -1
  188. package/dist/result/retry.d.cts +0 -70
  189. package/dist/result/retry.d.ts +0 -70
  190. package/dist/result/retry.js +0 -2
  191. package/dist/result/retry.js.map +0 -1
  192. package/dist/retry.cjs +0 -2
  193. package/dist/retry.cjs.map +0 -1
  194. package/dist/retry.d.cts +0 -388
  195. package/dist/retry.d.ts +0 -388
  196. package/dist/retry.js +0 -2
  197. package/dist/retry.js.map +0 -1
  198. package/dist/run.cjs +0 -7
  199. package/dist/run.cjs.map +0 -1
  200. package/dist/run.d.cts +0 -4
  201. package/dist/run.d.ts +0 -4
  202. package/dist/run.js +0 -7
  203. package/dist/run.js.map +0 -1
  204. package/dist/saga.cjs +0 -11
  205. package/dist/saga.cjs.map +0 -1
  206. package/dist/saga.d.cts +0 -164
  207. package/dist/saga.d.ts +0 -164
  208. package/dist/saga.js +0 -11
  209. package/dist/saga.js.map +0 -1
  210. package/dist/singleflight.cjs +0 -2
  211. package/dist/singleflight.cjs.map +0 -1
  212. package/dist/singleflight.d.cts +0 -145
  213. package/dist/singleflight.d.ts +0 -145
  214. package/dist/singleflight.js +0 -2
  215. package/dist/singleflight.js.map +0 -1
  216. package/dist/slugs.cjs +0 -2
  217. package/dist/slugs.cjs.map +0 -1
  218. package/dist/slugs.d.cts +0 -67
  219. package/dist/slugs.d.ts +0 -67
  220. package/dist/slugs.js +0 -2
  221. package/dist/slugs.js.map +0 -1
  222. package/dist/streaming.cjs +0 -9
  223. package/dist/streaming.cjs.map +0 -1
  224. package/dist/streaming.d.cts +0 -596
  225. package/dist/streaming.d.ts +0 -596
  226. package/dist/streaming.js +0 -9
  227. package/dist/streaming.js.map +0 -1
  228. package/dist/tagged-error.cjs +0 -2
  229. package/dist/tagged-error.cjs.map +0 -1
  230. package/dist/tagged-error.d.cts +0 -275
  231. package/dist/tagged-error.d.ts +0 -275
  232. package/dist/tagged-error.js +0 -2
  233. package/dist/tagged-error.js.map +0 -1
  234. package/dist/types-BziYHFkD.d.ts +0 -323
  235. package/dist/types-C5jLEUqY.d.cts +0 -323
  236. package/dist/webhook.cjs +0 -7
  237. package/dist/webhook.cjs.map +0 -1
  238. package/dist/webhook.d.cts +0 -499
  239. package/dist/webhook.d.ts +0 -499
  240. package/dist/webhook.js +0 -7
  241. package/dist/webhook.js.map +0 -1
@@ -1,2 +0,0 @@
1
- "use strict";var d=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var N=(t,e)=>{for(var n in e)d(t,n,{get:e[n],enumerable:!0})},R=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of V(e))!W.call(t,r)&&r!==n&&d(t,r,{get:()=>e[r],enumerable:!(s=v(e,r))||s.enumerable});return t};var E=t=>R(d({},"__esModule",{value:!0}),t);var C={};N(C,{SnapshotDecodeError:()=>c,SnapshotFormatError:()=>l,SnapshotMismatchError:()=>p,assertValidSnapshot:()=>x,createMemoryCache:()=>O,deserializeCauseNew:()=>w,looksLikeWorkflowSnapshot:()=>y,mergeSnapshots:()=>b,serializeError:()=>g,serializeThrown:()=>h,validateSnapshot:()=>m});module.exports=E(C);var l=class extends Error{constructor(n,s=[]){super(n);this.errors=s;this.name="SnapshotFormatError"}errors},p=class extends Error{constructor(n,s,r){super(n);this.mismatchType=s;this.details=r;this.name="SnapshotMismatchError"}mismatchType;details},c=class extends Error{constructor(n,s,r){super(n);this.stepId=s;this.originalError=r;this.name="SnapshotDecodeError"}stepId;originalError};function y(t){return typeof t=="object"&&t!==null&&"formatVersion"in t&&t.formatVersion===1&&"steps"in t&&typeof t.steps=="object"&&t.steps!==null&&"execution"in t&&typeof t.execution=="object"}function m(t){let e=[];if(typeof t!="object"||t===null)return{valid:!1,errors:["Snapshot must be an object"]};let n=t;if("formatVersion"in n?n.formatVersion!==1&&e.push(`Invalid formatVersion: expected 1, got ${n.formatVersion}`):e.push("Missing required field: formatVersion"),!("steps"in n))e.push("Missing required field: steps");else if(typeof n.steps!="object"||n.steps===null)e.push("steps must be an object");else{let s=n.steps;for(let[r,u]of Object.entries(s)){if(typeof u!="object"||u===null){e.push(`steps["${r}"] must be an object`);continue}let i=u;"ok"in i?typeof i.ok!="boolean"?e.push(`steps["${r}"].ok must be a boolean`):i.ok===!1&&("error"in i||e.push(`steps["${r}"] is error result but missing error field`),"cause"in i||e.push(`steps["${r}"] is error result but missing cause field`)):e.push(`steps["${r}"] missing required field: ok`)}}if(!("execution"in n))e.push("Missing required field: execution");else if(typeof n.execution!="object"||n.execution===null)e.push("execution must be an object");else{let s=n.execution;"status"in s?["running","completed","failed"].includes(s.status)||e.push("execution.status must be one of: running, completed, failed"):e.push("execution missing required field: status"),"lastUpdated"in s?typeof s.lastUpdated!="string"&&e.push("execution.lastUpdated must be a string (ISO timestamp)"):e.push("execution missing required field: lastUpdated")}return e.length>0?{valid:!1,errors:e}:{valid:!0,snapshot:t}}function x(t){let e=m(t);if(!e.valid)throw new l(`Invalid snapshot format: ${e.errors[0]}`,e.errors);return e.snapshot}function b(t,e){let n=Object.create(null);for(let[i,o]of Object.entries(t.steps))Object.prototype.hasOwnProperty.call(t.steps,i)&&(n[i]=o);for(let[i,o]of Object.entries(e.steps))Object.prototype.hasOwnProperty.call(e.steps,i)&&(n[i]=o);let s=t.metadata||e.metadata?{...t.metadata,...e.metadata}:void 0,u=[...(t.warnings||[]).filter(i=>!Object.prototype.hasOwnProperty.call(e.steps,i.stepId)),...e.warnings||[]];return{formatVersion:1,steps:n,execution:{...e.execution},metadata:s,warnings:u.length>0?u:void 0}}var S=1e3;function g(t){let e={type:"error",name:t.name,message:t.message};t.stack&&(e.stack=t.stack);let n=t;return n.cause!==void 0&&(n.cause instanceof Error?e.cause=g(n.cause):e.cause=h(n.cause)),e}function h(t){let e,n=!1;try{e=String(t),e.length>S&&(e=e.slice(0,S),n=!0)}catch{e="[unable to convert to string]"}let s=t===null?"null":typeof t=="object"?t.constructor?.name??"Object":typeof t,r;try{let i=JSON.stringify(t);i!==void 0&&(r=JSON.parse(i))}catch{}let u={type:"thrown",originalType:s,stringRepresentation:e};return r!==void 0&&(u.value=r),n&&(u.truncated=!0),u}function w(t){if(t.type==="error"){let e=new Error(t.message);return e.name=t.name,t.stack&&(e.stack=t.stack),t.cause&&(e.cause=w(t.cause)),e}return t.value!==void 0?t.value:t.stringRepresentation}function O(t={}){let{maxSize:e,ttl:n}=t,s=new Map,r=o=>{let a=o.entryTtl??n;return a?Date.now()-o.timestamp>a:!1},u=()=>{for(let[o,a]of s)r(a)&&s.delete(o)},i=()=>{if(!e||s.size<e)return;let o,a=1/0;for(let[f,k]of s)k.timestamp<a&&(a=k.timestamp,o=f);o&&s.delete(o)};return{get(o){u();let a=s.get(o);if(a){if(r(a)){s.delete(o);return}return a.result}},set(o,a,f){u(),i(),s.set(o,{result:a,timestamp:Date.now(),entryTtl:f?.ttl})},has(o){u();let a=s.get(o);return a?r(a)?(s.delete(o),!1):!0:!1},delete(o){return s.delete(o)},clear(){s.clear()}}}0&&(module.exports={SnapshotDecodeError,SnapshotFormatError,SnapshotMismatchError,assertValidSnapshot,createMemoryCache,deserializeCauseNew,looksLikeWorkflowSnapshot,mergeSnapshots,serializeError,serializeThrown,validateSnapshot});
2
- //# sourceMappingURL=persistence.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/persistence-entry.ts","../src/persistence.ts"],"sourcesContent":["/**\n * awaitly/persistence\n *\n * Simplified Persistence API for workflow snapshots.\n */\n\n// =============================================================================\n// Snapshot API (JSON-serializable workflow state)\n// =============================================================================\nexport {\n // Types\n type JSONValue,\n type WorkflowSnapshot,\n type StepResult,\n type SerializedCause,\n type SnapshotWarning,\n\n // Store interface\n type SnapshotStore,\n\n // Validation\n looksLikeWorkflowSnapshot,\n validateSnapshot,\n assertValidSnapshot,\n mergeSnapshots,\n\n // Error classes\n SnapshotFormatError,\n SnapshotMismatchError,\n SnapshotDecodeError,\n\n // Serialization helpers (for custom implementations)\n serializeError,\n serializeThrown,\n deserializeCauseNew,\n\n // Cache adapter\n type MemoryCacheOptions,\n createMemoryCache,\n} from \"./persistence\";\n","/**\n * awaitly/persistence\n *\n * Simplified Persistence API for workflow snapshots.\n * Provides JSON-serializable snapshot format and store adapters.\n */\n\nimport type { Result } from \"./core\";\nimport type { StepCache } from \"./workflow\";\n\n// =============================================================================\n// JSON-Safe Type Enforcement\n// =============================================================================\n\n/**\n * Enforce JSON-safety at type level.\n * Only allows values that can be safely serialized with JSON.stringify.\n */\nexport type JSONValue =\n | null\n | boolean\n | number\n | string\n | JSONValue[]\n | { [k: string]: JSONValue };\n\n// =============================================================================\n// WorkflowSnapshot Types (Simplified API)\n// =============================================================================\n\n/**\n * Canonical error wire format - handles both Error instances and thrown non-Errors.\n * This is the single source of truth for serialized errors in snapshots.\n */\nexport type SerializedCause =\n | { type: \"error\"; name: string; message: string; stack?: string; cause?: SerializedCause }\n | { type: \"thrown\"; originalType?: string; value?: JSONValue; stringRepresentation: string; truncated?: true };\n\n/**\n * Single source of truth for step outcome (no error/cause confusion).\n * Uses discriminated union with `ok` field.\n */\nexport type StepResult =\n | { ok: true; value: JSONValue }\n | { ok: false; error: JSONValue; cause: SerializedCause; meta?: { origin: \"result\" | \"throw\" } };\n\n/**\n * JSON-serializable workflow snapshot.\n * Designed to be passed directly to JSON.stringify without special handling.\n *\n * @example\n * ```typescript\n * // Persist\n * localStorage.setItem('wf-123', JSON.stringify(wf.getSnapshot()));\n *\n * // Restore (safe pattern - storage can be empty/corrupt)\n * const raw = localStorage.getItem('wf-123');\n * const snapshot = raw ? JSON.parse(raw) : null;\n * createWorkflow(deps, { snapshot }); // null = fresh start\n * ```\n */\nexport interface WorkflowSnapshot {\n /** Snapshot format version (literal type - bump when shape changes) */\n formatVersion: 1;\n /** Workflow name (from createWorkflow first argument). */\n workflowName?: string;\n /** Step results keyed by step ID. Uses Object.create(null) internally. */\n steps: Record<string, StepResult>;\n /** Execution state metadata */\n execution: {\n status: \"running\" | \"completed\" | \"failed\";\n /** ISO timestamp (UTC toISOString()) */\n lastUpdated: string;\n /** ISO timestamp if finished */\n completedAt?: string;\n /**\n * For paused/running workflows: the step key of the current step.\n * Aligns with Workflow Diagram DSL step state ids (see awaitly/workflow diagram-dsl)\n * so visualizers can highlight the current node.\n */\n currentStepId?: string;\n };\n /** Optional metadata for workflow identification and replay */\n metadata?: {\n /** Detect wrong snapshot for wrong workflow */\n workflowId?: string;\n /** Optional: detect definition changes (user-supplied, advisory only) */\n definitionHash?: string;\n /** Original input for replay */\n input?: JSONValue;\n [key: string]: JSONValue | undefined;\n };\n /** Warnings for lossy serialization (keeps step results pure) */\n warnings?: Array<{\n type: \"lossy_value\";\n stepId: string;\n path: string;\n reason: \"non-json\" | \"circular\" | \"encode-failed\";\n }>;\n}\n\n/**\n * Warning entry for lossy value serialization.\n */\nexport type SnapshotWarning = NonNullable<WorkflowSnapshot[\"warnings\"]>[number];\n\n// =============================================================================\n// Snapshot Validation\n// =============================================================================\n\n/**\n * Error thrown when snapshot structure is invalid.\n */\nexport class SnapshotFormatError extends Error {\n constructor(\n message: string,\n public readonly errors: string[] = []\n ) {\n super(message);\n this.name = \"SnapshotFormatError\";\n }\n}\n\n/**\n * Error thrown when snapshot doesn't match workflow (unknown steps, workflowId mismatch).\n */\nexport class SnapshotMismatchError extends Error {\n constructor(\n message: string,\n public readonly mismatchType: \"unknown_steps\" | \"workflow_id\" | \"definition_hash\",\n public readonly details?: {\n unknownSteps?: string[];\n snapshotWorkflowId?: string;\n expectedWorkflowId?: string;\n snapshotHash?: string;\n expectedHash?: string;\n }\n ) {\n super(message);\n this.name = \"SnapshotMismatchError\";\n }\n}\n\n/**\n * Error thrown when decode fails during restore.\n */\nexport class SnapshotDecodeError extends Error {\n constructor(\n message: string,\n public readonly stepId: string,\n public readonly originalError?: unknown\n ) {\n super(message);\n this.name = \"SnapshotDecodeError\";\n }\n}\n\n/**\n * Light check to see if an object looks like a WorkflowSnapshot.\n * Cheap check for basic structure - use validateSnapshot() for full validation.\n *\n * @example\n * ```typescript\n * const raw = JSON.parse(localStorage.getItem('wf-123') || 'null');\n * if (looksLikeWorkflowSnapshot(raw)) {\n * createWorkflow(deps, { snapshot: raw });\n * }\n * ```\n */\nexport function looksLikeWorkflowSnapshot(obj: unknown): obj is WorkflowSnapshot {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"formatVersion\" in obj &&\n (obj as { formatVersion: unknown }).formatVersion === 1 &&\n \"steps\" in obj &&\n typeof (obj as { steps: unknown }).steps === \"object\" &&\n (obj as { steps: unknown }).steps !== null &&\n \"execution\" in obj &&\n typeof (obj as { execution: unknown }).execution === \"object\"\n );\n}\n\n/**\n * Type guard for WorkflowSnapshot. Same as looksLikeWorkflowSnapshot; use for consistent naming with isResumeState / isSerializedResumeState.\n */\nexport const isWorkflowSnapshot = looksLikeWorkflowSnapshot;\n\n/**\n * Full validation with detailed errors.\n * Returns either a validated snapshot or an array of validation errors.\n */\nexport function validateSnapshot(obj: unknown): { valid: true; snapshot: WorkflowSnapshot } | { valid: false; errors: string[] } {\n const errors: string[] = [];\n\n if (typeof obj !== \"object\" || obj === null) {\n return { valid: false, errors: [\"Snapshot must be an object\"] };\n }\n\n const snapshot = obj as Record<string, unknown>;\n\n // Check formatVersion\n if (!(\"formatVersion\" in snapshot)) {\n errors.push(\"Missing required field: formatVersion\");\n } else if (snapshot.formatVersion !== 1) {\n errors.push(`Invalid formatVersion: expected 1, got ${snapshot.formatVersion}`);\n }\n\n // Check steps\n if (!(\"steps\" in snapshot)) {\n errors.push(\"Missing required field: steps\");\n } else if (typeof snapshot.steps !== \"object\" || snapshot.steps === null) {\n errors.push(\"steps must be an object\");\n } else {\n // Validate each step result\n const steps = snapshot.steps as Record<string, unknown>;\n for (const [stepId, stepResult] of Object.entries(steps)) {\n if (typeof stepResult !== \"object\" || stepResult === null) {\n errors.push(`steps[\"${stepId}\"] must be an object`);\n continue;\n }\n\n const step = stepResult as Record<string, unknown>;\n if (!(\"ok\" in step)) {\n errors.push(`steps[\"${stepId}\"] missing required field: ok`);\n } else if (typeof step.ok !== \"boolean\") {\n errors.push(`steps[\"${stepId}\"].ok must be a boolean`);\n } else if (step.ok === false) {\n if (!(\"error\" in step)) {\n errors.push(`steps[\"${stepId}\"] is error result but missing error field`);\n }\n if (!(\"cause\" in step)) {\n errors.push(`steps[\"${stepId}\"] is error result but missing cause field`);\n }\n }\n }\n }\n\n // Check execution\n if (!(\"execution\" in snapshot)) {\n errors.push(\"Missing required field: execution\");\n } else if (typeof snapshot.execution !== \"object\" || snapshot.execution === null) {\n errors.push(\"execution must be an object\");\n } else {\n const execution = snapshot.execution as Record<string, unknown>;\n if (!(\"status\" in execution)) {\n errors.push(\"execution missing required field: status\");\n } else if (![\"running\", \"completed\", \"failed\"].includes(execution.status as string)) {\n errors.push(`execution.status must be one of: running, completed, failed`);\n }\n if (!(\"lastUpdated\" in execution)) {\n errors.push(\"execution missing required field: lastUpdated\");\n } else if (typeof execution.lastUpdated !== \"string\") {\n errors.push(\"execution.lastUpdated must be a string (ISO timestamp)\");\n }\n }\n\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n return { valid: true, snapshot: obj as WorkflowSnapshot };\n}\n\n/**\n * Throwing helper for cleaner code.\n * Validates a snapshot and throws SnapshotFormatError if invalid.\n *\n * @throws {SnapshotFormatError} If snapshot is invalid\n */\nexport function assertValidSnapshot(obj: unknown): WorkflowSnapshot {\n const result = validateSnapshot(obj);\n if (!result.valid) {\n throw new SnapshotFormatError(`Invalid snapshot format: ${result.errors[0]}`, result.errors);\n }\n return result.snapshot;\n}\n\n// =============================================================================\n// Snapshot Merge Helper\n// =============================================================================\n\n/**\n * Merge two snapshots (for incremental updates).\n * Delta steps overwrite base steps; execution from delta; metadata shallow merge.\n */\nexport function mergeSnapshots(base: WorkflowSnapshot, delta: WorkflowSnapshot): WorkflowSnapshot {\n // Create new steps object using Object.create(null) for prototype safety\n const mergedSteps = Object.create(null) as Record<string, StepResult>;\n\n // Copy base steps (use Object.prototype.hasOwnProperty for ES2020 compat)\n for (const [key, value] of Object.entries(base.steps)) {\n if (Object.prototype.hasOwnProperty.call(base.steps, key)) {\n mergedSteps[key] = value;\n }\n }\n\n // Overlay delta steps\n for (const [key, value] of Object.entries(delta.steps)) {\n if (Object.prototype.hasOwnProperty.call(delta.steps, key)) {\n mergedSteps[key] = value;\n }\n }\n\n // Merge metadata (delta wins for conflicts)\n const mergedMetadata = base.metadata || delta.metadata\n ? { ...base.metadata, ...delta.metadata }\n : undefined;\n\n // Merge warnings: only keep base warnings for steps not re-executed in delta.\n // If a step was re-executed and serialized cleanly, its old warning should disappear.\n const baseWarnings = (base.warnings || []).filter(\n (w) => !Object.prototype.hasOwnProperty.call(delta.steps, w.stepId)\n );\n const mergedWarnings = [...baseWarnings, ...(delta.warnings || [])];\n\n return {\n formatVersion: 1,\n steps: mergedSteps,\n execution: { ...delta.execution },\n metadata: mergedMetadata,\n warnings: mergedWarnings.length > 0 ? mergedWarnings : undefined,\n };\n}\n\n// =============================================================================\n// Serialization Helpers\n// =============================================================================\n\n/**\n * Maximum length for string representation in thrown non-Error values.\n */\nconst MAX_STRING_REPRESENTATION_LENGTH = 1000;\n\n/**\n * Serialize an Error object to SerializedCause format.\n * Preserves Error.cause recursively.\n */\nexport function serializeError(error: Error): SerializedCause {\n const serialized: SerializedCause = {\n type: \"error\",\n name: error.name,\n message: error.message,\n };\n\n if (error.stack) {\n serialized.stack = error.stack;\n }\n\n // Recursively serialize Error.cause if present (ES2022 feature, but commonly available)\n const errorWithCause = error as Error & { cause?: unknown };\n if (errorWithCause.cause !== undefined) {\n if (errorWithCause.cause instanceof Error) {\n serialized.cause = serializeError(errorWithCause.cause);\n } else {\n // cause is not an Error, serialize as thrown value\n serialized.cause = serializeThrown(errorWithCause.cause);\n }\n }\n\n return serialized;\n}\n\n/**\n * Serialize a non-Error thrown value to SerializedCause format.\n */\nexport function serializeThrown(value: unknown): SerializedCause {\n // Get string representation\n let stringRepresentation: string;\n let truncated = false;\n\n try {\n stringRepresentation = String(value);\n if (stringRepresentation.length > MAX_STRING_REPRESENTATION_LENGTH) {\n stringRepresentation = stringRepresentation.slice(0, MAX_STRING_REPRESENTATION_LENGTH);\n truncated = true;\n }\n } catch {\n stringRepresentation = \"[unable to convert to string]\";\n }\n\n // Try to get the original type\n const originalType = value === null\n ? \"null\"\n : typeof value === \"object\"\n ? (value.constructor?.name ?? \"Object\")\n : typeof value;\n\n // Try to serialize the value as JSON\n let jsonValue: JSONValue | undefined;\n try {\n const serialized = JSON.stringify(value);\n if (serialized !== undefined) {\n jsonValue = JSON.parse(serialized) as JSONValue;\n }\n } catch {\n // Non-JSON-serializable, will only use stringRepresentation\n }\n\n const result: SerializedCause = {\n type: \"thrown\",\n originalType,\n stringRepresentation,\n };\n\n if (jsonValue !== undefined) {\n result.value = jsonValue;\n }\n\n if (truncated) {\n result.truncated = true;\n }\n\n return result;\n}\n\n/**\n * Deserialize a SerializedCause back to its original form.\n */\nexport function deserializeCauseNew(serialized: SerializedCause): unknown {\n if (serialized.type === \"error\") {\n const error = new Error(serialized.message);\n error.name = serialized.name;\n if (serialized.stack) {\n error.stack = serialized.stack;\n }\n if (serialized.cause) {\n (error as Error & { cause: unknown }).cause = deserializeCauseNew(serialized.cause);\n }\n return error;\n }\n\n // type === \"thrown\"\n // Return the JSON value if available, otherwise the string representation\n return serialized.value !== undefined ? serialized.value : serialized.stringRepresentation;\n}\n\n// =============================================================================\n// SnapshotStore Interface (New Simplified API)\n// =============================================================================\n\n/**\n * Simplified store interface for workflow snapshot persistence.\n * Works directly with WorkflowSnapshot objects.\n *\n * Adapters may implement an extended contract (see awaitly/workflow): save can accept\n * WorkflowSnapshot | ResumeState; load can return WorkflowSnapshot | ResumeState | null.\n * Use isWorkflowSnapshot / isSerializedResumeState and serializeResumeState / deserializeResumeState\n * when branching. For type-safe restore, use store.loadResumeState(id) or toResumeState(await store.load(id)).\n *\n * @example\n * ```typescript\n * import { postgres } from 'awaitly-postgres';\n * import { createWorkflow } from 'awaitly/workflow';\n *\n * const store = postgres('postgresql://localhost/mydb');\n * const workflow = createWorkflow(deps);\n *\n * // Run and persist resume state\n * const { result, resumeState } = await workflow.runWithState(fn);\n * await store.save('wf-123', resumeState);\n *\n * // Restore\n * const loaded = await store.load('wf-123');\n * const resumeState = toResumeState(loaded);\n * if (resumeState) await workflow.run(fn, { resumeState });\n * ```\n */\nexport interface SnapshotStore {\n /** Save a workflow snapshot (upsert - insert or update). Adapters may also accept ResumeState. */\n save(id: string, snapshot: WorkflowSnapshot): Promise<void>;\n /** Load a workflow snapshot. Returns null if not found. Adapters may return ResumeState when stored as such. */\n load(id: string): Promise<WorkflowSnapshot | null>;\n /** Delete a workflow snapshot. */\n delete(id: string): Promise<void>;\n /** List workflow IDs with their last update time. */\n list(options?: { prefix?: string; limit?: number }): Promise<Array<{ id: string; updatedAt: string }>>;\n /** Clean shutdown for tests/graceful exit. */\n close(): Promise<void>;\n}\n\n// =============================================================================\n// In-Memory Cache Adapter\n// =============================================================================\n\n/**\n * Options for the in-memory cache adapter.\n */\nexport interface MemoryCacheOptions {\n /**\n * Maximum number of entries to store.\n * Oldest entries are evicted when limit is reached.\n */\n maxSize?: number;\n\n /**\n * Time-to-live in milliseconds.\n * Entries are automatically removed after this duration.\n */\n ttl?: number;\n}\n\n/**\n * Create an in-memory StepCache with optional LRU eviction and TTL.\n *\n * @param options - Cache options\n * @returns StepCache implementation\n *\n * @example\n * ```typescript\n * const cache = createMemoryCache({ maxSize: 1000, ttl: 60000 });\n * const workflow = createWorkflow(deps, { cache });\n * ```\n */\nexport function createMemoryCache(options: MemoryCacheOptions = {}): StepCache {\n const { maxSize, ttl } = options;\n const cache = new Map<string, {\n result: Result<unknown, unknown, unknown>;\n timestamp: number;\n entryTtl?: number;\n }>();\n\n const isExpired = (entry: { timestamp: number; entryTtl?: number }): boolean => {\n const effectiveTtl = entry.entryTtl ?? ttl;\n if (!effectiveTtl) return false;\n return Date.now() - entry.timestamp > effectiveTtl;\n };\n\n const evictExpired = (): void => {\n for (const [key, entry] of cache) {\n if (isExpired(entry)) {\n cache.delete(key);\n }\n }\n };\n\n const evictOldest = (): void => {\n if (!maxSize || cache.size < maxSize) return;\n\n // Find oldest entry\n let oldestKey: string | undefined;\n let oldestTime = Infinity;\n\n for (const [key, entry] of cache) {\n if (entry.timestamp < oldestTime) {\n oldestTime = entry.timestamp;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n cache.delete(oldestKey);\n }\n };\n\n return {\n get(key: string): Result<unknown, unknown, unknown> | undefined {\n evictExpired();\n const entry = cache.get(key);\n if (!entry) return undefined;\n if (isExpired(entry)) {\n cache.delete(key);\n return undefined;\n }\n return entry.result;\n },\n\n set(key: string, result: Result<unknown, unknown, unknown>, options?: { ttl?: number }): void {\n evictExpired();\n evictOldest();\n cache.set(key, { result, timestamp: Date.now(), entryTtl: options?.ttl });\n },\n\n has(key: string): boolean {\n evictExpired();\n const entry = cache.get(key);\n if (!entry) return false;\n if (isExpired(entry)) {\n cache.delete(key);\n return false;\n }\n return true;\n },\n\n delete(key: string): boolean {\n return cache.delete(key);\n },\n\n clear(): void {\n cache.clear();\n },\n };\n}\n"],"mappings":"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","names":["persistence_entry_exports","__export","SnapshotDecodeError","SnapshotFormatError","SnapshotMismatchError","assertValidSnapshot","createMemoryCache","deserializeCauseNew","looksLikeWorkflowSnapshot","mergeSnapshots","serializeError","serializeThrown","validateSnapshot","__toCommonJS","SnapshotFormatError","message","errors","SnapshotMismatchError","mismatchType","details","SnapshotDecodeError","stepId","originalError","looksLikeWorkflowSnapshot","obj","validateSnapshot","obj","errors","snapshot","steps","stepId","stepResult","step","execution","assertValidSnapshot","result","SnapshotFormatError","mergeSnapshots","base","delta","mergedSteps","key","value","mergedMetadata","mergedWarnings","w","MAX_STRING_REPRESENTATION_LENGTH","serializeError","error","serialized","errorWithCause","serializeThrown","stringRepresentation","truncated","originalType","jsonValue","deserializeCauseNew","createMemoryCache","options","maxSize","ttl","cache","isExpired","entry","effectiveTtl","evictExpired","evictOldest","oldestKey","oldestTime"]}
@@ -1,7 +0,0 @@
1
- export { J as JSONValue, M as MemoryCacheOptions, m as SerializedCause, n as SnapshotDecodeError, o as SnapshotFormatError, p as SnapshotMismatchError, S as SnapshotStore, q as SnapshotWarning, g as StepResult, a as WorkflowSnapshot, u as assertValidSnapshot, z as createMemoryCache, B as deserializeCauseNew, w as looksLikeWorkflowSnapshot, x as mergeSnapshots, D as serializeError, F as serializeThrown, y as validateSnapshot } from './persistence-entry-B-8PjnSR.cjs';
2
- import './run-entry-DGs0tySr.cjs';
3
- import './errors.cjs';
4
- import './tagged-error.cjs';
5
- import './slugs.cjs';
6
- import './types-C5jLEUqY.cjs';
7
- import '@standard-schema/spec';
@@ -1,7 +0,0 @@
1
- export { J as JSONValue, M as MemoryCacheOptions, m as SerializedCause, n as SnapshotDecodeError, o as SnapshotFormatError, p as SnapshotMismatchError, S as SnapshotStore, q as SnapshotWarning, g as StepResult, a as WorkflowSnapshot, u as assertValidSnapshot, z as createMemoryCache, B as deserializeCauseNew, w as looksLikeWorkflowSnapshot, x as mergeSnapshots, D as serializeError, F as serializeThrown, y as validateSnapshot } from './persistence-entry-D8zRkLiT.js';
2
- import './run-entry-BOuNyVoO.js';
3
- import './errors.js';
4
- import './tagged-error.js';
5
- import './slugs.js';
6
- import './types-BziYHFkD.js';
7
- import '@standard-schema/spec';
@@ -1,2 +0,0 @@
1
- var l=class extends Error{constructor(n,s=[]){super(n);this.errors=s;this.name="SnapshotFormatError"}errors},c=class extends Error{constructor(n,s,i){super(n);this.mismatchType=s;this.details=i;this.name="SnapshotMismatchError"}mismatchType;details},f=class extends Error{constructor(n,s,i){super(n);this.stepId=s;this.originalError=i;this.name="SnapshotDecodeError"}stepId;originalError};function S(t){return typeof t=="object"&&t!==null&&"formatVersion"in t&&t.formatVersion===1&&"steps"in t&&typeof t.steps=="object"&&t.steps!==null&&"execution"in t&&typeof t.execution=="object"}function g(t){let e=[];if(typeof t!="object"||t===null)return{valid:!1,errors:["Snapshot must be an object"]};let n=t;if("formatVersion"in n?n.formatVersion!==1&&e.push(`Invalid formatVersion: expected 1, got ${n.formatVersion}`):e.push("Missing required field: formatVersion"),!("steps"in n))e.push("Missing required field: steps");else if(typeof n.steps!="object"||n.steps===null)e.push("steps must be an object");else{let s=n.steps;for(let[i,u]of Object.entries(s)){if(typeof u!="object"||u===null){e.push(`steps["${i}"] must be an object`);continue}let o=u;"ok"in o?typeof o.ok!="boolean"?e.push(`steps["${i}"].ok must be a boolean`):o.ok===!1&&("error"in o||e.push(`steps["${i}"] is error result but missing error field`),"cause"in o||e.push(`steps["${i}"] is error result but missing cause field`)):e.push(`steps["${i}"] missing required field: ok`)}}if(!("execution"in n))e.push("Missing required field: execution");else if(typeof n.execution!="object"||n.execution===null)e.push("execution must be an object");else{let s=n.execution;"status"in s?["running","completed","failed"].includes(s.status)||e.push("execution.status must be one of: running, completed, failed"):e.push("execution missing required field: status"),"lastUpdated"in s?typeof s.lastUpdated!="string"&&e.push("execution.lastUpdated must be a string (ISO timestamp)"):e.push("execution missing required field: lastUpdated")}return e.length>0?{valid:!1,errors:e}:{valid:!0,snapshot:t}}function y(t){let e=g(t);if(!e.valid)throw new l(`Invalid snapshot format: ${e.errors[0]}`,e.errors);return e.snapshot}function x(t,e){let n=Object.create(null);for(let[o,r]of Object.entries(t.steps))Object.prototype.hasOwnProperty.call(t.steps,o)&&(n[o]=r);for(let[o,r]of Object.entries(e.steps))Object.prototype.hasOwnProperty.call(e.steps,o)&&(n[o]=r);let s=t.metadata||e.metadata?{...t.metadata,...e.metadata}:void 0,u=[...(t.warnings||[]).filter(o=>!Object.prototype.hasOwnProperty.call(e.steps,o.stepId)),...e.warnings||[]];return{formatVersion:1,steps:n,execution:{...e.execution},metadata:s,warnings:u.length>0?u:void 0}}var m=1e3;function h(t){let e={type:"error",name:t.name,message:t.message};t.stack&&(e.stack=t.stack);let n=t;return n.cause!==void 0&&(n.cause instanceof Error?e.cause=h(n.cause):e.cause=w(n.cause)),e}function w(t){let e,n=!1;try{e=String(t),e.length>m&&(e=e.slice(0,m),n=!0)}catch{e="[unable to convert to string]"}let s=t===null?"null":typeof t=="object"?t.constructor?.name??"Object":typeof t,i;try{let o=JSON.stringify(t);o!==void 0&&(i=JSON.parse(o))}catch{}let u={type:"thrown",originalType:s,stringRepresentation:e};return i!==void 0&&(u.value=i),n&&(u.truncated=!0),u}function k(t){if(t.type==="error"){let e=new Error(t.message);return e.name=t.name,t.stack&&(e.stack=t.stack),t.cause&&(e.cause=k(t.cause)),e}return t.value!==void 0?t.value:t.stringRepresentation}function b(t={}){let{maxSize:e,ttl:n}=t,s=new Map,i=r=>{let a=r.entryTtl??n;return a?Date.now()-r.timestamp>a:!1},u=()=>{for(let[r,a]of s)i(a)&&s.delete(r)},o=()=>{if(!e||s.size<e)return;let r,a=1/0;for(let[p,d]of s)d.timestamp<a&&(a=d.timestamp,r=p);r&&s.delete(r)};return{get(r){u();let a=s.get(r);if(a){if(i(a)){s.delete(r);return}return a.result}},set(r,a,p){u(),o(),s.set(r,{result:a,timestamp:Date.now(),entryTtl:p?.ttl})},has(r){u();let a=s.get(r);return a?i(a)?(s.delete(r),!1):!0:!1},delete(r){return s.delete(r)},clear(){s.clear()}}}export{f as SnapshotDecodeError,l as SnapshotFormatError,c as SnapshotMismatchError,y as assertValidSnapshot,b as createMemoryCache,k as deserializeCauseNew,S as looksLikeWorkflowSnapshot,x as mergeSnapshots,h as serializeError,w as serializeThrown,g as validateSnapshot};
2
- //# sourceMappingURL=persistence.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/persistence.ts"],"sourcesContent":["/**\n * awaitly/persistence\n *\n * Simplified Persistence API for workflow snapshots.\n * Provides JSON-serializable snapshot format and store adapters.\n */\n\nimport type { Result } from \"./core\";\nimport type { StepCache } from \"./workflow\";\n\n// =============================================================================\n// JSON-Safe Type Enforcement\n// =============================================================================\n\n/**\n * Enforce JSON-safety at type level.\n * Only allows values that can be safely serialized with JSON.stringify.\n */\nexport type JSONValue =\n | null\n | boolean\n | number\n | string\n | JSONValue[]\n | { [k: string]: JSONValue };\n\n// =============================================================================\n// WorkflowSnapshot Types (Simplified API)\n// =============================================================================\n\n/**\n * Canonical error wire format - handles both Error instances and thrown non-Errors.\n * This is the single source of truth for serialized errors in snapshots.\n */\nexport type SerializedCause =\n | { type: \"error\"; name: string; message: string; stack?: string; cause?: SerializedCause }\n | { type: \"thrown\"; originalType?: string; value?: JSONValue; stringRepresentation: string; truncated?: true };\n\n/**\n * Single source of truth for step outcome (no error/cause confusion).\n * Uses discriminated union with `ok` field.\n */\nexport type StepResult =\n | { ok: true; value: JSONValue }\n | { ok: false; error: JSONValue; cause: SerializedCause; meta?: { origin: \"result\" | \"throw\" } };\n\n/**\n * JSON-serializable workflow snapshot.\n * Designed to be passed directly to JSON.stringify without special handling.\n *\n * @example\n * ```typescript\n * // Persist\n * localStorage.setItem('wf-123', JSON.stringify(wf.getSnapshot()));\n *\n * // Restore (safe pattern - storage can be empty/corrupt)\n * const raw = localStorage.getItem('wf-123');\n * const snapshot = raw ? JSON.parse(raw) : null;\n * createWorkflow(deps, { snapshot }); // null = fresh start\n * ```\n */\nexport interface WorkflowSnapshot {\n /** Snapshot format version (literal type - bump when shape changes) */\n formatVersion: 1;\n /** Workflow name (from createWorkflow first argument). */\n workflowName?: string;\n /** Step results keyed by step ID. Uses Object.create(null) internally. */\n steps: Record<string, StepResult>;\n /** Execution state metadata */\n execution: {\n status: \"running\" | \"completed\" | \"failed\";\n /** ISO timestamp (UTC toISOString()) */\n lastUpdated: string;\n /** ISO timestamp if finished */\n completedAt?: string;\n /**\n * For paused/running workflows: the step key of the current step.\n * Aligns with Workflow Diagram DSL step state ids (see awaitly/workflow diagram-dsl)\n * so visualizers can highlight the current node.\n */\n currentStepId?: string;\n };\n /** Optional metadata for workflow identification and replay */\n metadata?: {\n /** Detect wrong snapshot for wrong workflow */\n workflowId?: string;\n /** Optional: detect definition changes (user-supplied, advisory only) */\n definitionHash?: string;\n /** Original input for replay */\n input?: JSONValue;\n [key: string]: JSONValue | undefined;\n };\n /** Warnings for lossy serialization (keeps step results pure) */\n warnings?: Array<{\n type: \"lossy_value\";\n stepId: string;\n path: string;\n reason: \"non-json\" | \"circular\" | \"encode-failed\";\n }>;\n}\n\n/**\n * Warning entry for lossy value serialization.\n */\nexport type SnapshotWarning = NonNullable<WorkflowSnapshot[\"warnings\"]>[number];\n\n// =============================================================================\n// Snapshot Validation\n// =============================================================================\n\n/**\n * Error thrown when snapshot structure is invalid.\n */\nexport class SnapshotFormatError extends Error {\n constructor(\n message: string,\n public readonly errors: string[] = []\n ) {\n super(message);\n this.name = \"SnapshotFormatError\";\n }\n}\n\n/**\n * Error thrown when snapshot doesn't match workflow (unknown steps, workflowId mismatch).\n */\nexport class SnapshotMismatchError extends Error {\n constructor(\n message: string,\n public readonly mismatchType: \"unknown_steps\" | \"workflow_id\" | \"definition_hash\",\n public readonly details?: {\n unknownSteps?: string[];\n snapshotWorkflowId?: string;\n expectedWorkflowId?: string;\n snapshotHash?: string;\n expectedHash?: string;\n }\n ) {\n super(message);\n this.name = \"SnapshotMismatchError\";\n }\n}\n\n/**\n * Error thrown when decode fails during restore.\n */\nexport class SnapshotDecodeError extends Error {\n constructor(\n message: string,\n public readonly stepId: string,\n public readonly originalError?: unknown\n ) {\n super(message);\n this.name = \"SnapshotDecodeError\";\n }\n}\n\n/**\n * Light check to see if an object looks like a WorkflowSnapshot.\n * Cheap check for basic structure - use validateSnapshot() for full validation.\n *\n * @example\n * ```typescript\n * const raw = JSON.parse(localStorage.getItem('wf-123') || 'null');\n * if (looksLikeWorkflowSnapshot(raw)) {\n * createWorkflow(deps, { snapshot: raw });\n * }\n * ```\n */\nexport function looksLikeWorkflowSnapshot(obj: unknown): obj is WorkflowSnapshot {\n return (\n typeof obj === \"object\" &&\n obj !== null &&\n \"formatVersion\" in obj &&\n (obj as { formatVersion: unknown }).formatVersion === 1 &&\n \"steps\" in obj &&\n typeof (obj as { steps: unknown }).steps === \"object\" &&\n (obj as { steps: unknown }).steps !== null &&\n \"execution\" in obj &&\n typeof (obj as { execution: unknown }).execution === \"object\"\n );\n}\n\n/**\n * Type guard for WorkflowSnapshot. Same as looksLikeWorkflowSnapshot; use for consistent naming with isResumeState / isSerializedResumeState.\n */\nexport const isWorkflowSnapshot = looksLikeWorkflowSnapshot;\n\n/**\n * Full validation with detailed errors.\n * Returns either a validated snapshot or an array of validation errors.\n */\nexport function validateSnapshot(obj: unknown): { valid: true; snapshot: WorkflowSnapshot } | { valid: false; errors: string[] } {\n const errors: string[] = [];\n\n if (typeof obj !== \"object\" || obj === null) {\n return { valid: false, errors: [\"Snapshot must be an object\"] };\n }\n\n const snapshot = obj as Record<string, unknown>;\n\n // Check formatVersion\n if (!(\"formatVersion\" in snapshot)) {\n errors.push(\"Missing required field: formatVersion\");\n } else if (snapshot.formatVersion !== 1) {\n errors.push(`Invalid formatVersion: expected 1, got ${snapshot.formatVersion}`);\n }\n\n // Check steps\n if (!(\"steps\" in snapshot)) {\n errors.push(\"Missing required field: steps\");\n } else if (typeof snapshot.steps !== \"object\" || snapshot.steps === null) {\n errors.push(\"steps must be an object\");\n } else {\n // Validate each step result\n const steps = snapshot.steps as Record<string, unknown>;\n for (const [stepId, stepResult] of Object.entries(steps)) {\n if (typeof stepResult !== \"object\" || stepResult === null) {\n errors.push(`steps[\"${stepId}\"] must be an object`);\n continue;\n }\n\n const step = stepResult as Record<string, unknown>;\n if (!(\"ok\" in step)) {\n errors.push(`steps[\"${stepId}\"] missing required field: ok`);\n } else if (typeof step.ok !== \"boolean\") {\n errors.push(`steps[\"${stepId}\"].ok must be a boolean`);\n } else if (step.ok === false) {\n if (!(\"error\" in step)) {\n errors.push(`steps[\"${stepId}\"] is error result but missing error field`);\n }\n if (!(\"cause\" in step)) {\n errors.push(`steps[\"${stepId}\"] is error result but missing cause field`);\n }\n }\n }\n }\n\n // Check execution\n if (!(\"execution\" in snapshot)) {\n errors.push(\"Missing required field: execution\");\n } else if (typeof snapshot.execution !== \"object\" || snapshot.execution === null) {\n errors.push(\"execution must be an object\");\n } else {\n const execution = snapshot.execution as Record<string, unknown>;\n if (!(\"status\" in execution)) {\n errors.push(\"execution missing required field: status\");\n } else if (![\"running\", \"completed\", \"failed\"].includes(execution.status as string)) {\n errors.push(`execution.status must be one of: running, completed, failed`);\n }\n if (!(\"lastUpdated\" in execution)) {\n errors.push(\"execution missing required field: lastUpdated\");\n } else if (typeof execution.lastUpdated !== \"string\") {\n errors.push(\"execution.lastUpdated must be a string (ISO timestamp)\");\n }\n }\n\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n return { valid: true, snapshot: obj as WorkflowSnapshot };\n}\n\n/**\n * Throwing helper for cleaner code.\n * Validates a snapshot and throws SnapshotFormatError if invalid.\n *\n * @throws {SnapshotFormatError} If snapshot is invalid\n */\nexport function assertValidSnapshot(obj: unknown): WorkflowSnapshot {\n const result = validateSnapshot(obj);\n if (!result.valid) {\n throw new SnapshotFormatError(`Invalid snapshot format: ${result.errors[0]}`, result.errors);\n }\n return result.snapshot;\n}\n\n// =============================================================================\n// Snapshot Merge Helper\n// =============================================================================\n\n/**\n * Merge two snapshots (for incremental updates).\n * Delta steps overwrite base steps; execution from delta; metadata shallow merge.\n */\nexport function mergeSnapshots(base: WorkflowSnapshot, delta: WorkflowSnapshot): WorkflowSnapshot {\n // Create new steps object using Object.create(null) for prototype safety\n const mergedSteps = Object.create(null) as Record<string, StepResult>;\n\n // Copy base steps (use Object.prototype.hasOwnProperty for ES2020 compat)\n for (const [key, value] of Object.entries(base.steps)) {\n if (Object.prototype.hasOwnProperty.call(base.steps, key)) {\n mergedSteps[key] = value;\n }\n }\n\n // Overlay delta steps\n for (const [key, value] of Object.entries(delta.steps)) {\n if (Object.prototype.hasOwnProperty.call(delta.steps, key)) {\n mergedSteps[key] = value;\n }\n }\n\n // Merge metadata (delta wins for conflicts)\n const mergedMetadata = base.metadata || delta.metadata\n ? { ...base.metadata, ...delta.metadata }\n : undefined;\n\n // Merge warnings: only keep base warnings for steps not re-executed in delta.\n // If a step was re-executed and serialized cleanly, its old warning should disappear.\n const baseWarnings = (base.warnings || []).filter(\n (w) => !Object.prototype.hasOwnProperty.call(delta.steps, w.stepId)\n );\n const mergedWarnings = [...baseWarnings, ...(delta.warnings || [])];\n\n return {\n formatVersion: 1,\n steps: mergedSteps,\n execution: { ...delta.execution },\n metadata: mergedMetadata,\n warnings: mergedWarnings.length > 0 ? mergedWarnings : undefined,\n };\n}\n\n// =============================================================================\n// Serialization Helpers\n// =============================================================================\n\n/**\n * Maximum length for string representation in thrown non-Error values.\n */\nconst MAX_STRING_REPRESENTATION_LENGTH = 1000;\n\n/**\n * Serialize an Error object to SerializedCause format.\n * Preserves Error.cause recursively.\n */\nexport function serializeError(error: Error): SerializedCause {\n const serialized: SerializedCause = {\n type: \"error\",\n name: error.name,\n message: error.message,\n };\n\n if (error.stack) {\n serialized.stack = error.stack;\n }\n\n // Recursively serialize Error.cause if present (ES2022 feature, but commonly available)\n const errorWithCause = error as Error & { cause?: unknown };\n if (errorWithCause.cause !== undefined) {\n if (errorWithCause.cause instanceof Error) {\n serialized.cause = serializeError(errorWithCause.cause);\n } else {\n // cause is not an Error, serialize as thrown value\n serialized.cause = serializeThrown(errorWithCause.cause);\n }\n }\n\n return serialized;\n}\n\n/**\n * Serialize a non-Error thrown value to SerializedCause format.\n */\nexport function serializeThrown(value: unknown): SerializedCause {\n // Get string representation\n let stringRepresentation: string;\n let truncated = false;\n\n try {\n stringRepresentation = String(value);\n if (stringRepresentation.length > MAX_STRING_REPRESENTATION_LENGTH) {\n stringRepresentation = stringRepresentation.slice(0, MAX_STRING_REPRESENTATION_LENGTH);\n truncated = true;\n }\n } catch {\n stringRepresentation = \"[unable to convert to string]\";\n }\n\n // Try to get the original type\n const originalType = value === null\n ? \"null\"\n : typeof value === \"object\"\n ? (value.constructor?.name ?? \"Object\")\n : typeof value;\n\n // Try to serialize the value as JSON\n let jsonValue: JSONValue | undefined;\n try {\n const serialized = JSON.stringify(value);\n if (serialized !== undefined) {\n jsonValue = JSON.parse(serialized) as JSONValue;\n }\n } catch {\n // Non-JSON-serializable, will only use stringRepresentation\n }\n\n const result: SerializedCause = {\n type: \"thrown\",\n originalType,\n stringRepresentation,\n };\n\n if (jsonValue !== undefined) {\n result.value = jsonValue;\n }\n\n if (truncated) {\n result.truncated = true;\n }\n\n return result;\n}\n\n/**\n * Deserialize a SerializedCause back to its original form.\n */\nexport function deserializeCauseNew(serialized: SerializedCause): unknown {\n if (serialized.type === \"error\") {\n const error = new Error(serialized.message);\n error.name = serialized.name;\n if (serialized.stack) {\n error.stack = serialized.stack;\n }\n if (serialized.cause) {\n (error as Error & { cause: unknown }).cause = deserializeCauseNew(serialized.cause);\n }\n return error;\n }\n\n // type === \"thrown\"\n // Return the JSON value if available, otherwise the string representation\n return serialized.value !== undefined ? serialized.value : serialized.stringRepresentation;\n}\n\n// =============================================================================\n// SnapshotStore Interface (New Simplified API)\n// =============================================================================\n\n/**\n * Simplified store interface for workflow snapshot persistence.\n * Works directly with WorkflowSnapshot objects.\n *\n * Adapters may implement an extended contract (see awaitly/workflow): save can accept\n * WorkflowSnapshot | ResumeState; load can return WorkflowSnapshot | ResumeState | null.\n * Use isWorkflowSnapshot / isSerializedResumeState and serializeResumeState / deserializeResumeState\n * when branching. For type-safe restore, use store.loadResumeState(id) or toResumeState(await store.load(id)).\n *\n * @example\n * ```typescript\n * import { postgres } from 'awaitly-postgres';\n * import { createWorkflow } from 'awaitly/workflow';\n *\n * const store = postgres('postgresql://localhost/mydb');\n * const workflow = createWorkflow(deps);\n *\n * // Run and persist resume state\n * const { result, resumeState } = await workflow.runWithState(fn);\n * await store.save('wf-123', resumeState);\n *\n * // Restore\n * const loaded = await store.load('wf-123');\n * const resumeState = toResumeState(loaded);\n * if (resumeState) await workflow.run(fn, { resumeState });\n * ```\n */\nexport interface SnapshotStore {\n /** Save a workflow snapshot (upsert - insert or update). Adapters may also accept ResumeState. */\n save(id: string, snapshot: WorkflowSnapshot): Promise<void>;\n /** Load a workflow snapshot. Returns null if not found. Adapters may return ResumeState when stored as such. */\n load(id: string): Promise<WorkflowSnapshot | null>;\n /** Delete a workflow snapshot. */\n delete(id: string): Promise<void>;\n /** List workflow IDs with their last update time. */\n list(options?: { prefix?: string; limit?: number }): Promise<Array<{ id: string; updatedAt: string }>>;\n /** Clean shutdown for tests/graceful exit. */\n close(): Promise<void>;\n}\n\n// =============================================================================\n// In-Memory Cache Adapter\n// =============================================================================\n\n/**\n * Options for the in-memory cache adapter.\n */\nexport interface MemoryCacheOptions {\n /**\n * Maximum number of entries to store.\n * Oldest entries are evicted when limit is reached.\n */\n maxSize?: number;\n\n /**\n * Time-to-live in milliseconds.\n * Entries are automatically removed after this duration.\n */\n ttl?: number;\n}\n\n/**\n * Create an in-memory StepCache with optional LRU eviction and TTL.\n *\n * @param options - Cache options\n * @returns StepCache implementation\n *\n * @example\n * ```typescript\n * const cache = createMemoryCache({ maxSize: 1000, ttl: 60000 });\n * const workflow = createWorkflow(deps, { cache });\n * ```\n */\nexport function createMemoryCache(options: MemoryCacheOptions = {}): StepCache {\n const { maxSize, ttl } = options;\n const cache = new Map<string, {\n result: Result<unknown, unknown, unknown>;\n timestamp: number;\n entryTtl?: number;\n }>();\n\n const isExpired = (entry: { timestamp: number; entryTtl?: number }): boolean => {\n const effectiveTtl = entry.entryTtl ?? ttl;\n if (!effectiveTtl) return false;\n return Date.now() - entry.timestamp > effectiveTtl;\n };\n\n const evictExpired = (): void => {\n for (const [key, entry] of cache) {\n if (isExpired(entry)) {\n cache.delete(key);\n }\n }\n };\n\n const evictOldest = (): void => {\n if (!maxSize || cache.size < maxSize) return;\n\n // Find oldest entry\n let oldestKey: string | undefined;\n let oldestTime = Infinity;\n\n for (const [key, entry] of cache) {\n if (entry.timestamp < oldestTime) {\n oldestTime = entry.timestamp;\n oldestKey = key;\n }\n }\n\n if (oldestKey) {\n cache.delete(oldestKey);\n }\n };\n\n return {\n get(key: string): Result<unknown, unknown, unknown> | undefined {\n evictExpired();\n const entry = cache.get(key);\n if (!entry) return undefined;\n if (isExpired(entry)) {\n cache.delete(key);\n return undefined;\n }\n return entry.result;\n },\n\n set(key: string, result: Result<unknown, unknown, unknown>, options?: { ttl?: number }): void {\n evictExpired();\n evictOldest();\n cache.set(key, { result, timestamp: Date.now(), entryTtl: options?.ttl });\n },\n\n has(key: string): boolean {\n evictExpired();\n const entry = cache.get(key);\n if (!entry) return false;\n if (isExpired(entry)) {\n cache.delete(key);\n return false;\n }\n return true;\n },\n\n delete(key: string): boolean {\n return cache.delete(key);\n },\n\n clear(): void {\n cache.clear();\n },\n };\n}\n"],"mappings":"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","names":["SnapshotFormatError","message","errors","SnapshotMismatchError","mismatchType","details","SnapshotDecodeError","stepId","originalError","looksLikeWorkflowSnapshot","obj","validateSnapshot","obj","errors","snapshot","steps","stepId","stepResult","step","execution","assertValidSnapshot","result","SnapshotFormatError","mergeSnapshots","base","delta","mergedSteps","key","value","mergedMetadata","mergedWarnings","w","MAX_STRING_REPRESENTATION_LENGTH","serializeError","error","serialized","errorWithCause","serializeThrown","stringRepresentation","truncated","originalType","jsonValue","deserializeCauseNew","createMemoryCache","options","maxSize","ttl","cache","isExpired","entry","effectiveTtl","evictExpired","evictOldest","oldestKey","oldestTime"]}
package/dist/policies.cjs DELETED
@@ -1,2 +0,0 @@
1
- "use strict";var y=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var k=(t,e)=>{for(var i in e)y(t,i,{get:e[i],enumerable:!0})},D=(t,e,i,c)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of S(e))!h.call(t,l)&&l!==i&&y(t,l,{get:()=>e[l],enumerable:!(c=b(e,l))||c.enumerable});return t};var v=t=>D(y({},"__esModule",{value:!0}),t);var R={};k(R,{conditionalPolicy:()=>f,createPolicyApplier:()=>u,createPolicyBundle:()=>P,createPolicyRegistry:()=>O,envPolicy:()=>g,mergePolicies:()=>o,retryPolicies:()=>p,retryPolicy:()=>n,servicePolicies:()=>m,stepOptions:()=>x,timeoutPolicies:()=>s,timeoutPolicy:()=>r,withPolicies:()=>d,withPolicy:()=>a});module.exports=v(R);function o(...t){let e={};for(let i of t)i.key!==void 0&&(e.key=i.key),i.retry!==void 0&&(e.retry=e.retry?{...e.retry,...i.retry}:{...i.retry}),i.timeout!==void 0&&(e.timeout=e.timeout?{...e.timeout,...i.timeout}:{...i.timeout});return e}function u(...t){let e=o(...t);return i=>o(e,i??{})}function P(t,...e){return{name:t,policy:o(...e)}}function n(t){return{retry:t}}var p={none:n({attempts:1}),transient:n({attempts:3,backoff:"exponential",initialDelay:100,maxDelay:1e3,jitter:!0}),standard:n({attempts:3,backoff:"exponential",initialDelay:200,maxDelay:5e3,jitter:!0}),aggressive:n({attempts:5,backoff:"exponential",initialDelay:500,maxDelay:3e4,jitter:!0}),fixed:(t,e)=>n({attempts:t,backoff:"fixed",initialDelay:e,jitter:!1}),linear:(t,e)=>n({attempts:t,backoff:"linear",initialDelay:e,jitter:!0}),custom:t=>n({backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,...t})};function r(t){return{timeout:t}}var s={none:{},fast:r({ms:1e3}),api:r({ms:5e3}),extended:r({ms:3e4}),long:r({ms:12e4}),ms:t=>r({ms:t}),seconds:t=>r({ms:t*1e3}),withError:(t,e)=>r({ms:t,error:e}),withSignal:t=>r({ms:t,signal:!0})},m={httpApi:o(s.api,p.standard),database:o(s.extended,n({attempts:2,backoff:"exponential",initialDelay:100,maxDelay:2e3,jitter:!0})),cache:o(s.fast,p.none),messageQueue:o(s.extended,p.aggressive),fileSystem:o(s.long,p.standard),rateLimited:o(r({ms:1e4}),n({attempts:5,backoff:"linear",initialDelay:1e3,maxDelay:1e4,jitter:!0}))};function a(t,e){return o(t,e??{})}function d(t,e){let i=e??{};return o(...t,i)}function f(t,e,i={}){return t?e:i}function g(t,e=process.env.NODE_ENV??"development",i={}){return t[e]??i}function O(){let t=new Map;return{register(e,i){t.set(e,i)},get(e){return t.get(e)},has(e){return t.has(e)},names(){return Array.from(t.keys())},apply(e,i){let c=t.get(e);if(!c)throw new Error(`Policy not found: ${e}`);return a(c,i)}}}function x(){let t=[],e={key(i){return t.push({key:i}),e},policy(i){return t.push(i),e},timeout(i){return t.push(r({ms:i})),e},retry(i){return t.push(n(i)),e},retries(i){return t.push(p.custom({attempts:i})),e},build(){return o(...t)}};return e}0&&(module.exports={conditionalPolicy,createPolicyApplier,createPolicyBundle,createPolicyRegistry,envPolicy,mergePolicies,retryPolicies,retryPolicy,servicePolicies,stepOptions,timeoutPolicies,timeoutPolicy,withPolicies,withPolicy});
2
- //# sourceMappingURL=policies.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/policies-entry.ts","../src/policies.ts"],"sourcesContent":["/**\n * awaitly/policies\n *\n * Retry and timeout policies: composable reliability configurations.\n *\n * @example\n * ```typescript\n * import { servicePolicies, withPolicy, mergePolicies } from 'awaitly/policies';\n *\n * // Pre-built policies for common services\n * const dbPolicy = servicePolicies.database();\n * const apiPolicy = servicePolicies.externalApi();\n *\n * // Apply to steps\n * const user = await withPolicy(dbPolicy, () => step(fetchUser(id)));\n *\n * // Compose policies\n * const strictPolicy = mergePolicies(dbPolicy, { timeout: { ms: 1000 } });\n * ```\n */\n\nexport {\n type Policy,\n type PolicyFactory,\n type NamedPolicy,\n type WithPoliciesOptions,\n type PolicyRegistry,\n type StepOptionsBuilder,\n mergePolicies,\n createPolicyApplier,\n createPolicyBundle,\n retryPolicy,\n retryPolicies,\n timeoutPolicy,\n timeoutPolicies,\n servicePolicies,\n withPolicy,\n withPolicies,\n conditionalPolicy,\n envPolicy,\n createPolicyRegistry,\n stepOptions,\n} from \"./policies\";\n","/**\n * awaitly/policies\n *\n * Policy-Driven Step Middleware - Reusable bundles of StepOptions\n * that can be composed and applied per-workflow or per-step.\n */\n\nimport type { StepOptions, RetryOptions, TimeoutOptions } from \"./core\";\n\n// =============================================================================\n// Policy Types\n// =============================================================================\n\n/**\n * A policy is a partial StepOptions that can be merged with other policies.\n */\nexport type Policy = Partial<StepOptions>;\n\n/**\n * A policy factory that creates policies based on context.\n */\nexport type PolicyFactory<T = void> = T extends void\n ? () => Policy\n : (context: T) => Policy;\n\n/**\n * Named policy with metadata.\n */\nexport interface NamedPolicy {\n name: string;\n policy: Policy;\n description?: string;\n}\n\n// =============================================================================\n// Policy Composition\n// =============================================================================\n\n/**\n * Merge multiple policies into a single StepOptions object.\n * Later policies override earlier ones for conflicting properties.\n * Retry and timeout options are deep-merged.\n *\n * @param policies - Policies to merge (in order of precedence)\n * @returns Merged StepOptions\n *\n * @example\n * ```typescript\n * const merged = mergePolicies(\n * timeoutPolicies.api, // timeout: 5000ms\n * retryPolicies.transient, // retry: 3 attempts\n * { name: 'fetch-user' } // name override\n * );\n * ```\n */\nexport function mergePolicies(...policies: Policy[]): StepOptions {\n const result: StepOptions = {};\n\n for (const policy of policies) {\n if (policy.key !== undefined) result.key = policy.key;\n\n // Deep merge retry options\n if (policy.retry !== undefined) {\n result.retry = result.retry\n ? { ...result.retry, ...policy.retry }\n : { ...policy.retry };\n }\n\n // Deep merge timeout options\n if (policy.timeout !== undefined) {\n result.timeout = result.timeout\n ? { ...result.timeout, ...policy.timeout }\n : { ...policy.timeout };\n }\n }\n\n return result;\n}\n\n/**\n * Create a policy applier that merges base policies with step-specific options.\n *\n * @param basePolicies - Base policies to apply to all steps\n * @returns A function that applies policies to step options\n *\n * @example\n * ```typescript\n * const applyPolicy = createPolicyApplier(\n * timeoutPolicies.api,\n * retryPolicies.transient\n * );\n *\n * // In workflow\n * const user = await step(\n * 'fetch-user',\n * () => fetchUser(id),\n * applyPolicy({ key: 'user:' + id })\n * );\n * ```\n */\nexport function createPolicyApplier(\n ...basePolicies: Policy[]\n): (stepOptions?: StepOptions) => StepOptions {\n const basePolicy = mergePolicies(...basePolicies);\n\n return (stepOptions?: StepOptions): StepOptions => {\n const opts = stepOptions ?? {};\n return mergePolicies(basePolicy, opts);\n };\n}\n\n/**\n * Create a named policy bundle for reuse across workflows.\n *\n * @param name - Policy bundle name\n * @param policies - Policies to include in the bundle\n * @returns Named policy object\n */\nexport function createPolicyBundle(\n name: string,\n ...policies: Policy[]\n): NamedPolicy {\n return {\n name,\n policy: mergePolicies(...policies),\n };\n}\n\n// =============================================================================\n// Retry Policies\n// =============================================================================\n\n/**\n * Create a retry policy with the given options.\n */\nexport function retryPolicy(options: RetryOptions): Policy {\n return { retry: options };\n}\n\n/**\n * Pre-built retry policies for common scenarios.\n */\nexport const retryPolicies = {\n /**\n * No retry - fail immediately on error.\n */\n none: retryPolicy({ attempts: 1 }),\n\n /**\n * Quick retry for transient errors (3 attempts, fast backoff).\n */\n transient: retryPolicy({\n attempts: 3,\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 1000,\n jitter: true,\n }),\n\n /**\n * Standard retry for API calls (3 attempts, moderate backoff).\n */\n standard: retryPolicy({\n attempts: 3,\n backoff: \"exponential\",\n initialDelay: 200,\n maxDelay: 5000,\n jitter: true,\n }),\n\n /**\n * Aggressive retry for critical operations (5 attempts, longer backoff).\n */\n aggressive: retryPolicy({\n attempts: 5,\n backoff: \"exponential\",\n initialDelay: 500,\n maxDelay: 30000,\n jitter: true,\n }),\n\n /**\n * Fixed interval retry (useful for polling).\n */\n fixed: (attempts: number, delayMs: number): Policy =>\n retryPolicy({\n attempts,\n backoff: \"fixed\",\n initialDelay: delayMs,\n jitter: false,\n }),\n\n /**\n * Linear backoff retry.\n */\n linear: (attempts: number, initialDelay: number): Policy =>\n retryPolicy({\n attempts,\n backoff: \"linear\",\n initialDelay,\n jitter: true,\n }),\n\n /**\n * Custom retry policy builder.\n */\n custom: (options: Partial<RetryOptions> & { attempts: number }): Policy =>\n retryPolicy({\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 30000,\n jitter: true,\n ...options,\n }),\n} as const;\n\n// =============================================================================\n// Timeout Policies\n// =============================================================================\n\n/**\n * Create a timeout policy with the given options.\n */\nexport function timeoutPolicy(options: TimeoutOptions): Policy {\n return { timeout: options };\n}\n\n/**\n * Pre-built timeout policies for common scenarios.\n */\nexport const timeoutPolicies = {\n /**\n * No timeout.\n */\n none: {} as Policy,\n\n /**\n * Fast timeout for quick operations (1 second).\n */\n fast: timeoutPolicy({ ms: 1000 }),\n\n /**\n * Standard API timeout (5 seconds).\n */\n api: timeoutPolicy({ ms: 5000 }),\n\n /**\n * Extended timeout for slower operations (30 seconds).\n */\n extended: timeoutPolicy({ ms: 30000 }),\n\n /**\n * Long timeout for batch operations (2 minutes).\n */\n long: timeoutPolicy({ ms: 120000 }),\n\n /**\n * Custom timeout in milliseconds.\n */\n ms: (ms: number): Policy => timeoutPolicy({ ms }),\n\n /**\n * Custom timeout in seconds.\n */\n seconds: (seconds: number): Policy => timeoutPolicy({ ms: seconds * 1000 }),\n\n /**\n * Timeout with custom error.\n */\n withError: <E>(ms: number, error: E): Policy =>\n timeoutPolicy({ ms, error }),\n\n /**\n * Timeout with AbortSignal support.\n */\n withSignal: (ms: number): Policy =>\n timeoutPolicy({ ms, signal: true }),\n} as const;\n\n// =============================================================================\n// Combined Policies\n// =============================================================================\n\n/**\n * Pre-built combined policies for common service patterns.\n */\nexport const servicePolicies = {\n /**\n * Policy for external HTTP APIs.\n * - 5 second timeout\n * - 3 retries with exponential backoff\n */\n httpApi: mergePolicies(\n timeoutPolicies.api,\n retryPolicies.standard\n ),\n\n /**\n * Policy for database operations.\n * - 30 second timeout\n * - 2 retries for transient errors\n */\n database: mergePolicies(\n timeoutPolicies.extended,\n retryPolicy({\n attempts: 2,\n backoff: \"exponential\",\n initialDelay: 100,\n maxDelay: 2000,\n jitter: true,\n })\n ),\n\n /**\n * Policy for cache operations.\n * - 1 second timeout\n * - No retry (cache misses are not errors)\n */\n cache: mergePolicies(\n timeoutPolicies.fast,\n retryPolicies.none\n ),\n\n /**\n * Policy for message queue operations.\n * - 30 second timeout\n * - 5 retries with longer backoff\n */\n messageQueue: mergePolicies(\n timeoutPolicies.extended,\n retryPolicies.aggressive\n ),\n\n /**\n * Policy for file operations.\n * - 2 minute timeout\n * - 3 retries\n */\n fileSystem: mergePolicies(\n timeoutPolicies.long,\n retryPolicies.standard\n ),\n\n /**\n * Policy for third-party services with rate limits.\n * - 10 second timeout\n * - 5 retries with linear backoff\n */\n rateLimited: mergePolicies(\n timeoutPolicy({ ms: 10000 }),\n retryPolicy({\n attempts: 5,\n backoff: \"linear\",\n initialDelay: 1000,\n maxDelay: 10000,\n jitter: true,\n })\n ),\n} as const;\n\n// =============================================================================\n// Policy Decorators\n// =============================================================================\n\n/**\n * Options for withPolicies workflow wrapper.\n */\nexport interface WithPoliciesOptions {\n /**\n * Base policies applied to all steps.\n */\n policies: Policy[];\n\n /**\n * Step-specific policy overrides by name or key pattern.\n */\n overrides?: Record<string, Policy>;\n}\n\n/**\n * Create step options with policies applied.\n * This is a helper for applying policies inline.\n *\n * @param policies - Policies to apply\n * @param stepOptions - Step-specific options\n * @returns Merged StepOptions\n *\n * @example\n * ```typescript\n * const user = await step(\n * () => fetchUser(id),\n * withPolicy(servicePolicies.httpApi, { name: 'fetch-user' })\n * );\n * ```\n */\nexport function withPolicy(\n policy: Policy,\n stepOptions?: StepOptions\n): StepOptions {\n const opts = stepOptions ?? {};\n return mergePolicies(policy, opts);\n}\n\n/**\n * Create step options with multiple policies applied.\n *\n * @param policies - Policies to apply (in order)\n * @param stepOptions - Step-specific options\n * @returns Merged StepOptions\n *\n * @example\n * ```typescript\n * const user = await step(\n * 'fetch-user',\n * () => fetchUser(id),\n * withPolicies([timeoutPolicies.api, retryPolicies.standard])\n * );\n * ```\n */\nexport function withPolicies(\n policies: Policy[],\n stepOptions?: StepOptions\n): StepOptions {\n const opts = stepOptions ?? {};\n return mergePolicies(...policies, opts);\n}\n\n// =============================================================================\n// Conditional Policies\n// =============================================================================\n\n/**\n * Create a policy that applies conditionally.\n *\n * @param condition - Condition to check\n * @param policy - Policy to apply if condition is true\n * @param elsePolicy - Policy to apply if condition is false (optional)\n * @returns The selected policy\n *\n * @example\n * ```typescript\n * const policy = conditionalPolicy(\n * isProduction,\n * servicePolicies.httpApi, // Use in production\n * retryPolicies.none // Skip in development\n * );\n * ```\n */\nexport function conditionalPolicy(\n condition: boolean,\n policy: Policy,\n elsePolicy: Policy = {}\n): Policy {\n return condition ? policy : elsePolicy;\n}\n\n/**\n * Create a policy based on environment.\n *\n * @param envPolicies - Map of environment names to policies\n * @param currentEnv - Current environment (defaults to NODE_ENV)\n * @param defaultPolicy - Default policy if environment not found\n * @returns The selected policy\n *\n * @example\n * ```typescript\n * const policy = envPolicy({\n * production: servicePolicies.httpApi,\n * development: retryPolicies.none,\n * test: retryPolicies.none,\n * });\n * ```\n */\nexport function envPolicy(\n envPolicies: Record<string, Policy>,\n currentEnv: string = process.env.NODE_ENV ?? \"development\",\n defaultPolicy: Policy = {}\n): Policy {\n return envPolicies[currentEnv] ?? defaultPolicy;\n}\n\n// =============================================================================\n// Policy Registry\n// =============================================================================\n\n/**\n * A registry for managing named policies.\n */\nexport interface PolicyRegistry {\n /**\n * Register a named policy.\n */\n register(name: string, policy: Policy): void;\n\n /**\n * Get a policy by name.\n */\n get(name: string): Policy | undefined;\n\n /**\n * Check if a policy exists.\n */\n has(name: string): boolean;\n\n /**\n * Get all registered policy names.\n */\n names(): string[];\n\n /**\n * Create step options using a registered policy.\n */\n apply(policyName: string, stepOptions?: StepOptions): StepOptions;\n}\n\n/**\n * Create a policy registry for managing named policies.\n *\n * @returns PolicyRegistry instance\n *\n * @example\n * ```typescript\n * const registry = createPolicyRegistry();\n *\n * // Register policies\n * registry.register('api', servicePolicies.httpApi);\n * registry.register('db', servicePolicies.database);\n *\n * // Use in workflow\n * const user = await step(\n * 'fetch-user',\n * () => fetchUser(id),\n * registry.apply('api')\n * );\n * ```\n */\nexport function createPolicyRegistry(): PolicyRegistry {\n const policies = new Map<string, Policy>();\n\n return {\n register(name: string, policy: Policy): void {\n policies.set(name, policy);\n },\n\n get(name: string): Policy | undefined {\n return policies.get(name);\n },\n\n has(name: string): boolean {\n return policies.has(name);\n },\n\n names(): string[] {\n return Array.from(policies.keys());\n },\n\n apply(policyName: string, stepOptions?: StepOptions): StepOptions {\n const policy = policies.get(policyName);\n if (!policy) {\n throw new Error(`Policy not found: ${policyName}`);\n }\n return withPolicy(policy, stepOptions);\n },\n };\n}\n\n// =============================================================================\n// Step Options Builder (Fluent API)\n// =============================================================================\n\n/**\n * Fluent builder for constructing step options.\n */\nexport interface StepOptionsBuilder {\n /**\n * Set step key for caching.\n */\n key(key: string): StepOptionsBuilder;\n\n /**\n * Apply a policy.\n */\n policy(policy: Policy): StepOptionsBuilder;\n\n /**\n * Set timeout in milliseconds.\n */\n timeout(ms: number): StepOptionsBuilder;\n\n /**\n * Set retry options.\n */\n retry(options: RetryOptions): StepOptionsBuilder;\n\n /**\n * Set retry attempts (with default exponential backoff).\n */\n retries(attempts: number): StepOptionsBuilder;\n\n /**\n * Build the final StepOptions.\n */\n build(): StepOptions;\n}\n\n/**\n * Create a fluent builder for step options.\n *\n * @returns StepOptionsBuilder instance\n *\n * @example\n * ```typescript\n * const options = stepOptions()\n * .key('user:123')\n * .timeout(5000)\n * .retries(3)\n * .build();\n *\n * const user = await step('fetch-user', () => fetchUser(id), options);\n * ```\n */\nexport function stepOptions(): StepOptionsBuilder {\n const policies: Policy[] = [];\n\n const builder: StepOptionsBuilder = {\n key(key: string) {\n policies.push({ key });\n return builder;\n },\n\n policy(policy: Policy) {\n policies.push(policy);\n return builder;\n },\n\n timeout(ms: number) {\n policies.push(timeoutPolicy({ ms }));\n return builder;\n },\n\n retry(options: RetryOptions) {\n policies.push(retryPolicy(options));\n return builder;\n },\n\n retries(attempts: number) {\n policies.push(retryPolicies.custom({ attempts }));\n return builder;\n },\n\n build(): StepOptions {\n return mergePolicies(...policies);\n },\n };\n\n return builder;\n}\n"],"mappings":"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","names":["policies_entry_exports","__export","conditionalPolicy","createPolicyApplier","createPolicyBundle","createPolicyRegistry","envPolicy","mergePolicies","retryPolicies","retryPolicy","servicePolicies","stepOptions","timeoutPolicies","timeoutPolicy","withPolicies","withPolicy","__toCommonJS","mergePolicies","policies","result","policy","createPolicyApplier","basePolicies","basePolicy","stepOptions","createPolicyBundle","name","retryPolicy","options","retryPolicies","attempts","delayMs","initialDelay","timeoutPolicy","timeoutPolicies","ms","seconds","error","servicePolicies","withPolicy","withPolicies","opts","conditionalPolicy","condition","elsePolicy","envPolicy","envPolicies","currentEnv","defaultPolicy","createPolicyRegistry","policyName","builder","key"]}
@@ -1,379 +0,0 @@
1
- import { aj as StepOptions, ag as RetryOptions, ar as TimeoutOptions } from './run-entry-DGs0tySr.cjs';
2
- import './errors.cjs';
3
- import './tagged-error.cjs';
4
- import './slugs.cjs';
5
-
6
- /**
7
- * awaitly/policies
8
- *
9
- * Policy-Driven Step Middleware - Reusable bundles of StepOptions
10
- * that can be composed and applied per-workflow or per-step.
11
- */
12
-
13
- /**
14
- * A policy is a partial StepOptions that can be merged with other policies.
15
- */
16
- type Policy = Partial<StepOptions>;
17
- /**
18
- * A policy factory that creates policies based on context.
19
- */
20
- type PolicyFactory<T = void> = T extends void ? () => Policy : (context: T) => Policy;
21
- /**
22
- * Named policy with metadata.
23
- */
24
- interface NamedPolicy {
25
- name: string;
26
- policy: Policy;
27
- description?: string;
28
- }
29
- /**
30
- * Merge multiple policies into a single StepOptions object.
31
- * Later policies override earlier ones for conflicting properties.
32
- * Retry and timeout options are deep-merged.
33
- *
34
- * @param policies - Policies to merge (in order of precedence)
35
- * @returns Merged StepOptions
36
- *
37
- * @example
38
- * ```typescript
39
- * const merged = mergePolicies(
40
- * timeoutPolicies.api, // timeout: 5000ms
41
- * retryPolicies.transient, // retry: 3 attempts
42
- * { name: 'fetch-user' } // name override
43
- * );
44
- * ```
45
- */
46
- declare function mergePolicies(...policies: Policy[]): StepOptions;
47
- /**
48
- * Create a policy applier that merges base policies with step-specific options.
49
- *
50
- * @param basePolicies - Base policies to apply to all steps
51
- * @returns A function that applies policies to step options
52
- *
53
- * @example
54
- * ```typescript
55
- * const applyPolicy = createPolicyApplier(
56
- * timeoutPolicies.api,
57
- * retryPolicies.transient
58
- * );
59
- *
60
- * // In workflow
61
- * const user = await step(
62
- * 'fetch-user',
63
- * () => fetchUser(id),
64
- * applyPolicy({ key: 'user:' + id })
65
- * );
66
- * ```
67
- */
68
- declare function createPolicyApplier(...basePolicies: Policy[]): (stepOptions?: StepOptions) => StepOptions;
69
- /**
70
- * Create a named policy bundle for reuse across workflows.
71
- *
72
- * @param name - Policy bundle name
73
- * @param policies - Policies to include in the bundle
74
- * @returns Named policy object
75
- */
76
- declare function createPolicyBundle(name: string, ...policies: Policy[]): NamedPolicy;
77
- /**
78
- * Create a retry policy with the given options.
79
- */
80
- declare function retryPolicy(options: RetryOptions): Policy;
81
- /**
82
- * Pre-built retry policies for common scenarios.
83
- */
84
- declare const retryPolicies: {
85
- /**
86
- * No retry - fail immediately on error.
87
- */
88
- readonly none: Partial<StepOptions>;
89
- /**
90
- * Quick retry for transient errors (3 attempts, fast backoff).
91
- */
92
- readonly transient: Partial<StepOptions>;
93
- /**
94
- * Standard retry for API calls (3 attempts, moderate backoff).
95
- */
96
- readonly standard: Partial<StepOptions>;
97
- /**
98
- * Aggressive retry for critical operations (5 attempts, longer backoff).
99
- */
100
- readonly aggressive: Partial<StepOptions>;
101
- /**
102
- * Fixed interval retry (useful for polling).
103
- */
104
- readonly fixed: (attempts: number, delayMs: number) => Policy;
105
- /**
106
- * Linear backoff retry.
107
- */
108
- readonly linear: (attempts: number, initialDelay: number) => Policy;
109
- /**
110
- * Custom retry policy builder.
111
- */
112
- readonly custom: (options: Partial<RetryOptions> & {
113
- attempts: number;
114
- }) => Policy;
115
- };
116
- /**
117
- * Create a timeout policy with the given options.
118
- */
119
- declare function timeoutPolicy(options: TimeoutOptions): Policy;
120
- /**
121
- * Pre-built timeout policies for common scenarios.
122
- */
123
- declare const timeoutPolicies: {
124
- /**
125
- * No timeout.
126
- */
127
- readonly none: Policy;
128
- /**
129
- * Fast timeout for quick operations (1 second).
130
- */
131
- readonly fast: Partial<StepOptions>;
132
- /**
133
- * Standard API timeout (5 seconds).
134
- */
135
- readonly api: Partial<StepOptions>;
136
- /**
137
- * Extended timeout for slower operations (30 seconds).
138
- */
139
- readonly extended: Partial<StepOptions>;
140
- /**
141
- * Long timeout for batch operations (2 minutes).
142
- */
143
- readonly long: Partial<StepOptions>;
144
- /**
145
- * Custom timeout in milliseconds.
146
- */
147
- readonly ms: (ms: number) => Policy;
148
- /**
149
- * Custom timeout in seconds.
150
- */
151
- readonly seconds: (seconds: number) => Policy;
152
- /**
153
- * Timeout with custom error.
154
- */
155
- readonly withError: <E>(ms: number, error: E) => Policy;
156
- /**
157
- * Timeout with AbortSignal support.
158
- */
159
- readonly withSignal: (ms: number) => Policy;
160
- };
161
- /**
162
- * Pre-built combined policies for common service patterns.
163
- */
164
- declare const servicePolicies: {
165
- /**
166
- * Policy for external HTTP APIs.
167
- * - 5 second timeout
168
- * - 3 retries with exponential backoff
169
- */
170
- readonly httpApi: StepOptions;
171
- /**
172
- * Policy for database operations.
173
- * - 30 second timeout
174
- * - 2 retries for transient errors
175
- */
176
- readonly database: StepOptions;
177
- /**
178
- * Policy for cache operations.
179
- * - 1 second timeout
180
- * - No retry (cache misses are not errors)
181
- */
182
- readonly cache: StepOptions;
183
- /**
184
- * Policy for message queue operations.
185
- * - 30 second timeout
186
- * - 5 retries with longer backoff
187
- */
188
- readonly messageQueue: StepOptions;
189
- /**
190
- * Policy for file operations.
191
- * - 2 minute timeout
192
- * - 3 retries
193
- */
194
- readonly fileSystem: StepOptions;
195
- /**
196
- * Policy for third-party services with rate limits.
197
- * - 10 second timeout
198
- * - 5 retries with linear backoff
199
- */
200
- readonly rateLimited: StepOptions;
201
- };
202
- /**
203
- * Options for withPolicies workflow wrapper.
204
- */
205
- interface WithPoliciesOptions {
206
- /**
207
- * Base policies applied to all steps.
208
- */
209
- policies: Policy[];
210
- /**
211
- * Step-specific policy overrides by name or key pattern.
212
- */
213
- overrides?: Record<string, Policy>;
214
- }
215
- /**
216
- * Create step options with policies applied.
217
- * This is a helper for applying policies inline.
218
- *
219
- * @param policies - Policies to apply
220
- * @param stepOptions - Step-specific options
221
- * @returns Merged StepOptions
222
- *
223
- * @example
224
- * ```typescript
225
- * const user = await step(
226
- * () => fetchUser(id),
227
- * withPolicy(servicePolicies.httpApi, { name: 'fetch-user' })
228
- * );
229
- * ```
230
- */
231
- declare function withPolicy(policy: Policy, stepOptions?: StepOptions): StepOptions;
232
- /**
233
- * Create step options with multiple policies applied.
234
- *
235
- * @param policies - Policies to apply (in order)
236
- * @param stepOptions - Step-specific options
237
- * @returns Merged StepOptions
238
- *
239
- * @example
240
- * ```typescript
241
- * const user = await step(
242
- * 'fetch-user',
243
- * () => fetchUser(id),
244
- * withPolicies([timeoutPolicies.api, retryPolicies.standard])
245
- * );
246
- * ```
247
- */
248
- declare function withPolicies(policies: Policy[], stepOptions?: StepOptions): StepOptions;
249
- /**
250
- * Create a policy that applies conditionally.
251
- *
252
- * @param condition - Condition to check
253
- * @param policy - Policy to apply if condition is true
254
- * @param elsePolicy - Policy to apply if condition is false (optional)
255
- * @returns The selected policy
256
- *
257
- * @example
258
- * ```typescript
259
- * const policy = conditionalPolicy(
260
- * isProduction,
261
- * servicePolicies.httpApi, // Use in production
262
- * retryPolicies.none // Skip in development
263
- * );
264
- * ```
265
- */
266
- declare function conditionalPolicy(condition: boolean, policy: Policy, elsePolicy?: Policy): Policy;
267
- /**
268
- * Create a policy based on environment.
269
- *
270
- * @param envPolicies - Map of environment names to policies
271
- * @param currentEnv - Current environment (defaults to NODE_ENV)
272
- * @param defaultPolicy - Default policy if environment not found
273
- * @returns The selected policy
274
- *
275
- * @example
276
- * ```typescript
277
- * const policy = envPolicy({
278
- * production: servicePolicies.httpApi,
279
- * development: retryPolicies.none,
280
- * test: retryPolicies.none,
281
- * });
282
- * ```
283
- */
284
- declare function envPolicy(envPolicies: Record<string, Policy>, currentEnv?: string, defaultPolicy?: Policy): Policy;
285
- /**
286
- * A registry for managing named policies.
287
- */
288
- interface PolicyRegistry {
289
- /**
290
- * Register a named policy.
291
- */
292
- register(name: string, policy: Policy): void;
293
- /**
294
- * Get a policy by name.
295
- */
296
- get(name: string): Policy | undefined;
297
- /**
298
- * Check if a policy exists.
299
- */
300
- has(name: string): boolean;
301
- /**
302
- * Get all registered policy names.
303
- */
304
- names(): string[];
305
- /**
306
- * Create step options using a registered policy.
307
- */
308
- apply(policyName: string, stepOptions?: StepOptions): StepOptions;
309
- }
310
- /**
311
- * Create a policy registry for managing named policies.
312
- *
313
- * @returns PolicyRegistry instance
314
- *
315
- * @example
316
- * ```typescript
317
- * const registry = createPolicyRegistry();
318
- *
319
- * // Register policies
320
- * registry.register('api', servicePolicies.httpApi);
321
- * registry.register('db', servicePolicies.database);
322
- *
323
- * // Use in workflow
324
- * const user = await step(
325
- * 'fetch-user',
326
- * () => fetchUser(id),
327
- * registry.apply('api')
328
- * );
329
- * ```
330
- */
331
- declare function createPolicyRegistry(): PolicyRegistry;
332
- /**
333
- * Fluent builder for constructing step options.
334
- */
335
- interface StepOptionsBuilder {
336
- /**
337
- * Set step key for caching.
338
- */
339
- key(key: string): StepOptionsBuilder;
340
- /**
341
- * Apply a policy.
342
- */
343
- policy(policy: Policy): StepOptionsBuilder;
344
- /**
345
- * Set timeout in milliseconds.
346
- */
347
- timeout(ms: number): StepOptionsBuilder;
348
- /**
349
- * Set retry options.
350
- */
351
- retry(options: RetryOptions): StepOptionsBuilder;
352
- /**
353
- * Set retry attempts (with default exponential backoff).
354
- */
355
- retries(attempts: number): StepOptionsBuilder;
356
- /**
357
- * Build the final StepOptions.
358
- */
359
- build(): StepOptions;
360
- }
361
- /**
362
- * Create a fluent builder for step options.
363
- *
364
- * @returns StepOptionsBuilder instance
365
- *
366
- * @example
367
- * ```typescript
368
- * const options = stepOptions()
369
- * .key('user:123')
370
- * .timeout(5000)
371
- * .retries(3)
372
- * .build();
373
- *
374
- * const user = await step('fetch-user', () => fetchUser(id), options);
375
- * ```
376
- */
377
- declare function stepOptions(): StepOptionsBuilder;
378
-
379
- export { type NamedPolicy, type Policy, type PolicyFactory, type PolicyRegistry, type StepOptionsBuilder, type WithPoliciesOptions, conditionalPolicy, createPolicyApplier, createPolicyBundle, createPolicyRegistry, envPolicy, mergePolicies, retryPolicies, retryPolicy, servicePolicies, stepOptions, timeoutPolicies, timeoutPolicy, withPolicies, withPolicy };