@project-ajax/sdk 0.0.69 → 0.0.71

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.
@@ -9,41 +9,79 @@ type PropertyValueType<T extends PropertyConfiguration> = T extends {
9
9
  type: "place";
10
10
  } ? PlaceValue : TextValue;
11
11
  /**
12
- * An object representing a third-party record to be synced.
12
+ * Sync mode determines how the sync handles data lifecycle.
13
13
  */
14
- export type SyncedObject<PK extends string, S extends PropertySchema<PK>> = {
14
+ export type SyncMode = "replace" | "incremental";
15
+ /**
16
+ * A change representing a record to be created or updated.
17
+ */
18
+ export type SyncChangeUpsert<PK extends string, S extends PropertySchema<PK>> = {
19
+ /**
20
+ * The type of change. Use `"upsert"` to create or update a record.
21
+ */
22
+ type: "upsert";
23
+ /**
24
+ * A unique identifier for this record, used to match against existing pages.
25
+ * This value will be stored in the property specified by `primaryKeyProperty`.
26
+ */
15
27
  key: string;
28
+ /**
29
+ * The property values for this record.
30
+ * Keys must match the property names defined in the schema.
31
+ * Use the Builder helpers (e.g., `Builder.title()`, `Builder.richText()`) to create values.
32
+ */
16
33
  properties: {
17
34
  [Property in keyof S]: PropertyValueType<S[Property]>;
18
35
  };
19
36
  /**
20
37
  * Optional icon to use as the icon for this row's page.
21
- * Use the `icon()` builder to create an icon value.
38
+ * Use the `Builder.emojiIcon()`, `Builder.notionIcon()`, or `Builder.imageIcon()` helpers.
22
39
  */
23
40
  icon?: Icon;
24
41
  /**
25
- * Optional markdown content to add to the page.
26
- * This will be converted to blocks and added as page content.
42
+ * Optional markdown content to add to the page body.
43
+ * This will be converted to Notion blocks and added as page content.
27
44
  */
28
45
  pageContentMarkdown?: string;
29
46
  };
47
+ /**
48
+ * A change representing a record to be deleted.
49
+ * Only applicable when using `mode: "incremental"`.
50
+ */
51
+ export type SyncChangeDelete = {
52
+ /**
53
+ * The type of change. Use `"delete"` to remove a record.
54
+ */
55
+ type: "delete";
56
+ /**
57
+ * The unique identifier of the record to delete.
58
+ * Must match the `key` of a previously upserted record.
59
+ */
60
+ key: string;
61
+ };
62
+ /**
63
+ * A change to be applied to the synced database.
64
+ * Can be either an upsert (create/update) or a delete.
65
+ */
66
+ export type SyncChange<PK extends string, S extends PropertySchema<PK>> = SyncChangeUpsert<PK, S> | SyncChangeDelete;
30
67
  /**
31
68
  * Result returned from the sync execute function.
32
69
  */
33
70
  export type SyncExecutionResult<PK extends string, Context = unknown> = {
34
71
  /**
35
- * The batch of objects fetched in this execution.
72
+ * The batch of changes to apply in this execution.
73
+ * Can include upserts (create/update) and deletes.
36
74
  */
37
- objects: SyncedObject<PK, PropertySchema<PK>>[];
75
+ changes: SyncChange<PK, PropertySchema<PK>>[];
38
76
  /**
39
- * Indicates whether the sync is complete.
40
- * - `true`: No more data to fetch, sync is complete
41
- * - `false`: More data available, will trigger another execution with nextContext
77
+ * Indicates whether there is more data to fetch.
78
+ * - `true`: More data available, will trigger another execution with nextContext
79
+ * - `false`: No more data to fetch, sync is complete
42
80
  */
43
- done: boolean;
81
+ hasMore: boolean;
44
82
  /**
45
83
  * Optional context data to pass to the next execution.
46
- * Required if `done` is `false`, ignored if `done` is `true`.
84
+ * Required if `hasMore` is `true`, ignored if `hasMore` is `false`.
47
85
  * This can be any type of data (cursor, page number, timestamp, etc.).
48
86
  * The same data will be provided in the context parameter of the next execution.
49
87
  */
@@ -65,15 +103,16 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, Context =
65
103
  */
66
104
  schema: S;
67
105
  /**
68
- * Whether to delete pages from the collection that are not returned
69
- * from any of the sync executions (mark-and-sweep deletion).
70
- *
71
- * - `true`: Pages not seen in any execution batch will be deleted
72
- * - `false` (default): Only upsert pages, never delete
106
+ * How the sync handles data lifecycle:
107
+ * - "replace": Each sync returns the complete dataset. After hasMore:false,
108
+ * pages not seen in this sync run are deleted.
109
+ * - "incremental": Sync returns changes only. After hasMore:false, sync
110
+ * continues from saved cursor. Use delete markers
111
+ * to explicitly remove pages.
73
112
  *
74
- * @default false
113
+ * @default "replace"
75
114
  */
76
- deleteUnreturnedPages?: boolean;
115
+ mode?: SyncMode;
77
116
  /**
78
117
  * How often the sync should run.
79
118
  * - "continuous": Run as frequently as the system allows (default)
@@ -89,24 +128,24 @@ export type SyncConfiguration<PK extends string, S extends Schema<PK>, Context =
89
128
  * A function that fetches the data to sync from the third-party service.
90
129
  *
91
130
  * This function can return all data at once, or implement pagination by:
92
- * 1. Returning a batch of objects with `done: false` and a `nextContext`
131
+ * 1. Returning a batch of changes with `hasMore: true` and a `nextContext`
93
132
  * 2. The runtime will call execute again with that context data
94
- * 3. Continue until `done: true` is returned
133
+ * 3. Continue until `hasMore: false` is returned
95
134
  *
96
135
  * The runtime will handle diffing against the data source and creating,
97
136
  * updating, and deleting pages as necessary.
98
137
  *
99
138
  * @param context - Optional context data from previous execution (undefined on first call)
100
- * @returns A result containing objects, done status, and optional nextContext
139
+ * @returns A result containing changes, hasMore status, and optional nextContext
101
140
  */
102
141
  execute: (context?: Context) => Promise<SyncExecutionResult<PK, Context>>;
103
142
  };
104
143
  export type SyncHandlerResult<PK extends string, Context = unknown> = {
105
144
  primaryKeyProperty: PK;
106
- objects: SyncedObject<PK, PropertySchema<PK>>[];
107
- done: boolean;
145
+ changes: SyncChange<PK, PropertySchema<PK>>[];
146
+ hasMore: boolean;
108
147
  nextContext?: Context;
109
- deleteUnreturnedPages?: boolean;
148
+ mode?: SyncMode;
110
149
  };
111
150
  export type SyncCapability = ReturnType<typeof createSyncCapability>;
112
151
  /**
@@ -122,12 +161,12 @@ export declare function createSyncCapability<PK extends string, S extends Schema
122
161
  config: {
123
162
  primaryKeyProperty: PK;
124
163
  schema: S;
125
- deleteUnreturnedPages: boolean | undefined;
164
+ mode: SyncMode | undefined;
126
165
  schedule: SyncSchedule;
127
166
  };
128
167
  handler(context?: Context): Promise<{
129
- objects: SyncedObject<PK, PropertySchema<PK>>[];
130
- done: boolean;
168
+ changes: SyncChange<PK, PropertySchema<PK>>[];
169
+ hasMore: boolean;
131
170
  nextContext: Context | undefined;
132
171
  }>;
133
172
  };
@@ -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,EACX,IAAI,EACJ,WAAW,EACX,UAAU,EACV,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,CAAC,SAAS;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B,UAAU,GACV,SAAS,CAAC;AAEd;;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,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAErE;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CACnC,EAAE,SAAS,MAAM,EACjB,CAAC,SAAS,MAAM,CAAC,EAAE,CAAC,EACpB,OAAO,GAAG,OAAO,EAChB,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,EAAE,EAAE,CAAC,EAAE,OAAO,CAAC;;;;;;;;;sBAUzC,OAAO;;;;;EAkBhC"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/capabilities/sync.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ function createSyncCapability(key, syncConfiguration) {
6
6
  config: {
7
7
  primaryKeyProperty: syncConfiguration.primaryKeyProperty,
8
8
  schema: syncConfiguration.schema,
9
- deleteUnreturnedPages: syncConfiguration.deleteUnreturnedPages,
9
+ mode: syncConfiguration.mode,
10
10
  schedule: parseSchedule(syncConfiguration.schedule)
11
11
  },
12
12
  async handler(context) {
@@ -14,8 +14,8 @@ function createSyncCapability(key, syncConfiguration) {
14
14
  throw new ExecutionError(err);
15
15
  });
16
16
  const result = {
17
- objects: executionResult.objects,
18
- done: executionResult.done,
17
+ changes: executionResult.changes,
18
+ hasMore: executionResult.hasMore,
19
19
  nextContext: executionResult.nextContext
20
20
  };
21
21
  process.stdout.write(`
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { emojiIcon, imageIcon, notionIcon, place } from "./builder.js";
2
2
  export type { AutomationCapability, AutomationConfiguration, AutomationContext, PageObjectResponse, } from "./capabilities/automation.js";
3
3
  export type { NotionManagedOAuthConfiguration, OAuthCapability, OAuthConfiguration, UserManagedOAuthConfiguration, } from "./capabilities/oauth.js";
4
- export type { SyncCapability, SyncConfiguration, SyncExecutionResult, SyncedObject, } from "./capabilities/sync.js";
4
+ export type { SyncCapability, SyncChange, SyncChangeDelete, SyncChangeUpsert, SyncConfiguration, SyncExecutionResult, SyncMode, } from "./capabilities/sync.js";
5
5
  export type { ToolCapability, ToolConfiguration } from "./capabilities/tool.js";
6
6
  export type { Icon, ImageIcon, NoticonColor, NoticonName, PlaceValue, Schedule, } from "./types.js";
7
7
  export { Worker } from "./worker.js";
@@ -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,KAAK,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACX,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACX,+BAA+B,EAC/B,eAAe,EACf,kBAAkB,EAClB,6BAA6B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,GACZ,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,YAAY,EACX,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACvE,YAAY,EACX,oBAAoB,EACpB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACX,+BAA+B,EAC/B,eAAe,EACf,kBAAkB,EAClB,6BAA6B,GAC7B,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACX,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,QAAQ,GACR,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAChF,YAAY,EACX,IAAI,EACJ,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,EACV,QAAQ,GACR,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC"}
package/dist/worker.d.ts CHANGED
@@ -35,7 +35,7 @@ export declare class Worker {
35
35
  * },
36
36
  * },
37
37
  * execute: async () => {
38
- * const objects = [
38
+ * const changes = [
39
39
  * {
40
40
  * key: "task-1",
41
41
  * properties: {
@@ -46,7 +46,7 @@ export declare class Worker {
46
46
  * },
47
47
  * ];
48
48
  *
49
- * return { objects, done: true };
49
+ * return { changes, hasMore: false };
50
50
  * },
51
51
  * });
52
52
  * ```
package/dist/worker.js CHANGED
@@ -31,7 +31,7 @@ class Worker {
31
31
  * },
32
32
  * },
33
33
  * execute: async () => {
34
- * const objects = [
34
+ * const changes = [
35
35
  * {
36
36
  * key: "task-1",
37
37
  * properties: {
@@ -42,7 +42,7 @@ class Worker {
42
42
  * },
43
43
  * ];
44
44
  *
45
- * return { objects, done: true };
45
+ * return { changes, hasMore: false };
46
46
  * },
47
47
  * });
48
48
  * ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@project-ajax/sdk",
3
- "version": "0.0.69",
3
+ "version": "0.0.71",
4
4
  "description": "An SDK for building workers for the Project Ajax platform",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -26,44 +26,90 @@ type PropertyValueType<T extends PropertyConfiguration> = T extends {
26
26
  : TextValue;
27
27
 
28
28
  /**
29
- * An object representing a third-party record to be synced.
29
+ * Sync mode determines how the sync handles data lifecycle.
30
30
  */
31
- export type SyncedObject<PK extends string, S extends PropertySchema<PK>> = {
31
+ export type SyncMode = "replace" | "incremental";
32
+
33
+ /**
34
+ * A change representing a record to be created or updated.
35
+ */
36
+ export type SyncChangeUpsert<
37
+ PK extends string,
38
+ S extends PropertySchema<PK>,
39
+ > = {
40
+ /**
41
+ * The type of change. Use `"upsert"` to create or update a record.
42
+ */
43
+ type: "upsert";
44
+ /**
45
+ * A unique identifier for this record, used to match against existing pages.
46
+ * This value will be stored in the property specified by `primaryKeyProperty`.
47
+ */
32
48
  key: string;
49
+ /**
50
+ * The property values for this record.
51
+ * Keys must match the property names defined in the schema.
52
+ * Use the Builder helpers (e.g., `Builder.title()`, `Builder.richText()`) to create values.
53
+ */
33
54
  properties: {
34
55
  [Property in keyof S]: PropertyValueType<S[Property]>;
35
56
  };
36
57
  /**
37
58
  * Optional icon to use as the icon for this row's page.
38
- * Use the `icon()` builder to create an icon value.
59
+ * Use the `Builder.emojiIcon()`, `Builder.notionIcon()`, or `Builder.imageIcon()` helpers.
39
60
  */
40
61
  icon?: Icon;
41
62
  /**
42
- * Optional markdown content to add to the page.
43
- * This will be converted to blocks and added as page content.
63
+ * Optional markdown content to add to the page body.
64
+ * This will be converted to Notion blocks and added as page content.
44
65
  */
45
66
  pageContentMarkdown?: string;
46
67
  };
47
68
 
69
+ /**
70
+ * A change representing a record to be deleted.
71
+ * Only applicable when using `mode: "incremental"`.
72
+ */
73
+ export type SyncChangeDelete = {
74
+ /**
75
+ * The type of change. Use `"delete"` to remove a record.
76
+ */
77
+ type: "delete";
78
+ /**
79
+ * The unique identifier of the record to delete.
80
+ * Must match the `key` of a previously upserted record.
81
+ */
82
+ key: string;
83
+ };
84
+
85
+ /**
86
+ * A change to be applied to the synced database.
87
+ * Can be either an upsert (create/update) or a delete.
88
+ */
89
+ export type SyncChange<PK extends string, S extends PropertySchema<PK>> =
90
+ | SyncChangeUpsert<PK, S>
91
+ | SyncChangeDelete;
92
+
48
93
  /**
49
94
  * Result returned from the sync execute function.
50
95
  */
51
96
  export type SyncExecutionResult<PK extends string, Context = unknown> = {
52
97
  /**
53
- * The batch of objects fetched in this execution.
98
+ * The batch of changes to apply in this execution.
99
+ * Can include upserts (create/update) and deletes.
54
100
  */
55
- objects: SyncedObject<PK, PropertySchema<PK>>[];
101
+ changes: SyncChange<PK, PropertySchema<PK>>[];
56
102
 
57
103
  /**
58
- * Indicates whether the sync is complete.
59
- * - `true`: No more data to fetch, sync is complete
60
- * - `false`: More data available, will trigger another execution with nextContext
104
+ * Indicates whether there is more data to fetch.
105
+ * - `true`: More data available, will trigger another execution with nextContext
106
+ * - `false`: No more data to fetch, sync is complete
61
107
  */
62
- done: boolean;
108
+ hasMore: boolean;
63
109
 
64
110
  /**
65
111
  * Optional context data to pass to the next execution.
66
- * Required if `done` is `false`, ignored if `done` is `true`.
112
+ * Required if `hasMore` is `true`, ignored if `hasMore` is `false`.
67
113
  * This can be any type of data (cursor, page number, timestamp, etc.).
68
114
  * The same data will be provided in the context parameter of the next execution.
69
115
  */
@@ -92,15 +138,16 @@ export type SyncConfiguration<
92
138
  schema: S;
93
139
 
94
140
  /**
95
- * Whether to delete pages from the collection that are not returned
96
- * from any of the sync executions (mark-and-sweep deletion).
97
- *
98
- * - `true`: Pages not seen in any execution batch will be deleted
99
- * - `false` (default): Only upsert pages, never delete
141
+ * How the sync handles data lifecycle:
142
+ * - "replace": Each sync returns the complete dataset. After hasMore:false,
143
+ * pages not seen in this sync run are deleted.
144
+ * - "incremental": Sync returns changes only. After hasMore:false, sync
145
+ * continues from saved cursor. Use delete markers
146
+ * to explicitly remove pages.
100
147
  *
101
- * @default false
148
+ * @default "replace"
102
149
  */
103
- deleteUnreturnedPages?: boolean;
150
+ mode?: SyncMode;
104
151
 
105
152
  /**
106
153
  * How often the sync should run.
@@ -118,25 +165,25 @@ export type SyncConfiguration<
118
165
  * A function that fetches the data to sync from the third-party service.
119
166
  *
120
167
  * This function can return all data at once, or implement pagination by:
121
- * 1. Returning a batch of objects with `done: false` and a `nextContext`
168
+ * 1. Returning a batch of changes with `hasMore: true` and a `nextContext`
122
169
  * 2. The runtime will call execute again with that context data
123
- * 3. Continue until `done: true` is returned
170
+ * 3. Continue until `hasMore: false` is returned
124
171
  *
125
172
  * The runtime will handle diffing against the data source and creating,
126
173
  * updating, and deleting pages as necessary.
127
174
  *
128
175
  * @param context - Optional context data from previous execution (undefined on first call)
129
- * @returns A result containing objects, done status, and optional nextContext
176
+ * @returns A result containing changes, hasMore status, and optional nextContext
130
177
  */
131
178
  execute: (context?: Context) => Promise<SyncExecutionResult<PK, Context>>;
132
179
  };
133
180
 
134
181
  export type SyncHandlerResult<PK extends string, Context = unknown> = {
135
182
  primaryKeyProperty: PK;
136
- objects: SyncedObject<PK, PropertySchema<PK>>[];
137
- done: boolean;
183
+ changes: SyncChange<PK, PropertySchema<PK>>[];
184
+ hasMore: boolean;
138
185
  nextContext?: Context;
139
- deleteUnreturnedPages?: boolean;
186
+ mode?: SyncMode;
140
187
  };
141
188
 
142
189
  export type SyncCapability = ReturnType<typeof createSyncCapability>;
@@ -159,7 +206,7 @@ export function createSyncCapability<
159
206
  config: {
160
207
  primaryKeyProperty: syncConfiguration.primaryKeyProperty,
161
208
  schema: syncConfiguration.schema,
162
- deleteUnreturnedPages: syncConfiguration.deleteUnreturnedPages,
209
+ mode: syncConfiguration.mode,
163
210
  schedule: parseSchedule(syncConfiguration.schedule),
164
211
  },
165
212
  async handler(context?: Context) {
@@ -170,8 +217,8 @@ export function createSyncCapability<
170
217
  });
171
218
 
172
219
  const result = {
173
- objects: executionResult.objects,
174
- done: executionResult.done,
220
+ changes: executionResult.changes,
221
+ hasMore: executionResult.hasMore,
175
222
  nextContext: executionResult.nextContext,
176
223
  };
177
224
 
package/src/index.ts CHANGED
@@ -13,9 +13,12 @@ export type {
13
13
  } from "./capabilities/oauth.js";
14
14
  export type {
15
15
  SyncCapability,
16
+ SyncChange,
17
+ SyncChangeDelete,
18
+ SyncChangeUpsert,
16
19
  SyncConfiguration,
17
20
  SyncExecutionResult,
18
- SyncedObject,
21
+ SyncMode,
19
22
  } from "./capabilities/sync.js";
20
23
  export type { ToolCapability, ToolConfiguration } from "./capabilities/tool.js";
21
24
  export type {
package/src/worker.ts CHANGED
@@ -74,7 +74,7 @@ export class Worker {
74
74
  * },
75
75
  * },
76
76
  * execute: async () => {
77
- * const objects = [
77
+ * const changes = [
78
78
  * {
79
79
  * key: "task-1",
80
80
  * properties: {
@@ -85,7 +85,7 @@ export class Worker {
85
85
  * },
86
86
  * ];
87
87
  *
88
- * return { objects, done: true };
88
+ * return { changes, hasMore: false };
89
89
  * },
90
90
  * });
91
91
  * ```