@project-ajax/sdk 0.0.64 → 0.0.66

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.
@@ -1,5 +1,5 @@
1
1
  import type { PropertyConfiguration, PropertySchema, Schema } from "../schema.js";
2
- import type { Icon, PeopleValue, TextValue } from "../types.js";
2
+ import type { Icon, PeopleValue, Schedule, SyncSchedule, TextValue } from "../types.js";
3
3
  /**
4
4
  * Maps a property configuration to its corresponding value type.
5
5
  */
@@ -72,6 +72,17 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, Context =
72
72
  * @default false
73
73
  */
74
74
  deleteUnreturnedPages?: boolean;
75
+ /**
76
+ * How often the sync should run.
77
+ * - "continuous": Run as frequently as the system allows (default)
78
+ * - Interval string: Run at specified intervals, e.g. "1h", "30m", "1d"
79
+ *
80
+ * Minimum interval: 1 minute ("1m")
81
+ * Maximum interval: 7 days ("7d")
82
+ *
83
+ * @default "continuous"
84
+ */
85
+ schedule?: Schedule;
75
86
  /**
76
87
  * A function that fetches the data to sync from the third-party service.
77
88
  *
@@ -108,6 +119,7 @@ export declare function sync<PK extends string, S extends Schema<PK>, Context =
108
119
  primaryKeyProperty: PK;
109
120
  schema: S;
110
121
  deleteUnreturnedPages: boolean | undefined;
122
+ schedule: SyncSchedule;
111
123
  };
112
124
  handler(context?: Context): Promise<{
113
125
  objects: SyncedObject<PK, PropertySchema<PK>>[];
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,qBAAqB,EACrB,cAAc,EACd,MAAM,EACN,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhE;;GAEG;AACH,KAAK,iBAAiB,CAAC,CAAC,SAAS,qBAAqB,IAAI,CAAC,SAAS;IACnE,IAAI,EAAE,QAAQ,CAAC;CACf,GACE,WAAW,GACX,SAAS,CAAC;AAEb;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,SAAS,cAAc,CAAC,EAAE,CAAC,IAAI;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE;SACV,QAAQ,IAAI,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;KACrD,CAAC;IACF;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI;IACvE;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAEhD;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAC5B,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,OAAO,GAAG,OAAO,IACd;IACH;;;;OAIG;IACH,kBAAkB,EAAE,EAAE,CAAC;IAEvB;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;;;;;;;;OAaG;IACH,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;CAC1E,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI;IACrE,kBAAkB,EAAE,EAAE,CAAC;IACvB,OAAO,EAAE,YAAY,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,IAAI,CACnB,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,OAAO,GAAG,OAAO,EAChB,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC;;;;;;;sBAQ5B,OAAO;;;;;EAkBhC"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACX,qBAAqB,EACrB,cAAc,EACd,MAAM,EACN,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EACX,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,SAAS,EAET,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,KAAK,iBAAiB,CAAC,CAAC,SAAS,qBAAqB,IAAI,CAAC,SAAS;IACnE,IAAI,EAAE,QAAQ,CAAC;CACf,GACE,WAAW,GACX,SAAS,CAAC;AAEb;;GAEG;AACH,MAAM,MAAM,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC,SAAS,cAAc,CAAC,EAAE,CAAC,IAAI;IAC3E,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE;SACV,QAAQ,IAAI,MAAM,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;KACrD,CAAC;IACF;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI;IACvE;;OAEG;IACH,OAAO,EAAE,YAAY,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAEhD;;;;OAIG;IACH,IAAI,EAAE,OAAO,CAAC;IAEd;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,iBAAiB,CAC5B,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,OAAO,GAAG,OAAO,IACd;IACH;;;;OAIG;IACH,kBAAkB,EAAE,EAAE,CAAC;IAEvB;;OAEG;IACH,MAAM,EAAE,CAAC,CAAC;IAEV;;;;;;;;OAQG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;;;;;;;;;;OAaG;IACH,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;CAC1E,CAAC;AAEF,MAAM,MAAM,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,OAAO,GAAG,OAAO,IAAI;IACrE,kBAAkB,EAAE,EAAE,CAAC;IACvB,OAAO,EAAE,YAAY,CAAC,EAAE,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAChD,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,IAAI,CACnB,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,OAAO,GAAG,OAAO,EAChB,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC;;;;;;;;sBAS5B,OAAO;;;;;EAkBhC"}
@@ -1,11 +1,12 @@
1
- import { ExecutionError } from "../error.js";
1
+ import { ExecutionError, unreachable } from "../error.js";
2
2
  function sync(syncConfiguration) {
3
3
  return {
4
4
  _tag: "sync",
5
5
  config: {
6
6
  primaryKeyProperty: syncConfiguration.primaryKeyProperty,
7
7
  schema: syncConfiguration.schema,
8
- deleteUnreturnedPages: syncConfiguration.deleteUnreturnedPages
8
+ deleteUnreturnedPages: syncConfiguration.deleteUnreturnedPages,
9
+ schedule: parseSchedule(syncConfiguration.schedule)
9
10
  },
10
11
  async handler(context) {
11
12
  const executionResult = await syncConfiguration.execute(context).catch((err) => {
@@ -23,6 +24,49 @@ function sync(syncConfiguration) {
23
24
  }
24
25
  };
25
26
  }
27
+ const MS_PER_MINUTE = 60 * 1e3;
28
+ const MS_PER_HOUR = 60 * MS_PER_MINUTE;
29
+ const MS_PER_DAY = 24 * MS_PER_HOUR;
30
+ const MIN_INTERVAL_MS = MS_PER_MINUTE;
31
+ const MAX_INTERVAL_MS = 7 * MS_PER_DAY;
32
+ function parseSchedule(schedule) {
33
+ if (!schedule || schedule === "continuous") {
34
+ return { type: "continuous" };
35
+ }
36
+ const match = schedule.match(/^(\d+)(m|h|d)$/);
37
+ if (!match || !match[1] || !match[2]) {
38
+ throw new Error(
39
+ `Invalid schedule format: "${schedule}". Use "continuous" or an interval like "30m", "1h", "1d".`
40
+ );
41
+ }
42
+ const value = parseInt(match[1], 10);
43
+ const unit = match[2];
44
+ let intervalMs;
45
+ switch (unit) {
46
+ case "m":
47
+ intervalMs = value * MS_PER_MINUTE;
48
+ break;
49
+ case "h":
50
+ intervalMs = value * MS_PER_HOUR;
51
+ break;
52
+ case "d":
53
+ intervalMs = value * MS_PER_DAY;
54
+ break;
55
+ default:
56
+ unreachable(unit);
57
+ }
58
+ if (intervalMs < MIN_INTERVAL_MS) {
59
+ throw new Error(
60
+ `Schedule interval must be at least 1 minute. Got: "${schedule}"`
61
+ );
62
+ }
63
+ if (intervalMs > MAX_INTERVAL_MS) {
64
+ throw new Error(
65
+ `Schedule interval must be at most 7 days. Got: "${schedule}"`
66
+ );
67
+ }
68
+ return { type: "interval", intervalMs };
69
+ }
26
70
  export {
27
71
  sync
28
72
  };
package/dist/error.d.ts CHANGED
@@ -5,4 +5,8 @@ export declare class ExecutionError extends Error {
5
5
  readonly cause: unknown;
6
6
  constructor(cause: unknown);
7
7
  }
8
+ /**
9
+ * Helper for exhaustive switch statements. TypeScript will error if a case is not handled.
10
+ */
11
+ export declare function unreachable(value: never): never;
8
12
  //# sourceMappingURL=error.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACxC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBAEZ,KAAK,EAAE,OAAO;CAK1B"}
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACxC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;gBAEZ,KAAK,EAAE,OAAO;CAK1B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,KAAK,CAE/C"}
package/dist/error.js CHANGED
@@ -6,6 +6,10 @@ class ExecutionError extends Error {
6
6
  this.cause = cause;
7
7
  }
