@positronic/cloudflare 0.0.77 → 0.0.78

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.
Files changed (41) hide show
  1. package/dist/src/api/brains.js +90 -195
  2. package/dist/src/api/files.js +178 -0
  3. package/dist/src/api/index.js +9 -0
  4. package/dist/src/api/webhooks/coordination.js +0 -2
  5. package/dist/src/api/webhooks/index.js +43 -36
  6. package/dist/src/api/webhooks/system.js +23 -21
  7. package/dist/src/brain-runner-do.js +110 -170
  8. package/dist/src/content-type.js +6 -0
  9. package/dist/src/dev-server.js +128 -18
  10. package/dist/src/file-utils.js +7 -0
  11. package/dist/src/files-service.js +465 -0
  12. package/dist/src/manifest.js +13 -8
  13. package/dist/src/monitor-do.js +17 -0
  14. package/dist/src/schedule-do.js +5 -19
  15. package/dist/src/zip-builder.js +507 -0
  16. package/dist/types/api/brains.d.ts.map +1 -1
  17. package/dist/types/api/files.d.ts +7 -0
  18. package/dist/types/api/files.d.ts.map +1 -0
  19. package/dist/types/api/index.d.ts.map +1 -1
  20. package/dist/types/api/webhooks/coordination.d.ts +0 -1
  21. package/dist/types/api/webhooks/coordination.d.ts.map +1 -1
  22. package/dist/types/api/webhooks/index.d.ts.map +1 -1
  23. package/dist/types/api/webhooks/system.d.ts.map +1 -1
  24. package/dist/types/brain-runner-do.d.ts +13 -7
  25. package/dist/types/brain-runner-do.d.ts.map +1 -1
  26. package/dist/types/content-type.d.ts +2 -0
  27. package/dist/types/content-type.d.ts.map +1 -0
  28. package/dist/types/dev-server.d.ts +1 -0
  29. package/dist/types/dev-server.d.ts.map +1 -1
  30. package/dist/types/file-utils.d.ts +3 -0
  31. package/dist/types/file-utils.d.ts.map +1 -0
  32. package/dist/types/files-service.d.ts +4 -0
  33. package/dist/types/files-service.d.ts.map +1 -0
  34. package/dist/types/manifest.d.ts.map +1 -1
  35. package/dist/types/monitor-do.d.ts +6 -0
  36. package/dist/types/monitor-do.d.ts.map +1 -1
  37. package/dist/types/schedule-do.d.ts +0 -1
  38. package/dist/types/schedule-do.d.ts.map +1 -1
  39. package/dist/types/zip-builder.d.ts +4 -0
  40. package/dist/types/zip-builder.d.ts.map +1 -0
  41. package/package.json +5 -4
