@lunora/platform-node 1.0.0-alpha.108 → 1.0.0-alpha.109
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/index.d.mts +4 -3
- package/dist/index.d.ts +4 -3
- package/dist/index.mjs +1 -1
- package/dist/packem_shared/{createNodePlatform-BJFsyOy5.mjs → createNodePlatform-B6LVGo8q.mjs} +1 -1
- package/dist/packem_shared/createNodeWorkflowHost-DqOqumS8.mjs +1 -0
- package/package.json +7 -7
- package/dist/packem_shared/createNodeWorkflowHost-B5Aiwj3L.mjs +0 -1
package/dist/index.d.mts
CHANGED
|
@@ -352,7 +352,7 @@ declare const createNodeShardRegistry: (options?: NodeShardRegistryOptions) => N
|
|
|
352
352
|
interface NodeWorkflowHostOptions<Workflows extends Record<string, {
|
|
353
353
|
isLunoraWorkflow: true;
|
|
354
354
|
}>> {
|
|
355
|
-
/** Base env merged under the derived
|
|
355
|
+
/** Base env merged under the derived workflow bindings — surfaced to workflow bodies as `ctx.env` and used to resolve spawned children. */
|
|
356
356
|
env?: Record<string, unknown>;
|
|
357
357
|
/** How long (ms) the engine holds a cross-process lease while an activation runs, for stores that implement `acquire`. Defaults to 30000. */
|
|
358
358
|
leaseTtlMs?: number;
|
|
@@ -368,7 +368,8 @@ interface NodeWorkflowHost<Workflows extends Record<string, {
|
|
|
368
368
|
/** Per-export-name `WorkflowBindingLike` — the map `ctx.workflows` consumes. */
|
|
369
369
|
readonly bindings: { [K in keyof Workflows]: WorkflowBindingLike; };
|
|
370
370
|
/**
|
|
371
|
-
* The caller's `env` plus one
|
|
371
|
+
* The caller's `env` plus one binding per workflow under its class name
|
|
372
|
+
* (`OrderPipelineWorkflow`), the key `ctx.exports` would carry on Cloudflare —
|
|
372
373
|
* merge this into a worker env so `ctx.spawn`/`ctx.parallel` resolve
|
|
373
374
|
* children through the same runtime.
|
|
374
375
|
*/
|
|
@@ -378,7 +379,7 @@ interface NodeWorkflowHost<Workflows extends Record<string, {
|
|
|
378
379
|
}
|
|
379
380
|
/**
|
|
380
381
|
* Create a Node workflow host: compile every declared Lunora workflow onto the
|
|
381
|
-
* visulima engine, derive the
|
|
382
|
+
* visulima engine, derive the workflow env, and expose the per-workflow
|
|
382
383
|
* `WorkflowBindingLike` handles.
|
|
383
384
|
*/
|
|
384
385
|
declare const createNodeWorkflowHost: <Workflows extends Record<string, {
|
package/dist/index.d.ts
CHANGED
|
@@ -352,7 +352,7 @@ declare const createNodeShardRegistry: (options?: NodeShardRegistryOptions) => N
|
|
|
352
352
|
interface NodeWorkflowHostOptions<Workflows extends Record<string, {
|
|
353
353
|
isLunoraWorkflow: true;
|
|
354
354
|
}>> {
|
|
355
|
-
/** Base env merged under the derived
|
|
355
|
+
/** Base env merged under the derived workflow bindings — surfaced to workflow bodies as `ctx.env` and used to resolve spawned children. */
|
|
356
356
|
env?: Record<string, unknown>;
|
|
357
357
|
/** How long (ms) the engine holds a cross-process lease while an activation runs, for stores that implement `acquire`. Defaults to 30000. */
|
|
358
358
|
leaseTtlMs?: number;
|
|
@@ -368,7 +368,8 @@ interface NodeWorkflowHost<Workflows extends Record<string, {
|
|
|
368
368
|
/** Per-export-name `WorkflowBindingLike` — the map `ctx.workflows` consumes. */
|
|
369
369
|
readonly bindings: { [K in keyof Workflows]: WorkflowBindingLike; };
|
|
370
370
|
/**
|
|
371
|
-
* The caller's `env` plus one
|
|
371
|
+
* The caller's `env` plus one binding per workflow under its class name
|
|
372
|
+
* (`OrderPipelineWorkflow`), the key `ctx.exports` would carry on Cloudflare —
|
|
372
373
|
* merge this into a worker env so `ctx.spawn`/`ctx.parallel` resolve
|
|
373
374
|
* children through the same runtime.
|
|
374
375
|
*/
|
|
@@ -378,7 +379,7 @@ interface NodeWorkflowHost<Workflows extends Record<string, {
|
|
|
378
379
|
}
|
|
379
380
|
/**
|
|
380
381
|
* Create a Node workflow host: compile every declared Lunora workflow onto the
|
|
381
|
-
* visulima engine, derive the
|
|
382
|
+
* visulima engine, derive the workflow env, and expose the per-workflow
|
|
382
383
|
* `WorkflowBindingLike` handles.
|
|
383
384
|
*/
|
|
384
385
|
declare const createNodeWorkflowHost: <Workflows extends Record<string, {
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createNodeGlobalStore as r,createNodeSqlExec as t}from"./packem_shared/createNodeGlobalStore-DiGxjmD7.mjs";import{createNodeShardKvStore as d}from"./packem_shared/createNodeShardKvStore-DVi1OsvH.mjs";import{createNodePlatform as f}from"./packem_shared/createNodePlatform-
|
|
1
|
+
import{createNodeGlobalStore as r,createNodeSqlExec as t}from"./packem_shared/createNodeGlobalStore-DiGxjmD7.mjs";import{createNodeShardKvStore as d}from"./packem_shared/createNodeShardKvStore-DVi1OsvH.mjs";import{createNodePlatform as f}from"./packem_shared/createNodePlatform-B6LVGo8q.mjs";import{createNodeQueueHost as x}from"./packem_shared/createNodeQueueHost-CttDb5sY.mjs";import{createNodeR2Bucket as p}from"./packem_shared/createNodeR2Bucket-CajTvuOy.mjs";import{createNodeSchedulerHost as l}from"./packem_shared/createNodeSchedulerHost-BEAX6I4m.mjs";import{createNodeShardHost as h}from"./packem_shared/createNodeShardHost-Da19DFX0.mjs";import{createNodeShardRegistry as k}from"./packem_shared/createNodeShardRegistry-D-KxwdUc.mjs";import{createNodeShardState as w}from"./packem_shared/createNodeShardState-D6XMWbFs.mjs";import{createNodeSocketHost as W}from"./packem_shared/createNodeSocketHost-DQs85G7W.mjs";import{createNodeWorkflowHost as g}from"./packem_shared/createNodeWorkflowHost-DqOqumS8.mjs";import{createNodeWorkflowStore as q}from"./packem_shared/createNodeWorkflowStore-CL7RYP6H.mjs";export{r as createNodeGlobalStore,f as createNodePlatform,x as createNodeQueueHost,p as createNodeR2Bucket,l as createNodeSchedulerHost,h as createNodeShardHost,d as createNodeShardKvStore,k as createNodeShardRegistry,w as createNodeShardState,W as createNodeSocketHost,t as createNodeSqlExec,g as createNodeWorkflowHost,q as createNodeWorkflowStore};
|
package/dist/packem_shared/{createNodePlatform-BJFsyOy5.mjs → createNodePlatform-B6LVGo8q.mjs}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{LunoraError as S}from"@lunora/errors";import{NODE_CAPABILITIES as b}from"@lunora/platform";import{createNodeGlobalStore as N}from"./createNodeGlobalStore-DiGxjmD7.mjs";import{createNodeShardKvStore as k}from"./createNodeShardKvStore-DVi1OsvH.mjs";import{createNodeQueueHost as g}from"./createNodeQueueHost-CttDb5sY.mjs";import{createNodeR2Bucket as y}from"./createNodeR2Bucket-CajTvuOy.mjs";import{createNodeSchedulerHost as R}from"./createNodeSchedulerHost-BEAX6I4m.mjs";import{createNodeShardHost as q}from"./createNodeShardHost-Da19DFX0.mjs";import{createNodeShardRegistry as B}from"./createNodeShardRegistry-D-KxwdUc.mjs";import{createNodeSocketHost as H}from"./createNodeSocketHost-DQs85G7W.mjs";import{createNodeWorkflowHost as I}from"./createNodeWorkflowHost-
|
|
1
|
+
import{LunoraError as S}from"@lunora/errors";import{NODE_CAPABILITIES as b}from"@lunora/platform";import{createNodeGlobalStore as N}from"./createNodeGlobalStore-DiGxjmD7.mjs";import{createNodeShardKvStore as k}from"./createNodeShardKvStore-DVi1OsvH.mjs";import{createNodeQueueHost as g}from"./createNodeQueueHost-CttDb5sY.mjs";import{createNodeR2Bucket as y}from"./createNodeR2Bucket-CajTvuOy.mjs";import{createNodeSchedulerHost as R}from"./createNodeSchedulerHost-BEAX6I4m.mjs";import{createNodeShardHost as q}from"./createNodeShardHost-Da19DFX0.mjs";import{createNodeShardRegistry as B}from"./createNodeShardRegistry-D-KxwdUc.mjs";import{createNodeSocketHost as H}from"./createNodeSocketHost-DQs85G7W.mjs";import{createNodeWorkflowHost as I}from"./createNodeWorkflowHost-DqOqumS8.mjs";import{createNodeWorkflowStore as P}from"./createNodeWorkflowStore-CL7RYP6H.mjs";const G=(o={})=>{const e=[],{database:r,dispose:d,drain:u,host:i}=q(o);e.push(d);try{const s=k(r),t=B(o);e.push(()=>{t.close()});const{directory:l}=t,{socket:h}=H(r),{dispose:m,scheduler:f}=R(r,o);e.push(m);const n=o.queues===void 0?void 0:g(r,{onBatch:o.onQueueBatch??(()=>{throw new S("VALIDATION_ERROR","@lunora/platform-node: createNodePlatform was given `queues` without `onQueueBatch`, so a delivered batch has nowhere to go — pass dispatchQueueBatch from @lunora/queue")}),queues:o.queues}),p=o.objectStorageDirectory===void 0?void 0:y({directory:o.objectStorageDirectory}),a=o.globalTablesPath===void 0?void 0:N({path:o.globalTablesPath});a!==void 0&&e.push(()=>{a.dispose()});const w=o.workflows===void 0?void 0:I({store:P(r),workflows:o.workflows}),c=()=>{for(const v of e.toReversed())v()};return{capabilities:b,close:c,directory:l,drain:u,globalTables:a,kv:s,objectStorage:p,queues:n,scheduler:f,shard:i,sockets:h,workflows:w,[Symbol.dispose]:c}}catch(s){for(const t of e.toReversed())try{t()}catch{}throw s}};export{G as createNodePlatform};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{LunoraError as d}from"@lunora/errors";import{isWorkflowDefinition as _,workflowDefaultName as b,createWorkflowRunContext as M,workflowClassName as $}from"@lunora/workflow";import{defineWorkflow as O,createRuntime as L}from"@visulima/workflow";const A="@lunora/platform-node:terminated",D=100,S={d:864e5,day:864e5,days:864e5,h:36e5,hour:36e5,hours:36e5,m:6e4,millisecond:1,milliseconds:1,minute:6e4,minutes:6e4,ms:1,s:1e3,second:1e3,seconds:1e3,w:6048e5,week:6048e5,weeks:6048e5,month:2592e6,months:2592e6},x=/^(\d+(?:\.\d+)?)\s*([a-z]+)$/i,T=o=>{if(typeof o=="number"){if(!Number.isFinite(o))throw new d("VALIDATION_ERROR",`@lunora/platform-node: workflow duration must be finite, got ${String(o)}`);return Math.max(0,o)}const c=x.exec(o.trim());if(c===null)throw new d("VALIDATION_ERROR",`@lunora/platform-node: unsupported workflow duration "${o}"`);const n=Number(c[1]),r=(c[2]??"").toLowerCase(),s=S[r];if(s===void 0)throw new d("VALIDATION_ERROR",`@lunora/platform-node: unsupported workflow duration "${o}"`);const l=n*s;if(!Number.isFinite(l))throw new d("VALIDATION_ERROR",`@lunora/platform-node: workflow duration "${o}" overflows`);return Math.max(0,l)},g="@lunora/platform-node:alias",k=o=>`@lunora/platform-node:alias-of:${o}`,N=(o,c,n)=>({attempt:c,config:n,step:{count:1,name:o}}),F={retries:{limit:1}},P=2147483647,U=async o=>new Promise(c=>{setTimeout(c,Math.min(o,P))}),V=(o,c,n)=>{switch(c){case"exponential":return o*2**(n-1);case"linear":return o*n;default:return o}},B=async(o,c,n,r,s)=>{const l=o.retries?.delay;return typeof l=="function"?T(await l({ctx:r,error:s instanceof Error?s:new Error(String(s))})):V(c,o.retries?.backoff,n)},W=async(o,c)=>{const n=c instanceof Error?c:new Error(String(c));for(const r of o.splice(0).toSorted((s,l)=>l.order-s.order))try{await r.handler({ctx:r.context,error:n,output:r.output,stepName:r.name})}catch{}},q=o=>{switch(o){case"completed":return"complete";case"failed":return"errored";default:return"waiting"}},j=o=>{const c=[];let n=0;return{do:async(r,s,l,I)=>{const f=n;n+=1;const v=typeof s!="function",h=v?l:s,y=v?I:l;if(typeof h!="function")throw new d("VALIDATION_ERROR",`@lunora/platform-node: step.do("${r}") requires a callback`);const p=v?s:F,E=p.retries?.limit??1;if(!Number.isFinite(E))throw new d("VALIDATION_ERROR",`@lunora/platform-node: step.do("${r}") retries.limit must be a finite number, got ${String(E)}`);const e=Math.max(1,Math.trunc(E)),t=p.retries?.delay,a=t===void 0||typeof t=="function"?0:T(t);let i=N(r,1,p);try{const u=await o.step(r,async()=>{for(let w=1;;w+=1){i=N(r,w,p);try{return await h(i)}catch(m){if(w>=e)throw m;const R=await B(p,a,w,i,m);R>0&&await U(R)}}});return y?.rollback!==void 0&&c.push({context:i,handler:y.rollback,name:r,order:f,output:u}),u}catch(u){throw y?.rollback!==void 0&&c.push({context:i,handler:y.rollback,name:r,order:f,output:void 0}),await W(c,u),u}},sleep:async(r,s)=>{const l=T(s);l!==0&&await o.sleep(r,l)},sleepUntil:async(r,s)=>{const l=typeof s=="number"?s:s.getTime();if(!Number.isFinite(l))throw new d("VALIDATION_ERROR",`@lunora/platform-node: step.sleepUntil("${r}") needs a valid timestamp`);const I=Math.max(0,l-Date.now());I!==0&&await o.sleep(r,I)},waitForEvent:(async(r,s)=>({payload:await o.waitForEvent(r,s.type,{timeout:s.timeout===void 0?void 0:T(s.timeout)}),type:s.type}))}},X=o=>{const c=Object.entries(o.workflows).map(([e,t])=>{if(!_(t))throw new d("VALIDATION_ERROR",`@lunora/platform-node: "${e}" is not a defineWorkflow result`);return{definition:t,exportName:e,id:t.name??b(e)}}),{store:n}=o,r={...o.env},s=c.map(({definition:e,exportName:t,id:a})=>O({id:a,tags:[t],run:async i=>{const u=j(i),w=M({env:r,event:{instanceId:i.runId,payload:i.payload,timestamp:new Date,workflowName:a},exportName:t,step:u});return await e.handler(w)}})),l=new Set,I={acquire:n.acquire===void 0?void 0:async(e,t,a)=>n.acquire?.(e,t,a)??!1,delete:async e=>n.delete(e),due:async(e,t)=>n.due(e,t),load:async e=>{const t=await n.load(e);return t===void 0||t.definitionId===A||t.definitionId===g?void 0:t},release:n.release===void 0?void 0:async(e,t)=>n.release?.(e,t),save:async e=>{l.has(e.runId)||await n.save(e)}},f=L({leaseTtlMs:o.leaseTtlMs,store:I,workflows:s}),v=async e=>{const t=await n.load(e);if(t===void 0||t.definitionId===g)return!1;l.add(e),await n.delete(e);const a=await n.load(k(e));return a!==void 0&&(await n.delete(a.snapshot),await n.delete(k(e))),!0},h=e=>({delete:async()=>{await v(e)},id:e,pause:()=>Promise.reject(new d("NOT_IMPLEMENTED",`@lunora/platform-node: workflow instance "${e}" cannot be paused — the visulima engine has no pause equivalent`)),restart:()=>Promise.reject(new d("NOT_IMPLEMENTED",`@lunora/platform-node: workflow instance "${e}" cannot be restarted — the visulima engine has no restart equivalent`)),resume:async()=>{if((await n.load(e))?.definitionId===A)throw new d("BAD_REQUEST",`@lunora/platform-node: workflow instance "${e}" was terminated and cannot be resumed`);await f.resume(e)},sendEvent:async t=>{const a=await f.getRun(e);if(a?.status!=="waiting"||a.pending?.kind!=="event"||a.pending.eventName!==t.type)throw new d("BAD_REQUEST",`@lunora/platform-node: workflow instance "${e}" is not waiting for event "${t.type}"`);await f.signal(e,t.type,t.payload)},subscribe:()=>Promise.reject(new d("NOT_IMPLEMENTED",`@lunora/platform-node: workflow instance "${e}" cannot be subscribed to — the visulima engine keeps no per-instance event log to replay`)),status:async()=>{const t=await n.load(e);if(t===void 0)return{status:"unknown"};if(t.definitionId===A)return{status:"terminated"};const a=await f.getRun(e);return a===void 0?{status:"unknown"}:{error:a.error===void 0?void 0:{message:a.error.message,name:a.error.name},output:a.output,status:q(a.status)}},terminate:async()=>{await n.load(e)!==void 0&&(l.add(e),await n.delete(e),await n.save({definitionId:A,runId:e,snapshot:void 0,status:"failed",updatedAt:Date.now()}))}}),y=async e=>{const t=await n.load(e);return t?.definitionId===g?t.snapshot:e},p=async(e,t)=>{if(t?.id===void 0){const u=await f.trigger(e,t?.params);return h(u.runId)}const a=await n.load(t.id);if(a?.definitionId===g)return h(a.snapshot);if(a!==void 0)throw new d("BAD_REQUEST",`@lunora/platform-node: workflow create({ id: "${t.id}" }) names an existing run — pass the id a previous create returned, or a fresh one`);const i=await f.trigger(e,t.params);return await n.save({definitionId:g,runId:t.id,snapshot:i.runId,status:"failed",updatedAt:Date.now()}),await n.save({definitionId:g,runId:k(i.runId),snapshot:t.id,status:"failed",updatedAt:Date.now()}),h(i.runId)},E={};for(const{exportName:e,id:t}of c){const a={create:async i=>p(t,i),createBatch:async i=>{const u=[];for(const w of i)u.push(await p(t,w));return u},deleteBatch:async i=>{if(i.length>D)throw new d("VALIDATION_ERROR",`@lunora/platform-node: deleteBatch takes at most ${String(D)} instance ids, got ${String(i.length)}`);const u={deleted:[],errors:[]},w=new Map;for(const m of i){const R=w.get(m)??await v(await y(m));w.set(m,R),R?u.deleted.push({id:m}):u.errors.push({code:404,id:m,message:`workflow instance "${m}" not found`})}return u},get:async i=>h(await y(i))};E[e]=a,r[$(e)]=a}return{bindings:E,env:r,runtime:f}};export{X as createNodeWorkflowHost};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lunora/platform-node",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.109",
|
|
4
4
|
"description": "Node implementation of the Lunora platform contracts: ShardHost, SocketHost, ShardDirectory, ShardKvStore, SchedulerHost over better-sqlite3 and an in-process socket registry (dev/test target)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"better-sqlite3",
|
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
"access": "public"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@lunora/d1": "1.0.0-alpha.
|
|
50
|
-
"@lunora/errors": "1.0.0-alpha.
|
|
51
|
-
"@lunora/platform": "1.0.0-alpha.
|
|
52
|
-
"@lunora/queue": "1.0.0-alpha.
|
|
53
|
-
"@lunora/sql-store": "1.0.0-alpha.
|
|
54
|
-
"@lunora/workflow": "1.0.0-alpha.
|
|
49
|
+
"@lunora/d1": "1.0.0-alpha.154",
|
|
50
|
+
"@lunora/errors": "1.0.0-alpha.48",
|
|
51
|
+
"@lunora/platform": "1.0.0-alpha.46",
|
|
52
|
+
"@lunora/queue": "1.0.0-alpha.81",
|
|
53
|
+
"@lunora/sql-store": "1.0.0-alpha.155",
|
|
54
|
+
"@lunora/workflow": "1.0.0-alpha.69",
|
|
55
55
|
"@visulima/workflow": "3.0.0",
|
|
56
56
|
"better-sqlite3": "^13.0.3",
|
|
57
57
|
"cron-parser": "5.10.0"
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{LunoraError as l}from"@lunora/errors";import{isWorkflowDefinition as N,workflowDefaultName as T,createWorkflowRunContext as D,workflowBindingName as _}from"@lunora/workflow";import{defineWorkflow as b,createRuntime as M}from"@visulima/workflow";const v="@lunora/platform-node:terminated",O={d:864e5,day:864e5,days:864e5,h:36e5,hour:36e5,hours:36e5,m:6e4,millisecond:1,milliseconds:1,minute:6e4,minutes:6e4,ms:1,s:1e3,second:1e3,seconds:1e3,w:6048e5,week:6048e5,weeks:6048e5,month:2592e6,months:2592e6},$=/^(\d+(?:\.\d+)?)\s*([a-z]+)$/i,E=n=>{if(typeof n=="number"){if(!Number.isFinite(n))throw new l("VALIDATION_ERROR",`@lunora/platform-node: workflow duration must be finite, got ${String(n)}`);return Math.max(0,n)}const i=$.exec(n.trim());if(i===null)throw new l("VALIDATION_ERROR",`@lunora/platform-node: unsupported workflow duration "${n}"`);const o=Number(i[1]),r=(i[2]??"").toLowerCase(),s=O[r];if(s===void 0)throw new l("VALIDATION_ERROR",`@lunora/platform-node: unsupported workflow duration "${n}"`);const c=o*s;if(!Number.isFinite(c))throw new l("VALIDATION_ERROR",`@lunora/platform-node: workflow duration "${n}" overflows`);return Math.max(0,c)},R="@lunora/platform-node:alias",A=(n,i,o)=>({attempt:i,config:o,step:{count:1,name:n}}),L={retries:{limit:1}},S=2147483647,F=async n=>new Promise(i=>{setTimeout(i,Math.min(n,S))}),x=(n,i,o)=>{switch(i){case"exponential":return n*2**(o-1);case"linear":return n*o;default:return n}},U=async(n,i)=>{const o=i instanceof Error?i:new Error(String(i));for(const r of n.splice(0).toSorted((s,c)=>c.order-s.order))try{await r.handler({ctx:r.context,error:o,output:r.output,stepName:r.name})}catch{}},V=n=>{switch(n){case"completed":return"complete";case"failed":return"errored";default:return"waiting"}},P=n=>{const i=[];let o=0;return{do:async(r,s,c,y)=>{const w=o;o+=1;const m=typeof s!="function",I=m?c:s,h=m?y:c;if(typeof I!="function")throw new l("VALIDATION_ERROR",`@lunora/platform-node: step.do("${r}") requires a callback`);const f=m?s:L,t=f.retries?.limit??1;if(!Number.isFinite(t))throw new l("VALIDATION_ERROR",`@lunora/platform-node: step.do("${r}") retries.limit must be a finite number, got ${String(t)}`);const e=Math.max(1,Math.trunc(t)),a=f.retries?.delay===void 0?0:E(f.retries.delay);let u=A(r,1,f);try{const d=await n.step(r,async()=>{for(let p=1;;p+=1){u=A(r,p,f);try{return await I(u)}catch(k){if(p>=e)throw k;const g=x(a,f.retries?.backoff,p);g>0&&await F(g)}}});return h?.rollback!==void 0&&i.push({context:u,handler:h.rollback,name:r,order:w,output:d}),d}catch(d){throw h?.rollback!==void 0&&i.push({context:u,handler:h.rollback,name:r,order:w,output:void 0}),await U(i,d),d}},sleep:async(r,s)=>{const c=E(s);c!==0&&await n.sleep(r,c)},sleepUntil:async(r,s)=>{const c=typeof s=="number"?s:s.getTime();if(!Number.isFinite(c))throw new l("VALIDATION_ERROR",`@lunora/platform-node: step.sleepUntil("${r}") needs a valid timestamp`);const y=Math.max(0,c-Date.now());y!==0&&await n.sleep(r,y)},waitForEvent:(async(r,s)=>({payload:await n.waitForEvent(r,s.type,{timeout:s.timeout===void 0?void 0:E(s.timeout)}),type:s.type}))}},j=n=>{const i=Object.entries(n.workflows).map(([t,e])=>{if(!N(e))throw new l("VALIDATION_ERROR",`@lunora/platform-node: "${t}" is not a defineWorkflow result`);return{definition:e,exportName:t,id:e.name??T(t)}}),{store:o}=n,r={...n.env},s=i.map(({definition:t,exportName:e,id:a})=>b({id:a,tags:[e],run:async u=>{const d=P(u),p=D({env:r,event:{instanceId:u.runId,payload:u.payload,timestamp:new Date,workflowName:a},exportName:e,step:d});return await t.handler(p)}})),c=new Set,y={acquire:o.acquire===void 0?void 0:async(t,e,a)=>o.acquire?.(t,e,a)??!1,delete:async t=>o.delete(t),due:async(t,e)=>o.due(t,e),load:async t=>{const e=await o.load(t);return e===void 0||e.definitionId===v||e.definitionId===R?void 0:e},release:o.release===void 0?void 0:async(t,e)=>o.release?.(t,e),save:async t=>{c.has(t.runId)||await o.save(t)}},w=M({leaseTtlMs:n.leaseTtlMs,store:y,workflows:s}),m=t=>({id:t,pause:()=>Promise.reject(new l("NOT_IMPLEMENTED",`@lunora/platform-node: workflow instance "${t}" cannot be paused — the visulima engine has no pause equivalent`)),restart:()=>Promise.reject(new l("NOT_IMPLEMENTED",`@lunora/platform-node: workflow instance "${t}" cannot be restarted — the visulima engine has no restart equivalent`)),resume:async()=>{if((await o.load(t))?.definitionId===v)throw new l("BAD_REQUEST",`@lunora/platform-node: workflow instance "${t}" was terminated and cannot be resumed`);await w.resume(t)},sendEvent:async e=>{const a=await w.getRun(t);if(a?.status!=="waiting"||a.pending?.kind!=="event"||a.pending.eventName!==e.type)throw new l("BAD_REQUEST",`@lunora/platform-node: workflow instance "${t}" is not waiting for event "${e.type}"`);await w.signal(t,e.type,e.payload)},status:async()=>{const e=await o.load(t);if(e===void 0)return{status:"unknown"};if(e.definitionId===v)return{status:"terminated"};const a=await w.getRun(t);return a===void 0?{status:"unknown"}:{error:a.error===void 0?void 0:{message:a.error.message,name:a.error.name},output:a.output,status:V(a.status)}},terminate:async()=>{await o.load(t)!==void 0&&(c.add(t),await o.delete(t),await o.save({definitionId:v,runId:t,snapshot:void 0,status:"failed",updatedAt:Date.now()}))}}),I=async t=>{const e=await o.load(t);return e?.definitionId===R?e.snapshot:t},h=async(t,e)=>{if(e?.id===void 0){const d=await w.trigger(t,e?.params);return m(d.runId)}const a=await o.load(e.id);if(a?.definitionId===R)return m(a.snapshot);if(a!==void 0)throw new l("BAD_REQUEST",`@lunora/platform-node: workflow create({ id: "${e.id}" }) names an existing run — pass the id a previous create returned, or a fresh one`);const u=await w.trigger(t,e.params);return await o.save({definitionId:R,runId:e.id,snapshot:u.runId,status:"failed",updatedAt:Date.now()}),m(u.runId)},f={};for(const{exportName:t,id:e}of i){const a={create:async u=>h(e,u),createBatch:async u=>{const d=[];for(const p of u)d.push(await h(e,p));return d},get:async u=>m(await I(u))};f[t]=a,r[_(t)]=a}return{bindings:f,env:r,runtime:w}};export{j as createNodeWorkflowHost};
|