@lunora/workflow 1.0.0-alpha.54 → 1.0.0-alpha.56
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.
- package/dist/do/index.d.mts +1 -1
- package/dist/do/index.d.ts +1 -1
- package/dist/do/index.mjs +1 -1
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{createRunStep-DnLETYtC.mjs → createRunStep-DPafHcOc.mjs} +1 -1
- package/dist/packem_shared/createWorkflowRunContext-B2mYJh7u.mjs +1 -0
- package/dist/packem_shared/run-step-IuqYPWKG.mjs +1 -0
- package/dist/packem_shared/{types.d-C7jti0tm.d.ts → types.d-Dw7Wldsx.d.mts} +30 -3
- package/dist/packem_shared/{types.d-C7jti0tm.d.mts → types.d-Dw7Wldsx.d.ts} +30 -3
- package/package.json +3 -3
- package/dist/packem_shared/createWorkflowRunContext-C03ogm48.mjs +0 -1
- package/dist/packem_shared/run-step-CFhxLFfp.mjs +0 -1
package/dist/do/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
|
|
2
|
-
import { W as WorkflowDefinition } from "../packem_shared/types.d-
|
|
2
|
+
import { W as WorkflowDefinition } from "../packem_shared/types.d-Dw7Wldsx.mjs";
|
|
3
3
|
import '@lunora/values';
|
|
4
4
|
/**
|
|
5
5
|
* Base class for the generated `WorkflowEntrypoint` classes. Applies a
|
package/dist/do/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WorkflowEntrypoint, WorkflowEvent, WorkflowStep } from 'cloudflare:workers';
|
|
2
|
-
import { W as WorkflowDefinition } from "../packem_shared/types.d-
|
|
2
|
+
import { W as WorkflowDefinition } from "../packem_shared/types.d-Dw7Wldsx.js";
|
|
3
3
|
import '@lunora/values';
|
|
4
4
|
/**
|
|
5
5
|
* Base class for the generated `WorkflowEntrypoint` classes. Applies a
|
package/dist/do/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WorkflowEntrypoint as p}from"cloudflare:workers";import{NonRetryableError as i}from"cloudflare:workflows";import{convertNonRetryableError as m}from"../packem_shared/NonRetryableError-BPu01mU8.mjs";import{extractBranchMarker as f,stripBranchMarker as h,signalBranchParentSafe as l,errorOutcome as u,okOutcome as y}from"../packem_shared/MAX_BRANCHES-j59ZUUSu.mjs";import{createWorkflowRunContext as d}from"../packem_shared/createWorkflowRunContext-
|
|
1
|
+
import{WorkflowEntrypoint as p}from"cloudflare:workers";import{NonRetryableError as i}from"cloudflare:workflows";import{convertNonRetryableError as m}from"../packem_shared/NonRetryableError-BPu01mU8.mjs";import{extractBranchMarker as f,stripBranchMarker as h,signalBranchParentSafe as l,errorOutcome as u,okOutcome as y}from"../packem_shared/MAX_BRANCHES-j59ZUUSu.mjs";import{createWorkflowRunContext as d}from"../packem_shared/createWorkflowRunContext-B2mYJh7u.mjs";class N extends p{#r;#t;constructor(t,e,o,r){super(t,e),this.#t=o,this.#r=r??"workflow"}async run(t,e){const o=e,r=f(t.payload),c=r?{...t,payload:h(t.payload)}:t,a=d({env:this.env,event:c,exportName:this.#r,nonRetryableErrorClass:i,step:o});let n;try{n=await this.#t.handler(a)}catch(s){return r&&await l({env:this.env,log:a.log,step:o},r,u(s)),m(s,i)}return r&&await l({env:this.env,log:a.log,step:o},r,y(n)),n}}export{N as default};
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as Workflows, L as LunoraWorkflowsOptions, b as WorkflowEventDefinition, S as StepArgsValidator, c as StepConfig, d as StepDefinition, e as WorkflowConfig, W as WorkflowDefinition, f as WorkflowBranch, g as WorkflowInstanceStatus, h as WorkflowEventLike, i as WorkflowStepLike, j as WorkflowRunContext, k as WorkflowLogger, l as WorkflowRunFunction, m as WorkflowRunStepFunction, n as WorkflowWaitForEventFunction } from "./packem_shared/types.d-
|
|
2
|
-
export type { A as ArgsOf, B as BranchCompensationParams, F as FunctionKind, o as FunctionReference, I as InferStepArgs, R as RunFunctionOptions, p as RunStepOptions, q as StepHandler, r as StepRollbackContext, s as StepRollbackHandler, t as StepRunContext, u as WaitForEventOptions, v as WorkflowBindingLike, w as WorkflowBranchOutputs, x as WorkflowCreateOptions, y as WorkflowHandle, z as WorkflowHandler, C as WorkflowInstanceLike, D as WorkflowParallelFunction, E as WorkflowRollbackContextLike, G as WorkflowRollbackHandlerLike, H as WorkflowSpawnFunction, J as WorkflowSpawnOptions, K as WorkflowStatusResult, M as WorkflowStepConfigLike, N as WorkflowStepContextLike, O as WorkflowStepRollbackOptionsLike } from "./packem_shared/types.d-
|
|
1
|
+
import { a as Workflows, L as LunoraWorkflowsOptions, b as WorkflowEventDefinition, S as StepArgsValidator, c as StepConfig, d as StepDefinition, e as WorkflowConfig, W as WorkflowDefinition, f as WorkflowBranch, g as WorkflowInstanceStatus, h as WorkflowEventLike, i as WorkflowStepLike, j as WorkflowRunContext, k as WorkflowLogger, l as WorkflowRunFunction, m as WorkflowRunStepFunction, n as WorkflowWaitForEventFunction } from "./packem_shared/types.d-Dw7Wldsx.mjs";
|
|
2
|
+
export type { A as ArgsOf, B as BranchCompensationParams, F as FunctionKind, o as FunctionReference, I as InferStepArgs, R as RunFunctionOptions, p as RunStepOptions, q as StepHandler, r as StepRollbackContext, s as StepRollbackHandler, t as StepRunContext, u as WaitForEventOptions, v as WorkflowBindingLike, w as WorkflowBranchOutputs, x as WorkflowCreateOptions, y as WorkflowHandle, z as WorkflowHandler, C as WorkflowInstanceLike, D as WorkflowParallelFunction, E as WorkflowRollbackContextLike, G as WorkflowRollbackHandlerLike, H as WorkflowSpawnFunction, J as WorkflowSpawnOptions, K as WorkflowStatusResult, M as WorkflowStepConfigLike, N as WorkflowStepContextLike, O as WorkflowStepRollbackOptionsLike } from "./packem_shared/types.d-Dw7Wldsx.mjs";
|
|
3
3
|
import { Validator } from '@lunora/values';
|
|
4
4
|
import { LunoraError } from '@lunora/errors';
|
|
5
5
|
/** Wiring info for one declared workflow, emitted by codegen into the generated shard. */
|
|
@@ -120,7 +120,11 @@ declare const workflowDefaultName: (exportName: string) => string;
|
|
|
120
120
|
* handler: async (ctx) => {
|
|
121
121
|
* const order = await ctx.step.do("load", () => ctx.run(api.orders.get, { id: ctx.params.orderId }));
|
|
122
122
|
* await ctx.step.sleep("cool-off", "1 minute");
|
|
123
|
-
*
|
|
123
|
+
* // A raw `step.do` retries its callback in place, so a WRITE made through
|
|
124
|
+
* // it needs an explicit dedup id (or use `ctx.runStep`, which pins one).
|
|
125
|
+
* await ctx.step.do("charge", () =>
|
|
126
|
+
* ctx.run(api.payments.charge, { orderId: ctx.params.orderId }, { dedupId: `charge:${ctx.params.orderId}` }),
|
|
127
|
+
* );
|
|
124
128
|
* return order;
|
|
125
129
|
* },
|
|
126
130
|
* });
|
|
@@ -292,6 +296,8 @@ declare const validateStepArgs: (validators: StepArgsValidator, source: Record<s
|
|
|
292
296
|
interface RunStepDeps {
|
|
293
297
|
/** The Worker environment bindings, surfaced on the step context. */
|
|
294
298
|
env: Record<string, unknown>;
|
|
299
|
+
/** This workflow instance's id — the namespace for the replay-dedup ids the steps' dispatches carry. */
|
|
300
|
+
instanceId: string;
|
|
295
301
|
/** Structured logger surfaced on the step context. */
|
|
296
302
|
log: WorkflowLogger;
|
|
297
303
|
/** Native `cloudflare:workflows` `NonRetryableError` constructor — injected by `src/do`; absent in Node tests. */
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as Workflows, L as LunoraWorkflowsOptions, b as WorkflowEventDefinition, S as StepArgsValidator, c as StepConfig, d as StepDefinition, e as WorkflowConfig, W as WorkflowDefinition, f as WorkflowBranch, g as WorkflowInstanceStatus, h as WorkflowEventLike, i as WorkflowStepLike, j as WorkflowRunContext, k as WorkflowLogger, l as WorkflowRunFunction, m as WorkflowRunStepFunction, n as WorkflowWaitForEventFunction } from "./packem_shared/types.d-
|
|
2
|
-
export type { A as ArgsOf, B as BranchCompensationParams, F as FunctionKind, o as FunctionReference, I as InferStepArgs, R as RunFunctionOptions, p as RunStepOptions, q as StepHandler, r as StepRollbackContext, s as StepRollbackHandler, t as StepRunContext, u as WaitForEventOptions, v as WorkflowBindingLike, w as WorkflowBranchOutputs, x as WorkflowCreateOptions, y as WorkflowHandle, z as WorkflowHandler, C as WorkflowInstanceLike, D as WorkflowParallelFunction, E as WorkflowRollbackContextLike, G as WorkflowRollbackHandlerLike, H as WorkflowSpawnFunction, J as WorkflowSpawnOptions, K as WorkflowStatusResult, M as WorkflowStepConfigLike, N as WorkflowStepContextLike, O as WorkflowStepRollbackOptionsLike } from "./packem_shared/types.d-
|
|
1
|
+
import { a as Workflows, L as LunoraWorkflowsOptions, b as WorkflowEventDefinition, S as StepArgsValidator, c as StepConfig, d as StepDefinition, e as WorkflowConfig, W as WorkflowDefinition, f as WorkflowBranch, g as WorkflowInstanceStatus, h as WorkflowEventLike, i as WorkflowStepLike, j as WorkflowRunContext, k as WorkflowLogger, l as WorkflowRunFunction, m as WorkflowRunStepFunction, n as WorkflowWaitForEventFunction } from "./packem_shared/types.d-Dw7Wldsx.js";
|
|
2
|
+
export type { A as ArgsOf, B as BranchCompensationParams, F as FunctionKind, o as FunctionReference, I as InferStepArgs, R as RunFunctionOptions, p as RunStepOptions, q as StepHandler, r as StepRollbackContext, s as StepRollbackHandler, t as StepRunContext, u as WaitForEventOptions, v as WorkflowBindingLike, w as WorkflowBranchOutputs, x as WorkflowCreateOptions, y as WorkflowHandle, z as WorkflowHandler, C as WorkflowInstanceLike, D as WorkflowParallelFunction, E as WorkflowRollbackContextLike, G as WorkflowRollbackHandlerLike, H as WorkflowSpawnFunction, J as WorkflowSpawnOptions, K as WorkflowStatusResult, M as WorkflowStepConfigLike, N as WorkflowStepContextLike, O as WorkflowStepRollbackOptionsLike } from "./packem_shared/types.d-Dw7Wldsx.js";
|
|
3
3
|
import { Validator } from '@lunora/values';
|
|
4
4
|
import { LunoraError } from '@lunora/errors';
|
|
5
5
|
/** Wiring info for one declared workflow, emitted by codegen into the generated shard. */
|
|
@@ -120,7 +120,11 @@ declare const workflowDefaultName: (exportName: string) => string;
|
|
|
120
120
|
* handler: async (ctx) => {
|
|
121
121
|
* const order = await ctx.step.do("load", () => ctx.run(api.orders.get, { id: ctx.params.orderId }));
|
|
122
122
|
* await ctx.step.sleep("cool-off", "1 minute");
|
|
123
|
-
*
|
|
123
|
+
* // A raw `step.do` retries its callback in place, so a WRITE made through
|
|
124
|
+
* // it needs an explicit dedup id (or use `ctx.runStep`, which pins one).
|
|
125
|
+
* await ctx.step.do("charge", () =>
|
|
126
|
+
* ctx.run(api.payments.charge, { orderId: ctx.params.orderId }, { dedupId: `charge:${ctx.params.orderId}` }),
|
|
127
|
+
* );
|
|
124
128
|
* return order;
|
|
125
129
|
* },
|
|
126
130
|
* });
|
|
@@ -292,6 +296,8 @@ declare const validateStepArgs: (validators: StepArgsValidator, source: Record<s
|
|
|
292
296
|
interface RunStepDeps {
|
|
293
297
|
/** The Worker environment bindings, surfaced on the step context. */
|
|
294
298
|
env: Record<string, unknown>;
|
|
299
|
+
/** This workflow instance's id — the namespace for the replay-dedup ids the steps' dispatches carry. */
|
|
300
|
+
instanceId: string;
|
|
295
301
|
/** Structured logger surfaced on the step context. */
|
|
296
302
|
log: WorkflowLogger;
|
|
297
303
|
/** Native `cloudflare:workflows` `NonRetryableError` constructor — injected by `src/do`; absent in Node tests. */
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createWorkflowContext as e}from"./packem_shared/createWorkflowContext-zQR_9N-v.mjs";import{default as f}from"./packem_shared/createWorkflows-LvAyUyKq.mjs";import{defineWorkflowEvent as a,isWorkflowEventDefinition as i}from"./packem_shared/defineWorkflowEvent-suERPEEV.mjs";import{defineStep as p,isStepDefinition as s}from"./packem_shared/defineStep-D1-9eOnA.mjs";import{defineWorkflow as w,isWorkflowDefinition as x,workflowBindingName as k,workflowClassName as c,workflowDefaultName as E}from"./packem_shared/defineWorkflow-tKaIifbZ.mjs";import{NonRetryableError as N,convertNonRetryableError as R,isNonRetryableError as v,toNativeNonRetryableError as d}from"./packem_shared/NonRetryableError-BPu01mU8.mjs";import{MAX_BRANCHES as u,branch as C}from"./packem_shared/MAX_BRANCHES-j59ZUUSu.mjs";import{WorkflowsRestError as S,createWorkflowsRestClient as y}from"./packem_shared/WorkflowsRestError-Ccq1FUR1.mjs";import{createWorkflowRunContext as g}from"./packem_shared/createWorkflowRunContext-
|
|
1
|
+
import{createWorkflowContext as e}from"./packem_shared/createWorkflowContext-zQR_9N-v.mjs";import{default as f}from"./packem_shared/createWorkflows-LvAyUyKq.mjs";import{defineWorkflowEvent as a,isWorkflowEventDefinition as i}from"./packem_shared/defineWorkflowEvent-suERPEEV.mjs";import{defineStep as p,isStepDefinition as s}from"./packem_shared/defineStep-D1-9eOnA.mjs";import{defineWorkflow as w,isWorkflowDefinition as x,workflowBindingName as k,workflowClassName as c,workflowDefaultName as E}from"./packem_shared/defineWorkflow-tKaIifbZ.mjs";import{NonRetryableError as N,convertNonRetryableError as R,isNonRetryableError as v,toNativeNonRetryableError as d}from"./packem_shared/NonRetryableError-BPu01mU8.mjs";import{MAX_BRANCHES as u,branch as C}from"./packem_shared/MAX_BRANCHES-j59ZUUSu.mjs";import{WorkflowsRestError as S,createWorkflowsRestClient as y}from"./packem_shared/WorkflowsRestError-Ccq1FUR1.mjs";import{createWorkflowRunContext as g}from"./packem_shared/createWorkflowRunContext-B2mYJh7u.mjs";import{c as h,v as F}from"./packem_shared/run-step-IuqYPWKG.mjs";import{createWaitForEvent as I}from"./packem_shared/createWaitForEvent-D5Ohn2Pz.mjs";import{isDuplicateInstanceError as X}from"./packem_shared/isDuplicateInstanceError-CecnqNAa.mjs";export{u as MAX_BRANCHES,N as NonRetryableError,S as WorkflowsRestError,C as branch,R as convertNonRetryableError,h as createRunStep,I as createWaitForEvent,e as createWorkflowContext,g as createWorkflowRunContext,f as createWorkflows,y as createWorkflowsRestClient,p as defineStep,w as defineWorkflow,a as defineWorkflowEvent,X as isDuplicateInstanceError,v as isNonRetryableError,s as isStepDefinition,x as isWorkflowDefinition,i as isWorkflowEventDefinition,d as toNativeNonRetryableError,F as validateStepArgs,k as workflowBindingName,c as workflowClassName,E as workflowDefaultName};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as p,v as o}from"./run-step-
|
|
1
|
+
import{c as p,v as o}from"./run-step-IuqYPWKG.mjs";import"./defineWorkflowEvent-suERPEEV.mjs";import"./NonRetryableError-BPu01mU8.mjs";export{p as createRunStep,o as validateStepArgs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as A,p as h,c as I}from"./run-step-IuqYPWKG.mjs";import{LunoraError as R}from"@lunora/errors";import{workflowBindingName as y}from"./defineWorkflow-tKaIifbZ.mjs";import{raiseNonRetryable as k}from"./NonRetryableError-BPu01mU8.mjs";import{createSpawn as T,createParallel as C}from"./MAX_BRANCHES-j59ZUUSu.mjs";import{createWaitForEvent as N}from"./createWaitForEvent-D5Ohn2Pz.mjs";const O=r=>({debug:(n,...t)=>{console.debug(r,n,...t)},error:(n,...t)=>{console.error(r,n,...t)},info:(n,...t)=>{console.info(r,n,...t)},warn:(n,...t)=>{console.warn(r,n,...t)}}),v=r=>{let n="";for(let c=0;c<r.length;c+=32768)n+=String.fromCharCode(...r.subarray(c,c+32768));return btoa(n)},$=r=>{const n=atob(r),t=new Uint8Array(n.length);for(let c=0;c<n.length;c+=1)t[c]=n.codePointAt(c)??0;return t},S="$lunora.wire$",w=64,b=1024,g="__proto__",p={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},E={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},s=(r,n=0)=>{if(n>w)throw new RangeError(`wire-codec: value nesting exceeds the ${w}-level limit`);if(r===null||typeof r!="object")return r;if(Array.isArray(r)){if(r[0]===S)switch(r[1]){case"-inf":return-1/0;case"arr":return r[2].map(e=>s(e,n+1));case"bigint":{const e=r[2];if(typeof e!="string"||e.length>b||!/^-?\d+$/.test(e))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${b} digits)`);return BigInt(e)}case"date":{const e=s(r[2],n+1);if(typeof e!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(e)}case"map":{const e=r[2];return new Map(e.map(o=>{if(!Array.isArray(o)||o.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[s(o[0],n+1),s(o[1],n+1)]}))}case"set":return new Set(r[2].map(e=>s(e,n+1)));case"url":{const e=r[2];if(typeof e!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(e)}case"error":{const e=r[2],o=r[3];if(typeof e!="string"||typeof o!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const l=(Object.hasOwn(E,e)?E[e]:void 0)??Error,i=new l(o);i.name!==e&&Object.defineProperty(i,"name",{configurable:!0,value:e,writable:!0});const d=s(r[4],n+1);if(d===null||typeof d!="object"||Array.isArray(d))throw new TypeError("wire-codec: malformed error — props must be an object");for(const a of Object.keys(d))a===g?Object.defineProperty(i,a,{configurable:!0,enumerable:!0,value:d[a],writable:!0}):i[a]=d[a];return r.length>5&&Object.defineProperty(i,"cause",{configurable:!0,value:s(r[5],n+1),writable:!0}),i}case"bytes":{const e=r[2];if(typeof e!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const o=$(e);if(v(o)!==e)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const l=r[3]??"Uint8Array";if(l==="ArrayBuffer")return o.buffer.byteLength===o.byteLength?o.buffer:o.slice().buffer;const i=Object.hasOwn(p,l)?p[l]:void 0;return i?new i(o.slice().buffer):o}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return r.map(e=>s(e,n+1))}return r.map(f=>s(f,n+1))}const t=r,c={};for(const f of Object.keys(t)){const e=s(t[f],n+1);f===g?Object.defineProperty(c,f,{configurable:!0,enumerable:!0,value:e,writable:!0}):c[f]=e}return c},D=r=>{const n=O(`[workflow:${r.exportName}]`),t=A({env:r.env,fetchImpl:r.fetchImpl,label:"@lunora/workflow"}),c=h(t,`${r.event.instanceId}#body`),f=a=>{const u=y(a),m=r.env[u];if(!m||typeof m.create!="function"||typeof m.get!="function")throw new R("INTERNAL",`@lunora/workflow: cannot spawn child workflow "${a}" — no Workflow binding "${u}" on env (is it declared in lunora/workflows.ts?)`);return m};let e=0;const o=a=>{if(a!==void 0)return a;const u=`${r.event.instanceId}-c${String(e)}`;return e+=1,u},l={env:r.env,instanceId:r.event.instanceId,log:n,nextChildId:o,parentBinding:y(r.exportName),resolveBinding:f,step:r.step},d=(()=>{try{return s(r.event.payload)}catch(a){return k(`@lunora/workflow: workflow "${r.exportName}" params could not be decoded — ${a instanceof Error?a.message:String(a)}`,a,r.nonRetryableErrorClass)}})();return{env:r.env,event:r.event,log:n,parallel:C(l),params:d,run:c,runStep:I({env:r.env,instanceId:r.event.instanceId,log:n,nonRetryableErrorClass:r.nonRetryableErrorClass,run:t,step:r.step}),spawn:T(l),step:r.step,waitForEvent:N({nonRetryableErrorClass:r.nonRetryableErrorClass,step:r.step})}};export{D as createWorkflowRunContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as w,isLunoraError as B}from"@lunora/errors";import{parseValidatorMap as M}from"@lunora/values";import{RESERVED_EVENT_TYPE_PREFIX as S}from"./defineWorkflowEvent-suERPEEV.mjs";import{raiseNonRetryable as T,convertNonRetryableError as J}from"./NonRetryableError-BPu01mU8.mjs";const F=(e,t,o)=>{if(t===void 0)return{dispose:()=>{},signal:e};const a=new AbortController,n=setTimeout(()=>{a.abort(o())},t);return{dispose:()=>{clearTimeout(n)},signal:a.signal}},$=e=>{let t="";for(let o=0;o<e.length;o+=32768)t+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(t)},K=e=>{const t=atob(e),o=new Uint8Array(t.length);for(let a=0;a<t.length;a+=1)o[a]=t.codePointAt(a)??0;return o},b="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",k=e=>{let t="",o=0;const a=e.length-2;for(;o<a;o+=3){const r=e[o]<<16|e[o+1]<<8|e[o+2];t+=b.charAt(r>>18&63)+b.charAt(r>>12&63)+b.charAt(r>>6&63)+b.charAt(r&63)}const n=e.length-o;if(n===1){const r=e[o]<<16;t+=b.charAt(r>>18&63)+b.charAt(r>>12&63)}else if(n===2){const r=e[o]<<16|e[o+1]<<8;t+=b.charAt(r>>18&63)+b.charAt(r>>12&63)+b.charAt(r>>6&63)}return t};new TextDecoder;const P=new TextEncoder,I="=",V=e=>{for(let t=0;t<e.length;t+=1)if(e.charCodeAt(t)>255)return!1;return!0},W=e=>k(P.encode(JSON.stringify(e))),H=e=>!e.startsWith(I)&&V(e)?e:`${I}${k(P.encode(e))}`,l="$lunora.wire$",O=64,j=1024,R="__proto__",_={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},L={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},G=e=>{if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype},g=(e,t=0)=>{if(t>O)throw new RangeError(`wire-codec: value nesting exceeds the ${O}-level limit`);if(e===void 0)return[l,"undefined"];if(e===null)return null;const o=typeof e;if(o==="bigint")return[l,"bigint",e.toString()];if(o==="number"){const r=e;return Number.isNaN(r)?[l,"nan"]:r===1/0?[l,"inf"]:r===-1/0?[l,"-inf"]:r}if(o!=="object")return e;if(e instanceof Date)return[l,"date",g(e.getTime(),t+1)];if(e instanceof Error){const r=e,s={};for(const c of Object.keys(r)){if(r[c]===void 0)continue;const f=g(r[c],t+1);c===R?Object.defineProperty(s,c,{configurable:!0,enumerable:!0,value:f,writable:!0}):s[c]=f}const i=[l,"error",String(r.name),String(r.message),s];return r.cause!==void 0&&i.push(g(r.cause,t+1)),i}if(e instanceof URL)return[l,"url",e.href];if(e instanceof Map)return[l,"map",[...e.entries()].map(([r,s])=>[g(r,t+1),g(s,t+1)])];if(e instanceof Set)return[l,"set",[...e].map(r=>g(r,t+1))];if(e instanceof ArrayBuffer)return[l,"bytes",$(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const r=e,s=r.constructor.name,i=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);return s==="Uint8Array"?[l,"bytes",$(i)]:[l,"bytes",$(i),s]}if(Array.isArray(e)){const r=e.map(s=>g(s,t+1));return r.length>0&&r[0]===l?[l,"arr",r]:r}if(!G(e)){const r=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${r} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const a=e,n={};for(const r of Object.keys(a)){const s=a[r];if(s===void 0)continue;const i=g(s,t+1);r===R?Object.defineProperty(n,r,{configurable:!0,enumerable:!0,value:i,writable:!0}):n[r]=i}return n},y=(e,t=0)=>{if(t>O)throw new RangeError(`wire-codec: value nesting exceeds the ${O}-level limit`);if(e===null||typeof e!="object")return e;if(Array.isArray(e)){if(e[0]===l)switch(e[1]){case"-inf":return-1/0;case"arr":return e[2].map(n=>y(n,t+1));case"bigint":{const n=e[2];if(typeof n!="string"||n.length>j||!/^-?\d+$/.test(n))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${j} digits)`);return BigInt(n)}case"date":{const n=y(e[2],t+1);if(typeof n!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(n)}case"map":{const n=e[2];return new Map(n.map(r=>{if(!Array.isArray(r)||r.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[y(r[0],t+1),y(r[1],t+1)]}))}case"set":return new Set(e[2].map(n=>y(n,t+1)));case"url":{const n=e[2];if(typeof n!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(n)}case"error":{const n=e[2],r=e[3];if(typeof n!="string"||typeof r!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const s=(Object.hasOwn(L,n)?L[n]:void 0)??Error,i=new s(r);i.name!==n&&Object.defineProperty(i,"name",{configurable:!0,value:n,writable:!0});const c=y(e[4],t+1);if(c===null||typeof c!="object"||Array.isArray(c))throw new TypeError("wire-codec: malformed error — props must be an object");for(const f of Object.keys(c))f===R?Object.defineProperty(i,f,{configurable:!0,enumerable:!0,value:c[f],writable:!0}):i[f]=c[f];return e.length>5&&Object.defineProperty(i,"cause",{configurable:!0,value:y(e[5],t+1),writable:!0}),i}case"bytes":{const n=e[2];if(typeof n!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const r=K(n);if($(r)!==n)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const s=e[3]??"Uint8Array";if(s==="ArrayBuffer")return r.buffer.byteLength===r.byteLength?r.buffer:r.slice().buffer;const i=Object.hasOwn(_,s)?_[s]:void 0;return i?new i(r.slice().buffer):r}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return e.map(n=>y(n,t+1))}return e.map(n=>y(n,t+1))}const o=e,a={};for(const n of Object.keys(o)){const r=y(o[n],t+1);n===R?Object.defineProperty(a,n,{configurable:!0,enumerable:!0,value:r,writable:!0}):a[n]=r}return a},z=(e,t,o)=>{try{return g(o)}catch(a){throw new TypeError(`${e}: cannot encode args for '${t}' — ${a instanceof Error?a.message:String(a)}`,a instanceof Error?{cause:a}:void 0)}},X="/_lunora/scheduler/dispatch",Y=3e4,q=e=>{let t=e.length;for(;t>0&&e[t-1]==="/";)t-=1;return e.slice(0,t)},x=Symbol("lunoraDispatchFailure"),Q=Symbol("lunoraDispatchMessageId"),D=(e,t)=>(t!==void 0&&Object.defineProperty(e,Q,{value:t}),e),Z=(e,t)=>(Object.defineProperty(e,x,{value:!0}),D(e,t)),ee=(e,t,o,a)=>{try{const n=JSON.parse(o)?.error;if(typeof n=="object"&&n!==null&&typeof n.code=="string"){const{code:r,data:s,message:i}=n;return Z(new w(r,typeof i=="string"?i:void 0,{data:s,status:t}),a)}}catch{}return D(new w("INTERNAL",`${e}: function dispatch failed (${String(t)}): ${o}`,{status:t}),a)},te=new Set([400,403,404,422]),re=new Set(["DISPATCH_UNAUTHENTICATED"]),ne=e=>B(e)&&e[x]===!0&&te.has(e.status)&&!re.has(e.code),oe=(e,t,o)=>new w("INTERNAL",`${e}: function dispatch to "${t}" timed out after ${String(o)}ms`,{status:503}),le=e=>{const{label:t}=e,o=globalThis.fetch,a=e.fetchImpl??(typeof o=="function"?o.bind(globalThis):void 0);return async(n,r,s={})=>{if(typeof a!="function")throw new TypeError(`${t}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const i=()=>e.argsAlreadyEncoded===!0?r??{}:z(t,n.__lunoraRef,r??{}),c=e.env.LUNORA_ORIGIN_URL;if(typeof c!="string"||c.length===0)throw new w("INTERNAL",`${t}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const f=e.env.LUNORA_ADMIN_TOKEN;if(typeof f!="string"||f.length===0)throw new w("INTERNAL",`${t}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const v=`${q(c)}${X}`,h={authorization:`Bearer ${f}`,"content-type":"application/json"};e.traceparent!==void 0&&e.traceparent.length>0&&(h.traceparent=e.traceparent),e.identity?.userId!==void 0&&(h["x-lunora-userid"]=H(e.identity.userId)),e.identity?.claims!==void 0&&(h["x-lunora-identity"]=W(e.identity.claims));const p=s.timeoutMs??Y,N=F(void 0,p,()=>new DOMException(`dispatch timed out after ${String(p)}ms`,"TimeoutError")),m=d=>{throw d instanceof Error&&d.name==="TimeoutError"?oe(t,n.__lunoraRef,p):d};let u;try{try{u=await a(v,{body:JSON.stringify({args:i(),functionPath:n.__lunoraRef,id:s.dedupId,shardKey:s.shardKey}),headers:h,method:"POST",signal:N.signal})}catch(E){return m(E)}if(!u.ok){let E;try{E=await u.text()}catch(C){return m(C)}throw ee(t,u.status,E,s.messageId)}let d;try{d=await u.text()}catch(E){return m(E)}if(d.length===0)return;let A;try{A=JSON.parse(d)}catch{throw new w("INTERNAL",`${t}: function dispatch returned a non-JSON body (${String(u.status)}): ${d}`,{status:u.status})}if(A===null||typeof A!="object"||Array.isArray(A)||!("result"in A))throw new w("INTERNAL",`${t}: function dispatch returned a JSON body that is not a { result } envelope (${String(u.status)}): ${d}`,{status:u.status});return y(A.result)}finally{N.dispose()}}},U=(e,t)=>{let o=0;return(a,n,r)=>(o+=1,e(a,n,{...r,dedupId:r?.dedupId??`${t}.${String(o)}`}))},ae=(e,t)=>M(e,t,"step args"),fe=e=>{let t=0;return async(o,a,n)=>{const r=`${e.instanceId}#step${String(t)}`;t+=1;const s=n?.config??o.config,i=n?.name??o.name;if(i.startsWith(S))return T(`@lunora/workflow: ctx.runStep step name "${i}" is reserved — the "${S}" prefix is used by the framework's own steps`,void 0,e.nonRetryableErrorClass);const c=ae(o.args,a),f=async p=>{const N={attempt:p.attempt,config:p.config,env:e.env,log:e.log,run:U(e.run,r),step:p.step};let m;try{m=await o.handler(N,c)}catch(u){return ne(u)?T(u.message,u,e.nonRetryableErrorClass):J(u,e.nonRetryableErrorClass)}if(!o.returns)return m;try{return o.returns.parse(m)}catch(u){const d=u instanceof Error?u.message:String(u);return T(`step "${o.name}" returns validation failed: ${d}`,u,e.nonRetryableErrorClass)}},v=o.rollback,h=v?{rollback:async p=>{await v({args:c,env:e.env,error:p.error,log:e.log,output:p.output,run:U(e.run,`${r}rollback`)})},rollbackConfig:o.rollbackConfig}:void 0;return s===void 0?e.step.do(i,f,h):e.step.do(i,s,f,h)}};export{fe as c,U as p,le as t,ae as v};
|
|
@@ -176,16 +176,43 @@ interface WorkflowLogger {
|
|
|
176
176
|
}
|
|
177
177
|
/** Per-call options for {@link WorkflowRunFunction}. */
|
|
178
178
|
interface RunFunctionOptions {
|
|
179
|
+
/**
|
|
180
|
+
* The replay-dedup key for THIS ONE CALL, forwarded to the shard as the
|
|
181
|
+
* `(identity, mutationId)` dedup id so a re-issued dispatch of the same
|
|
182
|
+
* call applies once instead of twice.
|
|
183
|
+
*
|
|
184
|
+
* Usually leave it unset: `ctx.run`, a `ctx.runStep` body's `context.run`
|
|
185
|
+
* and a rollback's `context.run` each pin a deterministic id already (see
|
|
186
|
+
* `src/dedup-id.ts`), and a supplied id wins over that pin. Pass one when
|
|
187
|
+
* the automatic id cannot be right — a body whose `ctx.run` ORDER varies
|
|
188
|
+
* per attempt, or a bare `ctx.run` inside a raw `ctx.step.do(...)`
|
|
189
|
+
* callback, which the pin cannot see is being retried.
|
|
190
|
+
*
|
|
191
|
+
* Must be unique per call: the dedup table carries no function path and
|
|
192
|
+
* every server-initiated dispatch shares the `"system:"` identity, so
|
|
193
|
+
* reusing one id across two calls makes the second return the first's
|
|
194
|
+
* cached result without ever executing.
|
|
195
|
+
*/
|
|
196
|
+
dedupId?: string;
|
|
179
197
|
/** Routing hint forwarded to the Worker so the call lands on the right shard. */
|
|
180
198
|
shardKey?: string;
|
|
181
199
|
}
|
|
182
200
|
/**
|
|
183
201
|
* Calls a Lunora query / mutation / action from inside a workflow and resolves
|
|
184
|
-
* with its result. Wrap it in
|
|
185
|
-
*
|
|
202
|
+
* with its result. Wrap it in a durable step to make the call memoized and
|
|
203
|
+
* retried — prefer {@link WorkflowRunStepFunction}, whose `context.run` also
|
|
204
|
+
* pins a retry-stable {@link RunFunctionOptions.dedupId}:
|
|
205
|
+
*
|
|
206
|
+
* ```ts
|
|
207
|
+
* const { receiptId } = await ctx.runStep(charge, { id });
|
|
208
|
+
* ```
|
|
209
|
+
*
|
|
210
|
+
* A raw {@link WorkflowStepLike.do} retries its callback IN PLACE, which the
|
|
211
|
+
* automatic (positional) id cannot see, so a write made that way needs an
|
|
212
|
+
* explicit id or it applies once per attempt:
|
|
186
213
|
*
|
|
187
214
|
* ```ts
|
|
188
|
-
*
|
|
215
|
+
* await ctx.step.do("charge", () => ctx.run(api.payments.charge, { id }, { dedupId: `charge:${id}` }));
|
|
189
216
|
* ```
|
|
190
217
|
*/
|
|
191
218
|
type WorkflowRunFunction = <F extends FunctionReference>(function_: F, args?: ArgsOf<F>, options?: RunFunctionOptions) => Promise<unknown>;
|
|
@@ -176,16 +176,43 @@ interface WorkflowLogger {
|
|
|
176
176
|
}
|
|
177
177
|
/** Per-call options for {@link WorkflowRunFunction}. */
|
|
178
178
|
interface RunFunctionOptions {
|
|
179
|
+
/**
|
|
180
|
+
* The replay-dedup key for THIS ONE CALL, forwarded to the shard as the
|
|
181
|
+
* `(identity, mutationId)` dedup id so a re-issued dispatch of the same
|
|
182
|
+
* call applies once instead of twice.
|
|
183
|
+
*
|
|
184
|
+
* Usually leave it unset: `ctx.run`, a `ctx.runStep` body's `context.run`
|
|
185
|
+
* and a rollback's `context.run` each pin a deterministic id already (see
|
|
186
|
+
* `src/dedup-id.ts`), and a supplied id wins over that pin. Pass one when
|
|
187
|
+
* the automatic id cannot be right — a body whose `ctx.run` ORDER varies
|
|
188
|
+
* per attempt, or a bare `ctx.run` inside a raw `ctx.step.do(...)`
|
|
189
|
+
* callback, which the pin cannot see is being retried.
|
|
190
|
+
*
|
|
191
|
+
* Must be unique per call: the dedup table carries no function path and
|
|
192
|
+
* every server-initiated dispatch shares the `"system:"` identity, so
|
|
193
|
+
* reusing one id across two calls makes the second return the first's
|
|
194
|
+
* cached result without ever executing.
|
|
195
|
+
*/
|
|
196
|
+
dedupId?: string;
|
|
179
197
|
/** Routing hint forwarded to the Worker so the call lands on the right shard. */
|
|
180
198
|
shardKey?: string;
|
|
181
199
|
}
|
|
182
200
|
/**
|
|
183
201
|
* Calls a Lunora query / mutation / action from inside a workflow and resolves
|
|
184
|
-
* with its result. Wrap it in
|
|
185
|
-
*
|
|
202
|
+
* with its result. Wrap it in a durable step to make the call memoized and
|
|
203
|
+
* retried — prefer {@link WorkflowRunStepFunction}, whose `context.run` also
|
|
204
|
+
* pins a retry-stable {@link RunFunctionOptions.dedupId}:
|
|
205
|
+
*
|
|
206
|
+
* ```ts
|
|
207
|
+
* const { receiptId } = await ctx.runStep(charge, { id });
|
|
208
|
+
* ```
|
|
209
|
+
*
|
|
210
|
+
* A raw {@link WorkflowStepLike.do} retries its callback IN PLACE, which the
|
|
211
|
+
* automatic (positional) id cannot see, so a write made that way needs an
|
|
212
|
+
* explicit id or it applies once per attempt:
|
|
186
213
|
*
|
|
187
214
|
* ```ts
|
|
188
|
-
*
|
|
215
|
+
* await ctx.step.do("charge", () => ctx.run(api.payments.charge, { id }, { dedupId: `charge:${id}` }));
|
|
189
216
|
* ```
|
|
190
217
|
*/
|
|
191
218
|
type WorkflowRunFunction = <F extends FunctionReference>(function_: F, args?: ArgsOf<F>, options?: RunFunctionOptions) => Promise<unknown>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/workflow",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.56",
|
|
4
4
|
"description": "Durable workflows for Lunora: defineWorkflow over Cloudflare Workflows, generated WorkflowEntrypoint classes, and the ctx.workflows surface",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
"access": "public"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
52
|
-
"@lunora/values": "1.0.0-alpha.
|
|
51
|
+
"@lunora/errors": "1.0.0-alpha.39",
|
|
52
|
+
"@lunora/values": "1.0.0-alpha.49"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
55
|
"node": "^22.15.0 || >=24.11.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as E,c as A}from"./run-step-CFhxLFfp.mjs";import{LunoraError as h}from"@lunora/errors";import{workflowBindingName as m}from"./defineWorkflow-tKaIifbZ.mjs";import{raiseNonRetryable as R}from"./NonRetryableError-BPu01mU8.mjs";import{createSpawn as I,createParallel as k}from"./MAX_BRANCHES-j59ZUUSu.mjs";import{createWaitForEvent as T}from"./createWaitForEvent-D5Ohn2Pz.mjs";const C=r=>({debug:(n,...o)=>{console.debug(r,n,...o)},error:(n,...o)=>{console.error(r,n,...o)},info:(n,...o)=>{console.info(r,n,...o)},warn:(n,...o)=>{console.warn(r,n,...o)}}),N=r=>{let n="";for(let c=0;c<r.length;c+=32768)n+=String.fromCharCode(...r.subarray(c,c+32768));return btoa(n)},O=r=>{const n=atob(r),o=new Uint8Array(n.length);for(let c=0;c<n.length;c+=1)o[c]=n.codePointAt(c)??0;return o},S="$lunora.wire$",w=64,y=1024,b="__proto__",g={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},p={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},i=(r,n=0)=>{if(n>w)throw new RangeError(`wire-codec: value nesting exceeds the ${w}-level limit`);if(r===null||typeof r!="object")return r;if(Array.isArray(r)){if(r[0]===S)switch(r[1]){case"-inf":return-1/0;case"arr":return r[2].map(e=>i(e,n+1));case"bigint":{const e=r[2];if(typeof e!="string"||e.length>y||!/^-?\d+$/.test(e))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${y} digits)`);return BigInt(e)}case"date":{const e=i(r[2],n+1);if(typeof e!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(e)}case"map":{const e=r[2];return new Map(e.map(t=>{if(!Array.isArray(t)||t.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[i(t[0],n+1),i(t[1],n+1)]}))}case"set":return new Set(r[2].map(e=>i(e,n+1)));case"url":{const e=r[2];if(typeof e!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(e)}case"error":{const e=r[2],t=r[3];if(typeof e!="string"||typeof t!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const u=(Object.hasOwn(p,e)?p[e]:void 0)??Error,s=new u(t);s.name!==e&&Object.defineProperty(s,"name",{configurable:!0,value:e,writable:!0});const a=i(r[4],n+1);if(a===null||typeof a!="object"||Array.isArray(a))throw new TypeError("wire-codec: malformed error — props must be an object");for(const l of Object.keys(a))l===b?Object.defineProperty(s,l,{configurable:!0,enumerable:!0,value:a[l],writable:!0}):s[l]=a[l];return r.length>5&&Object.defineProperty(s,"cause",{configurable:!0,value:i(r[5],n+1),writable:!0}),s}case"bytes":{const e=r[2];if(typeof e!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const t=O(e);if(N(t)!==e)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const u=r[3]??"Uint8Array";if(u==="ArrayBuffer")return t.buffer.byteLength===t.byteLength?t.buffer:t.slice().buffer;const s=Object.hasOwn(g,u)?g[u]:void 0;return s?new s(t.slice().buffer):t}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return r.map(e=>i(e,n+1))}return r.map(f=>i(f,n+1))}const o=r,c={};for(const f of Object.keys(o)){const e=i(o[f],n+1);f===b?Object.defineProperty(c,f,{configurable:!0,enumerable:!0,value:e,writable:!0}):c[f]=e}return c},P=r=>{const n=C(`[workflow:${r.exportName}]`),o=E({env:r.env,fetchImpl:r.fetchImpl,label:"@lunora/workflow"}),c=a=>{const l=m(a),d=r.env[l];if(!d||typeof d.create!="function"||typeof d.get!="function")throw new h("INTERNAL",`@lunora/workflow: cannot spawn child workflow "${a}" — no Workflow binding "${l}" on env (is it declared in lunora/workflows.ts?)`);return d};let f=0;const e=a=>{if(a!==void 0)return a;const l=`${r.event.instanceId}-c${String(f)}`;return f+=1,l},t={env:r.env,instanceId:r.event.instanceId,log:n,nextChildId:e,parentBinding:m(r.exportName),resolveBinding:c,step:r.step},s=(()=>{try{return i(r.event.payload)}catch(a){return R(`@lunora/workflow: workflow "${r.exportName}" params could not be decoded — ${a instanceof Error?a.message:String(a)}`,a,r.nonRetryableErrorClass)}})();return{env:r.env,event:r.event,log:n,parallel:k(t),params:s,run:o,runStep:A({env:r.env,log:n,nonRetryableErrorClass:r.nonRetryableErrorClass,run:o,step:r.step}),spawn:I(t),step:r.step,waitForEvent:T({nonRetryableErrorClass:r.nonRetryableErrorClass,step:r.step})}};export{P as createWorkflowRunContext};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as w,isLunoraError as C}from"@lunora/errors";import{parseValidatorMap as B}from"@lunora/values";import{RESERVED_EVENT_TYPE_PREFIX as S}from"./defineWorkflowEvent-suERPEEV.mjs";import{raiseNonRetryable as $,convertNonRetryableError as M}from"./NonRetryableError-BPu01mU8.mjs";const J=(e,t,o)=>{if(t===void 0)return{dispose:()=>{},signal:e};const a=new AbortController,n=setTimeout(()=>{a.abort(o())},t);return{dispose:()=>{clearTimeout(n)},signal:a.signal}},O=e=>{let t="";for(let o=0;o<e.length;o+=32768)t+=String.fromCharCode(...e.subarray(o,o+32768));return btoa(t)},F=e=>{const t=atob(e),o=new Uint8Array(t.length);for(let a=0;a<t.length;a+=1)o[a]=t.codePointAt(a)??0;return o},p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_",U=e=>{let t="",o=0;const a=e.length-2;for(;o<a;o+=3){const r=e[o]<<16|e[o+1]<<8|e[o+2];t+=p.charAt(r>>18&63)+p.charAt(r>>12&63)+p.charAt(r>>6&63)+p.charAt(r&63)}const n=e.length-o;if(n===1){const r=e[o]<<16;t+=p.charAt(r>>18&63)+p.charAt(r>>12&63)}else if(n===2){const r=e[o]<<16|e[o+1]<<8;t+=p.charAt(r>>18&63)+p.charAt(r>>12&63)+p.charAt(r>>6&63)}return t};new TextDecoder;const k=new TextEncoder,I="=",K=e=>{for(let t=0;t<e.length;t+=1)if(e.charCodeAt(t)>255)return!1;return!0},V=e=>U(k.encode(JSON.stringify(e))),W=e=>!e.startsWith(I)&&K(e)?e:`${I}${U(k.encode(e))}`,u="$lunora.wire$",R=64,j=1024,T="__proto__",_={BigInt64Array,BigUint64Array,Float32Array,Float64Array,Int8Array,Int16Array,Int32Array,Uint8Array,Uint8ClampedArray,Uint16Array,Uint32Array},L={Error,EvalError,RangeError,ReferenceError,SyntaxError,TypeError,URIError},H=e=>{if(e===null||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===null||t===Object.prototype},h=(e,t=0)=>{if(t>R)throw new RangeError(`wire-codec: value nesting exceeds the ${R}-level limit`);if(e===void 0)return[u,"undefined"];if(e===null)return null;const o=typeof e;if(o==="bigint")return[u,"bigint",e.toString()];if(o==="number"){const r=e;return Number.isNaN(r)?[u,"nan"]:r===1/0?[u,"inf"]:r===-1/0?[u,"-inf"]:r}if(o!=="object")return e;if(e instanceof Date)return[u,"date",h(e.getTime(),t+1)];if(e instanceof Error){const r=e,s={};for(const c of Object.keys(r)){if(r[c]===void 0)continue;const l=h(r[c],t+1);c===T?Object.defineProperty(s,c,{configurable:!0,enumerable:!0,value:l,writable:!0}):s[c]=l}const i=[u,"error",String(r.name),String(r.message),s];return r.cause!==void 0&&i.push(h(r.cause,t+1)),i}if(e instanceof URL)return[u,"url",e.href];if(e instanceof Map)return[u,"map",[...e.entries()].map(([r,s])=>[h(r,t+1),h(s,t+1)])];if(e instanceof Set)return[u,"set",[...e].map(r=>h(r,t+1))];if(e instanceof ArrayBuffer)return[u,"bytes",O(new Uint8Array(e)),"ArrayBuffer"];if(ArrayBuffer.isView(e)){const r=e,s=r.constructor.name,i=new Uint8Array(r.buffer,r.byteOffset,r.byteLength);return s==="Uint8Array"?[u,"bytes",O(i)]:[u,"bytes",O(i),s]}if(Array.isArray(e)){const r=e.map(s=>h(s,t+1));return r.length>0&&r[0]===u?[u,"arr",r]:r}if(!H(e)){const r=e.constructor?.name??"value";throw new TypeError(`wire-codec: cannot encode a ${r} over the Lunora wire — only plain objects, arrays, and the supported built-ins (Date, Error, URL, Map, Set, ArrayBuffer/typed arrays, bigint) round-trip`)}const a=e,n={};for(const r of Object.keys(a)){const s=a[r];if(s===void 0)continue;const i=h(s,t+1);r===T?Object.defineProperty(n,r,{configurable:!0,enumerable:!0,value:i,writable:!0}):n[r]=i}return n},y=(e,t=0)=>{if(t>R)throw new RangeError(`wire-codec: value nesting exceeds the ${R}-level limit`);if(e===null||typeof e!="object")return e;if(Array.isArray(e)){if(e[0]===u)switch(e[1]){case"-inf":return-1/0;case"arr":return e[2].map(n=>y(n,t+1));case"bigint":{const n=e[2];if(typeof n!="string"||n.length>j||!/^-?\d+$/.test(n))throw new RangeError(`wire-codec: invalid or over-long bigint (max ${j} digits)`);return BigInt(n)}case"date":{const n=y(e[2],t+1);if(typeof n!="number")throw new TypeError("wire-codec: malformed date — epoch must be a number");return new Date(n)}case"map":{const n=e[2];return new Map(n.map(r=>{if(!Array.isArray(r)||r.length!==2)throw new TypeError("wire-codec: malformed map entry — expected a [key, value] pair");return[y(r[0],t+1),y(r[1],t+1)]}))}case"set":return new Set(e[2].map(n=>y(n,t+1)));case"url":{const n=e[2];if(typeof n!="string")throw new TypeError("wire-codec: malformed url — href must be a string");return new URL(n)}case"error":{const n=e[2],r=e[3];if(typeof n!="string"||typeof r!="string")throw new TypeError("wire-codec: malformed error — name and message must be strings");const s=(Object.hasOwn(L,n)?L[n]:void 0)??Error,i=new s(r);i.name!==n&&Object.defineProperty(i,"name",{configurable:!0,value:n,writable:!0});const c=y(e[4],t+1);if(c===null||typeof c!="object"||Array.isArray(c))throw new TypeError("wire-codec: malformed error — props must be an object");for(const l of Object.keys(c))l===T?Object.defineProperty(i,l,{configurable:!0,enumerable:!0,value:c[l],writable:!0}):i[l]=c[l];return e.length>5&&Object.defineProperty(i,"cause",{configurable:!0,value:y(e[5],t+1),writable:!0}),i}case"bytes":{const n=e[2];if(typeof n!="string")throw new TypeError("wire-codec: malformed bytes — payload must be a base64 string");const r=F(n);if(O(r)!==n)throw new TypeError("wire-codec: malformed bytes — payload must be canonical padded base64");const s=e[3]??"Uint8Array";if(s==="ArrayBuffer")return r.buffer.byteLength===r.byteLength?r.buffer:r.slice().buffer;const i=Object.hasOwn(_,s)?_[s]:void 0;return i?new i(r.slice().buffer):r}case"inf":return 1/0;case"nan":return Number.NaN;case"undefined":return;default:return e.map(n=>y(n,t+1))}return e.map(n=>y(n,t+1))}const o=e,a={};for(const n of Object.keys(o)){const r=y(o[n],t+1);n===T?Object.defineProperty(a,n,{configurable:!0,enumerable:!0,value:r,writable:!0}):a[n]=r}return a},G=(e,t,o)=>{try{return h(o)}catch(a){throw new TypeError(`${e}: cannot encode args for '${t}' — ${a instanceof Error?a.message:String(a)}`,a instanceof Error?{cause:a}:void 0)}},z="/_lunora/scheduler/dispatch",X=3e4,Y=e=>{let t=e.length;for(;t>0&&e[t-1]==="/";)t-=1;return e.slice(0,t)},P=Symbol("lunoraDispatchFailure"),q=Symbol("lunoraDispatchMessageId"),x=(e,t)=>(t!==void 0&&Object.defineProperty(e,q,{value:t}),e),Q=(e,t)=>(Object.defineProperty(e,P,{value:!0}),x(e,t)),Z=(e,t,o,a)=>{try{const n=JSON.parse(o)?.error;if(typeof n=="object"&&n!==null&&typeof n.code=="string"){const{code:r,data:s,message:i}=n;return Q(new w(r,typeof i=="string"?i:void 0,{data:s,status:t}),a)}}catch{}return x(new w("INTERNAL",`${e}: function dispatch failed (${String(t)}): ${o}`,{status:t}),a)},ee=new Set([400,403,404,422]),te=new Set(["DISPATCH_UNAUTHENTICATED"]),re=e=>C(e)&&e[P]===!0&&ee.has(e.status)&&!te.has(e.code),ne=(e,t,o)=>new w("INTERNAL",`${e}: function dispatch to "${t}" timed out after ${String(o)}ms`,{status:503}),ue=e=>{const{label:t}=e,o=globalThis.fetch,a=e.fetchImpl??(typeof o=="function"?o.bind(globalThis):void 0);return async(n,r,s={})=>{if(typeof a!="function")throw new TypeError(`${t}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const i=()=>e.argsAlreadyEncoded===!0?r??{}:G(t,n.__lunoraRef,r??{}),c=e.env.LUNORA_ORIGIN_URL;if(typeof c!="string"||c.length===0)throw new w("INTERNAL",`${t}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const l=e.env.LUNORA_ADMIN_TOKEN;if(typeof l!="string"||l.length===0)throw new w("INTERNAL",`${t}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const g=`${Y(c)}${z}`,A={authorization:`Bearer ${l}`,"content-type":"application/json"};e.traceparent!==void 0&&e.traceparent.length>0&&(A.traceparent=e.traceparent),e.identity?.userId!==void 0&&(A["x-lunora-userid"]=W(e.identity.userId)),e.identity?.claims!==void 0&&(A["x-lunora-identity"]=V(e.identity.claims));const m=s.timeoutMs??X,f=J(void 0,m,()=>new DOMException(`dispatch timed out after ${String(m)}ms`,"TimeoutError")),N=b=>{throw b instanceof Error&&b.name==="TimeoutError"?ne(t,n.__lunoraRef,m):b};let d;try{try{d=await a(g,{body:JSON.stringify({args:i(),functionPath:n.__lunoraRef,id:s.dedupId,shardKey:s.shardKey}),headers:A,method:"POST",signal:f.signal})}catch(v){return N(v)}if(!d.ok){let v;try{v=await d.text()}catch(D){return N(D)}throw Z(t,d.status,v,s.messageId)}let b;try{b=await d.text()}catch(v){return N(v)}if(b.length===0)return;let E;try{E=JSON.parse(b)}catch{throw new w("INTERNAL",`${t}: function dispatch returned a non-JSON body (${String(d.status)}): ${b}`,{status:d.status})}if(E===null||typeof E!="object"||Array.isArray(E)||!("result"in E))throw new w("INTERNAL",`${t}: function dispatch returned a JSON body that is not a { result } envelope (${String(d.status)}): ${b}`,{status:d.status});return y(E.result)}finally{f.dispose()}}},oe=(e,t)=>B(e,t,"step args"),le=e=>async(t,o,a)=>{const n=a?.config??t.config,r=a?.name??t.name;if(r.startsWith(S))return $(`@lunora/workflow: ctx.runStep step name "${r}" is reserved — the "${S}" prefix is used by the framework's own steps`,void 0,e.nonRetryableErrorClass);const s=oe(t.args,o),i=async g=>{const A={attempt:g.attempt,config:g.config,env:e.env,log:e.log,run:e.run,step:g.step};let m;try{m=await t.handler(A,s)}catch(f){return re(f)?$(f.message,f,e.nonRetryableErrorClass):M(f,e.nonRetryableErrorClass)}if(!t.returns)return m;try{return t.returns.parse(m)}catch(f){const N=f instanceof Error?f.message:String(f);return $(`step "${t.name}" returns validation failed: ${N}`,f,e.nonRetryableErrorClass)}},c=t.rollback,l=c?{rollback:async g=>{await c({args:s,env:e.env,error:g.error,log:e.log,output:g.output,run:e.run})},rollbackConfig:t.rollbackConfig}:void 0;return n===void 0?e.step.do(r,i,l):e.step.do(r,n,i,l)};export{le as c,ue as t,oe as v};
|