@powersync/service-module-mongodb-storage 0.0.0-dev-20260313100403 → 0.0.0-dev-20260515144844

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 (207) hide show
  1. package/CHANGELOG.md +96 -8
  2. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js +1 -1
  3. package/dist/migrations/db/migrations/1688556755264-initial-sync-rules.js.map +1 -1
  4. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js +3 -3
  5. package/dist/migrations/db/migrations/1702295701188-sync-rule-state.js.map +1 -1
  6. package/dist/migrations/db/migrations/1770213298299-storage-version.js.map +1 -1
  7. package/dist/storage/MongoBucketStorage.d.ts +5 -3
  8. package/dist/storage/MongoBucketStorage.js +50 -36
  9. package/dist/storage/MongoBucketStorage.js.map +1 -1
  10. package/dist/storage/MongoReportStorage.d.ts +3 -3
  11. package/dist/storage/MongoReportStorage.js +5 -5
  12. package/dist/storage/MongoReportStorage.js.map +1 -1
  13. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +17 -0
  14. package/dist/storage/implementation/BucketDefinitionMapping.js +58 -0
  15. package/dist/storage/implementation/BucketDefinitionMapping.js.map +1 -0
  16. package/dist/storage/implementation/MongoBucketBatch.d.ts +16 -14
  17. package/dist/storage/implementation/MongoBucketBatch.js +80 -115
  18. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  19. package/dist/storage/implementation/MongoBucketBatchShared.d.ts +5 -0
  20. package/dist/storage/implementation/MongoBucketBatchShared.js +8 -0
  21. package/dist/storage/implementation/MongoBucketBatchShared.js.map +1 -0
  22. package/dist/storage/implementation/MongoChecksums.d.ts +28 -17
  23. package/dist/storage/implementation/MongoChecksums.js +13 -72
  24. package/dist/storage/implementation/MongoChecksums.js.map +1 -1
  25. package/dist/storage/implementation/MongoCompactor.d.ts +98 -52
  26. package/dist/storage/implementation/MongoCompactor.js +256 -295
  27. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  28. package/dist/storage/implementation/MongoParameterCompactor.d.ts +11 -6
  29. package/dist/storage/implementation/MongoParameterCompactor.js +24 -9
  30. package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
  31. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +14 -0
  32. package/dist/storage/implementation/MongoPersistedSyncRules.js +64 -0
  33. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +1 -0
  34. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +3 -0
  35. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +9 -0
  36. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
  37. package/dist/storage/implementation/MongoStorageProvider.js +1 -1
  38. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  39. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +49 -30
  40. package/dist/storage/implementation/MongoSyncBucketStorage.js +100 -456
  41. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  42. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +5 -3
  43. package/dist/storage/implementation/MongoSyncRulesLock.js +12 -10
  44. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  45. package/dist/storage/implementation/MongoWriteCheckpointAPI.js +1 -1
  46. package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
  47. package/dist/storage/implementation/OperationBatch.js +1 -1
  48. package/dist/storage/implementation/common/BucketDataDoc.d.ts +35 -0
  49. package/dist/storage/implementation/common/BucketDataDoc.js +2 -0
  50. package/dist/storage/implementation/common/BucketDataDoc.js.map +1 -0
  51. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.d.ts +13 -0
  52. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js +2 -0
  53. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js.map +1 -0
  54. package/dist/storage/implementation/common/PersistedBatch.d.ts +108 -0
  55. package/dist/storage/implementation/common/PersistedBatch.js +237 -0
  56. package/dist/storage/implementation/common/PersistedBatch.js.map +1 -0
  57. package/dist/storage/implementation/common/SingleBucketStore.d.ts +54 -0
  58. package/dist/storage/implementation/common/SingleBucketStore.js +3 -0
  59. package/dist/storage/implementation/common/SingleBucketStore.js.map +1 -0
  60. package/dist/storage/implementation/common/SourceRecordStore.d.ts +36 -0
  61. package/dist/storage/implementation/common/SourceRecordStore.js +2 -0
  62. package/dist/storage/implementation/common/SourceRecordStore.js.map +1 -0
  63. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.d.ts +27 -0
  64. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +57 -0
  65. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -0
  66. package/dist/storage/implementation/createMongoSyncBucketStorage.d.ts +7 -0
  67. package/dist/storage/implementation/createMongoSyncBucketStorage.js +9 -0
  68. package/dist/storage/implementation/createMongoSyncBucketStorage.js.map +1 -0
  69. package/dist/storage/implementation/db.d.ts +34 -34
  70. package/dist/storage/implementation/db.js +78 -98
  71. package/dist/storage/implementation/db.js.map +1 -1
  72. package/dist/storage/implementation/models.d.ts +65 -36
  73. package/dist/storage/implementation/models.js +21 -2
  74. package/dist/storage/implementation/models.js.map +1 -1
  75. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +13 -0
  76. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +22 -0
  77. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -0
  78. package/dist/storage/implementation/v1/MongoChecksumsV1.d.ts +12 -0
  79. package/dist/storage/implementation/v1/MongoChecksumsV1.js +56 -0
  80. package/dist/storage/implementation/v1/MongoChecksumsV1.js.map +1 -0
  81. package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +23 -0
  82. package/dist/storage/implementation/v1/MongoCompactorV1.js +52 -0
  83. package/dist/storage/implementation/v1/MongoCompactorV1.js.map +1 -0
  84. package/dist/storage/implementation/v1/MongoParameterCompactorV1.d.ts +9 -0
  85. package/dist/storage/implementation/v1/MongoParameterCompactorV1.js +20 -0
  86. package/dist/storage/implementation/v1/MongoParameterCompactorV1.js.map +1 -0
  87. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +41 -0
  88. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +283 -0
  89. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -0
  90. package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +26 -0
  91. package/dist/storage/implementation/v1/PersistedBatchV1.js +183 -0
  92. package/dist/storage/implementation/v1/PersistedBatchV1.js.map +1 -0
  93. package/dist/storage/implementation/v1/SingleBucketStoreV1.d.ts +18 -0
  94. package/dist/storage/implementation/v1/SingleBucketStoreV1.js +57 -0
  95. package/dist/storage/implementation/v1/SingleBucketStoreV1.js.map +1 -0
  96. package/dist/storage/implementation/v1/SourceRecordStoreV1.d.ts +19 -0
  97. package/dist/storage/implementation/v1/SourceRecordStoreV1.js +105 -0
  98. package/dist/storage/implementation/v1/SourceRecordStoreV1.js.map +1 -0
  99. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.d.ts +12 -0
  100. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js +20 -0
  101. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js.map +1 -0
  102. package/dist/storage/implementation/v1/models.d.ts +34 -0
  103. package/dist/storage/implementation/v1/models.js +37 -0
  104. package/dist/storage/implementation/v1/models.js.map +1 -0
  105. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +13 -0
  106. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +34 -0
  107. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -0
  108. package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +15 -0
  109. package/dist/storage/implementation/v3/MongoChecksumsV3.js +84 -0
  110. package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -0
  111. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +23 -0
  112. package/dist/storage/implementation/v3/MongoCompactorV3.js +68 -0
  113. package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -0
  114. package/dist/storage/implementation/v3/MongoParameterCompactorV3.d.ts +9 -0
  115. package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +18 -0
  116. package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +1 -0
  117. package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +5 -0
  118. package/dist/storage/implementation/v3/MongoParameterLookupV3.js +9 -0
  119. package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +1 -0
  120. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +41 -0
  121. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +407 -0
  122. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -0
  123. package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +29 -0
  124. package/dist/storage/implementation/v3/PersistedBatchV3.js +259 -0
  125. package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -0
  126. package/dist/storage/implementation/v3/SingleBucketStoreV3.d.ts +18 -0
  127. package/dist/storage/implementation/v3/SingleBucketStoreV3.js +48 -0
  128. package/dist/storage/implementation/v3/SingleBucketStoreV3.js.map +1 -0
  129. package/dist/storage/implementation/v3/SourceRecordStoreV3.d.ts +22 -0
  130. package/dist/storage/implementation/v3/SourceRecordStoreV3.js +164 -0
  131. package/dist/storage/implementation/v3/SourceRecordStoreV3.js.map +1 -0
  132. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +21 -0
  133. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +71 -0
  134. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -0
  135. package/dist/storage/implementation/v3/models.d.ts +43 -0
  136. package/dist/storage/implementation/v3/models.js +34 -0
  137. package/dist/storage/implementation/v3/models.js.map +1 -0
  138. package/dist/storage/storage-index.d.ts +8 -5
  139. package/dist/storage/storage-index.js +8 -5
  140. package/dist/storage/storage-index.js.map +1 -1
  141. package/dist/utils/util.d.ts +11 -4
  142. package/dist/utils/util.js +25 -4
  143. package/dist/utils/util.js.map +1 -1
  144. package/package.json +9 -9
  145. package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +1 -1
  146. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -7
  147. package/src/migrations/db/migrations/1770213298299-storage-version.ts +1 -1
  148. package/src/storage/MongoBucketStorage.ts +97 -62
  149. package/src/storage/MongoReportStorage.ts +7 -7
  150. package/src/storage/implementation/BucketDefinitionMapping.ts +72 -0
  151. package/src/storage/implementation/MongoBucketBatch.ts +110 -144
  152. package/src/storage/implementation/MongoBucketBatchShared.ts +11 -0
  153. package/src/storage/implementation/MongoChecksums.ts +53 -76
  154. package/src/storage/implementation/MongoCompactor.ts +401 -403
  155. package/src/storage/implementation/MongoParameterCompactor.ts +51 -25
  156. package/src/storage/implementation/MongoPersistedSyncRules.ts +76 -0
  157. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +18 -1
  158. package/src/storage/implementation/MongoStorageProvider.ts +1 -1
  159. package/src/storage/implementation/MongoSyncBucketStorage.ts +190 -457
  160. package/src/storage/implementation/MongoSyncRulesLock.ts +12 -14
  161. package/src/storage/implementation/MongoWriteCheckpointAPI.ts +4 -2
  162. package/src/storage/implementation/OperationBatch.ts +1 -1
  163. package/src/storage/implementation/common/BucketDataDoc.ts +37 -0
  164. package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +15 -0
  165. package/src/storage/implementation/common/PersistedBatch.ts +364 -0
  166. package/src/storage/implementation/common/SingleBucketStore.ts +63 -0
  167. package/src/storage/implementation/common/SourceRecordStore.ts +49 -0
  168. package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +80 -0
  169. package/src/storage/implementation/createMongoSyncBucketStorage.ts +25 -0
  170. package/src/storage/implementation/db.ts +107 -128
  171. package/src/storage/implementation/models.ts +86 -40
  172. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +32 -0
  173. package/src/storage/implementation/v1/MongoChecksumsV1.ts +75 -0
  174. package/src/storage/implementation/v1/MongoCompactorV1.ts +93 -0
  175. package/src/storage/implementation/v1/MongoParameterCompactorV1.ts +26 -0
  176. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +448 -0
  177. package/src/storage/implementation/v1/PersistedBatchV1.ts +230 -0
  178. package/src/storage/implementation/v1/SingleBucketStoreV1.ts +74 -0
  179. package/src/storage/implementation/v1/SourceRecordStoreV1.ts +156 -0
  180. package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +28 -0
  181. package/src/storage/implementation/v1/models.ts +84 -0
  182. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +44 -0
  183. package/src/storage/implementation/v3/MongoChecksumsV3.ts +120 -0
  184. package/src/storage/implementation/v3/MongoCompactorV3.ts +107 -0
  185. package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +24 -0
  186. package/src/storage/implementation/v3/MongoParameterLookupV3.ts +12 -0
  187. package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +550 -0
  188. package/src/storage/implementation/v3/PersistedBatchV3.ts +318 -0
  189. package/src/storage/implementation/v3/SingleBucketStoreV3.ts +68 -0
  190. package/src/storage/implementation/v3/SourceRecordStoreV3.ts +226 -0
  191. package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +112 -0
  192. package/src/storage/implementation/v3/models.ts +96 -0
  193. package/src/storage/storage-index.ts +8 -5
  194. package/src/utils/util.ts +36 -7
  195. package/test/src/__snapshots__/{client-connections-storage.test.ts.snap → connection-report-storage.test.ts.snap} +68 -68
  196. package/test/src/__snapshots__/storage_sync.test.ts.snap +282 -0
  197. package/test/src/{client-connections-storage.test.ts → connection-report-storage.test.ts} +4 -4
  198. package/test/src/setup.ts +1 -1
  199. package/test/src/storage.test.ts +2 -2
  200. package/test/src/storage_compacting.test.ts +94 -3
  201. package/test/src/storage_sync.test.ts +351 -5
  202. package/test/tsconfig.json +0 -1
  203. package/tsconfig.tsbuildinfo +1 -1
  204. package/dist/storage/implementation/PersistedBatch.d.ts +0 -71
  205. package/dist/storage/implementation/PersistedBatch.js +0 -354
  206. package/dist/storage/implementation/PersistedBatch.js.map +0 -1
  207. package/src/storage/implementation/PersistedBatch.ts +0 -432
