@positronic/cloudflare 0.0.65 → 0.0.67

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.
@@ -155,7 +155,7 @@ function _ts_generator(thisArg, body) {
155
155
  }
156
156
  import { Hono } from 'hono';
157
157
  import { v4 as uuidv4 } from 'uuid';
158
- import { parseCronExpression } from 'cron-schedule';
158
+ import { Cron } from 'croner';
159
159
  import Fuse from 'fuse.js';
160
160
  import { isSignalValid, brainMachineDefinition } from '@positronic/core';
161
161
  import { getManifest } from '../brain-runner-do.js';
@@ -922,15 +922,15 @@ brains.get('/', function(context) {
922
922
  // Create a new schedule
923
923
  brains.post('/schedules', function(context) {
924
924
  return _async_to_generator(function() {
925
- var body, cronExpression, identifier, manifest, resolution, brain, brainTitle, scheduleId, scheduleStub, schedule, error, errorMessage;
925
+ var body, cronExpression, identifier, manifest, resolution, brain, brainTitle, scheduleDoId, scheduleStub, timezone, schedule, error, errorMessage;
926
926
  return _ts_generator(this, function(_state) {
927
927
  switch(_state.label){
928
928
  case 0:
929
929
  _state.trys.push([
930
930
  0,
931
- 3,
931
+ 5,
932
932
  ,
933
- 4
933
+ 6
934
934
  ]);
935
935
  return [
936
936
  4,
@@ -959,7 +959,7 @@ brains.post('/schedules', function(context) {
959
959
  }
960
960
  // Validate cron expression before calling DO
961
961
  try {
962
- parseCronExpression(cronExpression);
962
+ new Cron(cronExpression);
963
963
  } catch (e) {
964
964
  return [
965
965
  2,
@@ -1001,19 +1001,46 @@ brains.post('/schedules', function(context) {
1001
1001
  brain = resolution.brain;
1002
1002
  brainTitle = brain.title || identifier;
1003
1003
  // Get the schedule singleton instance
1004
- scheduleId = context.env.SCHEDULE_DO.idFromName('singleton');
1005
- scheduleStub = context.env.SCHEDULE_DO.get(scheduleId);
1004
+ scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
1005
+ scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
1006
+ // Determine timezone: use provided value, fall back to project timezone
1007
+ timezone = body.timezone;
1008
+ if (!!timezone) return [
1009
+ 3,
1010
+ 3
1011
+ ];
1006
1012
  return [
1007
1013
  4,
1008
- scheduleStub.createSchedule(brainTitle, cronExpression)
1014
+ scheduleStub.getProjectTimezone()
1009
1015
  ];
1010
1016
  case 2:
1017
+ timezone = _state.sent();
1018
+ _state.label = 3;
1019
+ case 3:
1020
+ // Validate timezone
1021
+ try {
1022
+ Intl.DateTimeFormat(undefined, {
1023
+ timeZone: timezone
1024
+ });
1025
+ } catch (e) {
1026
+ return [
1027
+ 2,
1028
+ context.json({
1029
+ error: "Invalid timezone: ".concat(timezone)
1030
+ }, 400)
1031
+ ];
1032
+ }
1033
+ return [
1034
+ 4,
1035
+ scheduleStub.createSchedule(brainTitle, cronExpression, timezone)
1036
+ ];
1037
+ case 4:
1011
1038
  schedule = _state.sent();
1012
1039
  return [
1013
1040
  2,
1014
1041
  context.json(schedule, 201)
1015
1042
  ];
1016
- case 3:
1043
+ case 5:
1017
1044
  error = _state.sent();
1018
1045
  errorMessage = _instanceof(error, Error) ? error.message : 'Failed to create schedule';
1019
1046
  return [
@@ -1022,7 +1049,7 @@ brains.post('/schedules', function(context) {
1022
1049
  error: errorMessage
1023
1050
  }, 400)
1024
1051
  ];
1025
- case 4:
1052
+ case 6:
1026
1053
  return [
1027
1054
  2
1028
1055
  ];
@@ -1078,6 +1105,84 @@ brains.get('/schedules/runs', function(context) {
1078
1105
  });
1079
1106
  })();
1080
1107
  });
1108
+ // Get project timezone
1109
+ brains.get('/schedules/timezone', function(context) {
1110
+ return _async_to_generator(function() {
1111
+ var scheduleDoId, scheduleStub, timezone;
1112
+ return _ts_generator(this, function(_state) {
1113
+ switch(_state.label){
1114
+ case 0:
1115
+ scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
1116
+ scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
1117
+ return [
1118
+ 4,
1119
+ scheduleStub.getProjectTimezone()
1120
+ ];
1121
+ case 1:
1122
+ timezone = _state.sent();
1123
+ return [
1124
+ 2,
1125
+ context.json({
1126
+ timezone: timezone
1127
+ })
1128
+ ];
1129
+ }
1130
+ });
1131
+ })();
1132
+ });
1133
+ // Set project timezone
1134
+ brains.put('/schedules/timezone', function(context) {
1135
+ return _async_to_generator(function() {
1136
+ var body, timezone, scheduleDoId, scheduleStub;
1137
+ return _ts_generator(this, function(_state) {
1138
+ switch(_state.label){
1139
+ case 0:
1140
+ return [
1141
+ 4,
1142
+ context.req.json()
1143
+ ];
1144
+ case 1:
1145
+ body = _state.sent();
1146
+ timezone = body.timezone;
1147
+ if (!timezone) {
1148
+ return [
1149
+ 2,
1150
+ context.json({
1151
+ error: 'Missing required field "timezone"'
1152
+ }, 400)
1153
+ ];
1154
+ }
1155
+ // Validate timezone
1156
+ try {
1157
+ Intl.DateTimeFormat(undefined, {
1158
+ timeZone: timezone
1159
+ });
1160
+ } catch (e) {
1161
+ return [
1162
+ 2,
1163
+ context.json({
1164
+ error: "Invalid timezone: ".concat(timezone)
1165
+ }, 400)
1166
+ ];
1167
+ }
1168
+ scheduleDoId = context.env.SCHEDULE_DO.idFromName('singleton');
1169
+ scheduleStub = context.env.SCHEDULE_DO.get(scheduleDoId);
1170
+ return [
1171
+ 4,
1172
+ scheduleStub.setProjectTimezone(timezone)
1173
+ ];
1174
+ case 2:
1175
+ _state.sent();
1176
+ return [
1177
+ 2,
1178
+ context.json({
1179
+ timezone: timezone
1180
+ })
1181
+ ];
1182
+ }
1183
+ });
1184
+ })();
1185
+ });
1081
1186
  // Delete a schedule
1082
1187
  brains.delete('/schedules/:scheduleId', function(context) {
1083
1188
  return _async_to_generator(function() {
@@ -825,7 +825,7 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
825
825
  * SQLite state is missing (zombie brain scenario).
826
826
  */ function kill(brainRunId, brainTitle) {
827
827
  return _async_to_generator(function() {
828
- var monitorStub, actualBrainRunId, actualBrainTitle, startEvent, eventLoader, err, existingRun, activeStatuses, cancelledEvent, _this_pageAdapter, pageAdapter;
828
+ var monitorStub, actualBrainRunId, actualBrainTitle, startEvent, eventLoader, err, existingRun, activeStatuses, cancelledEvent, pendingTimeout, _this_pageAdapter, pageAdapter;
829
829
  return _ts_generator(this, function(_state) {
830
830
  switch(_state.label){
831
831
  case 0:
@@ -933,6 +933,22 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
933
933
  brainRunId: actualBrainRunId,
934
934
  options: (startEvent === null || startEvent === void 0 ? void 0 : startEvent.options) || {}
935
935
  };
936
+ // Clean up any pending wait timeout and alarm to prevent spurious
937
+ // alarm fires after the brain has been manually cancelled.
938
+ pendingTimeout = this.getWaitTimeout();
939
+ if (!pendingTimeout) return [
940
+ 3,
941
+ 7
942
+ ];
943
+ this.clearWaitTimeout(pendingTimeout.brainRunId);
944
+ return [
945
+ 4,
946
+ this.ctx.storage.deleteAlarm()
947
+ ];
948
+ case 6:
949
+ _state.sent();
950
+ _state.label = 7;
951
+ case 7:
936
952
  // Dispatch to PageAdapter for cleanup (deletes non-persistent pages from R2)
937
953
  // This is needed because when a brain is paused (waiting for webhook), the BrainRunner
938
954
  // has already returned and adapters aren't receiving events through the normal pipeline.
@@ -942,13 +958,13 @@ export var BrainRunnerDO = /*#__PURE__*/ function(DurableObject) {
942
958
  4,
943
959
  pageAdapter.dispatch(cancelledEvent)
944
960
  ];
945
- case 6:
961
+ case 8:
946
962
  _state.sent();
947
963
  return [
948
964
  4,
949
965
  monitorStub.handleBrainEvent(cancelledEvent)
950
966
  ];
951
- case 7:
967
+ case 9:
952
968
  _state.sent();
953
969
  return [
954
970
  2,
@@ -238,7 +238,7 @@ function _ts_generator(thisArg, body) {
238
238
  }
239
239
  import { DurableObject } from 'cloudflare:workers';
240
240
  import { v4 as uuidv4 } from 'uuid';
241
- import { parseCronExpression } from 'cron-schedule';
241
+ import { Cron } from 'croner';
242
242
  import { BRAIN_EVENTS } from '@positronic/core';
243
243
  var ALARM_INTERVAL = 60 * 1000;
244
244
  export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
@@ -254,14 +254,21 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
254
254
  _this.storage = state.storage.sql;
255
255
  // Initialize database schema
256
256
  _this.storage.exec("\n CREATE TABLE IF NOT EXISTS schedules (\n id TEXT PRIMARY KEY,\n brain_title TEXT NOT NULL,\n cron_expression TEXT NOT NULL,\n enabled INTEGER NOT NULL DEFAULT 1,\n created_at INTEGER NOT NULL,\n next_run_at INTEGER\n );\n\n CREATE INDEX IF NOT EXISTS idx_schedules_brain\n ON schedules(brain_title);\n\n CREATE INDEX IF NOT EXISTS idx_schedules_enabled\n ON schedules(enabled);\n\n CREATE TABLE IF NOT EXISTS scheduled_runs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n schedule_id TEXT NOT NULL,\n brain_run_id TEXT UNIQUE,\n status TEXT NOT NULL CHECK(status IN ('triggered', 'failed', 'complete')),\n ran_at INTEGER NOT NULL,\n completed_at INTEGER,\n error TEXT,\n FOREIGN KEY (schedule_id) REFERENCES schedules(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_runs_schedule\n ON scheduled_runs(schedule_id, ran_at DESC);\n ");
257
+ // Migration: add timezone column for existing DOs
258
+ try {
259
+ _this.storage.exec("ALTER TABLE schedules ADD COLUMN timezone TEXT NOT NULL DEFAULT 'UTC'");
260
+ } catch (e) {
261
+ // Column already exists
262
+ }
257
263
  return _this;
258
264
  }
259
265
  _create_class(ScheduleDO, [
260
266
  {
261
267
  key: "createSchedule",
262
268
  value: function createSchedule(brainTitle, cronExpression) {
269
+ var timezone = arguments.length > 2 && arguments[2] !== void 0 ? arguments[2] : 'UTC';
263
270
  return _async_to_generator(function() {
264
- var id, createdAt, alarm, cron, nextRunAt;
271
+ var id, createdAt, alarm, nextRunAt;
265
272
  return _ts_generator(this, function(_state) {
266
273
  switch(_state.label){
267
274
  case 0:
@@ -291,15 +298,15 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
291
298
  case 3:
292
299
  // Note: Cron expression is validated at the API level before calling this method
293
300
  // Calculate next run time
294
- cron = parseCronExpression(cronExpression);
295
- nextRunAt = this.calculateNextRunTime(cron, createdAt);
296
- this.storage.exec("INSERT INTO schedules (id, brain_title, cron_expression, enabled, created_at, next_run_at)\n VALUES (?, ?, ?, 1, ?, ?)", id, brainTitle, cronExpression, createdAt, nextRunAt);
301
+ nextRunAt = this.calculateNextRunTime(cronExpression, createdAt, timezone);
302
+ this.storage.exec("INSERT INTO schedules (id, brain_title, cron_expression, timezone, enabled, created_at, next_run_at)\n VALUES (?, ?, ?, ?, 1, ?, ?)", id, brainTitle, cronExpression, timezone, createdAt, nextRunAt);
297
303
  return [
298
304
  2,
299
305
  {
300
306
  id: id,
301
307
  brainTitle: brainTitle,
302
308
  cronExpression: cronExpression,
309
+ timezone: timezone,
303
310
  enabled: true,
304
311
  createdAt: createdAt,
305
312
  nextRunAt: nextRunAt
@@ -316,7 +323,7 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
316
323
  return _async_to_generator(function() {
317
324
  var results, result;
318
325
  return _ts_generator(this, function(_state) {
319
- results = this.storage.exec("SELECT id, brain_title, cron_expression, enabled, created_at, next_run_at\n FROM schedules WHERE id = ?", scheduleId).toArray();
326
+ results = this.storage.exec("SELECT id, brain_title, cron_expression, timezone, enabled, created_at, next_run_at\n FROM schedules WHERE id = ?", scheduleId).toArray();
320
327
  if (results.length === 0) {
321
328
  return [
322
329
  2,
@@ -330,6 +337,7 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
330
337
  id: result.id,
331
338
  brainTitle: result.brain_title,
332
339
  cronExpression: result.cron_expression,
340
+ timezone: result.timezone || 'UTC',
333
341
  enabled: result.enabled === 1,
334
342
  createdAt: result.created_at,
335
343
  nextRunAt: result.next_run_at
@@ -408,11 +416,12 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
408
416
  _state.sent();
409
417
  _state.label = 4;
410
418
  case 4:
411
- schedules = this.storage.exec("SELECT id, brain_title, cron_expression, enabled, created_at, next_run_at\n FROM schedules\n ORDER BY created_at DESC").toArray().map(function(row) {
419
+ schedules = this.storage.exec("SELECT id, brain_title, cron_expression, timezone, enabled, created_at, next_run_at\n FROM schedules\n ORDER BY created_at DESC").toArray().map(function(row) {
412
420
  return {
413
421
  id: row.id,
414
422
  brainTitle: row.brain_title,
415
423
  cronExpression: row.cron_expression,
424
+ timezone: row.timezone || 'UTC',
416
425
  enabled: row.enabled === 1,
417
426
  createdAt: row.created_at,
418
427
  nextRunAt: row.next_run_at
@@ -485,7 +494,7 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
485
494
  value: // Handle the alarm trigger - runs every minute in a perpetual cycle
486
495
  function alarm() {
487
496
  return _async_to_generator(function() {
488
- var now, dueSchedules, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, schedule, scheduleId, brainTitle, cronExpression, brainRunId, error, errorMessage, cron, nextRunAt, err;
497
+ var now, dueSchedules, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, schedule, scheduleId, brainTitle, cronExpression, brainRunId, error, errorMessage, timezone, nextRunAt, err;
489
498
  return _ts_generator(this, function(_state) {
490
499
  switch(_state.label){
491
500
  case 0:
@@ -500,7 +509,7 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
500
509
  // checking every minute ensures we never miss a scheduled run.
501
510
  // Get all enabled schedules that are due
502
511
  now = Date.now();
503
- dueSchedules = this.storage.exec("SELECT id, brain_title, cron_expression\n FROM schedules\n WHERE enabled = 1 AND next_run_at <= ?", now).toArray();
512
+ dueSchedules = this.storage.exec("SELECT id, brain_title, cron_expression, timezone\n FROM schedules\n WHERE enabled = 1 AND next_run_at <= ?", now).toArray();
504
513
  _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
505
514
  _state.label = 1;
506
515
  case 1:
@@ -553,8 +562,8 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
553
562
  ];
554
563
  case 6:
555
564
  // Calculate and update next run time
556
- cron = parseCronExpression(cronExpression);
557
- nextRunAt = this.calculateNextRunTime(cron, now);
565
+ timezone = schedule.timezone || 'UTC';
566
+ nextRunAt = this.calculateNextRunTime(cronExpression, now, timezone);
558
567
  this.storage.exec("UPDATE schedules SET next_run_at = ? WHERE id = ?", nextRunAt, scheduleId);
559
568
  _state.label = 7;
560
569
  case 7:
@@ -685,8 +694,7 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
685
694
  key: "isValidCronExpression",
686
695
  value: function isValidCronExpression(expression) {
687
696
  try {
688
- // Try to parse the expression - if it throws, it's invalid
689
- parseCronExpression(expression);
697
+ new Cron(expression);
690
698
  return true;
691
699
  } catch (error) {
692
700
  return false;
@@ -695,10 +703,47 @@ export var ScheduleDO = /*#__PURE__*/ function(DurableObject) {
695
703
  },
696
704
  {
697
705
  key: "calculateNextRunTime",
698
- value: function calculateNextRunTime(cron, afterTime) {
699
- var nextDate = cron.getNextDate(new Date(afterTime));
706
+ value: function calculateNextRunTime(cronExpression, afterTime, timezone) {
707
+ var job = new Cron(cronExpression, {
708
+ timezone: timezone
709
+ });
710
+ var nextDate = job.nextRun(new Date(afterTime));
700
711
  return nextDate.getTime();
701
712
  }
713
+ },
714
+ {
715
+ key: "setProjectTimezone",
716
+ value: function setProjectTimezone(timezone) {
717
+ return _async_to_generator(function() {
718
+ return _ts_generator(this, function(_state) {
719
+ this.ctx.storage.put('projectTimezone', timezone);
720
+ return [
721
+ 2
722
+ ];
723
+ });
724
+ }).call(this);
725
+ }
726
+ },
727
+ {
728
+ key: "getProjectTimezone",
729
+ value: function getProjectTimezone() {
730
+ return _async_to_generator(function() {
731
+ return _ts_generator(this, function(_state) {
732
+ switch(_state.label){
733
+ case 0:
734
+ return [
735
+ 4,
736
+ this.ctx.storage.get('projectTimezone')
737
+ ];
738
+ case 1:
739
+ return [
740
+ 2,
741
+ _state.sent() || 'UTC'
742
+ ];
743
+ }
744
+ });
745
+ }).call(this);
746
+ }
702
747
  }
703
748
  ]);
704
749
  return ScheduleDO;
@@ -1 +1 @@
1
- {"version":3,"file":"brains.d.ts","sourceRoot":"","sources":["../../../src/api/brains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAM1C,OAAO,KAAK,EAAE,QAAQ,EAAiD,MAAM,YAAY,CAAC;AAE1F,QAAA,MAAM,MAAM;cAAwB,QAAQ;yCAAK,CAAC;AAsjBlD,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"brains.d.ts","sourceRoot":"","sources":["../../../src/api/brains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAM1C,OAAO,KAAK,EAAE,QAAQ,EAAiD,MAAM,YAAY,CAAC;AAE1F,QAAA,MAAM,MAAM;cAAwB,QAAQ;yCAAK,CAAC;AA+lBlD,eAAe,MAAM,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"brain-runner-do.d.ts","sourceRoot":"","sources":["../../src/brain-runner-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiG,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChK,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUnD,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,CAExD;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;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAsGD,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;IACvD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,2BAA2B,CAAS;gBAEhC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAO/C,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,0BAA0B;IAOlC,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAStD,gBAAgB,CAAC,UAAU,EAAE,MAAM;IAQnC,cAAc,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAWlE;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAmB9I;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,WAAW,EAAE;YA+C5D,mBAAmB;IAqEjC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAiBvB;;;;;;;;OAQG;IACG,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IA0E9F,KAAK;IASL,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAyHnC;;;;OAIG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM;IAyJzB,KAAK,CAAC,OAAO,EAAE,OAAO;CAkE7B"}
1
+ {"version":3,"file":"brain-runner-do.d.ts","sourceRoot":"","sources":["../../src/brain-runner-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAiG,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChK,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAUnD,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,CAExD;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;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAsGD,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;IACvD,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,uBAAuB,CAAS;IACxC,OAAO,CAAC,2BAA2B,CAAS;gBAEhC,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAO/C,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,0BAA0B;IAOlC,gBAAgB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;IAStD,gBAAgB,CAAC,UAAU,EAAE,MAAM;IAQnC,cAAc,IAAI;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAWlE;;;;OAIG;IACG,WAAW,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAmB9I;;;;OAIG;IACH,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,KAAK,GAAG,WAAW,EAAE;YA+C5D,mBAAmB;IAqEjC;;;OAGG;IACH,OAAO,CAAC,eAAe;IAiBvB;;;;;;;;OAQG;IACG,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAkF9F,KAAK;IASL,KAAK,CACT,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAyHnC;;;;OAIG;IACG,MAAM,CAAC,UAAU,EAAE,MAAM;IAyJzB,KAAK,CAAC,OAAO,EAAE,OAAO;CAkE7B"}
@@ -10,6 +10,7 @@ interface Schedule {
10
10
  id: string;
11
11
  brainTitle: string;
12
12
  cronExpression: string;
13
+ timezone: string;
13
14
  enabled: boolean;
14
15
  createdAt: number;
15
16
  nextRunAt?: number;
@@ -26,7 +27,7 @@ interface ScheduledRun {
26
27
  export declare class ScheduleDO extends DurableObject<Env> {
27
28
  private readonly storage;
28
29
  constructor(state: DurableObjectState, env: Env);
29
- createSchedule(brainTitle: string, cronExpression: string): Promise<Schedule>;
30
+ createSchedule(brainTitle: string, cronExpression: string, timezone?: string): Promise<Schedule>;
30
31
  getSchedule(scheduleId: string): Promise<Schedule | null>;
31
32
  deleteSchedule(scheduleId: string): Promise<boolean>;
32
33
  listSchedules(): Promise<{
@@ -42,6 +43,8 @@ export declare class ScheduleDO extends DurableObject<Env> {
42
43
  handleBrainEvent(event: BrainEvent<any>): Promise<void>;
43
44
  private isValidCronExpression;
44
45
  private calculateNextRunTime;
46
+ setProjectTimezone(timezone: string): Promise<void>;
47
+ getProjectTimezone(): Promise<string>;
45
48
  }
46
49
  export {};
47
50
  //# sourceMappingURL=schedule-do.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schedule-do.d.ts","sourceRoot":"","sources":["../../src/schedule-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,GAAG;IAClB,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,UAAW,SAAQ,aAAa,CAAC,GAAG,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;gBAEzB,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IAqCzC,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,QAAQ,CAAC;IAkCd,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAyBzD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYpD,aAAa,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAkClE,UAAU,CACd,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC;QAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA4C7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA2Ed,eAAe;IAcvB,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C7D,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,oBAAoB;CAI7B"}
1
+ {"version":3,"file":"schedule-do.d.ts","sourceRoot":"","sources":["../../src/schedule-do.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAgB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,MAAM,WAAW,GAAG;IAClB,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,YAAY;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,UAAW,SAAQ,aAAa,CAAC,GAAG,CAAC;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;gBAEzB,KAAK,EAAE,kBAAkB,EAAE,GAAG,EAAE,GAAG;IA4CzC,cAAc,CAClB,UAAU,EAAE,MAAM,EAClB,cAAc,EAAE,MAAM,EACtB,QAAQ,GAAE,MAAc,GACvB,OAAO,CAAC,QAAQ,CAAC;IAmCd,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IA0BzD,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAYpD,aAAa,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,QAAQ,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAmClE,UAAU,CACd,UAAU,CAAC,EAAE,MAAM,EACnB,KAAK,GAAE,MAAY,GAClB,OAAO,CAAC;QAAE,IAAI,EAAE,YAAY,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA4C7C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YA2Ed,eAAe;IAcvB,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C7D,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,oBAAoB;IAMtB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAInD,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC;CAG5C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@positronic/cloudflare",
3
- "version": "0.0.65",
3
+ "version": "0.0.67",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -31,12 +31,12 @@
31
31
  "clean": "rm -rf tsconfig.tsbuildinfo dist"
32
32
  },
33
33
  "dependencies": {
34
- "@positronic/core": "^0.0.65",
35
- "@positronic/spec": "^0.0.65",
36
- "@positronic/template-new-project": "^0.0.65",
34
+ "@positronic/core": "^0.0.67",
35
+ "@positronic/spec": "^0.0.67",
36
+ "@positronic/template-new-project": "^0.0.67",
37
37
  "aws4fetch": "^1.0.18",
38
38
  "caz": "^2.0.0",
39
- "cron-schedule": "^5.0.4",
39
+ "croner": "^10.0.1",
40
40
  "dotenv": "^16.0.3",
41
41
  "fuse.js": "^7.1.0",
42
42
  "hono": "^4.2.3",