@powersync/service-module-mongodb-storage 0.0.0-dev-20260225160713 → 0.0.0-dev-20260511080634

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 (213) hide show
  1. package/CHANGELOG.md +119 -6
  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 +53 -26
  9. package/dist/storage/MongoBucketStorage.js.map +1 -1
  10. package/dist/storage/MongoReportStorage.js.map +1 -1
  11. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +17 -0
  12. package/dist/storage/implementation/BucketDefinitionMapping.js +58 -0
  13. package/dist/storage/implementation/BucketDefinitionMapping.js.map +1 -0
  14. package/dist/storage/implementation/MongoBucketBatch.d.ts +25 -21
  15. package/dist/storage/implementation/MongoBucketBatch.js +256 -210
  16. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  17. package/dist/storage/implementation/MongoBucketBatchShared.d.ts +5 -0
  18. package/dist/storage/implementation/MongoBucketBatchShared.js +8 -0
  19. package/dist/storage/implementation/MongoBucketBatchShared.js.map +1 -0
  20. package/dist/storage/implementation/MongoChecksums.d.ts +30 -19
  21. package/dist/storage/implementation/MongoChecksums.js +13 -71
  22. package/dist/storage/implementation/MongoChecksums.js.map +1 -1
  23. package/dist/storage/implementation/MongoCompactor.d.ts +99 -53
  24. package/dist/storage/implementation/MongoCompactor.js +265 -303
  25. package/dist/storage/implementation/MongoCompactor.js.map +1 -1
  26. package/dist/storage/implementation/MongoParameterCompactor.d.ts +12 -7
  27. package/dist/storage/implementation/MongoParameterCompactor.js +24 -9
  28. package/dist/storage/implementation/MongoParameterCompactor.js.map +1 -1
  29. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +14 -0
  30. package/dist/storage/implementation/MongoPersistedSyncRules.js +64 -0
  31. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +1 -0
  32. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +3 -0
  33. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +11 -7
  34. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
  35. package/dist/storage/implementation/MongoStorageProvider.js +1 -1
  36. package/dist/storage/implementation/MongoStorageProvider.js.map +1 -1
  37. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +54 -30
  38. package/dist/storage/implementation/MongoSyncBucketStorage.js +118 -472
  39. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  40. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +7 -5
  41. package/dist/storage/implementation/MongoSyncRulesLock.js +12 -10
  42. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  43. package/dist/storage/implementation/MongoWriteCheckpointAPI.d.ts +4 -4
  44. package/dist/storage/implementation/MongoWriteCheckpointAPI.js +1 -1
  45. package/dist/storage/implementation/MongoWriteCheckpointAPI.js.map +1 -1
  46. package/dist/storage/implementation/OperationBatch.js +3 -2
  47. package/dist/storage/implementation/OperationBatch.js.map +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 +38 -4
  70. package/dist/storage/implementation/db.js +80 -1
  71. package/dist/storage/implementation/db.js.map +1 -1
  72. package/dist/storage/implementation/models.d.ts +66 -25
  73. package/dist/storage/implementation/models.js +22 -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 +269 -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 +404 -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/test-utils.d.ts +4 -1
  142. package/dist/utils/test-utils.js +15 -12
  143. package/dist/utils/test-utils.js.map +1 -1
  144. package/dist/utils/util.d.ts +13 -5
  145. package/dist/utils/util.js +40 -5
  146. package/dist/utils/util.js.map +1 -1
  147. package/package.json +9 -9
  148. package/src/migrations/db/migrations/1688556755264-initial-sync-rules.ts +1 -1
  149. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +7 -7
  150. package/src/migrations/db/migrations/1770213298299-storage-version.ts +1 -1
  151. package/src/storage/MongoBucketStorage.ts +111 -55
  152. package/src/storage/MongoReportStorage.ts +2 -2
  153. package/src/storage/implementation/BucketDefinitionMapping.ts +72 -0
  154. package/src/storage/implementation/MongoBucketBatch.ts +322 -270
  155. package/src/storage/implementation/MongoBucketBatchShared.ts +11 -0
  156. package/src/storage/implementation/MongoChecksums.ts +54 -75
  157. package/src/storage/implementation/MongoCompactor.ts +411 -412
  158. package/src/storage/implementation/MongoParameterCompactor.ts +52 -26
  159. package/src/storage/implementation/MongoPersistedSyncRules.ts +76 -0
  160. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +19 -10
  161. package/src/storage/implementation/MongoStorageProvider.ts +1 -1
  162. package/src/storage/implementation/MongoSyncBucketStorage.ts +206 -466
  163. package/src/storage/implementation/MongoSyncRulesLock.ts +14 -16
  164. package/src/storage/implementation/MongoWriteCheckpointAPI.ts +7 -5
  165. package/src/storage/implementation/OperationBatch.ts +3 -2
  166. package/src/storage/implementation/common/BucketDataDoc.ts +37 -0
  167. package/src/storage/implementation/common/MongoSyncBucketStorageContext.ts +15 -0
  168. package/src/storage/implementation/common/PersistedBatch.ts +364 -0
  169. package/src/storage/implementation/common/SingleBucketStore.ts +63 -0
  170. package/src/storage/implementation/common/SourceRecordStore.ts +49 -0
  171. package/src/storage/implementation/common/VersionedPowerSyncMongoBase.ts +80 -0
  172. package/src/storage/implementation/createMongoSyncBucketStorage.ts +25 -0
  173. package/src/storage/implementation/db.ts +115 -8
  174. package/src/storage/implementation/models.ts +88 -28
  175. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +32 -0
  176. package/src/storage/implementation/v1/MongoChecksumsV1.ts +75 -0
  177. package/src/storage/implementation/v1/MongoCompactorV1.ts +93 -0
  178. package/src/storage/implementation/v1/MongoParameterCompactorV1.ts +26 -0
  179. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +432 -0
  180. package/src/storage/implementation/v1/PersistedBatchV1.ts +230 -0
  181. package/src/storage/implementation/v1/SingleBucketStoreV1.ts +74 -0
  182. package/src/storage/implementation/v1/SourceRecordStoreV1.ts +156 -0
  183. package/src/storage/implementation/v1/VersionedPowerSyncMongoV1.ts +28 -0
  184. package/src/storage/implementation/v1/models.ts +84 -0
  185. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +44 -0
  186. package/src/storage/implementation/v3/MongoChecksumsV3.ts +120 -0
  187. package/src/storage/implementation/v3/MongoCompactorV3.ts +107 -0
  188. package/src/storage/implementation/v3/MongoParameterCompactorV3.ts +24 -0
  189. package/src/storage/implementation/v3/MongoParameterLookupV3.ts +12 -0
  190. package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +545 -0
  191. package/src/storage/implementation/v3/PersistedBatchV3.ts +318 -0
  192. package/src/storage/implementation/v3/SingleBucketStoreV3.ts +68 -0
  193. package/src/storage/implementation/v3/SourceRecordStoreV3.ts +226 -0
  194. package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +112 -0
  195. package/src/storage/implementation/v3/models.ts +96 -0
  196. package/src/storage/storage-index.ts +8 -5
  197. package/src/utils/test-utils.ts +15 -12
  198. package/src/utils/util.ts +53 -9
  199. package/test/src/__snapshots__/storage.test.ts.snap +201 -0
  200. package/test/src/__snapshots__/storage_compacting.test.ts.snap +17 -0
  201. package/test/src/__snapshots__/storage_sync.test.ts.snap +1393 -16
  202. package/test/src/connection-report-storage.test.ts +3 -3
  203. package/test/src/setup.ts +1 -1
  204. package/test/src/storage.test.ts +10 -8
  205. package/test/src/storage_compacting.test.ts +146 -46
  206. package/test/src/storage_sync.test.ts +404 -56
  207. package/test/src/util.ts +3 -3
  208. package/test/tsconfig.json +0 -1
  209. package/tsconfig.tsbuildinfo +1 -1
  210. package/dist/storage/implementation/PersistedBatch.d.ts +0 -64
  211. package/dist/storage/implementation/PersistedBatch.js +0 -323
  212. package/dist/storage/implementation/PersistedBatch.js.map +0 -1
  213. package/src/storage/implementation/PersistedBatch.ts +0 -401