@@ -0,0 +1,112 @@
1
+ import { mongo } from '@powersync/lib-service-mongodb';
2
+ import { BucketDefinitionId, ParameterIndexId } from '../BucketDefinitionMapping.js';
3
+ import { BaseVersionedPowerSyncMongo } from '../common/VersionedPowerSyncMongoBase.js';
4
+ import { CommonSourceTableDocument } from '../models.js';
5
+ import {
6
+ BucketDataDocumentV3,
7
+ BucketParameterDocumentV3,
8
+ BucketStateDocumentV3,
9
+ CurrentDataDocumentV3,
10
+ SourceTableDocumentV3
11
+ } from './models.js';
12
+
13
+ export class VersionedPowerSyncMongoV3 extends BaseVersionedPowerSyncMongo {
14
+ sourceRecordsV3(replicationStreamId: number, sourceTableId: mongo.ObjectId): mongo.Collection<CurrentDataDocumentV3> {
15
+ const collectionName = this.sourceRecordsCollectionName(replicationStreamId, sourceTableId);
16
+ return this.db.collection<CurrentDataDocumentV3>(collectionName);
17
+ }
18
+
19
+ async listSourceRecordCollectionsV3(replicationStreamId: number): Promise<mongo.Collection<CurrentDataDocumentV3>[]> {
20
+ return this.listCollectionsByPrefix<CurrentDataDocumentV3>(`source_records_${replicationStreamId}_`);
21
+ }
22
+
23
+ async initializeSourceRecordsCollection(replicationStreamId: number, sourceTableId: mongo.ObjectId) {
24
+ await this.sourceRecordsV3(replicationStreamId, sourceTableId).createIndex(
25
+ {
26
+ pending_delete: 1
27
+ },
28
+ {
29
+ partialFilterExpression: { pending_delete: { $exists: true } },
30
+ name: 'pending_delete'
31
+ }
32
+ );
33
+ }
34
+
35
+ commonSourceTables(replicationStreamId: number): mongo.Collection<CommonSourceTableDocument> {
36
+ return this.sourceTablesV3(replicationStreamId) as mongo.Collection<CommonSourceTableDocument>;
37
+ }
38
+
39
+ bucketStateV3(replicationStreamId: number): mongo.Collection<BucketStateDocumentV3> {
40
+ return this.db.collection(`bucket_state_${replicationStreamId}`);
41
+ }
42
+
43
+ parameterIndexV3(
44
+ replicationStreamId: number,
45
+ indexId: ParameterIndexId
46
+ ): mongo.Collection<BucketParameterDocumentV3> {
47
+ return this.db.collection(`parameter_index_${replicationStreamId}_${indexId}`);
48
+ }
49
+
50
+ sourceTablesV3(replicationStreamId: number): mongo.Collection<SourceTableDocumentV3> {
51
+ return this.db.collection<SourceTableDocumentV3>(this.sourceTableCollectionName(replicationStreamId));
52
+ }
53
+
54
+ async initializeStreamStorage(replicationStreamId: number) {
55
+ const sourceTables = this.sourceTablesV3(replicationStreamId);
56
+ const bucketState = this.bucketStateV3(replicationStreamId);
57
+ await sourceTables.createIndex(
58
+ {
59
+ connection_id: 1,
60
+ schema_name: 1,
61
+ table_name: 1,
62
+ relation_id: 1
63
+ },
64
+ {
65
+ name: 'source_lookup'
66
+ }
67
+ );
68
+ await sourceTables.createIndex(
69
+ {
70
+ latest_pending_delete: 1
71
+ },
72
+ {
73
+ partialFilterExpression: { latest_pending_delete: { $exists: true } },
74
+ name: 'latest_pending_delete'
75
+ }
76
+ );
77
+ await bucketState.createIndex(
78
+ {
79
+ last_op: 1
80
+ },
81
+ { name: 'bucket_updates', unique: true }
82
+ );
83
+ await bucketState.createIndex(
84
+ {
85
+ 'estimate_since_compact.count': -1
86
+ },
87
+ { name: 'dirty_count' }
88
+ );
89
+ }
90
+
91
+ bucketDataV3(replicationStreamId: number, definitionId: BucketDefinitionId) {
92
+ return this.db.collection<BucketDataDocumentV3>(`bucket_data_${replicationStreamId}_${definitionId}`);
93
+ }
94
+
95
+ listBucketDataCollectionsV3(replicationStreamId: number) {
96
+ return this.upstream.listBucketDataCollectionsV3(replicationStreamId);
97
+ }
98
+
99
+ async listParameterIndexCollectionsV3(
100
+ replicationStreamId: number
101
+ ): Promise<{ collection: mongo.Collection<BucketParameterDocumentV3>; indexId: ParameterIndexId }[]> {
102
+ const prefix = `parameter_index_${replicationStreamId}_`;
103
+ const collections = await this.db.listCollections({ name: new RegExp(`^${prefix}`) }, { nameOnly: true }).toArray();
104
+
105
+ return collections
106
+ .filter((collection) => collection.name.startsWith(prefix))
107
+ .map((collection) => ({
108
+ collection: this.db.collection<BucketParameterDocumentV3>(collection.name),
109
+ indexId: collection.name.slice(prefix.length)
110
+ }));
111
+ }
112
+ }
@@ -0,0 +1,96 @@
1
+ import { InternalOpId } from '@powersync/service-core';
2
+ import * as bson from 'bson';
3
+ import { BucketDefinitionId, ParameterIndexId } from '../BucketDefinitionMapping.js';
4
+ import { BucketDataDoc, BucketKey } from '../common/BucketDataDoc.js';
5
+ import {
6
+ BucketDataDocumentBase,
7
+ BucketDataKey,
8
+ BucketParameterDocumentBase,
9
+ BucketStateDocumentBase,
10
+ CurrentBucket,
11
+ ReplicaId,
12
+ SourceTableDocument,
13
+ SourceTableKey,
14
+ TaggedBucketParameterDocument
15
+ } from '../models.js';
16
+
17
+ export interface CurrentBucketV3 extends CurrentBucket {
18
+ def: BucketDefinitionId;
19
+ }
20
+
21
+ export interface RecordedLookupV3 {
22
+ i: ParameterIndexId;
23
+ l: bson.Binary;
24
+ }
25
+
26
+ export interface CurrentDataDocumentV3 {
27
+ _id: ReplicaId;
28
+ data: bson.Binary | null;
29
+ buckets: CurrentBucketV3[];
30
+ lookups: RecordedLookupV3[];
31
+ /**
32
+ * If set, this can be deleted, once there is a consistent checkpoint >= pending_delete.
33
+ *
34
+ * This must only be set if buckets = [], lookups = [].
35
+ */
36
+ pending_delete?: bigint;
37
+ }
38
+
39
+ export interface BucketParameterDocumentV3 extends BucketParameterDocumentBase<SourceTableKey> {}
40
+
41
+ export type BucketDataKeyV3 = BucketDataKey;
42
+
43
+ export interface BucketDataDocumentV3 extends BucketDataDocumentBase {
44
+ _id: BucketDataKeyV3;
45
+ }
46
+
47
+ export function serializeBucketDataV3(document: BucketDataDoc): BucketDataDocumentV3 {
48
+ const { bucketKey, o } = document;
49
+ return {
50
+ _id: {
51
+ b: bucketKey.bucket,
52
+ o: o
53
+ },
54
+ // List fields directly, so that we don't accidentally persist any unknown fields
55
+ op: document.op,
56
+ source_table: document.source_table,
57
+ source_key: document.source_key,
58
+ table: document.table,
59
+ row_id: document.row_id,
60
+ checksum: document.checksum,
61
+ data: document.data,
62
+ target_op: document.target_op
63
+ };
64
+ }
65
+
66
+ export function loadBucketDataDocumentV3(
67
+ context: Pick<BucketKey, 'replicationStreamId' | 'definitionId'>,
68
+ doc: BucketDataDocumentV3
69
+ ): BucketDataDoc {
70
+ const { _id, ...rest } = doc;
71
+ return {
72
+ bucketKey: {
73
+ ...context,
74
+ bucket: _id.b
75
+ },
76
+ o: _id.o,
77
+ ...rest
78
+ };
79
+ }
80
+
81
+ export function taggedBucketParameterDocumentToV3(document: TaggedBucketParameterDocument): BucketParameterDocumentV3 {
82
+ const { index: _index, ...rest } = document;
83
+ return rest as BucketParameterDocumentV3;
84
+ }
85
+
86
+ export interface SourceTableDocumentV3 extends SourceTableDocument {
87
+ bucket_data_source_ids: BucketDefinitionId[];
88
+ parameter_lookup_source_ids: ParameterIndexId[];
89
+ latest_pending_delete?: InternalOpId | undefined;
90
+ }
91
+
92
+ export interface BucketStateDocumentV3 extends BucketStateDocumentBase {
93
+ _id: BucketStateDocumentBase['_id'] & {
94
+ d: BucketDefinitionId;
95
+ };
96
+ }
@@ -1,14 +1,17 @@
1
+ export * as test_utils from '../utils/test-utils.js';
2
+ export * from '../utils/util.js';
3
+ export * from './implementation/BucketDefinitionMapping.js';
4
+ export * from './implementation/common/PersistedBatch.js';
5
+ export * from './implementation/createMongoSyncBucketStorage.js';
1
6
  export * from './implementation/db.js';
