@stepflowjs/trigger-cron 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.
- package/dist/index.d.ts +82 -0
- package/dist/index.js +193 -0
- package/dist/index.js.map +1 -0
- package/package.json +58 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Trigger, TriggerHandler } from '@stepflowjs/core';
|
|
2
|
+
import { StorageAdapter } from '@stepflowjs/core/storage';
|
|
3
|
+
|
|
4
|
+
interface CronTriggerConfig {
|
|
5
|
+
/** Cron expression (e.g., '0 * * * *' for hourly) */
|
|
6
|
+
expression: string;
|
|
7
|
+
/** IANA timezone (default: 'UTC') */
|
|
8
|
+
timezone?: string;
|
|
9
|
+
/** Run missed executions on startup (default: false) */
|
|
10
|
+
catchUp?: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Cron schedule trigger for Stepflow workflows with leader election
|
|
14
|
+
*
|
|
15
|
+
* Triggers workflows on a cron schedule using distributed leader election
|
|
16
|
+
* to ensure only one instance runs the schedule in a multi-instance deployment.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const trigger = new CronTrigger(
|
|
21
|
+
* {
|
|
22
|
+
* expression: '0 * * * *', // Every hour
|
|
23
|
+
* timezone: 'America/New_York',
|
|
24
|
+
* catchUp: false,
|
|
25
|
+
* },
|
|
26
|
+
* storage,
|
|
27
|
+
* 'daily-report'
|
|
28
|
+
* );
|
|
29
|
+
*
|
|
30
|
+
* await trigger.start(async (event) => {
|
|
31
|
+
* await stepflow.trigger('daily-report', event.data);
|
|
32
|
+
* });
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
declare class CronTrigger implements Trigger<CronTriggerConfig> {
|
|
36
|
+
readonly config: CronTriggerConfig;
|
|
37
|
+
private storage;
|
|
38
|
+
private workflowId;
|
|
39
|
+
readonly type = "cron";
|
|
40
|
+
private handler?;
|
|
41
|
+
private interval?;
|
|
42
|
+
private isLeader;
|
|
43
|
+
private lockId;
|
|
44
|
+
private lastExecutionTime?;
|
|
45
|
+
private renewInterval?;
|
|
46
|
+
constructor(config: CronTriggerConfig, storage: StorageAdapter, workflowId: string);
|
|
47
|
+
/**
|
|
48
|
+
* Start the trigger with a handler function
|
|
49
|
+
* @param handler Function to call when cron schedule fires
|
|
50
|
+
*/
|
|
51
|
+
start(handler: TriggerHandler): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Stop the trigger and release leadership
|
|
54
|
+
*/
|
|
55
|
+
stop(): Promise<void>;
|
|
56
|
+
/**
|
|
57
|
+
* Health check - returns true if handler is registered
|
|
58
|
+
*/
|
|
59
|
+
healthCheck(): Promise<boolean>;
|
|
60
|
+
/**
|
|
61
|
+
* Leader election loop
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
private leaderLoop;
|
|
65
|
+
/**
|
|
66
|
+
* Check if cron schedule should execute and run if needed
|
|
67
|
+
* @private
|
|
68
|
+
*/
|
|
69
|
+
private checkAndExecute;
|
|
70
|
+
/**
|
|
71
|
+
* Run catch-up executions for missed schedules
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
private runCatchUp;
|
|
75
|
+
/**
|
|
76
|
+
* Execute the trigger handler
|
|
77
|
+
* @private
|
|
78
|
+
*/
|
|
79
|
+
private execute;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export { CronTrigger, type CronTriggerConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { CronExpressionParser } from "cron-parser";
|
|
3
|
+
var CronTrigger = class {
|
|
4
|
+
constructor(config, storage, workflowId) {
|
|
5
|
+
this.config = config;
|
|
6
|
+
this.storage = storage;
|
|
7
|
+
this.workflowId = workflowId;
|
|
8
|
+
this.lockId = `cron:${workflowId}`;
|
|
9
|
+
try {
|
|
10
|
+
CronExpressionParser.parse(config.expression, {
|
|
11
|
+
tz: config.timezone || "UTC"
|
|
12
|
+
});
|
|
13
|
+
} catch (error) {
|
|
14
|
+
throw new Error(
|
|
15
|
+
`Invalid cron expression "${config.expression}": ${error.message}`
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
type = "cron";
|
|
20
|
+
handler;
|
|
21
|
+
interval;
|
|
22
|
+
isLeader = false;
|
|
23
|
+
lockId;
|
|
24
|
+
lastExecutionTime;
|
|
25
|
+
renewInterval;
|
|
26
|
+
/**
|
|
27
|
+
* Start the trigger with a handler function
|
|
28
|
+
* @param handler Function to call when cron schedule fires
|
|
29
|
+
*/
|
|
30
|
+
async start(handler) {
|
|
31
|
+
this.handler = handler;
|
|
32
|
+
this.interval = setInterval(() => this.leaderLoop(), 1e4);
|
|
33
|
+
await this.leaderLoop();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Stop the trigger and release leadership
|
|
37
|
+
*/
|
|
38
|
+
async stop() {
|
|
39
|
+
if (this.interval) {
|
|
40
|
+
clearInterval(this.interval);
|
|
41
|
+
this.interval = void 0;
|
|
42
|
+
}
|
|
43
|
+
if (this.renewInterval) {
|
|
44
|
+
clearInterval(this.renewInterval);
|
|
45
|
+
this.renewInterval = void 0;
|
|
46
|
+
}
|
|
47
|
+
if (this.isLeader) {
|
|
48
|
+
try {
|
|
49
|
+
await this.storage.leader.release(this.lockId);
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error("Failed to release leader lock:", error);
|
|
52
|
+
}
|
|
53
|
+
this.isLeader = false;
|
|
54
|
+
}
|
|
55
|
+
this.handler = void 0;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Health check - returns true if handler is registered
|
|
59
|
+
*/
|
|
60
|
+
async healthCheck() {
|
|
61
|
+
return this.handler !== void 0;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Leader election loop
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
async leaderLoop() {
|
|
68
|
+
try {
|
|
69
|
+
if (this.isLeader) {
|
|
70
|
+
const renewed = await this.storage.leader.renew(this.lockId, 60);
|
|
71
|
+
if (!renewed) {
|
|
72
|
+
this.isLeader = false;
|
|
73
|
+
if (this.renewInterval) {
|
|
74
|
+
clearInterval(this.renewInterval);
|
|
75
|
+
this.renewInterval = void 0;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
const acquired = await this.storage.leader.acquire(this.lockId, 60);
|
|
80
|
+
if (acquired) {
|
|
81
|
+
this.isLeader = true;
|
|
82
|
+
this.renewInterval = setInterval(async () => {
|
|
83
|
+
const renewed = await this.storage.leader.renew(this.lockId, 60);
|
|
84
|
+
if (!renewed) {
|
|
85
|
+
this.isLeader = false;
|
|
86
|
+
if (this.renewInterval) {
|
|
87
|
+
clearInterval(this.renewInterval);
|
|
88
|
+
this.renewInterval = void 0;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}, 1e4);
|
|
92
|
+
if (this.config.catchUp) {
|
|
93
|
+
await this.runCatchUp();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (this.isLeader) {
|
|
98
|
+
await this.checkAndExecute();
|
|
99
|
+
}
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error("Leader loop error:", error);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Check if cron schedule should execute and run if needed
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
async checkAndExecute() {
|
|
109
|
+
if (!this.handler) {
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const now = /* @__PURE__ */ new Date();
|
|
114
|
+
const interval = CronExpressionParser.parse(this.config.expression, {
|
|
115
|
+
currentDate: now,
|
|
116
|
+
tz: this.config.timezone || "UTC"
|
|
117
|
+
});
|
|
118
|
+
const prevScheduledTime = interval.prev().toDate();
|
|
119
|
+
if (!this.lastExecutionTime || prevScheduledTime > this.lastExecutionTime) {
|
|
120
|
+
const timeSinceScheduled = now.getTime() - prevScheduledTime.getTime();
|
|
121
|
+
if (timeSinceScheduled >= 0 && timeSinceScheduled < 1e4) {
|
|
122
|
+
await this.execute(prevScheduledTime);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (error) {
|
|
126
|
+
console.error("Check and execute error:", error);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Run catch-up executions for missed schedules
|
|
131
|
+
* @private
|
|
132
|
+
*/
|
|
133
|
+
async runCatchUp() {
|
|
134
|
+
if (!this.handler || !this.lastExecutionTime) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
try {
|
|
138
|
+
const now = /* @__PURE__ */ new Date();
|
|
139
|
+
const interval = CronExpressionParser.parse(this.config.expression, {
|
|
140
|
+
currentDate: now,
|
|
141
|
+
tz: this.config.timezone || "UTC"
|
|
142
|
+
});
|
|
143
|
+
const missedExecutions = [];
|
|
144
|
+
let checkTime = interval.prev().toDate();
|
|
145
|
+
while (checkTime > this.lastExecutionTime) {
|
|
146
|
+
missedExecutions.push(checkTime);
|
|
147
|
+
interval.reset();
|
|
148
|
+
checkTime = interval.prev().toDate();
|
|
149
|
+
}
|
|
150
|
+
for (const scheduledTime of missedExecutions.reverse()) {
|
|
151
|
+
await this.execute(scheduledTime);
|
|
152
|
+
}
|
|
153
|
+
} catch (error) {
|
|
154
|
+
console.error("Catch-up error:", error);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Execute the trigger handler
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
async execute(scheduledTime) {
|
|
162
|
+
if (!this.handler) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
try {
|
|
166
|
+
const eventId = crypto.randomUUID();
|
|
167
|
+
const event = {
|
|
168
|
+
id: eventId,
|
|
169
|
+
type: this.type,
|
|
170
|
+
source: `cron:${this.config.expression}`,
|
|
171
|
+
data: {
|
|
172
|
+
scheduledTime: scheduledTime.toISOString(),
|
|
173
|
+
timezone: this.config.timezone || "UTC"
|
|
174
|
+
},
|
|
175
|
+
metadata: {
|
|
176
|
+
workflowId: this.workflowId,
|
|
177
|
+
expression: this.config.expression,
|
|
178
|
+
timezone: this.config.timezone || "UTC"
|
|
179
|
+
},
|
|
180
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
181
|
+
};
|
|
182
|
+
await this.handler(event);
|
|
183
|
+
this.lastExecutionTime = scheduledTime;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error("Execution error:", error);
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
export {
|
|
191
|
+
CronTrigger
|
|
192
|
+
};
|
|
193
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Trigger, TriggerHandler, TriggerEvent } from \"@stepflowjs/core\";\nimport type { StorageAdapter } from \"@stepflowjs/core/storage\";\nimport { CronExpressionParser } from \"cron-parser\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CronTriggerConfig {\n /** Cron expression (e.g., '0 * * * *' for hourly) */\n expression: string;\n /** IANA timezone (default: 'UTC') */\n timezone?: string;\n /** Run missed executions on startup (default: false) */\n catchUp?: boolean;\n}\n\n// ============================================================================\n// CronTrigger Implementation\n// ============================================================================\n\n/**\n * Cron schedule trigger for Stepflow workflows with leader election\n *\n * Triggers workflows on a cron schedule using distributed leader election\n * to ensure only one instance runs the schedule in a multi-instance deployment.\n *\n * @example\n * ```typescript\n * const trigger = new CronTrigger(\n * {\n * expression: '0 * * * *', // Every hour\n * timezone: 'America/New_York',\n * catchUp: false,\n * },\n * storage,\n * 'daily-report'\n * );\n *\n * await trigger.start(async (event) => {\n * await stepflow.trigger('daily-report', event.data);\n * });\n * ```\n */\nexport class CronTrigger implements Trigger<CronTriggerConfig> {\n readonly type = \"cron\";\n private handler?: TriggerHandler;\n private interval?: NodeJS.Timeout;\n private isLeader = false;\n private lockId: string;\n private lastExecutionTime?: Date;\n private renewInterval?: NodeJS.Timeout;\n\n constructor(\n readonly config: CronTriggerConfig,\n private storage: StorageAdapter,\n private workflowId: string,\n ) {\n this.lockId = `cron:${workflowId}`;\n // Validate cron expression on construction\n try {\n CronExpressionParser.parse(config.expression, {\n tz: config.timezone || \"UTC\",\n });\n } catch (error) {\n throw new Error(\n `Invalid cron expression \"${config.expression}\": ${(error as Error).message}`,\n );\n }\n }\n\n /**\n * Start the trigger with a handler function\n * @param handler Function to call when cron schedule fires\n */\n async start(handler: TriggerHandler): Promise<void> {\n this.handler = handler;\n\n // Start leader election loop (check every 10 seconds)\n this.interval = setInterval(() => this.leaderLoop(), 10000);\n\n // Run immediately on start\n await this.leaderLoop();\n }\n\n /**\n * Stop the trigger and release leadership\n */\n async stop(): Promise<void> {\n // Clear intervals\n if (this.interval) {\n clearInterval(this.interval);\n this.interval = undefined;\n }\n if (this.renewInterval) {\n clearInterval(this.renewInterval);\n this.renewInterval = undefined;\n }\n\n // Release leadership lock\n if (this.isLeader) {\n try {\n await this.storage.leader.release(this.lockId);\n } catch (error) {\n console.error(\"Failed to release leader lock:\", error);\n }\n this.isLeader = false;\n }\n\n this.handler = undefined;\n }\n\n /**\n * Health check - returns true if handler is registered\n */\n async healthCheck(): Promise<boolean> {\n return this.handler !== undefined;\n }\n\n /**\n * Leader election loop\n * @private\n */\n private async leaderLoop(): Promise<void> {\n try {\n if (this.isLeader) {\n // Try to renew existing lock\n const renewed = await this.storage.leader.renew(this.lockId, 60);\n if (!renewed) {\n // Lost leadership\n this.isLeader = false;\n if (this.renewInterval) {\n clearInterval(this.renewInterval);\n this.renewInterval = undefined;\n }\n }\n } else {\n // Try to acquire leadership\n const acquired = await this.storage.leader.acquire(this.lockId, 60);\n if (acquired) {\n this.isLeader = true;\n // Set up lock renewal every 10 seconds\n this.renewInterval = setInterval(async () => {\n const renewed = await this.storage.leader.renew(this.lockId, 60);\n if (!renewed) {\n this.isLeader = false;\n if (this.renewInterval) {\n clearInterval(this.renewInterval);\n this.renewInterval = undefined;\n }\n }\n }, 10000);\n\n // Check for catch-up runs on first leadership acquisition\n if (this.config.catchUp) {\n await this.runCatchUp();\n }\n }\n }\n\n // If we're the leader, check if we should execute\n if (this.isLeader) {\n await this.checkAndExecute();\n }\n } catch (error) {\n console.error(\"Leader loop error:\", error);\n }\n }\n\n /**\n * Check if cron schedule should execute and run if needed\n * @private\n */\n private async checkAndExecute(): Promise<void> {\n if (!this.handler) {\n return;\n }\n\n try {\n const now = new Date();\n const interval = CronExpressionParser.parse(this.config.expression, {\n currentDate: now,\n tz: this.config.timezone || \"UTC\",\n });\n\n // Get the previous scheduled time\n const prevScheduledTime = interval.prev().toDate();\n\n // If we haven't executed yet, or if the previous scheduled time is after our last execution\n if (\n !this.lastExecutionTime ||\n prevScheduledTime > this.lastExecutionTime\n ) {\n // Check if we're within the execution window (within 10 seconds of scheduled time)\n const timeSinceScheduled = now.getTime() - prevScheduledTime.getTime();\n if (timeSinceScheduled >= 0 && timeSinceScheduled < 10000) {\n await this.execute(prevScheduledTime);\n }\n }\n } catch (error) {\n console.error(\"Check and execute error:\", error);\n }\n }\n\n /**\n * Run catch-up executions for missed schedules\n * @private\n */\n private async runCatchUp(): Promise<void> {\n if (!this.handler || !this.lastExecutionTime) {\n return;\n }\n\n try {\n const now = new Date();\n const interval = CronExpressionParser.parse(this.config.expression, {\n currentDate: now,\n tz: this.config.timezone || \"UTC\",\n });\n\n // Find all missed executions between last execution and now\n const missedExecutions: Date[] = [];\n let checkTime = interval.prev().toDate();\n\n while (checkTime > this.lastExecutionTime) {\n missedExecutions.push(checkTime);\n interval.reset();\n checkTime = interval.prev().toDate();\n }\n\n // Execute missed runs in chronological order\n for (const scheduledTime of missedExecutions.reverse()) {\n await this.execute(scheduledTime);\n }\n } catch (error) {\n console.error(\"Catch-up error:\", error);\n }\n }\n\n /**\n * Execute the trigger handler\n * @private\n */\n private async execute(scheduledTime: Date): Promise<void> {\n if (!this.handler) {\n return;\n }\n\n try {\n const eventId = crypto.randomUUID();\n const event: TriggerEvent = {\n id: eventId,\n type: this.type,\n source: `cron:${this.config.expression}`,\n data: {\n scheduledTime: scheduledTime.toISOString(),\n timezone: this.config.timezone || \"UTC\",\n },\n metadata: {\n workflowId: this.workflowId,\n expression: this.config.expression,\n timezone: this.config.timezone || \"UTC\",\n },\n timestamp: new Date(),\n };\n\n await this.handler(event);\n this.lastExecutionTime = scheduledTime;\n } catch (error) {\n console.error(\"Execution error:\", error);\n throw error;\n }\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@stepflowjs/trigger-cron",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Cron schedule trigger for Stepflow with leader election",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"cron-parser": "^5.5.0",
|
|
20
|
+
"@stepflowjs/core": "0.0.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"tsup": "^8.5.1",
|
|
24
|
+
"vitest": "^4.0.17"
|
|
25
|
+
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"typescript": "^5.0.0"
|
|
28
|
+
},
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"author": "Stepflow Contributors",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://stepflow-production.up.railway.app",
|
|
34
|
+
"directory": "packages/triggers/cron"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://stepflow-production.up.railway.app",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://stepflow-production.up.railway.app"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"stepflow",
|
|
42
|
+
"trigger",
|
|
43
|
+
"cron",
|
|
44
|
+
"schedule",
|
|
45
|
+
"workflow",
|
|
46
|
+
"orchestration"
|
|
47
|
+
],
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsup",
|
|
53
|
+
"dev": "tsup --watch",
|
|
54
|
+
"typecheck": "tsc --noEmit",
|
|
55
|
+
"test": "vitest",
|
|
56
|
+
"clean": "rm -rf dist"
|
|
57
|
+
}
|
|
58
|
+
}
|