@powersync/service-module-mongodb-storage 0.16.0 → 0.18.0

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 (206) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/storage/MongoBucketStorage.d.ts +35 -15
  3. package/dist/storage/MongoBucketStorage.js +309 -86
  4. package/dist/storage/MongoBucketStorage.js.map +1 -1
  5. package/dist/storage/implementation/CheckpointState.d.ts +20 -0
  6. package/dist/storage/implementation/CheckpointState.js +31 -0
  7. package/dist/storage/implementation/CheckpointState.js.map +1 -0
  8. package/dist/storage/implementation/MongoBucketBatch.d.ts +69 -39
  9. package/dist/storage/implementation/MongoBucketBatch.js +104 -313
  10. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  11. package/dist/storage/implementation/MongoChecksums.d.ts +11 -9
  12. package/dist/storage/implementation/MongoChecksums.js +3 -111
  13. package/dist/storage/implementation/MongoChecksums.js.map +1 -1
  14. package/dist/storage/implementation/MongoCompactor.d.ts +3 -1
  15. package/dist/storage/implementation/MongoCompactor.js +18 -9
  16. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  17. package/dist/storage/implementation/MongoHydrationState.d.ts +11 -0
  18. package/dist/storage/implementation/MongoHydrationState.js +49 -0
  19. package/dist/storage/implementation/MongoHydrationState.js.map +1 -0
  20. package/dist/storage/implementation/MongoParameterCompactor.d.ts +6 -5
  21. package/dist/storage/implementation/MongoParameterCompactor.js +24 -1
  22. package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
  23. package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +13 -0
  24. package/dist/storage/implementation/MongoParsedSyncConfigSet.js +64 -0
  25. package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -0
  26. package/dist/storage/implementation/MongoPersistedReplicationStream.d.ts +36 -0
  27. package/dist/storage/implementation/MongoPersistedReplicationStream.js +90 -0
  28. package/dist/storage/implementation/MongoPersistedReplicationStream.js.map +1 -0
  29. package/dist/storage/implementation/MongoPersistedSyncConfigContent.d.ts +25 -0
  30. package/dist/storage/implementation/MongoPersistedSyncConfigContent.js +121 -0
  31. package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -0
  32. package/dist/storage/implementation/MongoStorageProvider.js +5 -2
  33. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  34. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +50 -21
  35. package/dist/storage/implementation/MongoSyncBucketStorage.js +62 -199
  36. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  37. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +5 -1
  38. package/dist/storage/implementation/MongoSyncRulesLock.js +9 -5
  39. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  40. package/dist/storage/implementation/SyncRuleStateUpdate.d.ts +14 -0
  41. package/dist/storage/implementation/SyncRuleStateUpdate.js +36 -0
  42. package/dist/storage/implementation/SyncRuleStateUpdate.js.map +1 -0
  43. package/dist/storage/implementation/common/BucketDataDoc.d.ts +1 -1
  44. package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.d.ts +6 -0
  45. package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js +2 -0
  46. package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js.map +1 -0
  47. package/dist/storage/implementation/common/PersistedBatch.d.ts +2 -3
  48. package/dist/storage/implementation/common/PersistedBatch.js +5 -0
  49. package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
  50. package/dist/storage/implementation/common/SourceRecordStore.d.ts +1 -2
  51. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.d.ts +1 -1
  52. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +1 -1
  53. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -1
  54. package/dist/storage/implementation/createMongoSyncBucketStorage.d.ts +2 -2
  55. package/dist/storage/implementation/createMongoSyncBucketStorage.js +4 -4
  56. package/dist/storage/implementation/createMongoSyncBucketStorage.js.map +1 -1
  57. package/dist/storage/implementation/db.d.ts +10 -2
  58. package/dist/storage/implementation/db.js +9 -14
  59. package/dist/storage/implementation/db.js.map +1 -1
  60. package/dist/storage/implementation/models.d.ts +25 -50
  61. package/dist/storage/implementation/models.js.map +1 -1
  62. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +23 -1
  63. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +403 -2
  64. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
  65. package/dist/storage/implementation/v1/MongoChecksumsV1.js +114 -3
  66. package/dist/storage/implementation/v1/MongoChecksumsV1.js.map +1 -1
  67. package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +1 -1
  68. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +22 -15
  69. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +100 -27
  70. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
  71. package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +1 -2
  72. package/dist/storage/implementation/v1/PersistedBatchV1.js.map +1 -1
  73. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.d.ts +2 -1
  74. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js +3 -0
  75. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js.map +1 -1
  76. package/dist/storage/implementation/v1/models.d.ts +21 -1
  77. package/dist/storage/implementation/v1/models.js.map +1 -1
  78. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +21 -0
  79. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +459 -3
  80. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
  81. package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +27 -7
  82. package/dist/storage/implementation/v3/MongoChecksumsV3.js +202 -18
  83. package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -1
  84. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +20 -3
  85. package/dist/storage/implementation/v3/MongoCompactorV3.js +511 -22
  86. package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
  87. package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +62 -0
  88. package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +350 -0
  89. package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -0
  90. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +50 -16
  91. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +292 -75
  92. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
  93. package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +2 -3
  94. package/dist/storage/implementation/v3/PersistedBatchV3.js +43 -20
  95. package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
  96. package/dist/storage/implementation/v3/SingleBucketStoreV3.js +52 -16
  97. package/dist/storage/implementation/v3/SingleBucketStoreV3.js.map +1 -1
  98. package/dist/storage/implementation/v3/SourceRecordStoreV3.d.ts +3 -3
  99. package/dist/storage/implementation/v3/SourceRecordStoreV3.js +13 -11
  100. package/dist/storage/implementation/v3/SourceRecordStoreV3.js.map +1 -1
  101. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +16 -14
  102. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +32 -27
  103. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
  104. package/dist/storage/implementation/v3/bucket-format.d.ts +4 -0
  105. package/dist/storage/implementation/v3/bucket-format.js +58 -0
  106. package/dist/storage/implementation/v3/bucket-format.js.map +1 -0
  107. package/dist/storage/implementation/v3/chunking.d.ts +10 -0
  108. package/dist/storage/implementation/v3/chunking.js +28 -0
  109. package/dist/storage/implementation/v3/chunking.js.map +1 -0
  110. package/dist/storage/implementation/v3/models.d.ts +111 -10
  111. package/dist/storage/implementation/v3/models.js +11 -28
  112. package/dist/storage/implementation/v3/models.js.map +1 -1
  113. package/dist/storage/implementation/v3/source-table-utils.d.ts +55 -0
  114. package/dist/storage/implementation/v3/source-table-utils.js +214 -0
  115. package/dist/storage/implementation/v3/source-table-utils.js.map +1 -0
  116. package/dist/storage/storage-index.d.ts +4 -4
  117. package/dist/storage/storage-index.js +4 -4
  118. package/dist/storage/storage-index.js.map +1 -1
  119. package/dist/types/types.d.ts +2 -2
  120. package/dist/utils/test-utils.d.ts +1 -2
  121. package/dist/utils/test-utils.js +5 -1
  122. package/dist/utils/test-utils.js.map +1 -1
  123. package/dist/utils/util.d.ts +1 -1
  124. package/dist/utils/util.js +3 -2
  125. package/dist/utils/util.js.map +1 -1
  126. package/package.json +9 -19
  127. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +1 -1
  128. package/src/storage/MongoBucketStorage.ts +464 -95
  129. package/src/storage/implementation/CheckpointState.ts +59 -0
  130. package/src/storage/implementation/MongoBucketBatch.ts +159 -405
  131. package/src/storage/implementation/MongoChecksums.ts +7 -138
  132. package/src/storage/implementation/MongoCompactor.ts +20 -10
  133. package/src/storage/implementation/MongoHydrationState.ts +61 -0
  134. package/src/storage/implementation/MongoParameterCompactor.ts +24 -5
  135. package/src/storage/implementation/MongoParsedSyncConfigSet.ts +88 -0
  136. package/src/storage/implementation/MongoPersistedReplicationStream.ts +118 -0
  137. package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +152 -0
  138. package/src/storage/implementation/MongoStorageProvider.ts +5 -2
  139. package/src/storage/implementation/MongoSyncBucketStorage.ts +89 -250
  140. package/src/storage/implementation/MongoSyncRulesLock.ts +14 -5
  141. package/src/storage/implementation/SyncRuleStateUpdate.ts +38 -0
  142. package/src/storage/implementation/common/BucketDataDoc.ts +1 -1
  143. package/src/storage/implementation/common/MongoSyncBucketStorageCheckpoint.ts +7 -0
  144. package/src/storage/implementation/common/PersistedBatch.ts +8 -4
  145. package/src/storage/implementation/common/SourceRecordStore.ts +1 -2
  146. package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +1 -1
  147. package/src/storage/implementation/createMongoSyncBucketStorage.ts +21 -7
  148. package/src/storage/implementation/db.ts +16 -21
  149. package/src/storage/implementation/models.ts +28 -61
  150. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +503 -5
  151. package/src/storage/implementation/v1/MongoChecksumsV1.ts +137 -4
  152. package/src/storage/implementation/v1/MongoCompactorV1.ts +1 -1
  153. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +150 -49
  154. package/src/storage/implementation/v1/PersistedBatchV1.ts +1 -2
  155. package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +11 -1
  156. package/src/storage/implementation/v1/models.ts +25 -0
  157. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +611 -4
  158. package/src/storage/implementation/v3/MongoChecksumsV3.ts +262 -26
  159. package/src/storage/implementation/v3/MongoCompactorV3.ts +647 -30
  160. package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +480 -0
  161. package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +397 -111
  162. package/src/storage/implementation/v3/PersistedBatchV3.ts +63 -38
  163. package/src/storage/implementation/v3/SingleBucketStoreV3.ts +59 -19
  164. package/src/storage/implementation/v3/SourceRecordStoreV3.ts +12 -12
  165. package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +48 -38
  166. package/src/storage/implementation/v3/bucket-format.ts +70 -0
  167. package/src/storage/implementation/v3/chunking.ts +38 -0
  168. package/src/storage/implementation/v3/models.ts +150 -44
  169. package/src/storage/implementation/v3/source-table-utils.ts +392 -0
  170. package/src/storage/storage-index.ts +12 -4
  171. package/src/utils/test-utils.ts +6 -3
  172. package/src/utils/util.ts +3 -2
  173. package/test/src/__snapshots__/storage.test.ts.snap +0 -75
  174. package/test/src/__snapshots__/storage_sync.test.ts.snap +48 -48
  175. package/test/src/cleanup-stopped-sync-configs.test.ts +648 -0
  176. package/test/src/storage.test.ts +11 -11
  177. package/test/src/storage_compacting.test.ts +1956 -6
  178. package/test/src/storage_sync.test.ts +1429 -42
  179. package/test/src/storeCurrentData.test.ts +221 -0
  180. package/test/src/util.ts +2 -1
  181. package/tsconfig.json +1 -4
  182. package/tsconfig.tsbuildinfo +1 -1
  183. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +0 -17
  184. package/dist/storage/implementation/BucketDefinitionMapping.js +0 -58
  185. package/dist/storage/implementation/BucketDefinitionMapping.js.map +0 -1
  186. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +0 -14
  187. package/dist/storage/implementation/MongoPersistedSyncRules.js +0 -64
  188. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
  189. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +0 -15
  190. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +0 -42
  191. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +0 -1
  192. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.d.ts +0 -13
  193. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js +0 -2
  194. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js.map +0 -1
  195. package/dist/storage/implementation/v3/MongoParameterCompactorV3.d.ts +0 -9
  196. package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +0 -18
  197. package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +0 -1
  198. package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +0 -5
  199. package/dist/storage/implementation/v3/MongoParameterLookupV3.js +0 -9
  200. package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +0 -1
  201. package/src/storage/implementation/BucketDefinitionMapping.ts +0 -72
  202. package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -76
  203. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +0 -56
  204. package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +0 -15
  205. package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +0 -24
  206. package/src/storage/implementation/v3/MongoParameterLookupV3.ts +0 -12