2
7
  export * from './implementation/models.js';
3
- export * from './implementation/MongoBucketBatch.js';
4
8
  export * from './implementation/MongoIdSequence.js';
9
+ export * from './implementation/MongoPersistedSyncRules.js';
5
10
  export * from './implementation/MongoPersistedSyncRulesContent.js';
6
11
  export * from './implementation/MongoStorageProvider.js';
7
- export * from './implementation/MongoSyncBucketStorage.js';
8
12
  export * from './implementation/MongoSyncRulesLock.js';
9
13
  export * from './implementation/OperationBatch.js';
10
- export * from './implementation/PersistedBatch.js';
11
- export * from '../utils/util.js';
14
+ export * from './implementation/v1/models.js';
15
+ export * from './implementation/v3/models.js';
12
16
  export * from './MongoBucketStorage.js';
13
17
  export * from './MongoReportStorage.js';
14
- export * as test_utils from '../utils/test-utils.js';
package/src/utils/util.ts CHANGED
@@ -1,10 +1,12 @@
1
+ import * as lib_mongo from '@powersync/lib-service-mongodb';
2
+ import { mongo } from '@powersync/lib-service-mongodb';
3
+ import { ReplicationAbortedError, ServiceAssertionError } from '@powersync/lib-services-framework';
4
+ import { storage, utils } from '@powersync/service-core';
1
5
  import * as bson from 'bson';
