@powersync/service-module-mongodb-storage 0.9.5 → 0.10.1

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 (46) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/migrations/db/migrations/1749720702136-checkpoint-events.d.ts +3 -0
  3. package/dist/migrations/db/migrations/1749720702136-checkpoint-events.js +34 -0
  4. package/dist/migrations/db/migrations/1749720702136-checkpoint-events.js.map +1 -0
  5. package/dist/storage/MongoBucketStorage.js +5 -0
  6. package/dist/storage/MongoBucketStorage.js.map +1 -1
  7. package/dist/storage/implementation/MongoBucketBatch.d.ts +9 -3
  8. package/dist/storage/implementation/MongoBucketBatch.js +116 -36
  9. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  10. package/dist/storage/implementation/MongoCompactor.js +2 -2
  11. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  12. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +1 -0
  13. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +2 -0
  14. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
  15. package/dist/storage/implementation/MongoStorageProvider.js +23 -1
  16. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  17. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +14 -5
  18. package/dist/storage/implementation/MongoSyncBucketStorage.js +165 -160
  19. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  20. package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js +2 -0
  21. package/dist/storage/implementation/MongoTestStorageFactoryGenerator.js.map +1 -1
  22. package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +9 -15
  23. package/dist/storage/implementation/MongoWriteCheckpointAPI.js +55 -191
  24. package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
  25. package/dist/storage/implementation/PersistedBatch.d.ts +6 -2
  26. package/dist/storage/implementation/PersistedBatch.js +40 -8
  27. package/dist/storage/implementation/PersistedBatch.js.map +1 -1
  28. package/dist/storage/implementation/db.d.ts +12 -1
  29. package/dist/storage/implementation/db.js +39 -0
  30. package/dist/storage/implementation/db.js.map +1 -1
  31. package/dist/storage/implementation/models.d.ts +30 -2
  32. package/package.json +6 -6
  33. package/src/migrations/db/migrations/1749720702136-checkpoint-events.ts +50 -0
  34. package/src/storage/MongoBucketStorage.ts +5 -0
  35. package/src/storage/implementation/MongoBucketBatch.ts +159 -48
  36. package/src/storage/implementation/MongoCompactor.ts +2 -2
  37. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +2 -0
  38. package/src/storage/implementation/MongoStorageProvider.ts +27 -1
  39. package/src/storage/implementation/MongoSyncBucketStorage.ts +191 -201
  40. package/src/storage/implementation/MongoTestStorageFactoryGenerator.ts +3 -0
  41. package/src/storage/implementation/MongoWriteCheckpointAPI.ts +66 -255
  42. package/src/storage/implementation/PersistedBatch.ts +51 -12
  43. package/src/storage/implementation/db.ts +42 -0
  44. package/src/storage/implementation/models.ts +33 -2
  45. package/test/src/storage_sync.test.ts +7 -0
  46. package/tsconfig.tsbuildinfo +1 -1
