@vite-hub/workflow 0.0.0 → 0.0.2
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/README.md +110 -1
- package/dist/_app-DgwN4ulW.d.ts +11 -0
- package/dist/app-BZpq2cwC.js +10 -0
- package/dist/cloudflare-Cds1VIWa.js +42 -0
- package/dist/cloudflare-env-CIjdFTv6.d.ts +22 -0
- package/dist/cloudflare-env-mFp2Uj6Z.js +53 -0
- package/dist/cloudflare-shared-BVVgDSdq.d.ts +1 -0
- package/dist/cloudflare-vite-B0zel2Do.js +39 -0
- package/dist/config-BDqB6I4E.js +130 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.js +357 -0
- package/dist/provider-operation-CWIV4k42.js +62 -0
- package/dist/runtime/cloudflare-runner.d.ts +27 -0
- package/dist/runtime/cloudflare-runner.js +24 -0
- package/dist/runtime/cloudflare-shared.d.ts +2 -0
- package/dist/runtime/cloudflare-shared.js +2 -0
- package/dist/runtime/cloudflare-vite.d.ts +17 -0
- package/dist/runtime/cloudflare-vite.js +2 -0
- package/dist/runtime/execute.d.ts +11 -0
- package/dist/runtime/execute.js +25 -0
- package/dist/runtime/openworkflow-worker.d.ts +20 -0
- package/dist/runtime/openworkflow-worker.js +112 -0
- package/dist/runtime/openworkflow.d.ts +23 -0
- package/dist/runtime/openworkflow.js +216 -0
- package/dist/runtime/state.d.ts +35 -0
- package/dist/runtime/state.js +179 -0
- package/dist/runtime/vercel-vite.d.ts +69 -0
- package/dist/runtime/vercel-vite.js +49 -0
- package/dist/types-BUlYBZwH.d.ts +163 -0
- package/dist/vercel-D2_J5D_Y.js +217 -0
- package/dist/vite.d.ts +13 -0
- package/dist/vite.js +2037 -0
- package/package.json +90 -5
package/dist/index.js
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { t as normalizeWorkflowOptions } from "./config-BDqB6I4E.js";
|
|
2
|
+
import { a as encodeNameHex, i as getCloudflareWorkflowName, n as getCloudflareWorkflowBindingName, r as getCloudflareWorkflowClassName } from "./cloudflare-Cds1VIWa.js";
|
|
3
|
+
import { i as createWorkflowError, n as runWorkflowProviderOperation, r as safeWorkflowName } from "./provider-operation-CWIV4k42.js";
|
|
4
|
+
import { n as getCloudflareEnv, r as resolveWaitUntil } from "./cloudflare-env-mFp2Uj6Z.js";
|
|
5
|
+
import { runWorkflowHandler } from "./runtime/execute.js";
|
|
6
|
+
import { getOpenWorkflowRun, runOpenWorkflow } from "./runtime/openworkflow.js";
|
|
7
|
+
import { getWorkflowRunState, getWorkflowRuntimeConfig, getWorkflowRuntimeEvent, loadWorkflowDefinition, registerInlineWorkflowDefinition, runWithWorkflowRuntimeEvent, setWorkflowRun } from "./runtime/state.js";
|
|
8
|
+
import { a as startVercelWorkflow, n as inspectVercelWorkflowRun, r as resumeVercelWorkflowSignal, t as cancelVercelWorkflow } from "./vercel-D2_J5D_Y.js";
|
|
9
|
+
import { t as createWorkflowCloudflareWorker } from "./cloudflare-vite-B0zel2Do.js";
|
|
10
|
+
//#region src/definition.ts
|
|
11
|
+
function defineWorkflow(handler, options) {
|
|
12
|
+
if (typeof handler !== "function") throw new TypeError("`defineWorkflow()` requires a workflow handler.");
|
|
13
|
+
if (typeof options !== "undefined" && (!options || typeof options !== "object" || Array.isArray(options))) throw new TypeError("`defineWorkflow()` options must be a plain object.");
|
|
14
|
+
if (options?.native !== void 0 && typeof options.native !== "function") throw new TypeError("`defineWorkflow()` native entry must be a workflow handler.");
|
|
15
|
+
return {
|
|
16
|
+
handler,
|
|
17
|
+
options
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/integrations/vercel.ts
|
|
22
|
+
function getVercelWorkflowName(name) {
|
|
23
|
+
return `workflow--${encodeNameHex(name)}`;
|
|
24
|
+
}
|
|
25
|
+
//#endregion
|
|
26
|
+
//#region ../internal/src/runtime/random.ts
|
|
27
|
+
function randomId(prefix) {
|
|
28
|
+
const body = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
29
|
+
return prefix ? `${prefix}_${body}` : body;
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/runtime/adapters.ts
|
|
33
|
+
function unsupportedOperation(provider, operation) {
|
|
34
|
+
throw createWorkflowError({
|
|
35
|
+
code: "WORKFLOW_OPERATION_UNSUPPORTED",
|
|
36
|
+
details: {
|
|
37
|
+
operation,
|
|
38
|
+
provider
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function resolveCloudflareBinding(event, binding, name) {
|
|
43
|
+
const bindingName = binding || getCloudflareWorkflowBindingName(name);
|
|
44
|
+
return getCloudflareEnv(event)?.[bindingName];
|
|
45
|
+
}
|
|
46
|
+
const cloudflareStatusMap = {
|
|
47
|
+
cancelled: "cancelled",
|
|
48
|
+
complete: "completed",
|
|
49
|
+
completed: "completed",
|
|
50
|
+
errored: "failed",
|
|
51
|
+
failed: "failed",
|
|
52
|
+
queued: "queued",
|
|
53
|
+
running: "running",
|
|
54
|
+
success: "completed",
|
|
55
|
+
terminated: "failed"
|
|
56
|
+
};
|
|
57
|
+
function normalizeCloudflareStatus(status) {
|
|
58
|
+
const value = typeof status === "object" && status ? status.status : status;
|
|
59
|
+
return cloudflareStatusMap[String(value || "").toLowerCase()] || "unknown";
|
|
60
|
+
}
|
|
61
|
+
function createCloudflareAdapter(config) {
|
|
62
|
+
return {
|
|
63
|
+
cancel: () => unsupportedOperation("cloudflare", "cancellation"),
|
|
64
|
+
async get({ event, id, name }) {
|
|
65
|
+
const binding = resolveCloudflareBinding(event, config.binding, name);
|
|
66
|
+
if (binding) {
|
|
67
|
+
const instance = await runWorkflowProviderOperation("cloudflare", "get", () => binding.get(id));
|
|
68
|
+
const metadata = await runWorkflowProviderOperation("cloudflare", "status", () => instance.status());
|
|
69
|
+
return {
|
|
70
|
+
id,
|
|
71
|
+
metadata,
|
|
72
|
+
provider: "cloudflare",
|
|
73
|
+
status: normalizeCloudflareStatus(metadata)
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return await inlineAdapter(config).get({
|
|
77
|
+
event,
|
|
78
|
+
id,
|
|
79
|
+
name
|
|
80
|
+
});
|
|
81
|
+
},
|
|
82
|
+
async run({ definition, event, id, name, options, payload }) {
|
|
83
|
+
const binding = resolveCloudflareBinding(event, config.binding, name);
|
|
84
|
+
if (binding) {
|
|
85
|
+
const start = runWorkflowProviderOperation("cloudflare", "create", () => binding.create({
|
|
86
|
+
id,
|
|
87
|
+
params: payload
|
|
88
|
+
}));
|
|
89
|
+
const waitUntil = options.deferred ? resolveWaitUntil(event) : void 0;
|
|
90
|
+
if (waitUntil) waitUntil(start);
|
|
91
|
+
const instance = await start;
|
|
92
|
+
return {
|
|
93
|
+
id: instance.id,
|
|
94
|
+
metadata: await runWorkflowProviderOperation("cloudflare", "status", () => instance.status()),
|
|
95
|
+
payload,
|
|
96
|
+
provider: "cloudflare",
|
|
97
|
+
status: "queued"
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return await inlineAdapter(config).run({
|
|
101
|
+
definition,
|
|
102
|
+
event,
|
|
103
|
+
id,
|
|
104
|
+
name,
|
|
105
|
+
options,
|
|
106
|
+
payload
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
resume: () => unsupportedOperation("cloudflare", "signals")
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function createOpenWorkflowAdapter(config) {
|
|
113
|
+
return {
|
|
114
|
+
cancel: () => unsupportedOperation("openworkflow", "cancellation"),
|
|
115
|
+
get: async ({ id, name }) => await getOpenWorkflowRun(config, name, id),
|
|
116
|
+
resume: () => unsupportedOperation("openworkflow", "signals"),
|
|
117
|
+
run: async ({ definition, name, options, payload }) => await runOpenWorkflow(config, name, payload, definition, options)
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function inlineAdapter(config) {
|
|
121
|
+
return {
|
|
122
|
+
cancel: () => unsupportedOperation(config.provider, "cancellation"),
|
|
123
|
+
async get({ id, name }) {
|
|
124
|
+
const run = getWorkflowRunState(name, id);
|
|
125
|
+
if (run) {
|
|
126
|
+
if (run.status === "running") return {
|
|
127
|
+
id,
|
|
128
|
+
provider: config.provider,
|
|
129
|
+
status: "running"
|
|
130
|
+
};
|
|
131
|
+
return {
|
|
132
|
+
id,
|
|
133
|
+
metadata: run.error,
|
|
134
|
+
provider: config.provider,
|
|
135
|
+
result: run.result,
|
|
136
|
+
status: run.status
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
id,
|
|
141
|
+
provider: config.provider,
|
|
142
|
+
status: "unknown"
|
|
143
|
+
};
|
|
144
|
+
},
|
|
145
|
+
async run({ definition, event, id, name, payload }) {
|
|
146
|
+
const runState = setWorkflowRun(name, id, Promise.resolve().then(() => runWorkflowHandler({
|
|
147
|
+
id,
|
|
148
|
+
name,
|
|
149
|
+
payload,
|
|
150
|
+
provider: config.provider
|
|
151
|
+
}, definition)).then((result) => ({
|
|
152
|
+
result,
|
|
153
|
+
status: "completed"
|
|
154
|
+
})).catch((error) => ({
|
|
155
|
+
error,
|
|
156
|
+
status: "failed"
|
|
157
|
+
})));
|
|
158
|
+
const waitUntil = resolveWaitUntil(event);
|
|
159
|
+
if (waitUntil) waitUntil(runState.promise);
|
|
160
|
+
return {
|
|
161
|
+
id,
|
|
162
|
+
metadata: config.provider === "vercel" ? {
|
|
163
|
+
mode: "inline",
|
|
164
|
+
workflow: getVercelWorkflowName(name)
|
|
165
|
+
} : void 0,
|
|
166
|
+
payload,
|
|
167
|
+
provider: config.provider,
|
|
168
|
+
status: "queued"
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
resume: () => unsupportedOperation(config.provider, "signals")
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
function createVercelAdapter(config) {
|
|
175
|
+
const fallback = inlineAdapter(config);
|
|
176
|
+
return {
|
|
177
|
+
async cancel({ id, name }) {
|
|
178
|
+
const definition = await loadWorkflowDefinition(name);
|
|
179
|
+
if (!definition?.options?.native) return await fallback.cancel({
|
|
180
|
+
event: void 0,
|
|
181
|
+
id,
|
|
182
|
+
name
|
|
183
|
+
});
|
|
184
|
+
return await cancelVercelWorkflow(name, definition, id);
|
|
185
|
+
},
|
|
186
|
+
async get({ id, name }) {
|
|
187
|
+
const definition = await loadWorkflowDefinition(name);
|
|
188
|
+
return definition?.options?.native ? await inspectVercelWorkflowRun(name, definition, id) : await fallback.get({
|
|
189
|
+
event: void 0,
|
|
190
|
+
id,
|
|
191
|
+
name
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
resume: async (token, payload) => await resumeVercelWorkflowSignal(token, payload),
|
|
195
|
+
async run({ definition, event, id, name, options, payload }) {
|
|
196
|
+
if (!definition.options?.native) return await fallback.run({
|
|
197
|
+
definition,
|
|
198
|
+
event,
|
|
199
|
+
id,
|
|
200
|
+
name,
|
|
201
|
+
options,
|
|
202
|
+
payload
|
|
203
|
+
});
|
|
204
|
+
if (options.id) throw createWorkflowError({
|
|
205
|
+
code: "WORKFLOW_RUN_ID_UNSUPPORTED",
|
|
206
|
+
details: {
|
|
207
|
+
...safeWorkflowName(name) ? { name } : {},
|
|
208
|
+
provider: "vercel"
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return await startVercelWorkflow(name, definition, payload);
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function getWorkflowRuntimeAdapter(config) {
|
|
216
|
+
if (config.provider === "cloudflare") return createCloudflareAdapter(config);
|
|
217
|
+
if (config.provider === "openworkflow") return createOpenWorkflowAdapter(config);
|
|
218
|
+
return createVercelAdapter(config);
|
|
219
|
+
}
|
|
220
|
+
//#endregion
|
|
221
|
+
//#region src/runtime/client.ts
|
|
222
|
+
function getActiveWorkflowConfig() {
|
|
223
|
+
const config = getWorkflowRuntimeConfig();
|
|
224
|
+
if (config === false) return false;
|
|
225
|
+
return config || normalizeWorkflowOptions(void 0, { hosting: "vercel" });
|
|
226
|
+
}
|
|
227
|
+
async function loadRequiredWorkflowDefinition(name) {
|
|
228
|
+
const definition = await loadWorkflowDefinition(name);
|
|
229
|
+
if (!definition) throw createWorkflowError({
|
|
230
|
+
code: "WORKFLOW_DEFINITION_NOT_FOUND",
|
|
231
|
+
details: safeWorkflowName(name) ? { name } : void 0
|
|
232
|
+
});
|
|
233
|
+
return definition;
|
|
234
|
+
}
|
|
235
|
+
function normalizeWorkflowRunIdValue(value) {
|
|
236
|
+
if (value === void 0) return null;
|
|
237
|
+
if (value === null || typeof value !== "object") return value;
|
|
238
|
+
if (Array.isArray(value)) return value.map((item) => normalizeWorkflowRunIdValue(item));
|
|
239
|
+
const record = value;
|
|
240
|
+
return Object.fromEntries(Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, normalizeWorkflowRunIdValue(record[key])]));
|
|
241
|
+
}
|
|
242
|
+
async function sha256Hex(value) {
|
|
243
|
+
const data = new TextEncoder().encode(value);
|
|
244
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
245
|
+
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
246
|
+
}
|
|
247
|
+
async function createStableWorkflowRunId(name, value) {
|
|
248
|
+
const hash = await sha256Hex(`${name}:${JSON.stringify(normalizeWorkflowRunIdValue(value))}`);
|
|
249
|
+
return `${name.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "workflow"}-${hash.slice(0, 32)}`;
|
|
250
|
+
}
|
|
251
|
+
async function resolveWorkflowStartOptions(name, payload, createOptions, startOptions) {
|
|
252
|
+
if (startOptions.id || !createOptions?.id) return startOptions;
|
|
253
|
+
return {
|
|
254
|
+
...startOptions,
|
|
255
|
+
id: await createStableWorkflowRunId(name, await createOptions.id({
|
|
256
|
+
name,
|
|
257
|
+
payload
|
|
258
|
+
}))
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
function createWorkflow(nameOrOptions, handlerOrOptions, options) {
|
|
262
|
+
if (typeof nameOrOptions === "object" && nameOrOptions !== null) {
|
|
263
|
+
const createOptions = nameOrOptions;
|
|
264
|
+
const { handler, name } = createOptions;
|
|
265
|
+
if (!name || typeof name !== "string") throw new TypeError("`createWorkflow()` requires a workflow name.");
|
|
266
|
+
if (typeof handler !== "function") throw new TypeError("`createWorkflow()` requires a workflow handler.");
|
|
267
|
+
registerInlineWorkflowDefinition(name, { handler });
|
|
268
|
+
return {
|
|
269
|
+
cancel: (id) => cancelWorkflow(name, id),
|
|
270
|
+
name,
|
|
271
|
+
defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
|
|
272
|
+
getRun: (id) => getWorkflowRun(name, id),
|
|
273
|
+
run: async (payload, options = {}) => runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options))
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
const name = nameOrOptions;
|
|
277
|
+
if (!name || typeof name !== "string") throw new TypeError("`createWorkflow()` requires a workflow name.");
|
|
278
|
+
const handler = typeof handlerOrOptions === "function" ? handlerOrOptions : typeof handlerOrOptions === "object" && handlerOrOptions !== null ? handlerOrOptions.handler : void 0;
|
|
279
|
+
const createOptions = typeof handlerOrOptions === "function" ? options : handlerOrOptions;
|
|
280
|
+
if (handler !== void 0) {
|
|
281
|
+
if (typeof handler !== "function") throw new TypeError("`createWorkflow()` requires a workflow handler.");
|
|
282
|
+
registerInlineWorkflowDefinition(name, { handler });
|
|
283
|
+
} else if (handlerOrOptions !== void 0 && (typeof handlerOrOptions !== "object" || handlerOrOptions === null)) throw new TypeError("`createWorkflow()` options must be an object.");
|
|
284
|
+
return {
|
|
285
|
+
cancel: (id) => cancelWorkflow(name, id),
|
|
286
|
+
name,
|
|
287
|
+
defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
|
|
288
|
+
getRun: (id) => getWorkflowRun(name, id),
|
|
289
|
+
run: async (payload, options = {}) => runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options))
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
async function runWorkflow(name, payload, options = {}) {
|
|
293
|
+
const config = getActiveWorkflowConfig();
|
|
294
|
+
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
295
|
+
const id = options.id || randomId("wrun");
|
|
296
|
+
const definition = await loadRequiredWorkflowDefinition(name);
|
|
297
|
+
return await getWorkflowRuntimeAdapter(config).run({
|
|
298
|
+
definition,
|
|
299
|
+
event: getWorkflowRuntimeEvent(),
|
|
300
|
+
id,
|
|
301
|
+
name,
|
|
302
|
+
options,
|
|
303
|
+
payload
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
async function getWorkflowRun(name, id) {
|
|
307
|
+
const config = getActiveWorkflowConfig();
|
|
308
|
+
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
309
|
+
return await getWorkflowRuntimeAdapter(config).get({
|
|
310
|
+
event: getWorkflowRuntimeEvent(),
|
|
311
|
+
id,
|
|
312
|
+
name
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
async function cancelWorkflow(name, id) {
|
|
316
|
+
const config = getActiveWorkflowConfig();
|
|
317
|
+
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
318
|
+
await loadRequiredWorkflowDefinition(name);
|
|
319
|
+
return await getWorkflowRuntimeAdapter(config).cancel({
|
|
320
|
+
event: getWorkflowRuntimeEvent(),
|
|
321
|
+
id,
|
|
322
|
+
name
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
async function resumeWorkflowSignal(token, payload) {
|
|
326
|
+
if (!token || typeof token !== "string") throw new TypeError("`resumeWorkflowSignal()` requires an opaque signal token.");
|
|
327
|
+
const config = getActiveWorkflowConfig();
|
|
328
|
+
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
329
|
+
return await getWorkflowRuntimeAdapter(config).resume(token, payload);
|
|
330
|
+
}
|
|
331
|
+
function deferWorkflow(name, payload, options = {}) {
|
|
332
|
+
return runWithWorkflowRuntimeEvent(getWorkflowRuntimeEvent(), () => runWorkflow(name, payload, {
|
|
333
|
+
...options,
|
|
334
|
+
deferred: true
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/runtime/payload.ts
|
|
339
|
+
async function readRequestPayload(request) {
|
|
340
|
+
if ((request.headers.get("content-type") || "").includes("application/json")) return await request.json();
|
|
341
|
+
return await request.text();
|
|
342
|
+
}
|
|
343
|
+
async function validatePayload(payload, schema) {
|
|
344
|
+
if (typeof schema === "function") return await schema(payload);
|
|
345
|
+
if ("safeParse" in schema && typeof schema.safeParse === "function") {
|
|
346
|
+
const result = schema.safeParse(payload);
|
|
347
|
+
if (!result.success) throw result.error || /* @__PURE__ */ new TypeError("Invalid workflow payload.");
|
|
348
|
+
return result.data;
|
|
349
|
+
}
|
|
350
|
+
if ("parse" in schema && typeof schema.parse === "function") return schema.parse(payload);
|
|
351
|
+
throw new TypeError("Invalid workflow payload schema.");
|
|
352
|
+
}
|
|
353
|
+
async function readValidatedPayload(request, schema) {
|
|
354
|
+
return await validatePayload(await readRequestPayload(request), schema);
|
|
355
|
+
}
|
|
356
|
+
//#endregion
|
|
357
|
+
export { cancelWorkflow, createWorkflow, createWorkflowCloudflareWorker, deferWorkflow, defineWorkflow, getCloudflareWorkflowBindingName, getCloudflareWorkflowClassName, getCloudflareWorkflowName, getVercelWorkflowName, getWorkflowRun, normalizeWorkflowOptions, readRequestPayload, readValidatedPayload, resumeWorkflowSignal, runWorkflow, validatePayload };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ViteHubError, getViteHubErrorShape } from "@vite-hub/runtime";
|
|
2
|
+
//#region src/errors.ts
|
|
3
|
+
const workflowErrorMessages = {
|
|
4
|
+
OPENWORKFLOW_BACKEND_CLOSE_FAILED: "OpenWorkflow backend cleanup failed.",
|
|
5
|
+
OPENWORKFLOW_RUNTIME_RESET: "OpenWorkflow runtime was reset while it was being acquired.",
|
|
6
|
+
OPENWORKFLOW_WORKER_STOP_FAILED: "OpenWorkflow worker stop failed.",
|
|
7
|
+
VERCEL_WORKFLOW_SDK_LOAD_FAILED: "Vercel Workflow DevKit load failed. Install the optional workflow peer dependency.",
|
|
8
|
+
WORKFLOW_DEFINITION_NOT_FOUND: "Workflow definition was not found.",
|
|
9
|
+
WORKFLOW_DISABLED: "Workflow is disabled.",
|
|
10
|
+
WORKFLOW_NATIVE_ENTRY_INVALID: "Workflow has no transformed native Vercel entry.",
|
|
11
|
+
WORKFLOW_NATIVE_ENTRY_REQUIRED: "Workflow has no native durable entry for Vercel.",
|
|
12
|
+
WORKFLOW_OPERATION_UNSUPPORTED: "Workflow provider operation is unsupported.",
|
|
13
|
+
WORKFLOW_PROVIDER_OPERATION_FAILED: "Workflow provider operation failed.",
|
|
14
|
+
WORKFLOW_RUN_ID_UNSUPPORTED: "Native Vercel workflows assign their own run IDs."
|
|
15
|
+
};
|
|
16
|
+
function createWorkflowError(options) {
|
|
17
|
+
return new ViteHubError(options.code, workflowErrorMessages[options.code], options);
|
|
18
|
+
}
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/runtime/provider-operation.ts
|
|
21
|
+
function isWorkflowBoundaryError(error) {
|
|
22
|
+
if (getViteHubErrorShape(error)) return true;
|
|
23
|
+
if (typeof error !== "object" || error === null) return false;
|
|
24
|
+
try {
|
|
25
|
+
return "name" in error && error.name === "AbortError";
|
|
26
|
+
} catch {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function getProviderStatus(error) {
|
|
31
|
+
if (typeof error !== "object" || error === null) return void 0;
|
|
32
|
+
try {
|
|
33
|
+
const value = error;
|
|
34
|
+
const response = typeof value.response === "object" && value.response !== null ? value.response : void 0;
|
|
35
|
+
const status = value.status ?? value.statusCode ?? response?.status;
|
|
36
|
+
return typeof status === "number" && Number.isInteger(status) && status >= 400 && status <= 599 ? status : void 0;
|
|
37
|
+
} catch {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async function runWorkflowProviderOperation(provider, operation, run) {
|
|
42
|
+
try {
|
|
43
|
+
return await run();
|
|
44
|
+
} catch (error) {
|
|
45
|
+
if (isWorkflowBoundaryError(error)) throw error;
|
|
46
|
+
const status = getProviderStatus(error);
|
|
47
|
+
throw createWorkflowError({
|
|
48
|
+
cause: error,
|
|
49
|
+
code: "WORKFLOW_PROVIDER_OPERATION_FAILED",
|
|
50
|
+
details: {
|
|
51
|
+
operation,
|
|
52
|
+
provider,
|
|
53
|
+
...status === void 0 ? {} : { status }
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function safeWorkflowName(name) {
|
|
59
|
+
return /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(name) ? name : void 0;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { createWorkflowError as i, runWorkflowProviderOperation as n, safeWorkflowName as r, isWorkflowBoundaryError as t };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { C as WorkflowProviderStep, h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-BUlYBZwH.js";
|
|
2
|
+
import { t as CloudflareWorkerEnv } from "../cloudflare-env-CIjdFTv6.js";
|
|
3
|
+
|
|
4
|
+
//#region src/runtime/cloudflare-runner.d.ts
|
|
5
|
+
interface CloudflareWorkflowEvent {
|
|
6
|
+
id?: string;
|
|
7
|
+
instanceId?: string;
|
|
8
|
+
payload?: unknown;
|
|
9
|
+
}
|
|
10
|
+
interface RunCloudflareWorkflowOptions {
|
|
11
|
+
config: false | ResolvedWorkflowOptions | undefined;
|
|
12
|
+
env: CloudflareWorkerEnv;
|
|
13
|
+
event: CloudflareWorkflowEvent;
|
|
14
|
+
name: string;
|
|
15
|
+
registry: WorkflowDefinitionRegistry;
|
|
16
|
+
step?: WorkflowProviderStep;
|
|
17
|
+
}
|
|
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 };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { i as runWithActiveCloudflareEnv } from "../cloudflare-env-mFp2Uj6Z.js";
|
|
2
|
+
import { runWorkflowHandler } from "./execute.js";
|
|
3
|
+
import { loadWorkflowDefinition, runWithWorkflowRuntimeEvent, setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry } from "./state.js";
|
|
4
|
+
//#region src/runtime/cloudflare-runner.ts
|
|
5
|
+
async function runCloudflareWorkflow({ config, env, event, name, registry, step }) {
|
|
6
|
+
setWorkflowRuntimeConfig(config);
|
|
7
|
+
setWorkflowRuntimeRegistry(registry);
|
|
8
|
+
return await runWithActiveCloudflareEnv(env, async () => {
|
|
9
|
+
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));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
//#endregion
|
|
24
|
+
export { runCloudflareWorkflow };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as setActiveCloudflareEnv, i as runWithActiveCloudflareEnv, n as CloudflareWorkerExecutionContext, r as createCloudflareRuntimeEvent, t as CloudflareWorkerEnv } from "../cloudflare-env-CIjdFTv6.js";
|
|
2
|
+
export { type CloudflareWorkerEnv, type CloudflareWorkerExecutionContext, createCloudflareRuntimeEvent, runWithActiveCloudflareEnv, setActiveCloudflareEnv };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-BUlYBZwH.js";
|
|
2
|
+
import { t as WorkflowApp } from "../_app-DgwN4ulW.js";
|
|
3
|
+
import { n as CloudflareWorkerExecutionContext, t as CloudflareWorkerEnv } from "../cloudflare-env-CIjdFTv6.js";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/cloudflare-vite.d.ts
|
|
6
|
+
type CloudflareWorkerApp = WorkflowApp;
|
|
7
|
+
interface WorkflowCloudflareWorkerOptions {
|
|
8
|
+
app?: CloudflareWorkerApp;
|
|
9
|
+
registry?: WorkflowDefinitionRegistry;
|
|
10
|
+
workflow?: false | ResolvedWorkflowOptions;
|
|
11
|
+
}
|
|
12
|
+
interface WorkflowCloudflareWorker {
|
|
13
|
+
fetch: (request: Request, env: CloudflareWorkerEnv, context: CloudflareWorkerExecutionContext) => Promise<Response>;
|
|
14
|
+
}
|
|
15
|
+
declare function createWorkflowCloudflareWorker(options?: WorkflowCloudflareWorkerOptions): WorkflowCloudflareWorker;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { CloudflareWorkerApp, WorkflowCloudflareWorker, WorkflowCloudflareWorkerOptions, createWorkflowCloudflareWorker };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { A as WorkflowStepFunction, C as WorkflowProviderStep, g as WorkflowExecutionContext, j as WorkflowStepOptions, p as WorkflowDefinition } from "../types-BUlYBZwH.js";
|
|
2
|
+
|
|
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<{
|
|
6
|
+
name: string;
|
|
7
|
+
run: WorkflowStepFunction;
|
|
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 };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/runtime/execute.ts
|
|
2
|
+
const defaultStepOptions = { retries: {
|
|
3
|
+
backoff: "exponential",
|
|
4
|
+
delay: "10 seconds",
|
|
5
|
+
limit: 3
|
|
6
|
+
} };
|
|
7
|
+
async function runProviderStep(step, name, run, options = defaultStepOptions) {
|
|
8
|
+
if (typeof step?.do === "function") return await step.do(name, options, run);
|
|
9
|
+
return await run();
|
|
10
|
+
}
|
|
11
|
+
function toStepPropertyName(file) {
|
|
12
|
+
return file.split("/").pop().replace(/\.(?:c|m)?[jt]s$/i, "").replace(/^\d+[.-]?/, "").replace(/[-_.]+([a-z0-9])/gi, (_, char) => char.toUpperCase());
|
|
13
|
+
}
|
|
14
|
+
function createWorkflowSteps(context, stepModules) {
|
|
15
|
+
return Object.fromEntries(stepModules.map((module) => {
|
|
16
|
+
return [toStepPropertyName(module.name), async (input) => await runProviderStep(context.step, `${context.name}/${module.name}`, () => module.run(input))];
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
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);
|
|
23
|
+
}
|
|
24
|
+
//#endregion
|
|
25
|
+
export { createWorkflowSteps, runProviderStep, runWorkflowHandler };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { h as WorkflowDefinitionRegistry, l as ResolvedWorkflowOptions } from "../types-BUlYBZwH.js";
|
|
2
|
+
import { getOpenWorkflowRuntime } from "./openworkflow.js";
|
|
3
|
+
import { ViteHubError } from "@vite-hub/runtime";
|
|
4
|
+
|
|
5
|
+
//#region src/runtime/openworkflow-worker.d.ts
|
|
6
|
+
type OpenWorkflowWorker = ReturnType<Awaited<ReturnType<typeof getOpenWorkflowRuntime>>["client"]["newWorker"]>;
|
|
7
|
+
interface CreateOpenWorkflowWorkerOptions {
|
|
8
|
+
concurrency?: number;
|
|
9
|
+
config?: false | ResolvedWorkflowOptions;
|
|
10
|
+
registry?: WorkflowDefinitionRegistry;
|
|
11
|
+
}
|
|
12
|
+
interface StartOpenWorkflowWorkerOptions extends CreateOpenWorkflowWorkerOptions {
|
|
13
|
+
onError?: (error: ViteHubError) => Promise<void> | void;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
signals?: boolean;
|
|
16
|
+
}
|
|
17
|
+
declare function createOpenWorkflowWorker(options?: CreateOpenWorkflowWorkerOptions): Promise<OpenWorkflowWorker>;
|
|
18
|
+
declare function startOpenWorkflowWorker(options?: StartOpenWorkflowWorkerOptions): Promise<OpenWorkflowWorker>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { CreateOpenWorkflowWorkerOptions, StartOpenWorkflowWorkerOptions, createOpenWorkflowWorker, startOpenWorkflowWorker };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { i as createWorkflowError } from "../provider-operation-CWIV4k42.js";
|
|
2
|
+
import { getOpenWorkflowRuntime, registerOpenWorkflowDefinition } from "./openworkflow.js";
|
|
3
|
+
import { getInlineWorkflowDefinitions, getWorkflowRuntimeConfig, getWorkflowRuntimeRegistry, setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry, takeInlineWorkflowDefinitionForModule } from "./state.js";
|
|
4
|
+
import "@vite-hub/runtime";
|
|
5
|
+
//#region src/runtime/openworkflow-worker.ts
|
|
6
|
+
function getProcess() {
|
|
7
|
+
return globalThis.process;
|
|
8
|
+
}
|
|
9
|
+
async function loadRegistryDefinitions(registry) {
|
|
10
|
+
const definitions = /* @__PURE__ */ new Map();
|
|
11
|
+
for (const name of Object.keys(registry).sort()) {
|
|
12
|
+
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") {
|
|
15
|
+
definitions.set(name, definition);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const inlineDefinition = takeInlineWorkflowDefinitionForModule(name, loaded);
|
|
19
|
+
if (inlineDefinition) definitions.set(name, inlineDefinition);
|
|
20
|
+
}
|
|
21
|
+
return definitions;
|
|
22
|
+
}
|
|
23
|
+
function mergeInlineDefinitions(definitions) {
|
|
24
|
+
for (const [name, definition] of getInlineWorkflowDefinitions()) {
|
|
25
|
+
const existing = definitions.get(name);
|
|
26
|
+
if (existing && existing !== definition) throw new Error(`Duplicate workflow name "${name}" from inline and discovered definitions.`);
|
|
27
|
+
definitions.set(name, definition);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
async function createOpenWorkflowWorker(options = {}) {
|
|
31
|
+
const config = options.config ?? getWorkflowRuntimeConfig();
|
|
32
|
+
if (!config || config.provider !== "openworkflow") throw new Error("OpenWorkflow worker requires workflow.provider \"openworkflow\".");
|
|
33
|
+
const registry = options.registry ?? getWorkflowRuntimeRegistry() ?? {};
|
|
34
|
+
setWorkflowRuntimeConfig(config);
|
|
35
|
+
setWorkflowRuntimeRegistry(registry);
|
|
36
|
+
const runtime = await getOpenWorkflowRuntime(config);
|
|
37
|
+
const definitions = await loadRegistryDefinitions(registry);
|
|
38
|
+
mergeInlineDefinitions(definitions);
|
|
39
|
+
for (const [name, definition] of definitions) await registerOpenWorkflowDefinition(runtime, name, definition);
|
|
40
|
+
return runtime.client.newWorker({ concurrency: options.concurrency ?? config.worker?.concurrency });
|
|
41
|
+
}
|
|
42
|
+
async function startOpenWorkflowWorker(options = {}) {
|
|
43
|
+
const worker = await createOpenWorkflowWorker(options);
|
|
44
|
+
await worker.start();
|
|
45
|
+
const originalStop = worker.stop.bind(worker);
|
|
46
|
+
const proc = getProcess();
|
|
47
|
+
let abortListenerActive = false;
|
|
48
|
+
let processListenersActive = false;
|
|
49
|
+
let stopTask;
|
|
50
|
+
const removeListeners = () => {
|
|
51
|
+
if (abortListenerActive) {
|
|
52
|
+
abortListenerActive = false;
|
|
53
|
+
options.signal?.removeEventListener("abort", requestStop);
|
|
54
|
+
}
|
|
55
|
+
if (processListenersActive) {
|
|
56
|
+
processListenersActive = false;
|
|
57
|
+
proc?.off?.("SIGINT", requestStop);
|
|
58
|
+
proc?.off?.("SIGTERM", requestStop);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const stop = () => {
|
|
62
|
+
removeListeners();
|
|
63
|
+
stopTask ??= Promise.resolve().then(() => originalStop()).catch((cause) => {
|
|
64
|
+
throw createWorkflowError({
|
|
65
|
+
cause,
|
|
66
|
+
code: "OPENWORKFLOW_WORKER_STOP_FAILED",
|
|
67
|
+
details: { provider: "openworkflow" }
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
return stopTask;
|
|
71
|
+
};
|
|
72
|
+
const reportUnhandledError = (error) => {
|
|
73
|
+
try {
|
|
74
|
+
if (proc?.emitWarning) proc.emitWarning(error);
|
|
75
|
+
else console.error(error);
|
|
76
|
+
} catch {}
|
|
77
|
+
};
|
|
78
|
+
const reportError = (error) => {
|
|
79
|
+
if (!options.onError) {
|
|
80
|
+
reportUnhandledError(error);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
try {
|
|
84
|
+
Promise.resolve(options.onError(error)).catch(() => {
|
|
85
|
+
reportUnhandledError(error);
|
|
86
|
+
});
|
|
87
|
+
} catch {
|
|
88
|
+
reportUnhandledError(error);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
function requestStop() {
|
|
92
|
+
stop().catch(reportError);
|
|
93
|
+
}
|
|
94
|
+
Object.defineProperty(worker, "stop", {
|
|
95
|
+
configurable: true,
|
|
96
|
+
value: stop,
|
|
97
|
+
writable: true
|
|
98
|
+
});
|
|
99
|
+
if (options.signal) {
|
|
100
|
+
abortListenerActive = true;
|
|
101
|
+
options.signal.addEventListener("abort", requestStop, { once: true });
|
|
102
|
+
}
|
|
103
|
+
if (options.signals !== false && proc?.on && proc.off) {
|
|
104
|
+
processListenersActive = true;
|
|
105
|
+
proc.on("SIGINT", requestStop);
|
|
106
|
+
proc.on("SIGTERM", requestStop);
|
|
107
|
+
}
|
|
108
|
+
if (options.signal?.aborted) requestStop();
|
|
109
|
+
return worker;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { createOpenWorkflowWorker, startOpenWorkflowWorker };
|