@positronic/cloudflare 0.0.19 → 0.0.21
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 +189 -1
- package/dist/src/brain-runner-do.js +112 -3
- package/dist/src/dev-server.js +2 -1
- package/dist/src/index.js +1 -1
- package/dist/src/monitor-do.js +33 -2
- 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 +3 -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 +15 -0
- 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) {
|
|
@@ -1472,4 +1518,146 @@ app.post('/resources/presigned-link', function(context) {
|
|
|
1472
1518
|
});
|
|
1473
1519
|
})();
|
|
1474
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
|
+
// Handle verification challenge (for Slack, Stripe, GitHub, Discord)
|
|
1595
|
+
if (result.type === 'verification') {
|
|
1596
|
+
return [
|
|
1597
|
+
2,
|
|
1598
|
+
context.json({
|
|
1599
|
+
challenge: result.challenge
|
|
1600
|
+
})
|
|
1601
|
+
];
|
|
1602
|
+
}
|
|
1603
|
+
// Normal webhook processing - check if there's a brain waiting
|
|
1604
|
+
monitorId = context.env.MONITOR_DO.idFromName('singleton');
|
|
1605
|
+
monitorStub = context.env.MONITOR_DO.get(monitorId);
|
|
1606
|
+
return [
|
|
1607
|
+
4,
|
|
1608
|
+
monitorStub.findWaitingBrain(slug, result.identifier)
|
|
1609
|
+
];
|
|
1610
|
+
case 3:
|
|
1611
|
+
brainRunId = _state.sent();
|
|
1612
|
+
if (!brainRunId) return [
|
|
1613
|
+
3,
|
|
1614
|
+
5
|
|
1615
|
+
];
|
|
1616
|
+
// Found a brain waiting for this webhook - resume it
|
|
1617
|
+
namespace = context.env.BRAIN_RUNNER_DO;
|
|
1618
|
+
doId = namespace.idFromName(brainRunId);
|
|
1619
|
+
stub = namespace.get(doId);
|
|
1620
|
+
// Resume the brain with the webhook response
|
|
1621
|
+
return [
|
|
1622
|
+
4,
|
|
1623
|
+
stub.resume(brainRunId, result.response)
|
|
1624
|
+
];
|
|
1625
|
+
case 4:
|
|
1626
|
+
_state.sent();
|
|
1627
|
+
return [
|
|
1628
|
+
2,
|
|
1629
|
+
context.json({
|
|
1630
|
+
received: true,
|
|
1631
|
+
action: 'resumed',
|
|
1632
|
+
identifier: result.identifier,
|
|
1633
|
+
brainRunId: brainRunId
|
|
1634
|
+
})
|
|
1635
|
+
];
|
|
1636
|
+
case 5:
|
|
1637
|
+
// No brain waiting for this webhook
|
|
1638
|
+
return [
|
|
1639
|
+
2,
|
|
1640
|
+
context.json({
|
|
1641
|
+
received: true,
|
|
1642
|
+
action: 'queued',
|
|
1643
|
+
identifier: result.identifier
|
|
1644
|
+
})
|
|
1645
|
+
];
|
|
1646
|
+
case 6:
|
|
1647
|
+
error = _state.sent();
|
|
1648
|
+
console.error("Error receiving webhook ".concat(slug, ":"), error);
|
|
1649
|
+
return [
|
|
1650
|
+
2,
|
|
1651
|
+
context.json({
|
|
1652
|
+
error: 'Failed to process webhook'
|
|
1653
|
+
}, 500)
|
|
1654
|
+
];
|
|
1655
|
+
case 7:
|
|
1656
|
+
return [
|
|
1657
|
+
2
|
|
1658
|
+
];
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
})();
|
|
1662
|
+
});
|
|
1475
1663
|
export default app;
|
|
@@ -243,8 +243,10 @@ function _ts_generator(thisArg, body) {
|
|
|
243
243
|
};
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
|
+
import { STATUS, BRAIN_EVENTS } from '@positronic/core';
|
|
246
247
|
import { DurableObject } from 'cloudflare:workers';
|
|
247
248
|
import { BrainRunSQLiteAdapter } from './sqlite-adapter.js';
|
|
249
|
+
import { WebhookAdapter } from './webhook-adapter.js';
|
|
248
250
|
import { CloudflareR2Loader } from './r2-loader.js';
|
|
249
251
|
import { createResources } from '@positronic/core';
|
|
250
252
|
var manifest = null;
|
|
@@ -258,6 +260,13 @@ var brainRunner = null;
|
|
|
258
260
|
export function setBrainRunner(runner) {
|
|
259
261
|
brainRunner = runner;
|
|
260
262
|
}
|
|
263
|
+
var webhookManifest = null;
|
|
264
|
+
export function setWebhookManifest(manifest) {
|
|
265
|
+
webhookManifest = manifest;
|
|
266
|
+
}
|
|
267
|
+
export function getWebhookManifest() {
|
|
268
|
+
return webhookManifest;
|
|
269
|
+
}
|
|
261
270
|
var EventStreamAdapter = /*#__PURE__*/ function() {
|
|
262
271
|
"use strict";
|
|
263
272
|
function EventStreamAdapter() {
|
|
@@ -560,7 +569,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
560
569
|
key: "start",
|
|
561
570
|
value: function start(brainTitle, brainRunId, initialData) {
|
|
562
571
|
return _async_to_generator(function() {
|
|
563
|
-
var _this, 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;
|
|
564
573
|
return _ts_generator(this, function(_state) {
|
|
565
574
|
switch(_state.label){
|
|
566
575
|
case 0:
|
|
@@ -586,8 +595,10 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
586
595
|
}
|
|
587
596
|
sqliteAdapter = new BrainRunSQLiteAdapter(sql);
|
|
588
597
|
eventStreamAdapter = this.eventStreamAdapter;
|
|
589
|
-
|
|
598
|
+
monitorDOStub = this.env.MONITOR_DO.get(this.env.MONITOR_DO.idFromName('singleton'));
|
|
599
|
+
monitorAdapter = new MonitorAdapter(monitorDOStub);
|
|
590
600
|
scheduleAdapter = new ScheduleAdapter(this.env.SCHEDULE_DO.get(this.env.SCHEDULE_DO.idFromName('singleton')));
|
|
601
|
+
webhookAdapter = new WebhookAdapter(monitorDOStub);
|
|
591
602
|
if (!brainRunner) {
|
|
592
603
|
throw new Error('BrainRunner not initialized');
|
|
593
604
|
}
|
|
@@ -612,7 +623,8 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
612
623
|
sqliteAdapter,
|
|
613
624
|
eventStreamAdapter,
|
|
614
625
|
monitorAdapter,
|
|
615
|
-
scheduleAdapter
|
|
626
|
+
scheduleAdapter,
|
|
627
|
+
webhookAdapter
|
|
616
628
|
]).run(brainToRun, _object_spread_props(_object_spread({
|
|
617
629
|
initialState: initialState,
|
|
618
630
|
brainRunId: brainRunId
|
|
@@ -622,6 +634,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
622
634
|
signal: this.abortController.signal
|
|
623
635
|
})).catch(function(err) {
|
|
624
636
|
console.error("[DO ".concat(brainRunId, "] BrainRunner run failed:"), err);
|
|
637
|
+
throw err; // Re-throw to ensure proper error propagation
|
|
625
638
|
}).finally(function() {
|
|
626
639
|
// Clean up abort controller when run completes
|
|
627
640
|
_this.abortController = null;
|
|
@@ -634,6 +647,102 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
634
647
|
}).call(this);
|
|
635
648
|
}
|
|
636
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;
|
|
737
|
+
});
|
|
738
|
+
return [
|
|
739
|
+
2
|
|
740
|
+
];
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
}).call(this);
|
|
744
|
+
}
|
|
745
|
+
},
|
|
637
746
|
{
|
|
638
747
|
key: "fetch",
|
|
639
748
|
value: function fetch(request) {
|
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,7 +218,7 @@ 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, [
|
|
@@ -232,6 +232,10 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
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,7 +345,6 @@ 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();
|
|
@@ -364,6 +367,34 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
|
|
|
364
367
|
value: function activeRuns(brainTitle) {
|
|
365
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();
|
|
366
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
|
+
}
|
|
367
398
|
}
|
|
368
399
|
]);
|
|
369
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;AAwwB/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>;
|
|
@@ -25,6 +27,7 @@ export declare class BrainRunnerDO extends DurableObject<Env> {
|
|
|
25
27
|
message: string;
|
|
26
28
|
}>;
|
|
27
29
|
start(brainTitle: string, brainRunId: string, initialData?: Record<string, any>): Promise<void>;
|
|
30
|
+
resume(brainRunId: string, webhookResponse: Record<string, any>): Promise<void>;
|
|
28
31
|
fetch(request: Request): Promise<Response>;
|
|
29
32
|
}
|
|
30
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"}
|
|
@@ -12,5 +12,20 @@ export declare class MonitorDO extends DurableObject<Env> {
|
|
|
12
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.21",
|
|
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.21",
|
|
35
|
+
"@positronic/spec": "^0.0.21",
|
|
36
|
+
"@positronic/template-new-project": "^0.0.21",
|
|
37
37
|
"aws4fetch": "^1.0.18",
|
|
38
38
|
"caz": "^2.0.0",
|
|
39
39
|
"cron-schedule": "^5.0.4",
|