@powersync/service-core 0.18.1 → 1.7.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.
- package/CHANGELOG.md +16 -0
- package/dist/api/RouteAPI.d.ts +1 -1
- package/dist/api/diagnostics.js +107 -169
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/entry/commands/compact-action.js +10 -73
- package/dist/entry/commands/compact-action.js.map +1 -1
- package/dist/modules/AbstractModule.d.ts +1 -1
- package/dist/replication/AbstractReplicator.js +2 -65
- package/dist/replication/AbstractReplicator.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.js +3 -2
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/routes/endpoints/socket-route.js +5 -5
- package/dist/routes/endpoints/socket-route.js.map +1 -1
- package/dist/routes/endpoints/sync-stream.js +5 -5
- package/dist/routes/endpoints/sync-stream.js.map +1 -1
- package/dist/runner/teardown.js +3 -65
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +1 -442
- package/dist/storage/BucketStorage.js +0 -9
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/BucketStorageBatch.d.ts +130 -0
- package/dist/storage/BucketStorageBatch.js +10 -0
- package/dist/storage/BucketStorageBatch.js.map +1 -0
- package/dist/storage/BucketStorageFactory.d.ts +136 -0
- package/dist/storage/BucketStorageFactory.js +2 -0
- package/dist/storage/BucketStorageFactory.js.map +1 -0
- package/dist/storage/ChecksumCache.js.map +1 -1
- package/dist/storage/PersistedSyncRulesContent.d.ts +20 -0
- package/dist/storage/PersistedSyncRulesContent.js +2 -0
- package/dist/storage/PersistedSyncRulesContent.js.map +1 -0
- package/dist/storage/ReplicationEventPayload.d.ts +1 -1
- package/dist/storage/ReplicationLock.d.ts +4 -0
- package/dist/storage/ReplicationLock.js +2 -0
- package/dist/storage/ReplicationLock.js.map +1 -0
- package/dist/storage/StorageEngine.d.ts +4 -4
- package/dist/storage/StorageEngine.js +2 -2
- package/dist/storage/StorageEngine.js.map +1 -1
- package/dist/storage/StorageProvider.d.ts +4 -1
- package/dist/storage/SyncRulesBucketStorage.d.ts +201 -0
- package/dist/storage/SyncRulesBucketStorage.js +7 -0
- package/dist/storage/SyncRulesBucketStorage.js.map +1 -0
- package/dist/storage/bson.d.ts +11 -3
- package/dist/storage/bson.js +24 -2
- package/dist/storage/bson.js.map +1 -1
- package/dist/storage/storage-index.d.ts +5 -0
- package/dist/storage/storage-index.js +5 -0
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/sync/BucketChecksumState.d.ts +91 -0
- package/dist/sync/BucketChecksumState.js +313 -0
- package/dist/sync/BucketChecksumState.js.map +1 -0
- package/dist/sync/sync-index.d.ts +1 -0
- package/dist/sync/sync-index.js +1 -0
- package/dist/sync/sync-index.js.map +1 -1
- package/dist/sync/sync.d.ts +7 -3
- package/dist/sync/sync.js +131 -135
- package/dist/sync/sync.js.map +1 -1
- package/dist/sync/util.d.ts +9 -0
- package/dist/sync/util.js +44 -0
- package/dist/sync/util.js.map +1 -1
- package/dist/util/checkpointing.d.ts +1 -1
- package/dist/util/checkpointing.js +15 -78
- package/dist/util/checkpointing.js.map +1 -1
- package/dist/util/protocol-types.d.ts +13 -4
- package/package.json +4 -4
- package/src/api/RouteAPI.ts +1 -1
- package/src/api/diagnostics.ts +1 -1
- package/src/entry/commands/compact-action.ts +2 -3
- package/src/modules/AbstractModule.ts +1 -1
- package/src/replication/AbstractReplicator.ts +1 -2
- package/src/routes/endpoints/checkpointing.ts +3 -3
- package/src/routes/endpoints/socket-route.ts +7 -5
- package/src/routes/endpoints/sync-stream.ts +8 -5
- package/src/runner/teardown.ts +1 -1
- package/src/storage/BucketStorage.ts +1 -552
- package/src/storage/BucketStorageBatch.ts +158 -0
- package/src/storage/BucketStorageFactory.ts +156 -0
- package/src/storage/ChecksumCache.ts +1 -0
- package/src/storage/PersistedSyncRulesContent.ts +26 -0
- package/src/storage/ReplicationEventPayload.ts +1 -1
- package/src/storage/ReplicationLock.ts +5 -0
- package/src/storage/StorageEngine.ts +4 -4
- package/src/storage/StorageProvider.ts +4 -1
- package/src/storage/SyncRulesBucketStorage.ts +256 -0
- package/src/storage/bson.ts +28 -4
- package/src/storage/storage-index.ts +5 -0
- package/src/sync/BucketChecksumState.ts +392 -0
- package/src/sync/sync-index.ts +1 -0
- package/src/sync/sync.ts +173 -157
- package/src/sync/util.ts +54 -0
- package/src/util/checkpointing.ts +4 -6
- package/src/util/protocol-types.ts +16 -4
- package/test/src/auth.test.ts +5 -5
- package/test/src/sync/BucketChecksumState.test.ts +565 -0
- package/test/src/sync/util.test.ts +34 -0
- package/tsconfig.tsbuildinfo +1 -1
package/dist/storage/bson.d.ts
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import * as bson from 'bson';
|
|
2
2
|
import { SqliteJsonValue } from '@powersync/service-sync-rules';
|
|
3
|
-
import { ReplicaId } from './
|
|
3
|
+
import { ReplicaId } from './BucketStorageBatch.js';
|
|
4
4
|
type NodeBuffer = Buffer<ArrayBuffer>;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Use for internal (bucket storage) data, where we control each field.
|
|
7
|
+
*/
|
|
8
|
+
export declare const BSON_DESERIALIZE_INTERNAL_OPTIONS: bson.DeserializeOptions;
|
|
9
|
+
/**
|
|
10
|
+
* Use for data from external sources.
|
|
11
|
+
*/
|
|
12
|
+
export declare const BSON_DESERIALIZE_DATA_OPTIONS: bson.DeserializeOptions;
|
|
6
13
|
/**
|
|
7
14
|
* Lookup serialization must be number-agnostic. I.e. normalize numbers, instead of preserving numbers.
|
|
8
15
|
* @param lookup
|
|
9
16
|
*/
|
|
10
17
|
export declare const serializeLookupBuffer: (lookup: SqliteJsonValue[]) => NodeBuffer;
|
|
11
18
|
export declare const serializeLookup: (lookup: SqliteJsonValue[]) => bson.Binary;
|
|
19
|
+
export declare const getLookupBucketDefinitionName: (lookup: bson.Binary) => string;
|
|
12
20
|
/**
|
|
13
21
|
* True if this is a bson.UUID.
|
|
14
22
|
*
|
|
@@ -17,7 +25,7 @@ export declare const serializeLookup: (lookup: SqliteJsonValue[]) => bson.Binary
|
|
|
17
25
|
export declare const isUUID: (value: any) => value is bson.UUID;
|
|
18
26
|
export declare const serializeReplicaId: (id: ReplicaId) => NodeBuffer;
|
|
19
27
|
export declare const deserializeReplicaId: (id: Buffer) => ReplicaId;
|
|
20
|
-
export declare const deserializeBson: (buffer:
|
|
28
|
+
export declare const deserializeBson: (buffer: Uint8Array) => bson.Document;
|
|
21
29
|
export declare const serializeBson: (document: any) => NodeBuffer;
|
|
22
30
|
/**
|
|
23
31
|
* Returns true if two ReplicaId values are the same (serializes to the same BSON value).
|
package/dist/storage/bson.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import * as bson from 'bson';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* Use for internal (bucket storage) data, where we control each field.
|
|
4
|
+
*/
|
|
5
|
+
export const BSON_DESERIALIZE_INTERNAL_OPTIONS = {
|
|
3
6
|
// use bigint instead of Long
|
|
4
7
|
useBigInt64: true
|
|
5
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Use for data from external sources.
|
|
11
|
+
*/
|
|
12
|
+
export const BSON_DESERIALIZE_DATA_OPTIONS = {
|
|
13
|
+
// Temporarily disable due to https://jira.mongodb.org/browse/NODE-6764
|
|
14
|
+
useBigInt64: false
|
|
15
|
+
};
|
|
6
16
|
/**
|
|
7
17
|
* Lookup serialization must be number-agnostic. I.e. normalize numbers, instead of preserving numbers.
|
|
8
18
|
* @param lookup
|
|
@@ -21,6 +31,10 @@ export const serializeLookupBuffer = (lookup) => {
|
|
|
21
31
|
export const serializeLookup = (lookup) => {
|
|
22
32
|
return new bson.Binary(serializeLookupBuffer(lookup));
|
|
23
33
|
};
|
|
34
|
+
export const getLookupBucketDefinitionName = (lookup) => {
|
|
35
|
+
const parsed = bson.deserialize(lookup.buffer, BSON_DESERIALIZE_INTERNAL_OPTIONS).l;
|
|
36
|
+
return parsed[0];
|
|
37
|
+
};
|
|
24
38
|
/**
|
|
25
39
|
* True if this is a bson.UUID.
|
|
26
40
|
*
|
|
@@ -41,7 +55,15 @@ export const deserializeReplicaId = (id) => {
|
|
|
41
55
|
return deserialized.id;
|
|
42
56
|
};
|
|
43
57
|
export const deserializeBson = (buffer) => {
|
|
44
|
-
|
|
58
|
+
const doc = bson.deserialize(buffer, BSON_DESERIALIZE_DATA_OPTIONS);
|
|
59
|
+
// Temporary workaround due to https://jira.mongodb.org/browse/NODE-6764
|
|
60
|
+
for (let key in doc) {
|
|
61
|
+
const value = doc[key];
|
|
62
|
+
if (value instanceof bson.Long) {
|
|
63
|
+
doc[key] = value.toBigInt();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return doc;
|
|
45
67
|
};
|
|
46
68
|
export const serializeBson = (document) => {
|
|
47
69
|
return bson.serialize(document);
|
package/dist/storage/bson.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bson.js","sourceRoot":"","sources":["../../src/storage/bson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAO7B,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"bson.js","sourceRoot":"","sources":["../../src/storage/bson.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAO7B;;GAEG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAA4B;IACxE,6BAA6B;IAC7B,WAAW,EAAE,IAAI;CAClB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAA4B;IACpE,uEAAuE;IACvE,WAAW,EAAE,KAAK;CACnB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,MAAyB,EAAc,EAAE;IAC7E,MAAM,UAAU,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACtC,IAAI,OAAO,KAAK,IAAI,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;aAAM,CAAC;YACN,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAe,CAAC;AACzD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAyB,EAAE,EAAE;IAC3D,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,MAAmB,EAAE,EAAE;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC,CAAsB,CAAC;IACzG,OAAO,MAAM,CAAC,CAAC,CAAW,CAAC;AAC7B,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAU,EAAsB,EAAE;IACvD,IAAI,KAAK,IAAI,IAAI,IAAI,OAAO,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC9C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,IAAI,GAAG,KAAkB,CAAC;IAChC,OAAO,IAAI,CAAC,SAAS,IAAI,QAAQ,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;AACjF,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAa,EAAc,EAAE;IAC9D,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,CAAe,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EAAU,EAAa,EAAE;IAC5D,MAAM,YAAY,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;IACzC,OAAO,YAAY,CAAC,EAAE,CAAC;AACzB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,MAAkB,EAAiB,EAAE;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,6BAA6B,CAAC,CAAC;IACpE,wEAAwE;IACxE,KAAK,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;QACvB,IAAI,KAAK,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC;YAC/B,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAa,EAAc,EAAE;IACzD,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAe,CAAC;AAChD,CAAC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAY,EAAE,CAAY,EAAE,EAAE;IAC5D,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACZ,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,IAAI,OAAO,CAAC,IAAI,QAAQ,IAAI,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;QACxD,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC;SAAM,IAAI,MAAM,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC;SAAM,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;SAAM,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,CAAC;SAAM,CAAC;QACN,iEAAiE;QACjE,OAAO,kBAAkB,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -7,3 +7,8 @@ export * from './SourceTable.js';
|
|
|
7
7
|
export * from './StorageEngine.js';
|
|
8
8
|
export * from './StorageProvider.js';
|
|
9
9
|
export * from './WriteCheckpointAPI.js';
|
|
10
|
+
export * from './BucketStorageFactory.js';
|
|
11
|
+
export * from './BucketStorageBatch.js';
|
|
12
|
+
export * from './SyncRulesBucketStorage.js';
|
|
13
|
+
export * from './PersistedSyncRulesContent.js';
|
|
14
|
+
export * from './ReplicationLock.js';
|
|
@@ -7,4 +7,9 @@ export * from './SourceTable.js';
|
|
|
7
7
|
export * from './StorageEngine.js';
|
|
8
8
|
export * from './StorageProvider.js';
|
|
9
9
|
export * from './WriteCheckpointAPI.js';
|
|
10
|
+
export * from './BucketStorageFactory.js';
|
|
11
|
+
export * from './BucketStorageBatch.js';
|
|
12
|
+
export * from './SyncRulesBucketStorage.js';
|
|
13
|
+
export * from './PersistedSyncRulesContent.js';
|
|
14
|
+
export * from './ReplicationLock.js';
|
|
10
15
|
//# sourceMappingURL=storage-index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage-index.js","sourceRoot":"","sources":["../../src/storage/storage-index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"storage-index.js","sourceRoot":"","sources":["../../src/storage/storage-index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { BucketDescription, RequestParameters, SqlSyncRules } from '@powersync/service-sync-rules';
|
|
2
|
+
import * as storage from '../storage/storage-index.js';
|
|
3
|
+
import * as util from '../util/util-index.js';
|
|
4
|
+
import { BucketSyncState } from './sync.js';
|
|
5
|
+
export interface BucketChecksumStateOptions {
|
|
6
|
+
bucketStorage: BucketChecksumStateStorage;
|
|
7
|
+
syncRules: SqlSyncRules;
|
|
8
|
+
syncParams: RequestParameters;
|
|
9
|
+
initialBucketPositions?: {
|
|
10
|
+
name: string;
|
|
11
|
+
after: string;
|
|
12
|
+
}[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Represents the state of the checksums and data for a specific connection.
|
|
16
|
+
*
|
|
17
|
+
* Handles incrementally re-computing checkpoints.
|
|
18
|
+
*/
|
|
19
|
+
export declare class BucketChecksumState {
|
|
20
|
+
private readonly bucketStorage;
|
|
21
|
+
/**
|
|
22
|
+
* Bucket state of bucket id -> op_id.
|
|
23
|
+
* This starts with the state from the client. May contain buckets that the user do not have access to (anymore).
|
|
24
|
+
*/
|
|
25
|
+
bucketDataPositions: Map<string, BucketSyncState>;
|
|
26
|
+
/**
|
|
27
|
+
* Last checksums sent to the client. We keep this to calculate checkpoint diffs.
|
|
28
|
+
*/
|
|
29
|
+
private lastChecksums;
|
|
30
|
+
private lastWriteCheckpoint;
|
|
31
|
+
private readonly parameterState;
|
|
32
|
+
/**
|
|
33
|
+
* Keep track of buckets that need to be downloaded. This is specifically relevant when
|
|
34
|
+
* partial checkpoints are sent.
|
|
35
|
+
*/
|
|
36
|
+
private pendingBucketDownloads;
|
|
37
|
+
constructor(options: BucketChecksumStateOptions);
|
|
38
|
+
buildNextCheckpointLine(next: storage.StorageCheckpointUpdate): Promise<CheckpointLine | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Get bucket positions to sync, given the list of buckets.
|
|
41
|
+
*
|
|
42
|
+
* @param bucketsToFetch List of buckets to fetch, typically from buildNextCheckpointLine, or a subset of that
|
|
43
|
+
* @returns
|
|
44
|
+
*/
|
|
45
|
+
getFilteredBucketPositions(bucketsToFetch: BucketDescription[]): Map<string, string>;
|
|
46
|
+
/**
|
|
47
|
+
* Update the position of bucket data the client has.
|
|
48
|
+
*
|
|
49
|
+
* @param bucket the bucket name
|
|
50
|
+
* @param nextAfter sync operations >= this value in the next batch
|
|
51
|
+
*/
|
|
52
|
+
updateBucketPosition(options: {
|
|
53
|
+
bucket: string;
|
|
54
|
+
nextAfter: string;
|
|
55
|
+
hasMore: boolean;
|
|
56
|
+
}): void;
|
|
57
|
+
}
|
|
58
|
+
export interface CheckpointUpdate {
|
|
59
|
+
/**
|
|
60
|
+
* All buckets forming part of the checkpoint.
|
|
61
|
+
*/
|
|
62
|
+
buckets: BucketDescription[];
|
|
63
|
+
/**
|
|
64
|
+
* If present, a set of buckets that have been updated since the last checkpoint.
|
|
65
|
+
*
|
|
66
|
+
* If null, assume that any bucket in `buckets` may have been updated.
|
|
67
|
+
*/
|
|
68
|
+
updatedBuckets: Set<string> | null;
|
|
69
|
+
}
|
|
70
|
+
export declare class BucketParameterState {
|
|
71
|
+
readonly bucketStorage: BucketChecksumStateStorage;
|
|
72
|
+
readonly syncRules: SqlSyncRules;
|
|
73
|
+
readonly syncParams: RequestParameters;
|
|
74
|
+
private readonly querier;
|
|
75
|
+
private readonly staticBuckets;
|
|
76
|
+
constructor(bucketStorage: BucketChecksumStateStorage, syncRules: SqlSyncRules, syncParams: RequestParameters);
|
|
77
|
+
getCheckpointUpdate(checkpoint: storage.StorageCheckpointUpdate): Promise<CheckpointUpdate | null>;
|
|
78
|
+
/**
|
|
79
|
+
* For static buckets, we can keep track of which buckets have been updated.
|
|
80
|
+
*/
|
|
81
|
+
private getCheckpointUpdateStatic;
|
|
82
|
+
/**
|
|
83
|
+
* For dynamic buckets, we need to re-query the list of buckets every time.
|
|
84
|
+
*/
|
|
85
|
+
private getCheckpointUpdateDynamic;
|
|
86
|
+
}
|
|
87
|
+
export interface CheckpointLine {
|
|
88
|
+
checkpointLine: util.StreamingSyncCheckpointDiff | util.StreamingSyncCheckpoint;
|
|
89
|
+
bucketsToFetch: BucketDescription[];
|
|
90
|
+
}
|
|
91
|
+
export type BucketChecksumStateStorage = Pick<storage.SyncRulesBucketStorage, 'getChecksums' | 'getParameterSets'>;
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import * as util from '../util/util-index.js';
|
|
2
|
+
import { ErrorCode, logger, ServiceAssertionError, ServiceError } from '@powersync/lib-services-framework';
|
|
3
|
+
/**
|
|
4
|
+
* Represents the state of the checksums and data for a specific connection.
|
|
5
|
+
*
|
|
6
|
+
* Handles incrementally re-computing checkpoints.
|
|
7
|
+
*/
|
|
8
|
+
export class BucketChecksumState {
|
|
9
|
+
bucketStorage;
|
|
10
|
+
/**
|
|
11
|
+
* Bucket state of bucket id -> op_id.
|
|
12
|
+
* This starts with the state from the client. May contain buckets that the user do not have access to (anymore).
|
|
13
|
+
*/
|
|
14
|
+
bucketDataPositions = new Map();
|
|
15
|
+
/**
|
|
16
|
+
* Last checksums sent to the client. We keep this to calculate checkpoint diffs.
|
|
17
|
+
*/
|
|
18
|
+
lastChecksums = null;
|
|
19
|
+
lastWriteCheckpoint = null;
|
|
20
|
+
parameterState;
|
|
21
|
+
/**
|
|
22
|
+
* Keep track of buckets that need to be downloaded. This is specifically relevant when
|
|
23
|
+
* partial checkpoints are sent.
|
|
24
|
+
*/
|
|
25
|
+
pendingBucketDownloads = new Set();
|
|
26
|
+
constructor(options) {
|
|
27
|
+
this.bucketStorage = options.bucketStorage;
|
|
28
|
+
this.parameterState = new BucketParameterState(options.bucketStorage, options.syncRules, options.syncParams);
|
|
29
|
+
this.bucketDataPositions = new Map();
|
|
30
|
+
for (let { name, after: start } of options.initialBucketPositions ?? []) {
|
|
31
|
+
this.bucketDataPositions.set(name, { start_op_id: start });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async buildNextCheckpointLine(next) {
|
|
35
|
+
const { writeCheckpoint, base } = next;
|
|
36
|
+
const user_id = this.parameterState.syncParams.user_id;
|
|
37
|
+
const storage = this.bucketStorage;
|
|
38
|
+
const update = await this.parameterState.getCheckpointUpdate(next);
|
|
39
|
+
if (update == null) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const { buckets: allBuckets, updatedBuckets } = update;
|
|
43
|
+
let dataBucketsNew = new Map();
|
|
44
|
+
for (let bucket of allBuckets) {
|
|
45
|
+
dataBucketsNew.set(bucket.bucket, {
|
|
46
|
+
description: bucket,
|
|
47
|
+
start_op_id: this.bucketDataPositions.get(bucket.bucket)?.start_op_id ?? '0'
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
this.bucketDataPositions = dataBucketsNew;
|
|
51
|
+
let checksumMap;
|
|
52
|
+
if (updatedBuckets != null) {
|
|
53
|
+
if (this.lastChecksums == null) {
|
|
54
|
+
throw new ServiceAssertionError(`Bucket diff received without existing checksums`);
|
|
55
|
+
}
|
|
56
|
+
// Re-check updated buckets only
|
|
57
|
+
let checksumLookups = [];
|
|
58
|
+
let newChecksums = new Map();
|
|
59
|
+
for (let bucket of dataBucketsNew.keys()) {
|
|
60
|
+
if (!updatedBuckets.has(bucket)) {
|
|
61
|
+
const existing = this.lastChecksums.get(bucket);
|
|
62
|
+
if (existing == null) {
|
|
63
|
+
// If this happens, it means updatedBuckets did not correctly include all new buckets
|
|
64
|
+
throw new ServiceAssertionError(`Existing checksum not found for bucket ${bucket}`);
|
|
65
|
+
}
|
|
66
|
+
// Bucket is not specifically updated, and we have a previous checksum
|
|
67
|
+
newChecksums.set(bucket, existing);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
checksumLookups.push(bucket);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
let updatedChecksums = await storage.getChecksums(base.checkpoint, checksumLookups);
|
|
74
|
+
for (let [bucket, value] of updatedChecksums.entries()) {
|
|
75
|
+
newChecksums.set(bucket, value);
|
|
76
|
+
}
|
|
77
|
+
checksumMap = newChecksums;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Re-check all buckets
|
|
81
|
+
const bucketList = [...dataBucketsNew.keys()];
|
|
82
|
+
checksumMap = await storage.getChecksums(base.checkpoint, bucketList);
|
|
83
|
+
}
|
|
84
|
+
// Subset of buckets for which there may be new data in this batch.
|
|
85
|
+
let bucketsToFetch;
|
|
86
|
+
let checkpointLine;
|
|
87
|
+
if (this.lastChecksums) {
|
|
88
|
+
// TODO: If updatedBuckets is present, we can use that to more efficiently calculate a diff,
|
|
89
|
+
// and avoid any unnecessary loops through the entire list of buckets.
|
|
90
|
+
const diff = util.checksumsDiff(this.lastChecksums, checksumMap);
|
|
91
|
+
if (this.lastWriteCheckpoint == writeCheckpoint &&
|
|
92
|
+
diff.removedBuckets.length == 0 &&
|
|
93
|
+
diff.updatedBuckets.length == 0) {
|
|
94
|
+
// No changes - don't send anything to the client
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
let generateBucketsToFetch = new Set();
|
|
98
|
+
for (let bucket of diff.updatedBuckets) {
|
|
99
|
+
generateBucketsToFetch.add(bucket.bucket);
|
|
100
|
+
}
|
|
101
|
+
for (let bucket of this.pendingBucketDownloads) {
|
|
102
|
+
// Bucket from a previous checkpoint that hasn't been downloaded yet.
|
|
103
|
+
// If we still have this bucket, include it in the list of buckets to fetch.
|
|
104
|
+
if (checksumMap.has(bucket)) {
|
|
105
|
+
generateBucketsToFetch.add(bucket);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const updatedBucketDescriptions = diff.updatedBuckets.map((e) => ({
|
|
109
|
+
...e,
|
|
110
|
+
priority: this.bucketDataPositions.get(e.bucket).description.priority
|
|
111
|
+
}));
|
|
112
|
+
bucketsToFetch = [...generateBucketsToFetch].map((b) => {
|
|
113
|
+
return {
|
|
114
|
+
bucket: b,
|
|
115
|
+
priority: this.bucketDataPositions.get(b).description.priority
|
|
116
|
+
};
|
|
117
|
+
});
|
|
118
|
+
let message = `Updated checkpoint: ${base.checkpoint} | `;
|
|
119
|
+
message += `write: ${writeCheckpoint} | `;
|
|
120
|
+
message += `buckets: ${allBuckets.length} | `;
|
|
121
|
+
message += `updated: ${limitedBuckets(diff.updatedBuckets, 20)} | `;
|
|
122
|
+
message += `removed: ${limitedBuckets(diff.removedBuckets, 20)}`;
|
|
123
|
+
logger.info(message, {
|
|
124
|
+
checkpoint: base.checkpoint,
|
|
125
|
+
user_id: user_id,
|
|
126
|
+
buckets: allBuckets.length,
|
|
127
|
+
updated: diff.updatedBuckets.length,
|
|
128
|
+
removed: diff.removedBuckets.length
|
|
129
|
+
});
|
|
130
|
+
checkpointLine = {
|
|
131
|
+
checkpoint_diff: {
|
|
132
|
+
last_op_id: base.checkpoint,
|
|
133
|
+
write_checkpoint: writeCheckpoint ? String(writeCheckpoint) : undefined,
|
|
134
|
+
removed_buckets: diff.removedBuckets,
|
|
135
|
+
updated_buckets: updatedBucketDescriptions
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
let message = `New checkpoint: ${base.checkpoint} | write: ${writeCheckpoint} | `;
|
|
141
|
+
message += `buckets: ${allBuckets.length} ${limitedBuckets(allBuckets, 20)}`;
|
|
142
|
+
logger.info(message, { checkpoint: base.checkpoint, user_id: user_id, buckets: allBuckets.length });
|
|
143
|
+
bucketsToFetch = allBuckets;
|
|
144
|
+
checkpointLine = {
|
|
145
|
+
checkpoint: {
|
|
146
|
+
last_op_id: base.checkpoint,
|
|
147
|
+
write_checkpoint: writeCheckpoint ? String(writeCheckpoint) : undefined,
|
|
148
|
+
buckets: [...checksumMap.values()].map((e) => ({
|
|
149
|
+
...e,
|
|
150
|
+
priority: this.bucketDataPositions.get(e.bucket).description.priority
|
|
151
|
+
}))
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
this.lastChecksums = checksumMap;
|
|
156
|
+
this.lastWriteCheckpoint = writeCheckpoint;
|
|
157
|
+
this.pendingBucketDownloads = new Set(bucketsToFetch.map((b) => b.bucket));
|
|
158
|
+
return {
|
|
159
|
+
checkpointLine,
|
|
160
|
+
bucketsToFetch
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Get bucket positions to sync, given the list of buckets.
|
|
165
|
+
*
|
|
166
|
+
* @param bucketsToFetch List of buckets to fetch, typically from buildNextCheckpointLine, or a subset of that
|
|
167
|
+
* @returns
|
|
168
|
+
*/
|
|
169
|
+
getFilteredBucketPositions(bucketsToFetch) {
|
|
170
|
+
const filtered = new Map();
|
|
171
|
+
for (let bucket of bucketsToFetch) {
|
|
172
|
+
const state = this.bucketDataPositions.get(bucket.bucket);
|
|
173
|
+
if (state) {
|
|
174
|
+
filtered.set(bucket.bucket, state.start_op_id);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return filtered;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Update the position of bucket data the client has.
|
|
181
|
+
*
|
|
182
|
+
* @param bucket the bucket name
|
|
183
|
+
* @param nextAfter sync operations >= this value in the next batch
|
|
184
|
+
*/
|
|
185
|
+
updateBucketPosition(options) {
|
|
186
|
+
const state = this.bucketDataPositions.get(options.bucket);
|
|
187
|
+
if (state) {
|
|
188
|
+
state.start_op_id = options.nextAfter;
|
|
189
|
+
}
|
|
190
|
+
if (!options.hasMore) {
|
|
191
|
+
this.pendingBucketDownloads.delete(options.bucket);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export class BucketParameterState {
|
|
196
|
+
bucketStorage;
|
|
197
|
+
syncRules;
|
|
198
|
+
syncParams;
|
|
199
|
+
querier;
|
|
200
|
+
staticBuckets;
|
|
201
|
+
constructor(bucketStorage, syncRules, syncParams) {
|
|
202
|
+
this.bucketStorage = bucketStorage;
|
|
203
|
+
this.syncRules = syncRules;
|
|
204
|
+
this.syncParams = syncParams;
|
|
205
|
+
this.querier = syncRules.getBucketParameterQuerier(this.syncParams);
|
|
206
|
+
this.staticBuckets = new Map(this.querier.staticBuckets.map((b) => [b.bucket, b]));
|
|
207
|
+
}
|
|
208
|
+
async getCheckpointUpdate(checkpoint) {
|
|
209
|
+
const querier = this.querier;
|
|
210
|
+
let update;
|
|
211
|
+
if (querier.hasDynamicBuckets) {
|
|
212
|
+
update = await this.getCheckpointUpdateDynamic(checkpoint);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
update = await this.getCheckpointUpdateStatic(checkpoint);
|
|
216
|
+
}
|
|
217
|
+
if (update == null) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
if (update.buckets.length > 1000) {
|
|
221
|
+
// TODO: Limit number of buckets even before we get to this point
|
|
222
|
+
const error = new ServiceError(ErrorCode.PSYNC_S2305, `Too many buckets: ${update.buckets.length}`);
|
|
223
|
+
logger.error(error.message, {
|
|
224
|
+
checkpoint: checkpoint,
|
|
225
|
+
user_id: this.syncParams.user_id,
|
|
226
|
+
buckets: update.buckets.length
|
|
227
|
+
});
|
|
228
|
+
throw error;
|
|
229
|
+
}
|
|
230
|
+
return update;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* For static buckets, we can keep track of which buckets have been updated.
|
|
234
|
+
*/
|
|
235
|
+
async getCheckpointUpdateStatic(checkpoint) {
|
|
236
|
+
const querier = this.querier;
|
|
237
|
+
const update = checkpoint.update;
|
|
238
|
+
if (update.invalidateDataBuckets) {
|
|
239
|
+
return {
|
|
240
|
+
buckets: querier.staticBuckets,
|
|
241
|
+
updatedBuckets: null
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
let updatedBuckets = new Set();
|
|
245
|
+
for (let bucket of update.updatedDataBuckets ?? []) {
|
|
246
|
+
if (this.staticBuckets.has(bucket)) {
|
|
247
|
+
updatedBuckets.add(bucket);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (updatedBuckets.size == 0) {
|
|
251
|
+
// No change - skip this checkpoint
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
buckets: querier.staticBuckets,
|
|
256
|
+
updatedBuckets
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* For dynamic buckets, we need to re-query the list of buckets every time.
|
|
261
|
+
*/
|
|
262
|
+
async getCheckpointUpdateDynamic(checkpoint) {
|
|
263
|
+
const querier = this.querier;
|
|
264
|
+
const storage = this.bucketStorage;
|
|
265
|
+
const staticBuckets = querier.staticBuckets;
|
|
266
|
+
const update = checkpoint.update;
|
|
267
|
+
let hasChange = false;
|
|
268
|
+
if (update.invalidateDataBuckets || update.updatedDataBuckets?.length > 0) {
|
|
269
|
+
hasChange = true;
|
|
270
|
+
}
|
|
271
|
+
else if (update.invalidateParameterBuckets) {
|
|
272
|
+
hasChange = true;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
for (let bucket of update.updatedParameterBucketDefinitions ?? []) {
|
|
276
|
+
if (querier.dynamicBucketDefinitions.has(bucket)) {
|
|
277
|
+
hasChange = true;
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
if (!hasChange) {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
const dynamicBuckets = await querier.queryDynamicBucketDescriptions({
|
|
286
|
+
getParameterSets(lookups) {
|
|
287
|
+
return storage.getParameterSets(checkpoint.base.checkpoint, lookups);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
const allBuckets = [...staticBuckets, ...dynamicBuckets];
|
|
291
|
+
return {
|
|
292
|
+
buckets: allBuckets,
|
|
293
|
+
// We cannot track individual bucket updates for dynamic lookups yet
|
|
294
|
+
updatedBuckets: null
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
function limitedBuckets(buckets, limit) {
|
|
299
|
+
buckets = buckets.map((b) => {
|
|
300
|
+
if (typeof b != 'string') {
|
|
301
|
+
return b.bucket;
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
return b;
|
|
305
|
+
}
|
|
306
|
+
});
|
|
307
|
+
if (buckets.length <= limit) {
|
|
308
|
+
return JSON.stringify(buckets);
|
|
309
|
+
}
|
|
310
|
+
const limited = buckets.slice(0, limit);
|
|
311
|
+
return `${JSON.stringify(limited)}...`;
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=BucketChecksumState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BucketChecksumState.js","sourceRoot":"","sources":["../../src/sync/BucketChecksumState.ts"],"names":[],"mappings":"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"}
|
package/dist/sync/sync-index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync-index.js","sourceRoot":"","sources":["../../src/sync/sync-index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"sync-index.js","sourceRoot":"","sources":["../../src/sync/sync-index.ts"],"names":[],"mappings":"AAAA,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,qBAAqB,CAAC;AACpC,cAAc,eAAe,CAAC;AAC9B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC;AAC1B,cAAc,0BAA0B,CAAC"}
|
package/dist/sync/sync.d.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { RequestParameters } from '@powersync/service-sync-rules';
|
|
1
|
+
import { BucketDescription, RequestParameters, SqlSyncRules } from '@powersync/service-sync-rules';
|
|
2
2
|
import * as auth from '../auth/auth-index.js';
|
|
3
3
|
import * as storage from '../storage/storage-index.js';
|
|
4
4
|
import * as util from '../util/util-index.js';
|
|
5
5
|
import { RequestTracker } from './RequestTracker.js';
|
|
6
6
|
import { TokenStreamOptions } from './util.js';
|
|
7
7
|
export interface SyncStreamParameters {
|
|
8
|
-
|
|
8
|
+
bucketStorage: storage.SyncRulesBucketStorage;
|
|
9
|
+
syncRules: SqlSyncRules;
|
|
9
10
|
params: util.StreamingSyncRequest;
|
|
10
11
|
syncParams: RequestParameters;
|
|
11
12
|
token: auth.JwtPayload;
|
|
12
|
-
parseOptions: storage.ParseSyncRulesOptions;
|
|
13
13
|
/**
|
|
14
14
|
* If this signal is aborted, the stream response ends as soon as possible, without error.
|
|
15
15
|
*/
|
|
@@ -18,3 +18,7 @@ export interface SyncStreamParameters {
|
|
|
18
18
|
tracker: RequestTracker;
|
|
19
19
|
}
|
|
20
20
|
export declare function streamResponse(options: SyncStreamParameters): AsyncIterable<util.StreamingSyncLine | string | null>;
|
|
21
|
+
export type BucketSyncState = {
|
|
22
|
+
description?: BucketDescription;
|
|
23
|
+
start_op_id: string;
|
|
24
|
+
};
|