@vite-hub/workflow 0.0.3 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +187 -56
  3. package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
  4. package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
  5. package/dist/client-DsGM3M4U.js +389 -0
  6. package/dist/cloudflare-env-BNrYo29x.js +113 -0
  7. package/dist/cloudflare-nF4abPd4.js +59 -0
  8. package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
  9. package/dist/{cloudflare-vite-B0zel2Do.js → cloudflare-vite-B3IabBsv.js} +18 -10
  10. package/dist/{config-BDqB6I4E.js → config-IJMb0eeZ.js} +39 -25
  11. package/dist/error-diagnostics-A_8Kp-48.js +116 -0
  12. package/dist/error-diagnostics-pwNFvAHP.js +67 -0
  13. package/dist/index.d.ts +24 -20
  14. package/dist/index.js +25 -334
  15. package/dist/inspect-B72iFyj-.js +70 -0
  16. package/dist/operations-B_rYG71W.js +230 -0
  17. package/dist/operations-tNUdj3G4.d.ts +212 -0
  18. package/dist/operations.d.ts +37 -0
  19. package/dist/operations.js +887 -0
  20. package/dist/out-CsaJxg8m.js +21755 -0
  21. package/dist/{provider-operation-CWIV4k42.js → provider-operation-CW2cYfVy.js} +13 -10
  22. package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
  23. package/dist/runtime/cloudflare-runner.d.ts +8 -14
  24. package/dist/runtime/cloudflare-runner.js +77 -14
  25. package/dist/runtime/cloudflare-shared.d.ts +1 -0
  26. package/dist/runtime/cloudflare-shared.js +1 -1
  27. package/dist/runtime/cloudflare-vite.d.ts +8 -9
  28. package/dist/runtime/cloudflare-vite.js +2 -2
  29. package/dist/runtime/execute.d.ts +8 -7
  30. package/dist/runtime/execute.js +28 -5
  31. package/dist/runtime/openworkflow-worker.d.ts +6 -8
  32. package/dist/runtime/openworkflow-worker.js +43 -6
  33. package/dist/runtime/openworkflow.d.ts +8 -10
  34. package/dist/runtime/openworkflow.js +50 -32
  35. package/dist/runtime/state.d.ts +20 -21
  36. package/dist/runtime/state.js +90 -20
  37. package/dist/runtime/vercel-vite.d.ts +10 -11
  38. package/dist/runtime/vercel-vite.js +11 -8
  39. package/dist/runtime-type-DBCvIh5x.js +7 -0
  40. package/dist/{types-BUlYBZwH.d.ts → types-D82WmfZa.d.ts} +35 -18
  41. package/dist/{vercel-D2_J5D_Y.js → vercel-D-ZNtB_u.js} +59 -26
  42. package/dist/vite.d.ts +365 -6
  43. package/dist/vite.js +4667 -910
  44. package/package.json +78 -28
  45. package/dist/cloudflare-Cds1VIWa.js +0 -42
  46. package/dist/cloudflare-env-mFp2Uj6Z.js +0 -53
  47. package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
@@ -27,7 +27,7 @@ function isWorkflowBoundaryError(error) {
27
27
  return false;
28
28
  }
29
29
  }
30
- function getProviderStatus(error) {
30
+ function getWorkflowProviderStatus(error) {
31
31
  if (typeof error !== "object" || error === null) return void 0;
32
32
  try {
33
33
  const value = error;
@@ -38,20 +38,23 @@ function getProviderStatus(error) {
38
38
  return;
39
39
  }
40
40
  }
41
- async function runWorkflowProviderOperation(provider, operation, run) {
41
+ async function runWorkflowProviderOperation(provider, operation, run, options = {}) {
42
42
  try {
43
43
  return await run();
44
44
  } catch (error) {
45
- if (isWorkflowBoundaryError(error)) throw error;
46
- const status = getProviderStatus(error);
45
+ if (options.boundaryError?.(error) || isWorkflowBoundaryError(error)) throw error;
46
+ const status = getWorkflowProviderStatus(error);
47
+ const acknowledgement = options.acknowledgementUnknown?.(error, status) === true ? "unknown" : void 0;
48
+ const details = {
49
+ operation,
50
+ provider
51
+ };
52
+ if (acknowledgement) details.acknowledgement = acknowledgement;
53
+ if (status !== void 0) details.status = status;
47
54
  throw createWorkflowError({
48
55
  cause: error,
49
56
  code: "WORKFLOW_PROVIDER_OPERATION_FAILED",
50
- details: {
51
- operation,
52
- provider,
53
- ...status === void 0 ? {} : { status }
54
- }
57
+ details
55
58
  });
56
59
  }
57
60
  }
@@ -59,4 +62,4 @@ function safeWorkflowName(name) {
59
62
  return /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(name) ? name : void 0;
60
63
  }
61
64
  //#endregion
62
- export { createWorkflowError as i, runWorkflowProviderOperation as n, safeWorkflowName as r, isWorkflowBoundaryError as t };
65
+ export { createWorkflowError as a, safeWorkflowName as i, isWorkflowBoundaryError as n, runWorkflowProviderOperation as r, getWorkflowProviderStatus as t };
@@ -0,0 +1,26 @@
1
+ import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
12
+ key = keys[i];
13
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
14
+ get: ((k) => from[k]).bind(null, key),
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
21
+ value: mod,
22
+ enumerable: true
23
+ }) : target, mod));
24
+ var __require = /* #__PURE__ */ (() => createRequire(import.meta.url))();
25
+ //#endregion
26
+ export { __require as n, __toESM as r, __commonJSMin as t };
@@ -1,27 +1,21 @@
1
- import { C as WorkflowProviderStep, h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-BUlYBZwH.js";
1
+ import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions, w as WorkflowProviderStep } from "../types-D82WmfZa.js";
2
2
  import { t as CloudflareWorkerEnv } from "../cloudflare-env-CIjdFTv6.js";
