@powersync/service-module-mongodb-storage 0.17.0 → 0.18.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 (185) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/dist/storage/MongoBucketStorage.d.ts +34 -16
  3. package/dist/storage/MongoBucketStorage.js +219 -70
  4. package/dist/storage/MongoBucketStorage.js.map +1 -1
  5. package/dist/storage/implementation/MongoBucketBatch.d.ts +42 -23
  6. package/dist/storage/implementation/MongoBucketBatch.js +61 -44
  7. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  8. package/dist/storage/implementation/MongoChecksums.d.ts +10 -9
  9. package/dist/storage/implementation/MongoChecksums.js +3 -111
  10. package/dist/storage/implementation/MongoChecksums.js.map +1 -1
  11. package/dist/storage/implementation/MongoCompactor.d.ts +2 -0
  12. package/dist/storage/implementation/MongoCompactor.js +18 -9
  13. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  14. package/dist/storage/implementation/MongoHydrationState.d.ts +11 -0
  15. package/dist/storage/implementation/MongoHydrationState.js +49 -0
  16. package/dist/storage/implementation/MongoHydrationState.js.map +1 -0
  17. package/dist/storage/implementation/MongoParameterCompactor.d.ts +6 -5
  18. package/dist/storage/implementation/MongoParameterCompactor.js +24 -1
  19. package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
  20. package/dist/storage/implementation/MongoParsedSyncConfigSet.d.ts +13 -0
  21. package/dist/storage/implementation/MongoParsedSyncConfigSet.js +64 -0
  22. package/dist/storage/implementation/MongoParsedSyncConfigSet.js.map +1 -0
  23. package/dist/storage/implementation/MongoPersistedReplicationStream.d.ts +36 -0
  24. package/dist/storage/implementation/MongoPersistedReplicationStream.js +90 -0
  25. package/dist/storage/implementation/MongoPersistedReplicationStream.js.map +1 -0
  26. package/dist/storage/implementation/MongoPersistedSyncConfigContent.d.ts +25 -0
  27. package/dist/storage/implementation/MongoPersistedSyncConfigContent.js +123 -0
  28. package/dist/storage/implementation/MongoPersistedSyncConfigContent.js.map +1 -0
  29. package/dist/storage/implementation/MongoStorageProvider.js +5 -2
  30. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  31. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +41 -23
  32. package/dist/storage/implementation/MongoSyncBucketStorage.js +51 -43
  33. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  34. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +1 -1
  35. package/dist/storage/implementation/MongoSyncRulesLock.js +3 -3
  36. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  37. package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.d.ts +6 -0
  38. package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js +2 -0
  39. package/dist/storage/implementation/common/MongoSyncBucketStorageCheckpoint.js.map +1 -0
  40. package/dist/storage/implementation/common/PersistedBatch.d.ts +1 -2
  41. package/dist/storage/implementation/common/PersistedBatch.js +5 -0
  42. package/dist/storage/implementation/common/PersistedBatch.js.map +1 -1
  43. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js +1 -1
  44. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.js.map +1 -1
  45. package/dist/storage/implementation/createMongoSyncBucketStorage.d.ts +2 -2
  46. package/dist/storage/implementation/createMongoSyncBucketStorage.js +4 -4
  47. package/dist/storage/implementation/createMongoSyncBucketStorage.js.map +1 -1
  48. package/dist/storage/implementation/db.js +9 -14
  49. package/dist/storage/implementation/db.js.map +1 -1
  50. package/dist/storage/implementation/models.d.ts +4 -13
  51. package/dist/storage/implementation/models.js.map +1 -1
  52. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +9 -1
  53. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +42 -26
  54. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
  55. package/dist/storage/implementation/v1/MongoChecksumsV1.js +114 -3
  56. package/dist/storage/implementation/v1/MongoChecksumsV1.js.map +1 -1
  57. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +15 -17
  58. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +47 -45
  59. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
  60. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.d.ts +2 -1
  61. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js +3 -0
  62. package/dist/storage/implementation/v1/VersionedPowerSyncMongoV1.js.map +1 -1
  63. package/dist/storage/implementation/v1/models.d.ts +10 -1
  64. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +8 -4
  65. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +286 -259
  66. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
  67. package/dist/storage/implementation/v3/MongoChecksumsV3.d.ts +27 -7
  68. package/dist/storage/implementation/v3/MongoChecksumsV3.js +202 -18
  69. package/dist/storage/implementation/v3/MongoChecksumsV3.js.map +1 -1
  70. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +19 -2
  71. package/dist/storage/implementation/v3/MongoCompactorV3.js +511 -22
  72. package/dist/storage/implementation/v3/MongoCompactorV3.js.map +1 -1
  73. package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.d.ts +62 -0
  74. package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js +350 -0
  75. package/dist/storage/implementation/v3/MongoStoppedSyncConfigCleanup.js.map +1 -0
  76. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +40 -28
  77. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +232 -116
  78. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
  79. package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +1 -1
  80. package/dist/storage/implementation/v3/PersistedBatchV3.js +43 -20
  81. package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
  82. package/dist/storage/implementation/v3/SingleBucketStoreV3.js +52 -16
  83. package/dist/storage/implementation/v3/SingleBucketStoreV3.js.map +1 -1
  84. package/dist/storage/implementation/v3/SourceRecordStoreV3.d.ts +3 -3
  85. package/dist/storage/implementation/v3/SourceRecordStoreV3.js +13 -11
  86. package/dist/storage/implementation/v3/SourceRecordStoreV3.js.map +1 -1
  87. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +13 -12
  88. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +29 -27
  89. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
  90. package/dist/storage/implementation/v3/bucket-format.d.ts +4 -0
  91. package/dist/storage/implementation/v3/bucket-format.js +58 -0
  92. package/dist/storage/implementation/v3/bucket-format.js.map +1 -0
  93. package/dist/storage/implementation/v3/chunking.d.ts +10 -0
  94. package/dist/storage/implementation/v3/chunking.js +28 -0
  95. package/dist/storage/implementation/v3/chunking.js.map +1 -0
  96. package/dist/storage/implementation/v3/models.d.ts +64 -21
  97. package/dist/storage/implementation/v3/models.js +11 -28
  98. package/dist/storage/implementation/v3/models.js.map +1 -1
  99. package/dist/storage/implementation/v3/source-table-utils.d.ts +55 -0
  100. package/dist/storage/implementation/v3/source-table-utils.js +214 -0
  101. package/dist/storage/implementation/v3/source-table-utils.js.map +1 -0
  102. package/dist/storage/storage-index.d.ts +4 -4
  103. package/dist/storage/storage-index.js +4 -4
  104. package/dist/storage/storage-index.js.map +1 -1
  105. package/dist/types/types.d.ts +2 -2
  106. package/dist/utils/test-utils.d.ts +1 -2
  107. package/dist/utils/test-utils.js +5 -1
  108. package/dist/utils/test-utils.js.map +1 -1
  109. package/dist/utils/util.d.ts +1 -1
  110. package/dist/utils/util.js +3 -2
  111. package/dist/utils/util.js.map +1 -1
  112. package/package.json +9 -19
  113. package/src/storage/MongoBucketStorage.ts +334 -87
  114. package/src/storage/implementation/MongoBucketBatch.ts +86 -58
  115. package/src/storage/implementation/MongoChecksums.ts +6 -138
  116. package/src/storage/implementation/MongoCompactor.ts +19 -9
  117. package/src/storage/implementation/MongoHydrationState.ts +61 -0
  118. package/src/storage/implementation/MongoParameterCompactor.ts +24 -5
  119. package/src/storage/implementation/MongoParsedSyncConfigSet.ts +88 -0
  120. package/src/storage/implementation/MongoPersistedReplicationStream.ts +118 -0
  121. package/src/storage/implementation/MongoPersistedSyncConfigContent.ts +154 -0
  122. package/src/storage/implementation/MongoStorageProvider.ts +5 -2
  123. package/src/storage/implementation/MongoSyncBucketStorage.ts +70 -56
  124. package/src/storage/implementation/MongoSyncRulesLock.ts +7 -4
  125. package/src/storage/implementation/common/MongoSyncBucketStorageCheckpoint.ts +7 -0
  126. package/src/storage/implementation/common/PersistedBatch.ts +7 -3
  127. package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +1 -1
  128. package/src/storage/implementation/createMongoSyncBucketStorage.ts +21 -7
  129. package/src/storage/implementation/db.ts +11 -19
  130. package/src/storage/implementation/models.ts +4 -14
  131. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +55 -34
  132. package/src/storage/implementation/v1/MongoChecksumsV1.ts +137 -4
  133. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +70 -64
  134. package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +11 -1
  135. package/src/storage/implementation/v1/models.ts +11 -1
  136. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +358 -314
  137. package/src/storage/implementation/v3/MongoChecksumsV3.ts +262 -26
  138. package/src/storage/implementation/v3/MongoCompactorV3.ts +646 -29
  139. package/src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts +480 -0
  140. package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +315 -157
  141. package/src/storage/implementation/v3/PersistedBatchV3.ts +62 -36
  142. package/src/storage/implementation/v3/SingleBucketStoreV3.ts +59 -19
  143. package/src/storage/implementation/v3/SourceRecordStoreV3.ts +12 -12
  144. package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +41 -36
  145. package/src/storage/implementation/v3/bucket-format.ts +70 -0
  146. package/src/storage/implementation/v3/chunking.ts +38 -0
  147. package/src/storage/implementation/v3/models.ts +93 -55
  148. package/src/storage/implementation/v3/source-table-utils.ts +392 -0
  149. package/src/storage/storage-index.ts +12 -4
  150. package/src/utils/test-utils.ts +6 -3
  151. package/src/utils/util.ts +3 -2
  152. package/test/src/__snapshots__/storage.test.ts.snap +0 -75
  153. package/test/src/__snapshots__/storage_sync.test.ts.snap +48 -48
  154. package/test/src/cleanup-stopped-sync-configs.test.ts +648 -0
  155. package/test/src/storage.test.ts +11 -11
  156. package/test/src/storage_compacting.test.ts +1956 -6
  157. package/test/src/storage_sync.test.ts +1077 -68
  158. package/test/src/storeCurrentData.test.ts +17 -7
  159. package/test/src/util.ts +2 -1
  160. package/tsconfig.json +1 -4
  161. package/tsconfig.tsbuildinfo +1 -1
  162. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +0 -15
  163. package/dist/storage/implementation/BucketDefinitionMapping.js +0 -58
  164. package/dist/storage/implementation/BucketDefinitionMapping.js.map +0 -1
  165. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +0 -14
  166. package/dist/storage/implementation/MongoPersistedSyncRules.js +0 -67
  167. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +0 -1
  168. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +0 -29
  169. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +0 -76
  170. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +0 -1
  171. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.d.ts +0 -13
  172. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js +0 -2
  173. package/dist/storage/implementation/common/MongoSyncBucketStorageContext.js.map +0 -1
  174. package/dist/storage/implementation/v3/MongoParameterCompactorV3.d.ts +0 -9
  175. package/dist/storage/implementation/v3/MongoParameterCompactorV3.js +0 -18
  176. package/dist/storage/implementation/v3/MongoParameterCompactorV3.js.map +0 -1
  177. package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +0 -4
  178. package/dist/storage/implementation/v3/MongoParameterLookupV3.js +0 -9
  179. package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +0 -1
  180. package/src/storage/implementation/BucketDefinitionMapping.ts +0 -75
  181. package/src/storage/implementation/MongoPersistedSyncRules.ts +0 -82
  182. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +0 -101
  183. package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +0 -15
  184. package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +0 -24
  185. package/src/storage/implementation/v3/MongoParameterLookupV3.ts +0 -11