8
8
  }
9
+ function unreachable(value) {
10
+ throw new Error(`Unreachable: ${value}`);
11
+ }
9
12
  export {
10
- ExecutionError
13
+ ExecutionError,
14
+ unreachable
11
15
  };
package/dist/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export { automation } from "./capabilities/automation.js";
4
4
  export type { SyncConfiguration, SyncExecutionResult, SyncedObject, } from "./capabilities/sync.js";
5
5
  export { sync } from "./capabilities/sync.js";
6
6
  export { tool } from "./capabilities/tool.js";
7
- export type { Icon, ImageIcon, NoticonColor, NoticonName } from "./types.js";
7
+ export type { Icon, ImageIcon, NoticonColor, NoticonName, Schedule, } from "./types.js";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EACX,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,YAAY,EACX,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,YAAY,EACX,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAC9C,YAAY,EACX,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,QAAQ,GACR,MAAM,YAAY,CAAC"}
package/dist/types.d.ts CHANGED
@@ -130,4 +130,30 @@ export interface PersonReference {
130
130
  */
131
131
  export type PeopleValue = PersonReference[];
132
132
  export type { NoticonName } from "./icon-names.js";
133
+ /**
134
+ * Time units for schedule intervals.
135
+ * - "m": minutes
136
+ * - "h": hours
137
+ * - "d": days
138
+ */
139
+ export type TimeUnit = "m" | "h" | "d";
140
+ /**
141
+ * A string representing an interval, e.g. "30m", "1h", "7d".
142
+ */
143
+ export type IntervalString = `${number}${TimeUnit}`;
144
+ /**
145
+ * Schedule configuration for sync capabilities.
146
+ * - "continuous": Run as frequently as the system allows
147
+ * - IntervalString: Run at specified intervals, e.g. "30m", "1h", "1d"
148
+ */
149
+ export type Schedule = "continuous" | IntervalString;
150
+ /**
151
+ * Normalized schedule representation stored in the backend.
152
+ */
153
+ export type SyncSchedule = {
154
+ type: "continuous";
155
+ } | {
156
+ type: "interval";
157
+ intervalMs: number;
158
+ };
133
159
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,KAAK,SAAS,GAAG,CAAC,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AAExC;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC;AAEzC;;GAEG;AACH,MAAM,MAAM,WAAW,GACpB,SAAS,GACT,MAAM,GACN,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,MAAM,GACN,QAAQ,GACR,MAAM,GACN,KAAK,CAAC;AAET;;GAEG;AACH,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,WAAW,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,aAAa,GAAG,UAAU,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,YAAY,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,eAAe,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,cAAc,GAAG,SAAS,GAAG,aAAa,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,YAAY,GACrB,QAAQ,GACR,oBAAoB,GACpB,SAAS,GACT,QAAQ,GACR,MAAM,GACN,OAAO,GACP,KAAK,GACL,OAAO,GACP,KAAK,GACL,MAAM,CAAC;AAEV;;GAEG;AACH,MAAM,MAAM,UAAU,GACnB,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,IAAI,GACJ,OAAO,CAAC;AAEX,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GACrB,MAAM,GACN,WAAW,GACX,OAAO,GACP,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,MAAM,GACN,QAAQ,GACR,MAAM,GACN,KAAK,CAAC;AAET;;GAEG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,QAAQ,CAAC;IACf;;OAEG;IACH,IAAI,EAAE,WAAW,CAAC;IAClB;;OAEG;IACH,KAAK,EAAE,YAAY,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;GAEG;AACH,MAAM,MAAM,IAAI,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;AAE5C,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@project-ajax/sdk",
3
- "version": "0.0.64",
3
+ "version": "0.0.66",
4
4
  "description": "An SDK for building workers for the Project Ajax platform",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -1,10 +1,17 @@
1
- import { ExecutionError } from "../error.js";
1
+ import { ExecutionError, unreachable } from "../error.js";
2
2
  import type {
3
3
  PropertyConfiguration,
4
4
  PropertySchema,
5
5
  Schema,
6
6
  } from "../schema.js";
7
- import type { Icon, PeopleValue, TextValue } from "../types.js";
7
+ import type {
8
+ Icon,
9
+ PeopleValue,
10
+ Schedule,
11
+ SyncSchedule,
12
+ TextValue,
13
+ TimeUnit,
14
+ } from "../types.js";
8
15
 
9
16
  /**
10
17
  * Maps a property configuration to its corresponding value type.
@@ -92,6 +99,18 @@ export type SyncConfiguration<
92
99
  */
93
100
  deleteUnreturnedPages?: boolean;
94
101
 
102
+ /**
103
+ * How often the sync should run.
104
+ * - "continuous": Run as frequently as the system allows (default)
105
+ * - Interval string: Run at specified intervals, e.g. "1h", "30m", "1d"
106
+ *
107
+ * Minimum interval: 1 minute ("1m")
108
+ * Maximum interval: 7 days ("7d")
109
+ *
110
+ * @default "continuous"
111
+ */
112
+ schedule?: Schedule;
113
+
95
114
  /**
96
115
  * A function that fetches the data to sync from the third-party service.
97
116
  *
@@ -135,6 +154,7 @@ export function sync<
135
154
  primaryKeyProperty: syncConfiguration.primaryKeyProperty,
136
155
  schema: syncConfiguration.schema,
137
156
  deleteUnreturnedPages: syncConfiguration.deleteUnreturnedPages,
157
+ schedule: parseSchedule(syncConfiguration.schedule),
138
158
  },
139
159
  async handler(context?: Context) {
140
160
  const executionResult = await syncConfiguration
@@ -155,3 +175,57 @@ export function sync<
155
175
  },
156
176
  };
157
177
  }
178
+
179
+ const MS_PER_MINUTE = 60 * 1000;
180
+ const MS_PER_HOUR = 60 * MS_PER_MINUTE;
181
+ const MS_PER_DAY = 24 * MS_PER_HOUR;
182
+
183
+ const MIN_INTERVAL_MS = MS_PER_MINUTE; // 1m
184
+ const MAX_INTERVAL_MS = 7 * MS_PER_DAY; // 7d
185
+
186
+ /**
187
+ * Parses a user-friendly schedule string into the normalized backend format.
188
+ */
189
+ function parseSchedule(schedule: Schedule | undefined): SyncSchedule {
190
+ if (!schedule || schedule === "continuous") {
191
+ return { type: "continuous" };
192
+ }
193
+
194
+ const match = schedule.match(/^(\d+)(m|h|d)$/);
195
+ if (!match || !match[1] || !match[2]) {
196
+ throw new Error(
197
+ `Invalid schedule format: "${schedule}". Use "continuous" or an interval like "30m", "1h", "1d".`,
198
+ );
199
+ }
200
+
201
+ const value = parseInt(match[1], 10);
202
+ const unit = match[2] as TimeUnit;
203
+
204
+ let intervalMs: number;
205
+ switch (unit) {
206
+ case "m":
207
+ intervalMs = value * MS_PER_MINUTE;
208
+ break;
209
+ case "h":
210
+ intervalMs = value * MS_PER_HOUR;
211
+ break;
212
+ case "d":
213
+ intervalMs = value * MS_PER_DAY;
214
+ break;
215
+ default:
216
+ unreachable(unit);
217
+ }
218
+
219
+ if (intervalMs < MIN_INTERVAL_MS) {
220
+ throw new Error(
221
+ `Schedule interval must be at least 1 minute. Got: "${schedule}"`,
222
+ );
223
+ }
224
+ if (intervalMs > MAX_INTERVAL_MS) {
225
+ throw new Error(
226
+ `Schedule interval must be at most 7 days. Got: "${schedule}"`,
227
+ );
228
+ }
229
+
230
+ return { type: "interval", intervalMs };
231
+ }
package/src/error.ts CHANGED
@@ -10,3 +10,10 @@ export class ExecutionError extends Error {
10
10
  this.cause = cause;
11
11
  }
12
12
  }
