@powersync/service-module-mongodb-storage 0.16.0 → 0.17.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 (102) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/storage/MongoBucketStorage.d.ts +6 -4
  3. package/dist/storage/MongoBucketStorage.js +110 -36
  4. package/dist/storage/MongoBucketStorage.js.map +1 -1
  5. package/dist/storage/implementation/BucketDefinitionMapping.d.ts +4 -6
  6. package/dist/storage/implementation/BucketDefinitionMapping.js +3 -3
  7. package/dist/storage/implementation/BucketDefinitionMapping.js.map +1 -1
  8. package/dist/storage/implementation/CheckpointState.d.ts +20 -0
  9. package/dist/storage/implementation/CheckpointState.js +31 -0
  10. package/dist/storage/implementation/CheckpointState.js.map +1 -0
  11. package/dist/storage/implementation/MongoBucketBatch.d.ts +33 -22
  12. package/dist/storage/implementation/MongoBucketBatch.js +45 -271
  13. package/dist/storage/implementation/MongoBucketBatch.js.map +1 -1
  14. package/dist/storage/implementation/MongoChecksums.d.ts +2 -1
  15. package/dist/storage/implementation/MongoChecksums.js.map +1 -1
  16. package/dist/storage/implementation/MongoCompactor.d.ts +1 -1
  17. package/dist/storage/implementation/MongoPersistedSyncRules.d.ts +4 -4
  18. package/dist/storage/implementation/MongoPersistedSyncRules.js +11 -8
  19. package/dist/storage/implementation/MongoPersistedSyncRules.js.map +1 -1
  20. package/dist/storage/implementation/MongoPersistedSyncRulesContent.d.ts +19 -5
  21. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js +53 -19
  22. package/dist/storage/implementation/MongoPersistedSyncRulesContent.js.map +1 -1
  23. package/dist/storage/implementation/MongoSyncBucketStorage.d.ts +21 -10
  24. package/dist/storage/implementation/MongoSyncBucketStorage.js +18 -163
  25. package/dist/storage/implementation/MongoSyncBucketStorage.js.map +1 -1
  26. package/dist/storage/implementation/MongoSyncRulesLock.d.ts +5 -1
  27. package/dist/storage/implementation/MongoSyncRulesLock.js +7 -3
  28. package/dist/storage/implementation/MongoSyncRulesLock.js.map +1 -1
  29. package/dist/storage/implementation/SyncRuleStateUpdate.d.ts +14 -0
  30. package/dist/storage/implementation/SyncRuleStateUpdate.js +36 -0
  31. package/dist/storage/implementation/SyncRuleStateUpdate.js.map +1 -0
  32. package/dist/storage/implementation/common/BucketDataDoc.d.ts +1 -1
  33. package/dist/storage/implementation/common/PersistedBatch.d.ts +2 -2
  34. package/dist/storage/implementation/common/SourceRecordStore.d.ts +1 -2
  35. package/dist/storage/implementation/common/VersionedPowerSyncMongoBase.d.ts +1 -1
  36. package/dist/storage/implementation/createMongoSyncBucketStorage.d.ts +2 -2
  37. package/dist/storage/implementation/createMongoSyncBucketStorage.js.map +1 -1
  38. package/dist/storage/implementation/db.d.ts +10 -2
  39. package/dist/storage/implementation/db.js.map +1 -1
  40. package/dist/storage/implementation/models.d.ts +31 -47
  41. package/dist/storage/implementation/models.js.map +1 -1
  42. package/dist/storage/implementation/v1/MongoBucketBatchV1.d.ts +15 -1
  43. package/dist/storage/implementation/v1/MongoBucketBatchV1.js +385 -0
  44. package/dist/storage/implementation/v1/MongoBucketBatchV1.js.map +1 -1
  45. package/dist/storage/implementation/v1/MongoCompactorV1.d.ts +1 -1
  46. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.d.ts +16 -7
  47. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js +77 -6
  48. package/dist/storage/implementation/v1/MongoSyncBucketStorageV1.js.map +1 -1
  49. package/dist/storage/implementation/v1/PersistedBatchV1.d.ts +1 -2
  50. package/dist/storage/implementation/v1/PersistedBatchV1.js.map +1 -1
  51. package/dist/storage/implementation/v1/models.d.ts +12 -1
  52. package/dist/storage/implementation/v1/models.js.map +1 -1
  53. package/dist/storage/implementation/v3/MongoBucketBatchV3.d.ts +17 -0
  54. package/dist/storage/implementation/v3/MongoBucketBatchV3.js +429 -0
  55. package/dist/storage/implementation/v3/MongoBucketBatchV3.js.map +1 -1
  56. package/dist/storage/implementation/v3/MongoCompactorV3.d.ts +1 -1
  57. package/dist/storage/implementation/v3/MongoParameterLookupV3.d.ts +1 -2
  58. package/dist/storage/implementation/v3/MongoParameterLookupV3.js.map +1 -1
  59. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.d.ts +29 -7
  60. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js +117 -16
  61. package/dist/storage/implementation/v3/MongoSyncBucketStorageV3.js.map +1 -1
  62. package/dist/storage/implementation/v3/PersistedBatchV3.d.ts +1 -2
  63. package/dist/storage/implementation/v3/PersistedBatchV3.js.map +1 -1
  64. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.d.ts +3 -2
  65. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js +3 -0
  66. package/dist/storage/implementation/v3/VersionedPowerSyncMongoV3.js.map +1 -1
  67. package/dist/storage/implementation/v3/models.d.ts +61 -3
  68. package/dist/storage/implementation/v3/models.js.map +1 -1
  69. package/package.json +6 -6
  70. package/src/migrations/db/migrations/1702295701188-sync-rule-state.ts +1 -1
  71. package/src/storage/MongoBucketStorage.ts +166 -44
  72. package/src/storage/implementation/BucketDefinitionMapping.ts +12 -9
  73. package/src/storage/implementation/CheckpointState.ts +59 -0
  74. package/src/storage/implementation/MongoBucketBatch.ts +81 -355
  75. package/src/storage/implementation/MongoChecksums.ts +2 -1
  76. package/src/storage/implementation/MongoCompactor.ts +1 -1
  77. package/src/storage/implementation/MongoPersistedSyncRules.ts +13 -7
  78. package/src/storage/implementation/MongoPersistedSyncRulesContent.ts +69 -24
  79. package/src/storage/implementation/MongoSyncBucketStorage.ts +40 -215
  80. package/src/storage/implementation/MongoSyncRulesLock.ts +9 -3
  81. package/src/storage/implementation/SyncRuleStateUpdate.ts +38 -0
  82. package/src/storage/implementation/common/BucketDataDoc.ts +1 -1
  83. package/src/storage/implementation/common/PersistedBatch.ts +2 -2
  84. package/src/storage/implementation/common/SourceRecordStore.ts +1 -2
  85. package/src/storage/implementation/createMongoSyncBucketStorage.ts +2 -2
  86. package/src/storage/implementation/db.ts +5 -2
  87. package/src/storage/implementation/models.ts +35 -58
  88. package/src/storage/implementation/v1/MongoBucketBatchV1.ts +478 -1
  89. package/src/storage/implementation/v1/MongoCompactorV1.ts +1 -1
  90. package/src/storage/implementation/v1/MongoSyncBucketStorageV1.ts +111 -16
  91. package/src/storage/implementation/v1/PersistedBatchV1.ts +1 -2
  92. package/src/storage/implementation/v1/models.ts +15 -0
  93. package/src/storage/implementation/v3/MongoBucketBatchV3.ts +564 -1
  94. package/src/storage/implementation/v3/MongoCompactorV3.ts +1 -1
  95. package/src/storage/implementation/v3/MongoParameterLookupV3.ts +1 -2
  96. package/src/storage/implementation/v3/MongoSyncBucketStorageV3.ts +150 -22
  97. package/src/storage/implementation/v3/PersistedBatchV3.ts +1 -2
  98. package/src/storage/implementation/v3/VersionedPowerSyncMongoV3.ts +7 -2
  99. package/src/storage/implementation/v3/models.ts +70 -2
  100. package/test/src/storage_sync.test.ts +422 -6
  101. package/test/src/storeCurrentData.test.ts +211 -0
  102. package/tsconfig.tsbuildinfo +1 -1