@@ -0,0 +1,62 @@
1
+ import { Logger } from '@powersync/lib-services-framework';
2
+ import { storage } from '@powersync/service-core';
3
+ import { VersionedPowerSyncMongoV3 } from './VersionedPowerSyncMongoV3.js';
4
+ export interface MongoStoppedSyncConfigCleanupOptions extends storage.CleanupStoppedSyncConfigsOptions {
5
+ replicationStreamId: number;
6
+ db: VersionedPowerSyncMongoV3;
7
+ logger: Logger;
8
+ }
9
+ export declare class MongoStoppedSyncConfigCleanup {
10
+ private readonly db;
11
+ private readonly replicationStreamId;
12
+ private readonly signal;
13
+ private readonly logger;
14
+ private readonly defaultSchema;
15
+ private readonly sourceConnectionTag;
16
+ constructor(options: MongoStoppedSyncConfigCleanupOptions);
17
+ run(): Promise<storage.CleanupStoppedSyncConfigsResult>;
18
+ private loadSyncConfigDefinitions;
19
+ private storageIdsFor;
20
+ private cleanupSourceTableMemberships;
21
+ /**
22
+ * Clean up event-only source tables that no live sync config still triggers events for.
23
+ *
24
+ * Event-only source tables carry empty membership arrays (see source-table-utils:
25
+ * "Empty memberships indicate an event-only table"), so the membership filter never selects
26
+ * them. Without this, the source_tables row and its source_records collection leak when the
27
+ * config that contributed the event trigger is stopped.
28
+ */
29
+ private cleanupEventOnlySourceTables;
30
+ /**
31
+ * Drop the given source tables and their source_records collections.
32
+ *
33
+ * `refetchFilter` re-applies the deletability predicate against the latest persisted state, so
34
+ * a source table that became live through another writer after planning is not deleted. The
35
+ * sourceRecords collection is dropped before the related sourceTables row, so an interruption
36
+ * can be recovered on the next run.
37
+ */
38
+ private deleteSourceTables;
39
+ private membershipsBecomeEmpty;
40
+ private deletableSourceTableFilter;
41
+ private eventOnlySourceTableFilter;
42
+ private eventOnlyDeletableFilter;
43
+ private parseSyncConfigs;
44
+ private triggersLiveEvent;
45
+ private sourceTableMembershipFilter;
46
+ private dropBucketDataCollections;
47
+ /**
48
+ * Delete bucket_state documents for the unused bucket definitions.
49
+ *
50
+ * The bucket_state collection is shared across all bucket definitions of the
51
+ * stream (keyed by `_id`, an ordered `{ d, b }` compound), so we delete the individual documents.
52
+ *
53
+ * There can be hundreds of millions of buckets, so we delete per definition using a range filter
54
+ * on `_id` (which uses the `_id` index) rather than a slow `_id.d` field scan, and retry on
55
+ * MaxTimeMSExpired so each call makes progress in batches.
56
+ */
57
+ private deleteBucketStateDocuments;
58
+ private dropParameterIndexCollections;
59
+ private dropCollection;
60
+ private pruneStoppedSyncConfigStates;
61
+ private throwIfAborted;
62
+ }
@@ -0,0 +1,350 @@
1
+ import * as lib_mongo from '@powersync/lib-service-mongodb';
2
+ import { ReplicationAbortedError } from '@powersync/lib-services-framework';
3
+ import { SingleSyncConfigBucketDefinitionMapping, storage } from '@powersync/service-core';
4
+ import { idPrefixFilter, retryOnMongoMaxTimeMSExpired } from '../../../utils/util.js';
5
+ const LIVE_STATES = new Set([
6
+ storage.SyncRuleState.ACTIVE,
7
+ storage.SyncRuleState.PROCESSING,
8
+ storage.SyncRuleState.ERRORED
9
+ ]);
10
+ const EMPTY_RESULT = {
11
+ stoppedSyncConfigsRemoved: 0,
12
+ bucketDataCollectionsDropped: 0,
13
+ parameterIndexCollectionsDropped: 0,
14
+ bucketStateDocumentsDeleted: 0,
15
+ sourceRecordCollectionsDropped: 0,
16
+ sourceTablesUpdated: 0,
17
+ sourceTablesDeleted: 0
18
+ };
19
+ export class MongoStoppedSyncConfigCleanup {
20
+ db;
21
+ replicationStreamId;
22
+ signal;
23
+ logger;
24
+ defaultSchema;
25
+ sourceConnectionTag;
26
+ constructor(options) {
27
+ this.db = options.db;
28
+ this.replicationStreamId = options.replicationStreamId;
29
+ this.signal = options.signal;
30
+ this.logger = options.logger;
31
+ this.defaultSchema = options.defaultSchema;
32
+ this.sourceConnectionTag = options.sourceConnectionTag;
33
+ }
34
+ async run() {
35
+ this.throwIfAborted();
36
+ const doc = await this.db.sync_rules.findOne({ _id: this.replicationStreamId }, { projection: { sync_configs: 1 } });
37
+ if (doc == null || doc.sync_configs.length == 0) {
38
+ return { ...EMPTY_RESULT };
39
+ }
40
+ const stoppedStates = doc.sync_configs.filter((config) => config.state == storage.SyncRuleState.STOP);
41
+ if (stoppedStates.length == 0) {
42
+ return { ...EMPTY_RESULT };
43
+ }
44
+ const liveStates = doc.sync_configs.filter((config) => LIVE_STATES.has(config.state));
45
+ const configDocs = await this.loadSyncConfigDefinitions([...stoppedStates, ...liveStates]);
46
+ const stoppedIds = new Set(stoppedStates.map((state) => state._id.toHexString()));
47
+ const liveIds = new Set(liveStates.map((state) => state._id.toHexString()));
48
+ const stoppedConfigDocs = configDocs.filter((config) => stoppedIds.has(config._id.toHexString()));
49
+ const liveConfigDocs = configDocs.filter((config) => liveIds.has(config._id.toHexString()));
50
+ const stoppedStorageIds = this.storageIdsFor(stoppedConfigDocs);
51
+ const liveStorageIds = this.storageIdsFor(liveConfigDocs);
52
+ const unusedBucketDefinitionIds = difference(stoppedStorageIds.bucketDefinitionIds, liveStorageIds.bucketDefinitionIds);
53
+ const unusedParameterIndexIds = difference(stoppedStorageIds.parameterIndexIds, liveStorageIds.parameterIndexIds);
54
+ const result = {
55
+ ...EMPTY_RESULT
56
+ };
57
+ if (unusedBucketDefinitionIds.length > 0 || unusedParameterIndexIds.length > 0) {
58
+ await this.cleanupSourceTableMemberships(unusedBucketDefinitionIds, unusedParameterIndexIds, liveConfigDocs, result);
59
+ result.bucketDataCollectionsDropped = await this.dropBucketDataCollections(unusedBucketDefinitionIds);
60
+ result.bucketStateDocumentsDeleted = await this.deleteBucketStateDocuments(unusedBucketDefinitionIds);
61
+ result.parameterIndexCollectionsDropped = await this.dropParameterIndexCollections(unusedParameterIndexIds);
62
+ }
63
+ // Event-only source tables carry empty membership arrays, so they are never selected by the
64
+ // membership filter above. Clean them up separately, regardless of whether any bucket or
65
+ // parameter ids became unused (a stopped config may have contributed only an event trigger).
66
+ await this.cleanupEventOnlySourceTables(liveConfigDocs, result);
67
+ result.stoppedSyncConfigsRemoved = await this.pruneStoppedSyncConfigStates(stoppedStates);
68
+ if (result.stoppedSyncConfigsRemoved > 0) {
69
+ this.logger.info(`Cleaned up ${result.stoppedSyncConfigsRemoved} stopped sync config${result.stoppedSyncConfigsRemoved == 1 ? '' : 's'}`, result);
70
+ }
71
+ return result;
72
+ }
73
+ async loadSyncConfigDefinitions(states) {
74
+ const ids = [...new Map(states.map((state) => [state._id.toHexString(), state._id])).values()];
75
+ if (ids.length == 0) {
76
+ return [];
77
+ }
78
+ return this.db.syncConfigDefinitions.find({ _id: { $in: ids } }).toArray();
79
+ }
80
+ storageIdsFor(configs) {
81
+ const mappings = configs.map((config) => SingleSyncConfigBucketDefinitionMapping.fromPersistedMapping(config.rule_mapping));
82
+ return {
83
+ bucketDefinitionIds: [...new Set(mappings.flatMap((mapping) => mapping.allBucketDefinitionIds()))],
84
+ parameterIndexIds: [...new Set(mappings.flatMap((mapping) => mapping.allParameterIndexIds()))]
85
+ };
86
+ }
87
+ async cleanupSourceTableMemberships(unusedBucketDefinitionIds, unusedParameterIndexIds, liveConfigDocs, result) {
88
+ const update = {};
89
+ if (unusedBucketDefinitionIds.length > 0) {
90
+ update.bucket_data_source_ids = { $in: unusedBucketDefinitionIds };
91
+ }
92
+ if (unusedParameterIndexIds.length > 0) {
93
+ update.parameter_lookup_source_ids = { $in: unusedParameterIndexIds };
94
+ }
95
+ // Keep obsolete membership ids as the durable cleanup marker until each source table is
96
+ // either deleted or retained. If interrupted after dropping a source_records collection,
97
+ // the next run can still rediscover the source table from these obsolete ids and retry.
98
+ const filter = this.sourceTableMembershipFilter(unusedBucketDefinitionIds, unusedParameterIndexIds);
99
+ const candidateSourceTables = await this.db
100
+ .sourceTables(this.replicationStreamId)
101
+ .find(filter, {
102
+ projection: {
103
+ _id: 1,
104
+ bucket_data_source_ids: 1,
105
+ parameter_lookup_source_ids: 1,
106
+ schema_name: 1,
107
+ table_name: 1
108
+ }
109
+ })
110
+ .toArray();
111
+ if (candidateSourceTables.length == 0) {
112
+ return;
113
+ }
114
+ const liveSyncConfigs = this.parseSyncConfigs(liveConfigDocs);
115
+ const deletableSourceTables = candidateSourceTables.filter((sourceTable) => this.membershipsBecomeEmpty(sourceTable, unusedBucketDefinitionIds, unusedParameterIndexIds) &&
116
+ !this.triggersLiveEvent(sourceTable, liveSyncConfigs));
117
+ const retainedSourceTables = candidateSourceTables.filter((sourceTable) => !deletableSourceTables.some((deletable) => deletable._id.equals(sourceTable._id)));
118
+ const retainedSourceTableIds = retainedSourceTables.map((sourceTable) => sourceTable._id);
119
+ await this.deleteSourceTables(deletableSourceTables.map((table) => table._id), (ids) => this.deletableSourceTableFilter(ids, unusedBucketDefinitionIds, unusedParameterIndexIds), result);
120
+ // A retained source table whose memberships become empty is kept alive only by a live event
121
+ // (otherwise it would be deletable). It becomes event-only, and event-only save() never reads
122
+ // or writes current_data, so its source_records collection is now dead weight. Drop it before
123
+ // the $pull below, so the obsolete membership ids remain as a recovery marker if interrupted.
124
+ // Existing source-table docs only ever shrink their memberships, so this table cannot resume
125
+ // data sync on the same doc and need current_data again.
126
+ const becomingEventOnlySourceTableIds = retainedSourceTables
127
+ .filter((sourceTable) => this.membershipsBecomeEmpty(sourceTable, unusedBucketDefinitionIds, unusedParameterIndexIds))
128
+ .map((sourceTable) => sourceTable._id);
129
+ for (const sourceTableId of becomingEventOnlySourceTableIds) {
130
+ this.throwIfAborted();
131
+ await this.dropCollection(this.db.sourceRecords(this.replicationStreamId, sourceTableId));
132
+ result.sourceRecordCollectionsDropped += 1;
133
+ }
134
+ if (retainedSourceTableIds.length > 0) {
135
+ this.throwIfAborted();
136
+ const updateResult = await this.db.sourceTables(this.replicationStreamId).updateMany({ _id: { $in: retainedSourceTableIds } }, {
137
+ $pull: update
138
+ }, { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS });
139
+ result.sourceTablesUpdated += updateResult.modifiedCount;
140
+ }
141
+ }
142
+ /**
143
+ * Clean up event-only source tables that no live sync config still triggers events for.
144
+ *
145
+ * Event-only source tables carry empty membership arrays (see source-table-utils:
146
+ * "Empty memberships indicate an event-only table"), so the membership filter never selects
147
+ * them. Without this, the source_tables row and its source_records collection leak when the
148
+ * config that contributed the event trigger is stopped.
149
+ */
150
+ async cleanupEventOnlySourceTables(liveConfigDocs, result) {
151
+ const candidateSourceTables = await this.db
152
+ .sourceTables(this.replicationStreamId)
153
+ .find(this.eventOnlySourceTableFilter(), {
154
+ projection: {
155
+ _id: 1,
156
+ bucket_data_source_ids: 1,
157
+ parameter_lookup_source_ids: 1,
158
+ schema_name: 1,
159
+ table_name: 1
160
+ }
161
+ })
162
+ .toArray();
163
+ if (candidateSourceTables.length == 0) {
164
+ return;
165
+ }
166
+ const liveSyncConfigs = this.parseSyncConfigs(liveConfigDocs);
167
+ const deletableSourceTableIds = candidateSourceTables
168
+ .filter((sourceTable) => !this.triggersLiveEvent(sourceTable, liveSyncConfigs))
169
+ .map((sourceTable) => sourceTable._id);
170
+ await this.deleteSourceTables(deletableSourceTableIds, (ids) => this.eventOnlyDeletableFilter(ids), result);
171
+ }
172
+ /**
173
+ * Drop the given source tables and their source_records collections.
174
+ *
175
+ * `refetchFilter` re-applies the deletability predicate against the latest persisted state, so
176
+ * a source table that became live through another writer after planning is not deleted. The
177
+ * sourceRecords collection is dropped before the related sourceTables row, so an interruption
178
+ * can be recovered on the next run.
179
+ */
180
+ async deleteSourceTables(deletableSourceTableIds, refetchFilter, result) {
181
+ if (deletableSourceTableIds.length == 0) {
182
+ return;
183
+ }
184
+ const sourceTablesToDelete = await this.db
185
+ .sourceTables(this.replicationStreamId)
186
+ .find(refetchFilter(deletableSourceTableIds), { projection: { _id: 1 } })
187
+ .toArray();
188
+ for (const sourceTable of sourceTablesToDelete) {
189
+ this.throwIfAborted();
190
+ await this.dropCollection(this.db.sourceRecords(this.replicationStreamId, sourceTable._id));
191
+ result.sourceRecordCollectionsDropped += 1;
192
+ }
193
+ if (sourceTablesToDelete.length > 0) {
194
+ this.throwIfAborted();
195
+ const deleteResult = await this.db
196
+ .sourceTables(this.replicationStreamId)
197
+ .deleteMany(refetchFilter(sourceTablesToDelete.map((table) => table._id)), {
198
+ maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS
199
+ });
200
+ result.sourceTablesDeleted += deleteResult.deletedCount;
201
+ }
202
+ }
203
+ membershipsBecomeEmpty(sourceTable, unusedBucketDefinitionIds, unusedParameterIndexIds) {
204
+ const unusedBucketDefinitionIdSet = new Set(unusedBucketDefinitionIds);
205
+ const unusedParameterIndexIdSet = new Set(unusedParameterIndexIds);
206
+ return (sourceTable.bucket_data_source_ids.every((id) => unusedBucketDefinitionIdSet.has(id)) &&
207
+ sourceTable.parameter_lookup_source_ids.every((id) => unusedParameterIndexIdSet.has(id)));
208
+ }
209
+ deletableSourceTableFilter(ids, unusedBucketDefinitionIds, unusedParameterIndexIds) {
210
+ return {
211
+ _id: { $in: ids },
212
+ bucket_data_source_ids: { $not: { $elemMatch: { $nin: unusedBucketDefinitionIds } } },
213
+ parameter_lookup_source_ids: { $not: { $elemMatch: { $nin: unusedParameterIndexIds } } }
214
+ };
215
+ }
216
+ eventOnlySourceTableFilter() {
217
+ return {
218
+ bucket_data_source_ids: { $size: 0 },
219
+ parameter_lookup_source_ids: { $size: 0 }
220
+ };
221
+ }
222
+ eventOnlyDeletableFilter(ids) {
223
+ return {
224
+ _id: { $in: ids },
225
+ ...this.eventOnlySourceTableFilter()
226
+ };
227
+ }
228
+ parseSyncConfigs(configDocs) {
229
+ // This is ugly - we should not need to re-parse to achieve this.
230
+ // Revisit persistence for this later.
231
+ return configDocs.map((config) => {
232
+ return storage.parsePersistedSyncConfigContent({
233
+ content: config.content,
234
+ compiledPlan: config.serialized_plan ?? null,
235
+ storageVersion: config.storage_version,
236
+ parseOptions: {
237
+ defaultSchema: this.defaultSchema
238
+ }
239
+ }).config;
240
+ });
241
+ }
242
+ triggersLiveEvent(sourceTable, liveSyncConfigs) {
243
+ return liveSyncConfigs.some((syncConfig) => syncConfig.tableTriggersEvent({
244
+ connectionTag: this.sourceConnectionTag,
245
+ schema: sourceTable.schema_name,
246
+ name: sourceTable.table_name
247
+ }));
248
+ }
249
+ sourceTableMembershipFilter(bucketDefinitionIds, parameterIndexIds) {
250
+ const clauses = [];
251
+ if (bucketDefinitionIds.length > 0) {
252
+ clauses.push({ bucket_data_source_ids: { $in: bucketDefinitionIds } });
253
+ }
254
+ if (parameterIndexIds.length > 0) {
255
+ clauses.push({ parameter_lookup_source_ids: { $in: parameterIndexIds } });
256
+ }
257
+ if (clauses.length == 0) {
258
+ return { _id: { $exists: false } };
259
+ }
260
+ return { $or: clauses };
261
+ }
262
+ async dropBucketDataCollections(definitionIds) {
263
+ for (const definitionId of definitionIds) {
264
+ this.throwIfAborted();
265
+ await this.dropCollection(this.db.bucketData(this.replicationStreamId, definitionId));
266
+ }
267
+ return definitionIds.length;
268
+ }
269
+ /**
270
+ * Delete bucket_state documents for the unused bucket definitions.
271
+ *
272
+ * The bucket_state collection is shared across all bucket definitions of the
273
+ * stream (keyed by `_id`, an ordered `{ d, b }` compound), so we delete the individual documents.
274
+ *
275
+ * There can be hundreds of millions of buckets, so we delete per definition using a range filter
276
+ * on `_id` (which uses the `_id` index) rather than a slow `_id.d` field scan, and retry on
277
+ * MaxTimeMSExpired so each call makes progress in batches.
278
+ */
279
+ async deleteBucketStateDocuments(definitionIds) {
280
+ const collection = this.db.bucketState(this.replicationStreamId);
281
+ let deletedCount = 0;
282
+ for (const definitionId of definitionIds) {
283
+ this.throwIfAborted();
284
+ const result = await retryOnMongoMaxTimeMSExpired(() => collection.deleteMany({
285
+ _id: idPrefixFilter({ d: definitionId }, ['b'])
286
+ }, { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }), {
287
+ signal: this.signal,
288
+ abortMessage: 'Aborted stopped sync config cleanup',
289
+ retryDelayMs: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS / 5,
290
+ onRetry: () => {
291
+ this.logger.info(`Cleared batch of bucket state in ${lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS}ms, continuing...`);
292
+ }
293
+ });
294
+ deletedCount += result.deletedCount;
295
+ }
296
+ return deletedCount;
297
+ }
298
+ async dropParameterIndexCollections(indexIds) {
299
+ for (const indexId of indexIds) {
300
+ this.throwIfAborted();
301
+ await this.dropCollection(this.db.parameterIndex(this.replicationStreamId, indexId));
302
+ }
303
+ return indexIds.length;
304
+ }
305
+ async dropCollection(collection) {
306
+ await collection.drop({ maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS }).catch((error) => {
307
+ if (lib_mongo.isMongoServerError(error) && error.codeName === 'NamespaceNotFound') {
308
+ return;
309
+ }
310
+ throw error;
311
+ });
312
+ }
313
+ async pruneStoppedSyncConfigStates(stoppedStates) {
314
+ this.throwIfAborted();
315
+ const stoppedIds = stoppedStates.map((state) => state._id);
316
+ const result = await this.db.sync_rules.updateOne({
317
+ _id: this.replicationStreamId,
318
+ sync_configs: {
319
+ $not: {
320
+ $elemMatch: {
321
+ _id: { $in: stoppedIds },
322
+ state: { $ne: storage.SyncRuleState.STOP }
323
+ }
324
+ }
325
+ }
326
+ }, {
327
+ $pull: {
328
+ sync_configs: {
329
+ _id: { $in: stoppedIds },
330
+ state: storage.SyncRuleState.STOP
331
+ }
332
+ }
333
+ });
334
+ if (result.modifiedCount == 0 && stoppedIds.length > 0) {
335
+ this.logger.warn(`Skipped pruning stopped sync configs`);
336
+ return 0;
337
+ }
338
+ return stoppedStates.length;
339
+ }
340
+ throwIfAborted() {
341
+ if (this.signal?.aborted) {
342
+ throw new ReplicationAbortedError('Aborted stopped sync config cleanup', this.signal.reason);
343
+ }
344
+ }
345
+ }
346
+ function difference(left, right) {
347
+ const rightSet = new Set(right);
348
+ return left.filter((value) => !rightSet.has(value));
349
+ }
350
+ //# sourceMappingURL=MongoStoppedSyncConfigCleanup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MongoStoppedSyncConfigCleanup.js","sourceRoot":"","sources":["../../../../src/storage/implementation/v3/MongoStoppedSyncConfigCleanup.ts"],"names":[],"mappings":"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"}
@@ -1,52 +1,63 @@
1
- import * as lib_mongo from '@powersync/lib-service-mongodb';
2
1
  import { mongo } from '@powersync/lib-service-mongodb';
