@powersync/service-core 0.8.4 → 0.8.6

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 (44) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/db/mongo.d.ts +6 -0
  3. package/dist/db/mongo.js +6 -0
  4. package/dist/db/mongo.js.map +1 -1
  5. package/dist/replication/WalStream.js +8 -4
  6. package/dist/replication/WalStream.js.map +1 -1
  7. package/dist/storage/BucketStorage.d.ts +0 -1
  8. package/dist/storage/BucketStorage.js.map +1 -1
  9. package/dist/storage/ChecksumCache.d.ts +19 -1
  10. package/dist/storage/ChecksumCache.js +8 -1
  11. package/dist/storage/ChecksumCache.js.map +1 -1
  12. package/dist/storage/MongoBucketStorage.js +19 -9
  13. package/dist/storage/MongoBucketStorage.js.map +1 -1
  14. package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +1 -1
  15. package/dist/storage/mongo/MongoSyncBucketStorage.js +40 -21
  16. package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
  17. package/dist/storage/mongo/db.d.ts +9 -0
  18. package/dist/storage/mongo/db.js +11 -0
  19. package/dist/storage/mongo/db.js.map +1 -1
  20. package/dist/storage/mongo/util.d.ts +1 -1
  21. package/dist/storage/mongo/util.js.map +1 -1
  22. package/dist/util/protocol-types.d.ts +0 -65
  23. package/dist/util/protocol-types.js +0 -7
  24. package/dist/util/protocol-types.js.map +1 -1
  25. package/dist/util/utils.d.ts +2 -1
  26. package/dist/util/utils.js +10 -3
  27. package/dist/util/utils.js.map +1 -1
  28. package/package.json +4 -4
  29. package/src/db/mongo.ts +7 -0
  30. package/src/replication/WalStream.ts +11 -4
  31. package/src/storage/BucketStorage.ts +0 -2
  32. package/src/storage/ChecksumCache.ts +32 -2
  33. package/src/storage/MongoBucketStorage.ts +18 -9
  34. package/src/storage/mongo/MongoSyncBucketStorage.ts +44 -29
  35. package/src/storage/mongo/db.ts +12 -0
  36. package/src/storage/mongo/util.ts +3 -3
  37. package/src/util/protocol-types.ts +0 -89
  38. package/src/util/utils.ts +13 -6
  39. package/test/src/checksum_cache.test.ts +27 -20
  40. package/test/src/compacting.test.ts +78 -0
  41. package/test/src/data_storage.test.ts +22 -0
  42. package/test/src/sync.test.ts +0 -7
  43. package/test/src/util.ts +14 -3
  44. package/tsconfig.tsbuildinfo +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/mongo/db.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAY3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAUrD,MAAM,UAAU,oBAAoB,CAAC,MAA6C;IAChF,OAAO,IAAI,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,OAAO,cAAc;IAczB,YAAY,MAAyB,EAAE,OAA+B;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE;YACtC,GAAG,wBAAwB;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QAEb,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,UAAU,CAAsB,cAAc,CAAC,CAAC;QACvE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;CACF"}
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/mongo/db.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAY3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AAUrD,MAAM,UAAU,oBAAoB,CAAC,MAA6C;IAChF,OAAO,IAAI,cAAc,CAAC,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC/F,CAAC;AAED,MAAM,OAAO,cAAc;IAczB,YAAY,MAAyB,EAAE,OAA+B;QACpE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE;YACtC,GAAG,wBAAwB;SAC5B,CAAC,CAAC;QACH,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QAEb,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,UAAU,CAAsB,cAAc,CAAC,CAAC;QACvE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC9C,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;QACpD,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACrC,MAAM,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACxC,MAAM,IAAI,CAAC,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC;IAC/B,CAAC;CACF"}
@@ -1,8 +1,8 @@
1
1
  import { SqliteJsonValue } from '@powersync/service-sync-rules';
2
2
  import * as bson from 'bson';
3
3
  import * as mongo from 'mongodb';
4
- import { BucketDataDocument } from './models.js';
5
4
  import { OplogEntry } from '../../util/protocol-types.js';
