@rytejs/core 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/executor/index.cjs +5 -1
- package/dist/executor/index.cjs.map +1 -1
- package/dist/executor/index.d.cts +1 -1
- package/dist/executor/index.d.ts +1 -1
- package/dist/executor/index.js +5 -1
- package/dist/executor/index.js.map +1 -1
- package/dist/index.cjs +28 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +28 -13
- package/dist/index.js.map +1 -1
- package/dist/{plugin-CIVHyBaZ.d.ts → plugin-ByX9Eoe-.d.ts} +22 -14
- package/dist/{plugin-CQUbAdxj.d.cts → plugin-CGikcWDu.d.cts} +22 -14
- package/dist/reactor/index.d.cts +1 -1
- package/dist/reactor/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/executor/index.cjs
CHANGED
|
@@ -166,7 +166,11 @@ var WorkflowExecutor = class {
|
|
|
166
166
|
};
|
|
167
167
|
return;
|
|
168
168
|
}
|
|
169
|
-
const dispatchResult = await router.dispatch(
|
|
169
|
+
const dispatchResult = await router.dispatch(
|
|
170
|
+
restoreResult.workflow,
|
|
171
|
+
ctx.command.type,
|
|
172
|
+
ctx.command.payload
|
|
173
|
+
);
|
|
170
174
|
ctx.result = dispatchResult;
|
|
171
175
|
if (dispatchResult.ok) {
|
|
172
176
|
ctx.snapshot = definition.serialize(dispatchResult.workflow);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/executor/index.ts","../../src/compose.ts","../../src/store/errors.ts","../../src/executor/executor.ts"],"sourcesContent":["export { WorkflowExecutor } from \"./executor.js\";\nexport type {\n\tExecutionResult,\n\tExecutorContext,\n\tExecutorError,\n\tExecutorMiddleware,\n} from \"./types.js\";\n","type Middleware<TCtx> = (ctx: TCtx, next: () => Promise<void>) => Promise<void>;\n\n/** Composes an array of middleware into a single function (Koa-style onion model). */\nexport function compose<TCtx>(middleware: Middleware<TCtx>[]): (ctx: TCtx) => Promise<void> {\n\treturn async (ctx: TCtx) => {\n\t\tlet index = -1;\n\t\tasync function dispatch(i: number): Promise<void> {\n\t\t\tif (i <= index) throw new Error(\"next() called multiple times\");\n\t\t\tindex = i;\n\t\t\tconst fn = middleware[i];\n\t\t\tif (!fn) return;\n\t\t\tawait fn(ctx, () => dispatch(i + 1));\n\t\t}\n\t\tawait dispatch(0);\n\t};\n}\n","export class ConcurrencyConflictError extends Error {\n\treadonly name = \"ConcurrencyConflictError\";\n\n\tconstructor(\n\t\treadonly workflowId: string,\n\t\treadonly expectedVersion: number,\n\t\treadonly actualVersion: number,\n\t) {\n\t\tsuper(\n\t\t\t`Concurrency conflict for workflow \"${workflowId}\": expected version ${expectedVersion}, actual ${actualVersion}`,\n\t\t);\n\t}\n}\n","import { compose } from \"../compose.js\";\nimport type { WorkflowRouter } from \"../router.js\";\nimport type { WorkflowSnapshot } from \"../snapshot.js\";\nimport { ConcurrencyConflictError } from \"../store/errors.js\";\nimport type { StoreAdapter } from \"../store/types.js\";\nimport type { WorkflowConfig } from \"../types.js\";\nimport type { ExecutionResult, ExecutorContext, ExecutorMiddleware } from \"./types.js\";\n\nexport class WorkflowExecutor<TConfig extends WorkflowConfig> {\n\tprivate readonly middleware: ExecutorMiddleware[] = [];\n\n\tconstructor(\n\t\tpublic readonly router: WorkflowRouter<TConfig>,\n\t\tprivate readonly store: StoreAdapter,\n\t) {}\n\n\tuse(middleware: ExecutorMiddleware): this {\n\t\tthis.middleware.push(middleware);\n\t\treturn this;\n\t}\n\n\tasync execute(\n\t\tid: string,\n\t\tcommand: { type: string; payload: unknown },\n\t\toptions?: { expectedVersion?: number },\n\t): Promise<ExecutionResult> {\n\t\t// 1. Load\n\t\tconst stored = await this.store.load(id);\n\t\tif (!stored) {\n\t\t\treturn { ok: false, error: { category: \"not_found\", id } };\n\t\t}\n\n\t\t// 2. Optimistic version check\n\t\tif (options?.expectedVersion !== undefined && options.expectedVersion !== stored.version) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\tid,\n\t\t\t\t\texpectedVersion: options.expectedVersion,\n\t\t\t\t\tactualVersion: stored.version,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 3. Build context\n\t\tconst ctx: ExecutorContext = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tstored,\n\t\t\tresult: null,\n\t\t\tsnapshot: null,\n\t\t\tevents: [],\n\t\t};\n\n\t\t// 4. Run pipeline\n\t\ttry {\n\t\t\tconst chain = [...this.middleware, this.dispatchHandler()];\n\t\t\tawait compose(chain)(ctx);\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\terror: err,\n\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 5. Save if dispatch succeeded\n\t\tif (ctx.snapshot) {\n\t\t\tconst newVersion = stored.version + 1;\n\t\t\tconst savedSnapshot = { ...ctx.snapshot, version: newVersion };\n\n\t\t\ttry {\n\t\t\t\tawait this.store.save({\n\t\t\t\t\tid,\n\t\t\t\t\tsnapshot: ctx.snapshot,\n\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\tevents: ctx.events,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof ConcurrencyConflictError) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\t\t\tactualVersion: err.actualVersion,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\t\terror: err,\n\t\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tsnapshot: savedSnapshot,\n\t\t\t\tversion: newVersion,\n\t\t\t\tevents: ctx.events,\n\t\t\t};\n\t\t}\n\n\t\t// 6. Dispatch failed — return the error\n\t\tif (ctx.result && !ctx.result.ok) {\n\t\t\treturn { ok: false, error: ctx.result.error };\n\t\t}\n\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: {\n\t\t\t\tcategory: \"unexpected\",\n\t\t\t\terror: new Error(\"Pipeline completed without setting snapshot or error\"),\n\t\t\t\tmessage: \"Pipeline completed without setting snapshot or error\",\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate dispatchHandler(): ExecutorMiddleware {\n\t\tconst definition = this.router.definition;\n\t\tconst router = this.router;\n\n\t\treturn async (ctx, _next) => {\n\t\t\tconst restoreResult = definition.deserialize(ctx.stored.snapshot);\n\t\t\tif (!restoreResult.ok) {\n\t\t\t\tctx.result = {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"restore\" as const,\n\t\t\t\t\t\tid: ctx.id,\n\t\t\t\t\t\tissues: restoreResult.error.issues,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// as never: type erasure — executor holds WorkflowConfig base type,\n\t\t\t// but dispatch validates commands against Zod schemas at runtime\n\t\t\tconst dispatchResult = await router.dispatch(
|
|
1
|
+
{"version":3,"sources":["../../src/executor/index.ts","../../src/compose.ts","../../src/store/errors.ts","../../src/executor/executor.ts"],"sourcesContent":["export { WorkflowExecutor } from \"./executor.js\";\nexport type {\n\tExecutionResult,\n\tExecutorContext,\n\tExecutorError,\n\tExecutorMiddleware,\n} from \"./types.js\";\n","type Middleware<TCtx> = (ctx: TCtx, next: () => Promise<void>) => Promise<void>;\n\n/** Composes an array of middleware into a single function (Koa-style onion model). */\nexport function compose<TCtx>(middleware: Middleware<TCtx>[]): (ctx: TCtx) => Promise<void> {\n\treturn async (ctx: TCtx) => {\n\t\tlet index = -1;\n\t\tasync function dispatch(i: number): Promise<void> {\n\t\t\tif (i <= index) throw new Error(\"next() called multiple times\");\n\t\t\tindex = i;\n\t\t\tconst fn = middleware[i];\n\t\t\tif (!fn) return;\n\t\t\tawait fn(ctx, () => dispatch(i + 1));\n\t\t}\n\t\tawait dispatch(0);\n\t};\n}\n","export class ConcurrencyConflictError extends Error {\n\treadonly name = \"ConcurrencyConflictError\";\n\n\tconstructor(\n\t\treadonly workflowId: string,\n\t\treadonly expectedVersion: number,\n\t\treadonly actualVersion: number,\n\t) {\n\t\tsuper(\n\t\t\t`Concurrency conflict for workflow \"${workflowId}\": expected version ${expectedVersion}, actual ${actualVersion}`,\n\t\t);\n\t}\n}\n","import { compose } from \"../compose.js\";\nimport type { WorkflowRouter } from \"../router.js\";\nimport type { WorkflowSnapshot } from \"../snapshot.js\";\nimport { ConcurrencyConflictError } from \"../store/errors.js\";\nimport type { StoreAdapter } from \"../store/types.js\";\nimport type { WorkflowConfig } from \"../types.js\";\nimport type { ExecutionResult, ExecutorContext, ExecutorMiddleware } from \"./types.js\";\n\nexport class WorkflowExecutor<TConfig extends WorkflowConfig> {\n\tprivate readonly middleware: ExecutorMiddleware[] = [];\n\n\tconstructor(\n\t\tpublic readonly router: WorkflowRouter<TConfig>,\n\t\tprivate readonly store: StoreAdapter,\n\t) {}\n\n\tuse(middleware: ExecutorMiddleware): this {\n\t\tthis.middleware.push(middleware);\n\t\treturn this;\n\t}\n\n\tasync execute(\n\t\tid: string,\n\t\tcommand: { type: string; payload: unknown },\n\t\toptions?: { expectedVersion?: number },\n\t): Promise<ExecutionResult> {\n\t\t// 1. Load\n\t\tconst stored = await this.store.load(id);\n\t\tif (!stored) {\n\t\t\treturn { ok: false, error: { category: \"not_found\", id } };\n\t\t}\n\n\t\t// 2. Optimistic version check\n\t\tif (options?.expectedVersion !== undefined && options.expectedVersion !== stored.version) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\tid,\n\t\t\t\t\texpectedVersion: options.expectedVersion,\n\t\t\t\t\tactualVersion: stored.version,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 3. Build context\n\t\tconst ctx: ExecutorContext = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tstored,\n\t\t\tresult: null,\n\t\t\tsnapshot: null,\n\t\t\tevents: [],\n\t\t};\n\n\t\t// 4. Run pipeline\n\t\ttry {\n\t\t\tconst chain = [...this.middleware, this.dispatchHandler()];\n\t\t\tawait compose(chain)(ctx);\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\terror: err,\n\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 5. Save if dispatch succeeded\n\t\tif (ctx.snapshot) {\n\t\t\tconst newVersion = stored.version + 1;\n\t\t\tconst savedSnapshot = { ...ctx.snapshot, version: newVersion };\n\n\t\t\ttry {\n\t\t\t\tawait this.store.save({\n\t\t\t\t\tid,\n\t\t\t\t\tsnapshot: ctx.snapshot,\n\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\tevents: ctx.events,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof ConcurrencyConflictError) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\t\t\tactualVersion: err.actualVersion,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\t\terror: err,\n\t\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tsnapshot: savedSnapshot,\n\t\t\t\tversion: newVersion,\n\t\t\t\tevents: ctx.events,\n\t\t\t};\n\t\t}\n\n\t\t// 6. Dispatch failed — return the error\n\t\tif (ctx.result && !ctx.result.ok) {\n\t\t\treturn { ok: false, error: ctx.result.error };\n\t\t}\n\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: {\n\t\t\t\tcategory: \"unexpected\",\n\t\t\t\terror: new Error(\"Pipeline completed without setting snapshot or error\"),\n\t\t\t\tmessage: \"Pipeline completed without setting snapshot or error\",\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate dispatchHandler(): ExecutorMiddleware {\n\t\tconst definition = this.router.definition;\n\t\tconst router = this.router;\n\n\t\treturn async (ctx, _next) => {\n\t\t\tconst restoreResult = definition.deserialize(ctx.stored.snapshot);\n\t\t\tif (!restoreResult.ok) {\n\t\t\t\tctx.result = {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"restore\" as const,\n\t\t\t\t\t\tid: ctx.id,\n\t\t\t\t\t\tissues: restoreResult.error.issues,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// as never: type erasure — executor holds WorkflowConfig base type,\n\t\t\t// but dispatch validates commands against Zod schemas at runtime\n\t\t\tconst dispatchResult = await router.dispatch(\n\t\t\t\trestoreResult.workflow,\n\t\t\t\tctx.command.type as never,\n\t\t\t\tctx.command.payload as never,\n\t\t\t);\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — DispatchResult<TConfig> assigned to DispatchResult<WorkflowConfig>\n\t\t\tctx.result = dispatchResult as any;\n\n\t\t\tif (dispatchResult.ok) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — TConfig narrows WorkflowSnapshot but ctx.snapshot is unparameterized\n\t\t\t\tctx.snapshot = definition.serialize(dispatchResult.workflow) as any as WorkflowSnapshot;\n\t\t\t\tctx.events = (dispatchResult.events as Array<{ type: string; data: unknown }>).map((e) => ({\n\t\t\t\t\ttype: e.type,\n\t\t\t\t\tdata: e.data,\n\t\t\t\t}));\n\t\t\t}\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGO,SAAS,QAAc,YAA8D;AAC3F,SAAO,OAAO,QAAc;AAC3B,QAAI,QAAQ;AACZ,mBAAe,SAAS,GAA0B;AACjD,UAAI,KAAK,MAAO,OAAM,IAAI,MAAM,8BAA8B;AAC9D,cAAQ;AACR,YAAM,KAAK,WAAW,CAAC;AACvB,UAAI,CAAC,GAAI;AACT,YAAM,GAAG,KAAK,MAAM,SAAS,IAAI,CAAC,CAAC;AAAA,IACpC;AACA,UAAM,SAAS,CAAC;AAAA,EACjB;AACD;;;ACfO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAGnD,YACU,YACA,iBACA,eACR;AACD;AAAA,MACC,sCAAsC,UAAU,uBAAuB,eAAe,YAAY,aAAa;AAAA,IAChH;AANS;AACA;AACA;AAAA,EAKV;AAAA,EAVS,OAAO;AAWjB;;;ACJO,IAAM,mBAAN,MAAuD;AAAA,EAG7D,YACiB,QACC,OAChB;AAFe;AACC;AAAA,EACf;AAAA,EALc,aAAmC,CAAC;AAAA,EAOrD,IAAI,YAAsC;AACzC,SAAK,WAAW,KAAK,UAAU;AAC/B,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,QACL,IACA,SACA,SAC2B;AAE3B,UAAM,SAAS,MAAM,KAAK,MAAM,KAAK,EAAE;AACvC,QAAI,CAAC,QAAQ;AACZ,aAAO,EAAE,IAAI,OAAO,OAAO,EAAE,UAAU,aAAa,GAAG,EAAE;AAAA,IAC1D;AAGA,QAAI,SAAS,oBAAoB,UAAa,QAAQ,oBAAoB,OAAO,SAAS;AACzF,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,OAAO;AAAA,UACN,UAAU;AAAA,UACV;AAAA,UACA,iBAAiB,QAAQ;AAAA,UACzB,eAAe,OAAO;AAAA,QACvB;AAAA,MACD;AAAA,IACD;AAGA,UAAM,MAAuB;AAAA,MAC5B;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,QAAQ,CAAC;AAAA,IACV;AAGA,QAAI;AACH,YAAM,QAAQ,CAAC,GAAG,KAAK,YAAY,KAAK,gBAAgB,CAAC;AACzD,YAAM,QAAQ,KAAK,EAAE,GAAG;AAAA,IACzB,SAAS,KAAK;AACb,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,OAAO;AAAA,UACN,UAAU;AAAA,UACV,OAAO;AAAA,UACP,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,QACzD;AAAA,MACD;AAAA,IACD;AAGA,QAAI,IAAI,UAAU;AACjB,YAAM,aAAa,OAAO,UAAU;AACpC,YAAM,gBAAgB,EAAE,GAAG,IAAI,UAAU,SAAS,WAAW;AAE7D,UAAI;AACH,cAAM,KAAK,MAAM,KAAK;AAAA,UACrB;AAAA,UACA,UAAU,IAAI;AAAA,UACd,iBAAiB,OAAO;AAAA,UACxB,QAAQ,IAAI;AAAA,QACb,CAAC;AAAA,MACF,SAAS,KAAK;AACb,YAAI,eAAe,0BAA0B;AAC5C,iBAAO;AAAA,YACN,IAAI;AAAA,YACJ,OAAO;AAAA,cACN,UAAU;AAAA,cACV;AAAA,cACA,iBAAiB,OAAO;AAAA,cACxB,eAAe,IAAI;AAAA,YACpB;AAAA,UACD;AAAA,QACD;AACA,eAAO;AAAA,UACN,IAAI;AAAA,UACJ,OAAO;AAAA,YACN,UAAU;AAAA,YACV,OAAO;AAAA,YACP,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,UACzD;AAAA,QACD;AAAA,MACD;AAEA,aAAO;AAAA,QACN,IAAI;AAAA,QACJ,UAAU;AAAA,QACV,SAAS;AAAA,QACT,QAAQ,IAAI;AAAA,MACb;AAAA,IACD;AAGA,QAAI,IAAI,UAAU,CAAC,IAAI,OAAO,IAAI;AACjC,aAAO,EAAE,IAAI,OAAO,OAAO,IAAI,OAAO,MAAM;AAAA,IAC7C;AAEA,WAAO;AAAA,MACN,IAAI;AAAA,MACJ,OAAO;AAAA,QACN,UAAU;AAAA,QACV,OAAO,IAAI,MAAM,sDAAsD;AAAA,QACvE,SAAS;AAAA,MACV;AAAA,IACD;AAAA,EACD;AAAA,EAEQ,kBAAsC;AAC7C,UAAM,aAAa,KAAK,OAAO;AAC/B,UAAM,SAAS,KAAK;AAEpB,WAAO,OAAO,KAAK,UAAU;AAC5B,YAAM,gBAAgB,WAAW,YAAY,IAAI,OAAO,QAAQ;AAChE,UAAI,CAAC,cAAc,IAAI;AACtB,YAAI,SAAS;AAAA,UACZ,IAAI;AAAA,UACJ,OAAO;AAAA,YACN,UAAU;AAAA,YACV,IAAI,IAAI;AAAA,YACR,QAAQ,cAAc,MAAM;AAAA,UAC7B;AAAA,QACD;AACA;AAAA,MACD;AAIA,YAAM,iBAAiB,MAAM,OAAO;AAAA,QACnC,cAAc;AAAA,QACd,IAAI,QAAQ;AAAA,QACZ,IAAI,QAAQ;AAAA,MACb;AAGA,UAAI,SAAS;AAEb,UAAI,eAAe,IAAI;AAEtB,YAAI,WAAW,WAAW,UAAU,eAAe,QAAQ;AAC3D,YAAI,SAAU,eAAe,OAAkD,IAAI,CAAC,OAAO;AAAA,UAC1F,MAAM,EAAE;AAAA,UACR,MAAM,EAAE;AAAA,QACT,EAAE;AAAA,MACH;AAAA,IACD;AAAA,EACD;AACD;","names":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as WorkflowRouter } from '../plugin-
|
|
1
|
+
import { d as WorkflowRouter } from '../plugin-CGikcWDu.cjs';
|
|
2
2
|
import { S as StoredWorkflow, a as StoreAdapter } from '../types-BuFyzP66.cjs';
|
|
3
3
|
import { a as WorkflowSnapshot, P as PipelineError, W as WorkflowConfig, D as DispatchResult } from '../snapshot-6pxxtOjB.cjs';
|
|
4
4
|
import 'zod';
|
package/dist/executor/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as WorkflowRouter } from '../plugin-
|
|
1
|
+
import { d as WorkflowRouter } from '../plugin-ByX9Eoe-.js';
|
|
2
2
|
import { S as StoredWorkflow, a as StoreAdapter } from '../types-D41DR3xh.js';
|
|
3
3
|
import { a as WorkflowSnapshot, P as PipelineError, W as WorkflowConfig, D as DispatchResult } from '../snapshot-6pxxtOjB.js';
|
|
4
4
|
import 'zod';
|
package/dist/executor/index.js
CHANGED
|
@@ -119,7 +119,11 @@ var WorkflowExecutor = class {
|
|
|
119
119
|
};
|
|
120
120
|
return;
|
|
121
121
|
}
|
|
122
|
-
const dispatchResult = await router.dispatch(
|
|
122
|
+
const dispatchResult = await router.dispatch(
|
|
123
|
+
restoreResult.workflow,
|
|
124
|
+
ctx.command.type,
|
|
125
|
+
ctx.command.payload
|
|
126
|
+
);
|
|
123
127
|
ctx.result = dispatchResult;
|
|
124
128
|
if (dispatchResult.ok) {
|
|
125
129
|
ctx.snapshot = definition.serialize(dispatchResult.workflow);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/executor/executor.ts"],"sourcesContent":["import { compose } from \"../compose.js\";\nimport type { WorkflowRouter } from \"../router.js\";\nimport type { WorkflowSnapshot } from \"../snapshot.js\";\nimport { ConcurrencyConflictError } from \"../store/errors.js\";\nimport type { StoreAdapter } from \"../store/types.js\";\nimport type { WorkflowConfig } from \"../types.js\";\nimport type { ExecutionResult, ExecutorContext, ExecutorMiddleware } from \"./types.js\";\n\nexport class WorkflowExecutor<TConfig extends WorkflowConfig> {\n\tprivate readonly middleware: ExecutorMiddleware[] = [];\n\n\tconstructor(\n\t\tpublic readonly router: WorkflowRouter<TConfig>,\n\t\tprivate readonly store: StoreAdapter,\n\t) {}\n\n\tuse(middleware: ExecutorMiddleware): this {\n\t\tthis.middleware.push(middleware);\n\t\treturn this;\n\t}\n\n\tasync execute(\n\t\tid: string,\n\t\tcommand: { type: string; payload: unknown },\n\t\toptions?: { expectedVersion?: number },\n\t): Promise<ExecutionResult> {\n\t\t// 1. Load\n\t\tconst stored = await this.store.load(id);\n\t\tif (!stored) {\n\t\t\treturn { ok: false, error: { category: \"not_found\", id } };\n\t\t}\n\n\t\t// 2. Optimistic version check\n\t\tif (options?.expectedVersion !== undefined && options.expectedVersion !== stored.version) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\tid,\n\t\t\t\t\texpectedVersion: options.expectedVersion,\n\t\t\t\t\tactualVersion: stored.version,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 3. Build context\n\t\tconst ctx: ExecutorContext = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tstored,\n\t\t\tresult: null,\n\t\t\tsnapshot: null,\n\t\t\tevents: [],\n\t\t};\n\n\t\t// 4. Run pipeline\n\t\ttry {\n\t\t\tconst chain = [...this.middleware, this.dispatchHandler()];\n\t\t\tawait compose(chain)(ctx);\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\terror: err,\n\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 5. Save if dispatch succeeded\n\t\tif (ctx.snapshot) {\n\t\t\tconst newVersion = stored.version + 1;\n\t\t\tconst savedSnapshot = { ...ctx.snapshot, version: newVersion };\n\n\t\t\ttry {\n\t\t\t\tawait this.store.save({\n\t\t\t\t\tid,\n\t\t\t\t\tsnapshot: ctx.snapshot,\n\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\tevents: ctx.events,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof ConcurrencyConflictError) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\t\t\tactualVersion: err.actualVersion,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\t\terror: err,\n\t\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tsnapshot: savedSnapshot,\n\t\t\t\tversion: newVersion,\n\t\t\t\tevents: ctx.events,\n\t\t\t};\n\t\t}\n\n\t\t// 6. Dispatch failed — return the error\n\t\tif (ctx.result && !ctx.result.ok) {\n\t\t\treturn { ok: false, error: ctx.result.error };\n\t\t}\n\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: {\n\t\t\t\tcategory: \"unexpected\",\n\t\t\t\terror: new Error(\"Pipeline completed without setting snapshot or error\"),\n\t\t\t\tmessage: \"Pipeline completed without setting snapshot or error\",\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate dispatchHandler(): ExecutorMiddleware {\n\t\tconst definition = this.router.definition;\n\t\tconst router = this.router;\n\n\t\treturn async (ctx, _next) => {\n\t\t\tconst restoreResult = definition.deserialize(ctx.stored.snapshot);\n\t\t\tif (!restoreResult.ok) {\n\t\t\t\tctx.result = {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"restore\" as const,\n\t\t\t\t\t\tid: ctx.id,\n\t\t\t\t\t\tissues: restoreResult.error.issues,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// as never: type erasure — executor holds WorkflowConfig base type,\n\t\t\t// but dispatch validates commands against Zod schemas at runtime\n\t\t\tconst dispatchResult = await router.dispatch(
|
|
1
|
+
{"version":3,"sources":["../../src/executor/executor.ts"],"sourcesContent":["import { compose } from \"../compose.js\";\nimport type { WorkflowRouter } from \"../router.js\";\nimport type { WorkflowSnapshot } from \"../snapshot.js\";\nimport { ConcurrencyConflictError } from \"../store/errors.js\";\nimport type { StoreAdapter } from \"../store/types.js\";\nimport type { WorkflowConfig } from \"../types.js\";\nimport type { ExecutionResult, ExecutorContext, ExecutorMiddleware } from \"./types.js\";\n\nexport class WorkflowExecutor<TConfig extends WorkflowConfig> {\n\tprivate readonly middleware: ExecutorMiddleware[] = [];\n\n\tconstructor(\n\t\tpublic readonly router: WorkflowRouter<TConfig>,\n\t\tprivate readonly store: StoreAdapter,\n\t) {}\n\n\tuse(middleware: ExecutorMiddleware): this {\n\t\tthis.middleware.push(middleware);\n\t\treturn this;\n\t}\n\n\tasync execute(\n\t\tid: string,\n\t\tcommand: { type: string; payload: unknown },\n\t\toptions?: { expectedVersion?: number },\n\t): Promise<ExecutionResult> {\n\t\t// 1. Load\n\t\tconst stored = await this.store.load(id);\n\t\tif (!stored) {\n\t\t\treturn { ok: false, error: { category: \"not_found\", id } };\n\t\t}\n\n\t\t// 2. Optimistic version check\n\t\tif (options?.expectedVersion !== undefined && options.expectedVersion !== stored.version) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\tid,\n\t\t\t\t\texpectedVersion: options.expectedVersion,\n\t\t\t\t\tactualVersion: stored.version,\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 3. Build context\n\t\tconst ctx: ExecutorContext = {\n\t\t\tid,\n\t\t\tcommand,\n\t\t\tstored,\n\t\t\tresult: null,\n\t\t\tsnapshot: null,\n\t\t\tevents: [],\n\t\t};\n\n\t\t// 4. Run pipeline\n\t\ttry {\n\t\t\tconst chain = [...this.middleware, this.dispatchHandler()];\n\t\t\tawait compose(chain)(ctx);\n\t\t} catch (err) {\n\t\t\treturn {\n\t\t\t\tok: false,\n\t\t\t\terror: {\n\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\terror: err,\n\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t},\n\t\t\t};\n\t\t}\n\n\t\t// 5. Save if dispatch succeeded\n\t\tif (ctx.snapshot) {\n\t\t\tconst newVersion = stored.version + 1;\n\t\t\tconst savedSnapshot = { ...ctx.snapshot, version: newVersion };\n\n\t\t\ttry {\n\t\t\t\tawait this.store.save({\n\t\t\t\t\tid,\n\t\t\t\t\tsnapshot: ctx.snapshot,\n\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\tevents: ctx.events,\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\tif (err instanceof ConcurrencyConflictError) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: {\n\t\t\t\t\t\t\tcategory: \"conflict\",\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\texpectedVersion: stored.version,\n\t\t\t\t\t\t\tactualVersion: err.actualVersion,\n\t\t\t\t\t\t},\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"unexpected\",\n\t\t\t\t\t\terror: err,\n\t\t\t\t\t\tmessage: err instanceof Error ? err.message : String(err),\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tok: true,\n\t\t\t\tsnapshot: savedSnapshot,\n\t\t\t\tversion: newVersion,\n\t\t\t\tevents: ctx.events,\n\t\t\t};\n\t\t}\n\n\t\t// 6. Dispatch failed — return the error\n\t\tif (ctx.result && !ctx.result.ok) {\n\t\t\treturn { ok: false, error: ctx.result.error };\n\t\t}\n\n\t\treturn {\n\t\t\tok: false,\n\t\t\terror: {\n\t\t\t\tcategory: \"unexpected\",\n\t\t\t\terror: new Error(\"Pipeline completed without setting snapshot or error\"),\n\t\t\t\tmessage: \"Pipeline completed without setting snapshot or error\",\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate dispatchHandler(): ExecutorMiddleware {\n\t\tconst definition = this.router.definition;\n\t\tconst router = this.router;\n\n\t\treturn async (ctx, _next) => {\n\t\t\tconst restoreResult = definition.deserialize(ctx.stored.snapshot);\n\t\t\tif (!restoreResult.ok) {\n\t\t\t\tctx.result = {\n\t\t\t\t\tok: false as const,\n\t\t\t\t\terror: {\n\t\t\t\t\t\tcategory: \"restore\" as const,\n\t\t\t\t\t\tid: ctx.id,\n\t\t\t\t\t\tissues: restoreResult.error.issues,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// as never: type erasure — executor holds WorkflowConfig base type,\n\t\t\t// but dispatch validates commands against Zod schemas at runtime\n\t\t\tconst dispatchResult = await router.dispatch(\n\t\t\t\trestoreResult.workflow,\n\t\t\t\tctx.command.type as never,\n\t\t\t\tctx.command.payload as never,\n\t\t\t);\n\n\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — DispatchResult<TConfig> assigned to DispatchResult<WorkflowConfig>\n\t\t\tctx.result = dispatchResult as any;\n\n\t\t\tif (dispatchResult.ok) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: type erasure — TConfig narrows WorkflowSnapshot but ctx.snapshot is unparameterized\n\t\t\t\tctx.snapshot = definition.serialize(dispatchResult.workflow) as any as WorkflowSnapshot;\n\t\t\t\tctx.events = (dispatchResult.events as Array<{ type: string; data: unknown }>).map((e) => ({\n\t\t\t\t\ttype: e.type,\n\t\t\t\t\tdata: e.data,\n\t\t\t\t}));\n\t\t\t}\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -506,6 +506,9 @@ function createContext(definition, originalWorkflow, command, deps, options) {
|
|
|
506
506
|
command,
|
|
507
507
|
workflow: originalWorkflow,
|
|
508
508
|
deps: options?.wrapDeps !== false && deps != null && typeof deps === "object" ? wrapDeps(deps) : deps,
|
|
509
|
+
get state() {
|
|
510
|
+
return mutableState;
|
|
511
|
+
},
|
|
509
512
|
get data() {
|
|
510
513
|
return { ...mutableData };
|
|
511
514
|
},
|
|
@@ -520,7 +523,14 @@ function createContext(definition, originalWorkflow, command, deps, options) {
|
|
|
520
523
|
},
|
|
521
524
|
transition(target, data) {
|
|
522
525
|
if (!definition.hasState(target)) {
|
|
523
|
-
throw new
|
|
526
|
+
throw new ValidationError("transition", [
|
|
527
|
+
{
|
|
528
|
+
code: "custom",
|
|
529
|
+
message: `Unknown state: ${target}`,
|
|
530
|
+
input: target,
|
|
531
|
+
path: ["state"]
|
|
532
|
+
}
|
|
533
|
+
]);
|
|
524
534
|
}
|
|
525
535
|
const schema = definition.getStateSchema(target);
|
|
526
536
|
const result = schema.safeParse(data);
|
|
@@ -530,26 +540,30 @@ function createContext(definition, originalWorkflow, command, deps, options) {
|
|
|
530
540
|
mutableState = target;
|
|
531
541
|
mutableData = result.data;
|
|
532
542
|
},
|
|
533
|
-
emit(
|
|
534
|
-
const schema = definition.getEventSchema(
|
|
535
|
-
const result = schema.safeParse(
|
|
543
|
+
emit(type, data) {
|
|
544
|
+
const schema = definition.getEventSchema(type);
|
|
545
|
+
const result = schema.safeParse(data);
|
|
536
546
|
if (!result.success) {
|
|
537
547
|
throw new ValidationError("event", result.error.issues);
|
|
538
548
|
}
|
|
539
|
-
accumulatedEvents.push({ type
|
|
549
|
+
accumulatedEvents.push({ type, data: result.data });
|
|
540
550
|
},
|
|
541
551
|
get events() {
|
|
542
552
|
return [...accumulatedEvents];
|
|
543
553
|
},
|
|
544
|
-
error(
|
|
545
|
-
const schema = definition.getErrorSchema(
|
|
546
|
-
const result = schema.safeParse(
|
|
554
|
+
error(code, data) {
|
|
555
|
+
const schema = definition.getErrorSchema(code);
|
|
556
|
+
const result = schema.safeParse(data);
|
|
547
557
|
if (!result.success) {
|
|
548
|
-
throw new
|
|
549
|
-
`Invalid error data for '${err.code}': ${result.error.issues.map((i) => i.message).join(", ")}`
|
|
550
|
-
);
|
|
558
|
+
throw new ValidationError("state", result.error.issues);
|
|
551
559
|
}
|
|
552
|
-
throw new DomainErrorSignal(
|
|
560
|
+
throw new DomainErrorSignal(code, result.data);
|
|
561
|
+
},
|
|
562
|
+
match(matchers, fallback) {
|
|
563
|
+
const matcher = matchers[originalWorkflow.state];
|
|
564
|
+
if (matcher) return matcher(ctx.data, originalWorkflow);
|
|
565
|
+
if (fallback) return fallback();
|
|
566
|
+
throw new Error(`No matcher for state: ${originalWorkflow.state}`);
|
|
553
567
|
},
|
|
554
568
|
set(key, value) {
|
|
555
569
|
middlewareState.set(key.id, value);
|
|
@@ -766,7 +780,8 @@ var WorkflowRouter = class _WorkflowRouter {
|
|
|
766
780
|
* @param command - The command with its type and payload
|
|
767
781
|
* @returns A {@link DispatchResult} indicating success or failure with the updated workflow and events
|
|
768
782
|
*/
|
|
769
|
-
async dispatch(workflow,
|
|
783
|
+
async dispatch(workflow, type, payload) {
|
|
784
|
+
const command = { type, payload };
|
|
770
785
|
await this.hookRegistry.emit("dispatch:start", this.onHookError, workflow, command);
|
|
771
786
|
let result;
|
|
772
787
|
try {
|