@@ -0,0 +1,465 @@
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 _instanceof(left, right) {
31
+ if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
32
+ return !!right[Symbol.hasInstance](left);
33
+ } else {
34
+ return left instanceof right;
35
+ }
36
+ }
37
+ function _ts_generator(thisArg, body) {
38
+ var f, y, t, _ = {
39
+ label: 0,
40
+ sent: function() {
41
+ if (t[0] & 1) throw t[1];
42
+ return t[1];
43
+ },
44
+ trys: [],
45
+ ops: []
46
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
47
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
48
+ return this;
49
+ }), g;
50
+ function verb(n) {
51
+ return function(v) {
52
+ return step([
53
+ n,
54
+ v
55
+ ]);
56
+ };
57
+ }
58
+ function step(op) {
59
+ if (f) throw new TypeError("Generator is already executing.");
60
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
61
+ 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;
62
+ if (y = 0, t) op = [
63
+ op[0] & 2,
64
+ t.value
65
+ ];
66
+ switch(op[0]){
67
+ case 0:
68
+ case 1:
69
+ t = op;
70
+ break;
71
+ case 4:
72
+ _.label++;
73
+ return {
74
+ value: op[1],
75
+ done: false
76
+ };
77
+ case 5:
78
+ _.label++;
79
+ y = op[1];
80
+ op = [
81
+ 0
82
+ ];
83
+ continue;
84
+ case 7:
85
+ op = _.ops.pop();
86
+ _.trys.pop();
87
+ continue;
88
+ default:
89
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
90
+ _ = 0;
91
+ continue;
92
+ }
93
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
94
+ _.label = op[1];
95
+ break;
96
+ }
97
+ if (op[0] === 6 && _.label < t[1]) {
98
+ _.label = t[1];
99
+ t = op;
100
+ break;
101
+ }
102
+ if (t && _.label < t[2]) {
103
+ _.label = t[2];
104
+ _.ops.push(op);
105
+ break;
106
+ }
107
+ if (t[2]) _.ops.pop();
108
+ _.trys.pop();
109
+ continue;
110
+ }
111
+ op = body.call(thisArg, _);
112
+ } catch (e) {
113
+ op = [
114
+ 6,
115
+ e
116
+ ];
117
+ y = 0;
118
+ } finally{
119
+ f = t = 0;
120
+ }
121
+ if (op[0] & 5) throw op[1];
122
+ return {
123
+ value: op[0] ? op[1] : void 0,
124
+ done: true
125
+ };
126
+ }
127
+ }
128
+ import { guessContentType } from './content-type.js';
129
+ import { createR2ZipBuilder } from './zip-builder.js';
130
+ import { isFileHandle } from './file-utils.js';
131
+ export function createFilesService(bucket, brainTitle, brainRunId, currentUser, env) {
132
+ function resolveKey(name, options) {
133
+ var _options_scope;
134
+ var scope = (_options_scope = options === null || options === void 0 ? void 0 : options.scope) !== null && _options_scope !== void 0 ? _options_scope : 'brain';
135
+ var userName = currentUser.name;
136
+ switch(scope){
137
+ case 'run':
138
+ return "files/user/".concat(userName, "/").concat(brainTitle, "/runs/").concat(brainRunId, "/").concat(name);
139
+ case 'brain':
140
+ return "files/user/".concat(userName, "/").concat(brainTitle, "/").concat(name);
141
+ case 'global':
142
+ return "files/user/".concat(userName, "/").concat(name);
143
+ }
144
+ }
145
+ function createFileHandle(name, options) {
146
+ var key = resolveKey(name, options);
147
+ function writeContent(content) {
148
+ return _async_to_generator(function() {
149
+ var contentType, sourceBytes;
150
+ return _ts_generator(this, function(_state) {
151
+ switch(_state.label){
152
+ case 0:
153
+ contentType = guessContentType(name);
154
+ if (!(typeof content === 'string')) return [
155
+ 3,
156
+ 2
157
+ ];
158
+ return [
159
+ 4,
160
+ bucket.put(key, content, {
161
+ httpMetadata: {
162
+ contentType: contentType
163
+ }
164
+ })
165
+ ];
166
+ case 1:
167
+ _state.sent();
168
+ return [
169
+ 3,
170
+ 11
171
+ ];
172
+ case 2:
173
+ if (!_instanceof(content, Uint8Array)) return [
174
+ 3,
175
+ 4
176
+ ];
177
+ return [
178
+ 4,
179
+ bucket.put(key, content, {
180
+ httpMetadata: {
181
+ contentType: contentType
182
+ }
183
+ })
184
+ ];
185
+ case 3:
186
+ _state.sent();
187
+ return [
188
+ 3,
189
+ 11
190
+ ];
191
+ case 4:
192
+ if (!_instanceof(content, Response)) return [
193
+ 3,
194
+ 6
195
+ ];
196
+ // R2's ReadableStream type differs from the standard lib's — cast through any
197
+ return [
198
+ 4,
199
+ bucket.put(key, content.body, {
200
+ httpMetadata: {
201
+ contentType: contentType
202
+ }
203
+ })
204
+ ];
205
+ case 5:
206
+ _state.sent();
207
+ return [
208
+ 3,
209
+ 11
210
+ ];
211
+ case 6:
212
+ if (!isFileHandle(content)) return [
213
+ 3,
214
+ 9
215
+ ];
216
+ return [
217
+ 4,
218
+ content.readBytes()
219
+ ];
220
+ case 7:
221
+ sourceBytes = _state.sent();
222
+ return [
223
+ 4,
224
+ bucket.put(key, sourceBytes, {
225
+ httpMetadata: {
226
+ contentType: contentType
227
+ }
228
+ })
229
+ ];
230
+ case 8:
231
+ _state.sent();
232
+ return [
233
+ 3,
234
+ 11
235
+ ];
236
+ case 9:
237
+ // ReadableStream — R2's type differs from standard lib's, cast through any
238
+ return [
239
+ 4,
240
+ bucket.put(key, content, {
241
+ httpMetadata: {
242
+ contentType: contentType
243
+ }
244
+ })
245
+ ];
246
+ case 10:
247
+ _state.sent();
248
+ _state.label = 11;
249
+ case 11:
250
+ return [
251
+ 2,
252
+ {
253
+ name: name
254
+ }
255
+ ];
256
+ }
257
+ });
258
+ })();
259
+ }
260
+ var handle = {
261
+ name: name,
262
+ get url () {
263
+ // R2 key is "files/user/..." — strip the "files/" prefix since the
264
+ // route is already mounted at /files/
265
+ return "".concat(env.origin, "/files/").concat(key.slice('files/'.length));
266
+ },
267
+ read: function read() {
268
+ return _async_to_generator(function() {
269
+ var object;
270
+ return _ts_generator(this, function(_state) {
271
+ switch(_state.label){
272
+ case 0:
273
+ return [
274
+ 4,
275
+ bucket.get(key)
276
+ ];
277
+ case 1:
278
+ object = _state.sent();
279
+ if (!object) {
280
+ throw new Error("File '".concat(name, "' not found"));
281
+ }
282
+ return [
283
+ 2,
284
+ object.text()
285
+ ];
286
+ }
287
+ });
288
+ })();
289
+ },
290
+ readBytes: function readBytes() {
291
+ return _async_to_generator(function() {
292
+ var object, arrayBuffer;
293
+ return _ts_generator(this, function(_state) {
294
+ switch(_state.label){
295
+ case 0:
296
+ return [
297
+ 4,
298
+ bucket.get(key)
299
+ ];
300
+ case 1:
301
+ object = _state.sent();
302
+ if (!object) {
303
+ throw new Error("File '".concat(name, "' not found"));
304
+ }
305
+ return [
306
+ 4,
307
+ object.arrayBuffer()
308
+ ];
309
+ case 2:
310
+ arrayBuffer = _state.sent();
311
+ return [
312
+ 2,
313
+ new Uint8Array(arrayBuffer)
314
+ ];
315
+ }
316
+ });
317
+ })();
318
+ },
319
+ write: writeContent,
320
+ exists: function exists() {
321
+ return _async_to_generator(function() {
322
+ var object;
323
+ return _ts_generator(this, function(_state) {
324
+ switch(_state.label){
325
+ case 0:
326
+ return [
327
+ 4,
328
+ bucket.head(key)
329
+ ];
330
+ case 1:
331
+ object = _state.sent();
332
+ return [
333
+ 2,
334
+ object !== null
335
+ ];
336
+ }
337
+ });
338
+ })();
339
+ },
340
+ delete: function _delete() {
341
+ return _async_to_generator(function() {
342
+ return _ts_generator(this, function(_state) {
343
+ switch(_state.label){
344
+ case 0:
345
+ return [
346
+ 4,
347
+ bucket.delete(key)
348
+ ];
349
+ case 1:
350
+ _state.sent();
351
+ return [
352
+ 2
353
+ ];
354
+ }
355
+ });
356
+ })();
357
+ }
358
+ };
359
+ return handle;
360
+ }
361
+ return {
362
+ open: function open(name, options) {
363
+ return createFileHandle(name, options);
364
+ },
365
+ write: function write(name, content, options) {
366
+ return _async_to_generator(function() {
367
+ var handle;
368
+ return _ts_generator(this, function(_state) {
369
+ handle = createFileHandle(name, options);
370
+ return [
371
+ 2,
372
+ handle.write(content)
373
+ ];
374
+ });
375
+ })();
376
+ },
377
+ list: function list() {
378
+ return _async_to_generator(function() {
379
+ var prefix, refs, cursor, listed, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, object, name;
380
+ return _ts_generator(this, function(_state) {
381
+ switch(_state.label){
382
+ case 0:
383
+ prefix = "files/user/".concat(currentUser.name, "/").concat(brainTitle, "/");
384
+ refs = [];
385
+ _state.label = 1;
386
+ case 1:
387
+ return [
388
+ 4,
389
+ bucket.list({
390
+ prefix: prefix,
391
+ cursor: cursor
392
+ })
393
+ ];
394
+ case 2:
395
+ listed = _state.sent();
396
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
397
+ try {
398
+ for(_iterator = listed.objects[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
399
+ object = _step.value;
400
+ // Extract the file name from the key by removing the prefix
401
+ name = object.key.slice(prefix.length);
402
+ // Skip run-scoped files (they're in a runs/ subdirectory)
403
+ if (!name.startsWith('runs/')) {
404
+ refs.push({
405
+ name: name
406
+ });
407
+ }
408
+ }
409
+ } catch (err) {
410
+ _didIteratorError = true;
411
+ _iteratorError = err;
412
+ } finally{
413
+ try {
414
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
415
+ _iterator.return();
416
+ }
417
+ } finally{
418
+ if (_didIteratorError) {
419
+ throw _iteratorError;
420
+ }
421
+ }
422
+ }
423
+ cursor = listed.truncated ? listed.cursor : undefined;
424
+ _state.label = 3;
425
+ case 3:
426
+ if (cursor) return [
427
+ 3,
428
+ 1
429
+ ];
430
+ _state.label = 4;
431
+ case 4:
432
+ return [
433
+ 2,
434
+ refs
435
+ ];
436
+ }
437
+ });
438
+ })();
439
+ },
440
+ delete: function _delete(name) {
441
+ return _async_to_generator(function() {
442
+ var handle;
443
+ return _ts_generator(this, function(_state) {
444
+ switch(_state.label){
445
+ case 0:
446
+ handle = createFileHandle(name);
447
+ return [
448
+ 4,
449
+ handle.delete()
450
+ ];
451
+ case 1:
452
+ _state.sent();
453
+ return [
454
+ 2
455
+ ];
456
+ }
457
+ });
458
+ })();
459
+ },
460
+ zip: function zip(name, options) {
461
+ var key = resolveKey(name, options);
462
+ return createR2ZipBuilder(bucket, key, name);
463
+ }
464
+ };
465
+ }
@@ -202,34 +202,39 @@ var DynamicImportStrategy = /*#__PURE__*/ function() {
202
202
  key: "import",
203
203
  value: function _import(filename) {
204
204
  return _async_to_generator(function() {
205
- var module, e;
205
+ var _this, module, e;
206
206
  return _ts_generator(this, function(_state) {
207
207
  switch(_state.label){
208
208
  case 0:
209
+ _this = this;
210
+ _state.label = 1;
211
+ case 1:
209
212
  _state.trys.push([
210
- 0,
211
- 2,
213
+ 1,
214
+ 3,
212
215
  ,
213
- 3
216
+ 4
214
217
  ]);
215
218
  return [
216
219
  4,
217
- import("".concat(this.brainsDir, "/").concat(filename, ".ts"))
220
+ import("".concat(this.brainsDir, "/").concat(filename, ".tsx")).catch(function() {
221
+ return import("".concat(_this.brainsDir, "/").concat(filename, ".ts"));
222
+ })
218
223
  ];
219
- case 1:
224
+ case 2:
220
225
  module = _state.sent();
221
226
  return [
222
227
  2,
223
228
  module.default
224
229
  ];
225
- case 2:
230
+ case 3:
226
231
  e = _state.sent();
227
232
  console.error("Failed to import brain ".concat(filename, ":"), e);
228
233
  return [
229
234
  2,
230
235
  undefined
231
236
  ];
232
- case 3:
237
+ case 4:
233
238
  return [
234
239
  2
235
240
  ];
@@ -331,6 +331,23 @@ export var MonitorDO = /*#__PURE__*/ function(DurableObject) {
331
331
  }
332
332
  }
333
333
  },
334
+ {
335
+ /**
336
+ * Reset MonitorDO tracking state for a brain run that is about to be rerun.
337
+ * Clears stale events (keeping START for hydration), resets status to RUNNING,
338
+ * and broadcasts so `top` subscribers see the brain immediately.
339
+ */ key: "prepareForRerun",
340
+ value: function prepareForRerun(runId) {
341
+ // Delete all events except START (needed for state machine hydration)
342
+ this.storage.exec("DELETE FROM brain_events WHERE run_id = ? AND event_type != ?", runId, BRAIN_EVENTS.START);
343
+ // Reset status to RUNNING, clear terminal fields
344
+ this.storage.exec("UPDATE brain_runs SET status = ?, completed_at = NULL, error = NULL WHERE run_id = ?", STATUS.RUNNING, runId);
345
+ // Clear cached machine so it re-hydrates from [START] → running state
346
+ this.machines.delete(runId);
347
+ // Notify top subscribers immediately
348
+ this.broadcastRunningBrains();
349
+ }
350
+ },
334
351
  {
335
352
  key: "broadcastRunningBrains",
336
353
  value: function broadcastRunningBrains() {
@@ -255,6 +255,7 @@ import { DurableObject } from 'cloudflare:workers';
255
255
  import { v4 as uuidv4 } from 'uuid';
256
256
  import { Cron } from 'croner';
257
257
  import { BRAIN_EVENTS } from '@positronic/core';
258
+ import { startBrainRun } from './brain-runner-do.js';
258
259
  var ALARM_INTERVAL = 60 * 1000;
259
260
  export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
260
261
  "use strict";
@@ -681,15 +682,10 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
681
682
  key: "triggerBrainRun",
682
683
  value: function triggerBrainRun(brainTitle, runAsUserName, options, initialState) {
683
684
  return _async_to_generator(function() {
684
- var brainRunId, namespace, doId, stub, initialData;
685
+ var initialData, brainRunId;
685
686
  return _ts_generator(this, function(_state) {
686
687
  switch(_state.label){
687
688
  case 0:
688
- brainRunId = uuidv4();
689
- namespace = this.env.BRAIN_RUNNER_DO;
690
- doId = namespace.idFromName(brainRunId);
691
- stub = namespace.get(doId);
692
- console.log("[ScheduleDO] Triggering brain run ".concat(brainTitle, " with id ").concat(brainRunId, " as user ").concat(runAsUserName));
693
689
  initialData = _object_spread({}, options && {
694
690
  options: options
695
691
  }, initialState && {
@@ -697,12 +693,13 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
697
693
  });
698
694
  return [
699
695
  4,
700
- stub.start(brainTitle, brainRunId, {
696
+ startBrainRun(this.env.BRAIN_RUNNER_DO, brainTitle, {
701
697
  name: runAsUserName
702
698
  }, Object.keys(initialData).length > 0 ? initialData : undefined)
703
699
  ];
704
700
  case 1:
705
- _state.sent();
701
+ brainRunId = _state.sent();
702
+ console.log("[ScheduleDO] Triggered brain run ".concat(brainTitle, " with id ").concat(brainRunId, " as user ").concat(runAsUserName));
706
703
  return [
707
704
  2,
708
705
  brainRunId
@@ -746,17 +743,6 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
746
743
  }).call(this);
747
744
  }
748
745
  },
749
- {
750
- key: "isValidCronExpression",
751
- value: function isValidCronExpression(expression) {
752
- try {
753
- new Cron(expression);
754
- return true;
755
- } catch (error) {
756
- return false;
757
- }
758
- }
759
- },
760
746
  {
761
747
  key: "calculateNextRunTime",
762
748
  value: function calculateNextRunTime(cronExpression, afterTime, timezone) {