@@ -1,11 +1,13 @@
1
1
  import * as lib_mongo from '@powersync/lib-service-mongodb';
2
2
  import { mongo } from '@powersync/lib-service-mongodb';
3
+ import { ServiceAssertionError } from '@powersync/lib-services-framework';
3
4
  import {
4
5
  CheckpointChanges,
5
6
  deserializeParameterLookup,
6
7
  GetCheckpointChangesOptions,
7
8
  InternalOpId,
8
9
  internalToExternalOpId,
10
+ maxLsn,
9
11
  ParameterSetLimitExceededError,
10
12
  ProtocolOpId,
11
13
  storage,
@@ -16,51 +18,161 @@ import { ParameterLookupRows, ScopedParameterLookup, SqliteJsonRow } from '@powe
16
18
  import * as bson from 'bson';
17
19
  import { idPrefixFilter, mapOpEntry, readSingleBatch, setSessionSnapshotTime } from '../../../utils/util.js';
18
20
  import { MongoBucketStorage } from '../../MongoBucketStorage.js';
19
- import {
20
- MongoSyncBucketStorageCheckpoint,
21
- MongoSyncBucketStorageContext
22
- } from '../common/MongoSyncBucketStorageContext.js';
23
- import { CommonSourceTableDocument, SourceKey } from '../models.js';
24
- import { MongoBucketBatchOptions } from '../MongoBucketBatch.js';
21
+ import { MongoSyncBucketStorageCheckpoint } from '../common/MongoSyncBucketStorageCheckpoint.js';
22
+ import { SourceKey } from '../models.js';
25
23
  import { MongoChecksums } from '../MongoChecksums.js';
26
24
  import { MongoCompactOptions, MongoCompactor } from '../MongoCompactor.js';
27
25
  import { MongoParameterCompactor } from '../MongoParameterCompactor.js';
28
- import { MongoPersistedSyncRulesContent } from '../MongoPersistedSyncRulesContent.js';
26
+ import { MongoPersistedReplicationStream } from '../MongoPersistedReplicationStream.js';
29
27
  import { MongoSyncBucketStorage, MongoSyncBucketStorageOptions } from '../MongoSyncBucketStorage.js';
30
- import { BucketDataDocumentV1, BucketDataKeyV1, BucketStateDocument, loadBucketDataDocumentV1 } from './models.js';
28
+ import {
29
+ BucketDataDocumentV1,
30
+ BucketDataKeyV1,
31
+ BucketStateDocument,
32
+ loadBucketDataDocumentV1,
33
+ SyncRuleDocumentV1
34
+ } from './models.js';
31
35
  import { MongoBucketBatchV1 } from './MongoBucketBatchV1.js';
32
36
  import { MongoChecksumsV1 } from './MongoChecksumsV1.js';
33
37
  import { MongoCompactorV1 } from './MongoCompactorV1.js';
34
38
  import { MongoParameterCompactorV1 } from './MongoParameterCompactorV1.js';
35
39
  import { VersionedPowerSyncMongoV1 } from './VersionedPowerSyncMongoV1.js';
36
40
 
41
+ export interface MongoSyncBucketStorageContextV1 {
42
+ db: VersionedPowerSyncMongoV1;
43
+ replicationStreamId: number;
44
+ }
45
+
37
46
  export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
38
- // Declare types to be more specific
39
47
  declare readonly db: VersionedPowerSyncMongoV1;
40
48
  declare readonly checksums: MongoChecksumsV1;
41
49
 
42
50
  constructor(
43
51
  factory: MongoBucketStorage,
44
- group_id: number,
45
- sync_rules: MongoPersistedSyncRulesContent,
46
- slot_name: string,
52
+ replicationStreamId: number,
53
+ replicationStream: MongoPersistedReplicationStream,
54
+ replicationStreamName: string,
47
55
  writeCheckpointMode: storage.WriteCheckpointMode | undefined,
48
56
  options: MongoSyncBucketStorageOptions
49
57
  ) {
50
- super(factory, group_id, sync_rules, slot_name, writeCheckpointMode, options);
58
+ super(factory, replicationStreamId, replicationStream, replicationStreamName, writeCheckpointMode, options);
51
59
  }
52
60
 
53
61
  protected async initializeVersionStorage(): Promise<void> {}
54
62
 
55
- protected createWriterImpl(batchOptions: MongoBucketBatchOptions): storage.BucketStorageBatch {
56
- return new MongoBucketBatchV1(batchOptions);
63
+ protected async fetchPersistedOpHead(): Promise<InternalOpId | null> {
64
+ const doc = (await this.db.sync_rules.findOne(
65
+ { _id: this.replicationStreamId },
66
+ { projection: { keepalive_op: 1, last_checkpoint: 1 } }
67
+ )) as SyncRuleDocumentV1;
68
+ // keepalive_op covers ops not yet in a checkpoint (cleared once checkpointed),
69
+ // so the head is the max of the two.
70
+ const keepaliveOp = doc?.keepalive_op == null ? null : BigInt(doc.keepalive_op);
71
+ const lastCheckpoint = doc?.last_checkpoint ?? null;
72
+ if (keepaliveOp == null && lastCheckpoint == null) {
73
+ return null;
74
+ }
75
+ return (keepaliveOp ?? 0n) > (lastCheckpoint ?? 0n) ? keepaliveOp : lastCheckpoint;
76
+ }
77
+
78
+ protected async createWriterImpl(options: storage.CreateWriterOptions): Promise<storage.BucketStorageBatch> {
79
+ const doc = (await this.db.sync_rules.findOne(
80
+ {
81
+ _id: this.replicationStreamId
82
+ },
83
+ { projection: { last_checkpoint_lsn: 1, keepalive_op: 1, snapshot_lsn: 1 } }
84
+ )) as SyncRuleDocumentV1;
85
+
86
+ return new MongoBucketBatchV1({
87
+ ...this.writerBatchOptions(options),
88
+ // Resume from the last consistent checkpoint, or the in-progress snapshot position if it is newer.
89
+ resumeFromLsn: maxLsn(doc?.last_checkpoint_lsn, doc?.snapshot_lsn),
90
+ keepaliveOp: doc?.keepalive_op ? BigInt(doc.keepalive_op) : null
91
+ });
92
+ }
93
+
94
+ protected async fetchCheckpointState(
95
+ session: mongo.ClientSession
96
+ ): Promise<{ checkpoint: bigint; lsn: string | null } | null> {
97
+ const doc = (await this.db.sync_rules.findOne(
98
+ { _id: this.replicationStreamId },
99
+ {
100
+ session,
101
+ projection: { _id: 1, state: 1, last_checkpoint: 1, last_checkpoint_lsn: 1, snapshot_done: 1 }
102
+ }
103
+ )) as SyncRuleDocumentV1;
104
+ if (!doc?.snapshot_done || ![storage.SyncRuleState.ACTIVE, storage.SyncRuleState.ERRORED].includes(doc.state)) {
105
+ return null;
106
+ }
107
+ return {
108
+ checkpoint: doc.last_checkpoint ?? 0n,
109
+ lsn: doc.last_checkpoint_lsn ?? null
110
+ };
111
+ }
112
+
113
+ protected async terminateSyncRuleState(): Promise<void> {
114
+ await this.db.sync_rules.updateOne(
115
+ {
116
+ _id: this.replicationStreamId
117
+ },
118
+ {
119
+ $set: {
120
+ state: storage.SyncRuleState.TERMINATED,
121
+ persisted_lsn: null,
122
+ snapshot_done: false
123
+ }
124
+ }
125
+ );
126
+ }
127
+
128
+ protected async getStatusImpl(): Promise<storage.ReplicationStreamStatus> {
129
+ const doc = (await this.db.sync_rules.findOne(
130
+ {
131
+ _id: this.replicationStreamId
132
+ },
133
+ {
134
+ projection: {
135
+ snapshot_done: 1,
136
+ last_checkpoint_lsn: 1,
137
+ snapshot_lsn: 1
138
+ }
139
+ }
140
+ )) as SyncRuleDocumentV1;
141
+ if (doc == null) {
142
+ throw new ServiceAssertionError('Cannot find replication stream status');
143
+ }
144
+
145
+ return {
146
+ snapshotDone: doc.snapshot_done && doc.last_checkpoint_lsn != null,
147
+ resumeLsn: maxLsn(doc.snapshot_lsn, doc.last_checkpoint_lsn)
148
+ };
149
+ }
150
+
151
+ protected async clearSyncRuleState(): Promise<void> {
152
+ await this.db.sync_rules.updateOne(
153
+ {
154
+ _id: this.replicationStreamId
155
+ },
156
+ {
157
+ $set: {
158
+ snapshot_done: false,
159
+ persisted_lsn: null,
160
+ last_checkpoint_lsn: null,
161
+ last_checkpoint: null,
162
+ no_checkpoint_before: null
163
+ },
164
+ $unset: {
165
+ snapshot_lsn: 1
166
+ }
167
+ },
168
+ { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
169
+ );
57
170
  }
58
171
 
59
172
  protected createMongoChecksums(options: MongoSyncBucketStorageOptions): MongoChecksums {
60
- return new MongoChecksumsV1(this.db, this.group_id, {
173
+ return new MongoChecksumsV1(this.db, this.replicationStreamId, {
61
174
  ...options.checksumOptions,
62
- storageConfig: options?.storageConfig,
63
- mapping: this.sync_rules.mapping
175
+ storageConfig: options?.storageConfig
64
176
  });
65
177
  }
66
178
 
@@ -72,26 +184,13 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
72
184
  checkpoint: InternalOpId,
73
185
  options: storage.CompactOptions
74
186
  ): MongoParameterCompactor {
75
- return new MongoParameterCompactorV1(this.db, this.group_id, checkpoint, options);
76
- }
77
-
78
- protected sourceTableBaseId(): Partial<CommonSourceTableDocument> {
79
- return { group_id: this.group_id };
187
+ return new MongoParameterCompactorV1(this.db, this.replicationStreamId, checkpoint, options);
80
188
  }
81
189
 
82
- protected augmentCreatedSourceTableDocument(
83
- _createDoc: CommonSourceTableDocument,
84
- _options: storage.ResolveTableOptions,
85
- _candidateSourceTable: storage.SourceTable
86
- ): void {}
87
-
88
- protected async initializeResolvedSourceRecords(_sourceTableId: bson.ObjectId): Promise<void> {}
89
-
90
- protected override get versionContext(): MongoSyncBucketStorageContext<VersionedPowerSyncMongoV1> {
190
+ protected get versionContext(): MongoSyncBucketStorageContextV1 {
91
191
  return {
92
192
  db: this.db,
93
- group_id: this.group_id,
94
- mapping: this.mapping
193
+ replicationStreamId: this.replicationStreamId
95
194
  };
96
195
  }
97
196
 
@@ -117,7 +216,7 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
117
216
  () =>
118
217
  this.db.bucket_data.deleteMany(
119
218
  {
120
- _id: idPrefixFilter<BucketDataKeyV1>({ g: this.group_id }, ['b', 'o'])
219
+ _id: idPrefixFilter<BucketDataKeyV1>({ g: this.replicationStreamId }, ['b', 'o'])
121
220
  },
122
221
  { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
123
222
  ),
@@ -131,7 +230,7 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
131
230
  () =>
132
231
  this.db.parameterIndexV1.deleteMany(
133
232
  {
134
- 'key.g': this.group_id
233
+ 'key.g': this.replicationStreamId
135
234
  },
136
235
  { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
137
236
  ),
@@ -145,7 +244,7 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
145
244
  () =>
146
245
  this.db.sourceRecordsV1.deleteMany(
147
246
  {
148
- _id: idPrefixFilter<SourceKey>({ g: this.group_id }, ['t', 'k'])
247
+ _id: idPrefixFilter<SourceKey>({ g: this.replicationStreamId }, ['t', 'k'])
149
248
  },
150
249
  { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
151
250
  ),
@@ -159,7 +258,7 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
159
258
  () =>
160
259
  this.db.bucketStateV1.deleteMany(
161
260
  {
162
- _id: idPrefixFilter<BucketStateDocument['_id']>({ g: this.group_id }, ['b'])
261
+ _id: idPrefixFilter<BucketStateDocument['_id']>({ g: this.replicationStreamId }, ['b'])
163
262
  },
164
263
  { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
165
264
  ),
@@ -171,9 +270,9 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
171
270
  await this.clearDeleteMany(
172
271
  'source tables',
173
272
  () =>
174
- this.db.commonSourceTables(this.group_id).deleteMany(
273
+ this.db.sourceTablesV1(this.replicationStreamId).deleteMany(
175
274
  {
176
- group_id: this.group_id
275
+ group_id: this.replicationStreamId
177
276
  },
178
277
  { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
179
278
  ),
@@ -195,7 +294,7 @@ export class MongoSyncBucketStorageV1 extends MongoSyncBucketStorage {
195
294
  }
196
295
 
197
296
  export async function getParameterSetsV1(
198
- ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV1>,
297
+ ctx: MongoSyncBucketStorageContextV1,
199
298
  checkpoint: MongoSyncBucketStorageCheckpoint,
200
299
  lookups: ScopedParameterLookup[],
201
300
  limit: number
@@ -211,7 +310,7 @@ export async function getParameterSetsV1(
211
310
  [
212
311
  {
213
312
  $match: {
214
- 'key.g': ctx.group_id,
313
+ 'key.g': ctx.replicationStreamId,
215
314
  lookup: { $in: lookupFilter },
216
315
  _id: { $lte: checkpoint.checkpoint }
217
316
  }
@@ -269,7 +368,7 @@ export async function getParameterSetsV1(
269
368
  }
270
369
 
271
370
  export async function* getBucketDataBatchV1(
272
- ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV1>,
371
+ ctx: MongoSyncBucketStorageContextV1,
273
372
  checkpoint: utils.InternalOpId,
274
373
  dataBuckets: storage.BucketDataRequest[],
275
374
  options?: storage.BucketDataBatchOptions
@@ -288,12 +387,12 @@ export async function* getBucketDataBatchV1(
288
387
  filters.push({
289
388
  _id: {
290
389
  $gt: {
291
- g: ctx.group_id,
390
+ g: ctx.replicationStreamId,
292
391
  b: name,
293
392
  o: start
294
393
  },
295
394
  $lte: {
296
- g: ctx.group_id,
395
+ g: ctx.replicationStreamId,
297
396
  b: name,
298
397
  o: end as any
299
398
  }
@@ -304,6 +403,8 @@ export async function* getBucketDataBatchV1(
304
403
  const batchLimit = options?.limit ?? storage.DEFAULT_DOCUMENT_BATCH_LIMIT;
305
404
  const chunkSizeLimitBytes = options?.chunkLimitBytes ?? storage.DEFAULT_DOCUMENT_CHUNK_LIMIT_BYTES;
306
405
 
406
+ // raw: true returns Buffers, but the driver typing doesn't reflect that
407
+ // without an explicit cast to FindCursor<Buffer>.
307
408
  const cursor = ctx.db.bucket_data.find(
308
409
  {
309
410
  $or: filters
@@ -386,14 +487,14 @@ export async function* getBucketDataBatchV1(
386
487
  }
387
488
 
388
489
  export async function getDataBucketChangesV1(
389
- ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV1>,
490
+ ctx: MongoSyncBucketStorageContextV1,
390
491
  options: GetCheckpointChangesOptions
391
492
  ): Promise<Pick<CheckpointChanges, 'updatedDataBuckets' | 'invalidateDataBuckets'>> {
392
493
  const limit = 1000;
393
494
  const bucketStateUpdates = await ctx.db.bucketStateV1
394
495
  .find(
395
496
  {
396
- '_id.g': ctx.group_id,
497
+ '_id.g': ctx.replicationStreamId,
397
498
  last_op: { $gt: options.lastCheckpoint.checkpoint }
398
499
  },
399
500
  {
@@ -417,7 +518,7 @@ export async function getDataBucketChangesV1(
417
518
  }
418
519
 
419
520
  export async function getParameterBucketChangesV1(
420
- ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV1>,
521
+ ctx: MongoSyncBucketStorageContextV1,
421
522
  options: GetCheckpointChangesOptions
422
523
  ): Promise<Pick<CheckpointChanges, 'updatedParameterLookups' | 'invalidateParameterBuckets'>> {
423
524
  const limit = 1000;
@@ -425,7 +526,7 @@ export async function getParameterBucketChangesV1(
425
526
  .find(
426
527
  {
427
528
  _id: { $gt: options.lastCheckpoint.checkpoint, $lte: options.nextCheckpoint.checkpoint },
428
- 'key.g': ctx.group_id
529
+ 'key.g': ctx.replicationStreamId
429
530
  },
430
531
  {
431
532
  projection: {
@@ -3,9 +3,8 @@ import { ReplicationAssertionError } from '@powersync/lib-services-framework';
3
3
  import { storage } from '@powersync/service-core';
4
4
  import * as bson from 'bson';
5
5
 
6
- import { BucketDataSource } from '@powersync/service-sync-rules';
6
+ import { BucketDataSource, BucketDefinitionId } from '@powersync/service-sync-rules';
7
7
  import { mongoTableId } from '../../../utils/util.js';
8
- import { BucketDefinitionId } from '../BucketDefinitionMapping.js';
9
8
  import { EMPTY_DATA } from '../MongoBucketBatchShared.js';
10
9
  import {
11
10
  BucketStateUpdate,
@@ -1,7 +1,13 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { BaseVersionedPowerSyncMongo } from '../common/VersionedPowerSyncMongoBase.js';
3
3
  import { CommonSourceTableDocument } from '../models.js';
4
- import { BucketDataDocumentV1, BucketParameterDocument, BucketStateDocumentV1, CurrentDataDocument } from './models.js';
4
+ import {
5
+ BucketDataDocumentV1,
6
+ BucketParameterDocument,
7
+ BucketStateDocumentV1,
8
+ CurrentDataDocument,
9
+ SourceTableDocumentV1
10
+ } from './models.js';
5
11
 
6
12
  export class VersionedPowerSyncMongoV1 extends BaseVersionedPowerSyncMongo {
7
13
  get sourceRecordsV1(): mongo.Collection<CurrentDataDocument> {
@@ -16,6 +22,10 @@ export class VersionedPowerSyncMongoV1 extends BaseVersionedPowerSyncMongo {
16
22
  return this.upstream.source_tables as any as mongo.Collection<CommonSourceTableDocument>;
17
23
  }
18
24
 
25
+ sourceTablesV1(_replicationStreamId: number): mongo.Collection<SourceTableDocumentV1> {
26
+ return this.upstream.source_tables as any as mongo.Collection<SourceTableDocumentV1>;
27
+ }
28
+
19
29
  async initializeStreamStorage(_replicationStreamId: number): Promise<void> {}
20
30
 
21
31
  get bucketDataV1(): mongo.Collection<BucketDataDocumentV1> {
@@ -1,3 +1,4 @@
1
+ import { SerializedSyncPlan } from '@powersync/service-core';
1
2
  import * as bson from 'bson';
2
3
  import { BucketDataDoc } from '../common/BucketDataDoc.js';
3
4
  import {
@@ -8,6 +9,8 @@ import {
8
9
  LEGACY_BUCKET_DATA_DEFINITION_ID,
9
10
  SourceKey,
10
11
  SourceTableDocument,
12
+ SyncRuleCheckpointFields,
13
+ SyncRuleDocumentBase,
11
14
  TaggedBucketParameterDocument
12
15
  } from '../models.js';
13
16
 
@@ -75,6 +78,28 @@ export interface SourceTableDocumentV1 extends SourceTableDocument {
75
78
  group_id: number;
76
79
  }
77
80
 
81
+ export interface SyncRuleDocumentV1 extends SyncRuleDocumentBase, SyncRuleCheckpointFields {
82
+ content: string;
83
+ serialized_plan?: SerializedSyncPlan | null;
84
+
85
+ /**
86
+ * True if initial snapshot has been replicated.
87
+ *
88
+ * Can only be false if state == PROCESSING.
89
+ */
90
+ snapshot_done: boolean;
91
+
92
+ /**
93
+ * Goes together with no_checkpoint_before.
94
+ *
95
+ * If a keepalive is triggered that creates the checkpoint > no_checkpoint_before,
96
+ * then the checkpoint must be equal to this keepalive_op.
97
+ *
98
+ * string for legacy reasons - it's always a number.
99
+ */
100
+ keepalive_op: string | null;
101
+ }
102
+
78
103
  export interface BucketStateDocumentV1 extends BucketStateDocumentBase {
79
104
  _id: BucketStateDocumentBase['_id'] & {
80
105
  g: number;