@@ -12,6 +12,7 @@ export class PowerSyncMongo {
12
12
  instance;
13
13
  locks;
14
14
  bucket_state;
15
+ checkpoint_events;
15
16
  client;
16
17
  db;
17
18
  constructor(client, options) {
@@ -31,6 +32,7 @@ export class PowerSyncMongo {
31
32
  this.instance = db.collection('instance');
32
33
  this.locks = this.db.collection('locks');
33
34
  this.bucket_state = this.db.collection('bucket_state');
35
+ this.checkpoint_events = this.db.collection('checkpoint_events');
34
36
  }
35
37
  /**
36
38
  * Clear all collections.
@@ -56,6 +58,43 @@ export class PowerSyncMongo {
56
58
  async drop() {
57
59
  await this.db.dropDatabase();
58
60
  }
61
+ /**
62
+ * Call this after every checkpoint or sync rules status update. Rather call too often than too rarely.
63
+ *
64
+ * This is used in a similar way to the Postgres NOTIFY functionality.
65
+ */
66
+ async notifyCheckpoint() {
67
+ await this.checkpoint_events.insertOne({}, { forceServerObjectId: true });
68
+ }
69
+ /**
70
+ * Only use in migrations and tests.
71
+ */
72
+ async createCheckpointEventsCollection() {
73
+ // We cover the case where the replication process was started before running this migration.
74
+ const existingCollections = await this.db
75
+ .listCollections({ name: 'checkpoint_events' }, { nameOnly: false })
76
+ .toArray();
77
+ const collection = existingCollections[0];
78
+ if (collection != null) {
79
+ if (!collection.options?.capped) {
80
+ // Collection was auto-created but not capped, so we need to drop it
81
+ await this.db.dropCollection('checkpoint_events');
82
+ }
83
+ else {
84
+ // Collection previously created somehow - ignore
85
+ return;
86
+ }
87
+ }
88
+ await this.db.createCollection('checkpoint_events', {
89
+ capped: true,
90
+ // We want a small size, since opening a tailable cursor scans this entire collection.
91
+ // On the other hand, if we fill this up faster than a process can read it, it will
92
+ // invalidate the cursor. We do handle cursor invalidation events, but don't want
93
+ // that to happen too often.
94
+ size: 50 * 1024, // size in bytes
95
+ max: 50 // max number of documents
96
+ });
97
+ }
59
98
  }
60
99
  export function createPowerSyncMongo(config, options) {
61
100
  return new PowerSyncMongo(lib_mongo.createMongoClient(config, options), { database: config.database });
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/implementation/db.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/implementation/db.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { storage } from '@powersync/service-core';
1
+ import { InternalOpId, storage } from '@powersync/service-core';
2
2
  import { SqliteJsonValue } from '@powersync/service-sync-rules';
3
3
  import * as bson from 'bson';
4
4
  /**
@@ -49,7 +49,7 @@ export interface BucketDataDocument {
49
49
  source_key?: ReplicaId;
50
50
  table?: string;
51
51
  row_id?: string;
52
- checksum: number;
52
+ checksum: bigint;
53
53
  data: string | null;
54
54
  target_op?: bigint | null;
55
55
  }
@@ -68,6 +68,12 @@ export interface SourceTableDocument {
68
68
  type?: string;
69
69
  }[] | undefined;
70
70
  snapshot_done: boolean | undefined;
71
+ snapshot_status: SourceTableDocumentSnapshotStatus | undefined;
72
+ }
73
+ export interface SourceTableDocumentSnapshotStatus {
74
+ total_estimated_count: number;
75
+ replicated_count: number;
76
+ last_key: bson.Binary | null;
71
77
  }
72
78
  /**
73
79
  * Record the state of each bucket.
@@ -99,6 +105,12 @@ export interface SyncRuleDocument {
99
105
  * Can only be false if state == PROCESSING.
100
106
  */
101
107
  snapshot_done: boolean;
108
+ /**
109
+ * If snapshot_done = false, this may be the lsn at which we started the snapshot.
110
+ *
111
+ * This can be used for resuming the snapshot after a restart.
112
+ */
113
+ snapshot_lsn: string | undefined;
102
114
  /**
103
115
  * The last consistent checkpoint.
104
116
  *
@@ -139,18 +151,34 @@ export interface SyncRuleDocument {
139
151
  last_fatal_error: string | null;
140
152
  content: string;
141
153
  }
154
+ export interface CheckpointEventDocument {
155
+ _id: bson.ObjectId;
156
+ }
142
157
  export type SyncRuleCheckpointState = Pick<SyncRuleDocument, 'last_checkpoint' | 'last_checkpoint_lsn' | '_id' | 'state'>;
143
158
  export interface CustomWriteCheckpointDocument {
144
159
  _id: bson.ObjectId;
145
160
  user_id: string;
146
161
  checkpoint: bigint;
147
162
  sync_rules_id: number;
163
+ /**
164
+ * Unlike managed write checkpoints, custom write checkpoints are flushed together with
165
+ * normal ops. This means we can assign an op_id for ordering / correlating with read checkpoints.
166
+ *
167
+ * This is not unique - multiple write checkpoints can have the same op_id.
168
+ */
169
+ op_id?: InternalOpId;
148
170
  }
149
171
  export interface WriteCheckpointDocument {
150
172
  _id: bson.ObjectId;
151
173
  user_id: string;
152
174
  lsns: Record<string, string>;
153
175
  client_id: bigint;
176
+ /**
177
+ * This is set to the checkpoint lsn when the checkpoint lsn >= this lsn.
178
+ * This is used to make it easier to determine what write checkpoints have been processed
179
+ * between two checkpoints.
180
+ */
181
+ processed_at_lsn: string | null;
154
182
  }
155
183
  export interface InstanceDocument {
156
184
  _id: string;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@powersync/service-module-mongodb-storage",
3
3
  "repository": "https://github.com/powersync-ja/powersync-service",
4
4
  "types": "dist/index.d.ts",
5
- "version": "0.9.5",
5
+ "version": "0.10.1",
6
6
  "main": "dist/index.js",
7
7
  "license": "FSL-1.1-Apache-2.0",
8
8
  "type": "module",
@@ -27,15 +27,15 @@
27
27
  "lru-cache": "^10.2.2",
28
28
  "ts-codec": "^1.3.0",
29
29
  "uuid": "^11.1.0",
30
- "@powersync/lib-service-mongodb": "0.6.0",
31
- "@powersync/lib-services-framework": "0.6.0",
32
- "@powersync/service-core": "1.12.1",
30
+ "@powersync/lib-service-mongodb": "0.6.1",
31
+ "@powersync/lib-services-framework": "0.7.0",
32
+ "@powersync/service-core": "1.13.1",
33
33
  "@powersync/service-jsonbig": "0.17.10",
34
34
  "@powersync/service-sync-rules": "0.27.0",
35
- "@powersync/service-types": "0.11.0"
35
+ "@powersync/service-types": "0.12.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@powersync/service-core-tests": "0.9.5"
38
+ "@powersync/service-core-tests": "0.10.1"
39
39
  },
40
40
  "scripts": {
41
41
  "build": "tsc -b",
@@ -0,0 +1,50 @@
1
+ import { migrations } from '@powersync/service-core';
2
+ import * as storage from '../../../storage/storage-index.js';
3
+ import { MongoStorageConfig } from '../../../types/types.js';
4
+
5
+ export const up: migrations.PowerSyncMigrationFunction = async (context) => {
6
+ const {
7
+ service_context: { configuration }
8
+ } = context;
9
+ const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
10
+
11
+ try {
12
+ await db.createCheckpointEventsCollection();
13
+
14
+ await db.write_checkpoints.createIndex(
15
+ {
16
+ processed_at_lsn: 1
17
+ },
18
+ { name: 'processed_at_lsn' }
19
+ );
20
+
21
+ await db.custom_write_checkpoints.createIndex(
22
+ {
23
+ op_id: 1
24
+ },
25
+ { name: 'op_id' }
26
+ );
27
+ } finally {
28
+ await db.client.close();
29
+ }
30
+ };
31
+
32
+ export const down: migrations.PowerSyncMigrationFunction = async (context) => {
33
+ const {
34
+ service_context: { configuration }
35
+ } = context;
36
+
37
+ const db = storage.createPowerSyncMongo(configuration.storage as MongoStorageConfig);
38
+
39
+ try {
40
+ if (await db.write_checkpoints.indexExists('processed_at_lsn')) {
41
+ await db.write_checkpoints.dropIndex('processed_at_lsn');
42
+ }
43
+ if (await db.custom_write_checkpoints.indexExists('op_id')) {
44
+ await db.custom_write_checkpoints.dropIndex('op_id');
45
+ }
46
+ await db.db.dropCollection('checkpoint_events');
47
+ } finally {
48
+ await db.client.close();
49
+ }
50
+ };
@@ -119,6 +119,7 @@ export class MongoBucketStorage
119
119
  }
120
120
  }