3
-
4
3
  //#region src/runtime/cloudflare-runner.d.ts
5
- interface CloudflareWorkflowEvent {
4
+ export interface CloudflareWorkflowEvent {
6
5
  id?: string;
7
6
  instanceId?: string;
8
7
  payload?: unknown;
9
8
  }
10
- interface RunCloudflareWorkflowOptions {
9
+ export interface RunCloudflareWorkflowOptions {
11
10
  config: false | ResolvedWorkflowOptions | undefined;
11
+ createNonRetryableError?: (error: Error & {
12
+ isRetryable: false;
13
+ }) => Error;
12
14
  env: CloudflareWorkerEnv;
13
15
  event: CloudflareWorkflowEvent;
14
16
  name: string;
15
17
  registry: WorkflowDefinitionRegistry;
16
18
  step?: WorkflowProviderStep;
17
19
  }
18
- declare function runCloudflareWorkflow({
19
- config,
20
- env,
21
- event,
22
- name,
23
- registry,
24
- step
25
- }: RunCloudflareWorkflowOptions): Promise<unknown>;
26
- //#endregion
27
- export { CloudflareWorkflowEvent, RunCloudflareWorkflowOptions, runCloudflareWorkflow };
20
+ export declare function runCloudflareWorkflow({ config, createNonRetryableError, env, event, name, registry, step }: RunCloudflareWorkflowOptions): Promise<unknown>;
21
+ //#endregion
@@ -1,23 +1,86 @@
1
- import { i as runWithActiveCloudflareEnv } from "../cloudflare-env-mFp2Uj6Z.js";
2
- import { runWorkflowHandler } from "./execute.js";
1
+ import { t as workflowErrorDiagnostics } from "../error-diagnostics-pwNFvAHP.js";
2
+ import { t as hasRuntimeType } from "../runtime-type-DBCvIh5x.js";
3
+ import { i as runWithActiveCloudflareEnv } from "../cloudflare-env-BNrYo29x.js";
4
+ import { runSerializedWorkflowHandler } from "./execute.js";
3
5
  import { loadWorkflowDefinition, runWithWorkflowRuntimeEvent, setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry } from "./state.js";
4
6
  //#region src/runtime/cloudflare-runner.ts
5
- async function runCloudflareWorkflow({ config, env, event, name, registry, step }) {
7
+ function isNonRetryableError(error) {
8
+ if (!hasRuntimeType(error, "object") || error === null) return false;
9
+ try {
10
+ const candidate = error;
11
+ if (Reflect.get(candidate, "isRetryable") !== false) return false;
12
+ const nativeIsError = Reflect.get(Error, "isError");
13
+ if (hasRuntimeType(nativeIsError, "function")) return nativeIsError(candidate) === true;
14
+ const clone = Reflect.get(globalThis, "structuredClone");
15
+ if (!hasRuntimeType(clone, "function")) return false;
16
+ try {
17
+ return clone(candidate) instanceof Error;
18
+ } catch {
19
+ const descriptors = /* @__PURE__ */ new Map();
20
+ try {
21
+ for (const key of Reflect.ownKeys(candidate)) {
22
+ const descriptor = Reflect.getOwnPropertyDescriptor(candidate, key);
23
+ if (!descriptor?.configurable || !("value" in descriptor)) continue;
24
+ descriptors.set(key, descriptor);
25
+ Reflect.defineProperty(candidate, key, {
26
+ ...descriptor,
27
+ value: void 0
28
+ });
29
+ }
30
+ try {
31
+ return clone(candidate) instanceof Error;
32
+ } catch {
33
+ return false;
34
+ }
35
+ } finally {
36
+ for (const [key, descriptor] of descriptors) Reflect.defineProperty(candidate, key, descriptor);
37
+ }
38
+ }
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+ function translateNonRetryableError(error, createNonRetryableError) {
44
+ return createNonRetryableError && isNonRetryableError(error) ? createNonRetryableError(error) : error;
45
+ }
46
+ function wrapCloudflareWorkflowStep(step, createNonRetryableError, env, runtimeEvent) {
47
+ if (!step?.do) return step;
48
+ return {
49
+ async do(name, options, run) {
50
+ return await step.do(name, options, async () => await runWithActiveCloudflareEnv(env, async () => await runWithWorkflowRuntimeEvent(runtimeEvent(), async () => {
51
+ try {
52
+ return await run();
53
+ } catch (error) {
54
+ throw translateNonRetryableError(error, createNonRetryableError);
55
+ }
56
+ })));
57
+ },
58
+ ...step.sleep ? { sleep: step.sleep.bind(step) } : {}
59
+ };
60
+ }
61
+ async function runCloudflareWorkflow({ config, createNonRetryableError, env, event, name, registry, step }) {
6
62
  setWorkflowRuntimeConfig(config);
7
63
  setWorkflowRuntimeRegistry(registry);
64
+ let runtimeEvent;
65
+ const providerStep = wrapCloudflareWorkflowStep(step, createNonRetryableError, env, () => runtimeEvent);
66
+ runtimeEvent = {
67
+ env,
68
+ step: providerStep
69
+ };
8
70
  return await runWithActiveCloudflareEnv(env, async () => {
9
71
  const definition = await loadWorkflowDefinition(name);
10
- if (!definition) throw new Error(`Missing workflow definition: ${name}`);
11
- return await runWithWorkflowRuntimeEvent({
12
- env,
13
- step
14
- }, () => runWorkflowHandler({
15
- id: event?.instanceId || event?.id,
16
- name,
17
- payload: event?.payload,
18
- provider: "cloudflare",
19
- step
20
- }, definition));
72
+ if (!definition) throw workflowErrorDiagnostics.WORKFLOW_R0015({ message: `Missing workflow definition: ${name}` });
73
+ try {
74
+ return await runWithWorkflowRuntimeEvent(runtimeEvent, () => runSerializedWorkflowHandler({
75
+ id: event?.instanceId || event?.id,
76
+ name,
77
+ payload: event?.payload,
78
+ provider: "cloudflare",
79
+ step: providerStep
80
+ }, definition));
81
+ } catch (error) {
82
+ throw translateNonRetryableError(error, createNonRetryableError);
83
+ }
21
84
  });
22
85
  }
23
86
  //#endregion
@@ -1,2 +1,3 @@
1
1
  import { a as setActiveCloudflareEnv, i as runWithActiveCloudflareEnv, n as CloudflareWorkerExecutionContext, r as createCloudflareRuntimeEvent, t as CloudflareWorkerEnv } from "../cloudflare-env-CIjdFTv6.js";
2
+ import "../cloudflare-shared-CaxrMD1A.js";
2
3
  export { type CloudflareWorkerEnv, type CloudflareWorkerExecutionContext, createCloudflareRuntimeEvent, runWithActiveCloudflareEnv, setActiveCloudflareEnv };
@@ -1,2 +1,2 @@
1
- import { a as setActiveCloudflareEnv, i as runWithActiveCloudflareEnv, t as createCloudflareRuntimeEvent } from "../cloudflare-env-mFp2Uj6Z.js";
1
+ import { a as setActiveCloudflareEnv, i as runWithActiveCloudflareEnv, t as createCloudflareRuntimeEvent } from "../cloudflare-env-BNrYo29x.js";
2
2
  export { createCloudflareRuntimeEvent, runWithActiveCloudflareEnv, setActiveCloudflareEnv };
@@ -1,17 +1,16 @@
1
- import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-BUlYBZwH.js";
2
- import { t as WorkflowApp } from "../_app-DgwN4ulW.js";
1
+ import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-D82WmfZa.js";
2
+ import { t as VitehubApp } from "../app-BojnC_yf.js";
3
3
  import { n as CloudflareWorkerExecutionContext, t as CloudflareWorkerEnv } from "../cloudflare-env-CIjdFTv6.js";
4
-
5
4
  //#region src/runtime/cloudflare-vite.d.ts
6
- type CloudflareWorkerApp = WorkflowApp;
7
- interface WorkflowCloudflareWorkerOptions {
5
+ export type CloudflareWorkerApp = VitehubApp;
6
+ export interface WorkflowCloudflareWorkerOptions {
8
7
  app?: CloudflareWorkerApp;
9
8
  registry?: WorkflowDefinitionRegistry;
10
9
  workflow?: false | ResolvedWorkflowOptions;
11
10
  }
12
- interface WorkflowCloudflareWorker {
11
+ export interface WorkflowCloudflareWorker {
13
12
  fetch: (request: Request, env: CloudflareWorkerEnv, context: CloudflareWorkerExecutionContext) => Promise<Response>;
14
13
  }
15
- declare function createWorkflowCloudflareWorker(options?: WorkflowCloudflareWorkerOptions): WorkflowCloudflareWorker;
16
- //#endregion
17
- export { CloudflareWorkerApp, WorkflowCloudflareWorker, WorkflowCloudflareWorkerOptions, createWorkflowCloudflareWorker };
14
+ export declare function installWorkflowCloudflareRuntime(options?: WorkflowCloudflareWorkerOptions): void;
15
+ export declare function createWorkflowCloudflareWorker(options?: WorkflowCloudflareWorkerOptions): WorkflowCloudflareWorker;
16
+ //#endregion
@@ -1,2 +1,2 @@
1
- import { t as createWorkflowCloudflareWorker } from "../cloudflare-vite-B0zel2Do.js";
2
- export { createWorkflowCloudflareWorker };
1
+ import { n as installWorkflowCloudflareRuntime, t as createWorkflowCloudflareWorker } from "../cloudflare-vite-B3IabBsv.js";
2
+ export { createWorkflowCloudflareWorker, installWorkflowCloudflareRuntime };
@@ -1,11 +1,12 @@
1
- import { A as WorkflowStepFunction, C as WorkflowProviderStep, g as WorkflowExecutionContext, j as WorkflowStepOptions, p as WorkflowDefinition } from "../types-BUlYBZwH.js";
2
-
1
+ import { M as WorkflowStepOptions, S as WorkflowProviderContext, j as WorkflowStepFunction, p as WorkflowDefinition, w as WorkflowProviderStep } from "../types-D82WmfZa.js";
2
+ import { SerializedResponse } from "@vite-hub/runtime";
3
3
  //#region src/runtime/execute.d.ts
4
- declare function runProviderStep<TResult>(step: WorkflowProviderStep | undefined, name: string, run: () => TResult | Promise<TResult>, options?: WorkflowStepOptions): Promise<TResult>;
5
- declare function createWorkflowSteps(context: WorkflowExecutionContext, stepModules: Array<{
4
+ export declare function runProviderStep<TResult>(step: WorkflowProviderStep | undefined, name: string, run: () => TResult | Promise<TResult>, options?: WorkflowStepOptions): Promise<TResult>;
5
+ export declare function createWorkflowSteps(context: WorkflowProviderContext, stepModules: Array<{
6
6
  name: string;
7
7
  run: WorkflowStepFunction;
8
8
  }>): Record<string, WorkflowStepFunction>;
9
- declare function runWorkflowHandler<TPayload, TResult>(context: WorkflowExecutionContext<TPayload>, definition: WorkflowDefinition<TPayload, TResult>): Promise<TResult>;
10
- //#endregion
11
- export { createWorkflowSteps, runProviderStep, runWorkflowHandler };
9
+ export declare function runWorkflowHandler<TPayload, TResult>(context: WorkflowProviderContext<TPayload>, definition: WorkflowDefinition<TPayload, TResult>): Promise<Response>;
10
+ /** Encode inside the root step so both checkpoints and final outputs survive replay. */
11
+ export declare function runSerializedWorkflowHandler<TPayload, TResult>(context: WorkflowProviderContext<TPayload>, definition: WorkflowDefinition<TPayload, TResult>): Promise<SerializedResponse>;
12
+ //#endregion
@@ -1,3 +1,5 @@
1
+ import { t as workflowErrorDiagnostics } from "../error-diagnostics-pwNFvAHP.js";
2
+ import { serializeResponse, toResponse } from "@vite-hub/runtime";
1
3
  //#region src/runtime/execute.ts
2
4
  const defaultStepOptions = { retries: {
3
5
  backoff: "exponential",
@@ -12,14 +14,35 @@ function toStepPropertyName(file) {
12
14
  return file.split("/").pop().replace(/\.(?:c|m)?[jt]s$/i, "").replace(/^\d+[.-]?/, "").replace(/[-_.]+([a-z0-9])/gi, (_, char) => char.toUpperCase());
13
15
  }
14
16
  function createWorkflowSteps(context, stepModules) {
17
+ const names = /* @__PURE__ */ new Map();
15
18
  return Object.fromEntries(stepModules.map((module) => {
16
- return [toStepPropertyName(module.name), async (input) => await runProviderStep(context.step, `${context.name}/${module.name}`, () => module.run(input))];
19
+ const propertyName = toStepPropertyName(module.name);
20
+ if (!propertyName) throw workflowErrorDiagnostics.WORKFLOW_C0011({ message: `[vitehub] Workflow step file ${JSON.stringify(module.name)} normalizes to an empty step property. Rename the file so the step property is non-empty.` });
21
+ const previousName = names.get(propertyName);
22
+ if (previousName) throw workflowErrorDiagnostics.WORKFLOW_C0010({ message: `[vitehub] Workflow step files ${JSON.stringify(previousName)} and ${JSON.stringify(module.name)} both normalize to the \`${propertyName}\` step property. Rename one file so each step property is unique.` });
23
+ names.set(propertyName, module.name);
24
+ return [propertyName, async (input) => await runProviderStep(context.step, `${context.name}/${module.name}`, () => module.run(input))];
17
25
  }));
18
26
  }
27
+ /**
28
+ * Gives every handler a step runner. Generated folder Workflows replace this
29
+ * empty runner with their step files.
30
+ */
31
+ function toExecutionContext(context) {
32
+ return {
33
+ ...context,
34
+ steps: {}
35
+ };
36
+ }
19
37
  async function runWorkflowHandler(context, definition) {
20
- const run = () => definition.handler(context);
21
- if (definition.options?.rootStep === false) return await run();
22
- return await runProviderStep(context.step, context.name, run);
38
+ const run = () => definition.handler(toExecutionContext(context));
39
+ const value = definition.options?.rootStep === false ? await run() : await runProviderStep(context.step, context.name, run);
40
+ return toResponse(value);
41
+ }
42
+ /** Encode inside the root step so both checkpoints and final outputs survive replay. */
43
+ async function runSerializedWorkflowHandler(context, definition) {
44
+ const run = async () => serializeResponse(toResponse(await definition.handler(toExecutionContext(context))));
45
+ return definition.options?.rootStep === false ? await run() : await runProviderStep(context.step, context.name, run);
23
46
  }
24
47
  //#endregion
25
- export { createWorkflowSteps, runProviderStep, runWorkflowHandler };
48
+ export { createWorkflowSteps, runProviderStep, runSerializedWorkflowHandler, runWorkflowHandler };
@@ -1,20 +1,18 @@
1
- import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-BUlYBZwH.js";
1
+ import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-D82WmfZa.js";
2
2
  import { getOpenWorkflowRuntime } from "./openworkflow.js";
3
3
  import { ViteHubError } from "@vite-hub/runtime";
4
-
5
4
  //#region src/runtime/openworkflow-worker.d.ts
6
5
  type OpenWorkflowWorker = ReturnType<Awaited<ReturnType<typeof getOpenWorkflowRuntime>>["client"]["newWorker"]>;
7
- interface CreateOpenWorkflowWorkerOptions {
6
+ export interface CreateOpenWorkflowWorkerOptions {
8
7
  concurrency?: number;
9
8
  config?: false | ResolvedWorkflowOptions;
10
9
  registry?: WorkflowDefinitionRegistry;
11
10
  }
12
- interface StartOpenWorkflowWorkerOptions extends CreateOpenWorkflowWorkerOptions {
11
+ export interface StartOpenWorkflowWorkerOptions extends CreateOpenWorkflowWorkerOptions {
13
12
  onError?: (error: ViteHubError) => Promise<void> | void;
14
13
  signal?: AbortSignal;
15
14
  signals?: boolean;
16
15
  }
17
- declare function createOpenWorkflowWorker(options?: CreateOpenWorkflowWorkerOptions): Promise<OpenWorkflowWorker>;
18
- declare function startOpenWorkflowWorker(options?: StartOpenWorkflowWorkerOptions): Promise<OpenWorkflowWorker>;
19
- //#endregion
20
- export { CreateOpenWorkflowWorkerOptions, StartOpenWorkflowWorkerOptions, createOpenWorkflowWorker, startOpenWorkflowWorker };
16
+ export declare function createOpenWorkflowWorker(options?: CreateOpenWorkflowWorkerOptions): Promise<OpenWorkflowWorker>;
17
+ export declare function startOpenWorkflowWorker(options?: StartOpenWorkflowWorkerOptions): Promise<OpenWorkflowWorker>;
18
+ //#endregion
@@ -1,4 +1,6 @@
1
- import { i as createWorkflowError } from "../provider-operation-CWIV4k42.js";
1
+ import { t as workflowErrorDiagnostics } from "../error-diagnostics-pwNFvAHP.js";
2
+ import { n as isRuntimeRecord, t as hasRuntimeType } from "../runtime-type-DBCvIh5x.js";
3
+ import { a as createWorkflowError, r as runWorkflowProviderOperation } from "../provider-operation-CW2cYfVy.js";
2
4
  import { getOpenWorkflowRuntime, registerOpenWorkflowDefinition } from "./openworkflow.js";
3
5
  import { getInlineWorkflowDefinitions, getWorkflowRuntimeConfig, getWorkflowRuntimeRegistry, setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry, takeInlineWorkflowDefinitionForModule } from "./state.js";
4
6
  import "@vite-hub/runtime";
@@ -6,12 +8,15 @@ import "@vite-hub/runtime";
6
8
  function getProcess() {
7
9
  return globalThis.process;
8
10
  }
11
+ function isWorkflowDefinition(value) {
12
+ return isRuntimeRecord(value) && Object.hasOwn(value, "handler") && hasRuntimeType(value.handler, "function");
13
+ }
9
14
  async function loadRegistryDefinitions(registry) {
10
15
  const definitions = /* @__PURE__ */ new Map();
11
16
  for (const name of Object.keys(registry).sort()) {
12
17
  const loaded = await registry[name]?.();
13
- const definition = loaded && typeof loaded === "object" && "default" in loaded ? loaded.default : loaded;
14
- if (definition && typeof definition === "object" && "handler" in definition && typeof definition.handler === "function") {
18
+ const definition = isRuntimeRecord(loaded) && "default" in loaded ? loaded.default : loaded;
19
+ if (isWorkflowDefinition(definition)) {
15
20
  definitions.set(name, definition);
16
21
  continue;
17
22
  }
@@ -23,13 +28,13 @@ async function loadRegistryDefinitions(registry) {
23
28
  function mergeInlineDefinitions(definitions) {
24
29
  for (const [name, definition] of getInlineWorkflowDefinitions()) {
25
30
  const existing = definitions.get(name);
26
- if (existing && existing !== definition) throw new Error(`Duplicate workflow name "${name}" from inline and discovered definitions.`);
31
+ if (existing && existing !== definition) throw workflowErrorDiagnostics.WORKFLOW_R0016({ message: `Duplicate workflow name "${name}" from inline and discovered definitions.` });
27
32
  definitions.set(name, definition);
28
33
  }
29
34
  }
30
35
  async function createOpenWorkflowWorker(options = {}) {
31
36
  const config = options.config ?? getWorkflowRuntimeConfig();
32
- if (!config || config.provider !== "openworkflow") throw new Error("OpenWorkflow worker requires workflow.provider \"openworkflow\".");
37
+ if (!config || config.provider !== "openworkflow") throw workflowErrorDiagnostics.WORKFLOW_R0017({ message: "OpenWorkflow worker requires workflow.provider \"openworkflow\"." });
33
38
  const registry = options.registry ?? getWorkflowRuntimeRegistry() ?? {};
34
39
  setWorkflowRuntimeConfig(config);
35
40
  setWorkflowRuntimeRegistry(registry);
@@ -41,7 +46,39 @@ async function createOpenWorkflowWorker(options = {}) {
41
46
  }
42
47
  async function startOpenWorkflowWorker(options = {}) {
43
48
  const worker = await createOpenWorkflowWorker(options);
44
- await worker.start();
49
+ await runWorkflowProviderOperation("openworkflow", "start", async () => {
50
+ let removeStartupAbortListener;
51
+ let startTask;
52
+ try {
53
+ if (options.signal?.aborted) throw options.signal.reason;
54
+ startTask = Promise.resolve(worker.start());
55
+ if (!options.signal) await startTask;
56
+ else {
57
+ const signal = options.signal;
58
+ const abortTask = new Promise((_resolve, reject) => {
59
+ const abort = () => reject(signal.reason);
60
+ removeStartupAbortListener = () => signal.removeEventListener("abort", abort);
61
+ signal.addEventListener("abort", abort, { once: true });
62
+ if (signal.aborted) abort();
63
+ });
64
+ await Promise.race([startTask, abortTask]);
65
+ }
66
+ } catch (startError) {
67
+ const stopTask = Promise.resolve().then(() => worker.stop());
68
+ if (startTask && options.signal?.aborted) startTask.then(async () => {
69
+ await stopTask.catch(() => {});
70
+ await worker.stop();
71
+ }).catch(() => {});
72
+ try {
73
+ await stopTask;
74
+ } catch (stopError) {
75
+ throw new AggregateError([startError, stopError], "OpenWorkflow worker startup and cleanup failed.");
76
+ }
77
+ throw startError;
78
+ } finally {
79
+ removeStartupAbortListener?.();
80
+ }
81
+ }, { boundaryError: (error) => options.signal?.aborted === true && error === options.signal.reason });
45
82
  const originalStop = worker.stop.bind(worker);
46
83
  const proc = getProcess();
47
84
  let abortListenerActive = false;
@@ -1,5 +1,4 @@
1
- import { f as WorkflowDeferOptions, l as ResolvedWorkflowOptions, p as WorkflowDefinition, w as WorkflowRun } from "../types-BUlYBZwH.js";
2
-
1
+ import { T as WorkflowRun, f as WorkflowDeferOptions, l as ResolvedWorkflowOptions, p as WorkflowDefinition } from "../types-D82WmfZa.js";
3
2
  //#region src/runtime/openworkflow.d.ts
4
3
  type OpenWorkflowModule = typeof import("openworkflow");
5
4
  type OpenWorkflowPostgresModule = typeof import("openworkflow/postgres");
@@ -13,11 +12,10 @@ interface OpenWorkflowRuntime {
13
12
  client: OpenWorkflowClient;
14
13
  workflows: Map<string, OpenWorkflowRunnable>;
15
14
  }
16
- declare function getOpenWorkflowRuntime(config: ResolvedWorkflowOptions): Promise<OpenWorkflowRuntime>;
17
- declare function registerOpenWorkflowDefinition(runtime: OpenWorkflowRuntime, name: string, definition: WorkflowDefinition): Promise<OpenWorkflowRunnable>;
18
- declare function runOpenWorkflow<TPayload = unknown, TResult = unknown>(config: ResolvedWorkflowOptions, name: string, payload: TPayload | undefined, definition: WorkflowDefinition<TPayload, TResult>, options: WorkflowDeferOptions): Promise<WorkflowRun<TPayload, TResult>>;
19
- declare function getOpenWorkflowRun<TPayload = unknown, TResult = unknown>(config: ResolvedWorkflowOptions, name: string, id: string): Promise<WorkflowRun<TPayload, TResult>>;
20
- declare function resetOpenWorkflowRuntime(): Promise<void>;
21
- declare function setOpenWorkflowImporter(importer: OpenWorkflowImporter): void;
22
- //#endregion
23
- export { getOpenWorkflowRun, getOpenWorkflowRuntime, registerOpenWorkflowDefinition, resetOpenWorkflowRuntime, runOpenWorkflow, setOpenWorkflowImporter };
15
+ export declare function getOpenWorkflowRuntime(config: ResolvedWorkflowOptions): Promise<OpenWorkflowRuntime>;
16
+ export declare function registerOpenWorkflowDefinition(runtime: OpenWorkflowRuntime, name: string, definition: WorkflowDefinition): Promise<OpenWorkflowRunnable>;
17
+ export declare function runOpenWorkflow<TPayload = unknown, TResult = unknown>(config: ResolvedWorkflowOptions, name: string, payload: TPayload | undefined, definition: WorkflowDefinition<TPayload, TResult>, options: WorkflowDeferOptions, onDispatch?: () => void): Promise<WorkflowRun<TPayload, TResult>>;
18
+ export declare function getOpenWorkflowRun<TPayload = unknown, TResult = unknown>(config: ResolvedWorkflowOptions, name: string, id: string): Promise<WorkflowRun<TPayload, TResult>>;
19
+ export declare function resetOpenWorkflowRuntime(): Promise<void>;
20
+ export declare function setOpenWorkflowImporter(importer: OpenWorkflowImporter): void;
21
+ //#endregion
@@ -1,5 +1,7 @@
1
- import { i as createWorkflowError, n as runWorkflowProviderOperation } from "../provider-operation-CWIV4k42.js";
2
- import { runWorkflowHandler } from "./execute.js";
1
+ import { t as workflowErrorDiagnostics } from "../error-diagnostics-pwNFvAHP.js";
2
+ import { a as createWorkflowError, r as runWorkflowProviderOperation, t as getWorkflowProviderStatus } from "../provider-operation-CW2cYfVy.js";
3
+ import { runSerializedWorkflowHandler } from "./execute.js";
4
+ import { deserializeResponse, isSerializedResponse } from "@vite-hub/runtime";
3
5
  //#region src/runtime/openworkflow.ts
4
6
  const defaultImporter = new Function("specifier", "return import(specifier)");
5
7
  let openWorkflowImporter = defaultImporter;
@@ -24,8 +26,8 @@ function getRuntimeEnvNames(value) {
24
26
  return value.source?.names ?? (value.source?.name ? [value.source.name] : []);
25
27
  }
26
28
  function normalizeSqlitePath(path) {
27
- if (/^(?:libsql:|https?:\/\/)/i.test(path)) throw new Error(`OpenWorkflow SQLite storage requires a local SQLite file path, received ${JSON.stringify(path)}.`);
28
- if (/^[a-z][a-z0-9+.-]*:/i.test(path) && !path.startsWith("file:")) throw new Error(`OpenWorkflow SQLite storage received unsupported storage URL ${JSON.stringify(path)}.`);
29
+ if (/^(?:libsql:|https?:\/\/)/i.test(path)) throw workflowErrorDiagnostics.WORKFLOW_R0018({ message: `OpenWorkflow SQLite storage requires a local SQLite file path, received ${JSON.stringify(path)}.` });
30
+ if (/^[a-z][a-z0-9+.-]*:/i.test(path) && !path.startsWith("file:")) throw workflowErrorDiagnostics.WORKFLOW_R0019({ message: `OpenWorkflow SQLite storage received unsupported storage URL ${JSON.stringify(path)}.` });
29
31
  return path.startsWith("file:") ? path.slice(5) : path;
30
32
  }
31
33
  async function prepareSqlitePath(path, importer) {
@@ -36,17 +38,23 @@ async function prepareSqlitePath(path, importer) {
36
38
  return path;
37
39
  }
38
40
  function getOpenWorkflowConfig(config) {
39
- if (config.provider !== "openworkflow") throw new Error(`OpenWorkflow runtime requires workflow.provider "openworkflow", received "${config.provider}".`);
41
+ if (config.provider !== "openworkflow") throw workflowErrorDiagnostics.WORKFLOW_R0020({ message: `OpenWorkflow runtime requires workflow.provider "openworkflow", received "${config.provider}".` });
42
+ if ("database" in config && config.database !== void 0) throw workflowErrorDiagnostics.WORKFLOW_R0027({ message: "`workflow.database` is not supported. Set `workflow.sqlite.path` or `workflow.postgres.url` explicitly." });
40
43
  const sqlite = config.sqlite || {};
41
- const sqlitePath = resolveRuntimeConfigValue(sqlite.path) || readEnv("OPENWORKFLOW_SQLITE_PATH");
44
+ const postgres = config.postgres || {};
45
+ if (postgres.url !== void 0 && sqlite.path !== void 0) throw workflowErrorDiagnostics.WORKFLOW_R0030({ message: "`workflow.postgres.url` and `workflow.sqlite.path` cannot both configure OpenWorkflow storage." });
46
+ const explicitSqlitePath = resolveRuntimeConfigValue(sqlite.path);
47
+ const explicitPostgresUrl = resolveRuntimeConfigValue(postgres.url)?.trim();
48
+ if (sqlite.path !== void 0 && !explicitSqlitePath?.trim()) throw workflowErrorDiagnostics.WORKFLOW_R0028({ message: "`workflow.sqlite.path` must resolve to a non-empty local SQLite path. Check its runtime environment declaration." });
49
+ if (postgres.url !== void 0 && !explicitPostgresUrl) throw workflowErrorDiagnostics.WORKFLOW_R0029({ message: "`workflow.postgres.url` must resolve to a non-empty Postgres URL. Check its runtime environment declaration." });
50
+ const sqlitePath = explicitSqlitePath || (!explicitPostgresUrl ? readEnv("OPENWORKFLOW_SQLITE_PATH") : void 0);
42
51
  if (sqlitePath) return {
43
52
  backend: "sqlite",
44
53
  namespaceId: sqlite.namespaceId || readEnv("OPENWORKFLOW_NAMESPACE_ID") || "production",
45
54
  path: normalizeSqlitePath(sqlitePath),
46
55
  runMigrations: sqlite.runMigrations
47
56
  };
48
- const postgres = config.postgres || {};
49
- const url = resolveRuntimeConfigValue(postgres.url) || readEnv("OPENWORKFLOW_POSTGRES_URL") || readEnv("DATABASE_URL");
57
+ const url = explicitPostgresUrl || readEnv("OPENWORKFLOW_POSTGRES_URL") || readEnv("DATABASE_URL");
50
58
  if (url) return {
51
59
  backend: "postgres",
52
60
  namespaceId: postgres.namespaceId || readEnv("OPENWORKFLOW_NAMESPACE_ID") || "production",
@@ -61,11 +69,7 @@ function getOpenWorkflowConfig(config) {
61
69
  runMigrations: sqlite.runMigrations
62
70
  };
63
71
  }
64
- function getRuntimeKey(config) {
65
- return JSON.stringify(getOpenWorkflowConfig(config));
66
- }
67
- async function createOpenWorkflowRuntime(config, importer) {
68
- const options = getOpenWorkflowConfig(config);
72
+ async function createOpenWorkflowRuntime(options, importer) {
69
73
  const [{ OpenWorkflow }, backendModule] = await Promise.all([importOpenWorkflowModule("openworkflow", importer), options.backend === "sqlite" ? importOpenWorkflowModule("openworkflow/sqlite", importer) : importOpenWorkflowModule("openworkflow/postgres", importer)]);
70
74
  const { backend, client } = await runWorkflowProviderOperation("openworkflow", "connect", async () => {
71
75
  let backend;
@@ -91,10 +95,11 @@ async function createOpenWorkflowRuntime(config, importer) {
91
95
  }
92
96
  async function getOpenWorkflowRuntime(config) {
93
97
  const cache = runtimes;
94
- const key = getRuntimeKey(config);
98
+ const options = getOpenWorkflowConfig(config);
99
+ const key = JSON.stringify(options);
95
100
  let runtime = cache.get(key);
96
101
  if (!runtime) {
97
- runtime = createOpenWorkflowRuntime(config, openWorkflowImporter);
102
+ runtime = createOpenWorkflowRuntime(options, openWorkflowImporter);
98
103
  cache.set(key, runtime);
99
104
  runtime.catch(() => {
100
105
  if (cache.get(key) === runtime) cache.delete(key);
@@ -117,24 +122,28 @@ function toOpenWorkflowRetryPolicy(options) {
117
122
  };
118
123
  }
119
124
  function createOpenWorkflowProviderStep(step) {
120
- return { async do(name, options, run) {
121
- return await step.run({
122
- name,
123
- ...toOpenWorkflowRetryPolicy(options) ? { retryPolicy: toOpenWorkflowRetryPolicy(options) } : {}
124
- }, run);
125
- } };
125
+ return {
126
+ async do(name, options, run) {
127
+ return await step.run({
128
+ name,
129
+ ...toOpenWorkflowRetryPolicy(options) ? { retryPolicy: toOpenWorkflowRetryPolicy(options) } : {}
130
+ }, run);
131
+ },
132
+ sleep: async (name, duration) => await step.sleep(name, duration)
133
+ };
126
134
  }
127
135
  async function registerOpenWorkflowDefinition(runtime, name, definition) {
128
136
  const existing = runtime.workflows.get(name);
129
137
  if (existing) return existing;
138
+ const openWorkflowDefinition = definition;
130
139
  const workflow = runtime.client.defineWorkflow({ name }, async ({ input, run, step }) => {
131
- return await runWorkflowHandler({
140
+ return await runSerializedWorkflowHandler({
132
141
  id: run.id,
133
142
  name,
134
143
  payload: input,
135
144
  provider: "openworkflow",
136
145
  step: createOpenWorkflowProviderStep(step)
137
- }, definition);
146
+ }, openWorkflowDefinition);
138
147
  });
139
148
  runtime.workflows.set(name, workflow);
140
149
  return workflow;
@@ -143,7 +152,7 @@ function normalizeOpenWorkflowStatus(status) {
143
152
  switch (String(status || "").toLowerCase()) {
144
153
  case "completed":
145
154
  case "succeeded": return "completed";
146
- case "canceled":
155
+ case "canceled": return "cancelled";
147
156
  case "failed": return "failed";
148
157
  case "pending": return "queued";
149
158
  case "running":
@@ -157,6 +166,7 @@ function serializeOpenWorkflowRun(run, name) {
157
166
  provider: "openworkflow",
158
167
  status: "unknown"
159
168
  };
169
+ const result = isSerializedResponse(run.output) ? deserializeResponse(run.output) : run.output;
160
170
  return {
161
171
  id: run.id,
162
172
  metadata: run.error || {
@@ -165,23 +175,31 @@ function serializeOpenWorkflowRun(run, name) {
165
175
  workflowName: run.workflowName
166
176
  },
167
177
  provider: "openworkflow",
168
- result: run.output ?? void 0,
178
+ result,
169
179
  status: normalizeOpenWorkflowStatus(run.status)
170
180
  };
171
181
  }
172
- async function runOpenWorkflow(config, name, payload, definition, options) {
182
+ async function runOpenWorkflow(config, name, payload, definition, options, onDispatch) {
173
183
  const workflow = await registerOpenWorkflowDefinition(await getOpenWorkflowRuntime(config), name, definition);
184
+ onDispatch?.();
185
+ let firstAcknowledgementUnknown = false;
186
+ const handle = await runWorkflowProviderOperation("openworkflow", "run", async () => {
187
+ const start = () => workflow.run(payload, options.id ? { idempotencyKey: options.id } : void 0);
188
+ return await start().catch((error) => {
189
+ if (!options.id) throw error;
190
+ firstAcknowledgementUnknown = getWorkflowProviderStatus(error) === void 0;
191
+ return start();
192
+ });
193
+ }, { acknowledgementUnknown: (_error, status) => firstAcknowledgementUnknown || status === void 0 });
174
194
  return await runWorkflowProviderOperation("openworkflow", "run", async () => {
175
- const handle = await workflow.run(payload, options.id ? { idempotencyKey: options.id } : void 0);
195
+ const serialized = serializeOpenWorkflowRun(handle.workflowRun, name);
176
196
  return {
177
- id: handle.workflowRun.id,
178
- metadata: {
197
+ ...serialized,
198
+ metadata: serialized.status === "failed" ? serialized.metadata : {
179
199
  ...options.id ? { idempotencyKey: options.id } : {},
180
200
  workflow: name
181
201
  },
182
- payload,
183
- provider: "openworkflow",
184
- status: normalizeOpenWorkflowStatus(handle.workflowRun.status)
202
+ payload
185
203
  };
186
204
  });
187
205
  }