@tanstack/workflow-vercel 0.0.1 → 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/dist/index.cjs +1 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/sweep-handler.cjs +0 -25
- package/dist/sweep-handler.cjs.map +1 -1
- package/dist/sweep-handler.d.cts +1 -16
- package/dist/sweep-handler.d.ts +1 -16
- package/dist/sweep-handler.js +1 -24
- package/dist/sweep-handler.js.map +1 -1
- package/package.json +4 -1
- package/src/index.ts +1 -5
- package/src/sweep-handler.ts +0 -54
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,5 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
const require_sweep_handler = require('./sweep-handler.cjs');
|
|
3
3
|
let _tanstack_workflow_runtime = require("@tanstack/workflow-runtime");
|
|
4
4
|
|
|
5
|
-
exports.createVercelWorkflowCronConfig = require_sweep_handler.createVercelWorkflowCronConfig;
|
|
6
5
|
exports.createVercelWorkflowSweepHandler = require_sweep_handler.createVercelWorkflowSweepHandler;
|
|
7
|
-
exports.materializeWorkflowSchedules = _tanstack_workflow_runtime.materializeWorkflowSchedules;
|
|
8
|
-
exports.vercelWorkflowCronConfig = require_sweep_handler.vercelWorkflowCronConfig;
|
|
6
|
+
exports.materializeWorkflowSchedules = _tanstack_workflow_runtime.materializeWorkflowSchedules;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MaterializeWorkflowSchedulesOptions, MaterializedWorkflowSchedule,
|
|
2
|
-
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule, type
|
|
1
|
+
import { MaterializeWorkflowSchedulesOptions, MaterializedWorkflowSchedule, VercelWorkflowSweepHandler, VercelWorkflowSweepHandlerOptions, VercelWorkflowSweepResponse, VercelWorkflowSweepSummary, VercelWorkflowUnauthorizedResponse, createVercelWorkflowSweepHandler, materializeWorkflowSchedules } from "./sweep-handler.cjs";
|
|
2
|
+
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule, type VercelWorkflowSweepHandler, type VercelWorkflowSweepHandlerOptions, type VercelWorkflowSweepResponse, type VercelWorkflowSweepSummary, type VercelWorkflowUnauthorizedResponse, createVercelWorkflowSweepHandler, materializeWorkflowSchedules };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { MaterializeWorkflowSchedulesOptions, MaterializedWorkflowSchedule,
|
|
2
|
-
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule, type
|
|
1
|
+
import { MaterializeWorkflowSchedulesOptions, MaterializedWorkflowSchedule, VercelWorkflowSweepHandler, VercelWorkflowSweepHandlerOptions, VercelWorkflowSweepResponse, VercelWorkflowSweepSummary, VercelWorkflowUnauthorizedResponse, createVercelWorkflowSweepHandler, materializeWorkflowSchedules } from "./sweep-handler.js";
|
|
2
|
+
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule, type VercelWorkflowSweepHandler, type VercelWorkflowSweepHandlerOptions, type VercelWorkflowSweepResponse, type VercelWorkflowSweepSummary, type VercelWorkflowUnauthorizedResponse, createVercelWorkflowSweepHandler, materializeWorkflowSchedules };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { createVercelWorkflowSweepHandler, materializeWorkflowSchedules } from "./sweep-handler.js";
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export { createVercelWorkflowSweepHandler, materializeWorkflowSchedules };
|
package/dist/sweep-handler.cjs
CHANGED
|
@@ -1,29 +1,6 @@
|
|
|
1
1
|
let _tanstack_workflow_runtime = require("@tanstack/workflow-runtime");
|
|
2
2
|
|
|
3
3
|
//#region src/sweep-handler.ts
|
|
4
|
-
const DEFAULT_SWEEP_INTERVAL_MINUTES = 5;
|
|
5
|
-
const DEFAULT_SWEEP_PATH = "/api/workflow/sweep";
|
|
6
|
-
const vercelWorkflowCronConfig = createVercelWorkflowCronConfig();
|
|
7
|
-
function createVercelWorkflowCronConfig(options = {}) {
|
|
8
|
-
const path = options.path ?? DEFAULT_SWEEP_PATH;
|
|
9
|
-
if (!path.startsWith("/")) throw new Error("Vercel workflow cron path must start with \"/\".");
|
|
10
|
-
if (options.schedule) return {
|
|
11
|
-
$schema: "https://openapi.vercel.sh/vercel.json",
|
|
12
|
-
crons: [{
|
|
13
|
-
path,
|
|
14
|
-
schedule: options.schedule
|
|
15
|
-
}]
|
|
16
|
-
};
|
|
17
|
-
const everyMinutes = options.everyMinutes ?? DEFAULT_SWEEP_INTERVAL_MINUTES;
|
|
18
|
-
if (!Number.isInteger(everyMinutes) || everyMinutes <= 0) throw new Error("Vercel workflow sweep interval must be a positive integer.");
|
|
19
|
-
return {
|
|
20
|
-
$schema: "https://openapi.vercel.sh/vercel.json",
|
|
21
|
-
crons: [{
|
|
22
|
-
path,
|
|
23
|
-
schedule: everyMinutes === 1 ? "* * * * *" : `*/${everyMinutes} * * * *`
|
|
24
|
-
}]
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
4
|
function createVercelWorkflowSweepHandler(options) {
|
|
28
5
|
return async (request) => {
|
|
29
6
|
if (!isAuthorized(request, options.cronSecret)) return Response.json({
|
|
@@ -81,7 +58,5 @@ function defaultLeaseOwner(request, now) {
|
|
|
81
58
|
}
|
|
82
59
|
|
|
83
60
|
//#endregion
|
|
84
|
-
exports.createVercelWorkflowCronConfig = createVercelWorkflowCronConfig;
|
|
85
61
|
exports.createVercelWorkflowSweepHandler = createVercelWorkflowSweepHandler;
|
|
86
|
-
exports.vercelWorkflowCronConfig = vercelWorkflowCronConfig;
|
|
87
62
|
//# sourceMappingURL=sweep-handler.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sweep-handler.cjs","names":[],"sources":["../src/sweep-handler.ts"],"sourcesContent":["import { materializeWorkflowSchedules } from '@tanstack/workflow-runtime'\nimport type {\n MaterializedWorkflowSchedule,\n WorkflowRegistrationMap,\n WorkflowRuntimeDefinition,\n WorkflowRuntimeSweepArgs,\n WorkflowRuntimeSweepResult,\n} from '@tanstack/workflow-runtime'\n\
|
|
1
|
+
{"version":3,"file":"sweep-handler.cjs","names":[],"sources":["../src/sweep-handler.ts"],"sourcesContent":["import { materializeWorkflowSchedules } from '@tanstack/workflow-runtime'\nimport type {\n MaterializedWorkflowSchedule,\n WorkflowRegistrationMap,\n WorkflowRuntimeDefinition,\n WorkflowRuntimeSweepArgs,\n WorkflowRuntimeSweepResult,\n} from '@tanstack/workflow-runtime'\n\nexport { materializeWorkflowSchedules }\nexport type {\n MaterializedWorkflowSchedule,\n MaterializeWorkflowSchedulesOptions,\n} from '@tanstack/workflow-runtime'\n\nexport interface VercelWorkflowSweepResponse {\n ok: true\n now: number\n leaseOwner: string\n materialized: ReadonlyArray<MaterializedWorkflowSchedule>\n summary: VercelWorkflowSweepSummary\n deadlineReached: boolean\n remainingMayExist: boolean\n sweep?: WorkflowRuntimeSweepResult\n}\n\nexport interface VercelWorkflowUnauthorizedResponse {\n ok: false\n error: 'Unauthorized'\n}\n\nexport type VercelWorkflowSweepSummary =\n WorkflowRuntimeSweepResult['summary'] & {\n materialized: number\n }\n\nexport type VercelWorkflowSweepHandler = (request: Request) => Promise<Response>\n\nexport interface VercelWorkflowSweepHandlerOptions<\n TWorkflows extends WorkflowRegistrationMap = WorkflowRegistrationMap,\n> {\n runtime: WorkflowRuntimeDefinition<TWorkflows>\n now?: () => number\n leaseOwner?:\n | string\n | ((args: { request: Request; now: number }) => string | undefined)\n limit?: number\n maxScheduledRuns?: number\n maxTimers?: number\n maxDurationMs?: number\n leaseMs?: number\n includeEvents?: boolean\n maxEvents?: number\n includeSweepResult?: boolean\n materializeSchedules?: boolean\n cronLookbackMs?: number\n cronSecret?: string\n}\n\nexport function createVercelWorkflowSweepHandler<\n TWorkflows extends WorkflowRegistrationMap,\n>(\n options: VercelWorkflowSweepHandlerOptions<TWorkflows>,\n): VercelWorkflowSweepHandler {\n return async (request) => {\n if (!isAuthorized(request, options.cronSecret)) {\n return Response.json(\n {\n ok: false,\n error: 'Unauthorized',\n } satisfies VercelWorkflowUnauthorizedResponse,\n { status: 401 },\n )\n }\n\n const now = options.now?.() ?? Date.now()\n const materialized =\n options.materializeSchedules === false\n ? []\n : await materializeWorkflowSchedules(options.runtime, {\n now,\n cronLookbackMs: options.cronLookbackMs,\n })\n const leaseOwner = resolveLeaseOwner(options.leaseOwner, request, now)\n const sweepArgs: WorkflowRuntimeSweepArgs = {\n now,\n leaseOwner,\n limit: options.limit,\n maxScheduledRuns: options.maxScheduledRuns,\n maxTimers: options.maxTimers,\n maxDurationMs: options.maxDurationMs,\n leaseMs: options.leaseMs,\n includeEvents: options.includeEvents ?? false,\n maxEvents: options.maxEvents,\n }\n const sweep = await options.runtime.sweep(sweepArgs)\n const response: VercelWorkflowSweepResponse = {\n ok: true,\n now,\n leaseOwner,\n materialized,\n summary: {\n materialized: materialized.length,\n ...sweep.summary,\n },\n deadlineReached: sweep.deadlineReached,\n remainingMayExist: sweep.remainingMayExist,\n ...(options.includeSweepResult ? { sweep } : undefined),\n }\n\n return Response.json(response)\n }\n}\n\nfunction isAuthorized(request: Request, cronSecret: string | undefined) {\n if (!cronSecret) return true\n return request.headers.get('authorization') === `Bearer ${cronSecret}`\n}\n\nfunction resolveLeaseOwner(\n leaseOwner: VercelWorkflowSweepHandlerOptions['leaseOwner'],\n request: Request,\n now: number,\n) {\n if (typeof leaseOwner === 'string') return leaseOwner\n if (typeof leaseOwner === 'function') {\n return leaseOwner({ request, now }) ?? defaultLeaseOwner(request, now)\n }\n return defaultLeaseOwner(request, now)\n}\n\nfunction defaultLeaseOwner(request: Request, now: number) {\n return `vercel:${request.headers.get('x-vercel-id') ?? now}`\n}\n"],"mappings":";;;AA2DA,SAAgB,iCAGd,SAC4B;AAC5B,QAAO,OAAO,YAAY;AACxB,MAAI,CAAC,aAAa,SAAS,QAAQ,WAAW,CAC5C,QAAO,SAAS,KACd;GACE,IAAI;GACJ,OAAO;GACR,EACD,EAAE,QAAQ,KAAK,CAChB;EAGH,MAAM,MAAM,QAAQ,OAAO,IAAI,KAAK,KAAK;EACzC,MAAM,eACJ,QAAQ,yBAAyB,QAC7B,EAAE,GACF,mEAAmC,QAAQ,SAAS;GAClD;GACA,gBAAgB,QAAQ;GACzB,CAAC;EACR,MAAM,aAAa,kBAAkB,QAAQ,YAAY,SAAS,IAAI;EACtE,MAAM,YAAsC;GAC1C;GACA;GACA,OAAO,QAAQ;GACf,kBAAkB,QAAQ;GAC1B,WAAW,QAAQ;GACnB,eAAe,QAAQ;GACvB,SAAS,QAAQ;GACjB,eAAe,QAAQ,iBAAiB;GACxC,WAAW,QAAQ;GACpB;EACD,MAAM,QAAQ,MAAM,QAAQ,QAAQ,MAAM,UAAU;EACpD,MAAM,WAAwC;GAC5C,IAAI;GACJ;GACA;GACA;GACA,SAAS;IACP,cAAc,aAAa;IAC3B,GAAG,MAAM;IACV;GACD,iBAAiB,MAAM;GACvB,mBAAmB,MAAM;GACzB,GAAI,QAAQ,qBAAqB,EAAE,OAAO,GAAG;GAC9C;AAED,SAAO,SAAS,KAAK,SAAS;;;AAIlC,SAAS,aAAa,SAAkB,YAAgC;AACtE,KAAI,CAAC,WAAY,QAAO;AACxB,QAAO,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,UAAU;;AAG5D,SAAS,kBACP,YACA,SACA,KACA;AACA,KAAI,OAAO,eAAe,SAAU,QAAO;AAC3C,KAAI,OAAO,eAAe,WACxB,QAAO,WAAW;EAAE;EAAS;EAAK,CAAC,IAAI,kBAAkB,SAAS,IAAI;AAExE,QAAO,kBAAkB,SAAS,IAAI;;AAGxC,SAAS,kBAAkB,SAAkB,KAAa;AACxD,QAAO,UAAU,QAAQ,QAAQ,IAAI,cAAc,IAAI"}
|
package/dist/sweep-handler.d.cts
CHANGED
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { MaterializeWorkflowSchedulesOptions, MaterializedWorkflowSchedule, MaterializedWorkflowSchedule as MaterializedWorkflowSchedule$1, WorkflowRegistrationMap, WorkflowRuntimeDefinition, WorkflowRuntimeSweepResult, materializeWorkflowSchedules } from "@tanstack/workflow-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/sweep-handler.d.ts
|
|
4
|
-
interface VercelWorkflowCron {
|
|
5
|
-
path: string;
|
|
6
|
-
schedule: string;
|
|
7
|
-
}
|
|
8
|
-
interface VercelWorkflowCronConfig {
|
|
9
|
-
$schema: 'https://openapi.vercel.sh/vercel.json';
|
|
10
|
-
crons: ReadonlyArray<VercelWorkflowCron>;
|
|
11
|
-
}
|
|
12
|
-
interface VercelWorkflowCronConfigOptions {
|
|
13
|
-
path?: string;
|
|
14
|
-
schedule?: string;
|
|
15
|
-
everyMinutes?: number;
|
|
16
|
-
}
|
|
17
4
|
interface VercelWorkflowSweepResponse {
|
|
18
5
|
ok: true;
|
|
19
6
|
now: number;
|
|
@@ -51,9 +38,7 @@ interface VercelWorkflowSweepHandlerOptions<TWorkflows extends WorkflowRegistrat
|
|
|
51
38
|
cronLookbackMs?: number;
|
|
52
39
|
cronSecret?: string;
|
|
53
40
|
}
|
|
54
|
-
declare const vercelWorkflowCronConfig: VercelWorkflowCronConfig;
|
|
55
|
-
declare function createVercelWorkflowCronConfig(options?: VercelWorkflowCronConfigOptions): VercelWorkflowCronConfig;
|
|
56
41
|
declare function createVercelWorkflowSweepHandler<TWorkflows extends WorkflowRegistrationMap>(options: VercelWorkflowSweepHandlerOptions<TWorkflows>): VercelWorkflowSweepHandler;
|
|
57
42
|
//#endregion
|
|
58
|
-
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule$1 as MaterializedWorkflowSchedule,
|
|
43
|
+
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule$1 as MaterializedWorkflowSchedule, VercelWorkflowSweepHandler, VercelWorkflowSweepHandlerOptions, VercelWorkflowSweepResponse, VercelWorkflowSweepSummary, VercelWorkflowUnauthorizedResponse, createVercelWorkflowSweepHandler, materializeWorkflowSchedules };
|
|
59
44
|
//# sourceMappingURL=sweep-handler.d.cts.map
|
package/dist/sweep-handler.d.ts
CHANGED
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import { MaterializeWorkflowSchedulesOptions, MaterializedWorkflowSchedule, MaterializedWorkflowSchedule as MaterializedWorkflowSchedule$1, WorkflowRegistrationMap, WorkflowRuntimeDefinition, WorkflowRuntimeSweepResult, materializeWorkflowSchedules } from "@tanstack/workflow-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/sweep-handler.d.ts
|
|
4
|
-
interface VercelWorkflowCron {
|
|
5
|
-
path: string;
|
|
6
|
-
schedule: string;
|
|
7
|
-
}
|
|
8
|
-
interface VercelWorkflowCronConfig {
|
|
9
|
-
$schema: 'https://openapi.vercel.sh/vercel.json';
|
|
10
|
-
crons: ReadonlyArray<VercelWorkflowCron>;
|
|
11
|
-
}
|
|
12
|
-
interface VercelWorkflowCronConfigOptions {
|
|
13
|
-
path?: string;
|
|
14
|
-
schedule?: string;
|
|
15
|
-
everyMinutes?: number;
|
|
16
|
-
}
|
|
17
4
|
interface VercelWorkflowSweepResponse {
|
|
18
5
|
ok: true;
|
|
19
6
|
now: number;
|
|
@@ -51,9 +38,7 @@ interface VercelWorkflowSweepHandlerOptions<TWorkflows extends WorkflowRegistrat
|
|
|
51
38
|
cronLookbackMs?: number;
|
|
52
39
|
cronSecret?: string;
|
|
53
40
|
}
|
|
54
|
-
declare const vercelWorkflowCronConfig: VercelWorkflowCronConfig;
|
|
55
|
-
declare function createVercelWorkflowCronConfig(options?: VercelWorkflowCronConfigOptions): VercelWorkflowCronConfig;
|
|
56
41
|
declare function createVercelWorkflowSweepHandler<TWorkflows extends WorkflowRegistrationMap>(options: VercelWorkflowSweepHandlerOptions<TWorkflows>): VercelWorkflowSweepHandler;
|
|
57
42
|
//#endregion
|
|
58
|
-
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule$1 as MaterializedWorkflowSchedule,
|
|
43
|
+
export { type MaterializeWorkflowSchedulesOptions, type MaterializedWorkflowSchedule$1 as MaterializedWorkflowSchedule, VercelWorkflowSweepHandler, VercelWorkflowSweepHandlerOptions, VercelWorkflowSweepResponse, VercelWorkflowSweepSummary, VercelWorkflowUnauthorizedResponse, createVercelWorkflowSweepHandler, materializeWorkflowSchedules };
|
|
59
44
|
//# sourceMappingURL=sweep-handler.d.ts.map
|
package/dist/sweep-handler.js
CHANGED
|
@@ -1,29 +1,6 @@
|
|
|
1
1
|
import { materializeWorkflowSchedules } from "@tanstack/workflow-runtime";
|
|
2
2
|
|
|
3
3
|
//#region src/sweep-handler.ts
|
|
4
|
-
const DEFAULT_SWEEP_INTERVAL_MINUTES = 5;
|
|
5
|
-
const DEFAULT_SWEEP_PATH = "/api/workflow/sweep";
|
|
6
|
-
const vercelWorkflowCronConfig = createVercelWorkflowCronConfig();
|
|
7
|
-
function createVercelWorkflowCronConfig(options = {}) {
|
|
8
|
-
const path = options.path ?? DEFAULT_SWEEP_PATH;
|
|
9
|
-
if (!path.startsWith("/")) throw new Error("Vercel workflow cron path must start with \"/\".");
|
|
10
|
-
if (options.schedule) return {
|
|
11
|
-
$schema: "https://openapi.vercel.sh/vercel.json",
|
|
12
|
-
crons: [{
|
|
13
|
-
path,
|
|
14
|
-
schedule: options.schedule
|
|
15
|
-
}]
|
|
16
|
-
};
|
|
17
|
-
const everyMinutes = options.everyMinutes ?? DEFAULT_SWEEP_INTERVAL_MINUTES;
|
|
18
|
-
if (!Number.isInteger(everyMinutes) || everyMinutes <= 0) throw new Error("Vercel workflow sweep interval must be a positive integer.");
|
|
19
|
-
return {
|
|
20
|
-
$schema: "https://openapi.vercel.sh/vercel.json",
|
|
21
|
-
crons: [{
|
|
22
|
-
path,
|
|
23
|
-
schedule: everyMinutes === 1 ? "* * * * *" : `*/${everyMinutes} * * * *`
|
|
24
|
-
}]
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
4
|
function createVercelWorkflowSweepHandler(options) {
|
|
28
5
|
return async (request) => {
|
|
29
6
|
if (!isAuthorized(request, options.cronSecret)) return Response.json({
|
|
@@ -81,5 +58,5 @@ function defaultLeaseOwner(request, now) {
|
|
|
81
58
|
}
|
|
82
59
|
|
|
83
60
|
//#endregion
|
|
84
|
-
export {
|
|
61
|
+
export { createVercelWorkflowSweepHandler, materializeWorkflowSchedules };
|
|
85
62
|
//# sourceMappingURL=sweep-handler.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sweep-handler.js","names":[],"sources":["../src/sweep-handler.ts"],"sourcesContent":["import { materializeWorkflowSchedules } from '@tanstack/workflow-runtime'\nimport type {\n MaterializedWorkflowSchedule,\n WorkflowRegistrationMap,\n WorkflowRuntimeDefinition,\n WorkflowRuntimeSweepArgs,\n WorkflowRuntimeSweepResult,\n} from '@tanstack/workflow-runtime'\n\
|
|
1
|
+
{"version":3,"file":"sweep-handler.js","names":[],"sources":["../src/sweep-handler.ts"],"sourcesContent":["import { materializeWorkflowSchedules } from '@tanstack/workflow-runtime'\nimport type {\n MaterializedWorkflowSchedule,\n WorkflowRegistrationMap,\n WorkflowRuntimeDefinition,\n WorkflowRuntimeSweepArgs,\n WorkflowRuntimeSweepResult,\n} from '@tanstack/workflow-runtime'\n\nexport { materializeWorkflowSchedules }\nexport type {\n MaterializedWorkflowSchedule,\n MaterializeWorkflowSchedulesOptions,\n} from '@tanstack/workflow-runtime'\n\nexport interface VercelWorkflowSweepResponse {\n ok: true\n now: number\n leaseOwner: string\n materialized: ReadonlyArray<MaterializedWorkflowSchedule>\n summary: VercelWorkflowSweepSummary\n deadlineReached: boolean\n remainingMayExist: boolean\n sweep?: WorkflowRuntimeSweepResult\n}\n\nexport interface VercelWorkflowUnauthorizedResponse {\n ok: false\n error: 'Unauthorized'\n}\n\nexport type VercelWorkflowSweepSummary =\n WorkflowRuntimeSweepResult['summary'] & {\n materialized: number\n }\n\nexport type VercelWorkflowSweepHandler = (request: Request) => Promise<Response>\n\nexport interface VercelWorkflowSweepHandlerOptions<\n TWorkflows extends WorkflowRegistrationMap = WorkflowRegistrationMap,\n> {\n runtime: WorkflowRuntimeDefinition<TWorkflows>\n now?: () => number\n leaseOwner?:\n | string\n | ((args: { request: Request; now: number }) => string | undefined)\n limit?: number\n maxScheduledRuns?: number\n maxTimers?: number\n maxDurationMs?: number\n leaseMs?: number\n includeEvents?: boolean\n maxEvents?: number\n includeSweepResult?: boolean\n materializeSchedules?: boolean\n cronLookbackMs?: number\n cronSecret?: string\n}\n\nexport function createVercelWorkflowSweepHandler<\n TWorkflows extends WorkflowRegistrationMap,\n>(\n options: VercelWorkflowSweepHandlerOptions<TWorkflows>,\n): VercelWorkflowSweepHandler {\n return async (request) => {\n if (!isAuthorized(request, options.cronSecret)) {\n return Response.json(\n {\n ok: false,\n error: 'Unauthorized',\n } satisfies VercelWorkflowUnauthorizedResponse,\n { status: 401 },\n )\n }\n\n const now = options.now?.() ?? Date.now()\n const materialized =\n options.materializeSchedules === false\n ? []\n : await materializeWorkflowSchedules(options.runtime, {\n now,\n cronLookbackMs: options.cronLookbackMs,\n })\n const leaseOwner = resolveLeaseOwner(options.leaseOwner, request, now)\n const sweepArgs: WorkflowRuntimeSweepArgs = {\n now,\n leaseOwner,\n limit: options.limit,\n maxScheduledRuns: options.maxScheduledRuns,\n maxTimers: options.maxTimers,\n maxDurationMs: options.maxDurationMs,\n leaseMs: options.leaseMs,\n includeEvents: options.includeEvents ?? false,\n maxEvents: options.maxEvents,\n }\n const sweep = await options.runtime.sweep(sweepArgs)\n const response: VercelWorkflowSweepResponse = {\n ok: true,\n now,\n leaseOwner,\n materialized,\n summary: {\n materialized: materialized.length,\n ...sweep.summary,\n },\n deadlineReached: sweep.deadlineReached,\n remainingMayExist: sweep.remainingMayExist,\n ...(options.includeSweepResult ? { sweep } : undefined),\n }\n\n return Response.json(response)\n }\n}\n\nfunction isAuthorized(request: Request, cronSecret: string | undefined) {\n if (!cronSecret) return true\n return request.headers.get('authorization') === `Bearer ${cronSecret}`\n}\n\nfunction resolveLeaseOwner(\n leaseOwner: VercelWorkflowSweepHandlerOptions['leaseOwner'],\n request: Request,\n now: number,\n) {\n if (typeof leaseOwner === 'string') return leaseOwner\n if (typeof leaseOwner === 'function') {\n return leaseOwner({ request, now }) ?? defaultLeaseOwner(request, now)\n }\n return defaultLeaseOwner(request, now)\n}\n\nfunction defaultLeaseOwner(request: Request, now: number) {\n return `vercel:${request.headers.get('x-vercel-id') ?? now}`\n}\n"],"mappings":";;;AA2DA,SAAgB,iCAGd,SAC4B;AAC5B,QAAO,OAAO,YAAY;AACxB,MAAI,CAAC,aAAa,SAAS,QAAQ,WAAW,CAC5C,QAAO,SAAS,KACd;GACE,IAAI;GACJ,OAAO;GACR,EACD,EAAE,QAAQ,KAAK,CAChB;EAGH,MAAM,MAAM,QAAQ,OAAO,IAAI,KAAK,KAAK;EACzC,MAAM,eACJ,QAAQ,yBAAyB,QAC7B,EAAE,GACF,MAAM,6BAA6B,QAAQ,SAAS;GAClD;GACA,gBAAgB,QAAQ;GACzB,CAAC;EACR,MAAM,aAAa,kBAAkB,QAAQ,YAAY,SAAS,IAAI;EACtE,MAAM,YAAsC;GAC1C;GACA;GACA,OAAO,QAAQ;GACf,kBAAkB,QAAQ;GAC1B,WAAW,QAAQ;GACnB,eAAe,QAAQ;GACvB,SAAS,QAAQ;GACjB,eAAe,QAAQ,iBAAiB;GACxC,WAAW,QAAQ;GACpB;EACD,MAAM,QAAQ,MAAM,QAAQ,QAAQ,MAAM,UAAU;EACpD,MAAM,WAAwC;GAC5C,IAAI;GACJ;GACA;GACA;GACA,SAAS;IACP,cAAc,aAAa;IAC3B,GAAG,MAAM;IACV;GACD,iBAAiB,MAAM;GACvB,mBAAmB,MAAM;GACzB,GAAI,QAAQ,qBAAqB,EAAE,OAAO,GAAG;GAC9C;AAED,SAAO,SAAS,KAAK,SAAS;;;AAIlC,SAAS,aAAa,SAAkB,YAAgC;AACtE,KAAI,CAAC,WAAY,QAAO;AACxB,QAAO,QAAQ,QAAQ,IAAI,gBAAgB,KAAK,UAAU;;AAG5D,SAAS,kBACP,YACA,SACA,KACA;AACA,KAAI,OAAO,eAAe,SAAU,QAAO;AAC3C,KAAI,OAAO,eAAe,WACxB,QAAO,WAAW;EAAE;EAAS;EAAK,CAAC,IAAI,kBAAkB,SAAS,IAAI;AAExE,QAAO,kBAAkB,SAAS,IAAI;;AAGxC,SAAS,kBAAkB,SAAkB,KAAa;AACxD,QAAO,UAAU,QAAQ,QAAQ,IAAI,cAAc,IAAI"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/workflow-vercel",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "Vercel host adapter for TanStack Workflow runtimes.",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,5 +52,8 @@
|
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
54
|
"@tanstack/workflow-runtime": "workspace:*"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@tanstack/workflow-core": "workspace:*"
|
|
55
58
|
}
|
|
56
59
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
export {
|
|
2
|
-
createVercelWorkflowCronConfig,
|
|
3
2
|
createVercelWorkflowSweepHandler,
|
|
4
3
|
materializeWorkflowSchedules,
|
|
5
|
-
vercelWorkflowCronConfig,
|
|
6
4
|
} from './sweep-handler'
|
|
7
5
|
export type {
|
|
8
6
|
MaterializedWorkflowSchedule,
|
|
9
7
|
MaterializeWorkflowSchedulesOptions,
|
|
10
|
-
VercelWorkflowCron,
|
|
11
|
-
VercelWorkflowCronConfig,
|
|
12
|
-
VercelWorkflowCronConfigOptions,
|
|
13
8
|
VercelWorkflowSweepHandler,
|
|
14
9
|
VercelWorkflowSweepHandlerOptions,
|
|
15
10
|
VercelWorkflowSweepResponse,
|
|
11
|
+
VercelWorkflowSweepSummary,
|
|
16
12
|
VercelWorkflowUnauthorizedResponse,
|
|
17
13
|
} from './sweep-handler'
|
package/src/sweep-handler.ts
CHANGED
|
@@ -7,31 +7,12 @@ import type {
|
|
|
7
7
|
WorkflowRuntimeSweepResult,
|
|
8
8
|
} from '@tanstack/workflow-runtime'
|
|
9
9
|
|
|
10
|
-
const DEFAULT_SWEEP_INTERVAL_MINUTES = 5
|
|
11
|
-
const DEFAULT_SWEEP_PATH = '/api/workflow/sweep'
|
|
12
|
-
|
|
13
10
|
export { materializeWorkflowSchedules }
|
|
14
11
|
export type {
|
|
15
12
|
MaterializedWorkflowSchedule,
|
|
16
13
|
MaterializeWorkflowSchedulesOptions,
|
|
17
14
|
} from '@tanstack/workflow-runtime'
|
|
18
15
|
|
|
19
|
-
export interface VercelWorkflowCron {
|
|
20
|
-
path: string
|
|
21
|
-
schedule: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export interface VercelWorkflowCronConfig {
|
|
25
|
-
$schema: 'https://openapi.vercel.sh/vercel.json'
|
|
26
|
-
crons: ReadonlyArray<VercelWorkflowCron>
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export interface VercelWorkflowCronConfigOptions {
|
|
30
|
-
path?: string
|
|
31
|
-
schedule?: string
|
|
32
|
-
everyMinutes?: number
|
|
33
|
-
}
|
|
34
|
-
|
|
35
16
|
export interface VercelWorkflowSweepResponse {
|
|
36
17
|
ok: true
|
|
37
18
|
now: number
|
|
@@ -76,41 +57,6 @@ export interface VercelWorkflowSweepHandlerOptions<
|
|
|
76
57
|
cronSecret?: string
|
|
77
58
|
}
|
|
78
59
|
|
|
79
|
-
export const vercelWorkflowCronConfig = createVercelWorkflowCronConfig()
|
|
80
|
-
|
|
81
|
-
export function createVercelWorkflowCronConfig(
|
|
82
|
-
options: VercelWorkflowCronConfigOptions = {},
|
|
83
|
-
): VercelWorkflowCronConfig {
|
|
84
|
-
const path = options.path ?? DEFAULT_SWEEP_PATH
|
|
85
|
-
if (!path.startsWith('/')) {
|
|
86
|
-
throw new Error('Vercel workflow cron path must start with "/".')
|
|
87
|
-
}
|
|
88
|
-
if (options.schedule) {
|
|
89
|
-
return {
|
|
90
|
-
$schema: 'https://openapi.vercel.sh/vercel.json',
|
|
91
|
-
crons: [{ path, schedule: options.schedule }],
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const everyMinutes = options.everyMinutes ?? DEFAULT_SWEEP_INTERVAL_MINUTES
|
|
96
|
-
if (!Number.isInteger(everyMinutes) || everyMinutes <= 0) {
|
|
97
|
-
throw new Error(
|
|
98
|
-
'Vercel workflow sweep interval must be a positive integer.',
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return {
|
|
103
|
-
$schema: 'https://openapi.vercel.sh/vercel.json',
|
|
104
|
-
crons: [
|
|
105
|
-
{
|
|
106
|
-
path,
|
|
107
|
-
schedule:
|
|
108
|
-
everyMinutes === 1 ? '* * * * *' : `*/${everyMinutes} * * * *`,
|
|
109
|
-
},
|
|
110
|
-
],
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
60
|
export function createVercelWorkflowSweepHandler<
|
|
115
61
|
TWorkflows extends WorkflowRegistrationMap,
|
|
116
62
|
>(
|