@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.
- package/LICENSE +201 -0
- package/README.md +187 -56
- package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
- package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
- package/dist/client-DsGM3M4U.js +389 -0
- package/dist/cloudflare-env-BNrYo29x.js +113 -0
- package/dist/cloudflare-nF4abPd4.js +59 -0
- package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
- package/dist/{cloudflare-vite-B0zel2Do.js → cloudflare-vite-B3IabBsv.js} +18 -10
- package/dist/{config-BDqB6I4E.js → config-IJMb0eeZ.js} +39 -25
- package/dist/error-diagnostics-A_8Kp-48.js +116 -0
- package/dist/error-diagnostics-pwNFvAHP.js +67 -0
- package/dist/index.d.ts +24 -20
- package/dist/index.js +25 -334
- package/dist/inspect-B72iFyj-.js +70 -0
- package/dist/operations-B_rYG71W.js +230 -0
- package/dist/operations-tNUdj3G4.d.ts +212 -0
- package/dist/operations.d.ts +37 -0
- package/dist/operations.js +887 -0
- package/dist/out-CsaJxg8m.js +21755 -0
- package/dist/{provider-operation-CWIV4k42.js → provider-operation-CW2cYfVy.js} +13 -10
- package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
- package/dist/runtime/cloudflare-runner.d.ts +8 -14
- package/dist/runtime/cloudflare-runner.js +77 -14
- package/dist/runtime/cloudflare-shared.d.ts +1 -0
- package/dist/runtime/cloudflare-shared.js +1 -1
- package/dist/runtime/cloudflare-vite.d.ts +8 -9
- package/dist/runtime/cloudflare-vite.js +2 -2
- package/dist/runtime/execute.d.ts +8 -7
- package/dist/runtime/execute.js +28 -5
- package/dist/runtime/openworkflow-worker.d.ts +6 -8
- package/dist/runtime/openworkflow-worker.js +43 -6
- package/dist/runtime/openworkflow.d.ts +8 -10
- package/dist/runtime/openworkflow.js +50 -32
- package/dist/runtime/state.d.ts +20 -21
- package/dist/runtime/state.js +90 -20
- package/dist/runtime/vercel-vite.d.ts +10 -11
- package/dist/runtime/vercel-vite.js +11 -8
- package/dist/runtime-type-DBCvIh5x.js +7 -0
- package/dist/{types-BUlYBZwH.d.ts → types-D82WmfZa.d.ts} +35 -18
- package/dist/{vercel-D2_J5D_Y.js → vercel-D-ZNtB_u.js} +59 -26
- package/dist/vite.d.ts +365 -6
- package/dist/vite.js +4667 -910
- package/package.json +78 -28
- package/dist/cloudflare-Cds1VIWa.js +0 -42
- package/dist/cloudflare-env-mFp2Uj6Z.js +0 -53
- package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
import { t as normalizeWorkflowOptions } from "./config-IJMb0eeZ.js";
|
|
2
|
+
import { t as workflowErrorDiagnostics } from "./error-diagnostics-pwNFvAHP.js";
|
|
3
|
+
import { n as getCloudflareWorkflowBindingName, o as encodeNameHex } from "./cloudflare-nF4abPd4.js";
|
|
4
|
+
import { t as hasRuntimeType } from "./runtime-type-DBCvIh5x.js";
|
|
5
|
+
import { a as createWorkflowError, i as safeWorkflowName, r as runWorkflowProviderOperation } from "./provider-operation-CW2cYfVy.js";
|
|
6
|
+
import { n as getCloudflareEnv, r as resolveWaitUntil } from "./cloudflare-env-BNrYo29x.js";
|
|
7
|
+
import { runSerializedWorkflowHandler } from "./runtime/execute.js";
|
|
8
|
+
import { getOpenWorkflowRun, runOpenWorkflow } from "./runtime/openworkflow.js";
|
|
9
|
+
import { getWorkflowRunState, getWorkflowRuntimeConfig, getWorkflowRuntimeEvent, getWorkflowRuntimeRegistry, loadWorkflowDefinition, registerInlineWorkflowDefinition, runWithWorkflowRuntimeEvent, setWorkflowRun } from "./runtime/state.js";
|
|
10
|
+
import { a as startVercelWorkflow, n as inspectVercelWorkflowRun, r as resumeVercelWorkflowSignal, t as cancelVercelWorkflow } from "./vercel-D-ZNtB_u.js";
|
|
11
|
+
import { deserializeResponse, isSerializedResponse } from "@vite-hub/runtime";
|
|
12
|
+
//#region src/integrations/vercel.ts
|
|
13
|
+
function getVercelWorkflowName(name) {
|
|
14
|
+
return `workflow--${encodeNameHex(name)}`;
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region ../internal/src/runtime/random.ts
|
|
18
|
+
function randomId(prefix) {
|
|
19
|
+
const body = `${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
20
|
+
return prefix ? `${prefix}_${body}` : body;
|
|
21
|
+
}
|
|
22
|
+
//#endregion
|
|
23
|
+
//#region src/runtime/adapters.ts
|
|
24
|
+
function resolveDispatchObserver(event) {
|
|
25
|
+
if (!event || !hasRuntimeType(event, "object")) return void 0;
|
|
26
|
+
const candidate = Object.hasOwn(event, "onDispatch") ? Reflect.get(event, "onDispatch") : void 0;
|
|
27
|
+
return hasRuntimeType(candidate, "function") ? candidate : void 0;
|
|
28
|
+
}
|
|
29
|
+
function resolveSettlementObserver(event) {
|
|
30
|
+
if (!event || !hasRuntimeType(event, "object")) return void 0;
|
|
31
|
+
const candidate = Object.hasOwn(event, "settled") ? Reflect.get(event, "settled") : void 0;
|
|
32
|
+
if (hasRuntimeType(candidate, "function")) return candidate;
|
|
33
|
+
const context = Object.hasOwn(event, "context") ? Reflect.get(event, "context") : void 0;
|
|
34
|
+
if (!context || !hasRuntimeType(context, "object")) return void 0;
|
|
35
|
+
const contextObject = Object(context);
|
|
36
|
+
const nested = Object.hasOwn(contextObject, "settled") ? Reflect.get(contextObject, "settled") : void 0;
|
|
37
|
+
return hasRuntimeType(nested, "function") ? nested : void 0;
|
|
38
|
+
}
|
|
39
|
+
function unsupportedOperation(provider, operation) {
|
|
40
|
+
throw createWorkflowError({
|
|
41
|
+
code: "WORKFLOW_OPERATION_UNSUPPORTED",
|
|
42
|
+
details: {
|
|
43
|
+
operation,
|
|
44
|
+
provider
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
function resolveCloudflareBinding(event, binding, name, definition) {
|
|
49
|
+
const env = getCloudflareEnv(event);
|
|
50
|
+
const bindingName = definition?.internalAgentInvocationRecovery ? getCloudflareWorkflowBindingName(name) : binding || getCloudflareWorkflowBindingName(name);
|
|
51
|
+
return env && Object.hasOwn(env, bindingName) ? env[bindingName] : void 0;
|
|
52
|
+
}
|
|
53
|
+
function resolveCloudflareInspectionBinding(event, binding, name) {
|
|
54
|
+
return resolveCloudflareBinding(event, binding, name, getWorkflowRuntimeRegistry()?.[name]);
|
|
55
|
+
}
|
|
56
|
+
function normalizeCloudflareWorkflowStart(value, expectedId) {
|
|
57
|
+
if (!hasRuntimeType(value, "object") || value === null) throw new Error("Cloudflare Workflow provider returned an invalid workflow instance.");
|
|
58
|
+
let id;
|
|
59
|
+
try {
|
|
60
|
+
id = Reflect.get(value, "id");
|
|
61
|
+
} catch (cause) {
|
|
62
|
+
throw new Error("Cloudflare Workflow provider returned an invalid workflow instance.", { cause });
|
|
63
|
+
}
|
|
64
|
+
if (!hasRuntimeType(id, "string") || !id || id !== expectedId) throw new Error("Cloudflare Workflow provider returned an invalid workflow instance.");
|
|
65
|
+
return { id };
|
|
66
|
+
}
|
|
67
|
+
const cloudflareStatusMap = {
|
|
68
|
+
cancelled: "cancelled",
|
|
69
|
+
complete: "completed",
|
|
70
|
+
completed: "completed",
|
|
71
|
+
errored: "failed",
|
|
72
|
+
failed: "failed",
|
|
73
|
+
queued: "queued",
|
|
74
|
+
running: "running",
|
|
75
|
+
success: "completed",
|
|
76
|
+
terminated: "failed"
|
|
77
|
+
};
|
|
78
|
+
function normalizeCloudflareStatus(status) {
|
|
79
|
+
const value = hasRuntimeType(status, "object") && status && Object.hasOwn(status, "status") ? status.status : status;
|
|
80
|
+
const normalized = String(value || "").toLowerCase();
|
|
81
|
+
return Object.hasOwn(cloudflareStatusMap, normalized) ? cloudflareStatusMap[normalized] : "unknown";
|
|
82
|
+
}
|
|
83
|
+
function ownSerializedOutput(metadata) {
|
|
84
|
+
if (!hasRuntimeType(metadata, "object") || metadata === null || !Object.hasOwn(metadata, "output")) return void 0;
|
|
85
|
+
const output = metadata.output;
|
|
86
|
+
return isSerializedResponse(output) ? output : void 0;
|
|
87
|
+
}
|
|
88
|
+
function hasUnknownWorkflowAcknowledgement(error) {
|
|
89
|
+
if (!error || !hasRuntimeType(error, "object")) return false;
|
|
90
|
+
const details = error.details;
|
|
91
|
+
return Boolean(details && hasRuntimeType(details, "object") && details.acknowledgement === "unknown");
|
|
92
|
+
}
|
|
93
|
+
function createCloudflareAdapter(config) {
|
|
94
|
+
return {
|
|
95
|
+
cancel: () => unsupportedOperation("cloudflare", "cancellation"),
|
|
96
|
+
async get({ event, id, name }) {
|
|
97
|
+
const binding = resolveCloudflareInspectionBinding(event, config.binding, name);
|
|
98
|
+
if (binding) {
|
|
99
|
+
const instance = await runWorkflowProviderOperation("cloudflare", "get", () => binding.get(id));
|
|
100
|
+
const metadata = await runWorkflowProviderOperation("cloudflare", "status", () => instance.status());
|
|
101
|
+
const output = ownSerializedOutput(metadata);
|
|
102
|
+
return {
|
|
103
|
+
id,
|
|
104
|
+
metadata,
|
|
105
|
+
provider: "cloudflare",
|
|
106
|
+
result: output ? deserializeResponse(output) : void 0,
|
|
107
|
+
status: normalizeCloudflareStatus(metadata)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return await inlineAdapter(config).get({
|
|
111
|
+
event,
|
|
112
|
+
id,
|
|
113
|
+
name
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
async run({ definition, event, id, name, options, payload }) {
|
|
117
|
+
const binding = resolveCloudflareBinding(event, config.binding, name, definition);
|
|
118
|
+
if (binding) {
|
|
119
|
+
resolveDispatchObserver(event)?.();
|
|
120
|
+
const start = () => runWorkflowProviderOperation("cloudflare", "create", async () => normalizeCloudflareWorkflowStart((await binding.createBatch([{
|
|
121
|
+
id,
|
|
122
|
+
params: payload
|
|
123
|
+
}]))[0] || await binding.get(id), id), { acknowledgementUnknown: (_error, status) => status === void 0 });
|
|
124
|
+
const creation = start().catch(async (firstError) => {
|
|
125
|
+
try {
|
|
126
|
+
return await start();
|
|
127
|
+
} catch (retryError) {
|
|
128
|
+
if (hasUnknownWorkflowAcknowledgement(firstError)) throw firstError;
|
|
129
|
+
throw retryError;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
const waitUntil = options.deferred ? resolveWaitUntil(event) : void 0;
|
|
133
|
+
if (waitUntil) waitUntil(creation);
|
|
134
|
+
return {
|
|
135
|
+
id: (await creation).id,
|
|
136
|
+
payload,
|
|
137
|
+
provider: "cloudflare",
|
|
138
|
+
status: "queued"
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
return await inlineAdapter(config).run({
|
|
142
|
+
definition,
|
|
143
|
+
event,
|
|
144
|
+
id,
|
|
145
|
+
name,
|
|
146
|
+
options,
|
|
147
|
+
payload
|
|
148
|
+
});
|
|
149
|
+
},
|
|
150
|
+
resume: () => unsupportedOperation("cloudflare", "signals")
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function createOpenWorkflowAdapter(config) {
|
|
154
|
+
return {
|
|
155
|
+
cancel: () => unsupportedOperation("openworkflow", "cancellation"),
|
|
156
|
+
get: async ({ id, name }) => await getOpenWorkflowRun(config, name, id),
|
|
157
|
+
resume: () => unsupportedOperation("openworkflow", "signals"),
|
|
158
|
+
run: async ({ definition, event, name, options, payload }) => await runOpenWorkflow(config, name, payload, definition, options, resolveDispatchObserver(event))
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
function inlineAdapter(config) {
|
|
162
|
+
return {
|
|
163
|
+
cancel: () => unsupportedOperation(config.provider, "cancellation"),
|
|
164
|
+
async get({ id, name }) {
|
|
165
|
+
const run = getWorkflowRunState(name, id);
|
|
166
|
+
if (run) {
|
|
167
|
+
if (run.status === "running") return {
|
|
168
|
+
id,
|
|
169
|
+
provider: config.provider,
|
|
170
|
+
status: "running"
|
|
171
|
+
};
|
|
172
|
+
return {
|
|
173
|
+
id,
|
|
174
|
+
metadata: run.error,
|
|
175
|
+
provider: config.provider,
|
|
176
|
+
result: isSerializedResponse(run.result) ? deserializeResponse(run.result) : run.result,
|
|
177
|
+
status: run.status
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
id,
|
|
182
|
+
provider: config.provider,
|
|
183
|
+
status: "unknown"
|
|
184
|
+
};
|
|
185
|
+
},
|
|
186
|
+
async run({ definition, event, id, name, payload }) {
|
|
187
|
+
const existing = getWorkflowRunState(name, id);
|
|
188
|
+
if (existing) return {
|
|
189
|
+
id,
|
|
190
|
+
metadata: existing.error ?? (config.provider === "vercel" ? {
|
|
191
|
+
mode: "inline",
|
|
192
|
+
workflow: getVercelWorkflowName(name)
|
|
193
|
+
} : void 0),
|
|
194
|
+
payload: existing.payload,
|
|
195
|
+
provider: config.provider,
|
|
196
|
+
result: isSerializedResponse(existing.result) ? deserializeResponse(existing.result) : existing.result,
|
|
197
|
+
status: existing.status === "running" ? "queued" : existing.status
|
|
198
|
+
};
|
|
199
|
+
resolveDispatchObserver(event)?.();
|
|
200
|
+
const run = Promise.resolve().then(() => runSerializedWorkflowHandler({
|
|
201
|
+
id,
|
|
202
|
+
name,
|
|
203
|
+
payload,
|
|
204
|
+
provider: config.provider
|
|
205
|
+
}, definition)).then((result) => ({
|
|
206
|
+
result,
|
|
207
|
+
status: "completed"
|
|
208
|
+
})).catch((error) => ({
|
|
209
|
+
error,
|
|
210
|
+
status: "failed"
|
|
211
|
+
}));
|
|
212
|
+
const runState = setWorkflowRun(name, id, run, payload, true);
|
|
213
|
+
const waitUntil = resolveWaitUntil(event);
|
|
214
|
+
if (waitUntil) waitUntil(runState.promise);
|
|
215
|
+
return {
|
|
216
|
+
id,
|
|
217
|
+
metadata: config.provider === "vercel" ? {
|
|
218
|
+
mode: "inline",
|
|
219
|
+
workflow: getVercelWorkflowName(name)
|
|
220
|
+
} : void 0,
|
|
221
|
+
payload,
|
|
222
|
+
provider: config.provider,
|
|
223
|
+
status: "queued"
|
|
224
|
+
};
|
|
225
|
+
},
|
|
226
|
+
resume: () => unsupportedOperation(config.provider, "signals")
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function createVercelAdapter(config) {
|
|
230
|
+
const fallback = inlineAdapter(config);
|
|
231
|
+
return {
|
|
232
|
+
async cancel({ id, name }) {
|
|
233
|
+
const definition = await loadWorkflowDefinition(name);
|
|
234
|
+
if (!definition?.options?.native) return await fallback.cancel({
|
|
235
|
+
event: void 0,
|
|
236
|
+
id,
|
|
237
|
+
name
|
|
238
|
+
});
|
|
239
|
+
return await cancelVercelWorkflow(name, definition, id);
|
|
240
|
+
},
|
|
241
|
+
async get({ id, name }) {
|
|
242
|
+
const definition = await loadWorkflowDefinition(name);
|
|
243
|
+
return definition?.options?.native ? await inspectVercelWorkflowRun(name, definition, id) : await fallback.get({
|
|
244
|
+
event: void 0,
|
|
245
|
+
id,
|
|
246
|
+
name
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
resume: async (token, payload) => await resumeVercelWorkflowSignal(token, payload),
|
|
250
|
+
async run({ definition, event, id, name, options, payload }) {
|
|
251
|
+
if (!definition.options?.native) return await fallback.run({
|
|
252
|
+
definition,
|
|
253
|
+
event,
|
|
254
|
+
id,
|
|
255
|
+
name,
|
|
256
|
+
options,
|
|
257
|
+
payload
|
|
258
|
+
});
|
|
259
|
+
if (options.id) throw createWorkflowError({
|
|
260
|
+
code: "WORKFLOW_RUN_ID_UNSUPPORTED",
|
|
261
|
+
details: {
|
|
262
|
+
...safeWorkflowName(name) ? { name } : {},
|
|
263
|
+
provider: "vercel"
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
return await startVercelWorkflow(name, definition, payload, resolveSettlementObserver(event), resolveDispatchObserver(event));
|
|
267
|
+
}
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
function getWorkflowRuntimeAdapter(config) {
|
|
271
|
+
if (config.provider === "cloudflare") return createCloudflareAdapter(config);
|
|
272
|
+
if (config.provider === "openworkflow") return createOpenWorkflowAdapter(config);
|
|
273
|
+
return createVercelAdapter(config);
|
|
274
|
+
}
|
|
275
|
+
//#endregion
|
|
276
|
+
//#region src/runtime/client.ts
|
|
277
|
+
function getActiveWorkflowConfig() {
|
|
278
|
+
const config = getWorkflowRuntimeConfig();
|
|
279
|
+
if (config === false) throw createWorkflowError({ code: "WORKFLOW_DISABLED" });
|
|
280
|
+
return config || normalizeWorkflowOptions(void 0, { hosting: "vercel" });
|
|
281
|
+
}
|
|
282
|
+
async function loadRequiredWorkflowDefinition(name) {
|
|
283
|
+
const definition = await loadWorkflowDefinition(name);
|
|
284
|
+
if (!definition) throw createWorkflowError({
|
|
285
|
+
code: "WORKFLOW_DEFINITION_NOT_FOUND",
|
|
286
|
+
details: safeWorkflowName(name) ? { name } : void 0
|
|
287
|
+
});
|
|
288
|
+
return definition;
|
|
289
|
+
}
|
|
290
|
+
function normalizeWorkflowRunIdValue(value) {
|
|
291
|
+
if (value === void 0) return null;
|
|
292
|
+
if (value === null || !hasRuntimeType(value, "object")) return value;
|
|
293
|
+
if (Array.isArray(value)) return value.map((item) => normalizeWorkflowRunIdValue(item));
|
|
294
|
+
const record = value;
|
|
295
|
+
return Object.fromEntries(Object.keys(record).filter((key) => record[key] !== void 0).sort().map((key) => [key, normalizeWorkflowRunIdValue(record[key])]));
|
|
296
|
+
}
|
|
297
|
+
async function sha256Hex(value) {
|
|
298
|
+
const data = new TextEncoder().encode(value);
|
|
299
|
+
const digest = await crypto.subtle.digest("SHA-256", data);
|
|
300
|
+
return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
301
|
+
}
|
|
302
|
+
async function createStableWorkflowRunId(name, value) {
|
|
303
|
+
const hash = await sha256Hex(`${name}:${JSON.stringify(normalizeWorkflowRunIdValue(value))}`);
|
|
304
|
+
return `${name.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "workflow"}-${hash.slice(0, 32)}`;
|
|
305
|
+
}
|
|
306
|
+
async function resolveWorkflowStartOptions(name, payload, createOptions, startOptions) {
|
|
307
|
+
if (startOptions.id || !createOptions?.id) return startOptions;
|
|
308
|
+
return {
|
|
309
|
+
...startOptions,
|
|
310
|
+
id: await createStableWorkflowRunId(name, await createOptions.id({
|
|
311
|
+
name,
|
|
312
|
+
payload
|
|
313
|
+
}))
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function createWorkflow(nameOrOptions, handlerOrOptions, options) {
|
|
317
|
+
let name;
|
|
318
|
+
let handler;
|
|
319
|
+
let createOptions;
|
|
320
|
+
if (hasRuntimeType(nameOrOptions, "object") && nameOrOptions !== null) {
|
|
321
|
+
createOptions = nameOrOptions;
|
|
322
|
+
if (!createOptions.name || !hasRuntimeType(createOptions.name, "string")) throw workflowErrorDiagnostics.WORKFLOW_R0009({ message: "`createWorkflow()` requires a workflow name." });
|
|
323
|
+
if (!hasRuntimeType(createOptions.handler, "function")) throw workflowErrorDiagnostics.WORKFLOW_R0010({ message: "`createWorkflow()` requires a workflow handler." });
|
|
324
|
+
name = createOptions.name;
|
|
325
|
+
handler = createOptions.handler;
|
|
326
|
+
} else {
|
|
327
|
+
name = nameOrOptions;
|
|
328
|
+
if (!name || !hasRuntimeType(name, "string")) throw workflowErrorDiagnostics.WORKFLOW_R0011({ message: "`createWorkflow()` requires a workflow name." });
|
|
329
|
+
handler = hasRuntimeType(handlerOrOptions, "function") ? handlerOrOptions : hasRuntimeType(handlerOrOptions, "object") && handlerOrOptions !== null ? handlerOrOptions.handler : void 0;
|
|
330
|
+
createOptions = hasRuntimeType(handlerOrOptions, "function") ? options : handlerOrOptions;
|
|
331
|
+
if (handler !== void 0 && !hasRuntimeType(handler, "function")) throw workflowErrorDiagnostics.WORKFLOW_R0012({ message: "`createWorkflow()` requires a workflow handler." });
|
|
332
|
+
if (handler === void 0 && handlerOrOptions !== void 0 && (!hasRuntimeType(handlerOrOptions, "object") || handlerOrOptions === null)) throw workflowErrorDiagnostics.WORKFLOW_R0013({ message: "`createWorkflow()` options must be an object." });
|
|
333
|
+
}
|
|
334
|
+
if (handler !== void 0) registerInlineWorkflowDefinition(name, {
|
|
335
|
+
handler,
|
|
336
|
+
...createOptions?.rootStep === void 0 ? {} : { options: { rootStep: createOptions.rootStep } }
|
|
337
|
+
});
|
|
338
|
+
return {
|
|
339
|
+
cancel: (id) => cancelWorkflow(name, id),
|
|
340
|
+
name,
|
|
341
|
+
defer: async (payload, options = {}) => deferWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options)),
|
|
342
|
+
getRun: (id) => getWorkflowRun(name, id),
|
|
343
|
+
async run(payload, options = {}) {
|
|
344
|
+
return await runWorkflow(name, payload, await resolveWorkflowStartOptions(name, payload, createOptions, options));
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
async function runWorkflow(name, payload, options = {}) {
|
|
349
|
+
const config = getActiveWorkflowConfig();
|
|
350
|
+
const id = options.id || randomId("wrun");
|
|
351
|
+
const definition = await loadRequiredWorkflowDefinition(name);
|
|
352
|
+
return await getWorkflowRuntimeAdapter(config).run({
|
|
353
|
+
definition,
|
|
354
|
+
event: getWorkflowRuntimeEvent(),
|
|
355
|
+
id,
|
|
356
|
+
name,
|
|
357
|
+
options,
|
|
358
|
+
payload
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
async function getWorkflowRun(name, id) {
|
|
362
|
+
return await getWorkflowRuntimeAdapter(getActiveWorkflowConfig()).get({
|
|
363
|
+
event: getWorkflowRuntimeEvent(),
|
|
364
|
+
id,
|
|
365
|
+
name
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
async function cancelWorkflow(name, id) {
|
|
369
|
+
const config = getActiveWorkflowConfig();
|
|
370
|
+
await loadRequiredWorkflowDefinition(name);
|
|
371
|
+
return await getWorkflowRuntimeAdapter(config).cancel({
|
|
372
|
+
event: getWorkflowRuntimeEvent(),
|
|
373
|
+
id,
|
|
374
|
+
name
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
async function resumeWorkflowSignal(token, payload) {
|
|
378
|
+
if (!token || !hasRuntimeType(token, "string")) throw workflowErrorDiagnostics.WORKFLOW_R0014({ message: "`resumeWorkflowSignal()` requires an opaque signal token." });
|
|
379
|
+
return await getWorkflowRuntimeAdapter(getActiveWorkflowConfig()).resume(token, payload);
|
|
380
|
+
}
|
|
381
|
+
function deferWorkflow(name, payload, options = {}) {
|
|
382
|
+
const request = getWorkflowRuntimeEvent();
|
|
383
|
+
return runWithWorkflowRuntimeEvent(request, () => runWorkflow(name, payload, {
|
|
384
|
+
...options,
|
|
385
|
+
deferred: true
|
|
386
|
+
}));
|
|
387
|
+
}
|
|
388
|
+
//#endregion
|
|
389
|
+
export { resumeWorkflowSignal as a, getWorkflowRun as i, createWorkflow as n, runWorkflow as o, deferWorkflow as r, getVercelWorkflowName as s, cancelWorkflow as t };
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
|
+
//#region ../internal/src/runtime/cloudflare-env.ts
|
|
3
|
+
let activeEnv;
|
|
4
|
+
const activeEnvStorageKey = Symbol.for("vitehub.cloudflare.env-storage");
|
|
5
|
+
const runtimeGlobal = globalThis;
|
|
6
|
+
const activeEnvStorage = runtimeGlobal[activeEnvStorageKey] ||= new AsyncLocalStorage();
|
|
7
|
+
const globalEnvProbe = Symbol("vitehub.cloudflare.global-env-probe");
|
|
8
|
+
/**
|
|
9
|
+
* Under the Nitro Cloudflare dev server, `cloudflare:workers` exports unenv's env proxy, which reads every key from
|
|
10
|
+
* `globalThis.__env__`. Storing that proxy in `__env__` makes it read itself, and the next read overflows the stack.
|
|
11
|
+
*/
|
|
12
|
+
function readsGlobalEnv(env) {
|
|
13
|
+
const scope = globalThis;
|
|
14
|
+
const owned = Object.hasOwn(scope, "__env__");
|
|
15
|
+
const previous = scope.__env__;
|
|
16
|
+
scope.__env__ = { [globalEnvProbe]: true };
|
|
17
|
+
try {
|
|
18
|
+
return Reflect.get(env, globalEnvProbe) === true;
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
} finally {
|
|
22
|
+
if (owned) scope.__env__ = previous;
|
|
23
|
+
else delete scope.__env__;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function setActiveCloudflareEnv(env) {
|
|
27
|
+
activeEnv = env;
|
|
28
|
+
if (!env || !readsGlobalEnv(env)) globalThis.__env__ = env;
|
|
29
|
+
try {
|
|
30
|
+
activeEnvStorage.enterWith({ env });
|
|
31
|
+
} catch {}
|
|
32
|
+
}
|
|
33
|
+
function runWithActiveCloudflareEnv(env, callback) {
|
|
34
|
+
return activeEnvStorage.run({ env }, callback);
|
|
35
|
+
}
|
|
36
|
+
function getActiveCloudflareEnv() {
|
|
37
|
+
const scoped = activeEnvStorage.getStore();
|
|
38
|
+
if (scoped) return scoped.env;
|
|
39
|
+
const host = globalThis;
|
|
40
|
+
return Object.hasOwn(host, "__env__") && host.__env__ !== void 0 ? host.__env__ : activeEnv;
|
|
41
|
+
}
|
|
42
|
+
function ownValue(value, key) {
|
|
43
|
+
if (value === null || typeof value !== "object" && typeof value !== "function" || !Object.hasOwn(value, key)) return void 0;
|
|
44
|
+
return Reflect.get(value, key);
|
|
45
|
+
}
|
|
46
|
+
function ownObject(value) {
|
|
47
|
+
return value !== null && (typeof value === "object" || typeof value === "function") ? value : void 0;
|
|
48
|
+
}
|
|
49
|
+
/** The objects where H3 1, H3 2, and Nitro hosts put Cloudflare `env` and `context`, in lookup order. */
|
|
50
|
+
function cloudflareOwners(target) {
|
|
51
|
+
const context = ownObject(ownValue(target, "context"));
|
|
52
|
+
const platform = ownObject(ownValue(context, "_platform"));
|
|
53
|
+
const req = ownObject(ownValue(target, "req"));
|
|
54
|
+
const nodeReq = ownObject(ownValue(ownObject(ownValue(target, "node")), "req"));
|
|
55
|
+
return [
|
|
56
|
+
ownObject(ownValue(context, "cloudflare")),
|
|
57
|
+
ownObject(ownValue(platform, "cloudflare")),
|
|
58
|
+
ownObject(ownValue(ownObject(ownValue(req, "runtime")), "cloudflare")),
|
|
59
|
+
ownObject(ownValue(ownObject(ownValue(nodeReq, "runtime")), "cloudflare"))
|
|
60
|
+
];
|
|
61
|
+
}
|
|
62
|
+
function getCloudflareEnv(event, options = {}) {
|
|
63
|
+
const target = ownObject(event);
|
|
64
|
+
for (const candidate of [ownValue(target, "env"), ...cloudflareOwners(target).map((owner) => ownValue(owner, "env"))]) if (candidate) return candidate;
|
|
65
|
+
return options.fallback === false ? void 0 : getActiveCloudflareEnv();
|
|
66
|
+
}
|
|
67
|
+
function resolveWaitUntil(event, options = {}) {
|
|
68
|
+
const target = ownObject(event);
|
|
69
|
+
const context = ownObject(ownValue(target, "context"));
|
|
70
|
+
const cloudflare = ownObject(ownValue(context, "cloudflare"));
|
|
71
|
+
const cloudflareContext = ownObject(ownValue(cloudflare, "context"));
|
|
72
|
+
const platformCloudflare = ownObject(ownValue(ownObject(ownValue(context, "_platform")), "cloudflare"));
|
|
73
|
+
const platformCloudflareContext = ownObject(ownValue(platformCloudflare, "context"));
|
|
74
|
+
const req = ownObject(ownValue(target, "req"));
|
|
75
|
+
const reqCloudflare = ownObject(ownValue(ownObject(ownValue(req, "runtime")), "cloudflare"));
|
|
76
|
+
const reqCloudflareContext = ownObject(ownValue(reqCloudflare, "context"));
|
|
77
|
+
const nodeReq = ownObject(ownValue(ownObject(ownValue(target, "node")), "req"));
|
|
78
|
+
const nodeCloudflare = ownObject(ownValue(ownObject(ownValue(nodeReq, "runtime")), "cloudflare"));
|
|
79
|
+
const hosts = [
|
|
80
|
+
context,
|
|
81
|
+
cloudflare,
|
|
82
|
+
cloudflareContext,
|
|
83
|
+
platformCloudflare,
|
|
84
|
+
platformCloudflareContext,
|
|
85
|
+
req,
|
|
86
|
+
reqCloudflare,
|
|
87
|
+
reqCloudflareContext,
|
|
88
|
+
nodeReq,
|
|
89
|
+
nodeCloudflare,
|
|
90
|
+
ownObject(ownValue(nodeCloudflare, "context"))
|
|
91
|
+
];
|
|
92
|
+
const owners = options.preferHost ? [...hosts, target] : [target, ...hosts];
|
|
93
|
+
for (const owner of owners) {
|
|
94
|
+
const waitUntil = ownValue(owner, "waitUntil");
|
|
95
|
+
if (typeof waitUntil === "function") return waitUntil.bind(owner);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function createCloudflareRuntimeEvent(env, context) {
|
|
99
|
+
const waitUntil = typeof context?.waitUntil === "function" ? context.waitUntil.bind(context) : void 0;
|
|
100
|
+
return {
|
|
101
|
+
context: {
|
|
102
|
+
cloudflare: {
|
|
103
|
+
env,
|
|
104
|
+
context
|
|
105
|
+
},
|
|
106
|
+
waitUntil
|
|
107
|
+
},
|
|
108
|
+
env,
|
|
109
|
+
waitUntil
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
//#endregion
|
|
113
|
+
export { setActiveCloudflareEnv as a, runWithActiveCloudflareEnv as i, getCloudflareEnv as n, resolveWaitUntil as r, createCloudflareRuntimeEvent as t };
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { t as workflowErrorDiagnostics } from "./error-diagnostics-pwNFvAHP.js";
|
|
2
|
+
//#region ../internal/src/integrations/hex.ts
|
|
3
|
+
const textEncoder = new TextEncoder();
|
|
4
|
+
new TextDecoder();
|
|
5
|
+
function encodeNameHex(name) {
|
|
6
|
+
return [...textEncoder.encode(name)].map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
7
|
+
}
|
|
8
|
+
//#endregion
|
|
9
|
+
//#region src/integrations/cloudflare.ts
|
|
10
|
+
const cloudflareWorkflowNameMaxLength = 64;
|
|
11
|
+
function shortHash(value) {
|
|
12
|
+
let hash = 14695981039346656037n;
|
|
13
|
+
for (const char of value) {
|
|
14
|
+
hash ^= BigInt(char.codePointAt(0) || 0);
|
|
15
|
+
hash = BigInt.asUintN(64, hash * 1099511628211n);
|
|
16
|
+
}
|
|
17
|
+
return hash.toString(16).padStart(16, "0");
|
|
18
|
+
}
|
|
19
|
+
function legacyShortHash(value) {
|
|
20
|
+
let hash = 2166136261;
|
|
21
|
+
for (const char of value) {
|
|
22
|
+
hash ^= char.codePointAt(0) || 0;
|
|
23
|
+
hash = Math.imul(hash, 16777619);
|
|
24
|
+
}
|
|
25
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
26
|
+
}
|
|
27
|
+
function workflowClassPrefix(name) {
|
|
28
|
+
return name.split(/[^a-z0-9]+/i).filter(Boolean).map((segment) => `${segment.charAt(0).toUpperCase()}${segment.slice(1)}`).join("") || "Default";
|
|
29
|
+
}
|
|
30
|
+
function getCloudflareWorkflowBindingName(name) {
|
|
31
|
+
return `WORKFLOW_${encodeNameHex(name).toUpperCase()}`;
|
|
32
|
+
}
|
|
33
|
+
function getCloudflareWorkflowName(name) {
|
|
34
|
+
const encoded = encodeNameHex(name);
|
|
35
|
+
const fullName = `workflow--${encoded}`;
|
|
36
|
+
if (fullName.length <= cloudflareWorkflowNameMaxLength) return fullName;
|
|
37
|
+
const hash = shortHash(name);
|
|
38
|
+
const prefixLength = 53 - hash.length;
|
|
39
|
+
return `workflow--${encoded.slice(0, prefixLength)}-${hash}`;
|
|
40
|
+
}
|
|
41
|
+
function getCloudflareWorkflowClassName(name) {
|
|
42
|
+
return `ViteHub${workflowClassPrefix(name)}${shortHash(name)}Workflow`;
|
|
43
|
+
}
|
|
44
|
+
/** The pre-64-bit class export kept for existing Cloudflare Workflow instances. */
|
|
45
|
+
function getLegacyCloudflareWorkflowClassName(name) {
|
|
46
|
+
return `ViteHub${workflowClassPrefix(name)}${legacyShortHash(name)}Workflow`;
|
|
47
|
+
}
|
|
48
|
+
function createCloudflareWorkflowBindings(definitions, options) {
|
|
49
|
+
if (!definitions.length) return;
|
|
50
|
+
const configurable = definitions.filter((definition) => definition.source !== "agent-workflow-recovery");
|
|
51
|
+
if (configurable.length > 1 && options && (options.binding || options.name)) throw workflowErrorDiagnostics.WORKFLOW_R0001({ message: "Cloudflare workflow binding and name overrides are only supported when one workflow is discovered." });
|
|
52
|
+
return definitions.map((definition) => ({
|
|
53
|
+
binding: configurable.length === 1 && configurable[0] === definition && options ? options.binding || getCloudflareWorkflowBindingName(definition.name) : getCloudflareWorkflowBindingName(definition.name),
|
|
54
|
+
class_name: getCloudflareWorkflowClassName(definition.name),
|
|
55
|
+
name: configurable.length === 1 && configurable[0] === definition && options ? options.name || getCloudflareWorkflowName(definition.name) : getCloudflareWorkflowName(definition.name)
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
export { getLegacyCloudflareWorkflowClassName as a, getCloudflareWorkflowName as i, getCloudflareWorkflowBindingName as n, encodeNameHex as o, getCloudflareWorkflowClassName as r, createCloudflareWorkflowBindings as t };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import { t as normalizeWorkflowOptions } from "./config-
|
|
2
|
-
import { i as runWithActiveCloudflareEnv, t as createCloudflareRuntimeEvent } from "./cloudflare-env-
|
|
1
|
+
import { t as normalizeWorkflowOptions } from "./config-IJMb0eeZ.js";
|
|
2
|
+
import { i as runWithActiveCloudflareEnv, t as createCloudflareRuntimeEvent } from "./cloudflare-env-BNrYo29x.js";
|
|
3
3
|
import { runWithWorkflowRuntimeEvent, setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry } from "./runtime/state.js";
|
|
4
|
-
import { t as resolveAppFetch } from "./app-
|
|
5
|
-
import { H3, toWebHandler } from "h3/cloudflare";
|
|
4
|
+
import { t as resolveAppFetch } from "./app-CzPoP84f.js";
|
|
6
5
|
//#region ../internal/src/runtime/cloudflare-hosted.ts
|
|
7
6
|
function createWebRequestHandler(appHandler) {
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
return async (request, context) => await Promise.resolve(appHandler ? appHandler(request, context) : new Response(JSON.stringify({
|
|
8
|
+
status: 404,
|
|
9
|
+
message: `Cannot find any route matching [${request.method}] ${request.url}`
|
|
10
|
+
}), {
|
|
11
|
+
headers: { "content-type": "application/json;charset=UTF-8" },
|
|
12
|
+
status: 404,
|
|
13
|
+
statusText: "Not Found"
|
|
14
|
+
}));
|
|
10
15
|
}
|
|
11
16
|
function createCloudflareHostedWorker(adapter) {
|
|
12
17
|
const requestHandler = createWebRequestHandler(resolveAppFetch(adapter.label, adapter.app));
|
|
@@ -22,18 +27,21 @@ function createCloudflareHostedWorker(adapter) {
|
|
|
22
27
|
}
|
|
23
28
|
//#endregion
|
|
24
29
|
//#region src/runtime/cloudflare-vite.ts
|
|
25
|
-
function
|
|
30
|
+
function installWorkflowCloudflareRuntime(options = {}) {
|
|
26
31
|
const workflowConfig = options.workflow === false ? false : normalizeWorkflowOptions(options.workflow, { hosting: "cloudflare" });
|
|
32
|
+
setWorkflowRuntimeConfig(workflowConfig);
|
|
33
|
+
setWorkflowRuntimeRegistry(options.registry);
|
|
34
|
+
}
|
|
35
|
+
function createWorkflowCloudflareWorker(options = {}) {
|
|
27
36
|
return createCloudflareHostedWorker({
|
|
28
37
|
app: options.app,
|
|
29
38
|
label: "workflow",
|
|
30
39
|
async onRequest({ env, executionContext, handle }) {
|
|
31
|
-
|
|
32
|
-
setWorkflowRuntimeRegistry(options.registry);
|
|
40
|
+
installWorkflowCloudflareRuntime(options);
|
|
33
41
|
const runtimeEvent = createCloudflareRuntimeEvent(env, executionContext);
|
|
34
42
|
return await runWithActiveCloudflareEnv(env, () => runWithWorkflowRuntimeEvent(runtimeEvent, () => handle(runtimeEvent.context)));
|
|
35
43
|
}
|
|
36
44
|
});
|
|
37
45
|
}
|
|
38
46
|
//#endregion
|
|
39
|
-
export { createWorkflowCloudflareWorker as t };
|
|
47
|
+
export { installWorkflowCloudflareRuntime as n, createWorkflowCloudflareWorker as t };
|