@@ -1,23 +1,27 @@
1
1
  import { GetIntanceOptions, storage } from '@powersync/service-core';
2
2
 
3
- import { ErrorCode, ServiceError } from '@powersync/lib-services-framework';
3
+ import { DO_NOT_LOG, ErrorCode, ServiceError } from '@powersync/lib-services-framework';
4
4
  import { v4 as uuid } from 'uuid';
5
5
 
6
6
  import * as lib_mongo from '@powersync/lib-service-mongodb';
7
7
  import { mongo } from '@powersync/lib-service-mongodb';
8
8
 
9
- import { PowerSyncMongo } from './implementation/db.js';
10
- import { SyncRuleDocument } from './implementation/models.js';
11
- import { MongoPersistedSyncRulesContent } from './implementation/MongoPersistedSyncRulesContent.js';
12
- import { MongoSyncBucketStorage } from './implementation/MongoSyncBucketStorage.js';
13
9
  import { generateSlotName } from '../utils/util.js';
10
+ import { BucketDefinitionMapping } from './implementation/BucketDefinitionMapping.js';
11
+ import type { MongoSyncBucketStorage } from './implementation/createMongoSyncBucketStorage.js';
12
+ import { createMongoSyncBucketStorage } from './implementation/createMongoSyncBucketStorage.js';
13
+ import { PowerSyncMongo } from './implementation/db.js';
14
+ import { getMongoStorageConfig, SyncRuleDocument } from './implementation/models.js';
14
15
  import { MongoChecksumOptions } from './implementation/MongoChecksums.js';
