@positronic/cloudflare 0.0.18 → 0.0.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/api.js +255 -1
- package/dist/src/brain-runner-do.js +176 -5
- package/dist/src/dev-server.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/monitor-do.js +37 -5
- package/dist/src/webhook-adapter.js +246 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/brain-runner-do.d.ts +8 -0
- package/dist/types/brain-runner-do.d.ts.map +1 -1
- package/dist/types/dev-server.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/monitor-do.d.ts +16 -1
- package/dist/types/monitor-do.d.ts.map +1 -1
- package/dist/types/webhook-adapter.d.ts +14 -0
- package/dist/types/webhook-adapter.d.ts.map +1 -0
- package/package.json +4 -4
package/dist/src/api.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
function _array_like_to_array(arr, len) {
|
|
2
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
4
|
+
return arr2;
|
|
5
|
+
}
|
|
6
|
+
function _array_with_holes(arr) {
|
|
7
|
+
if (Array.isArray(arr)) return arr;
|
|
8
|
+
}
|
|
1
9
|
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
10
|
try {
|
|
3
11
|
var info = gen[key](arg);
|
|
@@ -47,6 +55,33 @@ function _instanceof(left, right) {
|
|
|
47
55
|
return left instanceof right;
|
|
48
56
|
}
|
|
49
57
|
}
|
|
58
|
+
function _iterable_to_array_limit(arr, i) {
|
|
59
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
60
|
+
if (_i == null) return;
|
|
61
|
+
var _arr = [];
|
|
62
|
+
var _n = true;
|
|
63
|
+
var _d = false;
|
|
64
|
+
var _s, _e;
|
|
65
|
+
try {
|
|
66
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
67
|
+
_arr.push(_s.value);
|
|
68
|
+
if (i && _arr.length === i) break;
|
|
69
|
+
}
|
|
70
|
+
} catch (err) {
|
|
71
|
+
_d = true;
|
|
72
|
+
_e = err;
|
|
73
|
+
} finally{
|
|
74
|
+
try {
|
|
75
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
76
|
+
} finally{
|
|
77
|
+
if (_d) throw _e;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return _arr;
|
|
81
|
+
}
|
|
82
|
+
function _non_iterable_rest() {
|
|
83
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
84
|
+
}
|
|
50
85
|
function _object_spread(target) {
|
|
51
86
|
for(var i = 1; i < arguments.length; i++){
|
|
52
87
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
@@ -86,6 +121,17 @@ function _object_spread_props(target, source) {
|
|
|
86
121
|
}
|
|
87
122
|
return target;
|
|
88
123
|
}
|
|
124
|
+
function _sliced_to_array(arr, i) {
|
|
125
|
+
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
|
|
126
|
+
}
|
|
127
|
+
function _unsupported_iterable_to_array(o, minLen) {
|
|
128
|
+
if (!o) return;
|
|
129
|
+
if (typeof o === "string") return _array_like_to_array(o, minLen);
|
|
130
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
131
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
132
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
133
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
134
|
+
}
|
|
89
135
|
function _ts_generator(thisArg, body) {
|
|
90
136
|
var f, y, t, _ = {
|
|
91
137
|
label: 0,
|
|
@@ -181,7 +227,7 @@ import { Hono } from 'hono';
|
|
|
181
227
|
import { v4 as uuidv4 } from 'uuid';
|
|
182
228
|
import { AwsClient } from 'aws4fetch';
|
|
183
229
|
import { parseCronExpression } from 'cron-schedule';
|
|
184
|
-
import { getManifest } from './brain-runner-do.js';
|
|
230
|
+
import { getManifest, getWebhookManifest } from './brain-runner-do.js';
|
|
185
231
|
import { RESOURCE_TYPES } from '@positronic/core';
|
|
186
232
|
var app = new Hono();
|
|
187
233
|
app.post('/brains/runs', function(context) {
|
|
@@ -397,6 +443,81 @@ app.get('/brains/runs/:runId/watch', function(context) {
|
|
|
397
443
|
});
|
|
398
444
|
})();
|
|
399
445
|
});
|
|
446
|
+
app.delete('/brains/runs/:runId', function(context) {
|
|
447
|
+
return _async_to_generator(function() {
|
|
448
|
+
var runId, monitorId, monitorStub, existingRun, namespace, doId, stub, result, error;
|
|
449
|
+
return _ts_generator(this, function(_state) {
|
|
450
|
+
switch(_state.label){
|
|
451
|
+
case 0:
|
|
452
|
+
runId = context.req.param('runId');
|
|
453
|
+
// First check if the run exists in the monitor
|
|
454
|
+
monitorId = context.env.MONITOR_DO.idFromName('singleton');
|
|
455
|
+
monitorStub = context.env.MONITOR_DO.get(monitorId);
|
|
456
|
+
return [
|
|
457
|
+
4,
|
|
458
|
+
monitorStub.getLastEvent(runId)
|
|
459
|
+
];
|
|
460
|
+
case 1:
|
|
461
|
+
existingRun = _state.sent();
|
|
462
|
+
if (!existingRun) {
|
|
463
|
+
return [
|
|
464
|
+
2,
|
|
465
|
+
context.json({
|
|
466
|
+
error: "Brain run '".concat(runId, "' not found")
|
|
467
|
+
}, 404)
|
|
468
|
+
];
|
|
469
|
+
}
|
|
470
|
+
// Now try to kill it
|
|
471
|
+
namespace = context.env.BRAIN_RUNNER_DO;
|
|
472
|
+
doId = namespace.idFromName(runId);
|
|
473
|
+
stub = namespace.get(doId);
|
|
474
|
+
_state.label = 2;
|
|
475
|
+
case 2:
|
|
476
|
+
_state.trys.push([
|
|
477
|
+
2,
|
|
478
|
+
4,
|
|
479
|
+
,
|
|
480
|
+
5
|
|
481
|
+
]);
|
|
482
|
+
return [
|
|
483
|
+
4,
|
|
484
|
+
stub.kill()
|
|
485
|
+
];
|
|
486
|
+
case 3:
|
|
487
|
+
result = _state.sent();
|
|
488
|
+
if (!result.success) {
|
|
489
|
+
// Brain run is not active or already completed
|
|
490
|
+
return [
|
|
491
|
+
2,
|
|
492
|
+
context.json({
|
|
493
|
+
error: result.message
|
|
494
|
+
}, 409)
|
|
495
|
+
];
|
|
496
|
+
}
|
|
497
|
+
// Return 204 No Content on success
|
|
498
|
+
return [
|
|
499
|
+
2,
|
|
500
|
+
new Response(null, {
|
|
501
|
+
status: 204
|
|
502
|
+
})
|
|
503
|
+
];
|
|
504
|
+
case 4:
|
|
505
|
+
error = _state.sent();
|
|
506
|
+
console.error("Error killing brain run ".concat(runId, ":"), error);
|
|
507
|
+
return [
|
|
508
|
+
2,
|
|
509
|
+
context.json({
|
|
510
|
+
error: 'Failed to kill brain run'
|
|
511
|
+
}, 500)
|
|
512
|
+
];
|
|
513
|
+
case 5:
|
|
514
|
+
return [
|
|
515
|
+
2
|
|
516
|
+
];
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
})();
|
|
520
|
+
});
|
|
400
521
|
app.get('/brains/:identifier/history', function(context) {
|
|
401
522
|
return _async_to_generator(function() {
|
|
402
523
|
var identifier, limit, manifest, resolution, brain, brainTitle, monitorId, monitorStub, runs;
|
|
@@ -1397,4 +1518,137 @@ app.post('/resources/presigned-link', function(context) {
|
|
|
1397
1518
|
});
|
|
1398
1519
|
})();
|
|
1399
1520
|
});
|
|
1521
|
+
// Webhook endpoints
|
|
1522
|
+
// List all webhooks
|
|
1523
|
+
app.get('/webhooks', function(context) {
|
|
1524
|
+
return _async_to_generator(function() {
|
|
1525
|
+
var webhookManifest, webhooks;
|
|
1526
|
+
return _ts_generator(this, function(_state) {
|
|
1527
|
+
webhookManifest = getWebhookManifest();
|
|
1528
|
+
if (!webhookManifest) {
|
|
1529
|
+
return [
|
|
1530
|
+
2,
|
|
1531
|
+
context.json({
|
|
1532
|
+
webhooks: [],
|
|
1533
|
+
count: 0
|
|
1534
|
+
})
|
|
1535
|
+
];
|
|
1536
|
+
}
|
|
1537
|
+
webhooks = Object.entries(webhookManifest).map(function(param) {
|
|
1538
|
+
var _param = _sliced_to_array(param, 2), slug = _param[0], webhook = _param[1];
|
|
1539
|
+
return {
|
|
1540
|
+
slug: slug,
|
|
1541
|
+
description: webhook.description
|
|
1542
|
+
};
|
|
1543
|
+
});
|
|
1544
|
+
return [
|
|
1545
|
+
2,
|
|
1546
|
+
context.json({
|
|
1547
|
+
webhooks: webhooks,
|
|
1548
|
+
count: webhooks.length
|
|
1549
|
+
})
|
|
1550
|
+
];
|
|
1551
|
+
});
|
|
1552
|
+
})();
|
|
1553
|
+
});
|
|
1554
|
+
// Receive incoming webhook from external service
|
|
1555
|
+
app.post('/webhooks/:slug', function(context) {
|
|
1556
|
+
return _async_to_generator(function() {
|
|
1557
|
+
var slug, webhookManifest, webhook, result, monitorId, monitorStub, brainRunId, namespace, doId, stub, error;
|
|
1558
|
+
return _ts_generator(this, function(_state) {
|
|
1559
|
+
switch(_state.label){
|
|
1560
|
+
case 0:
|
|
1561
|
+
slug = context.req.param('slug');
|
|
1562
|
+
webhookManifest = getWebhookManifest();
|
|
1563
|
+
if (!webhookManifest) {
|
|
1564
|
+
return [
|
|
1565
|
+
2,
|
|
1566
|
+
context.json({
|
|
1567
|
+
error: 'Webhook manifest not initialized'
|
|
1568
|
+
}, 500)
|
|
1569
|
+
];
|
|
1570
|
+
}
|
|
1571
|
+
webhook = webhookManifest[slug];
|
|
1572
|
+
if (!webhook) {
|
|
1573
|
+
return [
|
|
1574
|
+
2,
|
|
1575
|
+
context.json({
|
|
1576
|
+
error: "Webhook '".concat(slug, "' not found")
|
|
1577
|
+
}, 404)
|
|
1578
|
+
];
|
|
1579
|
+
}
|
|
1580
|
+
_state.label = 1;
|
|
1581
|
+
case 1:
|
|
1582
|
+
_state.trys.push([
|
|
1583
|
+
1,
|
|
1584
|
+
6,
|
|
1585
|
+
,
|
|
1586
|
+
7
|
|
1587
|
+
]);
|
|
1588
|
+
return [
|
|
1589
|
+
4,
|
|
1590
|
+
webhook.handler(context.req.raw)
|
|
1591
|
+
];
|
|
1592
|
+
case 2:
|
|
1593
|
+
result = _state.sent();
|
|
1594
|
+
// Check if there's a brain waiting for this webhook
|
|
1595
|
+
monitorId = context.env.MONITOR_DO.idFromName('singleton');
|
|
1596
|
+
monitorStub = context.env.MONITOR_DO.get(monitorId);
|
|
1597
|
+
return [
|
|
1598
|
+
4,
|
|
1599
|
+
monitorStub.findWaitingBrain(slug, result.identifier)
|
|
1600
|
+
];
|
|
1601
|
+
case 3:
|
|
1602
|
+
brainRunId = _state.sent();
|
|
1603
|
+
if (!brainRunId) return [
|
|
1604
|
+
3,
|
|
1605
|
+
5
|
|
1606
|
+
];
|
|
1607
|
+
// Found a brain waiting for this webhook - resume it
|
|
1608
|
+
namespace = context.env.BRAIN_RUNNER_DO;
|
|
1609
|
+
doId = namespace.idFromName(brainRunId);
|
|
1610
|
+
stub = namespace.get(doId);
|
|
1611
|
+
// Resume the brain with the webhook response
|
|
1612
|
+
return [
|
|
1613
|
+
4,
|
|
1614
|
+
stub.resume(brainRunId, result.response)
|
|
1615
|
+
];
|
|
1616
|
+
case 4:
|
|
1617
|
+
_state.sent();
|
|
1618
|
+
return [
|
|
1619
|
+
2,
|
|
1620
|
+
context.json({
|
|
1621
|
+
received: true,
|
|
1622
|
+
action: 'resumed',
|
|
1623
|
+
identifier: result.identifier,
|
|
1624
|
+
brainRunId: brainRunId
|
|
1625
|
+
})
|
|
1626
|
+
];
|
|
1627
|
+
case 5:
|
|
1628
|
+
// No brain waiting for this webhook
|
|
1629
|
+
return [
|
|
1630
|
+
2,
|
|
1631
|
+
context.json({
|
|
1632
|
+
received: true,
|
|
1633
|
+
action: 'queued',
|
|
1634
|
+
identifier: result.identifier
|
|
1635
|
+
})
|
|
1636
|
+
];
|
|
1637
|
+
case 6:
|
|
1638
|
+
error = _state.sent();
|
|
1639
|
+
console.error("Error receiving webhook ".concat(slug, ":"), error);
|
|
1640
|
+
return [
|
|
1641
|
+
2,
|
|
1642
|
+
context.json({
|
|
1643
|
+
error: 'Failed to process webhook'
|
|
1644
|
+
}, 500)
|
|
1645
|
+
];
|
|
1646
|
+
case 7:
|
|
1647
|
+
return [
|
|
1648
|
+
2
|
|
1649
|
+
];
|
|
1650
|
+
}
|
|
1651
|
+
});
|
|
1652
|
+
})();
|
|
1653
|
+
});
|
|
1400
1654
|
export default app;
|
|
@@ -103,6 +103,30 @@ function _object_spread(target) {
|
|
|
103
103
|
}
|
|
104
104
|
return target;
|
|
105
105
|
}
|
|
106
|
+
function ownKeys(object, enumerableOnly) {
|
|
107
|
+
var keys = Object.keys(object);
|
|
108
|
+
if (Object.getOwnPropertySymbols) {
|
|
109
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
110
|
+
if (enumerableOnly) {
|
|
111
|
+
symbols = symbols.filter(function(sym) {
|
|
112
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
keys.push.apply(keys, symbols);
|
|
116
|
+
}
|
|
117
|
+
return keys;
|
|
118
|
+
}
|
|
119
|
+
function _object_spread_props(target, source) {
|
|
120
|
+
source = source != null ? source : {};
|
|
121
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
122
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
123
|
+
} else {
|
|
124
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
125
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return target;
|
|
129
|
+
}
|
|
106
130
|
function _possible_constructor_return(self, call) {
|
|
107
131
|
if (call && (_type_of(call) === "object" || typeof call === "function")) {
|
|
108
132
|
return call;
|
|
@@ -219,8 +243,10 @@ function _ts_generator(thisArg, body) {
|
|
|
219
243
|
};
|
|
220
244
|
}
|
|
221
245
|
}
|
|
246
|
+
import { STATUS, BRAIN_EVENTS } from '@positronic/core';
|
|
222
247
|
import { DurableObject } from 'cloudflare:workers';
|
|
223
248
|
import { BrainRunSQLiteAdapter } from './sqlite-adapter.js';
|
|
249
|
+
import { WebhookAdapter } from './webhook-adapter.js';
|
|
224
250
|
import { CloudflareR2Loader } from './r2-loader.js';
|
|
225
251
|
import { createResources } from '@positronic/core';
|
|
226
252
|
var manifest = null;
|
|
@@ -234,6 +260,13 @@ var brainRunner = null;
|
|
|
234
260
|
export function setBrainRunner(runner) {
|
|
235
261
|
brainRunner = runner;
|
|
236
262
|
}
|
|
263
|
+
var webhookManifest = null;
|
|
264
|
+
export function setWebhookManifest(manifest) {
|
|
265
|
+
webhookManifest = manifest;
|
|
266
|
+
}
|
|
267
|
+
export function getWebhookManifest() {
|
|
268
|
+
return webhookManifest;
|
|
269
|
+
}
|
|
237
270
|
var EventStreamAdapter = /*#__PURE__*/ function() {
|
|
238
271
|
"use strict";
|
|
239
272
|
function EventStreamAdapter() {
|
|
@@ -364,7 +397,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
364
397
|
_this = _call_super(this, BrainRunnerDO, [
|
|
365
398
|
state,
|
|
366
399
|
env
|
|
367
|
-
]), _define_property(_this, "sql", void 0), _define_property(_this, "brainRunId", void 0), _define_property(_this, "eventStreamAdapter", new EventStreamAdapter());
|
|
400
|
+
]), _define_property(_this, "sql", void 0), _define_property(_this, "brainRunId", void 0), _define_property(_this, "eventStreamAdapter", new EventStreamAdapter()), _define_property(_this, "abortController", null);
|
|
368
401
|
_this.sql = state.storage.sql;
|
|
369
402
|
_this.brainRunId = state.id.toString();
|
|
370
403
|
_this.env = env;
|
|
@@ -502,14 +535,45 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
502
535
|
}).call(this);
|
|
503
536
|
}
|
|
504
537
|
},
|
|
538
|
+
{
|
|
539
|
+
key: "kill",
|
|
540
|
+
value: function kill() {
|
|
541
|
+
return _async_to_generator(function() {
|
|
542
|
+
return _ts_generator(this, function(_state) {
|
|
543
|
+
if (this.abortController && !this.abortController.signal.aborted) {
|
|
544
|
+
this.abortController.abort();
|
|
545
|
+
return [
|
|
546
|
+
2,
|
|
547
|
+
{
|
|
548
|
+
success: true,
|
|
549
|
+
message: 'Brain run kill signal sent'
|
|
550
|
+
}
|
|
551
|
+
];
|
|
552
|
+
} else {
|
|
553
|
+
return [
|
|
554
|
+
2,
|
|
555
|
+
{
|
|
556
|
+
success: false,
|
|
557
|
+
message: 'Brain run is not active or already completed'
|
|
558
|
+
}
|
|
559
|
+
];
|
|
560
|
+
}
|
|
561
|
+
return [
|
|
562
|
+
2
|
|
563
|
+
];
|
|
564
|
+
});
|
|
565
|
+
}).call(this);
|
|
566
|
+
}
|
|
567
|
+
},
|
|
505
568
|
{
|
|
506
569
|
key: "start",
|
|
507
570
|
value: function start(brainTitle, brainRunId, initialData) {
|
|
508
571
|
return _async_to_generator(function() {
|
|
509
|
-
var sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorAdapter, scheduleAdapter, r2Resources, runnerWithResources, options, initialState;
|
|
572
|
+
var _this, sql, resolution, brainToRun, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, r2Resources, runnerWithResources, options, initialState;
|
|
510
573
|
return _ts_generator(this, function(_state) {
|
|
511
574
|
switch(_state.label){
|
|
512
575
|
case 0:
|
|
576
|
+
_this = this;
|
|
513
577
|
sql = this.sql;
|
|
514
578
|
if (!manifest) {
|
|
515
579
|
throw new Error('Runtime manifest not initialized');
|
|
@@ -531,8 +595,10 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
531
595
|
}
|
|
532
596
|
sqliteAdapter = new BrainRunSQLiteAdapter(sql);
|
|
533
597
|
eventStreamAdapter = this.eventStreamAdapter;
|
|
534
|
-
|
|
598
|
+
monitorDOStub = this.env.MONITOR_DO.get(this.env.MONITOR_DO.idFromName('singleton'));
|
|
599
|
+
monitorAdapter = new MonitorAdapter(monitorDOStub);
|
|
535
600
|
scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
|
|
601
|
+
webhookAdapter = new WebhookAdapter(monitorDOStub);
|
|
536
602
|
if (!brainRunner) {
|
|
537
603
|
throw new Error('BrainRunner not initialized');
|
|
538
604
|
}
|
|
@@ -551,18 +617,123 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
551
617
|
// Extract options from initialData if present
|
|
552
618
|
options = initialData === null || initialData === void 0 ? void 0 : initialData.options;
|
|
553
619
|
initialState = initialData && !initialData.options ? initialData : {};
|
|
620
|
+
// Create abort controller for this run
|
|
621
|
+
this.abortController = new AbortController();
|
|
554
622
|
runnerWithResources.withAdapters([
|
|
555
623
|
sqliteAdapter,
|
|
556
624
|
eventStreamAdapter,
|
|
557
625
|
monitorAdapter,
|
|
558
|
-
scheduleAdapter
|
|
559
|
-
|
|
626
|
+
scheduleAdapter,
|
|
627
|
+
webhookAdapter
|
|
628
|
+
]).run(brainToRun, _object_spread_props(_object_spread({
|
|
560
629
|
initialState: initialState,
|
|
561
630
|
brainRunId: brainRunId
|
|
562
631
|
}, options && {
|
|
563
632
|
options: options
|
|
633
|
+
}), {
|
|
634
|
+
signal: this.abortController.signal
|
|
564
635
|
})).catch(function(err) {
|
|
565
636
|
console.error("[DO ".concat(brainRunId, "] BrainRunner run failed:"), err);
|
|
637
|
+
throw err; // Re-throw to ensure proper error propagation
|
|
638
|
+
}).finally(function() {
|
|
639
|
+
// Clean up abort controller when run completes
|
|
640
|
+
_this.abortController = null;
|
|
641
|
+
});
|
|
642
|
+
return [
|
|
643
|
+
2
|
|
644
|
+
];
|
|
645
|
+
}
|
|
646
|
+
});
|
|
647
|
+
}).call(this);
|
|
648
|
+
}
|
|
649
|
+
},
|
|
650
|
+
{
|
|
651
|
+
key: "resume",
|
|
652
|
+
value: function resume(brainRunId, webhookResponse) {
|
|
653
|
+
return _async_to_generator(function() {
|
|
654
|
+
var _this, sql, startEventResult, startEvent, brainTitle, initialState, resolution, brainToRun, eventsResult, initialCompletedSteps, sqliteAdapter, eventStreamAdapter, monitorDOStub, monitorAdapter, scheduleAdapter, webhookAdapter, r2Resources, runnerWithResources;
|
|
655
|
+
return _ts_generator(this, function(_state) {
|
|
656
|
+
switch(_state.label){
|
|
657
|
+
case 0:
|
|
658
|
+
_this = this;
|
|
659
|
+
sql = this.sql;
|
|
660
|
+
if (!manifest) {
|
|
661
|
+
throw new Error('Runtime manifest not initialized');
|
|
662
|
+
}
|
|
663
|
+
// Get the initial state and brain title by loading the START or RESTART event
|
|
664
|
+
startEventResult = sql.exec("SELECT serialized_event FROM brain_events WHERE event_type IN (?, ?) ORDER BY event_id DESC LIMIT 1", BRAIN_EVENTS.START, BRAIN_EVENTS.RESTART).toArray();
|
|
665
|
+
if (startEventResult.length === 0) {
|
|
666
|
+
throw new Error("No START or RESTART event found for brain run ".concat(brainRunId));
|
|
667
|
+
}
|
|
668
|
+
startEvent = JSON.parse(startEventResult[0].serialized_event);
|
|
669
|
+
brainTitle = startEvent.brainTitle;
|
|
670
|
+
initialState = startEvent.initialState || {};
|
|
671
|
+
if (!brainTitle) {
|
|
672
|
+
throw new Error("Brain title not found in START/RESTART event for brain run ".concat(brainRunId));
|
|
673
|
+
}
|
|
674
|
+
// Resolve the brain using the title
|
|
675
|
+
resolution = manifest.resolve(brainTitle);
|
|
676
|
+
if (resolution.matchType === 'none') {
|
|
677
|
+
console.error("[DO ".concat(brainRunId, "] Brain ").concat(brainTitle, " not found in manifest."));
|
|
678
|
+
throw new Error("Brain ".concat(brainTitle, " not found"));
|
|
679
|
+
}
|
|
680
|
+
if (resolution.matchType === 'multiple') {
|
|
681
|
+
console.error("[DO ".concat(brainRunId, "] Multiple brains match identifier ").concat(brainTitle), resolution.candidates);
|
|
682
|
+
throw new Error("Multiple brains match identifier ".concat(brainTitle));
|
|
683
|
+
}
|
|
684
|
+
brainToRun = resolution.brain;
|
|
685
|
+
if (!brainToRun) {
|
|
686
|
+
throw new Error("Brain ".concat(brainTitle, " resolved but brain object is missing"));
|
|
687
|
+
}
|
|
688
|
+
// Load completed steps from SQLite
|
|
689
|
+
eventsResult = sql.exec("SELECT serialized_event FROM brain_events WHERE event_type = ? ORDER BY event_id ASC", BRAIN_EVENTS.STEP_COMPLETE).toArray();
|
|
690
|
+
initialCompletedSteps = eventsResult.map(function(row) {
|
|
691
|
+
var event = JSON.parse(row.serialized_event);
|
|
692
|
+
return {
|
|
693
|
+
id: event.stepId,
|
|
694
|
+
title: event.stepTitle,
|
|
695
|
+
status: STATUS.COMPLETE,
|
|
696
|
+
patch: event.patch
|
|
697
|
+
};
|
|
698
|
+
});
|
|
699
|
+
sqliteAdapter = new BrainRunSQLiteAdapter(sql);
|
|
700
|
+
eventStreamAdapter = this.eventStreamAdapter;
|
|
701
|
+
monitorDOStub = this.env.MONITOR_DO.get(this.env.MONITOR_DO.idFromName('singleton'));
|
|
702
|
+
monitorAdapter = new MonitorAdapter(monitorDOStub);
|
|
703
|
+
scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
|
|
704
|
+
webhookAdapter = new WebhookAdapter(monitorDOStub);
|
|
705
|
+
if (!brainRunner) {
|
|
706
|
+
throw new Error('BrainRunner not initialized');
|
|
707
|
+
}
|
|
708
|
+
return [
|
|
709
|
+
4,
|
|
710
|
+
this.loadResourcesFromR2()
|
|
711
|
+
];
|
|
712
|
+
case 1:
|
|
713
|
+
r2Resources = _state.sent();
|
|
714
|
+
runnerWithResources = brainRunner;
|
|
715
|
+
if (r2Resources) {
|
|
716
|
+
runnerWithResources = brainRunner.withResources(r2Resources);
|
|
717
|
+
}
|
|
718
|
+
// Create abort controller for this run
|
|
719
|
+
this.abortController = new AbortController();
|
|
720
|
+
runnerWithResources.withAdapters([
|
|
721
|
+
sqliteAdapter,
|
|
722
|
+
eventStreamAdapter,
|
|
723
|
+
monitorAdapter,
|
|
724
|
+
scheduleAdapter,
|
|
725
|
+
webhookAdapter
|
|
726
|
+
]).run(brainToRun, {
|
|
727
|
+
initialState: initialState,
|
|
728
|
+
initialCompletedSteps: initialCompletedSteps,
|
|
729
|
+
brainRunId: brainRunId,
|
|
730
|
+
response: webhookResponse,
|
|
731
|
+
signal: this.abortController.signal
|
|
732
|
+
}).catch(function(err) {
|
|
733
|
+
console.error("[DO ".concat(brainRunId, "] BrainRunner resume failed:"), err);
|
|
734
|
+
throw err;
|
|
735
|
+
}).finally(function() {
|
|
736
|
+
_this.abortController = null;
|
|
566
737
|
});
|
|
567
738
|
return [
|
|
568
739
|
2
|
package/dist/src/dev-server.js
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BrainRunnerDO, setBrainRunner, setManifest, getManifest } from './brain-runner-do.js';
|
|
1
|
+
export { BrainRunnerDO, setBrainRunner, setManifest, getManifest, setWebhookManifest } from './brain-runner-do.js';
|
|
2
2
|
export { MonitorDO } from './monitor-do.js';
|
|
3
3
|
export { ScheduleDO } from './schedule-do.js';
|
|
4
4
|
export { PositronicManifest } from './manifest.js';
|
package/dist/src/monitor-do.js
CHANGED
|
@@ -218,20 +218,24 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
218
218
|
]), _define_property(_this, "storage", void 0), _define_property(_this, "eventStreamHandler", new EventStreamHandler());
|
|
219
219
|
_this.storage = state.storage.sql;
|
|
220
220
|
// Update table schema and indexes
|
|
221
|
-
_this.storage.exec("\n CREATE TABLE IF NOT EXISTS brain_runs (\n run_id TEXT PRIMARY KEY,\n brain_title TEXT NOT NULL, -- Renamed column\n brain_description TEXT, -- Renamed column\n type TEXT NOT NULL,\n status TEXT NOT NULL,\n options TEXT,\n error TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_brain_status -- Renamed index\n ON brain_runs(brain_title, status);\n\n CREATE INDEX IF NOT EXISTS idx_brain_time -- Renamed index\n ON brain_runs(created_at DESC);\n ");
|
|
221
|
+
_this.storage.exec("\n CREATE TABLE IF NOT EXISTS brain_runs (\n run_id TEXT PRIMARY KEY,\n brain_title TEXT NOT NULL, -- Renamed column\n brain_description TEXT, -- Renamed column\n type TEXT NOT NULL,\n status TEXT NOT NULL,\n options TEXT,\n error TEXT,\n created_at INTEGER NOT NULL,\n started_at INTEGER,\n completed_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_brain_status -- Renamed index\n ON brain_runs(brain_title, status);\n\n CREATE INDEX IF NOT EXISTS idx_brain_time -- Renamed index\n ON brain_runs(created_at DESC);\n\n CREATE TABLE IF NOT EXISTS webhook_registrations (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n slug TEXT NOT NULL,\n identifier TEXT NOT NULL,\n brain_run_id TEXT NOT NULL,\n created_at INTEGER NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS idx_webhook_lookup\n ON webhook_registrations(slug, identifier);\n\n CREATE INDEX IF NOT EXISTS idx_webhook_brain_run\n ON webhook_registrations(brain_run_id);\n ");
|
|
222
222
|
return _this;
|
|
223
223
|
}
|
|
224
224
|
_create_class(MonitorDO, [
|
|
225
225
|
{
|
|
226
226
|
key: "handleBrainEvent",
|
|
227
227
|
value: function handleBrainEvent(event) {
|
|
228
|
-
if (event.type === BRAIN_EVENTS.START || event.type === BRAIN_EVENTS.RESTART || event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR) {
|
|
228
|
+
if (event.type === BRAIN_EVENTS.START || event.type === BRAIN_EVENTS.RESTART || event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR || event.type === BRAIN_EVENTS.CANCELLED) {
|
|
229
229
|
var currentTime = Date.now();
|
|
230
230
|
var startTime = event.type === BRAIN_EVENTS.START || event.type === BRAIN_EVENTS.RESTART ? currentTime : null;
|
|
231
|
-
var completeTime = event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR ? currentTime : null;
|
|
231
|
+
var completeTime = event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR || event.type === BRAIN_EVENTS.CANCELLED ? currentTime : null;
|
|
232
232
|
var error = event.type === BRAIN_EVENTS.ERROR ? JSON.stringify(event.error) : null;
|
|
233
233
|
// Update SQL insert/update with new column names, read from existing event fields
|
|
234
234
|
this.storage.exec("\n INSERT INTO brain_runs (\n run_id, brain_title, brain_description, type, status,\n options, error, created_at, started_at, completed_at\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(run_id) DO UPDATE SET\n type = excluded.type,\n status = excluded.status,\n error = excluded.error,\n completed_at = excluded.completed_at\n ", event.brainRunId, event.brainTitle, event.brainDescription || null, event.type, event.status, JSON.stringify(event.options || {}), error, currentTime, startTime, completeTime);
|
|
235
|
+
// Clean up webhook registrations when brain terminates
|
|
236
|
+
if (event.type === BRAIN_EVENTS.COMPLETE || event.type === BRAIN_EVENTS.ERROR || event.type === BRAIN_EVENTS.CANCELLED) {
|
|
237
|
+
this.clearWebhookRegistrations(event.brainRunId);
|
|
238
|
+
}
|
|
235
239
|
this.broadcastRunningBrains();
|
|
236
240
|
}
|
|
237
241
|
}
|
|
@@ -341,10 +345,10 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
341
345
|
}
|
|
342
346
|
},
|
|
343
347
|
{
|
|
344
|
-
// No changes needed for getLastEvent, uses run_id
|
|
345
348
|
key: "getLastEvent",
|
|
346
349
|
value: function getLastEvent(brainRunId) {
|
|
347
|
-
|
|
350
|
+
var results = this.storage.exec("\n SELECT * FROM brain_runs WHERE run_id = ?\n ", brainRunId).toArray();
|
|
351
|
+
return results.length > 0 ? results[0] : null;
|
|
348
352
|
}
|
|
349
353
|
},
|
|
350
354
|
{
|
|
@@ -363,6 +367,34 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
363
367
|
value: function activeRuns(brainTitle) {
|
|
364
368
|
return this.storage.exec("\n SELECT\n run_id as brainRunId,\n brain_title as brainTitle,\n brain_description as brainDescription,\n type,\n status,\n options,\n error,\n created_at as createdAt,\n started_at as startedAt,\n completed_at as completedAt\n FROM brain_runs\n WHERE brain_title = ? AND status = ?\n ORDER BY created_at DESC\n ", brainTitle, STATUS.RUNNING).toArray();
|
|
365
369
|
}
|
|
370
|
+
},
|
|
371
|
+
{
|
|
372
|
+
/**
|
|
373
|
+
* Register a webhook to wait for
|
|
374
|
+
* Called when a brain emits a WEBHOOK event
|
|
375
|
+
*/ key: "registerWebhook",
|
|
376
|
+
value: function registerWebhook(slug, identifier, brainRunId) {
|
|
377
|
+
this.storage.exec("\n INSERT INTO webhook_registrations (slug, identifier, brain_run_id, created_at)\n VALUES (?, ?, ?, ?)\n ", slug, identifier, brainRunId, Date.now());
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
/**
|
|
382
|
+
* Find a brain waiting for this webhook
|
|
383
|
+
* Returns the brain_run_id if found, null otherwise
|
|
384
|
+
*/ key: "findWaitingBrain",
|
|
385
|
+
value: function findWaitingBrain(slug, identifier) {
|
|
386
|
+
var results = this.storage.exec("\n SELECT brain_run_id as brainRunId\n FROM webhook_registrations\n WHERE slug = ? AND identifier = ?\n LIMIT 1\n ", slug, identifier).toArray();
|
|
387
|
+
return results.length > 0 ? results[0].brainRunId : null;
|
|
388
|
+
}
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
/**
|
|
392
|
+
* Clear all webhook registrations for a brain run
|
|
393
|
+
* Called when brain completes, errors, or is cancelled
|
|
394
|
+
*/ key: "clearWebhookRegistrations",
|
|
395
|
+
value: function clearWebhookRegistrations(brainRunId) {
|
|
396
|
+
this.storage.exec("\n DELETE FROM webhook_registrations\n WHERE brain_run_id = ?\n ", brainRunId);
|
|
397
|
+
}
|
|
366
398
|
}
|
|
367
399
|
]);
|
|
368
400
|
return MonitorDO;
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
+
try {
|
|
3
|
+
var info = gen[key](arg);
|
|
4
|
+
var value = info.value;
|
|
5
|
+
} catch (error) {
|
|
6
|
+
reject(error);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (info.done) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
} else {
|
|
12
|
+
Promise.resolve(value).then(_next, _throw);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _async_to_generator(fn) {
|
|
16
|
+
return function() {
|
|
17
|
+
var self = this, args = arguments;
|
|
18
|
+
return new Promise(function(resolve, reject) {
|
|
19
|
+
var gen = fn.apply(self, args);
|
|
20
|
+
function _next(value) {
|
|
21
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
+
}
|
|
23
|
+
function _throw(err) {
|
|
24
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
+
}
|
|
26
|
+
_next(undefined);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function _class_call_check(instance, Constructor) {
|
|
31
|
+
if (!(instance instanceof Constructor)) {
|
|
32
|
+
throw new TypeError("Cannot call a class as a function");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function _defineProperties(target, props) {
|
|
36
|
+
for(var i = 0; i < props.length; i++){
|
|
37
|
+
var descriptor = props[i];
|
|
38
|
+
descriptor.enumerable = descriptor.enumerable || false;
|
|
39
|
+
descriptor.configurable = true;
|
|
40
|
+
if ("value" in descriptor) descriptor.writable = true;
|
|
41
|
+
Object.defineProperty(target, descriptor.key, descriptor);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function _create_class(Constructor, protoProps, staticProps) {
|
|
45
|
+
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
|
|
46
|
+
if (staticProps) _defineProperties(Constructor, staticProps);
|
|
47
|
+
return Constructor;
|
|
48
|
+
}
|
|
49
|
+
function _define_property(obj, key, value) {
|
|
50
|
+
if (key in obj) {
|
|
51
|
+
Object.defineProperty(obj, key, {
|
|
52
|
+
value: value,
|
|
53
|
+
enumerable: true,
|
|
54
|
+
configurable: true,
|
|
55
|
+
writable: true
|
|
56
|
+
});
|
|
57
|
+
} else {
|
|
58
|
+
obj[key] = value;
|
|
59
|
+
}
|
|
60
|
+
return obj;
|
|
61
|
+
}
|
|
62
|
+
function _ts_generator(thisArg, body) {
|
|
63
|
+
var f, y, t, _ = {
|
|
64
|
+
label: 0,
|
|
65
|
+
sent: function() {
|
|
66
|
+
if (t[0] & 1) throw t[1];
|
|
67
|
+
return t[1];
|
|
68
|
+
},
|
|
69
|
+
trys: [],
|
|
70
|
+
ops: []
|
|
71
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
72
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
73
|
+
return this;
|
|
74
|
+
}), g;
|
|
75
|
+
function verb(n) {
|
|
76
|
+
return function(v) {
|
|
77
|
+
return step([
|
|
78
|
+
n,
|
|
79
|
+
v
|
|
80
|
+
]);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function step(op) {
|
|
84
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
85
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
86
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
87
|
+
if (y = 0, t) op = [
|
|
88
|
+
op[0] & 2,
|
|
89
|
+
t.value
|
|
90
|
+
];
|
|
91
|
+
switch(op[0]){
|
|
92
|
+
case 0:
|
|
93
|
+
case 1:
|
|
94
|
+
t = op;
|
|
95
|
+
break;
|
|
96
|
+
case 4:
|
|
97
|
+
_.label++;
|
|
98
|
+
return {
|
|
99
|
+
value: op[1],
|
|
100
|
+
done: false
|
|
101
|
+
};
|
|
102
|
+
case 5:
|
|
103
|
+
_.label++;
|
|
104
|
+
y = op[1];
|
|
105
|
+
op = [
|
|
106
|
+
0
|
|
107
|
+
];
|
|
108
|
+
continue;
|
|
109
|
+
case 7:
|
|
110
|
+
op = _.ops.pop();
|
|
111
|
+
_.trys.pop();
|
|
112
|
+
continue;
|
|
113
|
+
default:
|
|
114
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
115
|
+
_ = 0;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
119
|
+
_.label = op[1];
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
123
|
+
_.label = t[1];
|
|
124
|
+
t = op;
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
if (t && _.label < t[2]) {
|
|
128
|
+
_.label = t[2];
|
|
129
|
+
_.ops.push(op);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if (t[2]) _.ops.pop();
|
|
133
|
+
_.trys.pop();
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
op = body.call(thisArg, _);
|
|
137
|
+
} catch (e) {
|
|
138
|
+
op = [
|
|
139
|
+
6,
|
|
140
|
+
e
|
|
141
|
+
];
|
|
142
|
+
y = 0;
|
|
143
|
+
} finally{
|
|
144
|
+
f = t = 0;
|
|
145
|
+
}
|
|
146
|
+
if (op[0] & 5) throw op[1];
|
|
147
|
+
return {
|
|
148
|
+
value: op[0] ? op[1] : void 0,
|
|
149
|
+
done: true
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
import { BRAIN_EVENTS } from '@positronic/core';
|
|
154
|
+
/**
|
|
155
|
+
* Adapter that handles WEBHOOK events by registering webhooks
|
|
156
|
+
* with the MonitorDO for brain resumption
|
|
157
|
+
*/ export var WebhookAdapter = /*#__PURE__*/ function() {
|
|
158
|
+
"use strict";
|
|
159
|
+
function WebhookAdapter(monitorStub) {
|
|
160
|
+
_class_call_check(this, WebhookAdapter);
|
|
161
|
+
_define_property(this, "monitorStub", void 0);
|
|
162
|
+
this.monitorStub = monitorStub;
|
|
163
|
+
}
|
|
164
|
+
_create_class(WebhookAdapter, [
|
|
165
|
+
{
|
|
166
|
+
key: "dispatch",
|
|
167
|
+
value: function dispatch(event) {
|
|
168
|
+
return _async_to_generator(function() {
|
|
169
|
+
var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, registration, err;
|
|
170
|
+
return _ts_generator(this, function(_state) {
|
|
171
|
+
switch(_state.label){
|
|
172
|
+
case 0:
|
|
173
|
+
// Only handle WEBHOOK events
|
|
174
|
+
if (event.type !== BRAIN_EVENTS.WEBHOOK) {
|
|
175
|
+
return [
|
|
176
|
+
2
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
180
|
+
_state.label = 1;
|
|
181
|
+
case 1:
|
|
182
|
+
_state.trys.push([
|
|
183
|
+
1,
|
|
184
|
+
6,
|
|
185
|
+
7,
|
|
186
|
+
8
|
|
187
|
+
]);
|
|
188
|
+
_iterator = event.waitFor[Symbol.iterator]();
|
|
189
|
+
_state.label = 2;
|
|
190
|
+
case 2:
|
|
191
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
192
|
+
3,
|
|
193
|
+
5
|
|
194
|
+
];
|
|
195
|
+
registration = _step.value;
|
|
196
|
+
return [
|
|
197
|
+
4,
|
|
198
|
+
this.monitorStub.registerWebhook(registration.slug, registration.identifier, event.brainRunId)
|
|
199
|
+
];
|
|
200
|
+
case 3:
|
|
201
|
+
_state.sent();
|
|
202
|
+
_state.label = 4;
|
|
203
|
+
case 4:
|
|
204
|
+
_iteratorNormalCompletion = true;
|
|
205
|
+
return [
|
|
206
|
+
3,
|
|
207
|
+
2
|
|
208
|
+
];
|
|
209
|
+
case 5:
|
|
210
|
+
return [
|
|
211
|
+
3,
|
|
212
|
+
8
|
|
213
|
+
];
|
|
214
|
+
case 6:
|
|
215
|
+
err = _state.sent();
|
|
216
|
+
_didIteratorError = true;
|
|
217
|
+
_iteratorError = err;
|
|
218
|
+
return [
|
|
219
|
+
3,
|
|
220
|
+
8
|
|
221
|
+
];
|
|
222
|
+
case 7:
|
|
223
|
+
try {
|
|
224
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
225
|
+
_iterator.return();
|
|
226
|
+
}
|
|
227
|
+
} finally{
|
|
228
|
+
if (_didIteratorError) {
|
|
229
|
+
throw _iteratorError;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return [
|
|
233
|
+
7
|
|
234
|
+
];
|
|
235
|
+
case 8:
|
|
236
|
+
return [
|
|
237
|
+
2
|
|
238
|
+
];
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}).call(this);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
]);
|
|
245
|
+
return WebhookAdapter;
|
|
246
|
+
}();
|
package/dist/types/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,2BAA2B,CAAC;AAGpE,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmBF,QAAA,MAAM,GAAG;cAAwB,QAAQ;yCAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,2BAA2B,CAAC;AAGpE,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmBF,QAAA,MAAM,GAAG;cAAwB,QAAQ;yCAAK,CAAC;AAmwB/C,eAAe,GAAG,CAAC"}
|
|
@@ -7,6 +7,8 @@ import type { R2Bucket } from '@cloudflare/workers-types';
|
|
|
7
7
|
export declare function setManifest(generatedManifest: PositronicManifest): void;
|
|
8
8
|
export declare function getManifest(): PositronicManifest | null;
|
|
9
9
|
export declare function setBrainRunner(runner: BrainRunner): void;
|
|
10
|
+
export declare function setWebhookManifest(manifest: Record<string, any>): void;
|
|
11
|
+
export declare function getWebhookManifest(): Record<string, any> | null;
|
|
10
12
|
export interface Env {
|
|
11
13
|
BRAIN_RUNNER_DO: DurableObjectNamespace;
|
|
12
14
|
MONITOR_DO: DurableObjectNamespace<MonitorDO>;
|
|
@@ -17,9 +19,15 @@ export declare class BrainRunnerDO extends DurableObject<Env> {
|
|
|
17
19
|
private sql;
|
|
18
20
|
private brainRunId;
|
|
19
21
|
private eventStreamAdapter;
|
|
22
|
+
private abortController;
|
|
20
23
|
constructor(state: DurableObjectState, env: Env);
|
|
21
24
|
private loadResourcesFromR2;
|
|
25
|
+
kill(): Promise<{
|
|
26
|
+
success: boolean;
|
|
27
|
+
message: string;
|
|
28
|
+
}>;
|
|
22
29
|
start(brainTitle: string, brainRunId: string, initialData?: Record<string, any>): Promise<void>;
|
|
30
|
+
resume(brainRunId: string, webhookResponse: Record<string, any>): Promise<void>;
|
|
23
31
|
fetch(request: Request): Promise<Response>;
|
|
24
32
|
}
|
|
25
33
|
//# sourceMappingURL=brain-runner-do.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"brain-runner-do.d.ts","sourceRoot":"","sources":["../../src/brain-runner-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"brain-runner-do.d.ts","sourceRoot":"","sources":["../../src/brain-runner-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAwC,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAKnD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAG1D,wBAAgB,WAAW,CAAC,iBAAiB,EAAE,kBAAkB,QAEhE;AAED,wBAAgB,WAAW,IAAI,kBAAkB,GAAG,IAAI,CAEvD;AAGD,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,QAEjD;AAGD,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,QAE/D;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAE/D;AAED,MAAM,WAAW,GAAG;IAClB,eAAe,EAAE,sBAAsB,CAAC;IACxC,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;CAC5B;AAwDD,qBAAa,aAAc,SAAQ,aAAa,CAAC,GAAG,CAAC;IACnD,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,eAAe,CAAgC;gBAE3C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;YAOjC,mBAAmB;IA0E3B,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAStD,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAuF7B,MAAM,CACV,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAuHhC,KAAK,CAAC,OAAO,EAAE,OAAO;CA4E7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/dev-server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/dev-server.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA4M1E,qBAAa,mBAAoB,YAAW,mBAAmB;IAyB1C,cAAc,EAAE,MAAM;IAjBzC;;;;;;;;;;;OAWG;IAEH,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,gBAAgB,CAAwC;gBAE7C,cAAc,EAAE,MAAM;IAEnC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAiB7B,qBAAqB;YA4DrB,wBAAwB;YAqBxB,yBAAyB;YAQzB,2BAA2B;IAuBzC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,wBAAwB;YASlB,0BAA0B;IA4BxC,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,gBAAgB;IA4BlB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAkD3C,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GACjC,OAAO,CAAC,IAAI,CAAC;IAUV,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA6E7B,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIhD,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIlD,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI9C,WAAW,IAAI,OAAO,CAC1B,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC,CAC5D;IAwCK,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CrD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuC5C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA0DnD"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BrainRunnerDO, setBrainRunner, setManifest, getManifest, } from './brain-runner-do.js';
|
|
1
|
+
export { BrainRunnerDO, setBrainRunner, setManifest, getManifest, setWebhookManifest, } from './brain-runner-do.js';
|
|
2
2
|
export { MonitorDO } from './monitor-do.js';
|
|
3
3
|
export { ScheduleDO } from './schedule-do.js';
|
|
4
4
|
export { PositronicManifest, type BrainMetadata, type ResolutionResult } from './manifest.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,cAAc,EACd,WAAW,EACX,WAAW,EACX,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,KAAK,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,EAAE,OAAO,IAAI,GAAG,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -9,8 +9,23 @@ export declare class MonitorDO extends DurableObject<Env> {
|
|
|
9
9
|
handleBrainEvent(event: BrainEvent<any>): void;
|
|
10
10
|
private broadcastRunningBrains;
|
|
11
11
|
fetch(request: Request): Promise<Response>;
|
|
12
|
-
getLastEvent(brainRunId: string): Record<string, SqlStorageValue
|
|
12
|
+
getLastEvent(brainRunId: string): Record<string, SqlStorageValue> | null;
|
|
13
13
|
history(brainTitle: string, limit?: number): Record<string, SqlStorageValue>[];
|
|
14
14
|
activeRuns(brainTitle: string): Record<string, SqlStorageValue>[];
|
|
15
|
+
/**
|
|
16
|
+
* Register a webhook to wait for
|
|
17
|
+
* Called when a brain emits a WEBHOOK event
|
|
18
|
+
*/
|
|
19
|
+
registerWebhook(slug: string, identifier: string, brainRunId: string): void;
|
|
20
|
+
/**
|
|
21
|
+
* Find a brain waiting for this webhook
|
|
22
|
+
* Returns the brain_run_id if found, null otherwise
|
|
23
|
+
*/
|
|
24
|
+
findWaitingBrain(slug: string, identifier: string): string | null;
|
|
25
|
+
/**
|
|
26
|
+
* Clear all webhook registrations for a brain run
|
|
27
|
+
* Called when brain completes, errors, or is cancelled
|
|
28
|
+
*/
|
|
29
|
+
clearWebhookRegistrations(brainRunId: string): void;
|
|
15
30
|
}
|
|
16
31
|
//# sourceMappingURL=monitor-do.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"monitor-do.d.ts","sourceRoot":"","sources":["../../src/monitor-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,GAAG;CAEnB;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,GAAG,CAAC;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;
|
|
1
|
+
{"version":3,"file":"monitor-do.d.ts","sourceRoot":"","sources":["../../src/monitor-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,WAAW,GAAG;CAEnB;AAED,qBAAa,SAAU,SAAQ,aAAa,CAAC,GAAG,CAAC;IAC/C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAA4B;gBAE1C,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAyC/C,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC;YA4DzB,sBAAsB;IA0B9B,KAAK,CAAC,OAAO,EAAE,OAAO;IA0D5B,YAAY,CAAC,UAAU,EAAE,MAAM;IAc/B,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW;IA6B9C,UAAU,CAAC,UAAU,EAAE,MAAM;IAyB7B;;;OAGG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;IAapE;;;OAGG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAiBjE;;;OAGG;IACH,yBAAyB,CAAC,UAAU,EAAE,MAAM;CAS7C"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Adapter, BrainEvent } from '@positronic/core';
|
|
2
|
+
import type { MonitorDO } from './monitor-do.js';
|
|
3
|
+
/**
|
|
4
|
+
* Adapter that handles WEBHOOK events by registering webhooks
|
|
5
|
+
* with the MonitorDO for brain resumption
|
|
6
|
+
*/
|
|
7
|
+
export declare class WebhookAdapter implements Adapter {
|
|
8
|
+
private monitorStub;
|
|
9
|
+
constructor(monitorStub: {
|
|
10
|
+
registerWebhook: MonitorDO['registerWebhook'];
|
|
11
|
+
});
|
|
12
|
+
dispatch(event: BrainEvent): Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=webhook-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-adapter.d.ts","sourceRoot":"","sources":["../../src/webhook-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,qBAAa,cAAe,YAAW,OAAO;IAChC,OAAO,CAAC,WAAW;gBAAX,WAAW,EAAE;QAAE,eAAe,EAAE,SAAS,CAAC,iBAAiB,CAAC,CAAA;KAAE;IAE5E,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAejD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@positronic/cloudflare",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"clean": "rm -rf tsconfig.tsbuildinfo dist"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@positronic/core": "^0.0.
|
|
35
|
-
"@positronic/spec": "^0.0.
|
|
36
|
-
"@positronic/template-new-project": "^0.0.
|
|
34
|
+
"@positronic/core": "^0.0.20",
|
|
35
|
+
"@positronic/spec": "^0.0.20",
|
|
36
|
+
"@positronic/template-new-project": "^0.0.20",
|
|
37
37
|
"aws4fetch": "^1.0.18",
|
|
38
38
|
"caz": "^2.0.0",
|
|
39
39
|
"cron-schedule": "^5.0.4",
|