2
6
  import * as crypto from 'crypto';
7
+ import * as timers from 'node:timers/promises';
3
8
  import * as uuid from 'uuid';
4
- import { mongo } from '@powersync/lib-service-mongodb';
5
- import { storage, utils } from '@powersync/service-core';
6
- import { ServiceAssertionError } from '@powersync/lib-services-framework';
7
- import { BucketDataDocument } from '../storage/implementation/models.js';
9
+ import { BucketDataDoc } from '../storage/implementation/common/BucketDataDoc.js';
8
10
 
9
11
  export function idPrefixFilter<T>(prefix: Partial<T>, rest: (keyof T)[]): mongo.Condition<T> {
10
12
  let filter = {
@@ -69,10 +71,10 @@ export async function readSingleBatch<T>(cursor: mongo.AbstractCursor<T>): Promi
69
71
  }
70
72
  }
71
73
 
72
- export function mapOpEntry(row: BucketDataDocument): utils.OplogEntry {
74
+ export function mapOpEntry(row: BucketDataDoc): utils.OplogEntry {
73
75
  if (row.op == 'PUT' || row.op == 'REMOVE') {
74
76
  return {
75
- op_id: utils.internalToExternalOpId(row._id.o),
77
+ op_id: utils.internalToExternalOpId(row.o),
76
78
  op: row.op,
77
79
  object_type: row.table,
78
80
  object_id: row.row_id,
@@ -84,7 +86,7 @@ export function mapOpEntry(row: BucketDataDocument): utils.OplogEntry {
84
86
  // MOVE, CLEAR
85
87
 
86
88
  return {
87
- op_id: utils.internalToExternalOpId(row._id.o),
89
+ op_id: utils.internalToExternalOpId(row.o),
88
90
  op: row.op,
89
91
  checksum: Number(row.checksum)
90
92
  };
@@ -129,6 +131,33 @@ export function setSessionSnapshotTime(session: mongo.ClientSession, time: bson.
129
131
  }
130
132
  }
131
133
 
134
+ export async function retryOnMongoMaxTimeMSExpired<T>(
135
+ operation: () => Promise<T>,
136
+ options: {
137
+ signal?: AbortSignal;
138
+ abortMessage?: string;
139
+ retryDelayMs: number;
140
+ onRetry?: (retryCount: number) => void;
141
+ }
142
+ ): Promise<T> {
143
+ let retryCount = 0;
144
+ while (true) {
145
+ if (options.signal?.aborted) {
146
+ throw new ReplicationAbortedError(options.abortMessage ?? 'Aborted MongoDB operation', options.signal.reason);
147
+ }
148
+ try {
149
+ return await operation();
150
+ } catch (e) {
151
+ if (!lib_mongo.isMongoServerError(e) || e.codeName !== 'MaxTimeMSExpired') {
152
+ throw e;
153
+ }
154
+ retryCount += 1;
155
+ options.onRetry?.(retryCount);
156
+ await timers.setTimeout(options.retryDelayMs);
157
+ }
158
+ }
159
+ }
160
+
132
161
  export const createPaginatedConnectionQuery = async <T extends mongo.Document>(
133
162
  query: mongo.Filter<T>,
134
163
  collection: mongo.Collection<T>,
@@ -19,7 +19,7 @@ exports[`Connection reporting storage > Should create a connection report if its
19
19
 
20
20
  exports[`Connection reporting storage > Should delete rows older than specified range 1`] = `
21
21
  {
22
- "sdk_breakdown": [
22
+ "sdks": [
23
23
  {
24
24
  "clients": 1,
25
25
  "sdk": "powersync-dart/1.6.4",
@@ -51,7 +51,7 @@ exports[`Connection reporting storage > Should delete rows older than specified
51
51
  "users": 1,
52
52
  },
53
53
  ],
54
- "total_users": 5,
54
+ "users": 5,
55
55
  }
56
56
  `;
57
57
 
@@ -77,9 +77,9 @@ exports[`Connection reporting storage > Should update a connection report if its
77
77
  ]
78
78
  `;
79
79
 
80
- exports[`Report storage tests > getClientConnectionsSummary returns the past day summary 1`] = `
80
+ exports[`Report storage tests > Should show connection report data for user over the past day 1`] = `
81
81
  {
82
- "sdk_breakdown": [
82
+ "sdks": [
83
83
  {
84
84
  "clients": 1,
85
85
  "sdk": "powersync-dart/1.6.4",
@@ -101,13 +101,13 @@ exports[`Report storage tests > getClientConnectionsSummary returns the past day
101
101
  "users": 1,
102
102
  },
103
103
  ],
104
- "total_users": 3,
104
+ "users": 3,
105
105
  }
106
106
  `;
107
107
 
108
- exports[`Report storage tests > getClientConnectionsSummary returns the past month summary 1`] = `
108
+ exports[`Report storage tests > Should show connection report data for user over the past month 1`] = `
109
109
  {
110
- "sdk_breakdown": [
110
+ "sdks": [
111
111
  {
112
112
  "clients": 1,
113
113
  "sdk": "powersync-dart/1.6.4",
@@ -149,13 +149,13 @@ exports[`Report storage tests > getClientConnectionsSummary returns the past mon
149
149
  "users": 1,
150
150
  },
151
151
  ],
152
- "total_users": 7,
152
+ "users": 7,
153
153
  }
154
154
  `;
155
155
 
156
- exports[`Report storage tests > getClientConnectionsSummary returns the past week summary 1`] = `
156
+ exports[`Report storage tests > Should show connection report data for user over the past week 1`] = `
157
157
  {
158
- "sdk_breakdown": [
158
+ "sdks": [
159
159
  {
160
160
  "clients": 1,
161
161
  "sdk": "powersync-dart/1.6.4",
@@ -187,11 +187,50 @@ exports[`Report storage tests > getClientConnectionsSummary returns the past wee
187
187
  "users": 1,
188
188
  },
189
189
  ],
190
- "total_users": 5,
190
+ "users": 5,
191
191
  }
192
192
  `;
193
193
 
194
- exports[`Report storage tests > getClientSessions returns paginated sessions with a limit 1`] = `
194
+ exports[`Report storage tests > Should show currently connected users 1`] = `
195
+ {
196
+ "sdks": [
197
+ {
198
+ "clients": 1,
199
+ "sdk": "powersync-dart/1.6.4",
200
+ "users": 1,
201
+ },
202
+ {
203
+ "clients": 1,
204
+ "sdk": "powersync-js/1.21.1",
205
+ "users": 1,
206
+ },
207
+ {
208
+ "clients": 1,
209
+ "sdk": "unknown",
210
+ "users": 1,
211
+ },
212
+ ],
213
+ "users": 2,
214
+ }
215
+ `;
216
+
217
+ exports[`Report storage tests > Should show paginated response of all connections of specified client_id 1`] = `
218
+ {
219
+ "count": 1,
220
+ "cursor": undefined,
221
+ "items": [
222
+ {
223
+ "client_id": "client_two",
224
+ "sdk": "powersync-js/1.21.1",
225
+ "user_agent": "powersync-js/1.21.0 powersync-web Chromium/138 linux",
226
+ "user_id": "user_two",
227
+ },
228
+ ],
229
+ "more": false,
230
+ }
231
+ `;
232
+
233
+ exports[`Report storage tests > Should show paginated response of all connections with a limit 1`] = `
195
234
  {
196
235
  "count": 4,
197
236
  "cursor": "<removed-for-snapshot>",
@@ -225,7 +264,7 @@ exports[`Report storage tests > getClientSessions returns paginated sessions wit
225
264
  }
226
265
  `;
227
266
 
228
- exports[`Report storage tests > getClientSessions returns paginated sessions with a limit 2`] = `
267
+ exports[`Report storage tests > Should show paginated response of all connections with a limit 2`] = `
229
268
  {
230
269
  "count": 4,
231
270
  "cursor": undefined,
@@ -259,7 +298,7 @@ exports[`Report storage tests > getClientSessions returns paginated sessions wit
259
298
  }
260
299
  `;
261
300
 
262
- exports[`Report storage tests > getClientSessions returns paginated sessions with a limit and date range 1`] = `
301
+ exports[`Report storage tests > Should show paginated response of all connections with a limit with date range 1`] = `
263
302
  {
264
303
  "count": 4,
265
304
  "cursor": "<removed-for-snapshot>",
@@ -293,7 +332,7 @@ exports[`Report storage tests > getClientSessions returns paginated sessions wit
293
332
  }
294
333
  `;
295
334
 
296
- exports[`Report storage tests > getClientSessions returns paginated sessions with a limit and date range 2`] = `
335
+ exports[`Report storage tests > Should show paginated response of all connections with a limit with date range 2`] = `
297
336
  {
298
337
  "count": 2,
299
338
  "cursor": undefined,
@@ -327,23 +366,29 @@ exports[`Report storage tests > getClientSessions returns paginated sessions wit
327
366
  }
328
367
  `;
329
368
 
330
- exports[`Report storage tests > getClientSessions returns sessions for a client_id 1`] = `
369
+ exports[`Report storage tests > Should show paginated response of connections of specified user_id 1`] = `
331
370
  {
332
- "count": 1,
371
+ "count": 2,
333
372
  "cursor": undefined,
334
373
  "items": [
335
374
  {
336
- "client_id": "client_two",
337
- "sdk": "powersync-js/1.21.1",
338
- "user_agent": "powersync-js/1.21.0 powersync-web Chromium/138 linux",
339
- "user_id": "user_two",
375
+ "client_id": "client_one",
376
+ "sdk": "powersync-dart/1.6.4",
377
+ "user_agent": "powersync-dart/1.6.4 Dart (flutter-web) Chrome/128 android",
378
+ "user_id": "user_one",
379
+ },
380
+ {
381
+ "client_id": "",
382
+ "sdk": "unknown",
383
+ "user_agent": "Dart (flutter-web) Chrome/128 android",
384
+ "user_id": "user_one",
340
385
  },
341
386
  ],
342
387
  "more": false,
343
388
  }
344
389
  `;
345
390
 
346
- exports[`Report storage tests > getClientSessions returns sessions for a date range 1`] = `
391
+ exports[`Report storage tests > Should show paginated response of connections over a date range 1`] = `
347
392
  {
348
393
  "count": 6,
349
394
  "cursor": undefined,
@@ -389,29 +434,7 @@ exports[`Report storage tests > getClientSessions returns sessions for a date ra
389
434
  }
390
435
  `;
391
436
 
392
- exports[`Report storage tests > getClientSessions returns sessions for a user_id 1`] = `
393
- {
394
- "count": 2,
395
- "cursor": undefined,
396
- "items": [
397
- {
398
- "client_id": "client_one",
399
- "sdk": "powersync-dart/1.6.4",
400
- "user_agent": "powersync-dart/1.6.4 Dart (flutter-web) Chrome/128 android",
401
- "user_id": "user_one",
402
- },
403
- {
404
- "client_id": "",
405
- "sdk": "unknown",
406
- "user_agent": "Dart (flutter-web) Chrome/128 android",
407
- "user_id": "user_one",
408
- },
409
- ],
410
- "more": false,
411
- }
412
- `;
413
-
414
- exports[`Report storage tests > getClientSessions returns sessions for client_id and user_id within a date range 1`] = `
437
+ exports[`Report storage tests > Should show paginated response of connections over a date range of specified client_id and user_id 1`] = `
415
438
  {
416
439
  "count": 1,
417
440
  "cursor": undefined,
@@ -426,26 +449,3 @@ exports[`Report storage tests > getClientSessions returns sessions for client_id
426
449
  "more": false,
427
450
  }
428
451
  `;
429
-
430
- exports[`Report storage tests > getCurrentConnections returns current connections 1`] = `
431
- {
432
- "sdk_breakdown": [
433
- {
434
- "clients": 1,
435
- "sdk": "powersync-dart/1.6.4",
436
- "users": 1,
437
- },
438
- {
439
- "clients": 1,
440
- "sdk": "powersync-js/1.21.1",
441
- "users": 1,
442
- },
443
- {
444
- "clients": 1,
445
- "sdk": "unknown",
446
- "users": 1,
447
- },
448
- ],
449
- "total_users": 2,
450
- }
451
- `;