16
+ import { MongoPersistedSyncRulesContent } from './implementation/MongoPersistedSyncRulesContent.js';
15
17
 
16
18
  export interface MongoBucketStorageOptions {
17
- checksumOptions?: Omit<MongoChecksumOptions, 'storageConfig'>;
19
+ checksumOptions?: Omit<MongoChecksumOptions, 'storageConfig' | 'mapping'>;
18
20
  }
19
21
 
20
22
  export class MongoBucketStorage extends storage.BucketStorageFactory {
23
+ [DO_NOT_LOG] = true;
24
+
21
25
  private readonly client: mongo.MongoClient;
22
26
  private readonly session: mongo.ClientSession;
23
27
  // TODO: This is still Postgres specific and needs to be reworked
@@ -51,10 +55,17 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
51
55
  id = Number(id);
52
56
  }
53
57
  const storageConfig = (syncRules as MongoPersistedSyncRulesContent).getStorageConfig();
54
- const storage = new MongoSyncBucketStorage(this, id, syncRules, slot_name, undefined, {
55
- ...this.internalOptions,
56
- storageConfig
57
- });
58
+ const storage = createMongoSyncBucketStorage(
59
+ this,
60
+ id,
61
+ syncRules as MongoPersistedSyncRulesContent,
62
+ slot_name,
63
+ undefined,
64
+ {
65
+ ...this.internalOptions,
66
+ storageConfig
67
+ }
68
+ );
58
69
  if (!options?.skipLifecycleHooks) {
59
70
  this.iterateListeners((cb) => cb.syncStorageCreated?.(storage));
60
71
  }
@@ -91,7 +102,7 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
91
102
  const active = await this.getActiveSyncRulesContent();
92
103
 