121
121
  );
122
+ await this.db.notifyCheckpoint();
122
123
  } else if (next == null && active?.id == sync_rules_group_id) {
123
124
  // Slot removed for "active" sync rules, while there is no "next" one.
124
125
  await this.updateSyncRules({
@@ -141,6 +142,7 @@ export class MongoBucketStorage
141
142
  }
142
143
  }
143
144
  );
145
+ await this.db.notifyCheckpoint();
144
146
  } else if (next != null && active?.id == sync_rules_group_id) {
145
147
  // Already have next sync rules, but need to stop replicating the active one.
146
148
 
@@ -155,6 +157,7 @@ export class MongoBucketStorage
155
157
  }
156
158
  }
157
159
  );
160
+ await this.db.notifyCheckpoint();
158
161
  }
159
162
  }
160
163
 
@@ -209,6 +212,7 @@ export class MongoBucketStorage
209
212
  no_checkpoint_before: null,
210
213
  keepalive_op: null,
211
214
  snapshot_done: false,
215
+ snapshot_lsn: undefined,
212
216
  state: storage.SyncRuleState.PROCESSING,
213
217
  slot_name: slot_name,
214
218
  last_checkpoint_ts: null,
@@ -216,6 +220,7 @@ export class MongoBucketStorage
216
220
  last_keepalive_ts: null
217
221
  };
218
222
  await this.db.sync_rules.insertOne(doc);
223
+ await this.db.notifyCheckpoint();
219
224
  rules = new MongoPersistedSyncRulesContent(this.db, doc);
220
225
  if (options.lock) {
221
226
  const lock = await rules.lock();