@@ -1,14 +1,14 @@
1
1
  import { storage } from '@powersync/service-core';
2
- import { HydratedSyncRules, HydrationState, SyncConfigWithErrors } from '@powersync/service-sync-rules';
2
+ import { HydratedSyncConfig, HydrationState, SyncConfigWithErrors } from '@powersync/service-sync-rules';
3
3
  import { BucketDefinitionMapping } from './BucketDefinitionMapping.js';
4
4
  import { StorageConfig } from './models.js';
5
5
  export declare class MongoPersistedSyncRules implements storage.PersistedSyncRules {
6
6
  readonly id: number;
7
- readonly sync_rules: SyncConfigWithErrors;
7
+ readonly syncConfigWithErrors: SyncConfigWithErrors;
8
8
  readonly slot_name: string;
9
9
  private readonly mapping;
10
10
  private readonly storageConfig;
11
11
  readonly hydrationState: HydrationState;
12
- constructor(id: number, sync_rules: SyncConfigWithErrors, slot_name: string, mapping: BucketDefinitionMapping | null, storageConfig: StorageConfig);
13
- hydratedSyncRules(): HydratedSyncRules;
12
+ constructor(id: number, syncConfigWithErrors: SyncConfigWithErrors, slot_name: string, mapping: BucketDefinitionMapping | null, storageConfig: StorageConfig);
13
+ hydratedSyncConfig(): HydratedSyncConfig;
14
14
  }
@@ -1,15 +1,16 @@
1
+ import * as sqlite from 'node:sqlite';
1
2
  import { ServiceAssertionError } from '@powersync/lib-services-framework';
