@vite-hub/workflow 0.0.0 → 0.0.1

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 (37) hide show
  1. package/README.md +60 -1
  2. package/dist/_app-BVWpnNHo.d.ts +11 -0
  3. package/dist/app-BE3EYOWn.js +10 -0
  4. package/dist/cloudflare-CeHVSHoN.js +42 -0
  5. package/dist/cloudflare-env-BVUMOgFK.d.ts +21 -0
  6. package/dist/cloudflare-env-g0Rf3ClH.js +49 -0
  7. package/dist/cloudflare-shared-BIeY2kak.d.ts +1 -0
  8. package/dist/cloudflare-vite-DcM5YVTP.js +40 -0
  9. package/dist/config-DkgsQuXz.js +92 -0
  10. package/dist/index.d.ts +65 -0
  11. package/dist/index.js +369 -0
  12. package/dist/module-UYEnVfxy.js +1546 -0
  13. package/dist/nitro.d.ts +19 -0
  14. package/dist/nitro.js +2 -0
  15. package/dist/openworkflow-amN7IkGO.d.ts +24 -0
  16. package/dist/runtime/cloudflare-runner.d.ts +27 -0
  17. package/dist/runtime/cloudflare-runner.js +23 -0
  18. package/dist/runtime/cloudflare-shared.d.ts +2 -0
  19. package/dist/runtime/cloudflare-shared.js +2 -0
  20. package/dist/runtime/cloudflare-vite.d.ts +17 -0
  21. package/dist/runtime/cloudflare-vite.js +2 -0
  22. package/dist/runtime/execute.d.ts +11 -0
  23. package/dist/runtime/execute.js +25 -0
  24. package/dist/runtime/nitro-plugin.d.ts +6 -0
  25. package/dist/runtime/nitro-plugin.js +14 -0
  26. package/dist/runtime/openworkflow-worker.d.ts +18 -0
  27. package/dist/runtime/openworkflow-worker.js +55 -0
  28. package/dist/runtime/openworkflow.d.ts +2 -0
  29. package/dist/runtime/openworkflow.js +143 -0
  30. package/dist/runtime/state.d.ts +35 -0
  31. package/dist/runtime/state.js +179 -0
  32. package/dist/runtime/vercel-vite.d.ts +14 -0
  33. package/dist/runtime/vercel-vite.js +48 -0
  34. package/dist/types-ThDitg7Z.d.ts +121 -0
  35. package/dist/vite.d.ts +16 -0
  36. package/dist/vite.js +503 -0
  37. package/package.json +93 -5
