ai-workflows 2.1.1 → 2.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -1
- package/README.md +305 -184
- package/dist/barrier.d.ts +159 -0
- package/dist/barrier.d.ts.map +1 -0
- package/dist/barrier.js +377 -0
- package/dist/barrier.js.map +1 -0
- package/dist/cascade-context.d.ts +149 -0
- package/dist/cascade-context.d.ts.map +1 -0
- package/dist/cascade-context.js +324 -0
- package/dist/cascade-context.js.map +1 -0
- package/dist/cascade-executor.d.ts +196 -0
- package/dist/cascade-executor.d.ts.map +1 -0
- package/dist/cascade-executor.js +384 -0
- package/dist/cascade-executor.js.map +1 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +27 -8
- package/dist/context.js.map +1 -1
- package/dist/cron-parser.d.ts +65 -0
- package/dist/cron-parser.d.ts.map +1 -0
- package/dist/cron-parser.js +294 -0
- package/dist/cron-parser.js.map +1 -0
- package/dist/cron-scheduler.d.ts +117 -0
- package/dist/cron-scheduler.d.ts.map +1 -0
- package/dist/cron-scheduler.js +176 -0
- package/dist/cron-scheduler.js.map +1 -0
- package/dist/database-context.d.ts +184 -0
- package/dist/database-context.d.ts.map +1 -0
- package/dist/database-context.js +428 -0
- package/dist/database-context.js.map +1 -0
- package/dist/dependency-graph.d.ts +157 -0
- package/dist/dependency-graph.d.ts.map +1 -0
- package/dist/dependency-graph.js +382 -0
- package/dist/dependency-graph.js.map +1 -0
- package/dist/digital-objects-adapter.d.ts +159 -0
- package/dist/digital-objects-adapter.d.ts.map +1 -0
- package/dist/digital-objects-adapter.js +229 -0
- package/dist/digital-objects-adapter.js.map +1 -0
- package/dist/durable-execution-cloudflare.d.ts +427 -0
- package/dist/durable-execution-cloudflare.d.ts.map +1 -0
- package/dist/durable-execution-cloudflare.js +510 -0
- package/dist/durable-execution-cloudflare.js.map +1 -0
- package/dist/durable-execution.d.ts +482 -0
- package/dist/durable-execution.d.ts.map +1 -0
- package/dist/durable-execution.js +594 -0
- package/dist/durable-execution.js.map +1 -0
- package/dist/durable-workflow.d.ts +176 -0
- package/dist/durable-workflow.d.ts.map +1 -0
- package/dist/durable-workflow.js +552 -0
- package/dist/durable-workflow.js.map +1 -0
- package/dist/every.d.ts +31 -2
- package/dist/every.d.ts.map +1 -1
- package/dist/every.js +63 -32
- package/dist/every.js.map +1 -1
- package/dist/graph/index.d.ts +8 -0
- package/dist/graph/index.d.ts.map +1 -0
- package/dist/graph/index.js +8 -0
- package/dist/graph/index.js.map +1 -0
- package/dist/graph/topological-sort.d.ts +121 -0
- package/dist/graph/topological-sort.d.ts.map +1 -0
- package/dist/graph/topological-sort.js +292 -0
- package/dist/graph/topological-sort.js.map +1 -0
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -0
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +101 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +115 -0
- package/dist/logger.js.map +1 -0
- package/dist/on.d.ts +35 -10
- package/dist/on.d.ts.map +1 -1
- package/dist/on.js +53 -19
- package/dist/on.js.map +1 -1
- package/dist/runtime.d.ts +169 -0
- package/dist/runtime.d.ts.map +1 -0
- package/dist/runtime.js +275 -0
- package/dist/runtime.js.map +1 -0
- package/dist/send.d.ts.map +1 -1
- package/dist/send.js +4 -3
- package/dist/send.js.map +1 -1
- package/dist/telemetry.d.ts +150 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +388 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/timer-registry.d.ts +77 -0
- package/dist/timer-registry.d.ts.map +1 -0
- package/dist/timer-registry.js +154 -0
- package/dist/timer-registry.js.map +1 -0
- package/dist/types.d.ts +105 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +17 -1
- package/dist/types.js.map +1 -1
- package/dist/worker/durable-step.d.ts +481 -0
- package/dist/worker/durable-step.d.ts.map +1 -0
- package/dist/worker/durable-step.js +606 -0
- package/dist/worker/durable-step.js.map +1 -0
- package/dist/worker/index.d.ts +106 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +124 -0
- package/dist/worker/index.js.map +1 -0
- package/dist/worker/state-adapter.d.ts +230 -0
- package/dist/worker/state-adapter.d.ts.map +1 -0
- package/dist/worker/state-adapter.js +409 -0
- package/dist/worker/state-adapter.js.map +1 -0
- package/dist/worker/topological-executor.d.ts +282 -0
- package/dist/worker/topological-executor.d.ts.map +1 -0
- package/dist/worker/topological-executor.js +396 -0
- package/dist/worker/topological-executor.js.map +1 -0
- package/dist/worker/workflow-builder.d.ts +286 -0
- package/dist/worker/workflow-builder.d.ts.map +1 -0
- package/dist/worker/workflow-builder.js +565 -0
- package/dist/worker/workflow-builder.js.map +1 -0
- package/dist/worker.d.ts +800 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +2428 -0
- package/dist/worker.js.map +1 -0
- package/dist/workflow-builder.d.ts +287 -0
- package/dist/workflow-builder.d.ts.map +1 -0
- package/dist/workflow-builder.js +762 -0
- package/dist/workflow-builder.js.map +1 -0
- package/dist/workflow.d.ts +14 -30
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +136 -292
- package/dist/workflow.js.map +1 -1
- package/examples/01-ecommerce-order-pipeline.ts +358 -0
- package/examples/02-content-moderation-cascade.ts +454 -0
- package/examples/03-scheduled-reporting-dependencies.ts +479 -0
- package/examples/04-database-persistence.ts +518 -0
- package/examples/README.md +173 -0
- package/package.json +21 -4
- package/src/__tests__/digital-objects-adapter.test.ts +274 -0
- package/src/__tests__/durable-workflow.test.ts +297 -0
- package/src/barrier.ts +507 -0
- package/src/cascade-context.ts +495 -0
- package/src/cascade-executor.ts +588 -0
- package/src/context.ts +51 -17
- package/src/cron-parser.ts +347 -0
- package/src/cron-scheduler.ts +239 -0
- package/src/database-context.ts +658 -0
- package/src/dependency-graph.ts +518 -0
- package/src/digital-objects-adapter.ts +351 -0
- package/src/durable-execution-cloudflare.ts +855 -0
- package/src/durable-execution.ts +1042 -0
- package/src/durable-workflow.ts +717 -0
- package/src/every.ts +104 -35
- package/src/graph/index.ts +19 -0
- package/src/graph/topological-sort.ts +412 -0
- package/src/index.ts +147 -0
- package/src/logger.ts +148 -0
- package/src/on.ts +81 -26
- package/src/runtime.ts +436 -0
- package/src/send.ts +4 -5
- package/src/telemetry.ts +577 -0
- package/src/timer-registry.ts +179 -0
- package/src/types.ts +146 -10
- package/src/worker/durable-step.ts +976 -0
- package/src/worker/index.ts +216 -0
- package/src/worker/state-adapter.ts +589 -0
- package/src/worker/topological-executor.ts +625 -0
- package/src/worker/workflow-builder.ts +871 -0
- package/src/worker.ts +2906 -0
- package/src/workflow-builder.ts +1068 -0
- package/src/workflow.ts +199 -355
- package/test/barrier-join.test.ts +442 -0
- package/test/barrier-unhandled-rejections.test.ts +359 -0
- package/test/cascade-context.test.ts +390 -0
- package/test/cascade-executor.test.ts +852 -0
- package/test/cron-parser.test.ts +314 -0
- package/test/cron-scheduler.test.ts +291 -0
- package/test/database-context.test.ts +770 -0
- package/test/db-provider-adapter.test.ts +862 -0
- package/test/dependency-graph.test.ts +512 -0
- package/test/durable-execution-cloudflare.test.ts +606 -0
- package/test/durable-execution-in-process.test.ts +286 -0
- package/test/durable-execution.test.ts +247 -0
- package/test/e2e/workflow-scenarios.e2e.test.ts +1039 -0
- package/test/graph/topological-sort.test.ts +586 -0
- package/test/integration.test.ts +442 -0
- package/test/rpc-surface.test.ts +946 -0
- package/test/runtime.test.ts +262 -0
- package/test/schedule-timer-cleanup.test.ts +353 -0
- package/test/send-race-conditions.test.ts +400 -0
- package/test/type-safety-every.test.ts +303 -0
- package/test/worker/durable-cascade.test.ts +1117 -0
- package/test/worker/durable-step.test.ts +723 -0
- package/test/worker/topological-executor.test.ts +1240 -0
- package/test/worker/workflow-builder.test.ts +1067 -0
- package/test/worker.test.ts +608 -0
- package/test/workflow-builder.test.ts +1670 -0
- package/test/workflow-cron.test.ts +256 -0
- package/test/workflow-state-adapter.test.ts +923 -0
- package/test/workflow.test.ts +25 -22
- package/tsconfig.json +3 -1
- package/vitest.config.ts +38 -1
- package/vitest.workers.config.ts +44 -0
- package/wrangler.jsonc +22 -0
- package/.turbo/turbo-test.log +0 -7
- package/src/context.js +0 -83
- package/src/every.js +0 -267
- package/src/index.js +0 -71
- package/src/on.js +0 -79
- package/src/send.js +0 -111
- package/src/types.js +0 -4
- package/src/workflow.js +0 -455
- package/test/context.test.js +0 -116
- package/test/every.test.js +0 -282
- package/test/on.test.js +0 -80
- package/test/send.test.js +0 -89
- package/test/workflow.test.js +0 -224
- package/vitest.config.js +0 -7
package/src/index.js
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ai-workflows - Event-driven workflows with $ context
|
|
3
|
-
*
|
|
4
|
-
* @example
|
|
5
|
-
* ```ts
|
|
6
|
-
* import { Workflow } from 'ai-workflows'
|
|
7
|
-
*
|
|
8
|
-
* // Create a workflow with $ context
|
|
9
|
-
* const workflow = Workflow($ => {
|
|
10
|
-
* // Register event handlers
|
|
11
|
-
* $.on.Customer.created(async (customer, $) => {
|
|
12
|
-
* $.log('New customer:', customer.name)
|
|
13
|
-
* await $.send('Email.welcome', { to: customer.email })
|
|
14
|
-
* })
|
|
15
|
-
*
|
|
16
|
-
* $.on.Order.completed(async (order, $) => {
|
|
17
|
-
* $.log('Order completed:', order.id)
|
|
18
|
-
* })
|
|
19
|
-
*
|
|
20
|
-
* // Register scheduled tasks
|
|
21
|
-
* $.every.hour(async ($) => {
|
|
22
|
-
* $.log('Hourly check')
|
|
23
|
-
* })
|
|
24
|
-
*
|
|
25
|
-
* $.every.Monday.at9am(async ($) => {
|
|
26
|
-
* $.log('Weekly standup reminder')
|
|
27
|
-
* })
|
|
28
|
-
*
|
|
29
|
-
* $.every.minutes(30)(async ($) => {
|
|
30
|
-
* $.log('Every 30 minutes')
|
|
31
|
-
* })
|
|
32
|
-
*
|
|
33
|
-
* // Natural language scheduling
|
|
34
|
-
* $.every('first Monday of the month', async ($) => {
|
|
35
|
-
* $.log('Monthly report')
|
|
36
|
-
* })
|
|
37
|
-
* })
|
|
38
|
-
*
|
|
39
|
-
* // Start the workflow
|
|
40
|
-
* await workflow.start()
|
|
41
|
-
*
|
|
42
|
-
* // Emit events
|
|
43
|
-
* await workflow.send('Customer.created', { name: 'John', email: 'john@example.com' })
|
|
44
|
-
* ```
|
|
45
|
-
*
|
|
46
|
-
* @example
|
|
47
|
-
* // Alternative: Use standalone on/every for global registration
|
|
48
|
-
* ```ts
|
|
49
|
-
* import { on, every, send } from 'ai-workflows'
|
|
50
|
-
*
|
|
51
|
-
* on.Customer.created(async (customer, $) => {
|
|
52
|
-
* await $.send('Email.welcome', { to: customer.email })
|
|
53
|
-
* })
|
|
54
|
-
*
|
|
55
|
-
* every.hour(async ($) => {
|
|
56
|
-
* $.log('Hourly task')
|
|
57
|
-
* })
|
|
58
|
-
*
|
|
59
|
-
* await send('Customer.created', { name: 'John' })
|
|
60
|
-
* ```
|
|
61
|
-
*/
|
|
62
|
-
// Main Workflow API
|
|
63
|
-
export { Workflow, createTestContext, parseEvent } from './workflow.js';
|
|
64
|
-
// Standalone event handling (for global registration)
|
|
65
|
-
export { on, registerEventHandler, getEventHandlers, clearEventHandlers } from './on.js';
|
|
66
|
-
// Standalone scheduling (for global registration)
|
|
67
|
-
export { every, registerScheduleHandler, getScheduleHandlers, clearScheduleHandlers, setCronConverter, toCron, intervalToMs, formatInterval, } from './every.js';
|
|
68
|
-
// Event emission
|
|
69
|
-
export { send, getEventBus } from './send.js';
|
|
70
|
-
// Context
|
|
71
|
-
export { createWorkflowContext, createIsolatedContext } from './context.js';
|
package/src/on.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event handler registration using on.Noun.event syntax
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* on.Customer.created(customer => { ... })
|
|
6
|
-
* on.Order.completed(order => { ... })
|
|
7
|
-
* on.Payment.failed(payment => { ... })
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Registry of event handlers
|
|
11
|
-
*/
|
|
12
|
-
const eventRegistry = [];
|
|
13
|
-
/**
|
|
14
|
-
* Get all registered event handlers
|
|
15
|
-
*/
|
|
16
|
-
export function getEventHandlers() {
|
|
17
|
-
return [...eventRegistry];
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Clear all registered event handlers
|
|
21
|
-
*/
|
|
22
|
-
export function clearEventHandlers() {
|
|
23
|
-
eventRegistry.length = 0;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Register an event handler directly
|
|
27
|
-
*/
|
|
28
|
-
export function registerEventHandler(noun, event, handler) {
|
|
29
|
-
eventRegistry.push({
|
|
30
|
-
noun,
|
|
31
|
-
event,
|
|
32
|
-
handler,
|
|
33
|
-
source: handler.toString(),
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Create the `on` proxy
|
|
38
|
-
*
|
|
39
|
-
* This creates a proxy that allows:
|
|
40
|
-
* on.Customer.created(handler)
|
|
41
|
-
* on.Order.shipped(handler)
|
|
42
|
-
*
|
|
43
|
-
* The first property access captures the noun (Customer, Order)
|
|
44
|
-
* The second property access captures the event (created, shipped)
|
|
45
|
-
* The function call registers the handler
|
|
46
|
-
*/
|
|
47
|
-
function createOnProxy() {
|
|
48
|
-
return new Proxy({}, {
|
|
49
|
-
get(_target, noun) {
|
|
50
|
-
// Return a proxy for the event level
|
|
51
|
-
return new Proxy({}, {
|
|
52
|
-
get(_eventTarget, event) {
|
|
53
|
-
// Return a function that registers the handler
|
|
54
|
-
return (handler) => {
|
|
55
|
-
registerEventHandler(noun, event, handler);
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* The `on` object for registering event handlers
|
|
64
|
-
*
|
|
65
|
-
* @example
|
|
66
|
-
* ```ts
|
|
67
|
-
* import { on } from 'ai-workflows'
|
|
68
|
-
*
|
|
69
|
-
* on.Customer.created(async (customer, $) => {
|
|
70
|
-
* $.log('Customer created:', customer.name)
|
|
71
|
-
* await $.send('Email.welcome', { to: customer.email })
|
|
72
|
-
* })
|
|
73
|
-
*
|
|
74
|
-
* on.Order.completed(async (order, $) => {
|
|
75
|
-
* $.log('Order completed:', order.id)
|
|
76
|
-
* })
|
|
77
|
-
* ```
|
|
78
|
-
*/
|
|
79
|
-
export const on = createOnProxy();
|
package/src/send.js
DELETED
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event emission using send('Noun.event', data)
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* send('Customer.created', customer)
|
|
6
|
-
* send('Order.completed', order)
|
|
7
|
-
*/
|
|
8
|
-
import { getEventHandlers } from './on.js';
|
|
9
|
-
import { createWorkflowContext } from './context.js';
|
|
10
|
-
/**
|
|
11
|
-
* Event bus for managing event delivery
|
|
12
|
-
*/
|
|
13
|
-
class EventBus {
|
|
14
|
-
pending = [];
|
|
15
|
-
processing = false;
|
|
16
|
-
/**
|
|
17
|
-
* Emit an event
|
|
18
|
-
*/
|
|
19
|
-
async emit(event, data) {
|
|
20
|
-
this.pending.push({ event, data });
|
|
21
|
-
if (!this.processing) {
|
|
22
|
-
await this.process();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Process pending events
|
|
27
|
-
*/
|
|
28
|
-
async process() {
|
|
29
|
-
this.processing = true;
|
|
30
|
-
while (this.pending.length > 0) {
|
|
31
|
-
const item = this.pending.shift();
|
|
32
|
-
await this.deliver(item.event, item.data);
|
|
33
|
-
}
|
|
34
|
-
this.processing = false;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Deliver an event to matching handlers
|
|
38
|
-
*/
|
|
39
|
-
async deliver(event, data) {
|
|
40
|
-
const parsed = parseEvent(event);
|
|
41
|
-
if (!parsed) {
|
|
42
|
-
console.warn(`Invalid event format: ${event}. Expected Noun.event`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const handlers = getEventHandlers();
|
|
46
|
-
const matching = handlers.filter(h => h.noun === parsed.noun && h.event === parsed.event);
|
|
47
|
-
if (matching.length === 0) {
|
|
48
|
-
// No handlers registered - that's okay, event is just not handled
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
// Create workflow context for handlers
|
|
52
|
-
const ctx = createWorkflowContext(this);
|
|
53
|
-
// Execute all matching handlers
|
|
54
|
-
await Promise.all(matching.map(async ({ handler }) => {
|
|
55
|
-
try {
|
|
56
|
-
await handler(data, ctx);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
console.error(`Error in handler for ${event}:`, error);
|
|
60
|
-
}
|
|
61
|
-
}));
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Parse event string into noun and event
|
|
66
|
-
*/
|
|
67
|
-
export function parseEvent(event) {
|
|
68
|
-
const parts = event.split('.');
|
|
69
|
-
if (parts.length !== 2) {
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
const [noun, eventName] = parts;
|
|
73
|
-
if (!noun || !eventName) {
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
return { noun, event: eventName };
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Global event bus instance
|
|
80
|
-
*/
|
|
81
|
-
const globalEventBus = new EventBus();
|
|
82
|
-
/**
|
|
83
|
-
* Send an event
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* ```ts
|
|
87
|
-
* import { send } from 'ai-workflows'
|
|
88
|
-
*
|
|
89
|
-
* // Emit a customer created event
|
|
90
|
-
* await send('Customer.created', {
|
|
91
|
-
* id: '123',
|
|
92
|
-
* name: 'John Doe',
|
|
93
|
-
* email: 'john@example.com'
|
|
94
|
-
* })
|
|
95
|
-
*
|
|
96
|
-
* // Emit an order completed event
|
|
97
|
-
* await send('Order.completed', {
|
|
98
|
-
* id: 'order-456',
|
|
99
|
-
* total: 99.99
|
|
100
|
-
* })
|
|
101
|
-
* ```
|
|
102
|
-
*/
|
|
103
|
-
export async function send(event, data) {
|
|
104
|
-
await globalEventBus.emit(event, data);
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Get the global event bus (for testing/internal use)
|
|
108
|
-
*/
|
|
109
|
-
export function getEventBus() {
|
|
110
|
-
return globalEventBus;
|
|
111
|
-
}
|
package/src/types.js
DELETED