93
104
  if (next != null && next.id == sync_rules_group_id) {
94
- // We need to redo the "next" sync rules
105
+ // We need to redo the "next" replication stream
95
106
  await this.updateSyncRules(next.asUpdateOptions());
96
107
  // Pro-actively stop replicating
97
108
  await this.db.sync_rules.updateOne(
@@ -107,7 +118,7 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
107
118
  );
108
119
  await this.db.notifyCheckpoint();
109
120
  } else if (next == null && active?.id == sync_rules_group_id) {
110
- // Slot removed for "active" sync rules, while there is no "next" one.
121
+ // Slot removed for "active" replication stream, while there is no "next" one.
111
122
  await this.updateSyncRules(active.asUpdateOptions());
112
123
 
113
124
  // In this case we keep the old one as active for clients, so that that existing clients
@@ -127,7 +138,7 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
127
138
  );
128
139
  await this.db.notifyCheckpoint();
129
140
  } else if (next != null && active?.id == sync_rules_group_id) {
130
- // Already have next sync rules, but need to stop replicating the active one.
141
+ // Already have next replication stream, but need to stop replicating the active one.
131
142
 
132
143
  await this.db.sync_rules.updateOne(
133
144
  {
@@ -145,10 +156,14 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
145
156
  }
146
157
 
147
158
  async updateSyncRules(options: storage.UpdateSyncRulesOptions): Promise<MongoPersistedSyncRulesContent> {
159
+ const storageVersion =
160
+ options.storageVersion ?? options.config.parsed.config.storageVersion ?? storage.CURRENT_STORAGE_VERSION;
161
+ const storageConfig = getMongoStorageConfig(storageVersion);
162
+
148
163
  let rules: MongoPersistedSyncRulesContent | undefined = undefined;
149
164
 
150
165
  await this.session.withTransaction(async () => {
151
- // Only have a single set of sync rules with PROCESSING.
166
+ // Only have a single replication stream with PROCESSING.
152
167
  await this.db.sync_rules.updateMany(
153
168
  {
154
169
  state: storage.SyncRuleState.PROCESSING
@@ -174,7 +189,6 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
174
189
  const id = Number(id_doc!.op_id);
175
190
  const slot_name = generateSlotName(this.slot_name_prefix, id);
176
191
 
177
- const storageVersion = options.storageVersion ?? storage.CURRENT_STORAGE_VERSION;
178
192
  const doc: SyncRuleDocument = {
179
193
  _id: id,
180
194
  storage_version: storageVersion,
@@ -193,6 +207,10 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
193
207
  last_fatal_error_ts: null,
194
208
  last_keepalive_ts: null
195
209
  };
210
+ if (storageConfig.incrementalReprocessing) {
211
+ const parsed = options.config.parsed;
212
+ doc.rule_mapping = BucketDefinitionMapping.fromParsedSyncRules(parsed).serialize();
213
+ }
196
214
  await this.db.sync_rules.insertOne(doc);
197
215
  await this.db.notifyCheckpoint();
198
216
  rules = new MongoPersistedSyncRulesContent(this.db, doc);
@@ -284,52 +302,90 @@ export class MongoBucketStorage extends storage.BucketStorageFactory {
284
302
  }
285
303
  };
286
304
 
287
- const active_sync_rules = await this.getActiveSyncRules({ defaultSchema: 'public' });
288
- if (active_sync_rules == null) {
289
- return {
290
- operations_size_bytes: 0,
291
- parameters_size_bytes: 0,
292
- replication_size_bytes: 0
293
- };
294
- }
295
- const operations_aggregate = await this.db.bucket_data
305
+ // For now, we get storage metrics over all v1 and v3 collections.
306
+ // In the future, we may split these metrics to report separately for active replication streams versus processing streams.
296
307
 
297
- .aggregate([
298
- {
299
- $collStats: {
300
- storageStats: {}
301
- }
302
- }
303
- ])
304
- .toArray()
305
- .catch(ignoreNotExisting);
308
+ const aggregateStaticCollection = async <T extends mongo.Document>(collection: mongo.Collection<T>) => {
309
+ // We check whether the collection exists before getting the statistics. This avoids repeated
310
+ // errors in the MongoDB logs if the collection hasn't been created yet.
311
+ const exists =
312
+ (await this.db.db.listCollections({ name: collection.collectionName }, { nameOnly: true }).toArray()).length >
313
+ 0;
314
+ if (!exists) {
315
+ return [{ storageStats: { size: 0 } }];
316
+ }
306
317
 
307
- const parameters_aggregate = await this.db.bucket_parameters
308
- .aggregate([
309
- {
310
- $collStats: {
311
- storageStats: {}
318
+ return collection
319
+ .aggregate([
320
+ {
321
+ $collStats: {
322
+ storageStats: {}
323
+ }
312
324
  }
313
- }
314
- ])
315
- .toArray()
316
- .catch(ignoreNotExisting);
325
+ ])
326
+ .toArray()
327
+ .catch(ignoreNotExisting);
328
+ };
317
329
 
318
- const replication_aggregate = await this.db.current_data
319
- .aggregate([
320
- {
321
- $collStats: {
322
- storageStats: {}
323
- }
324
- }
325
- ])
326
- .toArray()
327
- .catch(ignoreNotExisting);
330
+ const operations_aggregate = await aggregateStaticCollection(this.db.bucket_data);
331
+ const v3_operation_aggregates = await Promise.all(
332
+ (await this.db.listBucketDataCollectionsV3()).map((collection) =>
333
+ collection
334
+ .aggregate([
335
+ {
336
+ $collStats: {
337
+ storageStats: {}
338
+ }
339
+ }
340
+ ])
341
+ .toArray()
342
+ .catch(ignoreNotExisting)
343
+ )
344
+ );
328
345
 
346
+ const parameters_aggregate = await aggregateStaticCollection(this.db.bucket_parameters);
347
+
348
+ const v3_parameter_aggregates = await Promise.all(
349
+ (await this.db.listAllParameterIndexCollectionsV3()).map((collection) =>
350
+ collection
351
+ .aggregate([
352
+ {
353
+ $collStats: {
354
+ storageStats: {}
355
+ }
356
+ }
357
+ ])
358
+ .toArray()
359
+ .catch(ignoreNotExisting)
360
+ )
361
+ );
362
+
363
+ const v1_source_record_aggregate = await aggregateStaticCollection(this.db.current_data);
364
+
365
+ const source_record_aggregates = await Promise.all(
366
+ (await this.db.listAllSourceRecordCollectionsV3()).map((collection) =>
367
+ collection
368
+ .aggregate([
369
+ {
370
+ $collStats: {
371
+ storageStats: {}
372
+ }
373
+ }
374
+ ])
375
+ .toArray()
376
+ .catch(ignoreNotExisting)
377
+ )
378
+ );
329
379
  return {
330
- operations_size_bytes: Number(operations_aggregate[0].storageStats.size),
331
- parameters_size_bytes: Number(parameters_aggregate[0].storageStats.size),
332
- replication_size_bytes: Number(replication_aggregate[0].storageStats.size)
380
+ operations_size_bytes:
381
+ Number(operations_aggregate[0].storageStats.size) +
382
+ v3_operation_aggregates.reduce((total, aggregate) => total + Number(aggregate[0].storageStats.size), 0),
383
+ parameters_size_bytes:
384
+ Number(parameters_aggregate[0].storageStats.size) +
385
+ v3_parameter_aggregates.reduce((total, aggregate) => total + Number(aggregate[0].storageStats.size), 0),
386
+ replication_size_bytes:
387
+ Number(v1_source_record_aggregate[0]?.storageStats?.size ?? 0) +
388
+ source_record_aggregates.reduce((total, aggregate) => total + Number(aggregate[0]?.storageStats?.size ?? 0), 0)
333
389
  };
334
390
  }
335
391
 
@@ -1,8 +1,8 @@
1
+ import { logger } from '@powersync/lib-services-framework';
1
2
  import { storage } from '@powersync/service-core';
2
3
  import { event_types } from '@powersync/service-types';
3
- import { PowerSyncMongo } from './implementation/db.js';
4
- import { logger } from '@powersync/lib-services-framework';
5
4
  import { createPaginatedConnectionQuery } from '../utils/util.js';
5
+ import { PowerSyncMongo } from './implementation/db.js';
6
6
 
7
7
  export class MongoReportStorage implements storage.ReportStorage {
8
8
  public readonly db: PowerSyncMongo;
@@ -0,0 +1,72 @@
1
+ import { ServiceAssertionError } from '@powersync/lib-services-framework';
2
+ import { BucketDataSource, ParameterIndexLookupCreator, SyncConfigWithErrors } from '@powersync/service-sync-rules';
3
+ import { SyncRuleDocument } from './models.js';
4
+
5
+ export type BucketDefinitionId = string;
6
+ export type ParameterIndexId = string;
7
+
8
+ export class BucketDefinitionMapping {
9
+ static fromSyncRules(doc: Pick<SyncRuleDocument, 'rule_mapping'>): BucketDefinitionMapping {
10
+ return new BucketDefinitionMapping(doc.rule_mapping?.definitions ?? {}, doc.rule_mapping?.parameter_indexes ?? {});
11
+ }
12
+
13
+ static fromParsedSyncRules(syncRules: SyncConfigWithErrors): BucketDefinitionMapping {
14
+ const definitionNames = syncRules.config.bucketDataSources.map((source) => source.uniqueName).sort();
15
+ const parameterKeys = syncRules.config.bucketParameterLookupSources
16
+ .map((source) => `${source.defaultLookupScope.lookupName}#${source.defaultLookupScope.queryId}`)
17
+ .sort();
18
+
19
+ const definitions: Record<string, BucketDefinitionId> = {};
20
+ const parameterLookups: Record<string, ParameterIndexId> = {};
21
+
22
+ for (const [index, uniqueName] of definitionNames.entries()) {
23
+ definitions[uniqueName] = (index + 1).toString(16);
24
+ }
25
+ for (const [index, key] of parameterKeys.entries()) {
26
+ parameterLookups[key] = (index + 1).toString(16);
27
+ }
28
+
29
+ return new BucketDefinitionMapping(definitions, parameterLookups);
30
+ }
31
+
32
+ constructor(
33
+ private definitions: Record<string, BucketDefinitionId> = {},
34
+ private parameterLookupMapping: Record<string, ParameterIndexId> = {}
35
+ ) {}
36
+
37
+ bucketSourceId(source: BucketDataSource): BucketDefinitionId {
38
+ const defId = this.definitions[source.uniqueName];
39
+ if (defId == null) {
40
+ throw new ServiceAssertionError(`No mapping found for bucket source ${source.uniqueName}`);
41
+ }
42
+ return defId;
43
+ }
44
+
45
+ allBucketDefinitionIds(): BucketDefinitionId[] {
46
+ return Object.values(this.definitions);
47
+ }
48
+
49
+ allParameterIndexIds(): ParameterIndexId[] {
50
+ return Object.values(this.parameterLookupMapping);
51
+ }
52
+
53
+ parameterLookupId(source: ParameterIndexLookupCreator): ParameterIndexId {
54
+ const key = this.parameterLookupKey(source.defaultLookupScope.lookupName, source.defaultLookupScope.queryId);
55
+ const defId = this.parameterLookupMapping[key];
56
+ if (defId == null) {
57
+ throw new ServiceAssertionError(`No mapping found for parameter lookup source ${key}`);
58
+ }
59
+ return defId;
60
+ }
61
+
62
+ private parameterLookupKey(lookupName: string, queryId: string) {
63
+ return `${lookupName}#${queryId}`;
64
+ }
65
+
66
+ serialize(): NonNullable<SyncRuleDocument['rule_mapping']> {
67
+ return {
68
+ definitions: { ...this.definitions },
69
+ parameter_indexes: { ...this.parameterLookupMapping }
70
+ };
71
+ }
72
+ }