@kylebegeman/pulse 0.3.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/README.md +1078 -0
- package/dist/cron.d.ts +16 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +32 -0
- package/dist/cron.js.map +1 -0
- package/dist/executor.d.ts +43 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +333 -0
- package/dist/executor.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +198 -0
- package/dist/index.js.map +1 -0
- package/dist/logs.d.ts +11 -0
- package/dist/logs.d.ts.map +1 -0
- package/dist/logs.js +25 -0
- package/dist/logs.js.map +1 -0
- package/dist/matcher.d.ts +23 -0
- package/dist/matcher.d.ts.map +1 -0
- package/dist/matcher.js +184 -0
- package/dist/matcher.js.map +1 -0
- package/dist/queue.d.ts +42 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +85 -0
- package/dist/queue.js.map +1 -0
- package/dist/registry.d.ts +23 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +33 -0
- package/dist/registry.js.map +1 -0
- package/dist/replay.d.ts +10 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +24 -0
- package/dist/replay.js.map +1 -0
- package/dist/runs.d.ts +37 -0
- package/dist/runs.d.ts.map +1 -0
- package/dist/runs.js +296 -0
- package/dist/runs.js.map +1 -0
- package/dist/scheduler.d.ts +21 -0
- package/dist/scheduler.d.ts.map +1 -0
- package/dist/scheduler.js +67 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/schema/migrate.d.ts +3 -0
- package/dist/schema/migrate.d.ts.map +1 -0
- package/dist/schema/migrate.js +56 -0
- package/dist/schema/migrate.js.map +1 -0
- package/dist/schema/tables.d.ts +10 -0
- package/dist/schema/tables.d.ts.map +1 -0
- package/dist/schema/tables.js +123 -0
- package/dist/schema/tables.js.map +1 -0
- package/dist/types.d.ts +186 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/errors.d.ts +30 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +61 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/ids.d.ts +2 -0
- package/dist/utils/ids.d.ts.map +1 -0
- package/dist/utils/ids.js +6 -0
- package/dist/utils/ids.js.map +1 -0
- package/package.json +45 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { getTableNames } from './schema/tables.js';
|
|
2
|
+
import { runMigrations } from './schema/migrate.js';
|
|
3
|
+
import { Registry } from './registry.js';
|
|
4
|
+
import { Matcher } from './matcher.js';
|
|
5
|
+
import { RunManager } from './runs.js';
|
|
6
|
+
import { Scheduler } from './scheduler.js';
|
|
7
|
+
import { Executor } from './executor.js';
|
|
8
|
+
import { QueueManager } from './queue.js';
|
|
9
|
+
import { LogStore } from './logs.js';
|
|
10
|
+
import { ReplayManager } from './replay.js';
|
|
11
|
+
import { CronManager } from './cron.js';
|
|
12
|
+
import { CircularTriggerError } from './utils/errors.js';
|
|
13
|
+
const MAX_EMIT_DEPTH = 10;
|
|
14
|
+
export function createEngine(config) {
|
|
15
|
+
const tablePrefix = config.tablePrefix ?? 'pulse_';
|
|
16
|
+
const queuePrefix = config.queuePrefix ?? 'pulse';
|
|
17
|
+
const concurrency = config.concurrency ?? 5;
|
|
18
|
+
const tables = getTableNames(tablePrefix);
|
|
19
|
+
const registry = new Registry();
|
|
20
|
+
const runManager = new RunManager(config.db, tables);
|
|
21
|
+
const logStore = new LogStore(config.db, tables);
|
|
22
|
+
const scheduler = new Scheduler(runManager);
|
|
23
|
+
const queueManager = new QueueManager({
|
|
24
|
+
redis: config.redis,
|
|
25
|
+
prefix: queuePrefix,
|
|
26
|
+
concurrency,
|
|
27
|
+
});
|
|
28
|
+
// Forward declaration — resolved after matcher is created
|
|
29
|
+
let matcher;
|
|
30
|
+
let executor;
|
|
31
|
+
let replayManager;
|
|
32
|
+
let cronManager;
|
|
33
|
+
const emitFn = async (input, emitDepth = 0) => {
|
|
34
|
+
if (emitDepth >= MAX_EMIT_DEPTH) {
|
|
35
|
+
throw new CircularTriggerError(input.type, emitDepth);
|
|
36
|
+
}
|
|
37
|
+
const envelope = await matcher.persistTrigger(input);
|
|
38
|
+
await queueManager.enqueueMatch(envelope.id, false, emitDepth);
|
|
39
|
+
return envelope;
|
|
40
|
+
};
|
|
41
|
+
matcher = new Matcher(config.db, tables, registry, runManager);
|
|
42
|
+
cronManager = new CronManager(queueManager, (input) => emitFn(input, 0));
|
|
43
|
+
executor = new Executor(registry, runManager, scheduler, logStore, matcher, emitFn, queueManager, {
|
|
44
|
+
onStepComplete: config.onStepComplete,
|
|
45
|
+
onRunComplete: config.onRunComplete,
|
|
46
|
+
});
|
|
47
|
+
// Shared helper: schedule first step and enqueue it for a new run
|
|
48
|
+
async function startRun(run, emitDepth) {
|
|
49
|
+
const snapshot = run.definitionSnapshot;
|
|
50
|
+
if (!snapshot?.steps?.length)
|
|
51
|
+
return;
|
|
52
|
+
await scheduler.scheduleFirstStep(run, snapshot);
|
|
53
|
+
const steps = await runManager.getStepRuns(run.id);
|
|
54
|
+
if (steps.length > 0) {
|
|
55
|
+
const firstStep = steps[0];
|
|
56
|
+
const step = snapshot.steps[0];
|
|
57
|
+
const delay = step.type === 'delay' && step.delayMs ? step.delayMs : undefined;
|
|
58
|
+
await queueManager.enqueueStep(firstStep.id, run.id, delay, emitDepth, step.retryPolicy);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
replayManager = new ReplayManager(matcher, startRun);
|
|
62
|
+
// --- Match worker handler ---
|
|
63
|
+
async function handleMatch(job) {
|
|
64
|
+
const { triggerId, isReplay, emitDepth = 0 } = job.data;
|
|
65
|
+
if (emitDepth >= MAX_EMIT_DEPTH) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const trigger = await matcher.getTrigger(triggerId);
|
|
69
|
+
if (!trigger)
|
|
70
|
+
return;
|
|
71
|
+
const runs = await matcher.matchAndCreateRuns(trigger, isReplay);
|
|
72
|
+
for (const run of runs) {
|
|
73
|
+
await startRun(run, emitDepth);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// --- Step worker handler ---
|
|
77
|
+
async function handleStep(job) {
|
|
78
|
+
const { stepRunId, runId, emitDepth = 0 } = job.data;
|
|
79
|
+
const isLastAttempt = (job.attemptsMade + 1) >= (job.opts?.attempts ?? 1);
|
|
80
|
+
// Detect branch step vs top-level step
|
|
81
|
+
const stepRuns = await runManager.getStepRuns(runId);
|
|
82
|
+
const stepRun = stepRuns.find((s) => s.id === stepRunId);
|
|
83
|
+
if (stepRun?.parentStepRunId) {
|
|
84
|
+
// This is a branch step inside a parallel step
|
|
85
|
+
await executor.executeBranchStep(stepRunId, runId, emitDepth, isLastAttempt);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
await executor.executeStep(stepRunId, runId, emitDepth, isLastAttempt);
|
|
89
|
+
// Check if there's a next step to enqueue
|
|
90
|
+
const run = await runManager.getRun(runId);
|
|
91
|
+
if (!run || run.status === 'completed' || run.status === 'failed' || run.status === 'canceled') {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const allSteps = await runManager.getStepRuns(runId);
|
|
95
|
+
const nextStep = allSteps.find((s) => (s.status === 'scheduled' || s.status === 'pending') && !s.parentStepRunId);
|
|
96
|
+
if (nextStep) {
|
|
97
|
+
const snapshot = run.definitionSnapshot;
|
|
98
|
+
const step = snapshot?.steps?.[nextStep.stepIndex];
|
|
99
|
+
const delay = step?.type === 'delay' && step.delayMs ? step.delayMs : undefined;
|
|
100
|
+
await queueManager.enqueueStep(nextStep.id, runId, delay, emitDepth, step?.retryPolicy);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// --- Cron worker handler ---
|
|
104
|
+
async function handleCron(job) {
|
|
105
|
+
await cronManager.handleCronFire(job.data);
|
|
106
|
+
}
|
|
107
|
+
// --- Public API ---
|
|
108
|
+
const engine = {
|
|
109
|
+
registerTrigger(type, registration) {
|
|
110
|
+
registry.registerTrigger(type, registration);
|
|
111
|
+
},
|
|
112
|
+
registerAction(name, handler, options) {
|
|
113
|
+
registry.registerAction(name, handler, options);
|
|
114
|
+
},
|
|
115
|
+
registerCondition(name, handler) {
|
|
116
|
+
registry.registerCondition(name, handler);
|
|
117
|
+
},
|
|
118
|
+
async emit(input) {
|
|
119
|
+
return emitFn(input, 0);
|
|
120
|
+
},
|
|
121
|
+
async start() {
|
|
122
|
+
queueManager.startWorkers(handleMatch, handleStep, handleCron);
|
|
123
|
+
// Restore cron jobs for enabled definitions
|
|
124
|
+
const cronDefs = await matcher.getEnabledCronDefinitions();
|
|
125
|
+
await cronManager.restoreAll(cronDefs);
|
|
126
|
+
},
|
|
127
|
+
async stop() {
|
|
128
|
+
await queueManager.stop();
|
|
129
|
+
},
|
|
130
|
+
async getRun(runId) {
|
|
131
|
+
return runManager.getRun(runId);
|
|
132
|
+
},
|
|
133
|
+
async getRunSteps(runId) {
|
|
134
|
+
return runManager.getStepRuns(runId);
|
|
135
|
+
},
|
|
136
|
+
async getRunsByTrigger(triggerId) {
|
|
137
|
+
return runManager.getRunsByTrigger(triggerId);
|
|
138
|
+
},
|
|
139
|
+
async getTrigger(triggerId) {
|
|
140
|
+
return matcher.getTrigger(triggerId);
|
|
141
|
+
},
|
|
142
|
+
async getRunTimeline(runId) {
|
|
143
|
+
return runManager.getRunTimeline(runId);
|
|
144
|
+
},
|
|
145
|
+
async cancelRun(runId, reason) {
|
|
146
|
+
const run = await runManager.cancelRun(runId, reason);
|
|
147
|
+
await queueManager.removeStepJobs(runId);
|
|
148
|
+
return run;
|
|
149
|
+
},
|
|
150
|
+
async retryRun(runId) {
|
|
151
|
+
const run = await runManager.getRun(runId);
|
|
152
|
+
if (!run)
|
|
153
|
+
throw new Error(`Run ${runId} not found`);
|
|
154
|
+
if (run.status !== 'failed') {
|
|
155
|
+
throw new Error(`Cannot retry run ${runId} with status "${run.status}"`);
|
|
156
|
+
}
|
|
157
|
+
const resetStep = await runManager.resetFailedStep(runId);
|
|
158
|
+
if (!resetStep)
|
|
159
|
+
throw new Error(`No failed step found for run ${runId}`);
|
|
160
|
+
// Re-enqueue the reset step
|
|
161
|
+
const snapshot = run.definitionSnapshot;
|
|
162
|
+
const step = snapshot?.steps?.[resetStep.stepIndex];
|
|
163
|
+
await queueManager.enqueueStep(resetStep.id, runId, undefined, 0, step?.retryPolicy);
|
|
164
|
+
return (await runManager.getRun(runId));
|
|
165
|
+
},
|
|
166
|
+
async getFailedRuns(tenantId) {
|
|
167
|
+
return runManager.getFailedRuns(tenantId);
|
|
168
|
+
},
|
|
169
|
+
async replay(triggerId, options) {
|
|
170
|
+
return replayManager.replay(triggerId, options?.dryRun);
|
|
171
|
+
},
|
|
172
|
+
async createWorkflow(definition) {
|
|
173
|
+
const created = await matcher.createWorkflow(definition);
|
|
174
|
+
// Schedule cron if applicable
|
|
175
|
+
if (created.cronExpression && created.isEnabled) {
|
|
176
|
+
await cronManager.scheduleCron(created);
|
|
177
|
+
}
|
|
178
|
+
return created;
|
|
179
|
+
},
|
|
180
|
+
async enableWorkflow(definitionId) {
|
|
181
|
+
await matcher.setWorkflowEnabled(definitionId, true);
|
|
182
|
+
// Start cron if definition has one
|
|
183
|
+
const def = await matcher.getDefinition(definitionId);
|
|
184
|
+
if (def?.cronExpression) {
|
|
185
|
+
await cronManager.scheduleCron(def);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
async disableWorkflow(definitionId) {
|
|
189
|
+
await matcher.setWorkflowEnabled(definitionId, false);
|
|
190
|
+
await cronManager.removeCron(definitionId);
|
|
191
|
+
},
|
|
192
|
+
async migrate() {
|
|
193
|
+
await runMigrations(config.db, tablePrefix);
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
return engine;
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/logs.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
import type { ExecutionLog } from './types.js';
|
|
3
|
+
import type { TableNames } from './schema/tables.js';
|
|
4
|
+
export declare class LogStore {
|
|
5
|
+
private db;
|
|
6
|
+
private tables;
|
|
7
|
+
constructor(db: Pool, tables: TableNames);
|
|
8
|
+
write(runId: string, tenantId: string, level: ExecutionLog['level'], message: string, data?: Record<string, unknown>, stepRunId?: string): Promise<void>;
|
|
9
|
+
getByRun(runId: string): Promise<ExecutionLog[]>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAC9B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAC9C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAGpD,qBAAa,QAAQ;IAEjB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;gBADN,EAAE,EAAE,IAAI,EACR,MAAM,EAAE,UAAU;IAGtB,KAAK,CACT,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC,EAC5B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC;IAUV,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;CAYvD"}
|
package/dist/logs.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { generateId } from './utils/ids.js';
|
|
2
|
+
export class LogStore {
|
|
3
|
+
db;
|
|
4
|
+
tables;
|
|
5
|
+
constructor(db, tables) {
|
|
6
|
+
this.db = db;
|
|
7
|
+
this.tables = tables;
|
|
8
|
+
}
|
|
9
|
+
async write(runId, tenantId, level, message, data, stepRunId) {
|
|
10
|
+
const id = generateId('log');
|
|
11
|
+
await this.db.query(`INSERT INTO ${this.tables.executionLogs}
|
|
12
|
+
(id, run_id, step_run_id, tenant_id, level, message, data)
|
|
13
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)`, [id, runId, stepRunId ?? null, tenantId, level, message, data ? JSON.stringify(data) : null]);
|
|
14
|
+
}
|
|
15
|
+
async getByRun(runId) {
|
|
16
|
+
const result = await this.db.query(`SELECT id, run_id as "runId", step_run_id as "stepRunId",
|
|
17
|
+
tenant_id as "tenantId", level, message, data,
|
|
18
|
+
created_at as "createdAt"
|
|
19
|
+
FROM ${this.tables.executionLogs}
|
|
20
|
+
WHERE run_id = $1
|
|
21
|
+
ORDER BY created_at ASC`, [runId]);
|
|
22
|
+
return result.rows;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=logs.js.map
|
package/dist/logs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../src/logs.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,MAAM,OAAO,QAAQ;IAET;IACA;IAFV,YACU,EAAQ,EACR,MAAkB;QADlB,OAAE,GAAF,EAAE,CAAM;QACR,WAAM,GAAN,MAAM,CAAY;IACzB,CAAC;IAEJ,KAAK,CAAC,KAAK,CACT,KAAa,EACb,QAAgB,EAChB,KAA4B,EAC5B,OAAe,EACf,IAA8B,EAC9B,SAAkB;QAElB,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QAC5B,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CACjB,eAAe,IAAI,CAAC,MAAM,CAAC,aAAa;;2CAEH,EACrC,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,IAAI,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAC7F,CAAA;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,KAAa;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,KAAK,CAChC;;;cAGQ,IAAI,CAAC,MAAM,CAAC,aAAa;;+BAER,EACzB,CAAC,KAAK,CAAC,CACR,CAAA;QACD,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Pool } from 'pg';
|
|
2
|
+
import type { TriggerEnvelope, TriggerInput, WorkflowDefinition, WorkflowRun } from './types.js';
|
|
3
|
+
import type { TableNames } from './schema/tables.js';
|
|
4
|
+
import type { Registry } from './registry.js';
|
|
5
|
+
import type { RunManager } from './runs.js';
|
|
6
|
+
export declare class Matcher {
|
|
7
|
+
private db;
|
|
8
|
+
private tables;
|
|
9
|
+
private registry;
|
|
10
|
+
private runManager;
|
|
11
|
+
constructor(db: Pool, tables: TableNames, registry: Registry, runManager: RunManager);
|
|
12
|
+
persistTrigger(input: TriggerInput): Promise<TriggerEnvelope>;
|
|
13
|
+
getTrigger(triggerId: string): Promise<TriggerEnvelope | null>;
|
|
14
|
+
matchAndCreateRuns(trigger: TriggerEnvelope, isReplay?: boolean): Promise<WorkflowRun[]>;
|
|
15
|
+
private findMatchingDefinitions;
|
|
16
|
+
createWorkflow(def: Omit<WorkflowDefinition, 'id' | 'createdAt' | 'updatedAt'>): Promise<WorkflowDefinition>;
|
|
17
|
+
private validateStepHandlers;
|
|
18
|
+
getEnabledCronDefinitions(): Promise<WorkflowDefinition[]>;
|
|
19
|
+
setWorkflowEnabled(definitionId: string, enabled: boolean): Promise<void>;
|
|
20
|
+
getDefinition(definitionId: string): Promise<WorkflowDefinition | null>;
|
|
21
|
+
private mapDefinition;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=matcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher.d.ts","sourceRoot":"","sources":["../src/matcher.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAE9B,OAAO,KAAK,EACV,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACZ,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAyC3C,qBAAa,OAAO;IAEhB,OAAO,CAAC,EAAE;IACV,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,UAAU;gBAHV,EAAE,EAAE,IAAI,EACR,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,QAAQ,EAClB,UAAU,EAAE,UAAU;IAG1B,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC;IAyC7D,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAY9D,kBAAkB,CACtB,OAAO,EAAE,eAAe,EACxB,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,WAAW,EAAE,CAAC;YAuBX,uBAAuB;IAqB/B,cAAc,CAClB,GAAG,EAAE,IAAI,CAAC,kBAAkB,EAAE,IAAI,GAAG,WAAW,GAAG,WAAW,CAAC,GAC9D,OAAO,CAAC,kBAAkB,CAAC;IAqC9B,OAAO,CAAC,oBAAoB;IAyBtB,yBAAyB,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAQ1D,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,IAAI,CAAC;IASV,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAQ7E,OAAO,CAAC,aAAa;CAiBtB"}
|
package/dist/matcher.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { MAX_DELAY_MS } from './scheduler.js';
|
|
3
|
+
import { TriggerValidationError, UnregisteredTriggerError, WorkflowValidationError, } from './utils/errors.js';
|
|
4
|
+
import { generateId } from './utils/ids.js';
|
|
5
|
+
const retryPolicySchema = z.object({
|
|
6
|
+
maxAttempts: z.number().int().min(1).max(10),
|
|
7
|
+
backoffMs: z.number().int().min(100).max(300_000),
|
|
8
|
+
});
|
|
9
|
+
const baseStepSchema = z.object({
|
|
10
|
+
type: z.enum(['action', 'condition', 'delay', 'parallel']),
|
|
11
|
+
name: z.string().min(1),
|
|
12
|
+
config: z.record(z.unknown()).optional(),
|
|
13
|
+
delayMs: z.number().int().positive().max(MAX_DELAY_MS).optional(),
|
|
14
|
+
timeoutMs: z.number().int().positive().max(3_600_000).optional(),
|
|
15
|
+
retryPolicy: retryPolicySchema.optional(),
|
|
16
|
+
onFalse: z.union([
|
|
17
|
+
z.literal('complete'),
|
|
18
|
+
z.literal('skip'),
|
|
19
|
+
z.number().int().min(1),
|
|
20
|
+
]).optional(),
|
|
21
|
+
branches: z.array(z.array(z.lazy(() => workflowStepSchema))).optional(),
|
|
22
|
+
});
|
|
23
|
+
const workflowStepSchema = baseStepSchema.refine((step) => step.type !== 'delay' || (step.delayMs !== undefined && step.delayMs > 0), { message: 'Delay steps must specify a positive delayMs' }).refine((step) => step.type !== 'parallel' || (step.branches !== undefined && step.branches.length >= 2), { message: 'Parallel steps must have at least 2 branches' });
|
|
24
|
+
const workflowStepsSchema = z.array(workflowStepSchema).min(1, {
|
|
25
|
+
message: 'Workflow must have at least one step',
|
|
26
|
+
});
|
|
27
|
+
export class Matcher {
|
|
28
|
+
db;
|
|
29
|
+
tables;
|
|
30
|
+
registry;
|
|
31
|
+
runManager;
|
|
32
|
+
constructor(db, tables, registry, runManager) {
|
|
33
|
+
this.db = db;
|
|
34
|
+
this.tables = tables;
|
|
35
|
+
this.registry = registry;
|
|
36
|
+
this.runManager = runManager;
|
|
37
|
+
}
|
|
38
|
+
async persistTrigger(input) {
|
|
39
|
+
const registration = this.registry.getTrigger(input.type);
|
|
40
|
+
if (!registration) {
|
|
41
|
+
throw new UnregisteredTriggerError(input.type);
|
|
42
|
+
}
|
|
43
|
+
if (registration.payloadSchema && input.payload) {
|
|
44
|
+
const result = registration.payloadSchema.safeParse(input.payload);
|
|
45
|
+
if (!result.success) {
|
|
46
|
+
throw new TriggerValidationError(input.type, {
|
|
47
|
+
errors: result.error.issues,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
const id = generateId('trg');
|
|
52
|
+
const envelope = {
|
|
53
|
+
...input,
|
|
54
|
+
id,
|
|
55
|
+
createdAt: new Date(),
|
|
56
|
+
};
|
|
57
|
+
await this.db.query(`INSERT INTO ${this.tables.triggers}
|
|
58
|
+
(id, tenant_id, source, type, resource_type, resource_id, environment, payload)
|
|
59
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)`, [
|
|
60
|
+
envelope.id,
|
|
61
|
+
envelope.tenantId,
|
|
62
|
+
envelope.source,
|
|
63
|
+
envelope.type,
|
|
64
|
+
envelope.resourceType ?? null,
|
|
65
|
+
envelope.resourceId ?? null,
|
|
66
|
+
envelope.environment ?? null,
|
|
67
|
+
envelope.payload ? JSON.stringify(envelope.payload) : '{}',
|
|
68
|
+
]);
|
|
69
|
+
return envelope;
|
|
70
|
+
}
|
|
71
|
+
async getTrigger(triggerId) {
|
|
72
|
+
const result = await this.db.query(`SELECT id, tenant_id as "tenantId", source, type,
|
|
73
|
+
resource_type as "resourceType", resource_id as "resourceId",
|
|
74
|
+
environment, payload, created_at as "createdAt"
|
|
75
|
+
FROM ${this.tables.triggers}
|
|
76
|
+
WHERE id = $1`, [triggerId]);
|
|
77
|
+
return result.rows[0] ?? null;
|
|
78
|
+
}
|
|
79
|
+
async matchAndCreateRuns(trigger, isReplay = false) {
|
|
80
|
+
const definitions = await this.findMatchingDefinitions(trigger);
|
|
81
|
+
const runs = [];
|
|
82
|
+
for (const def of definitions) {
|
|
83
|
+
const snapshot = {
|
|
84
|
+
steps: def.steps,
|
|
85
|
+
config: def.config,
|
|
86
|
+
triggerType: def.triggerType,
|
|
87
|
+
};
|
|
88
|
+
const run = await this.runManager.createRun(def.id, trigger.tenantId, trigger.id, isReplay, snapshot);
|
|
89
|
+
runs.push(run);
|
|
90
|
+
}
|
|
91
|
+
return runs;
|
|
92
|
+
}
|
|
93
|
+
async findMatchingDefinitions(trigger) {
|
|
94
|
+
const result = await this.db.query(`SELECT * FROM ${this.tables.workflowDefinitions}
|
|
95
|
+
WHERE tenant_id = $1
|
|
96
|
+
AND trigger_type = $2
|
|
97
|
+
AND is_enabled = true
|
|
98
|
+
AND (environment_filter IS NULL OR environment_filter = $3)
|
|
99
|
+
AND (resource_type_filter IS NULL OR resource_type_filter = $4)`, [
|
|
100
|
+
trigger.tenantId,
|
|
101
|
+
trigger.type,
|
|
102
|
+
trigger.environment ?? null,
|
|
103
|
+
trigger.resourceType ?? null,
|
|
104
|
+
]);
|
|
105
|
+
return result.rows.map(this.mapDefinition);
|
|
106
|
+
}
|
|
107
|
+
async createWorkflow(def) {
|
|
108
|
+
// Validate step structure
|
|
109
|
+
const stepsResult = workflowStepsSchema.safeParse(def.steps);
|
|
110
|
+
if (!stepsResult.success) {
|
|
111
|
+
throw new WorkflowValidationError(`Invalid workflow steps: ${stepsResult.error.issues.map((i) => i.message).join(', ')}`, { errors: stepsResult.error.issues });
|
|
112
|
+
}
|
|
113
|
+
// Validate step handlers exist (recursive for parallel branches)
|
|
114
|
+
this.validateStepHandlers(def.steps);
|
|
115
|
+
const id = generateId('wf');
|
|
116
|
+
const result = await this.db.query(`INSERT INTO ${this.tables.workflowDefinitions}
|
|
117
|
+
(id, tenant_id, name, description, trigger_type,
|
|
118
|
+
environment_filter, resource_type_filter, steps, config, is_enabled, cron_expression)
|
|
119
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
|
|
120
|
+
RETURNING *`, [
|
|
121
|
+
id,
|
|
122
|
+
def.tenantId,
|
|
123
|
+
def.name,
|
|
124
|
+
def.description ?? null,
|
|
125
|
+
def.triggerType,
|
|
126
|
+
def.environmentFilter ?? null,
|
|
127
|
+
def.resourceTypeFilter ?? null,
|
|
128
|
+
JSON.stringify(def.steps),
|
|
129
|
+
JSON.stringify(def.config),
|
|
130
|
+
def.isEnabled,
|
|
131
|
+
def.cronExpression ?? null,
|
|
132
|
+
]);
|
|
133
|
+
return this.mapDefinition(result.rows[0]);
|
|
134
|
+
}
|
|
135
|
+
validateStepHandlers(steps, parentIndex) {
|
|
136
|
+
for (let i = 0; i < steps.length; i++) {
|
|
137
|
+
const step = steps[i];
|
|
138
|
+
const label = parentIndex !== undefined ? `Step ${parentIndex}.${i}` : `Step ${i}`;
|
|
139
|
+
if (step.type === 'action' && !this.registry.hasAction(step.name)) {
|
|
140
|
+
throw new WorkflowValidationError(`${label} references unregistered action "${step.name}"`, { stepIndex: i, stepName: step.name, stepType: step.type });
|
|
141
|
+
}
|
|
142
|
+
if (step.type === 'condition' && !this.registry.hasCondition(step.name)) {
|
|
143
|
+
throw new WorkflowValidationError(`${label} references unregistered condition "${step.name}"`, { stepIndex: i, stepName: step.name, stepType: step.type });
|
|
144
|
+
}
|
|
145
|
+
if (step.type === 'parallel' && step.branches) {
|
|
146
|
+
for (const branch of step.branches) {
|
|
147
|
+
this.validateStepHandlers(branch, i);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
async getEnabledCronDefinitions() {
|
|
153
|
+
const result = await this.db.query(`SELECT * FROM ${this.tables.workflowDefinitions}
|
|
154
|
+
WHERE is_enabled = true AND cron_expression IS NOT NULL`);
|
|
155
|
+
return result.rows.map(this.mapDefinition);
|
|
156
|
+
}
|
|
157
|
+
async setWorkflowEnabled(definitionId, enabled) {
|
|
158
|
+
await this.db.query(`UPDATE ${this.tables.workflowDefinitions}
|
|
159
|
+
SET is_enabled = $1, updated_at = NOW()
|
|
160
|
+
WHERE id = $2`, [enabled, definitionId]);
|
|
161
|
+
}
|
|
162
|
+
async getDefinition(definitionId) {
|
|
163
|
+
const result = await this.db.query(`SELECT * FROM ${this.tables.workflowDefinitions} WHERE id = $1`, [definitionId]);
|
|
164
|
+
return result.rows[0] ? this.mapDefinition(result.rows[0]) : null;
|
|
165
|
+
}
|
|
166
|
+
mapDefinition(row) {
|
|
167
|
+
return {
|
|
168
|
+
id: row.id,
|
|
169
|
+
tenantId: row.tenant_id,
|
|
170
|
+
name: row.name,
|
|
171
|
+
description: row.description,
|
|
172
|
+
triggerType: row.trigger_type,
|
|
173
|
+
environmentFilter: row.environment_filter,
|
|
174
|
+
resourceTypeFilter: row.resource_type_filter,
|
|
175
|
+
steps: row.steps,
|
|
176
|
+
config: (row.config ?? {}),
|
|
177
|
+
isEnabled: row.is_enabled,
|
|
178
|
+
cronExpression: row.cron_expression,
|
|
179
|
+
createdAt: row.created_at,
|
|
180
|
+
updatedAt: row.updated_at,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matcher.js","sourceRoot":"","sources":["../src/matcher.ts"],"names":[],"mappings":"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"}
|
package/dist/queue.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type Job } from 'bullmq';
|
|
2
|
+
export interface QueueConfig {
|
|
3
|
+
redis: unknown;
|
|
4
|
+
prefix: string;
|
|
5
|
+
concurrency: number;
|
|
6
|
+
}
|
|
7
|
+
export interface MatchJob {
|
|
8
|
+
triggerId: string;
|
|
9
|
+
isReplay: boolean;
|
|
10
|
+
emitDepth: number;
|
|
11
|
+
}
|
|
12
|
+
export interface StepJob {
|
|
13
|
+
stepRunId: string;
|
|
14
|
+
runId: string;
|
|
15
|
+
emitDepth: number;
|
|
16
|
+
}
|
|
17
|
+
export interface CronJob {
|
|
18
|
+
definitionId: string;
|
|
19
|
+
tenantId: string;
|
|
20
|
+
triggerType: string;
|
|
21
|
+
}
|
|
22
|
+
export declare class QueueManager {
|
|
23
|
+
private config;
|
|
24
|
+
private matchQueue;
|
|
25
|
+
private stepQueue;
|
|
26
|
+
private cronQueue;
|
|
27
|
+
private matchWorker?;
|
|
28
|
+
private stepWorker?;
|
|
29
|
+
private cronWorker?;
|
|
30
|
+
constructor(config: QueueConfig);
|
|
31
|
+
enqueueMatch(triggerId: string, isReplay?: boolean, emitDepth?: number): Promise<void>;
|
|
32
|
+
enqueueStep(stepRunId: string, runId: string, delayMs?: number, emitDepth?: number, retryPolicy?: {
|
|
33
|
+
maxAttempts: number;
|
|
34
|
+
backoffMs: number;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
removeStepJobs(runId: string): Promise<void>;
|
|
37
|
+
addCronJob(definitionId: string, tenantId: string, triggerType: string, cronExpression: string): Promise<void>;
|
|
38
|
+
removeCronJob(definitionId: string): Promise<void>;
|
|
39
|
+
startWorkers(matchHandler: (job: Job) => Promise<void>, stepHandler: (job: Job) => Promise<void>, cronHandler?: (job: Job) => Promise<void>): void;
|
|
40
|
+
stop(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,GAAG,EAAE,MAAM,QAAQ,CAAA;AAEhD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,OAAO,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,qBAAa,YAAY;IAQX,OAAO,CAAC,MAAM;IAP1B,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,WAAW,CAAC,CAAQ;IAC5B,OAAO,CAAC,UAAU,CAAC,CAAQ;IAC3B,OAAO,CAAC,UAAU,CAAC,CAAQ;gBAEP,MAAM,EAAE,WAAW;IAgBjC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,OAAe,EAAE,SAAS,GAAE,MAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIhG,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,GAAE,MAAU,EACrB,WAAW,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GACvD,OAAO,CAAC,IAAI,CAAC;IAcV,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5C,UAAU,CACd,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC;IAWV,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASxD,YAAY,CACV,YAAY,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EACzC,WAAW,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,EACxC,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,GACxC,IAAI;IA+BD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAU5B"}
|
package/dist/queue.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Queue, Worker } from 'bullmq';
|
|
2
|
+
export class QueueManager {
|
|
3
|
+
config;
|
|
4
|
+
matchQueue;
|
|
5
|
+
stepQueue;
|
|
6
|
+
cronQueue;
|
|
7
|
+
matchWorker;
|
|
8
|
+
stepWorker;
|
|
9
|
+
cronWorker;
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
const connection = config.redis;
|
|
13
|
+
this.matchQueue = new Queue(`${config.prefix}:match`, {
|
|
14
|
+
connection,
|
|
15
|
+
});
|
|
16
|
+
this.stepQueue = new Queue(`${config.prefix}:steps`, {
|
|
17
|
+
connection,
|
|
18
|
+
});
|
|
19
|
+
this.cronQueue = new Queue(`${config.prefix}:cron`, {
|
|
20
|
+
connection,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
async enqueueMatch(triggerId, isReplay = false, emitDepth = 0) {
|
|
24
|
+
await this.matchQueue.add('match', { triggerId, isReplay, emitDepth });
|
|
25
|
+
}
|
|
26
|
+
async enqueueStep(stepRunId, runId, delayMs, emitDepth = 0, retryPolicy) {
|
|
27
|
+
await this.stepQueue.add('step', { stepRunId, runId, emitDepth }, {
|
|
28
|
+
...(delayMs ? { delay: delayMs } : undefined),
|
|
29
|
+
...(retryPolicy ? {
|
|
30
|
+
attempts: retryPolicy.maxAttempts,
|
|
31
|
+
backoff: { type: 'fixed', delay: retryPolicy.backoffMs },
|
|
32
|
+
} : undefined),
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async removeStepJobs(runId) {
|
|
36
|
+
const jobs = await this.stepQueue.getJobs(['waiting', 'delayed']);
|
|
37
|
+
for (const job of jobs) {
|
|
38
|
+
if (job.data?.runId === runId) {
|
|
39
|
+
await job.remove();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// --- Cron repeatable jobs ---
|
|
44
|
+
async addCronJob(definitionId, tenantId, triggerType, cronExpression) {
|
|
45
|
+
await this.cronQueue.add(`cron:${definitionId}`, { definitionId, tenantId, triggerType }, {
|
|
46
|
+
repeat: { pattern: cronExpression },
|
|
47
|
+
jobId: `cron:${definitionId}`,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async removeCronJob(definitionId) {
|
|
51
|
+
const repeatableJobs = await this.cronQueue.getRepeatableJobs();
|
|
52
|
+
for (const rj of repeatableJobs) {
|
|
53
|
+
if (rj.name === `cron:${definitionId}`) {
|
|
54
|
+
await this.cronQueue.removeRepeatableByKey(rj.key);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
startWorkers(matchHandler, stepHandler, cronHandler) {
|
|
59
|
+
this.matchWorker = new Worker(`${this.config.prefix}:match`, matchHandler, {
|
|
60
|
+
connection: this.config.redis,
|
|
61
|
+
concurrency: this.config.concurrency,
|
|
62
|
+
});
|
|
63
|
+
this.stepWorker = new Worker(`${this.config.prefix}:steps`, stepHandler, {
|
|
64
|
+
connection: this.config.redis,
|
|
65
|
+
concurrency: this.config.concurrency,
|
|
66
|
+
});
|
|
67
|
+
if (cronHandler) {
|
|
68
|
+
this.cronWorker = new Worker(`${this.config.prefix}:cron`, cronHandler, {
|
|
69
|
+
connection: this.config.redis,
|
|
70
|
+
concurrency: 1,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async stop() {
|
|
75
|
+
await Promise.all([
|
|
76
|
+
this.matchWorker?.close(),
|
|
77
|
+
this.stepWorker?.close(),
|
|
78
|
+
this.cronWorker?.close(),
|
|
79
|
+
this.matchQueue.close(),
|
|
80
|
+
this.stepQueue.close(),
|
|
81
|
+
this.cronQueue.close(),
|
|
82
|
+
]);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.js","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TriggerRegistration, ActionHandler, ActionOptions, ConditionHandler } from './types.js';
|
|
2
|
+
export interface RegisteredAction {
|
|
3
|
+
handler: ActionHandler;
|
|
4
|
+
options: ActionOptions;
|
|
5
|
+
}
|
|
6
|
+
export interface RegisteredCondition {
|
|
7
|
+
handler: ConditionHandler;
|
|
8
|
+
}
|
|
9
|
+
export declare class Registry {
|
|
10
|
+
private triggers;
|
|
11
|
+
private actions;
|
|
12
|
+
private conditions;
|
|
13
|
+
registerTrigger(type: string, registration: TriggerRegistration): void;
|
|
14
|
+
registerAction(name: string, handler: ActionHandler, options?: ActionOptions): void;
|
|
15
|
+
registerCondition(name: string, handler: ConditionHandler): void;
|
|
16
|
+
getTrigger(type: string): TriggerRegistration | undefined;
|
|
17
|
+
getAction(name: string): RegisteredAction | undefined;
|
|
18
|
+
getCondition(name: string): RegisteredCondition | undefined;
|
|
19
|
+
hasTrigger(type: string): boolean;
|
|
20
|
+
hasAction(name: string): boolean;
|
|
21
|
+
hasCondition(name: string): boolean;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=registry.d.ts.map
|