3
- import { CheckpointChanges, GetCheckpointChangesOptions, InternalOpId, storage, utils } from '@powersync/service-core';
2
+ import { CheckpointChanges, GetCheckpointChangesOptions, InternalOpId, SingleSyncConfigBucketDefinitionMapping, storage, utils } from '@powersync/service-core';
4
3
  import { ParameterLookupRows, ScopedParameterLookup } from '@powersync/service-sync-rules';
5
4
  import { MongoBucketStorage } from '../../MongoBucketStorage.js';
6
- import { MongoSyncBucketStorageCheckpoint, MongoSyncBucketStorageContext } from '../common/MongoSyncBucketStorageContext.js';
7
- import { MongoBucketBatchOptions } from '../MongoBucketBatch.js';
5
+ import { MongoSyncBucketStorageCheckpoint } from '../common/MongoSyncBucketStorageCheckpoint.js';
8
6
  import { MongoChecksums } from '../MongoChecksums.js';
9
7
  import { MongoCompactOptions, MongoCompactor } from '../MongoCompactor.js';
10
8
  import { MongoParameterCompactor } from '../MongoParameterCompactor.js';
11
- import { MongoPersistedSyncRulesContentV1 } from '../MongoPersistedSyncRulesContent.js';
9
+ import { MongoPersistedReplicationStream } from '../MongoPersistedReplicationStream.js';
12
10
  import { MongoSyncBucketStorage, MongoSyncBucketStorageOptions } from '../MongoSyncBucketStorage.js';