13
+
14
+ /**
15
+ * Helper for exhaustive switch statements. TypeScript will error if a case is not handled.
16
+ */
17
+ export function unreachable(value: never): never {
18
+ throw new Error(`Unreachable: ${value}`);
19
+ }
package/src/index.ts CHANGED
@@ -12,4 +12,10 @@ export type {
12
12
  } from "./capabilities/sync.js";
13
13
  export { sync } from "./capabilities/sync.js";
14
14
  export { tool } from "./capabilities/tool.js";
15
- export type { Icon, ImageIcon, NoticonColor, NoticonName } from "./types.js";
15
+ export type {
16
+ Icon,
17
+ ImageIcon,
18
+ NoticonColor,
19
+ NoticonName,
20
+ Schedule,
21
+ } from "./types.js";
package/src/types.ts CHANGED
@@ -187,3 +187,30 @@ export interface PersonReference {
187
187
  export type PeopleValue = PersonReference[];
188
188
 
189
189
  export type { NoticonName } from "./icon-names.js";
190
+
191
+ /**
192
+ * Time units for schedule intervals.
193
+ * - "m": minutes
194
+ * - "h": hours
195
+ * - "d": days
196
+ */
197
+ export type TimeUnit = "m" | "h" | "d";
198
+
199
+ /**
200
+ * A string representing an interval, e.g. "30m", "1h", "7d".
201
+ */
202
+ export type IntervalString = `${number}${TimeUnit}`;
203
+
204
+ /**
205
+ * Schedule configuration for sync capabilities.
206
+ * - "continuous": Run as frequently as the system allows
207
+ * - IntervalString: Run at specified intervals, e.g. "30m", "1h", "1d"
208
+ */
209
+ export type Schedule = "continuous" | IntervalString;
210
+
211
+ /**
212
+ * Normalized schedule representation stored in the backend.
213
+ */
214
+ export type SyncSchedule =
215
+ | { type: "continuous" }
216
+ | { type: "interval"; intervalMs: number };