5
+ import { BucketDataDocument } from './models.js';
6
6
  /**
7
7
  * Lookup serialization must be number-agnostic. I.e. normalize numbers, instead of preserving numbers.
8
8
  * @param lookup
@@ -1 +1 @@
1
- {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/storage/mongo/util.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../src/storage/mongo/util.ts"],"names":[],"mappings":"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"}
@@ -1,46 +1,5 @@
1
1
  import * as t from 'ts-codec';
2
2
  import { SqliteJsonValue } from '@powersync/service-sync-rules';
3
- /**
4
- * For sync2.json
5
- */
6
- export interface ContinueCheckpointRequest {
7
- /**
8
- * Existing bucket states. Only these buckets are synchronized.
9
- */
10
- buckets: BucketRequest[];
11
- checkpoint_token: string;
12
- limit?: number;
13
- }
14
- export interface SyncNewCheckpointRequest {
15
- /**
16
- * Existing bucket states. Used if include_data is specified.
17
- */
18
- buckets?: BucketRequest[];
19
- request_checkpoint: {
20
- /**
21
- * Whether or not to include an initial data request.
22
- */
23
- include_data: boolean;
24
- /**
25
- * Whether or not to compute a checksum.
26
- */
27
- include_checksum: boolean;
28
- };
29
- limit?: number;
30
- }
31
- export type SyncRequest = ContinueCheckpointRequest | SyncNewCheckpointRequest;
32
- export interface SyncResponse {
33
- /**
34
- * Data for the buckets returned. May not have an an entry for each bucket in the request.
35
- */
36
- data?: SyncBucketData[];
37
- /**
38
- * True if the response limit has been reached, and another request must be made.
39
- */
40
- has_more: boolean;
41
- checkpoint_token?: string;
42
- checkpoint?: Checkpoint;
43
- }
44
3
  export declare const BucketRequest: t.ObjectCodec<{
45
4
  name: t.IdentityCodec<t.CodecType.String>;
46
5
  /**
@@ -160,27 +119,3 @@ export interface BucketChecksum {
160
119
  */
161
120
  count: number;
162
121
  }
163
- export declare function isContinueCheckpointRequest(request: SyncRequest): request is ContinueCheckpointRequest;
164
- export declare function isSyncNewCheckpointRequest(request: SyncRequest): request is SyncNewCheckpointRequest;
165
- /**
166
- * For crud.json
167
- */
168
- export interface CrudRequest {
169
- data: CrudEntry[];
170
- }
171
- export interface CrudEntry {
172
- op: 'PUT' | 'PATCH' | 'DELETE';
173
- type: string;
174
- id: string;
175
- data: string;
176
- }
177
- export interface CrudResponse {
178
- /**
179
- * A sync response with a checkpoint >= this checkpoint would contain all the changes in this request.
180
- *
181
- * Any earlier checkpoint may or may not contain these changes.
182
- *
183
- * May be empty when the request contains no ops.
184
- */
185
- checkpoint?: OpId;
186
- }
@@ -36,11 +36,4 @@ export const StreamingSyncRequest = t.object({
36
36
  */
37
37
  client_id: t.string.optional()
38
38
  });
39
- export function isContinueCheckpointRequest(request) {
40
- return (Array.isArray(request.buckets) &&
41
- typeof request.checkpoint_token == 'string');
42
- }
43
- export function isSyncNewCheckpointRequest(request) {
44
- return typeof request.request_checkpoint == 'object';
45
- }
46
39
  //# sourceMappingURL=protocol-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"protocol-types.js","sourceRoot":"","sources":["../../src/util/protocol-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAwD9B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM;IAEd;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM;CAChB,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C;;OAEG;IACH,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;IAE1C;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAElC;;OAEG;IACH,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAE9B;;OAEG;IACH,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAEjC;;OAEG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAgGH,MAAM,UAAU,2BAA2B,CAAC,OAAoB;IAC9D,OAAO,CACL,KAAK,CAAC,OAAO,CAAE,OAAqC,CAAC,OAAO,CAAC;QAC7D,OAAQ,OAAqC,CAAC,gBAAgB,IAAI,QAAQ,CAC3E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,OAAoB;IAC7D,OAAO,OAAQ,OAAoC,CAAC,kBAAkB,IAAI,QAAQ,CAAC;AACrF,CAAC"}