2
- import { CompatibilityOption, DEFAULT_HYDRATION_STATE, versionedHydrationState } from '@powersync/service-sync-rules';
3
+ import { CompatibilityOption, DEFAULT_HYDRATION_STATE, nodeSqlite, versionedHydrationState } from '@powersync/service-sync-rules';
3
4
  export class MongoPersistedSyncRules {
4
5
  id;
5
- sync_rules;
6
+ syncConfigWithErrors;
6
7
  slot_name;
7
8
  mapping;
8
9
  storageConfig;
9
10
  hydrationState;
10
- constructor(id, sync_rules, slot_name, mapping, storageConfig) {
11
+ constructor(id, syncConfigWithErrors, slot_name, mapping, storageConfig) {
11
12
  this.id = id;
12
- this.sync_rules = sync_rules;
13
+ this.syncConfigWithErrors = syncConfigWithErrors;
13
14
  this.slot_name = slot_name;
14
15
  this.mapping = mapping;
15
16
  this.storageConfig = storageConfig;
@@ -19,7 +20,7 @@ export class MongoPersistedSyncRules {
19
20
  }
20
21
  this.hydrationState = new MongoHydrationState(this.mapping, this.id);
21
22
  }
22
- else if (!this.sync_rules.config.compatibility.isEnabled(CompatibilityOption.versionedBucketIds) &&
23
+ else if (!this.syncConfigWithErrors.config.compatibility.isEnabled(CompatibilityOption.versionedBucketIds) &&
23
24
  !this.storageConfig.versionedBuckets) {
24
25
  this.hydrationState = DEFAULT_HYDRATION_STATE;
25
26
  }
@@ -27,8 +28,11 @@ export class MongoPersistedSyncRules {
27
28
  this.hydrationState = versionedHydrationState(this.id);
28
29
  }
29
30
  }
30
- hydratedSyncRules() {
31
- return this.sync_rules.config.hydrate({ hydrationState: this.hydrationState });
31
+ hydratedSyncConfig() {
32
+ return this.syncConfigWithErrors.config.hydrate({
33
+ hydrationState: this.hydrationState,
34
+ sqlite: nodeSqlite(sqlite)
35
+ });
32
36
  }
33
37
  }
34
38
  class MongoHydrationState {
@@ -42,7 +46,6 @@ class MongoHydrationState {
42
46
  // Keep this aligned with versionedHydrationState() for now.
43
47
  //
44
48
  // Previous Mongo-specific behavior:
45
- // const defId = this.mapping.bucketSourceId(source);
46
49
  // return {
47
50
  // bucketPrefix: defId,
48
51
  // source
@@ -1 +1 @@
1
- {"version":3,"file":"MongoPersistedSyncRules.js","sourceRoot":"","sources":["../../../src/storage/implementation/MongoPersistedSyncRules.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAGL,mBAAmB,EACnB,uBAAuB,EAKvB,uBAAuB,EACxB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,OAAO,uBAAuB;IAIhB;IACA;IACA;IACC;IACA;IAPH,cAAc,CAAiB;IAE/C,YACkB,EAAU,EACV,UAAgC,EAChC,SAAiB,EAChB,OAAuC,EACvC,aAA4B;QAJ7B,OAAE,GAAF,EAAE,CAAQ;QACV,eAAU,GAAV,UAAU,CAAsB;QAChC,cAAS,GAAT,SAAS,CAAQ;QAChB,YAAO,GAAP,OAAO,CAAgC;QACvC,kBAAa,GAAb,aAAa,CAAe;QAE7C,IAAI,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBACzB,MAAM,IAAI,qBAAqB,CAAC,oCAAoC,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;aAAM,IACL,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,mBAAmB,CAAC,kBAAkB,CAAC;YACvF,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,EACpC,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,CAAC;IACjF,CAAC;CACF;AAED,MAAM,mBAAmB;IAEJ;IACA;IAFnB,YACmB,OAAgC,EAChC,OAAe;QADf,YAAO,GAAP,OAAO,CAAyB;QAChC,YAAO,GAAP,OAAO,CAAQ;IAC/B,CAAC;IAEJ,oBAAoB,CAAC,MAAwB;QAC3C,4DAA4D;QAC5D,EAAE;QACF,oCAAoC;QACpC,qDAAqD;QACrD,WAAW;QACX,yBAAyB;QACzB,WAAW;QACX,KAAK;QACL,OAAO;YACL,YAAY,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE;YACpD,MAAM;SACP,CAAC;IACJ,CAAC;IAED,4BAA4B,CAAC,MAAmC;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,EAAE;YACX,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"MongoPersistedSyncRules.js","sourceRoot":"","sources":["../../../src/storage/implementation/MongoPersistedSyncRules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,EAGL,mBAAmB,EACnB,uBAAuB,EAGvB,UAAU,EAIV,uBAAuB,EACxB,MAAM,+BAA+B,CAAC;AAIvC,MAAM,OAAO,uBAAuB;IAIhB;IACA;IACA;IACC;IACA;IAPH,cAAc,CAAiB;IAE/C,YACkB,EAAU,EACV,oBAA0C,EAC1C,SAAiB,EAChB,OAAuC,EACvC,aAA4B;QAJ7B,OAAE,GAAF,EAAE,CAAQ;QACV,yBAAoB,GAApB,oBAAoB,CAAsB;QAC1C,cAAS,GAAT,SAAS,CAAQ;QAChB,YAAO,GAAP,OAAO,CAAgC;QACvC,kBAAa,GAAb,aAAa,CAAe;QAE7C,IAAI,IAAI,CAAC,aAAa,CAAC,uBAAuB,EAAE,CAAC;YAC/C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;gBACzB,MAAM,IAAI,qBAAqB,CAAC,oCAAoC,CAAC,CAAC;YACxE,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;aAAM,IACL,CAAC,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,mBAAmB,CAAC,kBAAkB,CAAC;YACjG,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,EACpC,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC;QAChD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,cAAc,GAAG,uBAAuB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,kBAAkB;QAChB,OAAO,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,OAAO,CAAC;YAC9C,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,mBAAmB;IAEJ;IACA;IAFnB,YACmB,OAAgC,EAChC,OAAe;QADf,YAAO,GAAP,OAAO,CAAyB;QAChC,YAAO,GAAP,OAAO,CAAQ;IAC/B,CAAC;IAEJ,oBAAoB,CAAC,MAAwB;QAC3C,4DAA4D;QAC5D,EAAE;QACF,oCAAoC;QACpC,WAAW;QACX,yBAAyB;QACzB,WAAW;QACX,KAAK;QACL,OAAO;YACL,YAAY,EAAE,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,UAAU,EAAE;YACpD,MAAM;SACP,CAAC;IACJ,CAAC;IAED,4BAA4B,CAAC,MAAmC;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;QACrD,OAAO;YACL,UAAU,EAAE,KAAK;YACjB,OAAO,EAAE,EAAE;YACX,MAAM;SACP,CAAC;IACJ,CAAC;CACF"}
@@ -1,15 +1,29 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { storage } from '@powersync/service-core';
3
+ import * as bson from 'bson';
4
+ import { ReplicationStreamDocumentV3, SyncConfigDefinition } from '../storage-index.js';
3
5
  import { BucketDefinitionMapping } from './BucketDefinitionMapping.js';
4
6
  import { MongoSyncRulesLock } from './MongoSyncRulesLock.js';
5
7
  import { PowerSyncMongo } from './db.js';
6
- import { SyncRuleDocument } from './models.js';
7
- export declare class MongoPersistedSyncRulesContent extends storage.PersistedSyncRulesContent {
8
- private db;
8
+ import { SyncRuleDocumentV1 } from './v1/models.js';
9
+ declare abstract class MongoPersistedSyncRulesContentBase extends storage.PersistedSyncRulesContent {
10
+ protected readonly db: PowerSyncMongo;
9
11
  current_lock: MongoSyncRulesLock | null;
10
12
  readonly mapping: BucketDefinitionMapping;
11
- constructor(db: PowerSyncMongo, doc: mongo.WithId<SyncRuleDocument>);
13
+ readonly syncConfigId: bson.ObjectId | null;
14
+ protected constructor(db: PowerSyncMongo, options: ConstructorParameters<typeof storage.PersistedSyncRulesContent>[0] & {
15
+ mapping: BucketDefinitionMapping;
16
+ syncConfigId: bson.ObjectId | null;
17
+ });
12
18
  getStorageConfig(): import("./models.js").StorageConfig;
13
19
  parsed(options: storage.ParseSyncRulesOptions): storage.PersistedSyncRules;
14
- lock(): Promise<MongoSyncRulesLock>;
20
+ lock(session?: mongo.ClientSession): Promise<MongoSyncRulesLock>;
15
21
  }
22
+ export declare class MongoPersistedSyncRulesContentV1 extends MongoPersistedSyncRulesContentBase {
23
+ constructor(db: PowerSyncMongo, doc: SyncRuleDocumentV1);
24
+ }
25
+ export declare class MongoPersistedSyncRulesContentV3 extends MongoPersistedSyncRulesContentBase {
26
+ readonly syncConfigId: bson.ObjectId;
27
+ constructor(db: PowerSyncMongo, doc: ReplicationStreamDocumentV3, config: SyncConfigDefinition);
28
+ }
29
+ export {};
@@ -1,14 +1,38 @@
1
- import { storage } from '@powersync/service-core';
1
+ import { ServiceAssertionError } from '@powersync/lib-services-framework';
2
+ import { storage, SyncRuleState } from '@powersync/service-core';
2
3
  import { BucketDefinitionMapping } from './BucketDefinitionMapping.js';
3
4
  import { MongoPersistedSyncRules } from './MongoPersistedSyncRules.js';
4
5
  import { MongoSyncRulesLock } from './MongoSyncRulesLock.js';
5
6
  import { getMongoStorageConfig } from './models.js';
6
- export class MongoPersistedSyncRulesContent extends storage.PersistedSyncRulesContent {
7
+ class MongoPersistedSyncRulesContentBase extends storage.PersistedSyncRulesContent {
7
8
  db;
8
9
  current_lock = null;
9
10
  mapping;
11
+ syncConfigId;
12
+ constructor(db, options) {
13
+ const { mapping, syncConfigId, ...base } = options;
14
+ super(base);
15
+ this.db = db;
16
+ this.mapping = mapping;
17
+ this.syncConfigId = syncConfigId;
18
+ }
19
+ getStorageConfig() {
20
+ return getMongoStorageConfig(this.storageVersion);
21
+ }
22
+ parsed(options) {
23
+ const parsed = super.parsed(options);
24
+ const storageConfig = this.getStorageConfig();
25
+ return new MongoPersistedSyncRules(parsed.id, parsed.syncConfigWithErrors, parsed.slot_name, storageConfig.incrementalReprocessing ? this.mapping : null, storageConfig);
26
+ }
27
+ async lock(session) {
28
+ const lock = await MongoSyncRulesLock.createLock(this.db.versioned(this.getStorageConfig()), this, session);
29
+ this.current_lock = lock;
30
+ return lock;
31
+ }
32
+ }
33
+ export class MongoPersistedSyncRulesContentV1 extends MongoPersistedSyncRulesContentBase {
10
34
  constructor(db, doc) {
11
- super({
35
+ super(db, {
12
36
  id: doc._id,
13
37
  sync_rules_content: doc.content,
14
38
  compiled_plan: doc.serialized_plan ?? null,
@@ -19,24 +43,34 @@ export class MongoPersistedSyncRulesContent extends storage.PersistedSyncRulesCo
19
43
  last_fatal_error_ts: doc.last_fatal_error_ts,
20
44
  last_checkpoint_ts: doc.last_checkpoint_ts,
21
45
  last_keepalive_ts: doc.last_keepalive_ts,
22
- active: doc.state == 'ACTIVE',
23
- storageVersion: doc.storage_version ?? storage.LEGACY_STORAGE_VERSION
46
+ active: doc.state == SyncRuleState.ACTIVE,
47
+ storageVersion: doc.storage_version ?? storage.LEGACY_STORAGE_VERSION,
48
+ mapping: new BucketDefinitionMapping(),
49
+ syncConfigId: null
24
50
  });
25
- this.db = db;
26
- this.mapping = BucketDefinitionMapping.fromSyncRules(doc);
27
51
  }
28
- getStorageConfig() {
29
- return getMongoStorageConfig(this.storageVersion);
30
- }
31
- parsed(options) {
32
- const parsed = super.parsed(options);
33
- const storageConfig = this.getStorageConfig();
34
- return new MongoPersistedSyncRules(parsed.id, parsed.sync_rules, parsed.slot_name, storageConfig.incrementalReprocessing ? this.mapping : null, storageConfig);
35
- }
36
- async lock() {
37
- const lock = await MongoSyncRulesLock.createLock(this.db.versioned(this.getStorageConfig()), this);
38
- this.current_lock = lock;
39
- return lock;
52
+ }
53
+ export class MongoPersistedSyncRulesContentV3 extends MongoPersistedSyncRulesContentBase {
54
+ constructor(db, doc, config) {
55
+ const state = doc.sync_configs.find((c) => c._id.equals(config._id));
56
+ if (state == null) {
57
+ throw new ServiceAssertionError(`Cannot find sync config ${config._id} in replication stream ${doc._id}`);
58
+ }
59
+ super(db, {
60
+ id: doc._id,
61
+ sync_rules_content: config.content,
62
+ compiled_plan: config.serialized_plan ?? null,
63
+ last_checkpoint_lsn: state?.last_checkpoint_lsn ?? null,
64
+ slot_name: doc.slot_name ?? `powersync_${doc._id}`,
65
+ last_fatal_error: doc.last_fatal_error,
66
+ last_fatal_error_ts: doc.last_fatal_error_ts,
67
+ last_checkpoint_ts: doc.last_checkpoint_ts,
68
+ last_keepalive_ts: doc.last_keepalive_ts,
69
+ active: doc.state == SyncRuleState.ACTIVE && state.state == SyncRuleState.ACTIVE,
70
+ storageVersion: doc.storage_version,
71
+ mapping: BucketDefinitionMapping.fromSyncConfig(config),
72
+ syncConfigId: config._id
73
+ });
40
74
  }
41
75
  }
42
76
  //# sourceMappingURL=MongoPersistedSyncRulesContent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MongoPersistedSyncRulesContent.js","sourceRoot":"","sources":["../../../src/storage/implementation/MongoPersistedSyncRulesContent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,qBAAqB,EAAoB,MAAM,aAAa,CAAC;AAEtE,MAAM,OAAO,8BAA+B,SAAQ,OAAO,CAAC,yBAAyB;IAKzE;IAJH,YAAY,GAA8B,IAAI,CAAC;IACtC,OAAO,CAA0B;IAEjD,YACU,EAAkB,EAC1B,GAAmC;QAEnC,KAAK,CAAC;YACJ,EAAE,EAAE,GAAG,CAAC,GAAG;YACX,kBAAkB,EAAE,GAAG,CAAC,OAAO;YAC/B,aAAa,EAAE,GAAG,CAAC,eAAe,IAAI,IAAI;YAC1C,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,uBAAuB;YACvB,SAAS,EAAE,GAAG,CAAC,SAAS,IAAI,aAAa,GAAG,CAAC,GAAG,EAAE;YAClD,gBAAgB,EAAE,GAAG,CAAC,gBAAgB;YACtC,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;YAC5C,kBAAkB,EAAE,GAAG,CAAC,kBAAkB;YAC1C,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;YACxC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,QAAQ;YAC7B,cAAc,EAAE,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,sBAAsB;SACtE,CAAC,CAAC;QAhBK,OAAE,GAAF,EAAE,CAAgB;QAiB1B,IAAI,CAAC,OAAO,GAAG,uBAAuB,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IAC5D,CAAC;IAED,gBAAgB;QACd,OAAO,qBAAqB,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,CAAC,OAAsC;QAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAE9C,OAAO,IAAI,uBAAuB,CAChC,MAAM,CAAC,EAAE,EACT,MAAM,CAAC,UAAU,EACjB,MAAM,CAAC,SAAS,EAChB,aAAa,CAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,EAC3D,aAAa,CACd,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACnG,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,OAAO,IAAI,CAAC;IACd,CAAC;CACF"}
1
+ {"version":3,"file":"MongoPersistedSyncRulesContent.js","sourceRoot":"","sources":["../../../src/storage/implementation/MongoPersistedSyncRulesContent.ts"],"names":[],"mappings":"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"}
@@ -1,17 +1,17 @@
1
1
  import { mongo } from '@powersync/lib-service-mongodb';
2
2
  import { BaseObserver, DO_NOT_LOG, Logger } from '@powersync/lib-services-framework';
3
3
  import { CheckpointChanges, GetCheckpointChangesOptions, InternalOpId, PopulateChecksumCacheOptions, PopulateChecksumCacheResults, ReplicationCheckpoint, storage, utils, WatchWriteCheckpointOptions } from '@powersync/service-core';
4
- import { HydratedSyncRules, ParameterLookupRows, ScopedParameterLookup } from '@powersync/service-sync-rules';
4
+ import { HydratedSyncConfig, ParameterLookupRows, ScopedParameterLookup } from '@powersync/service-sync-rules';
5
5
  import * as bson from 'bson';
6
6
  import { MongoBucketStorage } from '../MongoBucketStorage.js';
7
7
  import { MongoSyncBucketStorageContext } from './common/MongoSyncBucketStorageContext.js';
8
8
  import type { VersionedPowerSyncMongo } from './db.js';
9
- import { CommonSourceTableDocument, StorageConfig } from './models.js';
9
+ import { StorageConfig } from './models.js';
10
10
  import { MongoBucketBatchOptions } from './MongoBucketBatch.js';
11
11
  import { MongoChecksumOptions, MongoChecksums } from './MongoChecksums.js';
12
12
  import { MongoCompactOptions, MongoCompactor } from './MongoCompactor.js';
13
13
  import { MongoParameterCompactor } from './MongoParameterCompactor.js';
14
- import { MongoPersistedSyncRulesContent } from './MongoPersistedSyncRulesContent.js';
14
+ import { MongoPersistedSyncRulesContentV1 } from './MongoPersistedSyncRulesContent.js';
15
15
  export interface MongoSyncBucketStorageOptions {
16
16
  checksumOptions?: Omit<MongoChecksumOptions, 'storageConfig' | 'mapping'>;
17
17
  storageConfig: StorageConfig;
@@ -20,11 +20,17 @@ interface InternalCheckpointChanges extends CheckpointChanges {
20
20
  updatedWriteCheckpoints: Map<string, bigint>;
21
21
  invalidateWriteCheckpoints: boolean;
22
22
  }
23
+ interface WriterSyncState {
24
+ lastCheckpointLsn: string | null;
25
+ resumeFromLsn: string | null;
26
+ keepaliveOp: InternalOpId | null;
27
+ syncConfigId?: bson.ObjectId | null;
28
+ }
23
29
  export declare abstract class MongoSyncBucketStorage extends BaseObserver<storage.SyncRulesBucketStorageListener> implements storage.SyncRulesBucketStorage {
24
30
  #private;
25
31
  readonly factory: MongoBucketStorage;
26
32
  readonly group_id: number;
27
- protected readonly sync_rules: MongoPersistedSyncRulesContent;
33
+ protected readonly sync_rules: MongoPersistedSyncRulesContentV1;
28
34
  readonly slot_name: string;
29
35
  readonly db: VersionedPowerSyncMongo;
30
36
  [DO_NOT_LOG]: boolean;
@@ -32,7 +38,8 @@ export declare abstract class MongoSyncBucketStorage extends BaseObserver<storag
32
38
  private parsedSyncRulesCache;
33
39
  private writeCheckpointAPI;
34
40
  readonly logger: Logger;
35
- constructor(factory: MongoBucketStorage, group_id: number, sync_rules: MongoPersistedSyncRulesContent, slot_name: string, writeCheckpointMode: storage.WriteCheckpointMode | undefined, options: MongoSyncBucketStorageOptions);
41
+ readonly storageConfig: StorageConfig;
42
+ constructor(factory: MongoBucketStorage, group_id: number, sync_rules: MongoPersistedSyncRulesContentV1, slot_name: string, writeCheckpointMode: storage.WriteCheckpointMode | undefined, options: MongoSyncBucketStorageOptions);
36
43
  /**
37
44
  * Not for external use - public here for tests only.
38
45
  *
@@ -47,31 +54,35 @@ export declare abstract class MongoSyncBucketStorage extends BaseObserver<storag
47
54
  setWriteCheckpointMode(mode: storage.WriteCheckpointMode): void;
48
55
  createManagedWriteCheckpoint(checkpoint: storage.ManagedWriteCheckpointOptions): Promise<bigint>;
49
56
  lastWriteCheckpoint(filters: storage.SyncStorageLastWriteCheckpointFilters): Promise<bigint | null>;
50
- getParsedSyncRules(options: storage.ParseSyncRulesOptions): HydratedSyncRules;
57
+ getParsedSyncRules(options: storage.ParseSyncRulesOptions): HydratedSyncConfig;
51
58
  getCheckpoint(): Promise<storage.ReplicationCheckpoint>;
59
+ protected abstract fetchCheckpointState(session: mongo.ClientSession): Promise<{
60
+ checkpoint: bigint;
61
+ lsn: string | null;
62
+ } | null>;
52
63
  getCheckpointInternal(): Promise<storage.ReplicationCheckpoint | null>;
53
64
  protected abstract initializeVersionStorage(): Promise<void>;
54
65
  private initializeStorage;
55
66
  protected abstract createWriterImpl(batchOptions: MongoBucketBatchOptions): storage.BucketStorageBatch;
67
+ protected abstract getWriterSyncState(): Promise<WriterSyncState>;
56
68
  createWriter(options: storage.CreateWriterOptions): Promise<storage.BucketStorageBatch>;
57
69
  startBatch(options: storage.CreateWriterOptions, callback: (batch: storage.BucketStorageBatch) => Promise<void>): Promise<storage.FlushedResult | null>;
58
- protected abstract sourceTableBaseId(): Partial<CommonSourceTableDocument>;
59
- protected abstract augmentCreatedSourceTableDocument(createDoc: CommonSourceTableDocument, options: storage.ResolveTableOptions, candidateSourceTable: storage.SourceTable): void;
60
- protected abstract initializeResolvedSourceRecords(sourceTableId: bson.ObjectId): Promise<void>;
61
- resolveTable(options: storage.ResolveTableOptions): Promise<storage.ResolveTableResult>;
62
70
  protected abstract getParameterSetsImpl(checkpoint: MongoReplicationCheckpoint, lookups: ScopedParameterLookup[], limit: number): Promise<ParameterLookupRows[]>;
63
71
  getParameterSets(checkpoint: MongoReplicationCheckpoint, lookups: ScopedParameterLookup[], limit: number): Promise<ParameterLookupRows[]>;
64
72
  protected abstract getBucketDataBatchImpl(checkpoint: utils.InternalOpId, dataBuckets: storage.BucketDataRequest[], options?: storage.BucketDataBatchOptions): AsyncIterable<storage.SyncBucketDataChunk>;
65
73
  getBucketDataBatch(checkpoint: utils.InternalOpId, dataBuckets: storage.BucketDataRequest[], options?: storage.BucketDataBatchOptions): AsyncIterable<storage.SyncBucketDataChunk>;
66
74
  getChecksums(checkpoint: utils.InternalOpId, buckets: storage.BucketChecksumRequest[]): Promise<utils.ChecksumMap>;
67
75
  clearChecksumCache(): void;
76
+ protected abstract terminateSyncRuleState(): Promise<void>;
68
77
  terminate(options?: storage.TerminateOptions): Promise<void>;
78
+ protected abstract getStatusImpl(): Promise<storage.SyncRuleStatus>;
69
79
  getStatus(): Promise<storage.SyncRuleStatus>;
70
80
  protected abstract clearBucketData(signal?: AbortSignal): Promise<void>;
71
81
  protected abstract clearParameterIndexes(signal?: AbortSignal): Promise<void>;
72
82
  protected abstract clearSourceRecords(signal?: AbortSignal): Promise<void>;
73
83
  protected abstract clearBucketState(signal?: AbortSignal): Promise<void>;
74
84
  protected abstract clearSourceTables(signal?: AbortSignal): Promise<void>;
85
+ protected abstract clearSyncRuleState(): Promise<void>;
75
86
  clear(options?: storage.ClearStorageOptions): Promise<void>;
76
87
  protected clearDeleteMany(label: string, operation: () => Promise<mongo.DeleteResult>, signal?: AbortSignal): Promise<void>;
77
88
  reportError(e: any): Promise<void>;
@@ -1,7 +1,6 @@
1
1
  import * as lib_mongo from '@powersync/lib-service-mongodb';
2
2
  import { BaseObserver, DO_NOT_LOG, ReplicationAbortedError, ServiceAssertionError } from '@powersync/lib-services-framework';
3
- import { BroadcastIterable, CHECKPOINT_INVALIDATE_ALL, maxLsn, mergeAsyncIterables, storage } from '@powersync/service-core';
4
- import * as bson from 'bson';
3
+ import { BroadcastIterable, CHECKPOINT_INVALIDATE_ALL, mergeAsyncIterables, storage } from '@powersync/service-core';
5
4
  import { LRUCache } from 'lru-cache';
6
5
  import * as timers from 'timers/promises';
7
6
  import { retryOnMongoMaxTimeMSExpired } from '../../utils/util.js';
@@ -27,6 +26,7 @@ export class MongoSyncBucketStorage extends BaseObserver {
27
26
  parsedSyncRulesCache;
28
27
  writeCheckpointAPI;
29
28
  logger;
29
+ storageConfig;
30
30
  #storageInitialized = false;
31
31
  constructor(factory, group_id, sync_rules, slot_name, writeCheckpointMode, options) {
32
32
  super();
@@ -34,7 +34,8 @@ export class MongoSyncBucketStorage extends BaseObserver {
34
34
  this.group_id = group_id;
35
35
  this.sync_rules = sync_rules;
36
36
  this.slot_name = slot_name;
37
- this.db = factory.db.versioned(sync_rules.getStorageConfig());
37
+ this.storageConfig = options.storageConfig;
38
+ this.db = factory.db.versioned(this.storageConfig);
38
39
  this.checksums = this.createMongoChecksums(options);
39
40
  this.writeCheckpointAPI = new MongoWriteCheckpointAPI({
40
41
  db: this.db,
@@ -71,7 +72,7 @@ export class MongoSyncBucketStorage extends BaseObserver {
71
72
  getParsedSyncRules(options) {
72
73
  const { parsed, options: cachedOptions } = this.parsedSyncRulesCache ?? {};
73
74
  if (!parsed || options.defaultSchema != cachedOptions?.defaultSchema) {
74
- this.parsedSyncRulesCache = { parsed: this.sync_rules.parsed(options).hydratedSyncRules(), options };
75
+ this.parsedSyncRulesCache = { parsed: this.sync_rules.parsed(options).hydratedSyncConfig(), options };
75
76
  }
76
77
  return this.parsedSyncRulesCache.parsed;
77
78
  }
@@ -80,18 +81,15 @@ export class MongoSyncBucketStorage extends BaseObserver {
80
81
  }
81
82
  async getCheckpointInternal() {
82
83
  return await this.db.client.withSession({ snapshot: true }, async (session) => {
83
- const doc = await this.db.sync_rules.findOne({ _id: this.group_id }, {
84
- session,
85
- projection: { _id: 1, state: 1, last_checkpoint: 1, last_checkpoint_lsn: 1, snapshot_done: 1 }
86
- });
87
- if (!doc?.snapshot_done || !['ACTIVE', 'ERRORED'].includes(doc.state)) {
84
+ const state = await this.fetchCheckpointState(session);
85
+ if (state == null) {
88
86
  return null;
89
87
  }
90
88
  const snapshotTime = session.snapshotTime;
91
89
  if (snapshotTime == null) {
92
90
  throw new ServiceAssertionError('Missing snapshotTime in getCheckpoint()');
93
91
  }
94
- return new MongoReplicationCheckpoint(this, doc.last_checkpoint ?? 0n, doc.last_checkpoint_lsn ?? null, snapshotTime);
92
+ return new MongoReplicationCheckpoint(this, state.checkpoint, state.lsn, snapshotTime);
95
93
  });
96
94
  }
97
95
  async initializeStorage() {
@@ -104,23 +102,22 @@ export class MongoSyncBucketStorage extends BaseObserver {
104
102
  }
105
103
  async createWriter(options) {
106
104
  await this.initializeStorage();
107
- const doc = await this.db.sync_rules.findOne({
108
- _id: this.group_id
109
- }, { projection: { last_checkpoint_lsn: 1, no_checkpoint_before: 1, keepalive_op: 1, snapshot_lsn: 1 } });
110
- const checkpoint_lsn = doc?.last_checkpoint_lsn ?? null;
105
+ const state = await this.getWriterSyncState();
111
106
  const batchOptions = {
112
107
  logger: options.logger ?? this.logger,
113
108
  db: this.db,
114
- syncRules: this.sync_rules.parsed(options).hydratedSyncRules(),
109
+ syncRules: this.sync_rules.parsed(options).hydratedSyncConfig(),
115
110
  mapping: this.sync_rules.mapping,
116
111
  groupId: this.group_id,
117
112
  slotName: this.slot_name,
118
- lastCheckpointLsn: checkpoint_lsn,
119
- resumeFromLsn: maxLsn(checkpoint_lsn, doc?.snapshot_lsn),
120
- keepaliveOp: doc?.keepalive_op ? BigInt(doc.keepalive_op) : null,
113
+ lastCheckpointLsn: state.lastCheckpointLsn,
114
+ resumeFromLsn: state.resumeFromLsn,
115
+ keepaliveOp: state.keepaliveOp,
121
116
  storeCurrentData: options.storeCurrentData,
122
117
  skipExistingRows: options.skipExistingRows ?? false,
123
118
  markRecordUnavailable: options.markRecordUnavailable,
119
+ hooks: options.hooks,
120
+ syncConfigId: state.syncConfigId,
124
121
  tracer: options.tracer
125
122
  };
126
123
  const writer = this.createWriterImpl(batchOptions);
@@ -133,109 +130,6 @@ export class MongoSyncBucketStorage extends BaseObserver {
133
130
  await writer.flush();
134
131
  return writer.last_flushed_op != null ? { flushed_op: writer.last_flushed_op } : null;
135
132
  }
136
- async resolveTable(options) {
137
- const { group_id, connection_id, connection_tag, entity_descriptor } = options;
138
- const { schema, name, objectId, replicaIdColumns } = entity_descriptor;
139
- const normalizedReplicaIdColumns = replicaIdColumns.map((column) => ({
140
- name: column.name,
141
- type: column.type,
142
- type_oid: column.typeId
143
- }));
144
- let result = null;
145
- let initializeSourceRecordsFor = null;
146
- const baseId = this.sourceTableBaseId();
147
- await this.db.client.withSession(async (session) => {
148
- const col = this.db.commonSourceTables(group_id);
149
- let filter = {
150
- ...baseId,
151
- connection_id: connection_id,
152
- schema_name: schema,
153
- table_name: name,
154
- replica_id_columns2: normalizedReplicaIdColumns
155
- };
156
- if (objectId != null) {
157
- filter.relation_id = objectId;
158
- }
159
- let doc = await col.findOne(filter, { session });
160
- if (doc == null) {
161
- const candidateSourceTable = new storage.SourceTable({
162
- id: new bson.ObjectId(),
163
- connectionTag: connection_tag,
164
- objectId: objectId,
165
- schema: schema,
166
- name: name,
167
- replicaIdColumns: replicaIdColumns,
168
- snapshotComplete: false
169
- });
170
- const createDoc = {
171
- _id: candidateSourceTable.id,
172
- ...baseId,
173
- connection_id: connection_id,
174
- relation_id: objectId,
175
- schema_name: schema,
176
- table_name: name,
177
- replica_id_columns: null,
178
- replica_id_columns2: normalizedReplicaIdColumns,
179
- snapshot_done: false,
180
- snapshot_status: undefined
181
- };
182
- this.augmentCreatedSourceTableDocument(createDoc, options, candidateSourceTable);
183
- doc = createDoc;
184
- await col.insertOne(doc, { session });
185
- initializeSourceRecordsFor = doc._id;
186
- }
187
- const sourceTable = new storage.SourceTable({
188
- id: doc._id,
189
- connectionTag: connection_tag,
190
- objectId: objectId,
191
- schema: schema,
192
- name: name,
193
- replicaIdColumns: replicaIdColumns,
194
- snapshotComplete: doc.snapshot_done ?? true
195
- });
196
- sourceTable.syncEvent = options.sync_rules.tableTriggersEvent(sourceTable);
197
- sourceTable.syncData = options.sync_rules.tableSyncsData(sourceTable);
198
- sourceTable.syncParameters = options.sync_rules.tableSyncsParameters(sourceTable);
199
- sourceTable.snapshotStatus =
200
- doc.snapshot_status == null
201
- ? undefined
202
- : {
203
- lastKey: doc.snapshot_status.last_key?.buffer ?? null,
204
- totalEstimatedCount: doc.snapshot_status.total_estimated_count,
205
- replicatedCount: doc.snapshot_status.replicated_count
206
- };
207
- let dropTables = [];
208
- let truncateFilter = [{ schema_name: schema, table_name: name }];
209
- if (objectId != null) {
210
- truncateFilter.push({ relation_id: objectId });
211
- }
212
- const truncate = await col
213
- .find({
214
- ...baseId,
215
- connection_id: connection_id,
216
- _id: { $ne: doc._id },
217
- $or: truncateFilter
218
- }, { session })
219
- .toArray();
220
- dropTables = truncate.map((doc) => new storage.SourceTable({
221
- id: doc._id,
222
- connectionTag: connection_tag,
223
- objectId: doc.relation_id,
224
- schema: doc.schema_name,
225
- name: doc.table_name,
226
- replicaIdColumns: doc.replica_id_columns2?.map((c) => ({ name: c.name, typeOid: c.type_oid, type: c.type })) ?? [],
227
- snapshotComplete: doc.snapshot_done ?? true
228
- }));
229
- result = {
230
- table: sourceTable,
231
- dropTables: dropTables
232
- };
233
- });
234
- if (initializeSourceRecordsFor != null) {
235
- await this.initializeResolvedSourceRecords(initializeSourceRecordsFor);
236
- }
237
- return result;
238
- }
239
133
  async getParameterSets(checkpoint, lookups, limit) {
240
134
  return this.getParameterSetsImpl(checkpoint, lookups, limit);
241
135
  }
@@ -252,57 +146,18 @@ export class MongoSyncBucketStorage extends BaseObserver {
252
146
  if (!options || options?.clearStorage) {
253
147
  await this.clear(options);
254
148
  }
255
- await this.db.sync_rules.updateOne({
256
- _id: this.group_id
257
- }, {
258
- $set: {
259
- state: storage.SyncRuleState.TERMINATED,
260
- persisted_lsn: null,
261
- snapshot_done: false
262
- }
263
- });
149
+ await this.terminateSyncRuleState();
264
150
  await this.db.notifyCheckpoint();
265
151
  }
266
152
  async getStatus() {
267
- const doc = await this.db.sync_rules.findOne({
268
- _id: this.group_id
269
- }, {
270
- projection: {
271
- snapshot_done: 1,
272
- last_checkpoint_lsn: 1,
273
- state: 1,
274
- snapshot_lsn: 1
275
- }
276
- });
277
- if (doc == null) {
278
- throw new ServiceAssertionError('Cannot find replication stream status');
279
- }
280
- return {
281
- snapshot_done: doc.snapshot_done,
282
- snapshot_lsn: doc.snapshot_lsn ?? null,
283
- active: doc.state == 'ACTIVE',
284
- checkpoint_lsn: doc.last_checkpoint_lsn
285
- };
153
+ return this.getStatusImpl();
286
154
  }
287
155
  async clear(options) {
288
156
  const signal = options?.signal;
289
157
  if (signal?.aborted) {
290
158
  throw new ReplicationAbortedError('Aborted clearing data', signal.reason);
291
159
  }
292
- await this.db.sync_rules.updateOne({
293
- _id: this.group_id
294
- }, {
295
- $set: {
296
- snapshot_done: false,
297
- persisted_lsn: null,
298
- last_checkpoint_lsn: null,
299
- last_checkpoint: null,
300
- no_checkpoint_before: null
301
- },
302
- $unset: {
303
- snapshot_lsn: 1
304
- }
305
- }, { maxTimeMS: lib_mongo.db.MONGO_CLEAR_OPERATION_TIMEOUT_MS });
160
+ await this.clearSyncRuleState();
306
161
  await this.clearBucketData(signal);
307
162
  await this.clearParameterIndexes(signal);
308
163
  await this.clearSourceRecords(signal);