@classytic/streamline 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +740 -0
- package/dist/container-BzpIMrrj.mjs +2697 -0
- package/dist/errors-BqunvWPz.mjs +129 -0
- package/dist/events-B5aTz7kD.mjs +28 -0
- package/dist/events-C0sZINZq.d.mts +92 -0
- package/dist/index.d.mts +1589 -0
- package/dist/index.mjs +1102 -0
- package/dist/integrations/fastify.d.mts +12 -0
- package/dist/integrations/fastify.mjs +23 -0
- package/dist/telemetry/index.d.mts +18 -0
- package/dist/telemetry/index.mjs +102 -0
- package/dist/types-DG85_LzF.d.mts +275 -0
- package/package.json +104 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { _ as WorkflowHandlers, h as WorkflowDefinition } from "../types-DG85_LzF.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/fastify.d.ts
|
|
4
|
+
interface WorkflowPluginOptions {
|
|
5
|
+
workflows: Array<{
|
|
6
|
+
definition: WorkflowDefinition;
|
|
7
|
+
handlers: WorkflowHandlers;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
declare function workflowPlugin(fastify: unknown, options: WorkflowPluginOptions): Promise<void>;
|
|
11
|
+
//#endregion
|
|
12
|
+
export { workflowPlugin as default };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { p as WorkflowEngine, t as createContainer } from "../container-BzpIMrrj.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/fastify.ts
|
|
4
|
+
async function workflowPlugin(fastify, options) {
|
|
5
|
+
const engines = /* @__PURE__ */ new Map();
|
|
6
|
+
const fastifyInstance = fastify;
|
|
7
|
+
for (const { definition, handlers } of options.workflows) {
|
|
8
|
+
const engine = new WorkflowEngine(definition, handlers, createContainer());
|
|
9
|
+
engines.set(definition.id, engine);
|
|
10
|
+
}
|
|
11
|
+
fastifyInstance.decorate("workflows", engines);
|
|
12
|
+
fastifyInstance.decorate("getWorkflow", (id) => {
|
|
13
|
+
const engine = engines.get(id);
|
|
14
|
+
if (!engine) throw new Error(`Workflow ${id} not found`);
|
|
15
|
+
return engine;
|
|
16
|
+
});
|
|
17
|
+
fastifyInstance.addHook("onClose", async () => {
|
|
18
|
+
for (const engine of engines.values()) engine.shutdown();
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
//#endregion
|
|
23
|
+
export { workflowPlugin as default };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { t as WorkflowEventBus } from "../events-C0sZINZq.mjs";
|
|
2
|
+
import { Tracer } from "@opentelemetry/api";
|
|
3
|
+
|
|
4
|
+
//#region src/telemetry/index.d.ts
|
|
5
|
+
interface TelemetryConfig {
|
|
6
|
+
tracer: Tracer;
|
|
7
|
+
/** Event bus to listen to (defaults to globalEventBus) */
|
|
8
|
+
eventBus?: WorkflowEventBus;
|
|
9
|
+
}
|
|
10
|
+
declare function enableTelemetry(config: TelemetryConfig): void;
|
|
11
|
+
declare function disableTelemetry(): void;
|
|
12
|
+
declare function isTelemetryEnabled(): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Get the current event bus used by telemetry (for debugging)
|
|
15
|
+
*/
|
|
16
|
+
declare function getTelemetryEventBus(): WorkflowEventBus | null;
|
|
17
|
+
//#endregion
|
|
18
|
+
export { disableTelemetry, enableTelemetry, getTelemetryEventBus, isTelemetryEnabled };
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { n as globalEventBus } from "../events-B5aTz7kD.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/telemetry/index.ts
|
|
4
|
+
const spans = /* @__PURE__ */ new Map();
|
|
5
|
+
const listeners = [];
|
|
6
|
+
let currentEventBus = null;
|
|
7
|
+
let enabled = false;
|
|
8
|
+
function enableTelemetry(config) {
|
|
9
|
+
if (enabled) return;
|
|
10
|
+
const { tracer } = config;
|
|
11
|
+
const eventBus = config.eventBus ?? globalEventBus;
|
|
12
|
+
currentEventBus = eventBus;
|
|
13
|
+
enabled = true;
|
|
14
|
+
const on = (event, handler) => {
|
|
15
|
+
const fn = (...args) => handler(args[0]);
|
|
16
|
+
listeners.push({
|
|
17
|
+
event,
|
|
18
|
+
fn,
|
|
19
|
+
bus: eventBus
|
|
20
|
+
});
|
|
21
|
+
eventBus.on(event, fn);
|
|
22
|
+
};
|
|
23
|
+
on("workflow:started", ({ runId }) => {
|
|
24
|
+
if (!runId) return;
|
|
25
|
+
const span = tracer.startSpan(`workflow:${runId}`);
|
|
26
|
+
span.setAttribute("workflow.runId", runId);
|
|
27
|
+
spans.set(runId, span);
|
|
28
|
+
});
|
|
29
|
+
on("step:started", ({ runId, stepId }) => {
|
|
30
|
+
if (!runId || !stepId) return;
|
|
31
|
+
const span = tracer.startSpan(`step:${stepId}`);
|
|
32
|
+
span.setAttribute("workflow.runId", runId);
|
|
33
|
+
span.setAttribute("step.id", stepId);
|
|
34
|
+
spans.set(`${runId}:${stepId}`, span);
|
|
35
|
+
});
|
|
36
|
+
on("step:completed", ({ runId, stepId }) => {
|
|
37
|
+
if (!runId || !stepId) return;
|
|
38
|
+
const span = spans.get(`${runId}:${stepId}`);
|
|
39
|
+
if (span) {
|
|
40
|
+
span.setStatus({ code: 1 });
|
|
41
|
+
span.end();
|
|
42
|
+
spans.delete(`${runId}:${stepId}`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
on("step:failed", ({ runId, stepId, data }) => {
|
|
46
|
+
if (!runId || !stepId) return;
|
|
47
|
+
const span = spans.get(`${runId}:${stepId}`);
|
|
48
|
+
if (span) {
|
|
49
|
+
const errorData = data;
|
|
50
|
+
span.setStatus({
|
|
51
|
+
code: 2,
|
|
52
|
+
message: errorData?.error?.message
|
|
53
|
+
});
|
|
54
|
+
if (errorData?.error) span.recordException(errorData.error);
|
|
55
|
+
span.end();
|
|
56
|
+
spans.delete(`${runId}:${stepId}`);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
on("workflow:completed", ({ runId }) => {
|
|
60
|
+
if (!runId) return;
|
|
61
|
+
const span = spans.get(runId);
|
|
62
|
+
if (span) {
|
|
63
|
+
span.setStatus({ code: 1 });
|
|
64
|
+
span.end();
|
|
65
|
+
spans.delete(runId);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
on("workflow:failed", ({ runId, data }) => {
|
|
69
|
+
if (!runId) return;
|
|
70
|
+
const span = spans.get(runId);
|
|
71
|
+
if (span) {
|
|
72
|
+
const errorData = data;
|
|
73
|
+
span.setStatus({
|
|
74
|
+
code: 2,
|
|
75
|
+
message: errorData?.error?.message
|
|
76
|
+
});
|
|
77
|
+
if (errorData?.error) span.recordException(errorData.error);
|
|
78
|
+
span.end();
|
|
79
|
+
spans.delete(runId);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
function disableTelemetry() {
|
|
84
|
+
if (!enabled) return;
|
|
85
|
+
listeners.forEach(({ event, fn, bus }) => bus.off(event, fn));
|
|
86
|
+
listeners.length = 0;
|
|
87
|
+
spans.clear();
|
|
88
|
+
currentEventBus = null;
|
|
89
|
+
enabled = false;
|
|
90
|
+
}
|
|
91
|
+
function isTelemetryEnabled() {
|
|
92
|
+
return enabled;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get the current event bus used by telemetry (for debugging)
|
|
96
|
+
*/
|
|
97
|
+
function getTelemetryEventBus() {
|
|
98
|
+
return currentEventBus;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//#endregion
|
|
102
|
+
export { disableTelemetry, enableTelemetry, getTelemetryEventBus, isTelemetryEnabled };
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
//#region src/core/types.d.ts
|
|
2
|
+
type StepStatus = 'pending' | 'running' | 'waiting' | 'done' | 'failed' | 'skipped';
|
|
3
|
+
type RunStatus = 'draft' | 'running' | 'waiting' | 'done' | 'failed' | 'cancelled';
|
|
4
|
+
interface Step {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
/**
|
|
9
|
+
* Maximum number of execution attempts for this step (including the initial attempt).
|
|
10
|
+
*
|
|
11
|
+
* Example: retries=3 means:
|
|
12
|
+
* - Attempt 1 (initial execution)
|
|
13
|
+
* - Attempt 2 (first retry after failure)
|
|
14
|
+
* - Attempt 3 (second retry after failure)
|
|
15
|
+
* - Total: 3 attempts
|
|
16
|
+
*
|
|
17
|
+
* If all attempts fail, the step is marked as 'failed' and the workflow stops.
|
|
18
|
+
* Uses exponential backoff: 1s, 2s, 4s, 8s, ... (max 60s between retries).
|
|
19
|
+
*
|
|
20
|
+
* @default 3
|
|
21
|
+
*/
|
|
22
|
+
retries?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Maximum execution time in milliseconds for this step.
|
|
25
|
+
* If the step handler doesn't complete within this time, it throws a timeout error.
|
|
26
|
+
*
|
|
27
|
+
* @default undefined (no timeout)
|
|
28
|
+
*/
|
|
29
|
+
timeout?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Full condition function with access to context and run.
|
|
32
|
+
* Return true to execute the step, false to skip.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* step({
|
|
37
|
+
* id: 'send-email',
|
|
38
|
+
* name: 'Send Email',
|
|
39
|
+
* condition: (context, run) => context.shouldSendEmail && run.status === 'running'
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
condition?: (context: unknown, run: WorkflowRun) => boolean | Promise<boolean>;
|
|
44
|
+
/**
|
|
45
|
+
* Skip this step if the predicate returns true.
|
|
46
|
+
* Simpler alternative to condition for basic skip logic.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* step({ id: 'optional-step', name: 'Optional', skipIf: (ctx) => !ctx.featureEnabled })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
skipIf?: (context: unknown) => boolean | Promise<boolean>;
|
|
54
|
+
/**
|
|
55
|
+
* Only run this step if the predicate returns true.
|
|
56
|
+
* Simpler alternative to condition for basic run logic.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```typescript
|
|
60
|
+
* step({ id: 'premium-feature', name: 'Premium', runIf: (ctx) => ctx.isPremiumUser })
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
runIf?: (context: unknown) => boolean | Promise<boolean>;
|
|
64
|
+
}
|
|
65
|
+
interface StepError {
|
|
66
|
+
message: string;
|
|
67
|
+
code?: string;
|
|
68
|
+
retriable?: boolean;
|
|
69
|
+
stack?: string;
|
|
70
|
+
}
|
|
71
|
+
interface WorkflowError {
|
|
72
|
+
message: string;
|
|
73
|
+
code?: string;
|
|
74
|
+
stack?: string;
|
|
75
|
+
}
|
|
76
|
+
interface WaitingFor {
|
|
77
|
+
type: 'human' | 'webhook' | 'timer' | 'event';
|
|
78
|
+
reason: string;
|
|
79
|
+
resumeAt?: Date;
|
|
80
|
+
eventName?: string;
|
|
81
|
+
data?: unknown;
|
|
82
|
+
}
|
|
83
|
+
interface StepState<TOutput = unknown> {
|
|
84
|
+
stepId: string;
|
|
85
|
+
status: StepStatus;
|
|
86
|
+
attempts: number;
|
|
87
|
+
startedAt?: Date;
|
|
88
|
+
endedAt?: Date;
|
|
89
|
+
output?: TOutput;
|
|
90
|
+
waitingFor?: WaitingFor;
|
|
91
|
+
error?: StepError;
|
|
92
|
+
retryAfter?: Date;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Scheduling metadata for timezone-aware workflow execution
|
|
96
|
+
*/
|
|
97
|
+
interface SchedulingInfo {
|
|
98
|
+
/**
|
|
99
|
+
* User's intended local time as ISO string (without timezone suffix)
|
|
100
|
+
* Format: "YYYY-MM-DDTHH:mm:ss" (e.g., "2024-03-10T09:00:00")
|
|
101
|
+
* This is the ORIGINAL string the user provided, preserved for accurate rescheduling
|
|
102
|
+
*/
|
|
103
|
+
scheduledFor: string;
|
|
104
|
+
/** IANA timezone name (e.g., "America/New_York", "Europe/London") */
|
|
105
|
+
timezone: string;
|
|
106
|
+
/** Human-readable local time with timezone abbreviation (e.g., "2024-03-10 09:00:00 EDT") */
|
|
107
|
+
localTimeDisplay: string;
|
|
108
|
+
/** UTC execution time - used by scheduler for actual execution */
|
|
109
|
+
executionTime: Date;
|
|
110
|
+
/** Whether this time falls during a DST transition */
|
|
111
|
+
isDSTTransition: boolean;
|
|
112
|
+
/** Human-readable note about DST adjustments (if any) */
|
|
113
|
+
dstNote?: string;
|
|
114
|
+
/** Optional recurrence pattern for repeating workflows */
|
|
115
|
+
recurrence?: RecurrencePattern;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Recurrence pattern for scheduled workflows
|
|
119
|
+
*/
|
|
120
|
+
interface RecurrencePattern {
|
|
121
|
+
/** How often to repeat (daily, weekly, monthly, custom cron) */
|
|
122
|
+
pattern: 'daily' | 'weekly' | 'monthly' | 'custom';
|
|
123
|
+
/** For weekly: which days (0=Sunday, 6=Saturday) */
|
|
124
|
+
daysOfWeek?: number[];
|
|
125
|
+
/** For monthly: which day of month (1-31) */
|
|
126
|
+
dayOfMonth?: number;
|
|
127
|
+
/** Custom cron expression (if pattern='custom') */
|
|
128
|
+
cronExpression?: string;
|
|
129
|
+
/** Stop repeating after this date */
|
|
130
|
+
until?: Date;
|
|
131
|
+
/** Or stop after N occurrences */
|
|
132
|
+
count?: number;
|
|
133
|
+
/** How many times has this recurred so far */
|
|
134
|
+
occurrences?: number;
|
|
135
|
+
}
|
|
136
|
+
interface WorkflowRun<TContext = Record<string, unknown>> {
|
|
137
|
+
_id: string;
|
|
138
|
+
workflowId: string;
|
|
139
|
+
status: RunStatus;
|
|
140
|
+
steps: StepState[];
|
|
141
|
+
currentStepId: string | null;
|
|
142
|
+
context: TContext;
|
|
143
|
+
input: unknown;
|
|
144
|
+
output?: unknown;
|
|
145
|
+
error?: WorkflowError;
|
|
146
|
+
createdAt: Date;
|
|
147
|
+
updatedAt: Date;
|
|
148
|
+
startedAt?: Date;
|
|
149
|
+
endedAt?: Date;
|
|
150
|
+
lastHeartbeat?: Date;
|
|
151
|
+
paused?: boolean;
|
|
152
|
+
/** Timezone-aware scheduling metadata (optional - only for scheduled workflows) */
|
|
153
|
+
scheduling?: SchedulingInfo;
|
|
154
|
+
userId?: string;
|
|
155
|
+
tags?: string[];
|
|
156
|
+
meta?: Record<string, unknown>;
|
|
157
|
+
}
|
|
158
|
+
interface WorkflowDefinition<TContext = Record<string, unknown>> {
|
|
159
|
+
id: string;
|
|
160
|
+
name: string;
|
|
161
|
+
version: string;
|
|
162
|
+
steps: Step[];
|
|
163
|
+
createContext: (input: unknown) => TContext;
|
|
164
|
+
/**
|
|
165
|
+
* Default values for all steps in this workflow.
|
|
166
|
+
* Individual steps can override these defaults.
|
|
167
|
+
*/
|
|
168
|
+
defaults?: {
|
|
169
|
+
/**
|
|
170
|
+
* Maximum number of execution attempts for each step (including initial attempt).
|
|
171
|
+
* @default 3
|
|
172
|
+
*/
|
|
173
|
+
retries?: number;
|
|
174
|
+
/**
|
|
175
|
+
* Maximum execution time in milliseconds for each step.
|
|
176
|
+
* @default undefined (no timeout)
|
|
177
|
+
*/
|
|
178
|
+
timeout?: number;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
interface StepContext<TContext = Record<string, unknown>> {
|
|
182
|
+
runId: string;
|
|
183
|
+
stepId: string;
|
|
184
|
+
context: TContext;
|
|
185
|
+
input: unknown;
|
|
186
|
+
attempt: number;
|
|
187
|
+
/**
|
|
188
|
+
* AbortSignal for step cancellation.
|
|
189
|
+
* Handlers should check this signal and abort long-running operations when triggered.
|
|
190
|
+
* The signal is aborted when:
|
|
191
|
+
* - Step timeout is exceeded
|
|
192
|
+
* - Workflow is cancelled
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```typescript
|
|
196
|
+
* async function fetchData(ctx) {
|
|
197
|
+
* const response = await fetch(url, { signal: ctx.signal });
|
|
198
|
+
* // ...
|
|
199
|
+
* }
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
signal: AbortSignal;
|
|
203
|
+
set: <K extends keyof TContext>(key: K, value: TContext[K]) => Promise<void>;
|
|
204
|
+
getOutput: <T = unknown>(stepId: string) => T | undefined;
|
|
205
|
+
wait: (reason: string, data?: unknown) => Promise<never>;
|
|
206
|
+
waitFor: (eventName: string, reason?: string) => Promise<unknown>;
|
|
207
|
+
sleep: (ms: number) => Promise<void>;
|
|
208
|
+
/**
|
|
209
|
+
* Send a heartbeat to prevent the workflow from being marked as stale.
|
|
210
|
+
* Use this in long-running steps (5+ minutes) to signal the step is still active.
|
|
211
|
+
*
|
|
212
|
+
* Heartbeats are automatically sent every 30 seconds during step execution,
|
|
213
|
+
* but you can call this manually for extra control.
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* async function processLargeDataset(ctx) {
|
|
218
|
+
* for (const batch of batches) {
|
|
219
|
+
* await processBatch(batch);
|
|
220
|
+
* await ctx.heartbeat(); // Signal we're still alive
|
|
221
|
+
* }
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
heartbeat: () => Promise<void>;
|
|
226
|
+
emit: (eventName: string, data: unknown) => void;
|
|
227
|
+
log: (message: string, data?: unknown) => void;
|
|
228
|
+
}
|
|
229
|
+
type StepHandler<TOutput = unknown, TContext = Record<string, unknown>> = (ctx: StepContext<TContext>) => Promise<TOutput>;
|
|
230
|
+
type WorkflowHandlers<TContext = Record<string, unknown>> = {
|
|
231
|
+
[stepId: string]: StepHandler<unknown, TContext>;
|
|
232
|
+
};
|
|
233
|
+
/**
|
|
234
|
+
* Infer context type from WorkflowDefinition
|
|
235
|
+
* @example
|
|
236
|
+
* type MyContext = InferContext<typeof myWorkflow>
|
|
237
|
+
*/
|
|
238
|
+
type InferContext<T> = T extends WorkflowDefinition<infer TContext> ? TContext : never;
|
|
239
|
+
/**
|
|
240
|
+
* Infer context type from WorkflowHandlers
|
|
241
|
+
* @example
|
|
242
|
+
* type MyContext = InferHandlersContext<typeof myHandlers>
|
|
243
|
+
*/
|
|
244
|
+
type InferHandlersContext<T> = T extends WorkflowHandlers<infer TContext> ? TContext : never;
|
|
245
|
+
/**
|
|
246
|
+
* Strongly-typed handlers that match workflow steps
|
|
247
|
+
* Ensures all step IDs have corresponding handlers
|
|
248
|
+
* @example
|
|
249
|
+
* const handlers: TypedHandlers<typeof workflow, MyContext> = { ... }
|
|
250
|
+
*/
|
|
251
|
+
type TypedHandlers<TWorkflow extends WorkflowDefinition<any>, TContext = InferContext<TWorkflow>> = { [K in TWorkflow['steps'][number]['id']]: StepHandler<unknown, TContext> };
|
|
252
|
+
/**
|
|
253
|
+
* Extract step IDs as union type from workflow definition
|
|
254
|
+
* @example
|
|
255
|
+
* type MyStepIds = StepIds<typeof myWorkflow> // 'step1' | 'step2' | 'step3'
|
|
256
|
+
*/
|
|
257
|
+
type StepIds<T extends WorkflowDefinition<any>> = T['steps'][number]['id'];
|
|
258
|
+
/**
|
|
259
|
+
* Payload for workflow and engine events
|
|
260
|
+
*/
|
|
261
|
+
interface WorkflowEventPayload {
|
|
262
|
+
runId?: string;
|
|
263
|
+
stepId?: string;
|
|
264
|
+
data?: unknown;
|
|
265
|
+
error?: Error;
|
|
266
|
+
context?: string;
|
|
267
|
+
/**
|
|
268
|
+
* Explicit broadcast flag for resuming multiple workflows.
|
|
269
|
+
* When true, the event will resume ALL workflows waiting on this event.
|
|
270
|
+
* When false/undefined with no runId, a warning is logged.
|
|
271
|
+
*/
|
|
272
|
+
broadcast?: boolean;
|
|
273
|
+
}
|
|
274
|
+
//#endregion
|
|
275
|
+
export { WorkflowHandlers as _, SchedulingInfo as a, StepError as c, StepState as d, StepStatus as f, WorkflowEventPayload as g, WorkflowDefinition as h, RunStatus as i, StepHandler as l, WaitingFor as m, InferHandlersContext as n, Step as o, TypedHandlers as p, RecurrencePattern as r, StepContext as s, InferContext as t, StepIds as u, WorkflowRun as v };
|
package/package.json
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@classytic/streamline",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MongoDB-native durable workflow orchestration engine. Like Temporal but simpler - supports sleep, wait, retry, parallel execution, human-in-the-loop, and crash recovery. Perfect for payment gateways, approval flows, and scheduled tasks.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.mjs",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"types": "./dist/index.d.mts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.mts",
|
|
13
|
+
"default": "./dist/index.mjs"
|
|
14
|
+
},
|
|
15
|
+
"./fastify": {
|
|
16
|
+
"types": "./dist/integrations/fastify.d.mts",
|
|
17
|
+
"default": "./dist/integrations/fastify.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./telemetry": {
|
|
20
|
+
"types": "./dist/telemetry/index.d.mts",
|
|
21
|
+
"default": "./dist/telemetry/index.mjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsdown",
|
|
31
|
+
"dev": "tsdown --watch",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"test": "vitest run",
|
|
34
|
+
"test:watch": "vitest",
|
|
35
|
+
"prepublishOnly": "npm run typecheck && npm test && npm run build"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22"
|
|
39
|
+
},
|
|
40
|
+
"keywords": [
|
|
41
|
+
"workflow",
|
|
42
|
+
"temporal",
|
|
43
|
+
"durable",
|
|
44
|
+
"durable-execution",
|
|
45
|
+
"orchestration",
|
|
46
|
+
"mongodb",
|
|
47
|
+
"mongoose",
|
|
48
|
+
"sleep",
|
|
49
|
+
"wait",
|
|
50
|
+
"resume",
|
|
51
|
+
"human-in-the-loop",
|
|
52
|
+
"background-jobs",
|
|
53
|
+
"state-machine",
|
|
54
|
+
"crash-recovery",
|
|
55
|
+
"retry",
|
|
56
|
+
"parallel",
|
|
57
|
+
"scheduling",
|
|
58
|
+
"webhook",
|
|
59
|
+
"approval-flow",
|
|
60
|
+
"typescript"
|
|
61
|
+
],
|
|
62
|
+
"author": "Classytic <classytic.dev@gmail.com> (https://github.com/classytic)",
|
|
63
|
+
"contributors": [
|
|
64
|
+
"Sadman Chowdhury (https://github.com/siam923)"
|
|
65
|
+
],
|
|
66
|
+
"license": "MIT",
|
|
67
|
+
"repository": {
|
|
68
|
+
"type": "git",
|
|
69
|
+
"url": "https://github.com/classytic/streamline.git"
|
|
70
|
+
},
|
|
71
|
+
"homepage": "https://github.com/classytic/streamline#readme",
|
|
72
|
+
"bugs": {
|
|
73
|
+
"url": "https://github.com/classytic/streamline/issues"
|
|
74
|
+
},
|
|
75
|
+
"peerDependencies": {
|
|
76
|
+
"@classytic/mongokit": "^3.2.3",
|
|
77
|
+
"mongoose": "^9.0.0",
|
|
78
|
+
"@opentelemetry/api": ">=1.0.0"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"@opentelemetry/api": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"devDependencies": {
|
|
86
|
+
"@classytic/mongokit": "^3.2.3",
|
|
87
|
+
"@opentelemetry/api": "^1.9.0",
|
|
88
|
+
"@types/luxon": "^3.7.1",
|
|
89
|
+
"luxon": "^3.7.2",
|
|
90
|
+
"semver": "^7.7.3",
|
|
91
|
+
"@types/node": "^22.0.0",
|
|
92
|
+
"@types/semver": "^7.7.1",
|
|
93
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
94
|
+
"mongodb-memory-server": "^11.0.1",
|
|
95
|
+
"mongoose": "^9.0.0",
|
|
96
|
+
"tsdown": "^0.20.3",
|
|
97
|
+
"typescript": "^5.0.0",
|
|
98
|
+
"vitest": "^3.0.0"
|
|
99
|
+
},
|
|
100
|
+
"dependencies": {
|
|
101
|
+
"luxon": "^3.0.0",
|
|
102
|
+
"semver": "^7.0.0"
|
|
103
|
+
}
|
|
104
|
+
}
|