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
|
@@ -0,0 +1,552 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DurableWorkflow - Persistent workflow implementation using digital-objects
|
|
3
|
+
*
|
|
4
|
+
* Provides durable, recoverable workflows with:
|
|
5
|
+
* - Workflow state stored as Things
|
|
6
|
+
* - History and events stored as Actions
|
|
7
|
+
* - Automatic state recovery on restart
|
|
8
|
+
* - Graph-based dependency tracking
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import { createMemoryProvider } from 'digital-objects'
|
|
13
|
+
* import { DurableWorkflow } from 'ai-workflows'
|
|
14
|
+
*
|
|
15
|
+
* const provider = createMemoryProvider()
|
|
16
|
+
* const workflow = new DurableWorkflow(provider)
|
|
17
|
+
*
|
|
18
|
+
* await workflow.initialize('my-workflow', $ => {
|
|
19
|
+
* $.on.Order.created(async (order, $) => {
|
|
20
|
+
* await $.send('Invoice.generate', { orderId: order.id })
|
|
21
|
+
* })
|
|
22
|
+
* })
|
|
23
|
+
*
|
|
24
|
+
* await workflow.start()
|
|
25
|
+
* await workflow.send('Order.created', { id: 'order-1', total: 100 })
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @packageDocumentation
|
|
29
|
+
*/
|
|
30
|
+
import { PLURAL_UNITS, isPluralUnitKey } from './types.js';
|
|
31
|
+
import { createDigitalObjectsAdapter, } from './digital-objects-adapter.js';
|
|
32
|
+
import { parseEvent } from './workflow.js';
|
|
33
|
+
import { registerTimer, clearTimersForWorkflow, getTimerIdsForWorkflow, registerProcessCleanup, } from './timer-registry.js';
|
|
34
|
+
import { getLogger } from './logger.js';
|
|
35
|
+
/**
|
|
36
|
+
* Well-known cron patterns for common schedules
|
|
37
|
+
*/
|
|
38
|
+
const KNOWN_PATTERNS = {
|
|
39
|
+
second: '* * * * * *',
|
|
40
|
+
minute: '* * * * *',
|
|
41
|
+
hour: '0 * * * *',
|
|
42
|
+
day: '0 0 * * *',
|
|
43
|
+
week: '0 0 * * 0',
|
|
44
|
+
month: '0 0 1 * *',
|
|
45
|
+
year: '0 0 1 1 *',
|
|
46
|
+
Monday: '0 0 * * 1',
|
|
47
|
+
Tuesday: '0 0 * * 2',
|
|
48
|
+
Wednesday: '0 0 * * 3',
|
|
49
|
+
Thursday: '0 0 * * 4',
|
|
50
|
+
Friday: '0 0 * * 5',
|
|
51
|
+
Saturday: '0 0 * * 6',
|
|
52
|
+
Sunday: '0 0 * * 0',
|
|
53
|
+
weekday: '0 0 * * 1-5',
|
|
54
|
+
weekend: '0 0 * * 0,6',
|
|
55
|
+
midnight: '0 0 * * *',
|
|
56
|
+
noon: '0 12 * * *',
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Time suffixes for day-based schedules
|
|
60
|
+
*/
|
|
61
|
+
const TIME_PATTERNS = {
|
|
62
|
+
at6am: { hour: 6, minute: 0 },
|
|
63
|
+
at7am: { hour: 7, minute: 0 },
|
|
64
|
+
at8am: { hour: 8, minute: 0 },
|
|
65
|
+
at9am: { hour: 9, minute: 0 },
|
|
66
|
+
at10am: { hour: 10, minute: 0 },
|
|
67
|
+
at11am: { hour: 11, minute: 0 },
|
|
68
|
+
at12pm: { hour: 12, minute: 0 },
|
|
69
|
+
atnoon: { hour: 12, minute: 0 },
|
|
70
|
+
at1pm: { hour: 13, minute: 0 },
|
|
71
|
+
at2pm: { hour: 14, minute: 0 },
|
|
72
|
+
at3pm: { hour: 15, minute: 0 },
|
|
73
|
+
at4pm: { hour: 16, minute: 0 },
|
|
74
|
+
at5pm: { hour: 17, minute: 0 },
|
|
75
|
+
at6pm: { hour: 18, minute: 0 },
|
|
76
|
+
at7pm: { hour: 19, minute: 0 },
|
|
77
|
+
at8pm: { hour: 20, minute: 0 },
|
|
78
|
+
at9pm: { hour: 21, minute: 0 },
|
|
79
|
+
atmidnight: { hour: 0, minute: 0 },
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Combine a day pattern with a time pattern
|
|
83
|
+
*/
|
|
84
|
+
function combineWithTime(baseCron, time) {
|
|
85
|
+
const parts = baseCron.split(' ');
|
|
86
|
+
parts[0] = String(time.minute);
|
|
87
|
+
parts[1] = String(time.hour);
|
|
88
|
+
return parts.join(' ');
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* DurableWorkflow - A workflow implementation with persistent state
|
|
92
|
+
*
|
|
93
|
+
* Uses digital-objects as the backing store:
|
|
94
|
+
* - Workflow instance stored as a Thing
|
|
95
|
+
* - Events and history stored as Actions
|
|
96
|
+
* - State changes create audit trail
|
|
97
|
+
*/
|
|
98
|
+
export class DurableWorkflow {
|
|
99
|
+
provider;
|
|
100
|
+
db;
|
|
101
|
+
instanceId;
|
|
102
|
+
autoPersist;
|
|
103
|
+
initialized = false;
|
|
104
|
+
// Internal state (cached from digital-objects)
|
|
105
|
+
eventRegistry = [];
|
|
106
|
+
scheduleRegistry = [];
|
|
107
|
+
state = { context: {}, history: [] };
|
|
108
|
+
scheduleTimers = [];
|
|
109
|
+
// The $ context
|
|
110
|
+
$;
|
|
111
|
+
/**
|
|
112
|
+
* Create a new DurableWorkflow
|
|
113
|
+
*
|
|
114
|
+
* @param provider - The digital-objects provider (MemoryProvider, NS, etc.)
|
|
115
|
+
* @param options - Configuration options
|
|
116
|
+
*/
|
|
117
|
+
constructor(provider, options = {}) {
|
|
118
|
+
this.provider = provider;
|
|
119
|
+
this.instanceId =
|
|
120
|
+
options.instanceId ?? `workflow-${Date.now()}-${crypto.randomUUID().slice(0, 8)}`;
|
|
121
|
+
this.autoPersist = options.autoPersist ?? true;
|
|
122
|
+
if (options.context) {
|
|
123
|
+
this.state.context = { ...options.context };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Get the workflow instance ID
|
|
128
|
+
*/
|
|
129
|
+
get id() {
|
|
130
|
+
return this.instanceId;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get the current workflow state
|
|
134
|
+
*/
|
|
135
|
+
getState() {
|
|
136
|
+
return structuredClone({
|
|
137
|
+
...(this.state.current !== undefined && { current: this.state.current }),
|
|
138
|
+
context: this.state.context,
|
|
139
|
+
history: this.state.history,
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Initialize the workflow
|
|
144
|
+
*
|
|
145
|
+
* Creates or restores the workflow instance and runs the setup function
|
|
146
|
+
* to register event and schedule handlers.
|
|
147
|
+
*
|
|
148
|
+
* @param name - Workflow name for identification
|
|
149
|
+
* @param setup - Setup function that registers handlers using $
|
|
150
|
+
*/
|
|
151
|
+
async initialize(name, setup) {
|
|
152
|
+
if (this.initialized) {
|
|
153
|
+
throw new Error('Workflow already initialized');
|
|
154
|
+
}
|
|
155
|
+
// Create the database adapter
|
|
156
|
+
this.db = await createDigitalObjectsAdapter(this.provider, {
|
|
157
|
+
workflowId: this.instanceId,
|
|
158
|
+
});
|
|
159
|
+
// Check if workflow instance exists (for recovery)
|
|
160
|
+
const existing = await this.provider.get(this.instanceId);
|
|
161
|
+
if (existing) {
|
|
162
|
+
// Restore state from existing workflow
|
|
163
|
+
this.state.context = existing.data.context;
|
|
164
|
+
getLogger().log(`[durable-workflow] Restored workflow ${this.instanceId}`);
|
|
165
|
+
// Load history from actions
|
|
166
|
+
const actions = await this.db.listWorkflowActions(this.instanceId);
|
|
167
|
+
this.state.history = actions.map((a) => ({
|
|
168
|
+
timestamp: a.createdAt.getTime(),
|
|
169
|
+
type: a.data?.type ?? 'action',
|
|
170
|
+
name: a.data?.name ?? a.verb,
|
|
171
|
+
data: a.data?.data,
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
// Create new workflow instance
|
|
176
|
+
await this.provider.create('Workflow', {
|
|
177
|
+
name,
|
|
178
|
+
status: 'initializing',
|
|
179
|
+
context: this.state.context,
|
|
180
|
+
registeredEvents: [],
|
|
181
|
+
registeredSchedules: [],
|
|
182
|
+
version: 1,
|
|
183
|
+
createdAt: Date.now(),
|
|
184
|
+
updatedAt: Date.now(),
|
|
185
|
+
}, this.instanceId);
|
|
186
|
+
getLogger().log(`[durable-workflow] Created workflow ${this.instanceId}`);
|
|
187
|
+
}
|
|
188
|
+
// Create the $ context
|
|
189
|
+
this.$ = this.createContext();
|
|
190
|
+
// Run setup to capture handlers
|
|
191
|
+
setup(this.$);
|
|
192
|
+
// Update workflow with registered handlers
|
|
193
|
+
await this.provider.update(this.instanceId, {
|
|
194
|
+
status: 'running',
|
|
195
|
+
registeredEvents: this.eventRegistry.map((e) => `${e.noun}.${e.event}`),
|
|
196
|
+
registeredSchedules: this.scheduleRegistry.map((s) => s.interval.type === 'natural'
|
|
197
|
+
? s.interval.description
|
|
198
|
+
: s.interval.type === 'cron'
|
|
199
|
+
? s.interval.expression
|
|
200
|
+
: `${s.interval.type}:${s.interval.value ?? 1}`),
|
|
201
|
+
updatedAt: Date.now(),
|
|
202
|
+
});
|
|
203
|
+
this.initialized = true;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Start the workflow (begin processing schedules)
|
|
207
|
+
*/
|
|
208
|
+
async start() {
|
|
209
|
+
if (!this.initialized) {
|
|
210
|
+
throw new Error('Workflow not initialized. Call initialize() first.');
|
|
211
|
+
}
|
|
212
|
+
getLogger().log(`[durable-workflow] Starting with ${this.eventRegistry.length} event handlers and ${this.scheduleRegistry.length} schedules`);
|
|
213
|
+
// Register process cleanup
|
|
214
|
+
registerProcessCleanup();
|
|
215
|
+
// Start schedules
|
|
216
|
+
for (const schedule of this.scheduleRegistry) {
|
|
217
|
+
const { interval, handler } = schedule;
|
|
218
|
+
let ms = 0;
|
|
219
|
+
switch (interval.type) {
|
|
220
|
+
case 'second':
|
|
221
|
+
ms = (interval.value ?? 1) * 1000;
|
|
222
|
+
break;
|
|
223
|
+
case 'minute':
|
|
224
|
+
ms = (interval.value ?? 1) * 60 * 1000;
|
|
225
|
+
break;
|
|
226
|
+
case 'hour':
|
|
227
|
+
ms = (interval.value ?? 1) * 60 * 60 * 1000;
|
|
228
|
+
break;
|
|
229
|
+
case 'day':
|
|
230
|
+
ms = (interval.value ?? 1) * 24 * 60 * 60 * 1000;
|
|
231
|
+
break;
|
|
232
|
+
case 'week':
|
|
233
|
+
ms = (interval.value ?? 1) * 7 * 24 * 60 * 60 * 1000;
|
|
234
|
+
break;
|
|
235
|
+
case 'cron':
|
|
236
|
+
case 'natural':
|
|
237
|
+
throw new Error(`Cron scheduling not yet implemented: "${interval.type === 'cron' ? interval.expression : interval.description}". Use interval-based patterns instead.`);
|
|
238
|
+
}
|
|
239
|
+
if (ms > 0) {
|
|
240
|
+
const timer = setInterval(async () => {
|
|
241
|
+
try {
|
|
242
|
+
await this.addHistory('schedule', interval.natural ?? interval.type);
|
|
243
|
+
await handler(this.$);
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
getLogger().error('[durable-workflow] Schedule handler error:', error);
|
|
247
|
+
}
|
|
248
|
+
}, ms);
|
|
249
|
+
this.scheduleTimers.push(timer);
|
|
250
|
+
registerTimer(this.instanceId, timer);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
// Record start action
|
|
254
|
+
await this.addHistory('transition', 'workflow.started');
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Stop the workflow
|
|
258
|
+
*/
|
|
259
|
+
async stop() {
|
|
260
|
+
getLogger().log('[durable-workflow] Stopping');
|
|
261
|
+
this.cleanup();
|
|
262
|
+
await this.provider.update(this.instanceId, {
|
|
263
|
+
status: 'paused',
|
|
264
|
+
updatedAt: Date.now(),
|
|
265
|
+
});
|
|
266
|
+
await this.addHistory('transition', 'workflow.stopped');
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Send an event to the workflow
|
|
270
|
+
*/
|
|
271
|
+
async send(event, data) {
|
|
272
|
+
if (!this.initialized) {
|
|
273
|
+
throw new Error('Workflow not initialized');
|
|
274
|
+
}
|
|
275
|
+
const eventId = this.$.send(event, data);
|
|
276
|
+
// Deliver to handlers
|
|
277
|
+
await this.deliverEvent(event, { ...data, _eventId: eventId });
|
|
278
|
+
return eventId;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Destroy the workflow and clean up all resources
|
|
282
|
+
*/
|
|
283
|
+
async destroy() {
|
|
284
|
+
this.cleanup();
|
|
285
|
+
await this.provider.update(this.instanceId, {
|
|
286
|
+
status: 'completed',
|
|
287
|
+
updatedAt: Date.now(),
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Get the number of active timers
|
|
292
|
+
*/
|
|
293
|
+
get timerCount() {
|
|
294
|
+
return getTimerIdsForWorkflow(this.instanceId).length;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get timer IDs for this workflow
|
|
298
|
+
*/
|
|
299
|
+
getTimerIds() {
|
|
300
|
+
return getTimerIdsForWorkflow(this.instanceId);
|
|
301
|
+
}
|
|
302
|
+
// ==========================================================================
|
|
303
|
+
// Private methods
|
|
304
|
+
// ==========================================================================
|
|
305
|
+
/**
|
|
306
|
+
* Create the $ context
|
|
307
|
+
*/
|
|
308
|
+
createContext() {
|
|
309
|
+
const self = this;
|
|
310
|
+
return {
|
|
311
|
+
track(event, data) {
|
|
312
|
+
try {
|
|
313
|
+
self.addHistory('event', `track:${event}`, data).catch(() => { });
|
|
314
|
+
self.deliverEvent(event, data).catch(() => { });
|
|
315
|
+
}
|
|
316
|
+
catch {
|
|
317
|
+
// Silently swallow errors
|
|
318
|
+
}
|
|
319
|
+
},
|
|
320
|
+
send(event, data) {
|
|
321
|
+
const eventId = crypto.randomUUID();
|
|
322
|
+
self.addHistory('event', event, data).catch((err) => {
|
|
323
|
+
getLogger().error(`[durable-workflow] Failed to record event ${event}:`, err);
|
|
324
|
+
});
|
|
325
|
+
// Record to database (durable)
|
|
326
|
+
self.db.recordEvent(event, { ...data, _eventId: eventId }).catch((err) => {
|
|
327
|
+
getLogger().error(`[durable-workflow] Failed to persist event ${event}:`, err);
|
|
328
|
+
});
|
|
329
|
+
return eventId;
|
|
330
|
+
},
|
|
331
|
+
async do(event, data) {
|
|
332
|
+
await self.addHistory('action', `do:${event}`, data);
|
|
333
|
+
await self.db.recordEvent(event, data);
|
|
334
|
+
return self.executeEvent(event, data, true);
|
|
335
|
+
},
|
|
336
|
+
async try(event, data) {
|
|
337
|
+
await self.addHistory('action', `try:${event}`, data);
|
|
338
|
+
return self.executeEvent(event, data, false);
|
|
339
|
+
},
|
|
340
|
+
on: self.createOnProxy(),
|
|
341
|
+
every: self.createEveryProxy(),
|
|
342
|
+
state: self.state.context,
|
|
343
|
+
getState() {
|
|
344
|
+
return self.getState();
|
|
345
|
+
},
|
|
346
|
+
set(key, value) {
|
|
347
|
+
self.state.context[key] = value;
|
|
348
|
+
if (self.autoPersist) {
|
|
349
|
+
self.persistState().catch((err) => {
|
|
350
|
+
getLogger().error(`[durable-workflow] Failed to persist state:`, err);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
},
|
|
354
|
+
get(key) {
|
|
355
|
+
return self.state.context[key];
|
|
356
|
+
},
|
|
357
|
+
log(message, data) {
|
|
358
|
+
self.addHistory('action', 'log', { message, data }).catch(() => { });
|
|
359
|
+
getLogger().log(`[durable-workflow] ${message}`, data ?? '');
|
|
360
|
+
},
|
|
361
|
+
db: self.db,
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Create the $.on proxy
|
|
366
|
+
*/
|
|
367
|
+
createOnProxy() {
|
|
368
|
+
const self = this;
|
|
369
|
+
return new Proxy({}, {
|
|
370
|
+
get(_target, noun) {
|
|
371
|
+
return new Proxy({}, {
|
|
372
|
+
get(_eventTarget, event) {
|
|
373
|
+
return (handler) => {
|
|
374
|
+
self.eventRegistry.push({
|
|
375
|
+
noun,
|
|
376
|
+
event,
|
|
377
|
+
handler,
|
|
378
|
+
source: handler.toString(),
|
|
379
|
+
});
|
|
380
|
+
};
|
|
381
|
+
},
|
|
382
|
+
});
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Create the $.every proxy
|
|
388
|
+
*/
|
|
389
|
+
createEveryProxy() {
|
|
390
|
+
const self = this;
|
|
391
|
+
const handler = {
|
|
392
|
+
get(_target, prop) {
|
|
393
|
+
const pattern = KNOWN_PATTERNS[prop];
|
|
394
|
+
if (pattern) {
|
|
395
|
+
const result = (handlerFn) => {
|
|
396
|
+
self.scheduleRegistry.push({
|
|
397
|
+
interval: { type: 'cron', expression: pattern, natural: prop },
|
|
398
|
+
handler: handlerFn,
|
|
399
|
+
source: handlerFn.toString(),
|
|
400
|
+
});
|
|
401
|
+
};
|
|
402
|
+
return new Proxy(result, {
|
|
403
|
+
get(_t, timeKey) {
|
|
404
|
+
const time = TIME_PATTERNS[timeKey];
|
|
405
|
+
if (time) {
|
|
406
|
+
const cron = combineWithTime(pattern, time);
|
|
407
|
+
return (handlerFn) => {
|
|
408
|
+
self.scheduleRegistry.push({
|
|
409
|
+
interval: { type: 'cron', expression: cron, natural: `${prop}.${timeKey}` },
|
|
410
|
+
handler: handlerFn,
|
|
411
|
+
source: handlerFn.toString(),
|
|
412
|
+
});
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
return undefined;
|
|
416
|
+
},
|
|
417
|
+
apply(_t, _thisArg, args) {
|
|
418
|
+
self.scheduleRegistry.push({
|
|
419
|
+
interval: { type: 'cron', expression: pattern, natural: prop },
|
|
420
|
+
handler: args[0],
|
|
421
|
+
source: args[0].toString(),
|
|
422
|
+
});
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
// Plural units (seconds, minutes, hours, days, weeks)
|
|
427
|
+
if (isPluralUnitKey(prop)) {
|
|
428
|
+
const intervalType = PLURAL_UNITS[prop];
|
|
429
|
+
return (value) => (handlerFn) => {
|
|
430
|
+
self.scheduleRegistry.push({
|
|
431
|
+
interval: { type: intervalType, value, natural: `${value} ${prop}` },
|
|
432
|
+
handler: handlerFn,
|
|
433
|
+
source: handlerFn.toString(),
|
|
434
|
+
});
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
return undefined;
|
|
438
|
+
},
|
|
439
|
+
apply(_target, _thisArg, args) {
|
|
440
|
+
const [description, handlerFn] = args;
|
|
441
|
+
if (typeof description === 'string' && typeof handlerFn === 'function') {
|
|
442
|
+
self.scheduleRegistry.push({
|
|
443
|
+
interval: { type: 'natural', description },
|
|
444
|
+
handler: handlerFn,
|
|
445
|
+
source: handlerFn.toString(),
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
const target = function (_description, _handler) { };
|
|
451
|
+
return new Proxy(target, handler);
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* Add history entry (persisted as Action)
|
|
455
|
+
*/
|
|
456
|
+
async addHistory(type, name, data) {
|
|
457
|
+
const entry = {
|
|
458
|
+
timestamp: Date.now(),
|
|
459
|
+
type,
|
|
460
|
+
name,
|
|
461
|
+
data,
|
|
462
|
+
};
|
|
463
|
+
this.state.history.push(entry);
|
|
464
|
+
// Persist as Action
|
|
465
|
+
await this.provider.perform(type, this.instanceId, undefined, {
|
|
466
|
+
type,
|
|
467
|
+
name,
|
|
468
|
+
data,
|
|
469
|
+
});
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Persist current state to digital-objects
|
|
473
|
+
*/
|
|
474
|
+
async persistState() {
|
|
475
|
+
await this.provider.update(this.instanceId, {
|
|
476
|
+
context: this.state.context,
|
|
477
|
+
updatedAt: Date.now(),
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Deliver an event to matching handlers
|
|
482
|
+
*/
|
|
483
|
+
async deliverEvent(event, data) {
|
|
484
|
+
const parsed = parseEvent(event);
|
|
485
|
+
if (!parsed) {
|
|
486
|
+
getLogger().warn(`Invalid event format: ${event}. Expected Noun.event`);
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
const matching = this.eventRegistry.filter((h) => h.noun === parsed.noun && h.event === parsed.event);
|
|
490
|
+
if (matching.length === 0) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
await Promise.all(matching.map(async ({ handler }) => {
|
|
494
|
+
try {
|
|
495
|
+
await handler(data, this.$);
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
getLogger().error(`Error in handler for ${event}:`, error);
|
|
499
|
+
}
|
|
500
|
+
}));
|
|
501
|
+
}
|
|
502
|
+
/**
|
|
503
|
+
* Execute an event and wait for result
|
|
504
|
+
*/
|
|
505
|
+
async executeEvent(event, data, durable) {
|
|
506
|
+
const parsed = parseEvent(event);
|
|
507
|
+
if (!parsed) {
|
|
508
|
+
throw new Error(`Invalid event format: ${event}. Expected Noun.event`);
|
|
509
|
+
}
|
|
510
|
+
const matching = this.eventRegistry.filter((h) => h.noun === parsed.noun && h.event === parsed.event);
|
|
511
|
+
if (matching.length === 0) {
|
|
512
|
+
throw new Error(`No handler registered for ${event}`);
|
|
513
|
+
}
|
|
514
|
+
const { handler } = matching[0];
|
|
515
|
+
if (durable) {
|
|
516
|
+
await this.db.createAction({
|
|
517
|
+
actor: 'workflow',
|
|
518
|
+
object: event,
|
|
519
|
+
action: 'execute',
|
|
520
|
+
metadata: { data },
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
try {
|
|
524
|
+
const result = await handler(data, this.$);
|
|
525
|
+
return result;
|
|
526
|
+
}
|
|
527
|
+
catch (error) {
|
|
528
|
+
if (durable) {
|
|
529
|
+
getLogger().error(`[durable-workflow] Durable action failed for ${event}:`, error);
|
|
530
|
+
}
|
|
531
|
+
throw error;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Clean up timers
|
|
536
|
+
*/
|
|
537
|
+
cleanup() {
|
|
538
|
+
clearTimersForWorkflow(this.instanceId);
|
|
539
|
+
this.scheduleTimers = [];
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Factory function to create a DurableWorkflow
|
|
544
|
+
*
|
|
545
|
+
* @param provider - The digital-objects provider
|
|
546
|
+
* @param options - Configuration options
|
|
547
|
+
* @returns A new DurableWorkflow instance
|
|
548
|
+
*/
|
|
549
|
+
export function createDurableWorkflow(provider, options) {
|
|
550
|
+
return new DurableWorkflow(provider, options);
|
|
551
|
+
}
|
|
552
|
+
//# sourceMappingURL=durable-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"durable-workflow.js","sourceRoot":"","sources":["../src/durable-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAiBH,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAC1D,OAAO,EACL,2BAA2B,GAG5B,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC;;GAEG;AACH,MAAM,cAAc,GAA2B;IAC7C,MAAM,EAAE,aAAa;IACrB,MAAM,EAAE,WAAW;IACnB,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,WAAW;IACjB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,WAAW;IACpB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,WAAW;IACrB,MAAM,EAAE,WAAW;IACnB,QAAQ,EAAE,WAAW;IACrB,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,aAAa;IACtB,OAAO,EAAE,aAAa;IACtB,QAAQ,EAAE,WAAW;IACrB,IAAI,EAAE,YAAY;CACnB,CAAA;AAED;;GAEG;AACH,MAAM,aAAa,GAAqD;IACtE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IAC7B,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;IAC7B,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC/B,MAAM,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC/B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE;IAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE;CACnC,CAAA;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,QAAgB,EAAE,IAAsC;IAC/E,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IACjC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;IAC9B,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC5B,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC;AAyCD;;;;;;;GAOG;AACH,MAAM,OAAO,eAAe;IAClB,QAAQ,CAAwB;IAChC,EAAE,CAAgC;IAClC,UAAU,CAAQ;IAClB,WAAW,CAAS;IACpB,WAAW,GAAG,KAAK,CAAA;IAE3B,+CAA+C;IACvC,aAAa,GAAwB,EAAE,CAAA;IACvC,gBAAgB,GAA2B,EAAE,CAAA;IAC7C,KAAK,GAAkB,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IACnD,cAAc,GAAqB,EAAE,CAAA;IAE7C,gBAAgB;IACR,CAAC,CAAkB;IAE3B;;;;;OAKG;IACH,YAAY,QAAgC,EAAE,UAAkC,EAAE;QAChF,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;QACxB,IAAI,CAAC,UAAU;YACb,OAAO,CAAC,UAAU,IAAI,YAAY,IAAI,CAAC,GAAG,EAAE,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;QACnF,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAA;QAE9C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAA;QAC7C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,EAAE;QACJ,OAAO,IAAI,CAAC,UAAU,CAAA;IACxB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,eAAe,CAAC;YACrB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YACxE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;YAC3B,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;SAC5B,CAAC,CAAA;IACJ,CAAC;IAED;;;;;;;;OAQG;IACH,KAAK,CAAC,UAAU,CAAC,IAAY,EAAE,KAAmC;QAChE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACjD,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,EAAE,GAAG,MAAM,2BAA2B,CAAC,IAAI,CAAC,QAAQ,EAAE;YACzD,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAA;QAEF,mDAAmD;QACnD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAuB,IAAI,CAAC,UAAU,CAAC,CAAA;QAE/E,IAAI,QAAQ,EAAE,CAAC;YACb,uCAAuC;YACvC,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAA;YAC1C,SAAS,EAAE,CAAC,GAAG,CAAC,wCAAwC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;YAE1E,4BAA4B;YAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,mBAAmB,CAAsB,IAAI,CAAC,UAAU,CAAC,CAAA;YACvF,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACvC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE;gBAChC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,QAAQ;gBAC9B,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,IAAI;gBAC5B,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI;aACnB,CAAC,CAAC,CAAA;QACL,CAAC;aAAM,CAAC;YACN,+BAA+B;YAC/B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CACxB,UAAU,EACV;gBACE,IAAI;gBACJ,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;gBAC3B,gBAAgB,EAAE,EAAE;gBACpB,mBAAmB,EAAE,EAAE;gBACvB,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;gBACrB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,EACD,IAAI,CAAC,UAAU,CAChB,CAAA;YAED,SAAS,EAAE,CAAC,GAAG,CAAC,uCAAuC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAA;QAC3E,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,aAAa,EAAE,CAAA;QAE7B,gCAAgC;QAChC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAEb,2CAA2C;QAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAuB,IAAI,CAAC,UAAU,EAAE;YAChE,MAAM,EAAE,SAAS;YACjB,gBAAgB,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;YACvE,mBAAmB,EAAE,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnD,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS;gBAC3B,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW;gBACxB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,KAAK,MAAM;oBAC5B,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU;oBACvB,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,EAAE,CAClD;YACD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAA;QAEF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAA;IACzB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAA;QACvE,CAAC;QAED,SAAS,EAAE,CAAC,GAAG,CACb,oCAAoC,IAAI,CAAC,aAAa,CAAC,MAAM,uBAAuB,IAAI,CAAC,gBAAgB,CAAC,MAAM,YAAY,CAC7H,CAAA;QAED,2BAA2B;QAC3B,sBAAsB,EAAE,CAAA;QAExB,kBAAkB;QAClB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC7C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAA;YAEtC,IAAI,EAAE,GAAG,CAAC,CAAA;YACV,QAAQ,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACtB,KAAK,QAAQ;oBACX,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,IAAI,CAAA;oBACjC,MAAK;gBACP,KAAK,QAAQ;oBACX,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,IAAI,CAAA;oBACtC,MAAK;gBACP,KAAK,MAAM;oBACT,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;oBAC3C,MAAK;gBACP,KAAK,KAAK;oBACR,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;oBAChD,MAAK;gBACP,KAAK,MAAM;oBACT,EAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;oBACpD,MAAK;gBACP,KAAK,MAAM,CAAC;gBACZ,KAAK,SAAS;oBACZ,MAAM,IAAI,KAAK,CACb,yCACE,QAAQ,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,WAC5D,yCAAyC,CAC1C,CAAA;YACL,CAAC;YAED,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;gBACX,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;oBACnC,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAA;wBACpE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBACvB,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACf,SAAS,EAAE,CAAC,KAAK,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAA;oBACxE,CAAC;gBACH,CAAC,EAAE,EAAE,CAAC,CAAA;gBACN,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;gBAC/B,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;YACvC,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAA;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,SAAS,EAAE,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;QAC9C,IAAI,CAAC,OAAO,EAAE,CAAA;QAEd,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAuB,IAAI,CAAC,UAAU,EAAE;YAChE,MAAM,EAAE,QAAQ;YAChB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAA;QAEF,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,kBAAkB,CAAC,CAAA;IACzD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAc,KAAa,EAAE,IAAO;QAC5C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;QAC7C,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAExC,sBAAsB;QACtB,MAAM,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,EAAE,GAAI,IAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAA;QAE1E,OAAO,OAAO,CAAA;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,OAAO,EAAE,CAAA;QAEd,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAuB,IAAI,CAAC,UAAU,EAAE;YAChE,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACH,IAAI,UAAU;QACZ,OAAO,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CAAA;IACvD,CAAC;IAED;;OAEG;IACH,WAAW;QACT,OAAO,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IAChD,CAAC;IAED,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAE7E;;OAEG;IACK,aAAa;QACnB,MAAM,IAAI,GAAG,IAAI,CAAA;QAEjB,OAAO;YACL,KAAK,CAAC,KAAa,EAAE,IAAa;gBAChC,IAAI,CAAC;oBACH,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;oBAChE,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBAChD,CAAC;gBAAC,MAAM,CAAC;oBACP,0BAA0B;gBAC5B,CAAC;YACH,CAAC;YAED,IAAI,CAAc,KAAa,EAAE,IAAO;gBACtC,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,EAAE,CAAA;gBACnC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBAClD,SAAS,EAAE,CAAC,KAAK,CAAC,6CAA6C,KAAK,GAAG,EAAE,GAAG,CAAC,CAAA;gBAC/E,CAAC,CAAC,CAAA;gBAEF,+BAA+B;gBAC/B,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAE,GAAI,IAAe,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBACnF,SAAS,EAAE,CAAC,KAAK,CAAC,8CAA8C,KAAK,GAAG,EAAE,GAAG,CAAC,CAAA;gBAChF,CAAC,CAAC,CAAA;gBAEF,OAAO,OAAO,CAAA;YAChB,CAAC;YAED,KAAK,CAAC,EAAE,CAAqC,KAAa,EAAE,IAAW;gBACrE,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,MAAM,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;gBACpD,MAAM,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;gBACtC,OAAO,IAAI,CAAC,YAAY,CAAU,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;YACtD,CAAC;YAED,KAAK,CAAC,GAAG,CAAqC,KAAa,EAAE,IAAW;gBACtE,MAAM,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,KAAK,EAAE,EAAE,IAAI,CAAC,CAAA;gBACrD,OAAO,IAAI,CAAC,YAAY,CAAU,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;YACvD,CAAC;YAED,EAAE,EAAE,IAAI,CAAC,aAAa,EAAE;YACxB,KAAK,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAE9B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;YAEzB,QAAQ;gBACN,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAA;YACxB,CAAC;YAED,GAAG,CAAc,GAAW,EAAE,KAAQ;gBACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;gBAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACrB,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;wBAChC,SAAS,EAAE,CAAC,KAAK,CAAC,6CAA6C,EAAE,GAAG,CAAC,CAAA;oBACvE,CAAC,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;YAED,GAAG,CAAc,GAAW;gBAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAkB,CAAA;YACjD,CAAC;YAED,GAAG,CAAC,OAAe,EAAE,IAAc;gBACjC,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAA;gBACnE,SAAS,EAAE,CAAC,GAAG,CAAC,sBAAsB,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAA;YAC9D,CAAC;YAED,EAAE,EAAE,IAAI,CAAC,EAAE;SACZ,CAAA;IACH,CAAC;IAED;;OAEG;IACK,aAAa;QACnB,MAAM,IAAI,GAAG,IAAI,CAAA;QACjB,OAAO,IAAI,KAAK,CAAC,EAAa,EAAE;YAC9B,GAAG,CAAC,OAAO,EAAE,IAAY;gBACvB,OAAO,IAAI,KAAK,CACd,EAAE,EACF;oBACE,GAAG,CAAC,YAAY,EAAE,KAAa;wBAC7B,OAAO,CAAC,OAAqB,EAAE,EAAE;4BAC/B,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gCACtB,IAAI;gCACJ,KAAK;gCACL,OAAO;gCACP,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE;6BAC3B,CAAC,CAAA;wBACJ,CAAC,CAAA;oBACH,CAAC;iBACF,CACF,CAAA;YACH,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACK,gBAAgB;QACtB,MAAM,IAAI,GAAG,IAAI,CAAA;QAEjB,MAAM,OAAO,GAAG;YACd,GAAG,CAAC,OAAgB,EAAE,IAAY;gBAChC,MAAM,OAAO,GAAG,cAAc,CAAC,IAAI,CAAC,CAAA;gBACpC,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,MAAM,GAAG,CAAC,SAA0B,EAAE,EAAE;wBAC5C,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;4BACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;4BAC9D,OAAO,EAAE,SAAS;4BAClB,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE;yBAC7B,CAAC,CAAA;oBACJ,CAAC,CAAA;oBACD,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE;wBACvB,GAAG,CAAC,EAAE,EAAE,OAAe;4BACrB,MAAM,IAAI,GAAG,aAAa,CAAC,OAAO,CAAC,CAAA;4BACnC,IAAI,IAAI,EAAE,CAAC;gCACT,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;gCAC3C,OAAO,CAAC,SAA0B,EAAE,EAAE;oCACpC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;wCACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,IAAI,OAAO,EAAE,EAAE;wCAC3E,OAAO,EAAE,SAAS;wCAClB,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE;qCAC7B,CAAC,CAAA;gCACJ,CAAC,CAAA;4BACH,CAAC;4BACD,OAAO,SAAS,CAAA;wBAClB,CAAC;wBACD,KAAK,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI;4BACtB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;gCACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE;gCAC9D,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;gCAChB,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE;6BAC3B,CAAC,CAAA;wBACJ,CAAC;qBACF,CAAC,CAAA;gBACJ,CAAC;gBAED,sDAAsD;gBACtD,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,MAAM,YAAY,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;oBACvC,OAAO,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,SAA0B,EAAE,EAAE;wBACvD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;4BACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,KAAK,IAAI,IAAI,EAAE,EAAE;4BACpE,OAAO,EAAE,SAAS;4BAClB,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE;yBAC7B,CAAC,CAAA;oBACJ,CAAC,CAAA;gBACH,CAAC;gBAED,OAAO,SAAS,CAAA;YAClB,CAAC;YAED,KAAK,CAAC,OAAgB,EAAE,QAAiB,EAAE,IAAe;gBACxD,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,IAAiC,CAAA;gBAClE,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;oBACvE,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC;wBACzB,QAAQ,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE;wBAC1C,OAAO,EAAE,SAAS;wBAClB,MAAM,EAAE,SAAS,CAAC,QAAQ,EAAE;qBAC7B,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;SACF,CAAA;QAED,MAAM,MAAM,GAAqB,UAAU,YAAoB,EAAE,QAAyB,IAAG,CAAC,CAAA;QAC9F,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,CAA0B,CAAA;IAC5D,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CACtB,IAAkC,EAClC,IAAY,EACZ,IAAc;QAEd,MAAM,KAAK,GAAyB;YAClC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI;YACJ,IAAI;YACJ,IAAI;SACL,CAAA;QACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QAE9B,oBAAoB;QACpB,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAsB,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE;YACjF,IAAI;YACJ,IAAI;YACJ,IAAI;SACL,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY;QACxB,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAuB,IAAI,CAAC,UAAU,EAAE;YAChE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO;YAC3B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAA;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CAAC,KAAa,EAAE,IAAa;QACrD,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,SAAS,EAAE,CAAC,IAAI,CAAC,yBAAyB,KAAK,uBAAuB,CAAC,CAAA;YACvE,OAAM;QACR,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAC1D,CAAA;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAM;QACR,CAAC;QAED,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YACjC,IAAI,CAAC;gBACH,MAAM,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,EAAE,CAAC,KAAK,CAAC,wBAAwB,KAAK,GAAG,EAAE,KAAK,CAAC,CAAA;YAC5D,CAAC;QACH,CAAC,CAAC,CACH,CAAA;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,YAAY,CACxB,KAAa,EACb,IAAa,EACb,OAAgB;QAEhB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAA;QAChC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,uBAAuB,CAAC,CAAA;QACxE,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CACxC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAC1D,CAAA;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,EAAE,CAAC,CAAA;QACvD,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAE,CAAA;QAEhC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC;gBACzB,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,SAAS;gBACjB,QAAQ,EAAE,EAAE,IAAI,EAAE;aACnB,CAAC,CAAA;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAA;YAC1C,OAAO,MAAiB,CAAA;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,OAAO,EAAE,CAAC;gBACZ,SAAS,EAAE,CAAC,KAAK,CAAC,gDAAgD,KAAK,GAAG,EAAE,KAAK,CAAC,CAAA;YACpF,CAAC;YACD,MAAM,KAAK,CAAA;QACb,CAAC;IACH,CAAC;IAED;;OAEG;IACK,OAAO;QACb,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;QACvC,IAAI,CAAC,cAAc,GAAG,EAAE,CAAA;IAC1B,CAAC;CACF;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAgC,EAChC,OAAgC;IAEhC,OAAO,IAAI,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;AAC/C,CAAC"}
|
package/dist/every.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* every('hour during business hours', $ => { ... })
|
|
9
9
|
* every('first Monday of the month at 9am', $ => { ... })
|
|
10
10
|
*/
|
|
11
|
-
import type { ScheduleHandler, ScheduleRegistration, ScheduleInterval } from './types.js';
|
|
11
|
+
import type { ScheduleHandler, ScheduleRegistration, ScheduleInterval, EveryProxy } from './types.js';
|
|
12
12
|
/**
|
|
13
13
|
* Get all registered schedule handlers
|
|
14
14
|
*/
|
|
@@ -29,6 +29,35 @@ export declare function setCronConverter(converter: (description: string) => Pro
|
|
|
29
29
|
* Convert natural language to cron expression
|
|
30
30
|
*/
|
|
31
31
|
export declare function toCron(description: string): Promise<string>;
|
|
32
|
+
/**
|
|
33
|
+
* Schedule registration callback type
|
|
34
|
+
* Used by createTypedEveryProxy to customize handler registration
|
|
35
|
+
*/
|
|
36
|
+
export type EveryProxyRegistrationCallback = (interval: ScheduleInterval, handler: ScheduleHandler) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Create a typed EveryProxy with proper TypeScript generics
|
|
39
|
+
*
|
|
40
|
+
* This factory function creates a callable proxy that supports:
|
|
41
|
+
* - Direct calls: every('natural language', handler)
|
|
42
|
+
* - Simple patterns: every.hour(handler)
|
|
43
|
+
* - Day + time: every.Monday.at9am(handler)
|
|
44
|
+
* - Intervals: every.minutes(30)(handler)
|
|
45
|
+
*
|
|
46
|
+
* @param registerCallback - Function called when a handler is registered
|
|
47
|
+
* @returns A properly typed EveryProxy
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```ts
|
|
51
|
+
* // Create proxy with custom registration
|
|
52
|
+
* const myEvery = createTypedEveryProxy((interval, handler) => {
|
|
53
|
+
* myRegistry.push({ interval, handler })
|
|
54
|
+
* })
|
|
55
|
+
*
|
|
56
|
+
* myEvery.hour(handler) // Properly typed!
|
|
57
|
+
* myEvery.Monday.at9am(handler) // Chained access typed!
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function createTypedEveryProxy(registerCallback: EveryProxyRegistrationCallback): EveryProxy;
|
|
32
61
|
/**
|
|
33
62
|
* The `every` function/object for registering scheduled handlers
|
|
34
63
|
*
|
|
@@ -55,7 +84,7 @@ export declare function toCron(description: string): Promise<string>;
|
|
|
55
84
|
* every('every 15 minutes between 9am and 5pm on weekdays', $ => { ... })
|
|
56
85
|
* ```
|
|
57
86
|
*/
|
|
58
|
-
export declare const every:
|
|
87
|
+
export declare const every: EveryProxy;
|
|
59
88
|
/**
|
|
60
89
|
* Convert interval to milliseconds (for simulation/testing)
|
|
61
90
|
*/
|
package/dist/every.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"every.d.ts","sourceRoot":"","sources":["../src/every.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"every.d.ts","sourceRoot":"","sources":["../src/every.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAEhB,UAAU,EAGX,MAAM,YAAY,CAAA;AAQnB;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,oBAAoB,EAAE,CAE5D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,eAAe,GACvB,IAAI,CAMN;AA6ED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAE1F;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBjE;AAED;;;GAGG;AACH,MAAM,MAAM,8BAA8B,GAAG,CAC3C,QAAQ,EAAE,gBAAgB,EAC1B,OAAO,EAAE,eAAe,KACrB,IAAI,CAAA;AAET;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,gBAAgB,EAAE,8BAA8B,GAAG,UAAU,CA8ElG;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,KAAK,YAAqB,CAAA;AAEvC;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CAiB/D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,gBAAgB,GAAG,MAAM,CA+BjE"}
|