1
+ {"version":3,"file":"protocol-types.js","sourceRoot":"","sources":["../../src/util/protocol-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAG9B,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IACpC,IAAI,EAAE,CAAC,CAAC,MAAM;IAEd;;OAEG;IACH,KAAK,EAAE,CAAC,CAAC,MAAM;CAChB,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C;;OAEG;IACH,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE;IAE1C;;OAEG;IACH,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAElC;;OAEG;IACH,gBAAgB,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,QAAQ,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAE9B;;OAEG;IACH,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE;IAEjC;;OAEG;IACH,UAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAEtC;;OAEG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import * as pgwire from '@powersync/service-jpgwire';
2
+ import { PartialChecksum } from '../storage/ChecksumCache.js';
2
3
  import * as storage from '../storage/storage-index.js';
3
4
  import { BucketChecksum, OpId } from './protocol-types.js';
4
5
  export type ChecksumMap = Map<string, BucketChecksum>;
@@ -10,7 +11,7 @@ export declare function checksumsDiff(previous: ChecksumMap, current: ChecksumMa
10
11
  removedBuckets: string[];
11
12
  };
12
13
  export declare function addChecksums(a: number, b: number): number;
13
- export declare function addBucketChecksums(a: BucketChecksum, b: BucketChecksum | null): BucketChecksum;
14
+ export declare function addBucketChecksums(a: BucketChecksum, b: PartialChecksum | null): BucketChecksum;
14
15
  export declare function getClientCheckpoint(db: pgwire.PgClient, bucketStorage: storage.BucketStorageFactory, options?: {
15
16
  timeout?: number;
16
17
  }): Promise<OpId>;
@@ -1,7 +1,7 @@
1
1
  import crypto from 'crypto';
2
+ import { logger } from '@powersync/lib-services-framework';
2
3
  import { pgwireRows } from '@powersync/service-jpgwire';
3
4
  import { retriedQuery } from './pgwire_utils.js';
4
- import { logger } from '@powersync/lib-services-framework';
5
5
  export function hashData(type, id, data) {
6
6
  const hash = crypto.createHash('sha256');
7
7
  hash.update(`put.${type}.${id}.${data}`);
@@ -55,11 +55,18 @@ export function addBucketChecksums(a, b) {
55
55
  if (b == null) {
56
56
  return a;
57
57
  }
58
+ else if (b.isFullChecksum) {
59
+ return {
60
+ bucket: b.bucket,
61
+ count: b.partialCount,
62
+ checksum: b.partialChecksum
63
+ };
64
+ }
58
65
  else {
59
66
  return {
60
67
  bucket: a.bucket,
61
- count: a.count + b.count,
62
- checksum: addChecksums(a.checksum, b.checksum)
68
+ count: a.count + b.partialCount,
69
+ checksum: addChecksums(a.checksum, b.partialChecksum)
63
70
  };
64
71
  }
65
72
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/util/utils.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAIxD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAI3D,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,EAAU,EAAE,IAAY;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC7B,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACzC,IAAI,CAAC,MAAM,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;IAC7B,OAAO,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAU;IACxC,6EAA6E;IAC7E,6CAA6C;IAC7C,IAAI,OAAO,EAAE,IAAI,QAAQ,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,yBAAyB,EAAE,KAAK,OAAO,EAAE,GAAG,CAAC,CAAC;KAC/D;IACD,OAAO,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAqB,EAAE,OAAoB;IACvE,mBAAmB;IACnB,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEzD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAElD,KAAK,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACxC,IAAI,CAAC,IAAI,IAAI,EAAE;YACb,QAAQ;YACR,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;SAC/C;aAAM;YACL,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE;gBAChE,UAAU;gBACV,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;aAC/C;iBAAM;gBACL,YAAY;aACb;SACF;KACF;IAED,OAAO;QACL,cAAc,EAAE,CAAC,GAAG,cAAc,CAAC,MAAM,EAAE,CAAC;QAC5C,cAAc,EAAE,CAAC,GAAG,QAAQ,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,CAAS,EAAE,CAAS;IAC/C,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,UAAU,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,CAAiB,EAAE,CAAwB;IAC5E,IAAI,CAAC,IAAI,IAAI,EAAE;QACb,OAAO,CAAC,CAAC;KACV;SAAM;QACL,OAAO;YACL,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,KAAK,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK;YACxB,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC;SAC/C,CAAC;KACH;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAmB,EACnB,aAA2C,EAC3C,OAA8B;IAE9B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEzB,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC,CAAC;IAElH,gDAAgD;IAChD,wEAAwE;IAExE,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,KAAM,CAAC;IAE3C,MAAM,CAAC,IAAI,CAAC,+BAA+B,GAAG,EAAE,CAAC,CAAC;IAClD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,OAAO,EAAE;QACnC,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,mBAAmB,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE;YACtB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;SAC5C;QACD,IAAI,EAAE,CAAC,GAAG,IAAI,GAAG,EAAE;YACjB,MAAM,CAAC,IAAI,CAAC,yBAAyB,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC;YAC/D,OAAO,EAAE,CAAC,UAAU,CAAC;SACtB;QAED,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;KACzD;IAED,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,EAAmB,EACnB,aAA2C,EAC3C,OAAe;IAEf,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,UAAU,CAC1B,MAAM,YAAY,CAAC,EAAE,EAAE,mEAAmE,CAAC,CAC5F,CAAC;IAEF,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,qBAAqB,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5E,MAAM,CAAC,IAAI,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9E,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA2B,EAAE,SAA6B;IACzF,IAAI,OAAO,IAAI,IAAI,EAAE;QACnB,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;KACxC;IACD,IAAI,SAAS,IAAI,IAAI,EAAE;QACrB,OAAO,OAAO,CAAC;KAChB;IACD,OAAO,GAAG,OAAO,IAAI,SAAS,EAAE,CAAC;AACnC,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/util/utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
- "version": "0.8.4",
8
+ "version": "0.8.6",
9
9
  "main": "dist/index.js",
10
10
  "license": "FSL-1.1-Apache-2.0",
11
11
  "type": "module",
@@ -34,10 +34,10 @@
34
34
  "winston": "^3.13.0",
35
35
  "yaml": "^2.3.2",
36
36
  "@powersync/lib-services-framework": "0.1.1",
37
- "@powersync/service-rsocket-router": "0.0.13",
38
- "@powersync/service-jsonbig": "0.17.10",
39
37
  "@powersync/service-jpgwire": "0.17.14",
40
- "@powersync/service-sync-rules": "0.18.3",
38
+ "@powersync/service-jsonbig": "0.17.10",
39
+ "@powersync/service-rsocket-router": "0.0.13",
40
+ "@powersync/service-sync-rules": "0.20.0",
41
41
  "@powersync/service-types": "0.2.0"
42
42
  },
43
43
  "devDependencies": {
package/src/db/mongo.ts CHANGED
@@ -22,6 +22,13 @@ export const MONGO_SOCKET_TIMEOUT_MS = 60_000;
22
22
  */
23
23
  export const MONGO_OPERATION_TIMEOUT_MS = 30_000;
24
24
 
25
+ /**
26
+ * Same as above, but specifically for clear operations.
27
+ *
28
+ * These are retried when reaching the timeout.
29
+ */
30
+ export const MONGO_CLEAR_OPERATION_TIMEOUT_MS = 5_000;
31
+
25
32
  export function createMongoClient(config: configFile.PowerSyncConfig['storage']) {
26
33
  return new mongo.MongoClient(config.uri, {
27
34
  auth: {
@@ -209,15 +209,22 @@ export class WalStream {
209
209
  // We peek a large number of changes here, to make it more likely to pick up replication slot errors.
210
210
  // For example, "publication does not exist" only occurs here if the peek actually includes changes related
211
211
  // to the slot.
212
- await this.connections.pool.query({
213
- statement: `SELECT *
214
- FROM pg_catalog.pg_logical_slot_peek_binary_changes($1, NULL, 1000, 'proto_version', '1',
215
- 'publication_names', $2)`,
212
+ logger.info(`Checking ${slotName}`);
213
+
214
+ // The actual results can be quite large, so we don't actually return everything
215
+ // due to memory and processing overhead that would create.
216
+ const cursor = await this.connections.pool.stream({
217
+ statement: `SELECT 1 FROM pg_catalog.pg_logical_slot_peek_binary_changes($1, NULL, 1000, 'proto_version', '1', 'publication_names', $2)`,
216
218
  params: [
217
219
  { type: 'varchar', value: slotName },
218
220
  { type: 'varchar', value: this.publication_name }
219
221
  ]
220
222
  });
223
+
224
+ for await (let _chunk of cursor) {
225
+ // No-op, just exhaust the cursor
226
+ }
227
+
221
228
  // Success
222
229
  logger.info(`Slot ${slotName} appears healthy`);
223
230
  return { needsInitialSync: false };
@@ -253,8 +253,6 @@ export interface SyncRulesBucketStorage {
253
253
  */
254
254
  clear(): Promise<void>;
255
255
 
256
- setSnapshotDone(lsn: string): Promise<void>;
257
-
258
256
  autoActivate(): Promise<void>;
259
257
 
260
258
  /**
@@ -8,13 +8,34 @@ interface ChecksumFetchContext {
8
8
  checkpoint: bigint;
9
9
  }
10
10
 
11
+ export interface PartialChecksum {
12
+ bucket: string;
13
+ /**
14
+ * 32-bit unsigned hash.
15
+ */
16
+ partialChecksum: number;
17
+
18
+ /**
19
+ * Count of operations - informational only.
20
+ */
21
+ partialCount: number;
22
+
23
+ /**
24
+ * True if the queried operations contains (starts with) a CLEAR
25
+ * operation, indicating that the partial checksum is the full
26
+ * checksum, and must not be added to a previously-cached checksum.
27
+ */
28
+ isFullChecksum: boolean;
29
+ }
11
30
  export interface FetchPartialBucketChecksum {
12
31
  bucket: string;
13
32
  start?: OpId;
14
33
  end: OpId;
15
34
  }
16
35
 
17
- export type FetchChecksums = (batch: FetchPartialBucketChecksum[]) => Promise<ChecksumMap>;
36
+ export type PartialChecksumMap = Map<string, PartialChecksum>;
37
+
38
+ export type FetchChecksums = (batch: FetchPartialBucketChecksum[]) => Promise<PartialChecksumMap>;
18
39
 
19
40
  export interface ChecksumCacheOptions {
20
41
  /**
@@ -33,6 +54,8 @@ export interface ChecksumCacheOptions {
33
54
  // Approximately 5MB of memory, if we assume 50 bytes per entry
34
55
  const DEFAULT_MAX_SIZE = 100_000;
35
56
 
57
+ const TTL_MS = 3_600_000;
58
+
36
59
  /**
37
60
  * Implement a LRU cache for checksum requests. Each (bucket, checkpoint) request is cached separately,
38
61
  * while the lookups occur in batches.
@@ -93,7 +116,14 @@ export class ChecksumCache {
93
116
 
94
117
  // When we have more fetches than the cache size, complete the fetches instead
95
118
  // of failing with Error('evicted').
96
- ignoreFetchAbort: true
119
+ ignoreFetchAbort: true,
120
+
121
+ // We use a TTL so that counts can eventually be refreshed
122
+ // after a compact. This only has effect if the bucket has
123
+ // not been checked in the meantime.
124
+ ttl: TTL_MS,
125
+ ttlResolution: 1_000,
126
+ allowStale: false
97
127
  });
98
128
  }
99
129
 
@@ -294,6 +294,15 @@ export class MongoBucketStorage implements BucketStorageFactory {
294
294
  }
295
295
 
296
296
  async getStorageMetrics(): Promise<StorageMetrics> {
297
+ const ignoreNotExiting = (e: unknown) => {
298
+ if (e instanceof mongo.MongoServerError && e.codeName == 'NamespaceNotFound') {
299
+ // Collection doesn't exist - return 0
300
+ return [{ storageStats: { size: 0 } }];
301
+ } else {
302
+ return Promise.reject(e);
303
+ }
304
+ };
305
+
297
306
  const active_sync_rules = await this.getActiveSyncRules();
298
307
  if (active_sync_rules == null) {
299
308
  return {
@@ -307,34 +316,34 @@ export class MongoBucketStorage implements BucketStorageFactory {
307
316
  .aggregate([
308
317
  {
309
318
  $collStats: {
310
- storageStats: {},
311
- count: {}
319
+ storageStats: {}
312
320
  }
313
321
  }
314
322
  ])
315
- .toArray();
323
+ .toArray()
324
+ .catch(ignoreNotExiting);
316
325
 
317
326
  const parameters_aggregate = await this.db.bucket_parameters
318
327
  .aggregate([
319
328
  {
320
329
  $collStats: {
321
- storageStats: {},
322
- count: {}
330
+ storageStats: {}
323
331
  }
324
332
  }
325
333
  ])
326
- .toArray();
334
+ .toArray()
335
+ .catch(ignoreNotExiting);
327
336
 
328
337
  const replication_aggregate = await this.db.current_data
329
338
  .aggregate([
330
339
  {
331
340
  $collStats: {
332
- storageStats: {},
333
- count: {}
341
+ storageStats: {}
334
342
  }
335
343
  }
336
344
  ])
337
- .toArray();
345
+ .toArray()
346
+ .catch(ignoreNotExiting);
338
347
 
339
348
  return {
340
349
  operations_size_bytes: operations_aggregate[0].storageStats.size,
@@ -18,7 +18,7 @@ import {
18
18
  SyncRulesBucketStorage,
19
19
  SyncRuleStatus
20
20
  } from '../BucketStorage.js';
21
- import { ChecksumCache, FetchPartialBucketChecksum } from '../ChecksumCache.js';
21
+ import { ChecksumCache, FetchPartialBucketChecksum, PartialChecksum, PartialChecksumMap } from '../ChecksumCache.js';
22
22
  import { MongoBucketStorage } from '../MongoBucketStorage.js';
23
23
  import { SourceTable } from '../SourceTable.js';
24
24
  import { PowerSyncMongo } from './db.js';
@@ -26,6 +26,8 @@ import { BucketDataDocument, BucketDataKey, SourceKey, SyncRuleState } from './m
26
26
  import { MongoBucketBatch } from './MongoBucketBatch.js';
27
27
  import { MongoCompactor } from './MongoCompactor.js';
28
28
  import { BSON_DESERIALIZE_OPTIONS, idPrefixFilter, mapOpEntry, readSingleBatch, serializeLookup } from './util.js';
29
+ import { logger } from '@powersync/lib-services-framework';
30
+ import * as timers from 'timers/promises';
29
31
 
30
32
  export class MongoSyncBucketStorage implements SyncRulesBucketStorage {
31
33
  private readonly db: PowerSyncMongo;
@@ -333,7 +335,7 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage {
333
335
  return this.checksumCache.getChecksumMap(checkpoint, buckets);
334
336
  }
335
337
 
336
- private async getChecksumsInternal(batch: FetchPartialBucketChecksum[]): Promise<util.ChecksumMap> {
338
+ private async getChecksumsInternal(batch: FetchPartialBucketChecksum[]): Promise<PartialChecksumMap> {
337
339
  if (batch.length == 0) {
338
340
  return new Map();
339
341
  }
@@ -365,22 +367,32 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage {
365
367
  }
366
368
  },
367
369
  {
368
- $group: { _id: '$_id.b', checksum_total: { $sum: '$checksum' }, count: { $sum: 1 } }
370
+ $group: {
371
+ _id: '$_id.b',
372
+ checksum_total: { $sum: '$checksum' },
373
+ count: { $sum: 1 },
374
+ has_clear_op: {
375
+ $max: {
376
+ $cond: [{ $eq: ['$op', 'CLEAR'] }, 1, 0]
377
+ }
378
+ }
379
+ }
369
380
  }
370
381
  ],
371
- { session: undefined }
382
+ { session: undefined, readConcern: 'snapshot' }
372
383
  )
373
384
  .toArray();
374
385
 
375
- return new Map<string, util.BucketChecksum>(
386
+ return new Map<string, PartialChecksum>(
376
387
  aggregate.map((doc) => {
377
388
  return [
378
389
  doc._id,
379
390
  {
380
391
  bucket: doc._id,
381
- count: doc.count,
382
- checksum: Number(BigInt(doc.checksum_total) & 0xffffffffn) & 0xffffffff
383
- } satisfies util.BucketChecksum
392
+ partialCount: doc.count,
393
+ partialChecksum: Number(BigInt(doc.checksum_total) & 0xffffffffn) & 0xffffffff,
394
+ isFullChecksum: doc.has_clear_op == 1
395
+ } satisfies PartialChecksum
384
396
  ];
385
397
  })
386
398
  );
@@ -428,10 +440,28 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage {
428
440
  }
429
441
 
430
442
  async clear(): Promise<void> {
443
+ while (true) {
444
+ try {
445
+ await this.clearIteration();
446
+ return;
447
+ } catch (e: unknown) {
448
+ if (e instanceof mongo.MongoServerError && e.codeName == 'MaxTimeMSExpired') {
449
+ logger.info(
450
+ `Clearing took longer than ${db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS}ms, waiting and triggering another iteration.`
451
+ );
452
+ await timers.setTimeout(db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS / 5);
453
+ continue;
454
+ } else {
455
+ throw e;
456
+ }
457
+ }
458
+ }
459
+ }
460
+
461
+ private async clearIteration(): Promise<void> {
431
462
  // Individual operations here may time out with the maxTimeMS option.
432
463
  // It is expected to still make progress, and continue on the next try.
433
464
 
434
- // TODO: Transactional?
435
465
  await this.db.sync_rules.updateOne(
436
466
  {
437
467
  _id: this.group_id
@@ -445,48 +475,33 @@ export class MongoSyncBucketStorage implements SyncRulesBucketStorage {
445
475
  no_checkpoint_before: null
446
476
  }
447
477
  },
448
- { maxTimeMS: db.mongo.MONGO_OPERATION_TIMEOUT_MS }
478
+ { maxTimeMS: db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
449
479
  );
450
480
  await this.db.bucket_data.deleteMany(
451
481
  {
452
482
  _id: idPrefixFilter<BucketDataKey>({ g: this.group_id }, ['b', 'o'])
453
483
  },
454
- { maxTimeMS: db.mongo.MONGO_OPERATION_TIMEOUT_MS }
484
+ { maxTimeMS: db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
455
485
  );
456
486
  await this.db.bucket_parameters.deleteMany(
457
487
  {
458
488
  key: idPrefixFilter<SourceKey>({ g: this.group_id }, ['t', 'k'])
459
489
  },
460
- { maxTimeMS: db.mongo.MONGO_OPERATION_TIMEOUT_MS }
490
+ { maxTimeMS: db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
461
491
  );
462
492
 
463
493
  await this.db.current_data.deleteMany(
464
494
  {
465
495
  _id: idPrefixFilter<SourceKey>({ g: this.group_id }, ['t', 'k'])
466
496
  },
467
- { maxTimeMS: db.mongo.MONGO_OPERATION_TIMEOUT_MS }
497
+ { maxTimeMS: db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
468
498
  );
469
499
 
470
500
  await this.db.source_tables.deleteMany(
471
501
  {
472
502
  group_id: this.group_id
473
503
  },
474
- { maxTimeMS: db.mongo.MONGO_OPERATION_TIMEOUT_MS }
475
- );
476
- }
477
-
478
- async setSnapshotDone(lsn: string): Promise<void> {
479
- await this.db.sync_rules.updateOne(
480
- {
481
- _id: this.group_id
482
- },
483
- {
484
- $set: {
485
- snapshot_done: true,
486
- persisted_lsn: lsn,
487
- last_checkpoint_ts: new Date()
488
- }
489
- }
504
+ { maxTimeMS: db.mongo.MONGO_CLEAR_OPERATION_TIMEOUT_MS }
490
505
  );
491
506
  }
492
507
 
@@ -59,6 +59,9 @@ export class PowerSyncMongo {
59
59
  this.locks = this.db.collection('locks');
60
60
  }
61
61
 
62
+ /**
63
+ * Clear all collections.
64
+ */
62
65
  async clear() {
63
66
  await this.current_data.deleteMany({});
64
67
  await this.bucket_data.deleteMany({});
@@ -70,4 +73,13 @@ export class PowerSyncMongo {
70
73
  await this.instance.deleteOne({});
71
74
  await this.locks.deleteMany({});
72
75
  }
76
+
77
+ /**
78
+ * Drop the entire database.
79
+ *
80
+ * Primarily for tests.
81
+ */
82
+ async drop() {
83
+ await this.db.dropDatabase();
84
+ }
73
85
  }
@@ -1,10 +1,10 @@
1
1
  import { SqliteJsonValue } from '@powersync/service-sync-rules';
2
2
  import * as bson from 'bson';
3
- import * as mongo from 'mongodb';
4
3
  import * as crypto from 'crypto';
5
- import { BucketDataDocument } from './models.js';
6
- import { timestampToOpId } from '../../util/utils.js';
4
+ import * as mongo from 'mongodb';
7
5
  import { OplogEntry } from '../../util/protocol-types.js';
6
+ import { timestampToOpId } from '../../util/utils.js';
7
+ import { BucketDataDocument } from './models.js';
8
8
 
9
9
  /**
10
10
  * Lookup serialization must be number-agnostic. I.e. normalize numbers, instead of preserving numbers.