@jagreehal/workflow 1.11.0 → 1.13.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 (60) hide show
  1. package/README.md +1197 -20
  2. package/dist/batch.cjs +1 -1
  3. package/dist/batch.cjs.map +1 -1
  4. package/dist/batch.js +1 -1
  5. package/dist/batch.js.map +1 -1
  6. package/dist/core.cjs +1 -1
  7. package/dist/core.cjs.map +1 -1
  8. package/dist/core.d.cts +31 -17
  9. package/dist/core.d.ts +31 -17
  10. package/dist/core.js +1 -1
  11. package/dist/core.js.map +1 -1
  12. package/dist/duration.cjs +2 -0
  13. package/dist/duration.cjs.map +1 -0
  14. package/dist/duration.d.cts +246 -0
  15. package/dist/duration.d.ts +246 -0
  16. package/dist/duration.js +2 -0
  17. package/dist/duration.js.map +1 -0
  18. package/dist/index.cjs +5 -5
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.cts +3 -0
  21. package/dist/index.d.ts +3 -0
  22. package/dist/index.js +5 -5
  23. package/dist/index.js.map +1 -1
  24. package/dist/match.cjs +2 -0
  25. package/dist/match.cjs.map +1 -0
  26. package/dist/match.d.cts +216 -0
  27. package/dist/match.d.ts +216 -0
  28. package/dist/match.js +2 -0
  29. package/dist/match.js.map +1 -0
  30. package/dist/resource.cjs +1 -1
  31. package/dist/resource.cjs.map +1 -1
  32. package/dist/resource.js +1 -1
  33. package/dist/resource.js.map +1 -1
  34. package/dist/schedule.cjs +2 -0
  35. package/dist/schedule.cjs.map +1 -0
  36. package/dist/schedule.d.cts +387 -0
  37. package/dist/schedule.d.ts +387 -0
  38. package/dist/schedule.js +2 -0
  39. package/dist/schedule.js.map +1 -0
  40. package/dist/workflow.cjs +1 -1
  41. package/dist/workflow.cjs.map +1 -1
  42. package/dist/workflow.js +1 -1
  43. package/dist/workflow.js.map +1 -1
  44. package/docs/api.md +30 -0
  45. package/docs/coming-from-neverthrow.md +103 -10
  46. package/docs/effect-features-to-port.md +210 -0
  47. package/docs/match-examples.test.ts +558 -0
  48. package/docs/match.md +417 -0
  49. package/docs/policies-examples.test.ts +750 -0
  50. package/docs/policies.md +508 -0
  51. package/docs/resource-management-examples.test.ts +729 -0
  52. package/docs/resource-management.md +509 -0
  53. package/docs/schedule-examples.test.ts +736 -0
  54. package/docs/schedule.md +467 -0
  55. package/docs/tagged-error-examples.test.ts +494 -0
  56. package/docs/tagged-error.md +730 -0
  57. package/docs/visualization-examples.test.ts +663 -0
  58. package/docs/visualization.md +395 -0
  59. package/docs/visualize-examples.md +1 -1
  60. package/package.json +17 -2