13
11
  import { MongoChecksumsV3 } from './MongoChecksumsV3.js';
14
12
  import { VersionedPowerSyncMongoV3 } from './VersionedPowerSyncMongoV3.js';
13
+ export interface MongoSyncBucketStorageContextV3 {
14
+ db: VersionedPowerSyncMongoV3;
15
+ replicationStreamId: number;
16
+ /**
17
+ * Persisted mapping of the single sync config that read operations are served from.
18
+ *
19
+ * Implemented as a lazy getter: accessing it on a storage instance with multiple sync
20
+ * configs throws, but operations that don't use it remain unaffected.
21
+ */
22
+ readonly mapping: SingleSyncConfigBucketDefinitionMapping;
23
+ }
15
24
  export declare class MongoSyncBucketStorageV3 extends MongoSyncBucketStorage {
16
25
  readonly db: VersionedPowerSyncMongoV3;
17
26
  readonly checksums: MongoChecksumsV3;
18
- private readonly syncRulesV3;
19
- constructor(factory: MongoBucketStorage, group_id: number, sync_rules: MongoPersistedSyncRulesContentV1, slot_name: string, writeCheckpointMode: storage.WriteCheckpointMode | undefined, options: MongoSyncBucketStorageOptions);
20
- private get syncConfigId();
27
+ constructor(factory: MongoBucketStorage, replicationStreamId: number, replicationStream: MongoPersistedReplicationStream, replicationStreamName: string, writeCheckpointMode: storage.WriteCheckpointMode | undefined, options: MongoSyncBucketStorageOptions);
28
+ private get syncConfigIds();
21
29
  private get syncRulesCollection();
22
30
  private syncConfigMatch;
23
31
  private syncConfigProjection;
24
- private syncConfigArrayFilters;
25
- /**
26
- * For now, we only support a single sync config per replication stream.
27
- *
28
- * In the future we'll add support for multiple.
29
- */
30
- private selectedSyncConfig;
32
+ private selectedSyncConfigs;
31
33
  protected initializeVersionStorage(): Promise<void>;
32
34
  protected createMongoChecksums(options: MongoSyncBucketStorageOptions): MongoChecksums;
33
35
  createMongoCompactor(options: MongoCompactOptions): MongoCompactor;
34
36
  protected createMongoParameterCompactor(checkpoint: InternalOpId, options: storage.CompactOptions): MongoParameterCompactor;
35
- protected createWriterImpl(batchOptions: MongoBucketBatchOptions): storage.BucketStorageBatch;
37
+ protected fetchPersistedOpHead(): Promise<InternalOpId | null>;
38
+ protected createWriterImpl(options: storage.CreateWriterOptions): Promise<storage.BucketStorageBatch>;
36
39
  protected fetchCheckpointState(session: mongo.ClientSession): Promise<{
37
40
  checkpoint: bigint;
38
41
  lsn: string | null;
39
42
  } | null>;
40
- protected getWriterSyncState(): Promise<{
41
- lastCheckpointLsn: string | null;
42
- resumeFromLsn: string | null;
43
- keepaliveOp: bigint | null;
44
- syncConfigId: lib_mongo.mongo.BSON.ObjectId;
45
- }>;
46
43
  protected terminateSyncRuleState(): Promise<void>;
47
- protected getStatusImpl(): Promise<storage.SyncRuleStatus>;
44
+ protected getStatusImpl(): Promise<storage.ReplicationStreamStatus>;
48
45
  protected clearSyncRuleState(): Promise<void>;
49
- protected get versionContext(): MongoSyncBucketStorageContext<VersionedPowerSyncMongoV3>;
46
+ /**
47
+ * The persisted mapping of the single sync config that read operations are served from.
48
+ *
49
+ * Reads always operate on a single sync config: read-path storage instances are
50
+ * constructed for the active sync config only (see MongoBucketStorage.getActiveSyncConfig),
51
+ * and checkpoints are served from the single active config (see fetchCheckpointState).
52
+ * Within a single sync config, unique names are the persistence key of its rule mapping,
53
+ * so its name-keyed {@link SingleSyncConfigBucketDefinitionMapping} resolves sources from
54
+ * any parse of that config unambiguously - no parsed-set identity is required.
55
+ *
56
+ * Throws on storage instances with multiple sync configs (replication-side instances),
57
+ * which must not serve reads.
58
+ */
59
+ private singleSyncConfigMapping;
60
+ protected get versionContext(): MongoSyncBucketStorageContextV3;
50
61
  protected getParameterSetsImpl(checkpoint: MongoSyncBucketStorageCheckpoint, lookups: ScopedParameterLookup[], limit: number): Promise<ParameterLookupRows[]>;
51
62
  protected getBucketDataBatchImpl(checkpoint: utils.InternalOpId, dataBuckets: storage.BucketDataRequest[], options?: storage.BucketDataBatchOptions): AsyncIterable<storage.SyncBucketDataChunk>;
52
63
  protected clearBucketData(_signal?: AbortSignal): Promise<void>;
@@ -54,10 +65,11 @@ export declare class MongoSyncBucketStorageV3 extends MongoSyncBucketStorage {
54
65
  protected clearSourceRecords(_signal?: AbortSignal): Promise<void>;
55
66
  protected clearBucketState(_signal?: AbortSignal): Promise<void>;
56
67
  protected clearSourceTables(_signal?: AbortSignal): Promise<void>;
68
+ cleanupStoppedSyncConfigs(options: storage.CleanupStoppedSyncConfigsOptions): Promise<storage.CleanupStoppedSyncConfigsResult>;
57
69
  protected getDataBucketChangesImpl(options: GetCheckpointChangesOptions): Promise<Pick<CheckpointChanges, 'updatedDataBuckets' | 'invalidateDataBuckets'>>;
58
70
  protected getParameterBucketChangesImpl(options: GetCheckpointChangesOptions): Promise<Pick<CheckpointChanges, 'updatedParameterLookups' | 'invalidateParameterBuckets'>>;
59
71
  }
60
- export declare function getParameterSetsV3(ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV3>, checkpoint: MongoSyncBucketStorageCheckpoint, lookups: ScopedParameterLookup[], limit: number): Promise<ParameterLookupRows[]>;
61
- export declare function getBucketDataBatchV3(ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV3>, checkpoint: utils.InternalOpId, dataBuckets: storage.BucketDataRequest[], options?: storage.BucketDataBatchOptions): AsyncIterable<storage.SyncBucketDataChunk>;
62
- export declare function getDataBucketChangesV3(ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV3>, options: GetCheckpointChangesOptions): Promise<Pick<CheckpointChanges, 'updatedDataBuckets' | 'invalidateDataBuckets'>>;
63
- export declare function getParameterBucketChangesV3(ctx: MongoSyncBucketStorageContext<VersionedPowerSyncMongoV3>, options: GetCheckpointChangesOptions): Promise<Pick<CheckpointChanges, 'updatedParameterLookups' | 'invalidateParameterBuckets'>>;
72
+ export declare function getParameterSetsV3(ctx: MongoSyncBucketStorageContextV3, checkpoint: MongoSyncBucketStorageCheckpoint, lookups: ScopedParameterLookup[], limit: number): Promise<ParameterLookupRows[]>;
73
+ export declare function getBucketDataBatchV3(ctx: MongoSyncBucketStorageContextV3, checkpoint: utils.InternalOpId, dataBuckets: storage.BucketDataRequest[], options?: storage.BucketDataBatchOptions): AsyncIterable<storage.SyncBucketDataChunk>;
74
+ export declare function getDataBucketChangesV3(ctx: MongoSyncBucketStorageContextV3, options: GetCheckpointChangesOptions): Promise<Pick<CheckpointChanges, 'updatedDataBuckets' | 'invalidateDataBuckets'>>;
75
+ export declare function getParameterBucketChangesV3(ctx: MongoSyncBucketStorageContextV3, options: GetCheckpointChangesOptions): Promise<Pick<CheckpointChanges, 'updatedParameterLookups' | 'invalidateParameterBuckets'>>;