@@ -0,0 +1,48 @@
1
+ import { runWithWorkflowRuntimeEvent, setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry } from "./state.js";
2
+ import { t as resolveAppFetch } from "../app-BE3EYOWn.js";
3
+ import { waitUntil } from "@vercel/functions";
4
+ import { H3 } from "h3";
5
+ //#region ../internal/src/runtime/vercel-hosted.ts
6
+ function createVercelHostedServer(adapter) {
7
+ const app = new H3();
8
+ const appHandler = resolveAppFetch(adapter.label, adapter.app);
9
+ let nodeHandlerPromise;
10
+ return function hostedVercelServer(req, res) {
11
+ const handle = async () => {
12
+ nodeHandlerPromise ||= (async () => {
13
+ if (appHandler) {
14
+ const { fromWebHandler } = await import("h3");
15
+ app.use(fromWebHandler(async (request, context) => await appHandler(request, context)));
16
+ }
17
+ const { toNodeHandler } = await import("h3/node");
18
+ return toNodeHandler(app);
19
+ })();
20
+ return (await nodeHandlerPromise)(req, res);
21
+ };
22
+ if (adapter.onRequest) return adapter.onRequest({
23
+ handle,
24
+ req,
25
+ res
26
+ });
27
+ return handle();
28
+ };
29
+ }
30
+ //#endregion
31
+ //#region src/runtime/vercel-vite.ts
32
+ function createWorkflowVercelServer(options = {}) {
33
+ return createVercelHostedServer({
34
+ app: options.app,
35
+ label: "workflow",
36
+ onRequest({ handle, req, res }) {
37
+ setWorkflowRuntimeConfig(options.workflow);
38
+ setWorkflowRuntimeRegistry(options.registry);
39
+ return runWithWorkflowRuntimeEvent({
40
+ req,
41
+ res,
42
+ waitUntil
43
+ }, handle);
44
+ }
45
+ });
46
+ }
47
+ //#endregion
48
+ export { createWorkflowVercelServer };
@@ -0,0 +1,121 @@
1
+ //#region src/types.d.ts
2
+ type WorkflowProvider = "cloudflare" | "openworkflow" | "vercel";
3
+ interface CloudflareWorkflowBinding<TPayload = unknown> {
4
+ create: (options?: {
5
+ id?: string;
6
+ params?: TPayload;
7
+ }) => Promise<CloudflareWorkflowInstance>;
8
+ get: (id: string) => Promise<CloudflareWorkflowInstance>;
9
+ }
10
+ interface CloudflareWorkflowInstance {
11
+ id: string;
12
+ status: () => Promise<unknown>;
13
+ }
14
+ interface WorkflowSharedOptions {
15
+ binding?: string;
16
+ name?: string;
17
+ }
18
+ interface CloudflareWorkflowProviderOptions extends WorkflowSharedOptions {
19
+ provider: "cloudflare";
20
+ }
21
+ interface VercelWorkflowProviderOptions extends WorkflowSharedOptions {
22
+ provider: "vercel";
23
+ }
24
+ interface OpenWorkflowPostgresOptions {
25
+ namespaceId?: string;
26
+ runMigrations?: boolean;
27
+ schema?: string;
28
+ url?: string;
29
+ }
30
+ interface OpenWorkflowWorkerOptions {
31
+ concurrency?: number;
32
+ }
33
+ interface OpenWorkflowProviderOptions extends WorkflowSharedOptions {
34
+ postgres?: OpenWorkflowPostgresOptions;
35
+ provider: "openworkflow";
36
+ worker?: OpenWorkflowWorkerOptions;
37
+ }
38
+ interface InferredWorkflowProviderOptions extends WorkflowSharedOptions {
39
+ postgres?: OpenWorkflowPostgresOptions;
40
+ provider?: undefined;
41
+ worker?: OpenWorkflowWorkerOptions;
42
+ }
43
+ type WorkflowProviderOptions = CloudflareWorkflowProviderOptions | OpenWorkflowProviderOptions | VercelWorkflowProviderOptions;
44
+ type WorkflowModuleProviderOptions = InferredWorkflowProviderOptions | WorkflowProviderOptions;
45
+ type WorkflowModuleOptions = false | WorkflowModuleProviderOptions;
46
+ type ResolvedWorkflowOptions = WorkflowProviderOptions;
47
+ interface WorkflowRun<TPayload = unknown, TResult = unknown> {
48
+ id: string;
49
+ provider: WorkflowProvider;
50
+ result?: TResult;
51
+ status: WorkflowRunStatus;
52
+ metadata?: unknown;
53
+ payload?: TPayload;
54
+ }
55
+ type WorkflowRunStatus = "queued" | "running" | "completed" | "failed" | "unknown";
56
+ interface WorkflowStepOptions {
57
+ retries?: {
58
+ backoff?: string;
59
+ delay?: string;
60
+ limit?: number;
61
+ };
62
+ }
63
+ type WorkflowStepFunction<TInput = unknown, TResult = unknown> = (input: TInput) => TResult | Promise<TResult>;
64
+ interface WorkflowProviderStep {
65
+ do?: <TResult>(name: string, options: WorkflowStepOptions, run: () => TResult | Promise<TResult>) => Promise<TResult>;
66
+ }
67
+ type WorkflowStepRunner<TSteps extends Record<string, WorkflowStepFunction> = Record<string, WorkflowStepFunction>> = { [TName in keyof TSteps]: TSteps[TName] };
68
+ interface WorkflowExecutionContext<TPayload = unknown> {
69
+ id?: string;
70
+ name: string;
71
+ payload: TPayload;
72
+ provider: WorkflowProvider;
73
+ step?: WorkflowProviderStep;
74
+ steps?: WorkflowStepRunner;
75
+ }
76
+ type WorkflowHandler<TPayload = unknown, TResult = unknown> = (context: WorkflowExecutionContext<TPayload>) => TResult | Promise<TResult>;
77
+ type WorkflowRunIdValue = boolean | null | number | string | undefined | {
78
+ readonly [key: string]: WorkflowRunIdValue;
79
+ } | readonly WorkflowRunIdValue[];
80
+ interface WorkflowCreateOptions<TPayload = unknown, TResult = unknown> {
81
+ handler?: WorkflowHandler<TPayload, TResult>;
82
+ id?: (context: {
83
+ name: string;
84
+ payload?: TPayload;
85
+ }) => Promise<WorkflowRunIdValue> | WorkflowRunIdValue;
86
+ name?: string;
87
+ }
88
+ interface WorkflowDefinitionOptions {
89
+ id?: string;
90
+ rootStep?: boolean;
91
+ }
92
+ interface WorkflowDefinition<TPayload = unknown, TResult = unknown> {
93
+ handler: WorkflowHandler<TPayload, TResult>;
94
+ options?: WorkflowDefinitionOptions;
95
+ }
96
+ interface WorkflowHandle<TPayload = unknown, TResult = unknown> {
97
+ defer: (payload?: TPayload, options?: WorkflowStartOptions) => Promise<WorkflowRun<TPayload>>;
98
+ getRun: (id: string) => Promise<WorkflowRun<TPayload, TResult>>;
99
+ name: string;
100
+ run: (payload?: TPayload, options?: WorkflowStartOptions) => Promise<WorkflowRun<TPayload, TResult>>;
101
+ }
102
+ interface WorkflowStartOptions {
103
+ id?: string;
104
+ }
105
+ interface WorkflowDeferOptions extends WorkflowStartOptions {
106
+ deferred?: boolean;
107
+ }
108
+ interface WorkflowDefinitionRegistry {
109
+ [name: string]: () => Promise<{
110
+ default?: WorkflowDefinition;
111
+ [exportName: string]: unknown;
112
+ } | WorkflowDefinition>;
113
+ }
114
+ interface DiscoveredWorkflowDefinition {
115
+ handler: string;
116
+ name: string;
117
+ source?: "inline" | "nitro-server-workflows" | "vite-suffix";
118
+ steps?: string[];
119
+ }
120
+ //#endregion
121
+ export { WorkflowStepRunner as A, WorkflowProviderStep as C, WorkflowStartOptions as D, WorkflowSharedOptions as E, WorkflowStepFunction as O, WorkflowProviderOptions as S, WorkflowRunStatus as T, WorkflowHandle as _, InferredWorkflowProviderOptions as a, WorkflowModuleProviderOptions as b, OpenWorkflowWorkerOptions as c, WorkflowCreateOptions as d, WorkflowDeferOptions as f, WorkflowExecutionContext as g, WorkflowDefinitionRegistry as h, DiscoveredWorkflowDefinition as i, WorkflowStepOptions as k, ResolvedWorkflowOptions as l, WorkflowDefinitionOptions as m, CloudflareWorkflowInstance as n, OpenWorkflowPostgresOptions as o, WorkflowDefinition as p, CloudflareWorkflowProviderOptions as r, OpenWorkflowProviderOptions as s, CloudflareWorkflowBinding as t, VercelWorkflowProviderOptions as u, WorkflowHandler as v, WorkflowRun as w, WorkflowProvider as x, WorkflowModuleOptions as y };
package/dist/vite.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { y as WorkflowModuleOptions } from "./types-ThDitg7Z.js";
2
+ import { NitroModule } from "nitro/types";
3
+ import { Plugin } from "vite";
4
+
5
+ //#region src/vite.d.ts
6
+ type WorkflowVitePlugin = Plugin & {
7
+ nitro: NitroModule;
8
+ };
9
+ declare function hubWorkflow(options?: WorkflowModuleOptions): WorkflowVitePlugin;
10
+ declare module "vite" {
11
+ interface UserConfig {
12
+ workflow?: WorkflowModuleOptions;
13
+ }
14
+ }
15
+ //#endregion
16
+ export { WorkflowVitePlugin, hubWorkflow };
package/dist/vite.js ADDED
@@ -0,0 +1,503 @@
1
+ import { t as normalizeWorkflowOptions } from "./config-DkgsQuXz.js";
2
+ import { r as getCloudflareWorkflowClassName, t as createCloudflareWorkflowBindings } from "./cloudflare-CeHVSHoN.js";
3
+ import { a as createImportPath, i as computePackageDir, n as discoverWorkflowDefinitions, o as ensureGeneratedDir, r as createRuntimeRegistryContents, s as resolveRuntimeModule$1, t as workflowNitroModule } from "./module-UYEnVfxy.js";
4
+ import { cp, mkdir, readFile, readdir, rm, writeFile } from "node:fs/promises";
5
+ import { basename, resolve } from "node:path";
6
+ import { existsSync } from "node:fs";
7
+ import { dirname, relative as relative$1, resolve as resolve$1 } from "pathe";
8
+ import { build } from "esbuild";
9
+ const VITEHUB_MODES = {
10
+ e2e: "e2e",
11
+ blob: "blob",
12
+ chat: "chat",
13
+ db: "db",
14
+ env: "env",
15
+ kv: "kv",
16
+ queue: "queue",
17
+ schedule: "schedule",
18
+ sandbox: "sandbox",
19
+ workspace: "workspace",
20
+ workflow: "workflow"
21
+ };
22
+ function isViteCli(argv) {
23
+ return argv.some((arg) => /(?:^|[/\\])vite(?:\.[cm]?js)?$/.test(arg) || arg === "vite");
24
+ }
25
+ function getViteCliMode(argv = process.argv) {
26
+ if (!isViteCli(argv)) return;
27
+ const modes = new Set(Object.values(VITEHUB_MODES));
28
+ for (let index = 0; index < argv.length; index += 1) {
29
+ const arg = argv[index];
30
+ const mode = arg === "--mode" || arg === "-m" ? argv[index + 1] : arg.startsWith("--mode=") ? arg.slice(7) : void 0;
31
+ if (mode && modes.has(mode)) return mode;
32
+ }
33
+ }
34
+ function getViteMode(env = process.env) {
35
+ return env["VITEHUB_VITE_MODE"] ?? getViteCliMode();
36
+ }
37
+ //#endregion
38
+ //#region ../internal/src/build/client-output.ts
39
+ function hasStaticIndex(clientDir) {
40
+ return existsSync(resolve$1(clientDir, "index.html"));
41
+ }
42
+ async function copyClientOutput(clientDir, targetDir) {
43
+ const resolvedClientDir = resolve$1(clientDir);
44
+ const resolvedTargetDir = resolve$1(targetDir);
45
+ if (resolvedClientDir === resolvedTargetDir) return;
46
+ await rm(resolvedTargetDir, {
47
+ force: true,
48
+ recursive: true
49
+ });
50
+ await mkdir(dirname(resolvedTargetDir), { recursive: true });
51
+ const targetRelativePath = relative$1(resolvedClientDir, resolvedTargetDir);
52
+ if (targetRelativePath && !targetRelativePath.startsWith("../")) {
53
+ const [targetRootEntry] = targetRelativePath.split("/", 1);
54
+ await mkdir(resolvedTargetDir, { recursive: true });
55
+ await Promise.all((await readdir(resolvedClientDir)).filter((entry) => entry !== targetRootEntry).map((entry) => cp(resolve$1(resolvedClientDir, entry), resolve$1(resolvedTargetDir, entry), { recursive: true })));
56
+ return;
57
+ }
58
+ await cp(resolvedClientDir, resolvedTargetDir, { recursive: true });
59
+ }
60
+ //#endregion
61
+ //#region ../internal/src/build/esbuild.ts
62
+ async function bundleEsmEntry(entryFile, outfile, options = {}) {
63
+ const format = options.format || "esm";
64
+ const platform = options.platform || "neutral";
65
+ await build({
66
+ alias: options.alias,
67
+ banner: format === "esm" && platform === "node" ? { js: "import { createRequire as __createRequire } from \"node:module\";\nvar require = __createRequire(import.meta.url);\n" } : void 0,
68
+ bundle: true,
69
+ conditions: options.conditions,
70
+ entryPoints: [entryFile],
71
+ external: options.external,
72
+ format,
73
+ logLevel: "silent",
74
+ outfile,
75
+ platform,
76
+ sourcemap: false,
77
+ target: "es2022",
78
+ write: true
79
+ });
80
+ }
81
+ //#endregion
82
+ //#region ../internal/src/build/user-entry.ts
83
+ function toSafeAppName(rootDir) {
84
+ return basename(rootDir).replace(/[^a-z0-9-]+/gi, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
85
+ }
86
+ const DEFAULT_ENTRY_NAMES = [
87
+ "server.ts",
88
+ "server.mts",
89
+ "server.js",
90
+ "server.mjs",
91
+ "worker.ts",
92
+ "worker.mts",
93
+ "worker.js",
94
+ "worker.mjs"
95
+ ];
96
+ function resolveUserAppEntry(rootDir, options = {}) {
97
+ const names = options.names ?? DEFAULT_ENTRY_NAMES;
98
+ const srcSubdir = options.srcSubdir ?? "src";
99
+ return names.map((name) => resolve(rootDir, srcSubdir, name)).find(existsSync);
100
+ }
101
+ //#endregion
102
+ //#region ../internal/src/build/vercel-config.ts
103
+ function createVercelConfigJson() {
104
+ return {
105
+ routes: [{ handle: "filesystem" }, {
106
+ src: "/(.*)",
107
+ dest: "/__server"
108
+ }],
109
+ version: 3
110
+ };
111
+ }
112
+ function createNodeFunctionConfig(extra = {}) {
113
+ return {
114
+ handler: "index.mjs",
115
+ launcherType: "Nodejs",
116
+ runtime: "nodejs22.x",
117
+ shouldAddHelpers: false,
118
+ supportsResponseStreaming: true,
119
+ ...extra
120
+ };
121
+ }
122
+ //#endregion
123
+ //#region ../internal/src/build/deployment-output.ts
124
+ function resolveClientOutput(rootDir, clientOutDir) {
125
+ const clientDir = resolve(rootDir, clientOutDir);
126
+ return {
127
+ clientDir,
128
+ staticIndex: hasStaticIndex(clientDir)
129
+ };
130
+ }
131
+ function isJsonObject(value) {
132
+ return typeof value === "object" && value !== null && !Array.isArray(value);
133
+ }
134
+ async function readJsonObject(file) {
135
+ try {
136
+ const parsed = JSON.parse(await readFile(file, "utf8"));
137
+ return isJsonObject(parsed) ? parsed : {};
138
+ } catch (error) {
139
+ if (error.code === "ENOENT") return {};
140
+ throw error;
141
+ }
142
+ }
143
+ function deleteJsonObjectKeys(value, keys) {
144
+ if (!keys?.length) return value;
145
+ const next = { ...value };
146
+ for (const key of keys) delete next[key];
147
+ return next;
148
+ }
149
+ async function writeMergedJsonObject(file, value, ownedKeys) {
150
+ const existing = await readJsonObject(file);
151
+ await writeFile(file, `${JSON.stringify({
152
+ ...deleteJsonObjectKeys(existing, ownedKeys),
153
+ ...value
154
+ }, null, 2)}\n`, "utf8");
155
+ }
156
+ async function deleteJsonObjectKeysFromFile(file, keys) {
157
+ if (!keys?.length) return;
158
+ let existing;
159
+ try {
160
+ const parsed = JSON.parse(await readFile(file, "utf8"));
161
+ existing = isJsonObject(parsed) ? parsed : {};
162
+ } catch (error) {
163
+ if (error.code === "ENOENT") return;
164
+ throw error;
165
+ }
166
+ const next = { ...existing };
167
+ let changed = false;
168
+ for (const key of keys) if (key in next) {
169
+ delete next[key];
170
+ changed = true;
171
+ }
172
+ if (!changed) return;
173
+ await writeFile(file, `${JSON.stringify(next, null, 2)}\n`, "utf8");
174
+ }
175
+ function shouldSkipViteProviderBuild(command, mode) {
176
+ return command === "serve" || mode === "e2e";
177
+ }
178
+ function createDefaultCloudflareOutputRoot(rootDir) {
179
+ return resolve(rootDir, "dist", toSafeAppName(rootDir));
180
+ }
181
+ function createDefaultCloudflareStaticOutputDir(rootDir) {
182
+ return resolve(rootDir, "dist", "client");
183
+ }
184
+ function createDefaultVercelOutputRoot(rootDir) {
185
+ return resolve(rootDir, ".vercel", "output");
186
+ }
187
+ async function writeCloudflareDeploymentOutput(options) {
188
+ const { clientDir, staticIndex } = resolveClientOutput(options.rootDir, options.clientOutDir);
189
+ const outputRoot = options.outputRoot ?? createDefaultCloudflareOutputRoot(options.rootDir);
190
+ const workerOutfile = resolve(outputRoot, options.bundleOutfileName ?? "index.js");
191
+ await mkdir(outputRoot, { recursive: true });
192
+ await rm(workerOutfile, {
193
+ force: true,
194
+ recursive: true
195
+ });
196
+ await Promise.all([
197
+ bundleEsmEntry(options.bundleEntry, workerOutfile, options.bundleOptions),
198
+ writeMergedJsonObject(resolve(outputRoot, "wrangler.json"), options.wranglerConfig, options.wranglerConfigKeys),
199
+ staticIndex ? copyClientOutput(clientDir, options.staticOutputDir ?? createDefaultCloudflareStaticOutputDir(options.rootDir)) : Promise.resolve()
200
+ ]);
201
+ }
202
+ async function writeVercelDeploymentOutput(options) {
203
+ const { clientDir, staticIndex } = resolveClientOutput(options.rootDir, options.clientOutDir);
204
+ const outputRoot = options.outputRoot ?? createDefaultVercelOutputRoot(options.rootDir);
205
+ const serverDir = resolve(outputRoot, "functions", options.serverFunctionName ?? "__server.func");
206
+ const serverEntry = resolve(serverDir, "index.mjs");
207
+ await rm(serverDir, {
208
+ force: true,
209
+ recursive: true
210
+ });
211
+ await mkdir(serverDir, { recursive: true });
212
+ await Promise.all([
213
+ bundleEsmEntry(options.bundleEntry, serverEntry, options.bundleOptions),
214
+ writeFile(resolve(serverDir, ".vc-config.json"), `${JSON.stringify(options.functionConfig ?? createNodeFunctionConfig(), null, 2)}\n`, "utf8"),
215
+ writeMergedJsonObject(resolve(outputRoot, "config.json"), options.config ?? createVercelConfigJson(), options.configKeys),
216
+ staticIndex ? copyClientOutput(clientDir, options.staticOutputDir ?? resolve(outputRoot, "static")) : Promise.resolve()
217
+ ]);
218
+ }
219
+ async function cleanupCloudflareDeploymentOutput(rootDir, cleanup) {
220
+ const outputRoot = cleanup.outputRoot ?? createDefaultCloudflareOutputRoot(rootDir);
221
+ const writes = [];
222
+ if (cleanup.bundleOutfileName) writes.push(rm(resolve(outputRoot, cleanup.bundleOutfileName), {
223
+ force: true,
224
+ recursive: true
225
+ }));
226
+ writes.push(deleteJsonObjectKeysFromFile(resolve(outputRoot, "wrangler.json"), cleanup.wranglerConfigKeys));
227
+ await Promise.all(writes);
228
+ }
229
+ async function cleanupVercelDeploymentOutput(rootDir, cleanup) {
230
+ const outputRoot = cleanup.outputRoot ?? createDefaultVercelOutputRoot(rootDir);
231
+ const writes = [];
232
+ if (cleanup.serverFunctionName) writes.push(rm(resolve(outputRoot, "functions", cleanup.serverFunctionName), {
233
+ force: true,
234
+ recursive: true
235
+ }));
236
+ writes.push(deleteJsonObjectKeysFromFile(resolve(outputRoot, "config.json"), cleanup.configKeys));
237
+ await Promise.all(writes);
238
+ }
239
+ async function writeProviderDeploymentOutputs(options) {
240
+ const writes = [];
241
+ if (options.cloudflare) writes.push(writeCloudflareDeploymentOutput({
242
+ ...options.cloudflare,
243
+ clientOutDir: options.clientOutDir,
244
+ rootDir: options.rootDir
245
+ }));
246
+ else if (options.cleanup?.cloudflare) writes.push(cleanupCloudflareDeploymentOutput(options.rootDir, options.cleanup.cloudflare));
247
+ if (options.vercel) writes.push(writeVercelDeploymentOutput({
248
+ ...options.vercel,
249
+ clientOutDir: options.clientOutDir,
250
+ rootDir: options.rootDir
251
+ }));
252
+ else if (options.cleanup?.vercel) writes.push(cleanupVercelDeploymentOutput(options.rootDir, options.cleanup.vercel));
253
+ await Promise.all(writes);
254
+ }
255
+ //#endregion
256
+ //#region ../internal/src/build/vite.ts
257
+ function createNoExternalMerger(packageName) {
258
+ return (current) => {
259
+ if (current === true) return true;
260
+ if (!current) return [packageName];
261
+ const values = Array.isArray(current) ? current : [current];
262
+ return values.includes(packageName) ? values : [...values, packageName];
263
+ };
264
+ }
265
+ function isServerEnvironment(name, config) {
266
+ return name === "ssr" || config.consumer === "server";
267
+ }
268
+ //#endregion
269
+ //#region ../internal/src/build/cloudflare.ts
270
+ const defaultCloudflareCompatibilityDate = "2026-04-20";
271
+ //#endregion
272
+ //#region src/internal/vite-build.ts
273
+ const workflowPackageName = "@vite-hub/workflow";
274
+ const productName = "workflow";
275
+ const generatedRegistryFileName = "registry.mjs";
276
+ const packageDir = computePackageDir(import.meta.url);
277
+ const resolveRuntimeModule = (modulePath) => resolveRuntimeModule$1(packageDir, modulePath);
278
+ const WORKFLOW_ENTRY_BASE_NAMES = [
279
+ "server.ts",
280
+ "server.mts",
281
+ "server.js",
282
+ "server.mjs",
283
+ "worker.ts",
284
+ "worker.mts",
285
+ "worker.js",
286
+ "worker.mjs"
287
+ ];
288
+ const WORKFLOW_PRIORITY_NAMES = [
289
+ "server-workflow.ts",
290
+ "server-workflow.mts",
291
+ "server-workflow.js",
292
+ "server-workflow.mjs"
293
+ ];
294
+ function resolveWorkflowUserAppEntry(rootDir) {
295
+ return resolveUserAppEntry(rootDir, { names: getViteMode() === VITEHUB_MODES.workflow ? [...WORKFLOW_PRIORITY_NAMES, ...WORKFLOW_ENTRY_BASE_NAMES] : [...WORKFLOW_ENTRY_BASE_NAMES] });
296
+ }
297
+ const providerEntrySpecs = [{
298
+ name: "cloudflare",
299
+ entryFile: "cloudflare-worker.mjs",
300
+ runtimeModule: "runtime/cloudflare-vite",
301
+ factory: "createWorkflowCloudflareWorker",
302
+ hosting: "cloudflare"
303
+ }, {
304
+ name: "vercel",
305
+ entryFile: "vercel-server.mjs",
306
+ runtimeModule: "runtime/vercel-vite",
307
+ factory: "createWorkflowVercelServer",
308
+ hosting: "vercel"
309
+ }];
310
+ function resolveWorkflowConfig(workflow, hosting) {
311
+ return normalizeWorkflowOptions(workflow, { hosting }) ?? false;
312
+ }
313
+ function renderCloudflareWorkerWrapper(definitions) {
314
+ return [
315
+ definitions.length ? `import { WorkflowEntrypoint, waitUntil as viteHubWaitUntil } from "cloudflare:workers"` : `import { waitUntil as viteHubWaitUntil } from "cloudflare:workers"`,
316
+ `import worker, { runViteHubWorkflowDefinition } from "./worker.mjs"`,
317
+ "",
318
+ ...definitions.map((definition) => {
319
+ return [
320
+ `export class ${getCloudflareWorkflowClassName(definition.name)} extends WorkflowEntrypoint {`,
321
+ " async run(event, step) {",
322
+ ` return await runViteHubWorkflowDefinition(${JSON.stringify(definition.name)}, this.env || {}, event, step)`,
323
+ " }",
324
+ "}",
325
+ ""
326
+ ].join("\n");
327
+ }),
328
+ "const viteHubWorker = {",
329
+ " async fetch(request, env, context) {",
330
+ " const waitUntil = typeof viteHubWaitUntil === \"function\" ? viteHubWaitUntil : context?.waitUntil?.bind(context)",
331
+ " return await worker.fetch(request, env, waitUntil ? { ...context, waitUntil } : context)",
332
+ " }",
333
+ "}",
334
+ "",
335
+ "export default viteHubWorker",
336
+ ""
337
+ ].join("\n");
338
+ }
339
+ function renderProviderEntry(spec, entryFile, userAppEntry, serializedWorkflowConfig) {
340
+ const imports = [`import { ${spec.factory} } from ${JSON.stringify(createImportPath(entryFile, resolveRuntimeModule(spec.runtimeModule)))}`, `import workflowRegistry from ${JSON.stringify(`./${generatedRegistryFileName}`)}`];
341
+ if (spec.name === "cloudflare") imports.push(`import { runCloudflareWorkflow } from ${JSON.stringify(createImportPath(entryFile, resolveRuntimeModule("runtime/cloudflare-runner")))}`);
342
+ if (userAppEntry) imports.push(`import workflowApp from ${JSON.stringify(createImportPath(entryFile, userAppEntry))}`);
343
+ const cloudflareDispatcher = spec.name === "cloudflare" ? [
344
+ "",
345
+ "export async function runViteHubWorkflowDefinition(name, env, event, step) {",
346
+ " return await runCloudflareWorkflow({ config: workflowConfig, env: env || {}, event, name, registry: workflowRegistry, step })",
347
+ "}"
348
+ ] : [];
349
+ return [
350
+ ...imports,
351
+ "",
352
+ `const workflowConfig = ${serializedWorkflowConfig}`,
353
+ ...cloudflareDispatcher,
354
+ "",
355
+ `export default ${spec.factory}({`,
356
+ userAppEntry ? " app: workflowApp," : "",
357
+ " registry: workflowRegistry,",
358
+ " workflow: workflowConfig,",
359
+ "})",
360
+ ""
361
+ ].filter(Boolean).join("\n");
362
+ }
363
+ async function writeProviderEntries(rootDir, workflow) {
364
+ const generatedDir = ensureGeneratedDir(rootDir, productName);
365
+ await mkdir(generatedDir, { recursive: true });
366
+ const registryFile = resolve(generatedDir, generatedRegistryFileName);
367
+ const definitions = discoverWorkflowDefinitions({ rootDir });
368
+ const providerDefinitions = definitions;
369
+ const userAppEntry = resolveWorkflowUserAppEntry(rootDir);
370
+ const cloudflareWorkflowConfig = resolveWorkflowConfig(workflow, "cloudflare");
371
+ await writeFile(registryFile, createRuntimeRegistryContents(registryFile, definitions), "utf8");
372
+ const entryFiles = {
373
+ cloudflare: "",
374
+ openworkflow: "",
375
+ vercel: ""
376
+ };
377
+ await Promise.all(providerEntrySpecs.map(async (spec) => {
378
+ const entryFile = resolve(generatedDir, spec.entryFile);
379
+ const workflowConfig = spec.name === "cloudflare" ? cloudflareWorkflowConfig : resolveWorkflowConfig(workflow, spec.hosting);
380
+ await writeFile(entryFile, renderProviderEntry(spec, entryFile, userAppEntry, JSON.stringify(workflowConfig, null, 2)), "utf8");
381
+ entryFiles[spec.name] = entryFile;
382
+ }));
383
+ return {
384
+ cloudflareWorkerFile: entryFiles.cloudflare,
385
+ cloudflareWorkflowConfig,
386
+ definitions,
387
+ generatedDir,
388
+ providerDefinitions,
389
+ registryFile,
390
+ vercelServerFile: entryFiles.vercel
391
+ };
392
+ }
393
+ function createCloudflareOutput(rootDir, artifacts) {
394
+ const workflowConfig = artifacts.cloudflareWorkflowConfig && artifacts.cloudflareWorkflowConfig.provider === "cloudflare" ? artifacts.cloudflareWorkflowConfig : false;
395
+ const workflows = createCloudflareWorkflowBindings(workflowConfig ? artifacts.providerDefinitions : [], workflowConfig);
396
+ const wranglerConfig = {
397
+ compatibility_date: defaultCloudflareCompatibilityDate,
398
+ compatibility_flags: ["nodejs_compat"],
399
+ main: "index.js",
400
+ observability: { enabled: true },
401
+ ...workflows ? { workflows } : {}
402
+ };
403
+ return {
404
+ bundleEntry: artifacts.cloudflareWorkerFile,
405
+ bundleOptions: {
406
+ conditions: [
407
+ "workerd",
408
+ "worker",
409
+ "browser",
410
+ "default"
411
+ ],
412
+ external: [
413
+ "@cloudflare/sandbox",
414
+ "@vercel/blob",
415
+ "@vercel/functions",
416
+ "@vercel/queue",
417
+ "@vercel/sandbox",
418
+ "cloudflare:workers",
419
+ "node:async_hooks",
420
+ "workflow",
421
+ "workflow/api",
422
+ "workflow/runtime"
423
+ ],
424
+ format: "esm",
425
+ platform: "neutral"
426
+ },
427
+ bundleOutfileName: "worker.mjs",
428
+ outputRoot: createDefaultCloudflareOutputRoot(rootDir),
429
+ wranglerConfigKeys: ["workflows"],
430
+ wranglerConfig
431
+ };
432
+ }
433
+ async function writeCloudflareWorkflowWrapper(rootDir, artifacts) {
434
+ const outputRoot = createDefaultCloudflareOutputRoot(rootDir);
435
+ const workflowDefinitions = (artifacts.cloudflareWorkflowConfig && artifacts.cloudflareWorkflowConfig.provider === "cloudflare" ? artifacts.cloudflareWorkflowConfig : false) ? artifacts.providerDefinitions : [];
436
+ await writeFile(resolve(outputRoot, "index.js"), renderCloudflareWorkerWrapper(workflowDefinitions), "utf8");
437
+ }
438
+ function createVercelOutput(artifacts) {
439
+ return {
440
+ bundleEntry: artifacts.vercelServerFile,
441
+ bundleOptions: {
442
+ external: [
443
+ "@cloudflare/sandbox",
444
+ "cloudflare:workers",
445
+ "workflow",
446
+ "workflow/api",
447
+ "workflow/runtime"
448
+ ],
449
+ format: "esm",
450
+ platform: "node"
451
+ }
452
+ };
453
+ }
454
+ async function generateProviderOutputs(options) {
455
+ const artifacts = await writeProviderEntries(options.rootDir, options.workflow);
456
+ const cloudflareWorkflowConfig = resolveWorkflowConfig(options.workflow, "cloudflare");
457
+ const vercelWorkflowConfig = resolveWorkflowConfig(options.workflow, "vercel");
458
+ await writeProviderDeploymentOutputs({
459
+ clientOutDir: options.clientOutDir,
460
+ ...cloudflareWorkflowConfig && cloudflareWorkflowConfig.provider === "cloudflare" ? { cloudflare: createCloudflareOutput(options.rootDir, artifacts) } : {},
461
+ cleanup: { cloudflare: {
462
+ bundleOutfileName: "worker.mjs",
463
+ outputRoot: createDefaultCloudflareOutputRoot(options.rootDir),
464
+ wranglerConfigKeys: ["workflows"]
465
+ } },
466
+ rootDir: options.rootDir,
467
+ ...vercelWorkflowConfig && vercelWorkflowConfig.provider === "vercel" ? { vercel: createVercelOutput(artifacts) } : {}
468
+ });
469
+ if (cloudflareWorkflowConfig && cloudflareWorkflowConfig.provider === "cloudflare") await writeCloudflareWorkflowWrapper(options.rootDir, artifacts);
470
+ return artifacts;
471
+ }
472
+ //#endregion
473
+ //#region src/vite.ts
474
+ const mergeNoExternal = createNoExternalMerger(workflowPackageName);
475
+ function hubWorkflow(options) {
476
+ let resolved;
477
+ let workflow = options;
478
+ return {
479
+ name: "@vite-hub/workflow/vite",
480
+ nitro: workflowNitroModule,
481
+ config(config) {
482
+ workflow = config.workflow ?? workflow;
483
+ },
484
+ configResolved(config) {
485
+ resolved = config;
486
+ workflow = config.workflow ?? workflow;
487
+ },
488
+ configEnvironment(name, config) {
489
+ if (!isServerEnvironment(name, config)) return;
490
+ return { resolve: { noExternal: mergeNoExternal(config.resolve?.noExternal) } };
491
+ },
492
+ async closeBundle() {
493
+ if (!resolved || shouldSkipViteProviderBuild(resolved.command, getViteMode())) return;
494
+ await generateProviderOutputs({
495
+ clientOutDir: resolved.build.outDir,
496
+ rootDir: resolved.root,
497
+ workflow
498
+ });
499
+ }
500
+ };
501
+ }
502
+ //#endregion
503
+ export { hubWorkflow };