package/dist/match.cjs ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var g=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var w=(e,t)=>{for(var n in t)g(e,n,{get:t[n],enumerable:!0})},_=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let u of M(t))!R.call(e,u)&&u!==n&&g(e,u,{get:()=>t[u],enumerable:!(a=m(t,u))||a.enumerable});return e};var v=e=>_(g({},"__esModule",{value:!0}),e);var y={};w(y,{Match:()=>k,exhaustive:()=>o,is:()=>O,isOneOf:()=>h,matchValue:()=>f,orElse:()=>r,orElseValue:()=>T,tag:()=>s,tags:()=>l,when:()=>c});module.exports=v(y);function s(e,t){return n=>{let a=new Map(n.handlers);return a.set(e,t),{_tag:"Matcher",value:n.value,handlers:a,_remaining:void 0,_output:void 0}}}function l(e){return t=>{let n=new Map(t.handlers);for(let[a,u]of Object.entries(e))u&&n.set(a,u);return{_tag:"Matcher",value:t.value,handlers:n,_remaining:void 0,_output:void 0}}}function o(e){let t=e.handlers.get(e.value._tag);if(!t)throw new Error(`No handler for tag: ${e.value._tag}`);return t(e.value)}function r(e){return t=>{let n=t.handlers.get(t.value._tag);return n?n(t.value):e(t.value)}}function T(e){return r(()=>e)}function c(e,t,n){return a=>{let u=new Map(a.handlers),i=a.handlers.get(e);return u.set(e,p=>{let d=p;if(t(d))return n(d);if(i)return i(p);throw new Error(`No handler matched for tag: ${e}`)}),{_tag:"Matcher",value:a.value,handlers:u,_remaining:a._remaining,_output:void 0}}}function O(e){return t=>t._tag===e}function h(...e){let t=new Set(e);return n=>t.has(n._tag)}function I(e){return typeof e=="object"&&e!==null&&"_tag"in e&&e._tag==="Matcher"}function x(e){return{...e,pipe(t){let n=t(e);return I(n)?x(n):n}}}function f(e){return x({_tag:"Matcher",value:e,handlers:new Map,_remaining:e,_output:void 0})}var k={value:f,tag:s,tags:l,when:c,exhaustive:o,orElse:r,orElseValue:T,is:O,isOneOf:h};0&&(module.exports={Match,exhaustive,is,isOneOf,matchValue,orElse,orElseValue,tag,tags,when});
2
+ //# sourceMappingURL=match.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/match.ts"],"sourcesContent":["/**\n * @jagreehal/workflow/match\n *\n * Exhaustive pattern matching for discriminated unions.\n * Extends the TaggedError.match pattern to work with any tagged union.\n *\n * @example\n * ```typescript\n * type Event =\n * | { _tag: 'UserCreated'; user: User }\n * | { _tag: 'UserUpdated'; userId: string }\n * | { _tag: 'UserDeleted'; userId: string }\n *\n * const message = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => `Created: ${e.user.name}`))\n * .pipe(Match.tag(\"UserUpdated\", e => `Updated: ${e.userId}`))\n * .pipe(Match.tag(\"UserDeleted\", e => `Deleted: ${e.userId}`))\n * .pipe(Match.exhaustive)\n * ```\n */\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Any object with a _tag discriminator.\n */\nexport type Tagged<Tag extends string = string> = { readonly _tag: Tag };\n\n/**\n * Extract the tag from a tagged union member.\n */\nexport type TagOf<T extends Tagged> = T[\"_tag\"];\n\n/**\n * Extract union members that match a specific tag.\n */\nexport type MatchTag<T extends Tagged, Tag extends string> = Extract<T, { _tag: Tag }>;\n\n/**\n * A matcher that is accumulating handlers for a tagged union.\n *\n * @typeParam Input - The full union type being matched\n * @typeParam Remaining - Union members that haven't been handled yet\n * @typeParam Output - The output type (union of all handler return types)\n */\nexport interface Matcher<Input extends Tagged, Remaining extends Tagged, Output> {\n readonly _tag: \"Matcher\";\n readonly value: Input;\n readonly handlers: Map<string, (value: Tagged) => unknown>;\n readonly _remaining: Remaining;\n readonly _output: Output;\n}\n\n/**\n * A completed matcher that has handled all cases.\n */\nexport interface CompletedMatcher<Output> {\n readonly _tag: \"CompletedMatcher\";\n readonly result: Output;\n}\n\n// =============================================================================\n// Core Functions\n// =============================================================================\n\n\n/**\n * Add a handler for a specific tag.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user.name))\n * ```\n */\nexport function tag<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Tag extends TagOf<Remaining>,\n NewOutput,\n>(\n tagValue: Tag,\n handler: (value: MatchTag<Remaining, Tag>) => NewOutput\n): (\n matcher: Matcher<Input, Remaining, Output>\n) => Matcher<Input, Exclude<Remaining, { _tag: Tag }>, Output | NewOutput> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n newHandlers.set(tagValue, handler as (value: Tagged) => unknown);\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: undefined as unknown as Exclude<Remaining, { _tag: Tag }>,\n _output: undefined as unknown as Output | NewOutput,\n };\n };\n}\n\n/**\n * Add handlers for multiple tags at once.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.tags({\n * UserCreated: e => e.user.name,\n * UserUpdated: e => e.userId,\n * }))\n * ```\n */\nexport function tags<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Handlers extends {\n [K in TagOf<Remaining>]?: (value: MatchTag<Remaining, K>) => unknown;\n },\n>(\n handlers: Handlers\n): (\n matcher: Matcher<Input, Remaining, Output>\n) => Matcher<\n Input,\n Exclude<Remaining, { _tag: keyof Handlers }>,\n Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>\n> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n for (const [tagValue, handler] of Object.entries(handlers)) {\n if (handler) {\n newHandlers.set(tagValue, handler as (value: Tagged) => unknown);\n }\n }\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: undefined as unknown as Exclude<Remaining, { _tag: keyof Handlers }>,\n _output: undefined as unknown as Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>,\n };\n };\n}\n\n/**\n * Complete the match, requiring all cases to be handled.\n * This is a compile-time check - if any cases are missing, TypeScript will error.\n *\n * @example\n * ```typescript\n * // TypeScript error if any tag is not handled\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user))\n * .pipe(Match.tag(\"UserUpdated\", e => e.userId))\n * .pipe(Match.tag(\"UserDeleted\", e => e.userId))\n * .pipe(Match.exhaustive)\n * ```\n */\nexport function exhaustive<Input extends Tagged, Output>(\n matcher: Matcher<Input, never, Output>\n): Output {\n const handler = matcher.handlers.get(matcher.value._tag);\n if (!handler) {\n throw new Error(`No handler for tag: ${matcher.value._tag}`);\n }\n return handler(matcher.value) as Output;\n}\n\n/**\n * Complete the match with a default handler for any remaining cases.\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => `Created: ${e.user.name}`))\n * .pipe(Match.orElse(e => `Other event: ${e._tag}`))\n * ```\n */\nexport function orElse<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(\n handler: (value: Remaining) => DefaultOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput {\n return (matcher) => {\n const specificHandler = matcher.handlers.get(matcher.value._tag);\n if (specificHandler) {\n return specificHandler(matcher.value) as Output;\n }\n return handler(matcher.value as unknown as Remaining);\n };\n}\n\n/**\n * Complete the match with a default value for any remaining cases.\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user.name))\n * .pipe(Match.orElseValue(\"Unknown event\"))\n * ```\n */\nexport function orElseValue<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(\n defaultValue: DefaultOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput {\n return orElse(() => defaultValue);\n}\n\n// =============================================================================\n// Predicates & Guards\n// =============================================================================\n\n/**\n * Add a handler with an additional predicate.\n * The handler only runs if both the tag matches AND the predicate returns true.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.when(\n * \"UserCreated\",\n * e => e.user.isAdmin,\n * e => `Admin created: ${e.user.name}`\n * ))\n * ```\n */\nexport function when<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Tag extends TagOf<Remaining>,\n NewOutput,\n>(\n tagValue: Tag,\n predicate: (value: MatchTag<Remaining, Tag>) => boolean,\n handler: (value: MatchTag<Remaining, Tag>) => NewOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Remaining, Output | NewOutput> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n const existingHandler = matcher.handlers.get(tagValue);\n\n newHandlers.set(tagValue, (value: Tagged) => {\n const typedValue = value as MatchTag<Remaining, Tag>;\n if (predicate(typedValue)) {\n return handler(typedValue);\n }\n if (existingHandler) {\n return existingHandler(value);\n }\n throw new Error(`No handler matched for tag: ${tagValue}`);\n });\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: matcher._remaining,\n _output: undefined as unknown as Output | NewOutput,\n };\n };\n}\n\n// =============================================================================\n// Type Narrowing Utilities\n// =============================================================================\n\n/**\n * Check if a tagged value has a specific tag.\n * Type guard that narrows the type.\n *\n * @example\n * ```typescript\n * if (Match.is(\"UserCreated\")(event)) {\n * // event is narrowed to { _tag: 'UserCreated'; user: User }\n * console.log(event.user.name);\n * }\n * ```\n */\nexport function is<T extends Tagged, Tag extends string>(\n tagValue: Tag\n): (value: T) => value is Extract<T, { _tag: Tag }> {\n return (value): value is Extract<T, { _tag: Tag }> => value._tag === tagValue;\n}\n\n/**\n * Check if a tagged value has one of several tags.\n *\n * @example\n * ```typescript\n * if (Match.isOneOf(\"UserCreated\", \"UserUpdated\")(event)) {\n * // event is narrowed to UserCreated | UserUpdated\n * }\n * ```\n */\nexport function isOneOf<T extends Tagged, Tags extends TagOf<T>[]>(\n ...tags: Tags\n): (value: T) => value is Extract<T, { _tag: Tags[number] }> {\n const tagSet = new Set(tags);\n return (value): value is Extract<T, { _tag: Tags[number] }> =>\n tagSet.has(value._tag as Tags[number]);\n}\n\n// =============================================================================\n// Pipe Helper\n// =============================================================================\n\n/**\n * Type guard to check if a value is a Matcher.\n */\nfunction isMatcher(value: unknown): value is Matcher<Tagged, Tagged, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n (value as { _tag: unknown })._tag === \"Matcher\"\n );\n}\n\ntype PipedMatcher<Input extends Tagged, Remaining extends Tagged, Output> =\n Matcher<Input, Remaining, Output> & {\n pipe: <NewRemaining extends Tagged, NewOutput>(\n fn: (self: Matcher<Input, Remaining, Output>) => Matcher<Input, NewRemaining, NewOutput>\n ) => PipedMatcher<Input, NewRemaining, NewOutput>;\n } & {\n pipe: <R>(fn: (self: Matcher<Input, Remaining, Output>) => R) => R;\n };\n\nfunction addPipe<Input extends Tagged, Remaining extends Tagged, Output>(\n matcher: Matcher<Input, Remaining, Output>\n): PipedMatcher<Input, Remaining, Output> {\n return {\n ...matcher,\n pipe(fn: (self: Matcher<Input, Remaining, Output>) => unknown): unknown {\n const result = fn(matcher);\n // If result is a Matcher, add pipe to it too\n if (isMatcher(result)) {\n return addPipe(result as Matcher<Tagged, Tagged, unknown>);\n }\n return result;\n },\n } as PipedMatcher<Input, Remaining, Output>;\n}\n\n/**\n * Start matching on a value (with pipe support).\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"Created\", e => e.id))\n * .pipe(Match.exhaustive)\n * ```\n */\nexport function matchValue<T extends Tagged>(input: T): PipedMatcher<T, T, never> {\n const matcher: Matcher<T, T, never> = {\n _tag: \"Matcher\",\n value: input,\n handlers: new Map(),\n _remaining: input as T,\n _output: undefined as never,\n };\n\n return addPipe(matcher);\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Match namespace for exhaustive pattern matching.\n *\n * @example\n * ```typescript\n * import { Match } from \"@jagreehal/workflow\";\n *\n * type Event =\n * | { _tag: 'Created'; id: string }\n * | { _tag: 'Updated'; id: string; data: unknown }\n * | { _tag: 'Deleted'; id: string }\n *\n * function handle(event: Event): string {\n * return Match.value(event)\n * .pipe(Match.tag(\"Created\", e => `Created: ${e.id}`))\n * .pipe(Match.tag(\"Updated\", e => `Updated: ${e.id}`))\n * .pipe(Match.tag(\"Deleted\", e => `Deleted: ${e.id}`))\n * .pipe(Match.exhaustive)\n * }\n * ```\n */\nexport const Match = {\n value: matchValue,\n tag,\n tags,\n when,\n exhaustive,\n orElse,\n orElseValue,\n is,\n isOneOf,\n} as const;\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,WAAAE,EAAA,eAAAC,EAAA,OAAAC,EAAA,YAAAC,EAAA,eAAAC,EAAA,WAAAC,EAAA,gBAAAC,EAAA,QAAAC,EAAA,SAAAC,EAAA,SAAAC,IAAA,eAAAC,EAAAZ,GA6EO,SAASS,EAOdI,EACAC,EAGyE,CACzE,OAAQC,GAAY,CAClB,IAAMC,EAAc,IAAI,IAAID,EAAQ,QAAQ,EAC5C,OAAAC,EAAY,IAAIH,EAAUC,CAAqC,EAExD,CACL,KAAM,UACN,MAAOC,EAAQ,MACf,SAAUC,EACV,WAAY,OACZ,QAAS,MACX,CACF,CACF,CAcO,SAASN,EAQdO,EAOA,CACA,OAAQF,GAAY,CAClB,IAAMC,EAAc,IAAI,IAAID,EAAQ,QAAQ,EAC5C,OAAW,CAACF,EAAUC,CAAO,IAAK,OAAO,QAAQG,CAAQ,EACnDH,GACFE,EAAY,IAAIH,EAAUC,CAAqC,EAInE,MAAO,CACL,KAAM,UACN,MAAOC,EAAQ,MACf,SAAUC,EACV,WAAY,OACZ,QAAS,MACX,CACF,CACF,CAgBO,SAASb,EACdY,EACQ,CACR,IAAMD,EAAUC,EAAQ,SAAS,IAAIA,EAAQ,MAAM,IAAI,EACvD,GAAI,CAACD,EACH,MAAM,IAAI,MAAM,uBAAuBC,EAAQ,MAAM,IAAI,EAAE,EAE7D,OAAOD,EAAQC,EAAQ,KAAK,CAC9B,CAYO,SAASR,EACdO,EACwE,CACxE,OAAQC,GAAY,CAClB,IAAMG,EAAkBH,EAAQ,SAAS,IAAIA,EAAQ,MAAM,IAAI,EAC/D,OAAIG,EACKA,EAAgBH,EAAQ,KAAK,EAE/BD,EAAQC,EAAQ,KAA6B,CACtD,CACF,CAYO,SAASP,EACdW,EACwE,CACxE,OAAOZ,EAAO,IAAMY,CAAY,CAClC,CAoBO,SAASR,EAOdE,EACAO,EACAN,EAC+F,CAC/F,OAAQC,GAAY,CAClB,IAAMC,EAAc,IAAI,IAAID,EAAQ,QAAQ,EACtCM,EAAkBN,EAAQ,SAAS,IAAIF,CAAQ,EAErD,OAAAG,EAAY,IAAIH,EAAWS,GAAkB,CAC3C,IAAMC,EAAaD,EACnB,GAAIF,EAAUG,CAAU,EACtB,OAAOT,EAAQS,CAAU,EAE3B,GAAIF,EACF,OAAOA,EAAgBC,CAAK,EAE9B,MAAM,IAAI,MAAM,+BAA+BT,CAAQ,EAAE,CAC3D,CAAC,EAEM,CACL,KAAM,UACN,MAAOE,EAAQ,MACf,SAAUC,EACV,WAAYD,EAAQ,WACpB,QAAS,MACX,CACF,CACF,CAkBO,SAASX,EACdS,EACkD,CAClD,OAAQS,GAA8CA,EAAM,OAAST,CACvE,CAYO,SAASR,KACXK,EACwD,CAC3D,IAAMc,EAAS,IAAI,IAAId,CAAI,EAC3B,OAAQY,GACNE,EAAO,IAAIF,EAAM,IAAoB,CACzC,CASA,SAASG,EAAUH,EAA2D,CAC5E,OACE,OAAOA,GAAU,UACjBA,IAAU,MACV,SAAUA,GACTA,EAA4B,OAAS,SAE1C,CAWA,SAASI,EACPX,EACwC,CACxC,MAAO,CACL,GAAGA,EACH,KAAKY,EAAmE,CACtE,IAAMC,EAASD,EAAGZ,CAAO,EAEzB,OAAIU,EAAUG,CAAM,EACXF,EAAQE,CAA0C,EAEpDA,CACT,CACF,CACF,CAYO,SAAStB,EAA6BuB,EAAqC,CAShF,OAAOH,EAR+B,CACpC,KAAM,UACN,MAAOG,EACP,SAAU,IAAI,IACd,WAAYA,EACZ,QAAS,MACX,CAEsB,CACxB,CA2BO,IAAM3B,EAAQ,CACnB,MAAOI,EACP,IAAAG,EACA,KAAAC,EACA,KAAAC,EACA,WAAAR,EACA,OAAAI,EACA,YAAAC,EACA,GAAAJ,EACA,QAAAC,CACF","names":["match_exports","__export","Match","exhaustive","is","isOneOf","matchValue","orElse","orElseValue","tag","tags","when","__toCommonJS","tagValue","handler","matcher","newHandlers","handlers","specificHandler","defaultValue","predicate","existingHandler","value","typedValue","tagSet","isMatcher","addPipe","fn","result","input"]}
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @jagreehal/workflow/match
3
+ *
4
+ * Exhaustive pattern matching for discriminated unions.
5
+ * Extends the TaggedError.match pattern to work with any tagged union.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * type Event =
10
+ * | { _tag: 'UserCreated'; user: User }
11
+ * | { _tag: 'UserUpdated'; userId: string }
12
+ * | { _tag: 'UserDeleted'; userId: string }
13
+ *
14
+ * const message = Match.value(event)
15
+ * .pipe(Match.tag("UserCreated", e => `Created: ${e.user.name}`))
16
+ * .pipe(Match.tag("UserUpdated", e => `Updated: ${e.userId}`))
17
+ * .pipe(Match.tag("UserDeleted", e => `Deleted: ${e.userId}`))
18
+ * .pipe(Match.exhaustive)
19
+ * ```
20
+ */
21
+ /**
22
+ * Any object with a _tag discriminator.
23
+ */
24
+ type Tagged<Tag extends string = string> = {
25
+ readonly _tag: Tag;
26
+ };
27
+ /**
28
+ * Extract the tag from a tagged union member.
29
+ */
30
+ type TagOf<T extends Tagged> = T["_tag"];
31
+ /**
32
+ * Extract union members that match a specific tag.
33
+ */
34
+ type MatchTag<T extends Tagged, Tag extends string> = Extract<T, {
35
+ _tag: Tag;
36
+ }>;
37
+ /**
38
+ * A matcher that is accumulating handlers for a tagged union.
39
+ *
40
+ * @typeParam Input - The full union type being matched
41
+ * @typeParam Remaining - Union members that haven't been handled yet
42
+ * @typeParam Output - The output type (union of all handler return types)
43
+ */
44
+ interface Matcher<Input extends Tagged, Remaining extends Tagged, Output> {
45
+ readonly _tag: "Matcher";
46
+ readonly value: Input;
47
+ readonly handlers: Map<string, (value: Tagged) => unknown>;
48
+ readonly _remaining: Remaining;
49
+ readonly _output: Output;
50
+ }
51
+ /**
52
+ * A completed matcher that has handled all cases.
53
+ */
54
+ interface CompletedMatcher<Output> {
55
+ readonly _tag: "CompletedMatcher";
56
+ readonly result: Output;
57
+ }
58
+ /**
59
+ * Add a handler for a specific tag.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * Match.value(event)
64
+ * .pipe(Match.tag("UserCreated", e => e.user.name))
65
+ * ```
66
+ */
67
+ declare function tag<Input extends Tagged, Remaining extends Tagged, Output, Tag extends TagOf<Remaining>, NewOutput>(tagValue: Tag, handler: (value: MatchTag<Remaining, Tag>) => NewOutput): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Exclude<Remaining, {
68
+ _tag: Tag;
69
+ }>, Output | NewOutput>;
70
+ /**
71
+ * Add handlers for multiple tags at once.
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * Match.value(event)
76
+ * .pipe(Match.tags({
77
+ * UserCreated: e => e.user.name,
78
+ * UserUpdated: e => e.userId,
79
+ * }))
80
+ * ```
81
+ */
82
+ declare function tags<Input extends Tagged, Remaining extends Tagged, Output, Handlers extends {
83
+ [K in TagOf<Remaining>]?: (value: MatchTag<Remaining, K>) => unknown;
84
+ }>(handlers: Handlers): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Exclude<Remaining, {
85
+ _tag: keyof Handlers;
86
+ }>, Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>>;
87
+ /**
88
+ * Complete the match, requiring all cases to be handled.
89
+ * This is a compile-time check - if any cases are missing, TypeScript will error.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * // TypeScript error if any tag is not handled
94
+ * const result = Match.value(event)
95
+ * .pipe(Match.tag("UserCreated", e => e.user))
96
+ * .pipe(Match.tag("UserUpdated", e => e.userId))
97
+ * .pipe(Match.tag("UserDeleted", e => e.userId))
98
+ * .pipe(Match.exhaustive)
99
+ * ```
100
+ */
101
+ declare function exhaustive<Input extends Tagged, Output>(matcher: Matcher<Input, never, Output>): Output;
102
+ /**
103
+ * Complete the match with a default handler for any remaining cases.
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const result = Match.value(event)
108
+ * .pipe(Match.tag("UserCreated", e => `Created: ${e.user.name}`))
109
+ * .pipe(Match.orElse(e => `Other event: ${e._tag}`))
110
+ * ```
111
+ */
112
+ declare function orElse<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(handler: (value: Remaining) => DefaultOutput): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput;
113
+ /**
114
+ * Complete the match with a default value for any remaining cases.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const result = Match.value(event)
119
+ * .pipe(Match.tag("UserCreated", e => e.user.name))
120
+ * .pipe(Match.orElseValue("Unknown event"))
121
+ * ```
122
+ */
123
+ declare function orElseValue<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(defaultValue: DefaultOutput): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput;
124
+ /**
125
+ * Add a handler with an additional predicate.
126
+ * The handler only runs if both the tag matches AND the predicate returns true.
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * Match.value(event)
131
+ * .pipe(Match.when(
132
+ * "UserCreated",
133
+ * e => e.user.isAdmin,
134
+ * e => `Admin created: ${e.user.name}`
135
+ * ))
136
+ * ```
137
+ */
138
+ declare function when<Input extends Tagged, Remaining extends Tagged, Output, Tag extends TagOf<Remaining>, NewOutput>(tagValue: Tag, predicate: (value: MatchTag<Remaining, Tag>) => boolean, handler: (value: MatchTag<Remaining, Tag>) => NewOutput): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Remaining, Output | NewOutput>;
139
+ /**
140
+ * Check if a tagged value has a specific tag.
141
+ * Type guard that narrows the type.
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * if (Match.is("UserCreated")(event)) {
146
+ * // event is narrowed to { _tag: 'UserCreated'; user: User }
147
+ * console.log(event.user.name);
148
+ * }
149
+ * ```
150
+ */
151
+ declare function is<T extends Tagged, Tag extends string>(tagValue: Tag): (value: T) => value is Extract<T, {
152
+ _tag: Tag;
153
+ }>;
154
+ /**
155
+ * Check if a tagged value has one of several tags.
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * if (Match.isOneOf("UserCreated", "UserUpdated")(event)) {
160
+ * // event is narrowed to UserCreated | UserUpdated
161
+ * }
162
+ * ```
163
+ */
164
+ declare function isOneOf<T extends Tagged, Tags extends TagOf<T>[]>(...tags: Tags): (value: T) => value is Extract<T, {
165
+ _tag: Tags[number];
166
+ }>;
167
+ type PipedMatcher<Input extends Tagged, Remaining extends Tagged, Output> = Matcher<Input, Remaining, Output> & {
168
+ pipe: <NewRemaining extends Tagged, NewOutput>(fn: (self: Matcher<Input, Remaining, Output>) => Matcher<Input, NewRemaining, NewOutput>) => PipedMatcher<Input, NewRemaining, NewOutput>;
169
+ } & {
170
+ pipe: <R>(fn: (self: Matcher<Input, Remaining, Output>) => R) => R;
171
+ };
172
+ /**
173
+ * Start matching on a value (with pipe support).
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const result = Match.value(event)
178
+ * .pipe(Match.tag("Created", e => e.id))
179
+ * .pipe(Match.exhaustive)
180
+ * ```
181
+ */
182
+ declare function matchValue<T extends Tagged>(input: T): PipedMatcher<T, T, never>;
183
+ /**
184
+ * Match namespace for exhaustive pattern matching.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * import { Match } from "@jagreehal/workflow";
189
+ *
190
+ * type Event =
191
+ * | { _tag: 'Created'; id: string }
192
+ * | { _tag: 'Updated'; id: string; data: unknown }
193
+ * | { _tag: 'Deleted'; id: string }
194
+ *
195
+ * function handle(event: Event): string {
196
+ * return Match.value(event)
197
+ * .pipe(Match.tag("Created", e => `Created: ${e.id}`))
198
+ * .pipe(Match.tag("Updated", e => `Updated: ${e.id}`))
199
+ * .pipe(Match.tag("Deleted", e => `Deleted: ${e.id}`))
200
+ * .pipe(Match.exhaustive)
201
+ * }
202
+ * ```
203
+ */
204
+ declare const Match: {
205
+ readonly value: typeof matchValue;
206
+ readonly tag: typeof tag;
207
+ readonly tags: typeof tags;
208
+ readonly when: typeof when;
209
+ readonly exhaustive: typeof exhaustive;
210
+ readonly orElse: typeof orElse;
211
+ readonly orElseValue: typeof orElseValue;
212
+ readonly is: typeof is;
213
+ readonly isOneOf: typeof isOneOf;
214
+ };
215
+
216
+ export { type CompletedMatcher, Match, type MatchTag, type Matcher, type TagOf, type Tagged, exhaustive, is, isOneOf, matchValue, orElse, orElseValue, tag, tags, when };
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @jagreehal/workflow/match
3
+ *
4
+ * Exhaustive pattern matching for discriminated unions.
5
+ * Extends the TaggedError.match pattern to work with any tagged union.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * type Event =
10
+ * | { _tag: 'UserCreated'; user: User }
11
+ * | { _tag: 'UserUpdated'; userId: string }
12
+ * | { _tag: 'UserDeleted'; userId: string }
13
+ *
14
+ * const message = Match.value(event)
15
+ * .pipe(Match.tag("UserCreated", e => `Created: ${e.user.name}`))
16
+ * .pipe(Match.tag("UserUpdated", e => `Updated: ${e.userId}`))
17
+ * .pipe(Match.tag("UserDeleted", e => `Deleted: ${e.userId}`))
18
+ * .pipe(Match.exhaustive)
19
+ * ```
20
+ */
21
+ /**
22
+ * Any object with a _tag discriminator.
23
+ */
24
+ type Tagged<Tag extends string = string> = {
25
+ readonly _tag: Tag;
26
+ };
27
+ /**
28
+ * Extract the tag from a tagged union member.
29
+ */
30
+ type TagOf<T extends Tagged> = T["_tag"];
31
+ /**
32
+ * Extract union members that match a specific tag.
33
+ */
34
+ type MatchTag<T extends Tagged, Tag extends string> = Extract<T, {
35
+ _tag: Tag;
36
+ }>;
37
+ /**
38
+ * A matcher that is accumulating handlers for a tagged union.
39
+ *
40
+ * @typeParam Input - The full union type being matched
41
+ * @typeParam Remaining - Union members that haven't been handled yet
42
+ * @typeParam Output - The output type (union of all handler return types)
43
+ */
44
+ interface Matcher<Input extends Tagged, Remaining extends Tagged, Output> {
45
+ readonly _tag: "Matcher";
46
+ readonly value: Input;
47
+ readonly handlers: Map<string, (value: Tagged) => unknown>;
48
+ readonly _remaining: Remaining;
49
+ readonly _output: Output;
50
+ }
51
+ /**
52
+ * A completed matcher that has handled all cases.
53
+ */
54
+ interface CompletedMatcher<Output> {
55
+ readonly _tag: "CompletedMatcher";
56
+ readonly result: Output;
57
+ }
58
+ /**
59
+ * Add a handler for a specific tag.
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * Match.value(event)
64
+ * .pipe(Match.tag("UserCreated", e => e.user.name))
65
+ * ```
66
+ */
67
+ declare function tag<Input extends Tagged, Remaining extends Tagged, Output, Tag extends TagOf<Remaining>, NewOutput>(tagValue: Tag, handler: (value: MatchTag<Remaining, Tag>) => NewOutput): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Exclude<Remaining, {
68
+ _tag: Tag;
69
+ }>, Output | NewOutput>;
70
+ /**
71
+ * Add handlers for multiple tags at once.
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * Match.value(event)
76
+ * .pipe(Match.tags({
77
+ * UserCreated: e => e.user.name,
78
+ * UserUpdated: e => e.userId,
79
+ * }))
80
+ * ```
81
+ */
82
+ declare function tags<Input extends Tagged, Remaining extends Tagged, Output, Handlers extends {
83
+ [K in TagOf<Remaining>]?: (value: MatchTag<Remaining, K>) => unknown;
84
+ }>(handlers: Handlers): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Exclude<Remaining, {
85
+ _tag: keyof Handlers;
86
+ }>, Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>>;
87
+ /**
88
+ * Complete the match, requiring all cases to be handled.
89
+ * This is a compile-time check - if any cases are missing, TypeScript will error.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * // TypeScript error if any tag is not handled
94
+ * const result = Match.value(event)
95
+ * .pipe(Match.tag("UserCreated", e => e.user))
96
+ * .pipe(Match.tag("UserUpdated", e => e.userId))
97
+ * .pipe(Match.tag("UserDeleted", e => e.userId))
98
+ * .pipe(Match.exhaustive)
99
+ * ```
100
+ */
101
+ declare function exhaustive<Input extends Tagged, Output>(matcher: Matcher<Input, never, Output>): Output;
102
+ /**
103
+ * Complete the match with a default handler for any remaining cases.
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * const result = Match.value(event)
108
+ * .pipe(Match.tag("UserCreated", e => `Created: ${e.user.name}`))
109
+ * .pipe(Match.orElse(e => `Other event: ${e._tag}`))
110
+ * ```
111
+ */
112
+ declare function orElse<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(handler: (value: Remaining) => DefaultOutput): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput;
113
+ /**
114
+ * Complete the match with a default value for any remaining cases.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * const result = Match.value(event)
119
+ * .pipe(Match.tag("UserCreated", e => e.user.name))
120
+ * .pipe(Match.orElseValue("Unknown event"))
121
+ * ```
122
+ */
123
+ declare function orElseValue<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(defaultValue: DefaultOutput): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput;
124
+ /**
125
+ * Add a handler with an additional predicate.
126
+ * The handler only runs if both the tag matches AND the predicate returns true.
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * Match.value(event)
131
+ * .pipe(Match.when(
132
+ * "UserCreated",
133
+ * e => e.user.isAdmin,
134
+ * e => `Admin created: ${e.user.name}`
135
+ * ))
136
+ * ```
137
+ */
138
+ declare function when<Input extends Tagged, Remaining extends Tagged, Output, Tag extends TagOf<Remaining>, NewOutput>(tagValue: Tag, predicate: (value: MatchTag<Remaining, Tag>) => boolean, handler: (value: MatchTag<Remaining, Tag>) => NewOutput): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Remaining, Output | NewOutput>;
139
+ /**
140
+ * Check if a tagged value has a specific tag.
141
+ * Type guard that narrows the type.
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * if (Match.is("UserCreated")(event)) {
146
+ * // event is narrowed to { _tag: 'UserCreated'; user: User }
147
+ * console.log(event.user.name);
148
+ * }
149
+ * ```
150
+ */
151
+ declare function is<T extends Tagged, Tag extends string>(tagValue: Tag): (value: T) => value is Extract<T, {
152
+ _tag: Tag;
153
+ }>;
154
+ /**
155
+ * Check if a tagged value has one of several tags.
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * if (Match.isOneOf("UserCreated", "UserUpdated")(event)) {
160
+ * // event is narrowed to UserCreated | UserUpdated
161
+ * }
162
+ * ```
163
+ */
164
+ declare function isOneOf<T extends Tagged, Tags extends TagOf<T>[]>(...tags: Tags): (value: T) => value is Extract<T, {
165
+ _tag: Tags[number];
166
+ }>;
167
+ type PipedMatcher<Input extends Tagged, Remaining extends Tagged, Output> = Matcher<Input, Remaining, Output> & {
168
+ pipe: <NewRemaining extends Tagged, NewOutput>(fn: (self: Matcher<Input, Remaining, Output>) => Matcher<Input, NewRemaining, NewOutput>) => PipedMatcher<Input, NewRemaining, NewOutput>;
169
+ } & {
170
+ pipe: <R>(fn: (self: Matcher<Input, Remaining, Output>) => R) => R;
171
+ };
172
+ /**
173
+ * Start matching on a value (with pipe support).
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const result = Match.value(event)
178
+ * .pipe(Match.tag("Created", e => e.id))
179
+ * .pipe(Match.exhaustive)
180
+ * ```
181
+ */
182
+ declare function matchValue<T extends Tagged>(input: T): PipedMatcher<T, T, never>;
183
+ /**
184
+ * Match namespace for exhaustive pattern matching.
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * import { Match } from "@jagreehal/workflow";
189
+ *
190
+ * type Event =
191
+ * | { _tag: 'Created'; id: string }
192
+ * | { _tag: 'Updated'; id: string; data: unknown }
193
+ * | { _tag: 'Deleted'; id: string }
194
+ *
195
+ * function handle(event: Event): string {
196
+ * return Match.value(event)
197
+ * .pipe(Match.tag("Created", e => `Created: ${e.id}`))
198
+ * .pipe(Match.tag("Updated", e => `Updated: ${e.id}`))
199
+ * .pipe(Match.tag("Deleted", e => `Deleted: ${e.id}`))
200
+ * .pipe(Match.exhaustive)
201
+ * }
202
+ * ```
203
+ */
204
+ declare const Match: {
205
+ readonly value: typeof matchValue;
206
+ readonly tag: typeof tag;
207
+ readonly tags: typeof tags;
208
+ readonly when: typeof when;
209
+ readonly exhaustive: typeof exhaustive;
210
+ readonly orElse: typeof orElse;
211
+ readonly orElseValue: typeof orElseValue;
212
+ readonly is: typeof is;
213
+ readonly isOneOf: typeof isOneOf;
214
+ };
215
+
216
+ export { type CompletedMatcher, Match, type MatchTag, type Matcher, type TagOf, type Tagged, exhaustive, is, isOneOf, matchValue, orElse, orElseValue, tag, tags, when };
package/dist/match.js ADDED
@@ -0,0 +1,2 @@
1
+ function s(e,t){return n=>{let a=new Map(n.handlers);return a.set(e,t),{_tag:"Matcher",value:n.value,handlers:a,_remaining:void 0,_output:void 0}}}function l(e){return t=>{let n=new Map(t.handlers);for(let[a,u]of Object.entries(e))u&&n.set(a,u);return{_tag:"Matcher",value:t.value,handlers:n,_remaining:void 0,_output:void 0}}}function o(e){let t=e.handlers.get(e.value._tag);if(!t)throw new Error(`No handler for tag: ${e.value._tag}`);return t(e.value)}function p(e){return t=>{let n=t.handlers.get(t.value._tag);return n?n(t.value):e(t.value)}}function T(e){return p(()=>e)}function c(e,t,n){return a=>{let u=new Map(a.handlers),g=a.handlers.get(e);return u.set(e,r=>{let i=r;if(t(i))return n(i);if(g)return g(r);throw new Error(`No handler matched for tag: ${e}`)}),{_tag:"Matcher",value:a.value,handlers:u,_remaining:a._remaining,_output:void 0}}}function O(e){return t=>t._tag===e}function h(...e){let t=new Set(e);return n=>t.has(n._tag)}function x(e){return typeof e=="object"&&e!==null&&"_tag"in e&&e._tag==="Matcher"}function d(e){return{...e,pipe(t){let n=t(e);return x(n)?d(n):n}}}function f(e){return d({_tag:"Matcher",value:e,handlers:new Map,_remaining:e,_output:void 0})}var m={value:f,tag:s,tags:l,when:c,exhaustive:o,orElse:p,orElseValue:T,is:O,isOneOf:h};export{m as Match,o as exhaustive,O as is,h as isOneOf,f as matchValue,p as orElse,T as orElseValue,s as tag,l as tags,c as when};
2
+ //# sourceMappingURL=match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/match.ts"],"sourcesContent":["/**\n * @jagreehal/workflow/match\n *\n * Exhaustive pattern matching for discriminated unions.\n * Extends the TaggedError.match pattern to work with any tagged union.\n *\n * @example\n * ```typescript\n * type Event =\n * | { _tag: 'UserCreated'; user: User }\n * | { _tag: 'UserUpdated'; userId: string }\n * | { _tag: 'UserDeleted'; userId: string }\n *\n * const message = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => `Created: ${e.user.name}`))\n * .pipe(Match.tag(\"UserUpdated\", e => `Updated: ${e.userId}`))\n * .pipe(Match.tag(\"UserDeleted\", e => `Deleted: ${e.userId}`))\n * .pipe(Match.exhaustive)\n * ```\n */\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Any object with a _tag discriminator.\n */\nexport type Tagged<Tag extends string = string> = { readonly _tag: Tag };\n\n/**\n * Extract the tag from a tagged union member.\n */\nexport type TagOf<T extends Tagged> = T[\"_tag\"];\n\n/**\n * Extract union members that match a specific tag.\n */\nexport type MatchTag<T extends Tagged, Tag extends string> = Extract<T, { _tag: Tag }>;\n\n/**\n * A matcher that is accumulating handlers for a tagged union.\n *\n * @typeParam Input - The full union type being matched\n * @typeParam Remaining - Union members that haven't been handled yet\n * @typeParam Output - The output type (union of all handler return types)\n */\nexport interface Matcher<Input extends Tagged, Remaining extends Tagged, Output> {\n readonly _tag: \"Matcher\";\n readonly value: Input;\n readonly handlers: Map<string, (value: Tagged) => unknown>;\n readonly _remaining: Remaining;\n readonly _output: Output;\n}\n\n/**\n * A completed matcher that has handled all cases.\n */\nexport interface CompletedMatcher<Output> {\n readonly _tag: \"CompletedMatcher\";\n readonly result: Output;\n}\n\n// =============================================================================\n// Core Functions\n// =============================================================================\n\n\n/**\n * Add a handler for a specific tag.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user.name))\n * ```\n */\nexport function tag<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Tag extends TagOf<Remaining>,\n NewOutput,\n>(\n tagValue: Tag,\n handler: (value: MatchTag<Remaining, Tag>) => NewOutput\n): (\n matcher: Matcher<Input, Remaining, Output>\n) => Matcher<Input, Exclude<Remaining, { _tag: Tag }>, Output | NewOutput> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n newHandlers.set(tagValue, handler as (value: Tagged) => unknown);\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: undefined as unknown as Exclude<Remaining, { _tag: Tag }>,\n _output: undefined as unknown as Output | NewOutput,\n };\n };\n}\n\n/**\n * Add handlers for multiple tags at once.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.tags({\n * UserCreated: e => e.user.name,\n * UserUpdated: e => e.userId,\n * }))\n * ```\n */\nexport function tags<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Handlers extends {\n [K in TagOf<Remaining>]?: (value: MatchTag<Remaining, K>) => unknown;\n },\n>(\n handlers: Handlers\n): (\n matcher: Matcher<Input, Remaining, Output>\n) => Matcher<\n Input,\n Exclude<Remaining, { _tag: keyof Handlers }>,\n Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>\n> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n for (const [tagValue, handler] of Object.entries(handlers)) {\n if (handler) {\n newHandlers.set(tagValue, handler as (value: Tagged) => unknown);\n }\n }\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: undefined as unknown as Exclude<Remaining, { _tag: keyof Handlers }>,\n _output: undefined as unknown as Output | ReturnType<NonNullable<Handlers[keyof Handlers]>>,\n };\n };\n}\n\n/**\n * Complete the match, requiring all cases to be handled.\n * This is a compile-time check - if any cases are missing, TypeScript will error.\n *\n * @example\n * ```typescript\n * // TypeScript error if any tag is not handled\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user))\n * .pipe(Match.tag(\"UserUpdated\", e => e.userId))\n * .pipe(Match.tag(\"UserDeleted\", e => e.userId))\n * .pipe(Match.exhaustive)\n * ```\n */\nexport function exhaustive<Input extends Tagged, Output>(\n matcher: Matcher<Input, never, Output>\n): Output {\n const handler = matcher.handlers.get(matcher.value._tag);\n if (!handler) {\n throw new Error(`No handler for tag: ${matcher.value._tag}`);\n }\n return handler(matcher.value) as Output;\n}\n\n/**\n * Complete the match with a default handler for any remaining cases.\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => `Created: ${e.user.name}`))\n * .pipe(Match.orElse(e => `Other event: ${e._tag}`))\n * ```\n */\nexport function orElse<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(\n handler: (value: Remaining) => DefaultOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput {\n return (matcher) => {\n const specificHandler = matcher.handlers.get(matcher.value._tag);\n if (specificHandler) {\n return specificHandler(matcher.value) as Output;\n }\n return handler(matcher.value as unknown as Remaining);\n };\n}\n\n/**\n * Complete the match with a default value for any remaining cases.\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"UserCreated\", e => e.user.name))\n * .pipe(Match.orElseValue(\"Unknown event\"))\n * ```\n */\nexport function orElseValue<Input extends Tagged, Remaining extends Tagged, Output, DefaultOutput>(\n defaultValue: DefaultOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Output | DefaultOutput {\n return orElse(() => defaultValue);\n}\n\n// =============================================================================\n// Predicates & Guards\n// =============================================================================\n\n/**\n * Add a handler with an additional predicate.\n * The handler only runs if both the tag matches AND the predicate returns true.\n *\n * @example\n * ```typescript\n * Match.value(event)\n * .pipe(Match.when(\n * \"UserCreated\",\n * e => e.user.isAdmin,\n * e => `Admin created: ${e.user.name}`\n * ))\n * ```\n */\nexport function when<\n Input extends Tagged,\n Remaining extends Tagged,\n Output,\n Tag extends TagOf<Remaining>,\n NewOutput,\n>(\n tagValue: Tag,\n predicate: (value: MatchTag<Remaining, Tag>) => boolean,\n handler: (value: MatchTag<Remaining, Tag>) => NewOutput\n): (matcher: Matcher<Input, Remaining, Output>) => Matcher<Input, Remaining, Output | NewOutput> {\n return (matcher) => {\n const newHandlers = new Map(matcher.handlers);\n const existingHandler = matcher.handlers.get(tagValue);\n\n newHandlers.set(tagValue, (value: Tagged) => {\n const typedValue = value as MatchTag<Remaining, Tag>;\n if (predicate(typedValue)) {\n return handler(typedValue);\n }\n if (existingHandler) {\n return existingHandler(value);\n }\n throw new Error(`No handler matched for tag: ${tagValue}`);\n });\n\n return {\n _tag: \"Matcher\",\n value: matcher.value,\n handlers: newHandlers,\n _remaining: matcher._remaining,\n _output: undefined as unknown as Output | NewOutput,\n };\n };\n}\n\n// =============================================================================\n// Type Narrowing Utilities\n// =============================================================================\n\n/**\n * Check if a tagged value has a specific tag.\n * Type guard that narrows the type.\n *\n * @example\n * ```typescript\n * if (Match.is(\"UserCreated\")(event)) {\n * // event is narrowed to { _tag: 'UserCreated'; user: User }\n * console.log(event.user.name);\n * }\n * ```\n */\nexport function is<T extends Tagged, Tag extends string>(\n tagValue: Tag\n): (value: T) => value is Extract<T, { _tag: Tag }> {\n return (value): value is Extract<T, { _tag: Tag }> => value._tag === tagValue;\n}\n\n/**\n * Check if a tagged value has one of several tags.\n *\n * @example\n * ```typescript\n * if (Match.isOneOf(\"UserCreated\", \"UserUpdated\")(event)) {\n * // event is narrowed to UserCreated | UserUpdated\n * }\n * ```\n */\nexport function isOneOf<T extends Tagged, Tags extends TagOf<T>[]>(\n ...tags: Tags\n): (value: T) => value is Extract<T, { _tag: Tags[number] }> {\n const tagSet = new Set(tags);\n return (value): value is Extract<T, { _tag: Tags[number] }> =>\n tagSet.has(value._tag as Tags[number]);\n}\n\n// =============================================================================\n// Pipe Helper\n// =============================================================================\n\n/**\n * Type guard to check if a value is a Matcher.\n */\nfunction isMatcher(value: unknown): value is Matcher<Tagged, Tagged, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"_tag\" in value &&\n (value as { _tag: unknown })._tag === \"Matcher\"\n );\n}\n\ntype PipedMatcher<Input extends Tagged, Remaining extends Tagged, Output> =\n Matcher<Input, Remaining, Output> & {\n pipe: <NewRemaining extends Tagged, NewOutput>(\n fn: (self: Matcher<Input, Remaining, Output>) => Matcher<Input, NewRemaining, NewOutput>\n ) => PipedMatcher<Input, NewRemaining, NewOutput>;\n } & {\n pipe: <R>(fn: (self: Matcher<Input, Remaining, Output>) => R) => R;\n };\n\nfunction addPipe<Input extends Tagged, Remaining extends Tagged, Output>(\n matcher: Matcher<Input, Remaining, Output>\n): PipedMatcher<Input, Remaining, Output> {\n return {\n ...matcher,\n pipe(fn: (self: Matcher<Input, Remaining, Output>) => unknown): unknown {\n const result = fn(matcher);\n // If result is a Matcher, add pipe to it too\n if (isMatcher(result)) {\n return addPipe(result as Matcher<Tagged, Tagged, unknown>);\n }\n return result;\n },\n } as PipedMatcher<Input, Remaining, Output>;\n}\n\n/**\n * Start matching on a value (with pipe support).\n *\n * @example\n * ```typescript\n * const result = Match.value(event)\n * .pipe(Match.tag(\"Created\", e => e.id))\n * .pipe(Match.exhaustive)\n * ```\n */\nexport function matchValue<T extends Tagged>(input: T): PipedMatcher<T, T, never> {\n const matcher: Matcher<T, T, never> = {\n _tag: \"Matcher\",\n value: input,\n handlers: new Map(),\n _remaining: input as T,\n _output: undefined as never,\n };\n\n return addPipe(matcher);\n}\n\n// =============================================================================\n// Namespace Export\n// =============================================================================\n\n/**\n * Match namespace for exhaustive pattern matching.\n *\n * @example\n * ```typescript\n * import { Match } from \"@jagreehal/workflow\";\n *\n * type Event =\n * | { _tag: 'Created'; id: string }\n * | { _tag: 'Updated'; id: string; data: unknown }\n * | { _tag: 'Deleted'; id: string }\n *\n * function handle(event: Event): string {\n * return Match.value(event)\n * .pipe(Match.tag(\"Created\", e => `Created: ${e.id}`))\n * .pipe(Match.tag(\"Updated\", e => `Updated: ${e.id}`))\n * .pipe(Match.tag(\"Deleted\", e => `Deleted: ${e.id}`))\n * .pipe(Match.exhaustive)\n * }\n * ```\n */\nexport const Match = {\n value: matchValue,\n tag,\n tags,\n when,\n exhaustive,\n orElse,\n orElseValue,\n is,\n isOneOf,\n} as const;\n"],"mappings":"AA6EO,SAASA,EAOdC,EACAC,EAGyE,CACzE,OAAQC,GAAY,CAClB,IAAMC,EAAc,IAAI,IAAID,EAAQ,QAAQ,EAC5C,OAAAC,EAAY,IAAIH,EAAUC,CAAqC,EAExD,CACL,KAAM,UACN,MAAOC,EAAQ,MACf,SAAUC,EACV,WAAY,OACZ,QAAS,MACX,CACF,CACF,CAcO,SAASC,EAQdC,EAOA,CACA,OAAQH,GAAY,CAClB,IAAMC,EAAc,IAAI,IAAID,EAAQ,QAAQ,EAC5C,OAAW,CAACF,EAAUC,CAAO,IAAK,OAAO,QAAQI,CAAQ,EACnDJ,GACFE,EAAY,IAAIH,EAAUC,CAAqC,EAInE,MAAO,CACL,KAAM,UACN,MAAOC,EAAQ,MACf,SAAUC,EACV,WAAY,OACZ,QAAS,MACX,CACF,CACF,CAgBO,SAASG,EACdJ,EACQ,CACR,IAAMD,EAAUC,EAAQ,SAAS,IAAIA,EAAQ,MAAM,IAAI,EACvD,GAAI,CAACD,EACH,MAAM,IAAI,MAAM,uBAAuBC,EAAQ,MAAM,IAAI,EAAE,EAE7D,OAAOD,EAAQC,EAAQ,KAAK,CAC9B,CAYO,SAASK,EACdN,EACwE,CACxE,OAAQC,GAAY,CAClB,IAAMM,EAAkBN,EAAQ,SAAS,IAAIA,EAAQ,MAAM,IAAI,EAC/D,OAAIM,EACKA,EAAgBN,EAAQ,KAAK,EAE/BD,EAAQC,EAAQ,KAA6B,CACtD,CACF,CAYO,SAASO,EACdC,EACwE,CACxE,OAAOH,EAAO,IAAMG,CAAY,CAClC,CAoBO,SAASC,EAOdX,EACAY,EACAX,EAC+F,CAC/F,OAAQC,GAAY,CAClB,IAAMC,EAAc,IAAI,IAAID,EAAQ,QAAQ,EACtCW,EAAkBX,EAAQ,SAAS,IAAIF,CAAQ,EAErD,OAAAG,EAAY,IAAIH,EAAWc,GAAkB,CAC3C,IAAMC,EAAaD,EACnB,GAAIF,EAAUG,CAAU,EACtB,OAAOd,EAAQc,CAAU,EAE3B,GAAIF,EACF,OAAOA,EAAgBC,CAAK,EAE9B,MAAM,IAAI,MAAM,+BAA+Bd,CAAQ,EAAE,CAC3D,CAAC,EAEM,CACL,KAAM,UACN,MAAOE,EAAQ,MACf,SAAUC,EACV,WAAYD,EAAQ,WACpB,QAAS,MACX,CACF,CACF,CAkBO,SAASc,EACdhB,EACkD,CAClD,OAAQc,GAA8CA,EAAM,OAASd,CACvE,CAYO,SAASiB,KACXb,EACwD,CAC3D,IAAMc,EAAS,IAAI,IAAId,CAAI,EAC3B,OAAQU,GACNI,EAAO,IAAIJ,EAAM,IAAoB,CACzC,CASA,SAASK,EAAUL,EAA2D,CAC5E,OACE,OAAOA,GAAU,UACjBA,IAAU,MACV,SAAUA,GACTA,EAA4B,OAAS,SAE1C,CAWA,SAASM,EACPlB,EACwC,CACxC,MAAO,CACL,GAAGA,EACH,KAAKmB,EAAmE,CACtE,IAAMC,EAASD,EAAGnB,CAAO,EAEzB,OAAIiB,EAAUG,CAAM,EACXF,EAAQE,CAA0C,EAEpDA,CACT,CACF,CACF,CAYO,SAASC,EAA6BC,EAAqC,CAShF,OAAOJ,EAR+B,CACpC,KAAM,UACN,MAAOI,EACP,SAAU,IAAI,IACd,WAAYA,EACZ,QAAS,MACX,CAEsB,CACxB,CA2BO,IAAMC,EAAQ,CACnB,MAAOF,EACP,IAAAxB,EACA,KAAAK,EACA,KAAAO,EACA,WAAAL,EACA,OAAAC,EACA,YAAAE,EACA,GAAAO,EACA,QAAAC,CACF","names":["tag","tagValue","handler","matcher","newHandlers","tags","handlers","exhaustive","orElse","specificHandler","orElseValue","defaultValue","when","predicate","existingHandler","value","typedValue","is","isOneOf","tagSet","isMatcher","addPipe","fn","result","matchValue","input","Match"]}
package/dist/resource.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";var B=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var ce=(e,t)=>{for(var i in t)B(e,i,{get:t[i],enumerable:!0})},le=(e,t,i,k)=>{if(t&&typeof t=="object"||typeof t=="function")for(let x of ie(t))!pe.call(e,x)&&x!==i&&B(e,x,{get:()=>t[x],enumerable:!(k=ae(t,x))||k.enumerable});return e};var Ee=e=>le(B({},"__esModule",{value:!0}),e);var Se={};ce(Se,{createResource:()=>xe,createResourceScope:()=>oe,isResourceCleanupError:()=>H,withScope:()=>Ce});module.exports=Ee(Se);var q=e=>({ok:!0,value:e}),b=(e,t)=>({ok:!1,error:e,...t?.cause!==void 0?{cause:t.cause}:{}});var ye=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",j=Symbol.for("step_timeout_marker");function Z(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:j in e}function we(e){if(!(typeof e!="object"||e===null)){if(e.type==="STEP_TIMEOUT"){let t=e;return{timeoutMs:t.timeoutMs,stepName:t.stepName,stepKey:t.stepKey,attempt:t.attempt}}if(j in e)return e[j]}}var ne=Symbol("early-exit");function me(e,t){return{[ne]:!0,error:e,meta:t}}function Te(e){return typeof e=="object"&&e!==null&&e[ne]===!0}var re=Symbol("mapper-exception");function ke(e){return{[re]:!0,thrown:e}}function de(e){return typeof e=="object"&&e!==null&&e[re]===!0}function fe(e){return typeof e=="string"?{name:e}:e??{}}function G(e,t){let{backoff:i,initialDelay:k,maxDelay:x,jitter:O}=t,d;switch(i){case"fixed":d=k;break;case"linear":d=k*e;break;case"exponential":d=k*Math.pow(2,e-1);break}if(d=Math.min(d,x),O){let s=d*.25*Math.random();d=d+s}return Math.floor(d)}function z(e){return new Promise(t=>setTimeout(t,e))}var ee=Symbol("timeout");async function Re(e,t,i){let k=new AbortController,x=t.error??{type:"STEP_TIMEOUT",stepName:i.name,stepKey:i.key,timeoutMs:t.ms,attempt:i.attempt},O,d=new Promise((v,f)=>{O=setTimeout(()=>{k.abort(),f({[ee]:!0,error:x})},t.ms)}),s;t.signal?s=Promise.resolve(e(k.signal)):s=Promise.resolve(e());try{return await Promise.race([s,d])}catch(v){if(typeof v=="object"&&v!==null&&v[ee]===!0){let f=v.error;if(typeof f=="object"&&f!==null&&f.type!=="STEP_TIMEOUT"){let V={timeoutMs:t.ms,stepName:i.name,stepKey:i.key,attempt:i.attempt};j in f?f[j]=V:Object.defineProperty(f,j,{value:V,enumerable:!1,writable:!0,configurable:!1})}throw f}throw v}finally{clearTimeout(O)}}var K={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,retryOn:()=>!0,onRetry:()=>{}};async function te(e,t){let{onError:i,onEvent:k,catchUnexpected:x,workflowId:O,context:d}=t&&typeof t=="object"?t:{},s=O??crypto.randomUUID(),v=!i&&!x,f=[],V=0,W=r=>r??`step_${++V}`,l=r=>{let S=r.context!==void 0||d===void 0?r:{...r,context:d};if(S.type==="step_success"){let _=S.stepId;for(let U=f.length-1;U>=0;U--){let N=f[U];if(N.type==="race"&&!N.winnerId){N.winnerId=_;break}}}k?.(S,d)},M=me,Q=r=>Te(r),X=(r,S)=>v?S?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r,...S.resultCause!==void 0?{cause:S.resultCause}:{}}}:S?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:r,thrown:S.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r}}:r,se=r=>({type:"UNEXPECTED_ERROR",cause:r.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:r.error,...r.meta.resultCause!==void 0?{cause:r.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:r.error,thrown:r.meta.thrown}});try{let S=function(y,a){let u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),o=!1;f.push({scopeId:u,type:"parallel"});let R=()=>{if(o)return;o=!0;let c=f.findIndex(p=>p.scopeId===u);c!==-1&&f.splice(c,1),l({type:"scope_end",workflowId:s,scopeId:u,ts:Date.now(),durationMs:performance.now()-n})};l({type:"scope_start",workflowId:s,scopeId:u,scopeType:"parallel",name:y,ts:Date.now()});try{let c=await a();if(R(),!c.ok)throw i?.(c.error,y,d),M(c.error,{origin:"result",resultCause:c.cause});return c.value}catch(c){throw R(),c}})()},_=function(y,a){let u=Object.keys(y),n=a.name??`Parallel(${u.join(", ")})`,o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let R=performance.now(),c=!1;f.push({scopeId:o,type:"parallel"});let p=()=>{if(c)return;c=!0;let w=f.findIndex(T=>T.scopeId===o);w!==-1&&f.splice(w,1),l({type:"scope_end",workflowId:s,scopeId:o,ts:Date.now(),durationMs:performance.now()-R})};l({type:"scope_start",workflowId:s,scopeId:o,scopeType:"parallel",name:n,ts:Date.now()});try{let w=await new Promise(A=>{if(u.length===0){A([]);return}let h=!1,C=u.length,F=new Array(u.length);for(let P=0;P<u.length;P++){let D=u[P],Y=P;Promise.resolve(y[D]()).catch(m=>b({type:"PROMISE_REJECTED",cause:m},{cause:{type:"PROMISE_REJECTION",reason:m}})).then(m=>{if(!h){if(!m.ok){h=!0,A([{key:D,result:m}]);return}F[Y]={key:D,result:m},C--,C===0&&A(F)}})}});p();let T={};for(let{key:A,result:h}of w){if(!h.ok)throw i?.(h.error,A,d),M(h.error,{origin:"result",resultCause:h.cause});T[A]=h.value}return T}catch(w){throw p(),w}})()};var ge=S,Ae=_;let r=(y,a)=>(async()=>{let u=fe(a),{name:n,key:o,retry:R,timeout:c}=u,p=W(o),w=k,T=w?performance.now():0;if(!(typeof y=="function")){if(R&&R.attempts>1)throw new Error("step: retry options require a function operation. Direct Promise/Result values cannot be re-executed on retry. Wrap your operation in a function: step(() => yourOperation, { retry: {...} })");if(c)throw new Error("step: timeout options require a function operation. Direct Promise/Result values cannot be wrapped with timeout after they've started. Wrap your operation in a function: step(() => yourOperation, { timeout: {...} })")}let C={attempts:Math.max(1,R?.attempts??1),backoff:R?.backoff??K.backoff,initialDelay:R?.initialDelay??K.initialDelay,maxDelay:R?.maxDelay??K.maxDelay,jitter:R?.jitter??K.jitter,retryOn:R?.retryOn??K.retryOn,onRetry:R?.onRetry??K.onRetry};k&&l({type:"step_start",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now()});let F;for(let m=1;m<=C.attempts;m++){let ue=w?performance.now():0;try{let E;if(typeof y=="function"?c?E=await Re(y,c,{name:n,key:o,attempt:m}):E=await y():E=await y,E.ok){let I=performance.now()-T;return l({type:"step_success",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:I}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:n,ts:Date.now(),durationMs:I,result:E}),E.value}if(F=E,m<C.attempts&&C.retryOn(E.error,m)){let I=G(m,C);l({type:"step_retry",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),attempt:m+1,maxAttempts:C.attempts,delayMs:I,error:E.error}),C.onRetry(E.error,m,I),await z(I);continue}C.attempts>1&&l({type:"step_retries_exhausted",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:performance.now()-T,attempts:m,lastError:E.error});break}catch(E){let I=performance.now()-ue;if(Q(E))throw l({type:"step_aborted",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:I}),E;if(Z(E)){let g=we(E),$=c?.ms??g?.timeoutMs??0;if(l({type:"step_timeout",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),timeoutMs:$,attempt:m}),m<C.attempts&&C.retryOn(E,m)){let J=G(m,C);l({type:"step_retry",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),attempt:m+1,maxAttempts:C.attempts,delayMs:J,error:E}),C.onRetry(E,m,J),await z(J);continue}C.attempts>1&&l({type:"step_retries_exhausted",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:performance.now()-T,attempts:m,lastError:E})}if(m<C.attempts&&C.retryOn(E,m)){let g=G(m,C);l({type:"step_retry",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),attempt:m+1,maxAttempts:C.attempts,delayMs:g,error:E}),C.onRetry(E,m,g),await z(g);continue}C.attempts>1&&!Z(E)&&l({type:"step_retries_exhausted",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:performance.now()-T,attempts:m,lastError:E});let L=performance.now()-T;if(x){let g;try{g=x(E)}catch($){throw ke($)}throw l({type:"step_error",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:L,error:g}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:n,ts:Date.now(),durationMs:L,result:b(g,{cause:E}),meta:{origin:"throw",thrown:E}}),i?.(g,n,d),M(g,{origin:"throw",thrown:E})}else{let g={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:E}};throw l({type:"step_error",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:L,error:g}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:n,ts:Date.now(),durationMs:L,result:b(g,{cause:E}),meta:{origin:"throw",thrown:E}}),E}}}let P=F,D=performance.now()-T,Y=X(P.error,{origin:"result",resultCause:P.cause});throw l({type:"step_error",workflowId:s,stepId:p,stepKey:o,name:n,ts:Date.now(),durationMs:D,error:Y}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:n,ts:Date.now(),durationMs:D,result:P,meta:{origin:"result",resultCause:P.cause}}),i?.(P.error,n,d),M(P.error,{origin:"result",resultCause:P.cause})})();r.try=(y,a)=>{let u=a.name,n=a.key,o=W(n),R="error"in a?()=>a.error:a.onError,c=k;return(async()=>{let p=c?performance.now():0;k&&l({type:"step_start",workflowId:s,stepId:o,stepKey:n,name:u,ts:Date.now()});try{let w=await y(),T=performance.now()-p;return l({type:"step_success",workflowId:s,stepId:o,stepKey:n,name:u,ts:Date.now(),durationMs:T}),n&&l({type:"step_complete",workflowId:s,stepKey:n,name:u,ts:Date.now(),durationMs:T,result:q(w)}),w}catch(w){let T=R(w),A=performance.now()-p,h=X(T,{origin:"throw",thrown:w});throw l({type:"step_error",workflowId:s,stepId:o,stepKey:n,name:u,ts:Date.now(),durationMs:A,error:h}),n&&l({type:"step_complete",workflowId:s,stepKey:n,name:u,ts:Date.now(),durationMs:A,result:b(T,{cause:w}),meta:{origin:"throw",thrown:w}}),i?.(T,u,d),M(T,{origin:"throw",thrown:w})}})()},r.fromResult=(y,a)=>{let u=a.name,n=a.key,o=W(n),R="error"in a?()=>a.error:a.onError,c=k;return(async()=>{let p=c?performance.now():0;k&&l({type:"step_start",workflowId:s,stepId:o,stepKey:n,name:u,ts:Date.now()});let w=await y();if(w.ok){let T=performance.now()-p;return l({type:"step_success",workflowId:s,stepId:o,stepKey:n,name:u,ts:Date.now(),durationMs:T}),n&&l({type:"step_complete",workflowId:s,stepKey:n,name:u,ts:Date.now(),durationMs:T,result:q(w.value)}),w.value}else{let T=R(w.error),A=performance.now()-p,h=X(T,{origin:"result",resultCause:w.error});throw l({type:"step_error",workflowId:s,stepId:o,stepKey:n,name:u,ts:Date.now(),durationMs:A,error:h}),n&&l({type:"step_complete",workflowId:s,stepKey:n,name:u,ts:Date.now(),durationMs:A,result:b(T,{cause:w.error}),meta:{origin:"result",resultCause:w.error}}),i?.(T,u,d),M(T,{origin:"result",resultCause:w.error})}})()},r.retry=(y,a)=>r(y,{name:a.name,key:a.key,retry:{attempts:a.attempts,backoff:a.backoff,initialDelay:a.initialDelay,maxDelay:a.maxDelay,jitter:a.jitter,retryOn:a.retryOn,onRetry:a.onRetry},timeout:a.timeout}),r.withTimeout=(y,a)=>r(y,{name:a.name,key:a.key,timeout:a}),r.parallel=((...y)=>{if(typeof y[0]=="string"){let a=y[0],u=y[1];return S(a,u)}else{let a=y[0],u=y[1]??{};return _(a,u)}}),r.race=(y,a)=>{let u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),o=!1,R={scopeId:u,type:"race",winnerId:void 0};f.push(R);let c=()=>{if(o)return;o=!0;let p=f.findIndex(w=>w.scopeId===u);p!==-1&&f.splice(p,1),l({type:"scope_end",workflowId:s,scopeId:u,ts:Date.now(),durationMs:performance.now()-n,winnerId:R.winnerId})};l({type:"scope_start",workflowId:s,scopeId:u,scopeType:"race",name:y,ts:Date.now()});try{let p=await a();if(c(),!p.ok)throw i?.(p.error,y,d),M(p.error,{origin:"result",resultCause:p.cause});return p.value}catch(p){throw c(),p}})()},r.allSettled=(y,a)=>{let u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let n=performance.now(),o=!1;f.push({scopeId:u,type:"allSettled"});let R=()=>{if(o)return;o=!0;let c=f.findIndex(p=>p.scopeId===u);c!==-1&&f.splice(c,1),l({type:"scope_end",workflowId:s,scopeId:u,ts:Date.now(),durationMs:performance.now()-n})};l({type:"scope_start",workflowId:s,scopeId:u,scopeType:"allSettled",name:y,ts:Date.now()});try{let c=await a();if(R(),!c.ok)throw i?.(c.error,y,d),M(c.error,{origin:"result",resultCause:c.cause});return c.value}catch(c){throw R(),c}})()};let N=await e(r);return q(N)}catch(r){if(de(r))throw r.thrown;if(Q(r)){let _=r.meta.origin==="throw"?r.meta.thrown:r.meta.resultCause;if(x||i)return b(r.error,{cause:_});if(ye(r.error))return b(r.error,{cause:_});let U=se(r);return b(U,{cause:_})}if(x){let _=x(r);return i?.(_,"unexpected",d),b(_,{cause:r})}let S={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:r}};return i?.(S,"unexpected",d),b(S,{cause:r})}}te.strict=(e,t)=>te(e,t);function H(e){return typeof e=="object"&&e!==null&&e.type==="RESOURCE_CLEANUP_ERROR"}function oe(){let e=[];return{add:t=>(e.push(t),t.value),close:async()=>{let t=[];for(let i=e.length-1;i>=0;i--)try{await e[i].close()}catch(k){t.push(k)}if(e.length=0,t.length>0)throw{type:"RESOURCE_CLEANUP_ERROR",errors:t}},has:t=>e.includes(t),size:()=>e.length}}async function Ce(e){let t=oe(),i;try{i=await e(t)}catch(k){try{await t.close()}catch(x){if(H(x))return b({...x,originalResult:{thrown:k}})}throw k}try{await t.close()}catch(k){if(H(k))return b({...k,originalResult:i});throw k}return i}async function xe(e,t){let i=await e();return{value:i,close:async()=>{await t(i)}}}0&&(module.exports={createResource,createResourceScope,isResourceCleanupError,withScope});
1
+ "use strict";var B=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var pe=Object.prototype.hasOwnProperty;var ce=(e,n)=>{for(var i in n)B(e,i,{get:n[i],enumerable:!0})},le=(e,n,i,k)=>{if(n&&typeof n=="object"||typeof n=="function")for(let x of ie(n))!pe.call(e,x)&&x!==i&&B(e,x,{get:()=>n[x],enumerable:!(k=ae(n,x))||k.enumerable});return e};var Ee=e=>le(B({},"__esModule",{value:!0}),e);var Se={};ce(Se,{createResource:()=>xe,createResourceScope:()=>oe,isResourceCleanupError:()=>H,withScope:()=>Ce});module.exports=Ee(Se);var q=e=>({ok:!0,value:e}),P=(e,n)=>({ok:!1,error:e,...n?.cause!==void 0?{cause:n.cause}:{}});var ye=e=>typeof e=="object"&&e!==null&&e.type==="UNEXPECTED_ERROR",F=Symbol.for("step_timeout_marker");function Z(e){return typeof e!="object"||e===null?!1:e.type==="STEP_TIMEOUT"?!0:F in e}function we(e){if(!(typeof e!="object"||e===null)){if(e.type==="STEP_TIMEOUT"){let n=e;return{timeoutMs:n.timeoutMs,stepName:n.stepName,stepKey:n.stepKey,attempt:n.attempt}}if(F in e)return e[F]}}var te=Symbol("early-exit");function me(e,n){return{[te]:!0,error:e,meta:n}}function Te(e){return typeof e=="object"&&e!==null&&e[te]===!0}var re=Symbol("mapper-exception");function ke(e){return{[re]:!0,thrown:e}}function de(e){return typeof e=="object"&&e!==null&&e[re]===!0}function fe(e){return typeof e=="string"?{name:e}:e??{}}function G(e,n){let{backoff:i,initialDelay:k,maxDelay:x,jitter:I}=n,d;switch(i){case"fixed":d=k;break;case"linear":d=k*e;break;case"exponential":d=k*Math.pow(2,e-1);break}if(d=Math.min(d,x),I){let s=d*.25*Math.random();d=d+s}return Math.floor(d)}function z(e){return new Promise(n=>setTimeout(n,e))}var ee=Symbol("timeout");async function Re(e,n,i){let k=new AbortController,x=n.error??{type:"STEP_TIMEOUT",stepName:i.name,stepKey:i.key,timeoutMs:n.ms,attempt:i.attempt},I,d=new Promise((_,f)=>{I=setTimeout(()=>{k.abort(),f({[ee]:!0,error:x})},n.ms)}),s;n.signal?s=Promise.resolve(e(k.signal)):s=Promise.resolve(e());try{return await Promise.race([s,d])}catch(_){if(typeof _=="object"&&_!==null&&_[ee]===!0){let f=_.error;if(typeof f=="object"&&f!==null&&f.type!=="STEP_TIMEOUT"){let V={timeoutMs:n.ms,stepName:i.name,stepKey:i.key,attempt:i.attempt};F in f?f[F]=V:Object.defineProperty(f,F,{value:V,enumerable:!1,writable:!0,configurable:!1})}throw f}throw _}finally{clearTimeout(I)}}var K={backoff:"exponential",initialDelay:100,maxDelay:3e4,jitter:!0,retryOn:()=>!0,onRetry:()=>{}};async function ne(e,n){let{onError:i,onEvent:k,catchUnexpected:x,workflowId:I,context:d}=n&&typeof n=="object"?n:{},s=I??crypto.randomUUID(),_=!i&&!x,f=[],V=0,W=r=>r??`step_${++V}`,l=r=>{let S=r.context!==void 0||d===void 0?r:{...r,context:d};if(S.type==="step_success"){let v=S.stepId;for(let U=f.length-1;U>=0;U--){let j=f[U];if(j.type==="race"&&!j.winnerId){j.winnerId=v;break}}}k?.(S,d)},O=me,Q=r=>Te(r),X=(r,S)=>_?S?.origin==="result"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r,...S.resultCause!==void 0?{cause:S.resultCause}:{}}}:S?.origin==="throw"?{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"throw",error:r,thrown:S.thrown}}:{type:"UNEXPECTED_ERROR",cause:{type:"STEP_FAILURE",origin:"result",error:r}}:r,se=r=>({type:"UNEXPECTED_ERROR",cause:r.meta.origin==="result"?{type:"STEP_FAILURE",origin:"result",error:r.error,...r.meta.resultCause!==void 0?{cause:r.meta.resultCause}:{}}:{type:"STEP_FAILURE",origin:"throw",error:r.error,thrown:r.meta.thrown}});try{let S=function(y,a){let u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let t=performance.now(),o=!1;f.push({scopeId:u,type:"parallel"});let R=()=>{if(o)return;o=!0;let c=f.findIndex(p=>p.scopeId===u);c!==-1&&f.splice(c,1),l({type:"scope_end",workflowId:s,scopeId:u,ts:Date.now(),durationMs:performance.now()-t})};l({type:"scope_start",workflowId:s,scopeId:u,scopeType:"parallel",name:y,ts:Date.now()});try{let c=await a();if(R(),!c.ok)throw i?.(c.error,y,d),O(c.error,{origin:"result",resultCause:c.cause});return c.value}catch(c){throw R(),c}})()},v=function(y,a){let u=Object.keys(y),t=a.name??`Parallel(${u.join(", ")})`,o=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let R=performance.now(),c=!1;f.push({scopeId:o,type:"parallel"});let p=()=>{if(c)return;c=!0;let w=f.findIndex(T=>T.scopeId===o);w!==-1&&f.splice(w,1),l({type:"scope_end",workflowId:s,scopeId:o,ts:Date.now(),durationMs:performance.now()-R})};l({type:"scope_start",workflowId:s,scopeId:o,scopeType:"parallel",name:t,ts:Date.now()});try{let w=await new Promise(A=>{if(u.length===0){A([]);return}let h=!1,C=u.length,N=new Array(u.length);for(let b=0;b<u.length;b++){let D=u[b],Y=b;Promise.resolve(y[D]()).catch(m=>P({type:"PROMISE_REJECTED",cause:m},{cause:{type:"PROMISE_REJECTION",reason:m}})).then(m=>{if(!h){if(!m.ok){h=!0,A([{key:D,result:m}]);return}N[Y]={key:D,result:m},C--,C===0&&A(N)}})}});p();let T={};for(let{key:A,result:h}of w){if(!h.ok)throw i?.(h.error,A,d),O(h.error,{origin:"result",resultCause:h.cause});T[A]=h.value}return T}catch(w){throw p(),w}})()};var ge=S,Ae=v;let r=(y,a)=>(async()=>{let u=fe(a),{name:t,key:o,retry:R,timeout:c}=u,p=W(o),w=k,T=w?performance.now():0;if(!(typeof y=="function")){if(R&&R.attempts>1)throw new Error("step: retry options require a function operation. Direct Promise/Result values cannot be re-executed on retry. Wrap your operation in a function: step(() => yourOperation, { retry: {...} })");if(c)throw new Error("step: timeout options require a function operation. Direct Promise/Result values cannot be wrapped with timeout after they've started. Wrap your operation in a function: step(() => yourOperation, { timeout: {...} })")}let C={attempts:Math.max(1,R?.attempts??1),backoff:R?.backoff??K.backoff,initialDelay:R?.initialDelay??K.initialDelay,maxDelay:R?.maxDelay??K.maxDelay,jitter:R?.jitter??K.jitter,retryOn:R?.retryOn??K.retryOn,onRetry:R?.onRetry??K.onRetry};k&&l({type:"step_start",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now()});let N;for(let m=1;m<=C.attempts;m++){let ue=w?performance.now():0;try{let E;if(typeof y=="function"?c?E=await Re(y,c,{name:t,key:o,attempt:m}):E=await y():E=await y,E.ok){let M=performance.now()-T;return l({type:"step_success",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:M}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:M,result:E}),E.value}if(N=E,m<C.attempts&&C.retryOn(E.error,m)){let M=G(m,C);l({type:"step_retry",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),attempt:m+1,maxAttempts:C.attempts,delayMs:M,error:E.error}),C.onRetry(E.error,m,M),await z(M);continue}C.attempts>1&&l({type:"step_retries_exhausted",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:performance.now()-T,attempts:m,lastError:E.error});break}catch(E){let M=performance.now()-ue;if(Q(E))throw l({type:"step_aborted",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:M}),E;if(Z(E)){let g=we(E),$=c?.ms??g?.timeoutMs??0;if(l({type:"step_timeout",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),timeoutMs:$,attempt:m}),m<C.attempts&&C.retryOn(E,m)){let J=G(m,C);l({type:"step_retry",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),attempt:m+1,maxAttempts:C.attempts,delayMs:J,error:E}),C.onRetry(E,m,J),await z(J);continue}C.attempts>1&&l({type:"step_retries_exhausted",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:performance.now()-T,attempts:m,lastError:E})}if(m<C.attempts&&C.retryOn(E,m)){let g=G(m,C);l({type:"step_retry",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),attempt:m+1,maxAttempts:C.attempts,delayMs:g,error:E}),C.onRetry(E,m,g),await z(g);continue}C.attempts>1&&!Z(E)&&l({type:"step_retries_exhausted",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:performance.now()-T,attempts:m,lastError:E});let L=performance.now()-T;if(x){let g;try{g=x(E)}catch($){throw ke($)}throw l({type:"step_error",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:L,error:g}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:L,result:P(g,{cause:E}),meta:{origin:"throw",thrown:E}}),i?.(g,t,d),O(g,{origin:"throw",thrown:E})}else{let g={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:E}};throw l({type:"step_error",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:L,error:g}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:L,result:P(g,{cause:E}),meta:{origin:"throw",thrown:E}}),E}}}let b=N,D=performance.now()-T,Y=X(b.error,{origin:"result",resultCause:b.cause});throw l({type:"step_error",workflowId:s,stepId:p,stepKey:o,name:t,ts:Date.now(),durationMs:D,error:Y}),o&&l({type:"step_complete",workflowId:s,stepKey:o,name:t,ts:Date.now(),durationMs:D,result:b,meta:{origin:"result",resultCause:b.cause}}),i?.(b.error,t,d),O(b.error,{origin:"result",resultCause:b.cause})})();r.try=(y,a)=>{let u=a.name,t=a.key,o=W(t),R="error"in a?()=>a.error:a.onError,c=k;return(async()=>{let p=c?performance.now():0;k&&l({type:"step_start",workflowId:s,stepId:o,stepKey:t,name:u,ts:Date.now()});try{let w=await y(),T=performance.now()-p;return l({type:"step_success",workflowId:s,stepId:o,stepKey:t,name:u,ts:Date.now(),durationMs:T}),t&&l({type:"step_complete",workflowId:s,stepKey:t,name:u,ts:Date.now(),durationMs:T,result:q(w)}),w}catch(w){let T=R(w),A=performance.now()-p,h=X(T,{origin:"throw",thrown:w});throw l({type:"step_error",workflowId:s,stepId:o,stepKey:t,name:u,ts:Date.now(),durationMs:A,error:h}),t&&l({type:"step_complete",workflowId:s,stepKey:t,name:u,ts:Date.now(),durationMs:A,result:P(T,{cause:w}),meta:{origin:"throw",thrown:w}}),i?.(T,u,d),O(T,{origin:"throw",thrown:w})}})()},r.fromResult=(y,a)=>{let u=a.name,t=a.key,o=W(t),R="error"in a?()=>a.error:a.onError,c=k;return(async()=>{let p=c?performance.now():0;k&&l({type:"step_start",workflowId:s,stepId:o,stepKey:t,name:u,ts:Date.now()});let w=await y();if(w.ok){let T=performance.now()-p;return l({type:"step_success",workflowId:s,stepId:o,stepKey:t,name:u,ts:Date.now(),durationMs:T}),t&&l({type:"step_complete",workflowId:s,stepKey:t,name:u,ts:Date.now(),durationMs:T,result:q(w.value)}),w.value}else{let T=R(w.error),A=performance.now()-p,h=X(T,{origin:"result",resultCause:w.error});throw l({type:"step_error",workflowId:s,stepId:o,stepKey:t,name:u,ts:Date.now(),durationMs:A,error:h}),t&&l({type:"step_complete",workflowId:s,stepKey:t,name:u,ts:Date.now(),durationMs:A,result:P(T,{cause:w.error}),meta:{origin:"result",resultCause:w.error}}),i?.(T,u,d),O(T,{origin:"result",resultCause:w.error})}})()},r.retry=(y,a)=>r(y,{name:a.name,key:a.key,retry:{attempts:a.attempts,backoff:a.backoff,initialDelay:a.initialDelay,maxDelay:a.maxDelay,jitter:a.jitter,retryOn:a.retryOn,onRetry:a.onRetry},timeout:a.timeout}),r.withTimeout=(y,a)=>r(y,{name:a.name,key:a.key,timeout:a}),r.parallel=((...y)=>{if(typeof y[0]=="string"){let a=y[0],u=y[1];return S(a,u)}else{let a=y[0],u=y[1]??{};return v(a,u)}}),r.race=(y,a)=>{let u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let t=performance.now(),o=!1,R={scopeId:u,type:"race",winnerId:void 0};f.push(R);let c=()=>{if(o)return;o=!0;let p=f.findIndex(w=>w.scopeId===u);p!==-1&&f.splice(p,1),l({type:"scope_end",workflowId:s,scopeId:u,ts:Date.now(),durationMs:performance.now()-t,winnerId:R.winnerId})};l({type:"scope_start",workflowId:s,scopeId:u,scopeType:"race",name:y,ts:Date.now()});try{let p=await a();if(c(),!p.ok)throw i?.(p.error,y,d),O(p.error,{origin:"result",resultCause:p.cause});return p.value}catch(p){throw c(),p}})()},r.allSettled=(y,a)=>{let u=`scope_${Date.now()}_${Math.random().toString(36).slice(2,8)}`;return(async()=>{let t=performance.now(),o=!1;f.push({scopeId:u,type:"allSettled"});let R=()=>{if(o)return;o=!0;let c=f.findIndex(p=>p.scopeId===u);c!==-1&&f.splice(c,1),l({type:"scope_end",workflowId:s,scopeId:u,ts:Date.now(),durationMs:performance.now()-t})};l({type:"scope_start",workflowId:s,scopeId:u,scopeType:"allSettled",name:y,ts:Date.now()});try{let c=await a();if(R(),!c.ok)throw i?.(c.error,y,d),O(c.error,{origin:"result",resultCause:c.cause});return c.value}catch(c){throw R(),c}})()};let j=await e(r);return q(j)}catch(r){if(de(r))throw r.thrown;if(Q(r)){let v=r.meta.origin==="throw"?r.meta.thrown:r.meta.resultCause;if(x||i)return P(r.error,{cause:v});if(ye(r.error))return P(r.error,{cause:v});let U=se(r);return P(U,{cause:v})}if(x){let v=x(r);return i?.(v,"unexpected",d),P(v,{cause:r})}let S={type:"UNEXPECTED_ERROR",cause:{type:"UNCAUGHT_EXCEPTION",thrown:r}};return i?.(S,"unexpected",d),P(S,{cause:r})}}ne.strict=(e,n)=>ne(e,n);function H(e){return typeof e=="object"&&e!==null&&e.type==="RESOURCE_CLEANUP_ERROR"}function oe(){let e=[];return{add:n=>(e.push(n),n.value),close:async()=>{let n=[];for(let i=e.length-1;i>=0;i--)try{await e[i].close()}catch(k){n.push(k)}if(e.length=0,n.length>0)throw{type:"RESOURCE_CLEANUP_ERROR",errors:n}},has:n=>e.includes(n),size:()=>e.length}}async function Ce(e){let n=oe(),i;try{i=await e(n)}catch(k){try{await n.close()}catch(x){if(H(x))return P({...x,originalResult:{thrown:k}})}throw k}try{await n.close()}catch(k){if(H(k))return P({...k,originalResult:i});throw k}return i}async function xe(e,n){let i=await e();return{value:i,close:async()=>{await n(i)}}}0&&(module.exports={createResource,createResourceScope,isResourceCleanupError,withScope});
2
2
  //# sourceMappingURL=resource.cjs.map