@lunora/workflow 1.0.0-alpha.28 → 1.0.0-alpha.29
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.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/MAX_BRANCHES-ZS8UAw_t.mjs +1 -0
- package/dist/packem_shared/NonRetryableError-9ZqDUzwT.mjs +1 -0
- package/dist/packem_shared/WorkflowsRestError-HhBsn3PQ.mjs +1 -0
- package/dist/packem_shared/branch-marker-CCpWfS5k.mjs +1 -0
- package/dist/packem_shared/createRunStep-BfxFmj2D.mjs +1 -0
- package/dist/packem_shared/createWorkflowContext-DG-jCSoa.mjs +1 -0
- package/dist/packem_shared/createWorkflowRunContext-D1vdFtWC.mjs +1 -0
- package/dist/packem_shared/createWorkflows-uoAhGKCA.mjs +1 -0
- package/dist/packem_shared/{defineStep-rJ0XPdAx.mjs → defineStep-D1-9eOnA.mjs} +1 -1
- package/dist/packem_shared/defineWorkflow-tKaIifbZ.mjs +1 -0
- package/dist/packem_shared/run-step-7RiMJYR7.mjs +1 -0
- package/package.json +3 -3
- package/dist/packem_shared/MAX_BRANCHES-DtgdnoIA.mjs +0 -1
- package/dist/packem_shared/NonRetryableError-hhUGqOs8.mjs +0 -1
- package/dist/packem_shared/WorkflowsRestError--PIoe9uw.mjs +0 -1
- package/dist/packem_shared/branch-marker-B2lebQA6.mjs +0 -1
- package/dist/packem_shared/createRunStep-B-brWQMb.mjs +0 -1
- package/dist/packem_shared/createWorkflowContext-Dw8a1U68.mjs +0 -1
- package/dist/packem_shared/createWorkflowRunContext-D46__d3v.mjs +0 -1
- package/dist/packem_shared/createWorkflows-3djec-oS.mjs +0 -1
- package/dist/packem_shared/defineWorkflow-fBuCDkGT.mjs +0 -1
- package/dist/packem_shared/run-step-8dSqaby-.mjs +0 -1
package/dist/do/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{WorkflowEntrypoint as
|
|
1
|
+
import{WorkflowEntrypoint as p}from"cloudflare:workers";import{NonRetryableError as i}from"cloudflare:workflows";import{convertNonRetryableError as m}from"../packem_shared/NonRetryableError-9ZqDUzwT.mjs";import{extractBranchMarker as f,stripBranchMarker as h,signalBranchParentSafe as l,errorOutcome as u,okOutcome as y}from"../packem_shared/MAX_BRANCHES-ZS8UAw_t.mjs";import{createWorkflowRunContext as d}from"../packem_shared/createWorkflowRunContext-D1vdFtWC.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.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createWorkflowContext as e}from"./packem_shared/createWorkflowContext-
|
|
1
|
+
import{createWorkflowContext as e}from"./packem_shared/createWorkflowContext-DG-jCSoa.mjs";import{default as f}from"./packem_shared/createWorkflows-uoAhGKCA.mjs";import{defineStep as l,isStepDefinition as n}from"./packem_shared/defineStep-D1-9eOnA.mjs";import{defineWorkflow as s,isWorkflowDefinition as p,workflowBindingName as w,workflowClassName as m,workflowDefaultName as x}from"./packem_shared/defineWorkflow-tKaIifbZ.mjs";import{NonRetryableError as N,convertNonRetryableError as R,isNonRetryableError as c,toNativeNonRetryableError as W}from"./packem_shared/NonRetryableError-9ZqDUzwT.mjs";import{MAX_BRANCHES as b,branch as d}from"./packem_shared/MAX_BRANCHES-ZS8UAw_t.mjs";import{WorkflowsRestError as S,createWorkflowsRestClient as u}from"./packem_shared/WorkflowsRestError-HhBsn3PQ.mjs";import{createWorkflowRunContext as y}from"./packem_shared/createWorkflowRunContext-D1vdFtWC.mjs";import{c as D,v as g}from"./packem_shared/run-step-7RiMJYR7.mjs";export{b as MAX_BRANCHES,N as NonRetryableError,S as WorkflowsRestError,d as branch,R as convertNonRetryableError,D as createRunStep,e as createWorkflowContext,y as createWorkflowRunContext,f as createWorkflows,u as createWorkflowsRestClient,l as defineStep,s as defineWorkflow,c as isNonRetryableError,n as isStepDefinition,p as isWorkflowDefinition,W as toNativeNonRetryableError,g as validateStepArgs,w as workflowBindingName,m as workflowClassName,x as workflowDefaultName};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as y}from"@lunora/errors";import{h as E,B as v,a as p}from"./branch-marker-CCpWfS5k.mjs";import{NonRetryableError as d}from"./NonRetryableError-9ZqDUzwT.mjs";const h=100,g="lunora:spawn:",I="lunora:await:",$="lunora:signal:",x="lunora:compensate:",m="lunora:branch:",R=(t,r,n)=>({compensateWith:n?.compensateWith,id:n?.id,params:r,timeout:n?.timeout,workflow:t}),w=t=>t instanceof Error?{message:t.message,name:t.name}:{message:String(t),name:"Error"},b=t=>({status:"ok",value:t}),_=t=>({error:w(t),status:"error"}),f=async(t,r,n)=>{for(let o=r.length-1;o>=0;o-=1){const a=r[o],c=a?.plan.item.compensateWith;if(!(a===void 0||c===void 0))try{const s=t.resolveBinding(c);await t.step.do(`${x}${a.plan.childId}`,async()=>{const e=`${a.plan.childId}:compensate`,i={branch:a.plan.item.workflow,error:n,index:a.plan.index,output:a.output};return await s.create({id:e,params:i}),e})}catch(s){t.log?.error(`ctx.parallel: group-saga compensation "${c}" for branch "${a.plan.item.workflow}" (#${String(a.plan.index)}) failed`,s)}}},A=t=>async n=>{if(n.length===0)return[];if(n.length>h)throw new d(`ctx.parallel: ${String(n.length)} branches exceeds the cap of ${String(h)} — split the fan-out or raise the work into fewer child workflows`);const o=n.map((e,i)=>{const l=t.nextChildId(e.id);return{childId:l,eventType:`${m}${l}`,index:i,item:e}}),a=new Set;for(const e of o){if(a.has(e.childId))throw new d(`ctx.parallel: duplicate branch id "${e.childId}" — each branch in a group must resolve to a unique child instance id (check explicit \`id\` options)`);a.add(e.childId)}await Promise.all(o.map(e=>t.step.do(`${g}${e.childId}`,async()=>{const i=t.resolveBinding(e.item.workflow),l={eventType:e.eventType,index:e.index,parentBinding:t.parentBinding,parentId:t.instanceId};return await i.create({id:e.childId,params:{...e.item.params,[p]:l}}),e.childId})));const c=[],s=[];for(const e of o){let i;try{i=(await t.step.waitForEvent(`${I}${e.childId}`,{timeout:e.item.timeout,type:e.eventType})).payload}catch(l){const u=w(l);throw await f(t,s,u),new d(`ctx.parallel: branch "${e.item.workflow}" (#${String(e.index)}) join failed: ${u.message}`)}if(i.status==="error")throw await f(t,s,i.error),new d(`ctx.parallel: branch "${e.item.workflow}" (#${String(e.index)}) failed: ${i.error.message}`);s.push({output:i.value,plan:e}),c.push(i.value)}return c},k=t=>async(r,n,o)=>{if(E(n))throw new y("BAD_REQUEST",`@lunora/workflow: params ${v}`);const a=t.nextChildId(o?.id);return await t.step.do(`${g}${a}`,async()=>(await t.resolveBinding(r).create({id:a,params:n}),a)),t.resolveBinding(r).get(a)},N=t=>{if(typeof t!="object"||t===null)return;const r=t[p];if(typeof r!="object"||r===null)return;const n=r;if(!(typeof n.eventType!="string"||typeof n.parentBinding!="string"||typeof n.parentId!="string"||typeof n.index!="number")&&!(!n.parentBinding.startsWith("WORKFLOW_")||!n.eventType.startsWith(m)))return{eventType:n.eventType,index:n.index,parentBinding:n.parentBinding,parentId:n.parentId}},W=t=>{if(typeof t!="object"||t===null)return t;const r={...t};return Reflect.deleteProperty(r,p),r},B=async(t,r,n)=>{const o=t.env[r.parentBinding];if(!o||typeof o.get!="function")return;const a=o.get.bind(o);await t.step.do(`${$}${String(r.index)}`,async()=>(await(await a(r.parentId)).sendEvent({payload:n,type:r.eventType}),r.eventType))},C=async(t,r,n)=>{try{await B(t,r,n)}catch(o){t.log?.error(`@lunora/workflow: failed to signal branch parent "${r.parentId}" (event "${r.eventType}")`,o)}};export{h as MAX_BRANCHES,R as branch,A as createParallel,k as createSpawn,_ as errorOutcome,N as extractBranchMarker,b as okOutcome,B as signalBranchParent,C as signalBranchParentSafe,W as stripBranchMarker};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const s="__lunoraNonRetryable";class a extends Error{constructor(e,n="NonRetryableError"){super(e),this.name=n,this[s]=!0}}const c=t=>t instanceof Error&&t[s]===!0,r=(t,e)=>{const n=new e(t.message,t.name);return t.stack!==void 0&&(n.stack=t.stack),t.cause!==void 0&&n.cause===void 0&&(n.cause=t.cause),n},i=(t,e)=>{throw e!==void 0&&c(t)?r(t,e):t},u=(t,e,n)=>{const o=new a(t);return e!==void 0&&(o.cause=e),i(o,n)};export{a as NonRetryableError,i as convertNonRetryableError,c as isNonRetryableError,u as raiseNonRetryable,r as toNativeNonRetryableError};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as h}from"@lunora/errors";const R="https://api.cloudflare.com/client/v4/accounts",$={complete:!0,errored:!0,paused:!0,queued:!0,running:!0,terminated:!0,unknown:!0,waiting:!0,waitingForPause:!0},g=t=>typeof t=="string"&&Object.hasOwn($,t)?t:"unknown",u=t=>typeof t=="string"&&t!==""?t:void 0,S=(t,a)=>typeof t=="string"?t:a,A=t=>typeof t=="boolean"?t:void 0,_=t=>Array.isArray(t)?t.length:typeof t=="number"?t:void 0,f=t=>({createdOn:u(t.created_on),endedOn:u(t.ended_on),id:S(t.id,""),startedOn:u(t.started_on),status:g(t.status)}),I=t=>({attempts:_(t.attempts),end:u(t.end),error:t.error,name:S(t.name,""),output:t.output,start:u(t.start),success:A(t.success),type:u(t.type)});class l extends h{constructor(a,i){super("WORKFLOWS_REST_ERROR",`Cloudflare Workflows REST API returned ${String(a)}: ${i}`,{name:"WorkflowsRestError",status:a})}}const w=t=>{const a=t.fetch??globalThis.fetch.bind(globalThis),i=`${R}/${t.accountId}/workflows`,p=async(o,r)=>{const s=await a(`${i}${o}`,{...r,headers:{Authorization:`Bearer ${t.apiToken}`,"Content-Type":"application/json"}}),e=await s.text();let n;try{n=JSON.parse(e)}catch{throw new l(s.status,e)}if(!s.ok||n.success===!1)throw new l(s.status,e);return n};return{getInstance:async({instanceId:o,workflowName:r})=>{const e=(await p(`/${encodeURIComponent(r)}/instances/${encodeURIComponent(o)}`)).result??{},n=Array.isArray(e.steps)?e.steps:[];return{...f(e),error:e.error,output:e.output,params:e.params,steps:n.map(d=>I(d))}},listInstances:async({page:o,perPage:r,status:s,workflowName:e})=>{const n=new URLSearchParams;s!==void 0&&n.set("status",s),o!==void 0&&n.set("page",String(o)),r!==void 0&&n.set("per_page",String(r));const d=n.toString()===""?"":`?${n.toString()}`,y=await p(`/${encodeURIComponent(e)}/instances${d}`),m=Array.isArray(y.result)?y.result:[],c=y.result_info??{};return{instances:m.map(b=>f(b)),page:typeof c.page=="number"?c.page:o??1,perPage:typeof c.per_page=="number"?c.per_page:r??m.length,totalCount:typeof c.total_count=="number"?c.total_count:void 0}},setInstanceStatus:async({action:o,instanceId:r,workflowName:s})=>{const n=(await p(`/${encodeURIComponent(s)}/instances/${encodeURIComponent(r)}`,{body:JSON.stringify({status:o}),method:"PATCH"})).result??{};return{status:g(n.status)}}}};export{l as WorkflowsRestError,w as createWorkflowsRestClient};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e="__lunoraBranch",o=n=>typeof n=="object"&&n!==null&&Object.hasOwn(n,e),a=`may not contain the reserved workflow branch-marker key ("${e}")`;export{a as B,e as a,o as h};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{c as r,v as p}from"./run-step-7RiMJYR7.mjs";import"./NonRetryableError-9ZqDUzwT.mjs";export{r as createRunStep,p as validateStepArgs};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import r from"./createWorkflows-uoAhGKCA.mjs";const i=(n,c)=>{const o={};for(const e of c){const t=n[e.binding];t&&typeof t.create=="function"&&typeof t.createBatch=="function"&&typeof t.get=="function"&&(o[e.exportName]=t)}return r({bindings:o})};export{i as createWorkflowContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as w,c as u}from"./run-step-7RiMJYR7.mjs";import{LunoraError as v}from"@lunora/errors";import{workflowBindingName as f}from"./defineWorkflow-tKaIifbZ.mjs";import{createSpawn as i,createParallel as m}from"./MAX_BRANCHES-ZS8UAw_t.mjs";const g=e=>({debug:(n,...r)=>{console.debug(e,n,...r)},error:(n,...r)=>{console.error(e,n,...r)},info:(n,...r)=>{console.info(e,n,...r)},warn:(n,...r)=>{console.warn(e,n,...r)}}),h=e=>{const n=g(`[workflow:${e.exportName}]`),r=w({env:e.env,fetchImpl:e.fetchImpl,label:"@lunora/workflow"}),s=t=>{const a=f(t),o=e.env[a];if(!o||typeof o.create!="function"||typeof o.get!="function")throw new v("INTERNAL",`@lunora/workflow: cannot spawn child workflow "${t}" — no Workflow binding "${a}" on env (is it declared in lunora/workflows.ts?)`);return o};let l=0;const d=t=>{if(t!==void 0)return t;const a=`${e.event.instanceId}-c${String(l)}`;return l+=1,a},c={env:e.env,instanceId:e.event.instanceId,log:n,nextChildId:d,parentBinding:f(e.exportName),resolveBinding:s,step:e.step};return{env:e.env,event:e.event,log:n,parallel:m(c),params:e.event.payload,run:r,runStep:u({env:e.env,log:n,nonRetryableErrorClass:e.nonRetryableErrorClass,run:r,step:e.step}),spawn:i(c),step:e.step}};export{h as createWorkflowRunContext};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as s}from"@lunora/errors";import{h as w,B as f}from"./branch-marker-CCpWfS5k.mjs";const a=o=>{if(w(o?.params))throw new s("BAD_REQUEST",`@lunora/workflow: params ${f}`)},l=o=>({create:async r=>(a(r),o.create(r)),createBatch:async r=>{for(const e of r)a(e);return o.createBatch(r)},get:async r=>o.get(r)}),i=o=>{const r=o.bindings??{};return{get:e=>{const n=r[e];if(n===void 0){const t=Object.keys(r),c=t.length===0?"no workflows are declared":`known workflows: ${t.join(", ")}`;throw new s("INTERNAL",`@lunora/workflow: no workflow named "${e}" (${c})`)}return l(n)}}};export{i as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
const n=(r,e)=>{if(typeof r!="string"||r.length===0)throw new TypeError("defineStep: `name` must be a non-empty string (the durable step label)");const t=e.args;if(typeof t!="object"||t===null)throw new TypeError("defineStep: `args` must be a validator map (e.g. `{ id: v.string() }`)");if(typeof e.handler!="function")throw new TypeError("defineStep: `handler` must be a function (the step body)");if(e.rollback!==void 0&&typeof e.rollback!="function")throw new TypeError("defineStep: `rollback` must be a function when provided");return{args:e.args,config:e.config,handler:e.handler,isLunoraStep:!0,name:r,returns:e.returns,rollback:e.rollback,rollbackConfig:e.rollbackConfig}},o=r=>typeof r=="object"&&r!==null&&r.isLunoraStep===!0;export{n as defineStep,o as isStepDefinition};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=o=>`${o.charAt(0).toUpperCase()}${o.slice(1)}Workflow`,r=o=>`WORKFLOW_${o.replaceAll(/(?<=[a-z0-9])(?=[A-Z])/g,"_").toUpperCase()}`,n=o=>o.replaceAll(/(?<=[a-z0-9])(?=[A-Z])/g,"-").toLowerCase(),t=o=>{if(typeof o.handler!="function")throw new TypeError("defineWorkflow: `handler` must be a function (the workflow body)");if(o.name!==void 0&&(typeof o.name!="string"||o.name.length===0))throw new TypeError("defineWorkflow: `name` must be a non-empty string when provided");return{...o,isLunoraWorkflow:!0}},l=o=>typeof o=="object"&&o!==null&&o.isLunoraWorkflow===!0;export{t as defineWorkflow,l as isWorkflowDefinition,r as workflowBindingName,e as workflowClassName,n as workflowDefaultName};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as d,isLunoraError as A}from"@lunora/errors";import{parseValidatorMap as O}from"@lunora/values";import{raiseNonRetryable as b,convertNonRetryableError as S}from"./NonRetryableError-9ZqDUzwT.mjs";const I=t=>{let r="";for(let e=0;e<t.length;e+=32768)r+=String.fromCharCode(...t.subarray(e,e+32768));return btoa(r)},R=t=>I(t).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"");new TextDecoder;const $=new TextEncoder,N="=",L=t=>{for(let r=0;r<t.length;r+=1)if(t.charCodeAt(r)>255)return!1;return!0},T=t=>R($.encode(JSON.stringify(t))),_=t=>!t.startsWith(N)&&L(t)?t:`${N}${R($.encode(t))}`,k="/_lunora/scheduler/dispatch",C=3e4,U=t=>{let r=t.length;for(;r>0&&t[r-1]==="/";)r-=1;return t.slice(0,r)},v=Symbol("lunoraDispatchFailure"),w=t=>(Object.defineProperty(t,v,{value:!0}),t),x=(t,r,e)=>{try{const a=JSON.parse(e)?.error;if(typeof a=="object"&&a!==null&&typeof a.code=="string"){const{code:i,data:u,message:s}=a;return w(new d(i,typeof s=="string"?s:void 0,{data:u,status:r}))}}catch{}return w(new d("INTERNAL",`${t}: function dispatch failed (${String(r)}): ${e}`,{status:r}))},D=new Set([400,403,404,422]),J=t=>A(t)&&t[v]===!0&&D.has(t.status),K=(t,r,e)=>new d("INTERNAL",`${t}: function dispatch to "${r}" timed out after ${String(e)}ms`,{status:503}),G=t=>{const{label:r}=t,e=globalThis.fetch,a=t.fetchImpl??(typeof e=="function"?e.bind(globalThis):void 0);return async(i,u,s={})=>{if(typeof a!="function")throw new TypeError(`${r}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const f=t.env.LUNORA_ORIGIN_URL;if(typeof f!="string"||f.length===0)throw new d("INTERNAL",`${r}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const h=t.env.LUNORA_ADMIN_TOKEN;if(typeof h!="string"||h.length===0)throw new d("INTERNAL",`${r}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const c=`${U(f)}${k}`,y={authorization:`Bearer ${h}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(y["x-lunora-userid"]=_(t.identity.userId)),t.identity?.claims!==void 0&&(y["x-lunora-identity"]=T(t.identity.claims));const g=s.timeoutMs??C,n=AbortSignal.timeout(g),m=o=>{throw o instanceof Error&&o.name==="TimeoutError"?K(r,i.__lunoraRef,g):o};let l;try{l=await a(c,{body:JSON.stringify({args:u??{},functionPath:i.__lunoraRef,shardKey:s.shardKey}),headers:y,method:"POST",signal:n})}catch(o){return m(o)}if(!l.ok){let o;try{o=await l.text()}catch(E){return m(E)}throw x(r,l.status,o)}let p;try{p=await l.text()}catch(o){return m(o)}if(p.length!==0)try{return JSON.parse(p)}catch{throw new d("INTERNAL",`${r}: function dispatch returned a non-JSON body (${String(l.status)}): ${p}`,{status:l.status})}}},M=(t,r)=>O(t,r,"step args"),z=t=>async(r,e,a)=>{const i=a?.config??r.config,u=M(r.args,e),s=async c=>{const y={attempt:c.attempt,config:c.config,env:t.env,log:t.log,run:t.run,step:c.step};let g;try{g=await r.handler(y,u)}catch(n){return J(n)?b(n.message,n,t.nonRetryableErrorClass):S(n,t.nonRetryableErrorClass)}if(!r.returns)return g;try{return r.returns.parse(g)}catch(n){const m=n instanceof Error?n.message:String(n);return b(`step "${r.name}" returns validation failed: ${m}`,n,t.nonRetryableErrorClass)}},f=r.rollback,h=f?{rollback:async c=>{await f({args:u,env:t.env,error:c.error,log:t.log,output:c.output,run:t.run})},rollbackConfig:r.rollbackConfig}:void 0;return i===void 0?t.step.do(r.name,s,h):t.step.do(r.name,i,s,h)};export{G as a,z as c,M as v};
|
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.29",
|
|
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.22",
|
|
52
|
+
"@lunora/values": "1.0.0-alpha.27"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
55
|
"node": "^22.15.0 || >=24.11.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as g}from"@lunora/errors";import{a as p,h as y,B as $}from"./branch-marker-B2lebQA6.mjs";import{NonRetryableError as c}from"./NonRetryableError-hhUGqOs8.mjs";const h=100,f="lunora:spawn:",v="lunora:await:",x="lunora:signal:",B="lunora:compensate:",w="lunora:branch:",T=(e,t,a)=>({compensateWith:a?.compensateWith,id:a?.id,params:t,timeout:a?.timeout,workflow:e}),m=e=>e instanceof Error?{message:e.message,name:e.name}:{message:String(e),name:"Error"},R=e=>({status:"ok",value:e}),S=e=>({error:m(e),status:"error"}),u=async(e,t,a)=>{for(let i=t.length-1;i>=0;i-=1){const n=t[i],l=n?.plan.item.compensateWith;if(!(n===void 0||l===void 0))try{const r=e.resolveBinding(l);await e.step.do(`${B}${n.plan.childId}`,async()=>{const o=`${n.plan.childId}:compensate`,s={branch:n.plan.item.workflow,error:a,index:n.plan.index,output:n.output};return await r.create({id:o,params:s}),o})}catch(r){e.log?.error(`ctx.parallel: group-saga compensation "${l}" for branch "${n.plan.item.workflow}" (#${String(n.plan.index)}) failed`,r)}}},W=e=>async t=>{if(t.length===0)return[];if(t.length>h)throw new c(`ctx.parallel: ${String(t.length)} branches exceeds the cap of ${String(h)} — split the fan-out or raise the work into fewer child workflows`);const a=t.map((r,o)=>{const s=e.nextChildId(r.id);return{childId:s,eventType:`${w}${s}`,index:o,item:r}}),i=new Set;for(const r of a){if(i.has(r.childId))throw new c(`ctx.parallel: duplicate branch id "${r.childId}" — each branch in a group must resolve to a unique child instance id (check explicit \`id\` options)`);i.add(r.childId)}await Promise.all(a.map(r=>e.step.do(`${f}${r.childId}`,async()=>{const o=e.resolveBinding(r.item.workflow),s={eventType:r.eventType,index:r.index,parentBinding:e.parentBinding,parentId:e.instanceId};return await o.create({id:r.childId,params:{...r.item.params,[p]:s}}),r.childId})));const n=[],l=[];for(const r of a){let o;try{o=(await e.step.waitForEvent(`${v}${r.childId}`,{timeout:r.item.timeout,type:r.eventType})).payload}catch(s){const d=m(s);throw await u(e,l,d),new c(`ctx.parallel: branch "${r.item.workflow}" (#${String(r.index)}) join failed: ${d.message}`)}if(o.status==="error")throw await u(e,l,o.error),new c(`ctx.parallel: branch "${r.item.workflow}" (#${String(r.index)}) failed: ${o.error.message}`);l.push({output:o.value,plan:r}),n.push(o.value)}return n},A=e=>async(t,a,i)=>{if(y(a))throw new g("BAD_REQUEST",`@lunora/workflow: params ${$}`);const n=e.nextChildId(i?.id);return await e.step.do(`${f}${n}`,async()=>(await e.resolveBinding(t).create({id:n,params:a}),n)),e.resolveBinding(t).get(n)},_=e=>{if(typeof e!="object"||e===null)return;const t=e[p];if(typeof t!="object"||t===null)return;const a=t;if(!(typeof a.eventType!="string"||typeof a.parentBinding!="string"||typeof a.parentId!="string"||typeof a.index!="number")&&!(!a.parentBinding.startsWith("WORKFLOW_")||!a.eventType.startsWith(w)))return{eventType:a.eventType,index:a.index,parentBinding:a.parentBinding,parentId:a.parentId}},C=e=>{if(typeof e!="object"||e===null)return e;const t={...e};return Reflect.deleteProperty(t,p),t},I=async(e,t,a)=>{const i=e.env[t.parentBinding];if(!i||typeof i.get!="function")return;const n=i.get.bind(i);await e.step.do(`${x}${String(t.index)}`,async()=>(await(await n(t.parentId)).sendEvent({payload:a,type:t.eventType}),t.eventType))},M=async(e,t,a)=>{try{await I(e,t,a)}catch(i){e.log?.error(`@lunora/workflow: failed to signal branch parent "${t.parentId}" (event "${t.eventType}")`,i)}};export{h as MAX_BRANCHES,T as branch,W as createParallel,A as createSpawn,S as errorOutcome,_ as extractBranchMarker,R as okOutcome,I as signalBranchParent,M as signalBranchParentSafe,C as stripBranchMarker};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const t="__lunoraNonRetryable";class a extends Error{constructor(e,o="NonRetryableError"){super(e),this.name=o,this[t]=!0}}const c=r=>r instanceof Error&&r[t]===!0,n=(r,e)=>{const o=new e(r.message,r.name);return r.stack!==void 0&&(o.stack=r.stack),r.cause!==void 0&&o.cause===void 0&&(o.cause=r.cause),o},u=(r,e)=>{throw e!==void 0&&c(r)?n(r,e):r},i=(r,e,o)=>{const s=new a(r);return e!==void 0&&(s.cause=e),u(s,o)};export{a as NonRetryableError,u as convertNonRetryableError,c as isNonRetryableError,i as raiseNonRetryable,n as toNativeNonRetryableError};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as h}from"@lunora/errors";const $="https://api.cloudflare.com/client/v4/accounts",I={complete:!0,errored:!0,paused:!0,queued:!0,running:!0,terminated:!0,unknown:!0,waiting:!0,waitingForPause:!0},w=e=>typeof e=="string"&&Object.hasOwn(I,e)?e:"unknown",c=e=>typeof e=="string"&&e!==""?e:void 0,f=(e,a)=>typeof e=="string"?e:a,S=e=>typeof e=="boolean"?e:void 0,k=e=>Array.isArray(e)?e.length:typeof e=="number"?e:void 0,m=e=>({createdOn:c(e.created_on),endedOn:c(e.ended_on),id:f(e.id,""),startedOn:c(e.started_on),status:w(e.status)}),b=e=>({attempts:k(e.attempts),end:c(e.end),error:e.error,name:f(e.name,""),output:e.output,start:c(e.start),success:S(e.success),type:c(e.type)});class g extends h{constructor(a,i){super("WORKFLOWS_REST_ERROR",`Cloudflare Workflows REST API returned ${String(a)}: ${i}`,{name:"WorkflowsRestError",status:a})}}const C=e=>{const a=e.fetch??globalThis.fetch.bind(globalThis),i=`${$}/${e.accountId}/workflows`,p=async(r,s)=>{const t=await a(`${i}${r}`,{...s,headers:{Authorization:`Bearer ${e.apiToken}`,"Content-Type":"application/json"}}),o=await t.text();let n;try{n=JSON.parse(o)}catch{throw new g(t.status,o)}if(!t.ok||n.success===!1)throw new g(t.status,o);return n};return{getInstance:async({instanceId:r,workflowName:s})=>{const t=(await p(`/${encodeURIComponent(s)}/instances/${encodeURIComponent(r)}`)).result??{},o=Array.isArray(t.steps)?t.steps:[];return{...m(t),error:t.error,output:t.output,params:t.params,steps:o.map(n=>b(n))}},listInstances:async({page:r,perPage:s,status:t,workflowName:o})=>{const n=new URLSearchParams;t!==void 0&&n.set("status",t),r!==void 0&&n.set("page",String(r)),s!==void 0&&n.set("per_page",String(s));const y=n.toString()===""?"":`?${n.toString()}`,d=await p(`/${encodeURIComponent(o)}/instances${y}`),l=Array.isArray(d.result)?d.result:[],u=d.result_info??{};return{instances:l.map(R=>m(R)),page:typeof u.page=="number"?u.page:r??1,perPage:typeof u.per_page=="number"?u.per_page:s??l.length,totalCount:typeof u.total_count=="number"?u.total_count:void 0}},setInstanceStatus:async({action:r,instanceId:s,workflowName:t})=>{const o=(await p(`/${encodeURIComponent(t)}/instances/${encodeURIComponent(s)}`,{body:JSON.stringify({status:r}),method:"PATCH"})).result??{};return{status:w(o.status)}}}};export{g as WorkflowsRestError,C as createWorkflowsRestClient};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const r="__lunoraBranch",e=a=>typeof a=="object"&&a!==null&&Object.hasOwn(a,r),o=`may not contain the reserved workflow branch-marker key ("${r}")`;export{o as B,r as a,e as h};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{b as p,f as o}from"./run-step-8dSqaby-.mjs";import"@lunora/values";import"./NonRetryableError-hhUGqOs8.mjs";export{p as createRunStep,o as validateStepArgs};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import r from"./createWorkflows-3djec-oS.mjs";const i=(e,c)=>{const o={};for(const n of c){const t=e[n.binding];t&&typeof t.create=="function"&&typeof t.createBatch=="function"&&typeof t.get=="function"&&(o[n.exportName]=t)}return r({bindings:o})};export{i as createWorkflowContext};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{K as f,b as w}from"./run-step-8dSqaby-.mjs";import{LunoraError as v}from"@lunora/errors";import{workflowBindingName as i}from"./defineWorkflow-fBuCDkGT.mjs";import{createSpawn as d,createParallel as u}from"./MAX_BRANCHES-DtgdnoIA.mjs";const m=n=>({debug:(o,...r)=>{console.debug(n,o,...r)},error:(o,...r)=>{console.error(n,o,...r)},info:(o,...r)=>{console.info(n,o,...r)},warn:(o,...r)=>{console.warn(n,o,...r)}}),x=n=>{const o=m(`[workflow:${n.exportName}]`),r=f({env:n.env,fetchImpl:n.fetchImpl,label:"@lunora/workflow"}),c=e=>{const t=i(e),a=n.env[t];if(!a||typeof a.create!="function"||typeof a.get!="function")throw new v("INTERNAL",`@lunora/workflow: cannot spawn child workflow "${e}" — no Workflow binding "${t}" on env (is it declared in lunora/workflows.ts?)`);return a};let l=0;const p=e=>{if(e!==void 0)return e;const t=`${n.event.instanceId}-c${String(l)}`;return l+=1,t},s={env:n.env,instanceId:n.event.instanceId,log:o,nextChildId:p,parentBinding:i(n.exportName),resolveBinding:c,step:n.step};return{env:n.env,event:n.event,log:o,parallel:u(s),params:n.event.payload,run:r,runStep:w({env:n.env,log:o,nonRetryableErrorClass:n.nonRetryableErrorClass,run:r,step:n.step}),spawn:d(s),step:n.step}};export{x as createWorkflowRunContext};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as s}from"@lunora/errors";import{h as w,B as f}from"./branch-marker-B2lebQA6.mjs";const t=o=>{if(w(o?.params))throw new s("BAD_REQUEST",`@lunora/workflow: params ${f}`)},l=o=>({create:async r=>(t(r),o.create(r)),createBatch:async r=>{for(const a of r)t(a);return o.createBatch(r)},get:async r=>o.get(r)}),k=o=>{const r=o.bindings??{};return{get:a=>{const n=r[a];if(n===void 0){const e=Object.keys(r),c=e.length===0?"no workflows are declared":`known workflows: ${e.join(", ")}`;throw new s("INTERNAL",`@lunora/workflow: no workflow named "${a}" (${c})`)}return l(n)}}};export{k as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const o=e=>`${e.charAt(0).toUpperCase()}${e.slice(1)}Workflow`,r=e=>`WORKFLOW_${e.replaceAll(/(?<=[a-z0-9])(?=[A-Z])/g,"_").toUpperCase()}`,n=e=>e.replaceAll(/(?<=[a-z0-9])(?=[A-Z])/g,"-").toLowerCase(),a=e=>{if(typeof e.handler!="function")throw new TypeError("defineWorkflow: `handler` must be a function (the workflow body)");if(e.name!==void 0&&(typeof e.name!="string"||e.name.length===0))throw new TypeError("defineWorkflow: `name` must be a non-empty string when provided");return{...e,isLunoraWorkflow:!0}},t=e=>typeof e=="object"&&e!==null&&e.isLunoraWorkflow===!0;export{a as defineWorkflow,t as isWorkflowDefinition,r as workflowBindingName,o as workflowClassName,n as workflowDefaultName};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as p,isLunoraError as A}from"@lunora/errors";import{parseValidatorMap as O}from"@lunora/values";import{raiseNonRetryable as b,convertNonRetryableError as I}from"./NonRetryableError-hhUGqOs8.mjs";const L=t=>{let e="";for(let r=0;r<t.length;r+=32768)e+=String.fromCharCode(...t.subarray(r,r+32768));return btoa(e)},R=t=>L(t).replaceAll("+","-").replaceAll("/","_").replace(/=+$/,"");new TextDecoder;const $=new TextEncoder,N="=",S=t=>{for(let e=0;e<t.length;e+=1)if(t.charCodeAt(e)>255)return!1;return!0},T=t=>R($.encode(JSON.stringify(t))),_=t=>!t.startsWith(N)&&S(t)?t:`${N}${R($.encode(t))}`,k="/_lunora/scheduler/dispatch",x=3e4,C=t=>{let e=t.length;for(;e>0&&t[e-1]==="/";)e-=1;return t.slice(0,e)},v=Symbol("lunoraDispatchFailure"),w=t=>(Object.defineProperty(t,v,{value:!0}),t),U=(t,e,r)=>{try{const o=JSON.parse(r)?.error;if(typeof o=="object"&&o!==null&&typeof o.code=="string"){const{code:c,data:u,message:s}=o;return w(new p(c,typeof s=="string"?s:void 0,{data:u,status:e}))}}catch{}return w(new p("INTERNAL",`${t}: function dispatch failed (${String(e)}): ${r}`,{status:e}))},J=new Set([400,403,404,422]),D=t=>A(t)&&t[v]===!0&&J.has(t.status),K=(t,e,r)=>new p("INTERNAL",`${t}: function dispatch to "${e}" timed out after ${String(r)}ms`,{status:503}),G=t=>{const{label:e}=t,r=globalThis.fetch,o=t.fetchImpl??(typeof r=="function"?r.bind(globalThis):void 0);return async(c,u,s={})=>{if(typeof o!="function")throw new TypeError(`${e}: no fetch implementation available — pass fetchImpl or run on a platform with global fetch`);const f=t.env.LUNORA_ORIGIN_URL;if(typeof f!="string"||f.length===0)throw new p("INTERNAL",`${e}: \`LUNORA_ORIGIN_URL\` must be set on the Worker env so a handler can call back into Lunora functions`);const h=t.env.LUNORA_ADMIN_TOKEN;if(typeof h!="string"||h.length===0)throw new p("INTERNAL",`${e}: \`LUNORA_ADMIN_TOKEN\` must be set on the Worker env to authenticate function dispatch`);const i=`${C(f)}${k}`,g={authorization:`Bearer ${h}`,"content-type":"application/json"};t.identity?.userId!==void 0&&(g["x-lunora-userid"]=_(t.identity.userId)),t.identity?.claims!==void 0&&(g["x-lunora-identity"]=T(t.identity.claims));const d=s.timeoutMs??x,n=AbortSignal.timeout(d),y=a=>{throw a instanceof Error&&a.name==="TimeoutError"?K(e,c.__lunoraRef,d):a};let l;try{l=await o(i,{body:JSON.stringify({args:u??{},functionPath:c.__lunoraRef,shardKey:s.shardKey}),headers:g,method:"POST",signal:n})}catch(a){return y(a)}if(!l.ok){let a;try{a=await l.text()}catch(E){return y(E)}throw U(e,l.status,a)}let m;try{m=await l.text()}catch(a){return y(a)}if(m.length!==0)try{return JSON.parse(m)}catch{throw new p("INTERNAL",`${e}: function dispatch returned a non-JSON body (${String(l.status)}): ${m}`,{status:l.status})}}},M=(t,e)=>O(t,e,"step args"),z=t=>async(e,r,o)=>{const c=o?.config??e.config,u=M(e.args,r),s=async i=>{const g={attempt:i.attempt,config:i.config,env:t.env,log:t.log,run:t.run,step:i.step};let d;try{d=await e.handler(g,u)}catch(n){return D(n)?b(n.message,n,t.nonRetryableErrorClass):I(n,t.nonRetryableErrorClass)}if(!e.returns)return d;try{return e.returns.parse(d)}catch(n){const y=n instanceof Error?n.message:String(n);return b(`step "${e.name}" returns validation failed: ${y}`,n,t.nonRetryableErrorClass)}},f=e.rollback,h=f?{rollback:async i=>{await f({args:u,env:t.env,error:i.error,log:t.log,output:i.output,run:t.run})},rollbackConfig:e.rollbackConfig}:void 0;return c===void 0?t.step.do(e.name,s,h):t.step.do(e.name,c,s,h)};export{G as K,z as b,M as f};
|