@powersync/service-core-tests 0.0.0-dev-20260602073133 → 0.0.0-dev-20260909133214
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 +112 -4
- package/dist/test-utils/AbstractStreamTestContext.d.ts +7 -6
- package/dist/test-utils/AbstractStreamTestContext.js +28 -25
- package/dist/test-utils/AbstractStreamTestContext.js.map +1 -1
- package/dist/test-utils/StorageDataHelpers.d.ts +6 -5
- package/dist/test-utils/StorageDataHelpers.js +40 -2
- package/dist/test-utils/StorageDataHelpers.js.map +1 -1
- package/dist/test-utils/bucket-validation.d.ts +3 -3
- package/dist/test-utils/bucket-validation.js +3 -3
- package/dist/test-utils/general-utils.d.ts +16 -3
- package/dist/test-utils/general-utils.js +37 -4
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/test-utils/storage-combinations.d.ts +13 -0
- package/dist/test-utils/storage-combinations.js +26 -0
- package/dist/test-utils/storage-combinations.js.map +1 -0
- package/dist/test-utils/stream_utils.d.ts +0 -1
- package/dist/test-utils/stream_utils.js +0 -10
- package/dist/test-utils/stream_utils.js.map +1 -1
- package/dist/test-utils/test-utils-index.d.ts +1 -0
- package/dist/test-utils/test-utils-index.js +1 -0
- package/dist/test-utils/test-utils-index.js.map +1 -1
- package/dist/tests/register-compacting-tests.js +36 -29
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +138 -14
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.js +205 -138
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +44 -42
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +3 -2
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.js +404 -86
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +8 -2
- package/dist/tests/util.js +12 -0
- package/dist/tests/util.js.map +1 -1
- package/package.json +5 -6
- package/src/test-utils/AbstractStreamTestContext.ts +31 -27
- package/src/test-utils/StorageDataHelpers.ts +52 -8
- package/src/test-utils/bucket-validation.ts +3 -3
- package/src/test-utils/general-utils.ts +62 -10
- package/src/test-utils/storage-combinations.ts +51 -0
- package/src/test-utils/stream_utils.ts +0 -11
- package/src/test-utils/test-utils-index.ts +1 -0
- package/src/tests/register-compacting-tests.ts +55 -32
- package/src/tests/register-data-storage-checkpoint-tests.ts +171 -14
- package/src/tests/register-data-storage-data-tests.ts +251 -150
- package/src/tests/register-data-storage-parameter-tests.ts +58 -42
- package/src/tests/register-parameter-compacting-tests.ts +3 -2
- package/src/tests/register-sync-tests.ts +443 -88
- package/src/tests/util.ts +15 -2
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,112 @@
|
|
|
1
1
|
# @powersync/service-core-tests
|
|
2
2
|
|
|
3
|
-
## 0.0.0-dev-
|
|
3
|
+
## 0.0.0-dev-20260909133214
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [70b00a4]
|
|
8
|
+
- @powersync/service-sync-rules@0.0.0-dev-20260909133214
|
|
9
|
+
- @powersync/lib-services-framework@0.0.0-dev-20260909133214
|
|
10
|
+
- @powersync/service-core@0.0.0-dev-20260909133214
|
|
11
|
+
|
|
12
|
+
## 0.18.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- a997c88: Restructure MongoDB V3 bucket compacting.
|
|
17
|
+
- Updated dependencies [e11c54b]
|
|
18
|
+
- Updated dependencies [4b6a23e]
|
|
19
|
+
- Updated dependencies [189bd9e]
|
|
20
|
+
- Updated dependencies [bb08068]
|
|
21
|
+
- Updated dependencies [0077a8d]
|
|
22
|
+
- Updated dependencies [332d649]
|
|
23
|
+
- Updated dependencies [33a3c23]
|
|
24
|
+
- Updated dependencies [fccdff2]
|
|
25
|
+
- Updated dependencies [989d9e1]
|
|
26
|
+
- Updated dependencies [646c0de]
|
|
27
|
+
- Updated dependencies [cc121b3]
|
|
28
|
+
- Updated dependencies [4e4063b]
|
|
29
|
+
- Updated dependencies [2407f71]
|
|
30
|
+
- Updated dependencies [10131ca]
|
|
31
|
+
- Updated dependencies [4037e8f]
|
|
32
|
+
- Updated dependencies [3972bac]
|
|
33
|
+
- Updated dependencies [dd7a22f]
|
|
34
|
+
- Updated dependencies [a997c88]
|
|
35
|
+
- @powersync/service-core@1.26.0
|
|
36
|
+
- @powersync/service-sync-rules@0.41.0
|
|
37
|
+
- @powersync/lib-services-framework@0.10.1
|
|
38
|
+
|
|
39
|
+
## 0.18.0
|
|
40
|
+
|
|
41
|
+
### Minor Changes
|
|
42
|
+
|
|
43
|
+
- 2189250: Add `/sync/checkpoint-request` for client-supplied checkpoint request ids, previously called write checkpoint ids. The route returns the stored `checkpoint_request_id`, storage now treats managed request ids as monotonic per user/client, custom checkpoint request ids continue to use the existing `checkpoint` field for backwards compatibility, and `checkpoint_requested_at` metadata lets compact jobs remove expired request-derived checkpoint records.
|
|
44
|
+
|
|
45
|
+
This release includes storage migrations for the checkpoint request metadata. Self-hosters should run migrations as part of the upgrade.
|
|
46
|
+
|
|
47
|
+
### Patch Changes
|
|
48
|
+
|
|
49
|
+
- 63707af: Stability and performance fixes for MongoDB storage V3.
|
|
50
|
+
- Updated dependencies [087b61e]
|
|
51
|
+
- Updated dependencies [2189250]
|
|
52
|
+
- Updated dependencies [922f974]
|
|
53
|
+
- Updated dependencies [c4860c9]
|
|
54
|
+
- Updated dependencies [483415d]
|
|
55
|
+
- Updated dependencies [8daa300]
|
|
56
|
+
- Updated dependencies [aab068b]
|
|
57
|
+
- Updated dependencies [37591e9]
|
|
58
|
+
- Updated dependencies [be42e25]
|
|
59
|
+
- Updated dependencies [cb4c627]
|
|
60
|
+
- @powersync/service-core@1.24.0
|
|
61
|
+
- @powersync/lib-services-framework@0.10.0
|
|
62
|
+
- @powersync/service-sync-rules@0.40.0
|
|
63
|
+
|
|
64
|
+
## 0.17.2
|
|
65
|
+
|
|
66
|
+
### Patch Changes
|
|
67
|
+
|
|
68
|
+
- Updated dependencies [ea71bf3]
|
|
69
|
+
- Updated dependencies [ea31f64]
|
|
70
|
+
- Updated dependencies [edc6ed4]
|
|
71
|
+
- @powersync/service-sync-rules@0.39.0
|
|
72
|
+
- @powersync/service-core@1.23.3
|
|
73
|
+
- @powersync/lib-services-framework@0.9.8
|
|
74
|
+
|
|
75
|
+
## 0.17.1
|
|
76
|
+
|
|
77
|
+
### Patch Changes
|
|
78
|
+
|
|
79
|
+
- 71d4a0a: Add logs for checkpoint_complete to assist with debugging. Remove "sync lock" logs.
|
|
80
|
+
- e4f683d: [MongoDB Storage] Add experimental option to allow reading data from secondaries.
|
|
81
|
+
- 71d4a0a: Fix edge case where the service can return incomplete data. This could happen when using bucket priorities, and a checkpoint is invalidated by the compact process while syncing.
|
|
82
|
+
- df9ab1e: Batch concurrent write checkpoint requests and increase request limits to improve throughput.
|
|
83
|
+
- Updated dependencies [71d4a0a]
|
|
84
|
+
- Updated dependencies [e4f683d]
|
|
85
|
+
- Updated dependencies [71d4a0a]
|
|
86
|
+
- Updated dependencies [a6ae678]
|
|
87
|
+
- Updated dependencies [c2edf86]
|
|
88
|
+
- Updated dependencies [df9ab1e]
|
|
89
|
+
- @powersync/service-core@1.23.2
|
|
90
|
+
- @powersync/service-sync-rules@0.38.1
|
|
91
|
+
- @powersync/lib-services-framework@0.9.7
|
|
92
|
+
|
|
93
|
+
## 0.17.0
|
|
94
|
+
|
|
95
|
+
### Minor Changes
|
|
96
|
+
|
|
97
|
+
- a91a08f: [Experimental] Enable incremental reprocessing for MongoDB source + MongoDB storage. This includes significant changes to the v3 storage format.
|
|
98
|
+
|
|
99
|
+
### Patch Changes
|
|
100
|
+
|
|
101
|
+
- Updated dependencies [a91a08f]
|
|
102
|
+
- Updated dependencies [184c39f]
|
|
103
|
+
- Updated dependencies [c3f75df]
|
|
104
|
+
- Updated dependencies [4bd35ea]
|
|
105
|
+
- @powersync/service-core@1.23.0
|
|
106
|
+
- @powersync/service-sync-rules@0.38.0
|
|
107
|
+
- @powersync/lib-services-framework@0.9.6
|
|
108
|
+
|
|
109
|
+
## 0.16.0
|
|
4
110
|
|
|
5
111
|
### Minor Changes
|
|
6
112
|
|
|
@@ -8,6 +114,7 @@
|
|
|
8
114
|
|
|
9
115
|
### Patch Changes
|
|
10
116
|
|
|
117
|
+
- Updated dependencies [17fd96b]
|
|
11
118
|
- Updated dependencies [6e2a57e]
|
|
12
119
|
- Updated dependencies [ec6df9f]
|
|
13
120
|
- Updated dependencies [99d33d5]
|
|
@@ -20,11 +127,12 @@
|
|
|
20
127
|
- Updated dependencies [92cc83b]
|
|
21
128
|
- Updated dependencies [0aab0f9]
|
|
22
129
|
- Updated dependencies [15e2466]
|
|
130
|
+
- Updated dependencies [ebeaa3b]
|
|
23
131
|
- Updated dependencies [b116857]
|
|
24
132
|
- Updated dependencies [a94b6c3]
|
|
25
|
-
- @powersync/service-
|
|
26
|
-
- @powersync/service-
|
|
27
|
-
- @powersync/lib-services-framework@0.
|
|
133
|
+
- @powersync/service-core@1.22.0
|
|
134
|
+
- @powersync/service-sync-rules@0.37.0
|
|
135
|
+
- @powersync/lib-services-framework@0.9.5
|
|
28
136
|
|
|
29
137
|
## 0.15.5
|
|
30
138
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { BucketStorageFactory, InternalOpId, storage, SyncRulesBucketStorage } from '@powersync/service-core';
|
|
1
|
+
import { BucketStorageFactory, InternalOpId, ReplicationCheckpoint, storage, SyncRulesBucketStorage } from '@powersync/service-core';
|
|
2
2
|
export declare abstract class AbstractStreamTestContext implements AsyncDisposable {
|
|
3
3
|
protected abortController: AbortController;
|
|
4
|
-
protected syncRulesContent?: storage.
|
|
4
|
+
protected syncRulesContent?: storage.PersistedSyncConfigContent;
|
|
5
|
+
protected replicationStream?: storage.PersistedReplicationStream;
|
|
5
6
|
storage?: SyncRulesBucketStorage;
|
|
6
7
|
protected settledReplicationPromise?: Promise<PromiseSettledResult<void>>;
|
|
7
8
|
abstract get factory(): BucketStorageFactory;
|
|
@@ -12,7 +13,7 @@ export declare abstract class AbstractStreamTestContext implements AsyncDisposab
|
|
|
12
13
|
updateSyncRules(content: string): Promise<storage.SyncRulesBucketStorage>;
|
|
13
14
|
loadNextSyncRules(): Promise<storage.SyncRulesBucketStorage>;
|
|
14
15
|
loadActiveSyncRules(): Promise<storage.SyncRulesBucketStorage>;
|
|
15
|
-
private
|
|
16
|
+
private getSyncConfigContent;
|
|
16
17
|
/**
|
|
17
18
|
* Replicate a snapshot, start streaming, and wait for a consistent checkpoint.
|
|
18
19
|
*/
|
|
@@ -25,13 +26,13 @@ export declare abstract class AbstractStreamTestContext implements AsyncDisposab
|
|
|
25
26
|
replicateSnapshot(): Promise<void>;
|
|
26
27
|
abstract getClientCheckpoint(options?: {
|
|
27
28
|
timeout?: number;
|
|
28
|
-
}): Promise<
|
|
29
|
+
}): Promise<ReplicationCheckpoint>;
|
|
29
30
|
getCheckpoint(options?: {
|
|
30
31
|
timeout?: number;
|
|
31
|
-
}): Promise<
|
|
32
|
+
}): Promise<ReplicationCheckpoint>;
|
|
32
33
|
getBucketsDataBatch(buckets: Record<string, InternalOpId>, options?: {
|
|
33
34
|
timeout?: number;
|
|
34
|
-
}): Promise<storage.SyncBucketDataChunk[]>;
|
|
35
|
+
}): Promise<(storage.SyncBucketDataChunk | storage.SyncBucketDataBatchEnd)[]>;
|
|
35
36
|
/**
|
|
36
37
|
* This waits for a client checkpoint.
|
|
37
38
|
*/
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { ReplicationAbortedError } from '@powersync/lib-services-framework';
|
|
2
2
|
import { settledPromise, unsettledPromise, updateSyncRulesFromYaml } from '@powersync/service-core';
|
|
3
3
|
import { StorageDataHelpers } from './StorageDataHelpers.js';
|
|
4
|
-
import { bucketRequest } from './general-utils.js';
|
|
5
|
-
import { fromAsync } from './stream_utils.js';
|
|
4
|
+
import { bucketRequest, getBatchArray } from './general-utils.js';
|
|
6
5
|
export class AbstractStreamTestContext {
|
|
7
6
|
abortController = new AbortController();
|
|
8
7
|
syncRulesContent;
|
|
8
|
+
replicationStream;
|
|
9
9
|
storage;
|
|
10
10
|
settledReplicationPromise;
|
|
11
11
|
async [Symbol.asyncDispose]() {
|
|
@@ -28,32 +28,35 @@ export class AbstractStreamTestContext {
|
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
async updateSyncRules(content) {
|
|
31
|
-
const
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
31
|
+
const stream = await this.factory.updateSyncRules(updateSyncRulesFromYaml(content, { validate: true, storageVersion: this.storageVersion }));
|
|
32
|
+
this.replicationStream = stream;
|
|
33
|
+
this.syncRulesContent = stream.syncConfigContent[0];
|
|
34
|
+
this.storage = this.factory.getInstance(stream);
|
|
34
35
|
return this.storage;
|
|
35
36
|
}
|
|
36
37
|
async loadNextSyncRules() {
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
throw new Error(`Next sync
|
|
38
|
+
const syncConfig = await this.factory.getDeployingSyncConfig();
|
|
39
|
+
if (syncConfig == null) {
|
|
40
|
+
throw new Error(`Next sync config not available`);
|
|
40
41
|
}
|
|
41
|
-
this.syncRulesContent =
|
|
42
|
-
this.
|
|
42
|
+
this.syncRulesContent = syncConfig.content;
|
|
43
|
+
this.replicationStream = syncConfig.replicationStream;
|
|
44
|
+
this.storage = syncConfig.storage;
|
|
43
45
|
return this.storage;
|
|
44
46
|
}
|
|
45
47
|
async loadActiveSyncRules() {
|
|
46
|
-
const
|
|
47
|
-
if (
|
|
48
|
-
throw new Error(`Active sync
|
|
48
|
+
const syncConfig = await this.factory.getActiveSyncConfig();
|
|
49
|
+
if (syncConfig == null) {
|
|
50
|
+
throw new Error(`Active sync config not available`);
|
|
49
51
|
}
|
|
50
|
-
this.syncRulesContent =
|
|
51
|
-
this.
|
|
52
|
+
this.syncRulesContent = syncConfig.content;
|
|
53
|
+
this.replicationStream = syncConfig.replicationStream;
|
|
54
|
+
this.storage = syncConfig.storage;
|
|
52
55
|
return this.storage;
|
|
53
56
|
}
|
|
54
|
-
|
|
57
|
+
getSyncConfigContent() {
|
|
55
58
|
if (this.syncRulesContent == null) {
|
|
56
|
-
throw new Error('Sync
|
|
59
|
+
throw new Error('Sync config not configured - call updateSyncRules() first');
|
|
57
60
|
}
|
|
58
61
|
return this.syncRulesContent;
|
|
59
62
|
}
|
|
@@ -97,7 +100,7 @@ export class AbstractStreamTestContext {
|
|
|
97
100
|
return checkpoint;
|
|
98
101
|
}
|
|
99
102
|
async getBucketsDataBatch(buckets, options) {
|
|
100
|
-
const helpers = new StorageDataHelpers(this.storage, this.
|
|
103
|
+
const helpers = new StorageDataHelpers(this.storage, this.getSyncConfigContent());
|
|
101
104
|
const checkpoint = await this.getCheckpoint(options);
|
|
102
105
|
return helpers.getBucketsDataBatch(buckets, checkpoint);
|
|
103
106
|
}
|
|
@@ -105,14 +108,14 @@ export class AbstractStreamTestContext {
|
|
|
105
108
|
* This waits for a client checkpoint.
|
|
106
109
|
*/
|
|
107
110
|
async getBucketData(bucket, start, options) {
|
|
108
|
-
const helpers = new StorageDataHelpers(this.storage, this.
|
|
111
|
+
const helpers = new StorageDataHelpers(this.storage, this.getSyncConfigContent());
|
|
109
112
|
const checkpoint = await this.getCheckpoint(options);
|
|
110
113
|
return helpers.getBucketData(bucket, checkpoint, start);
|
|
111
114
|
}
|
|
112
115
|
async getChecksums(buckets, options) {
|
|
113
116
|
const checkpoint = await this.getCheckpoint(options);
|
|
114
|
-
const
|
|
115
|
-
const versionedBuckets = buckets.map((bucket) => bucketRequest(
|
|
117
|
+
const syncConfigContent = this.getSyncConfigContent();
|
|
118
|
+
const versionedBuckets = buckets.map((bucket) => bucketRequest(syncConfigContent, bucket, 0n));
|
|
116
119
|
const checksums = await this.storage.getChecksums(checkpoint, versionedBuckets);
|
|
117
120
|
const unversioned = new Map();
|
|
118
121
|
for (let i = 0; i < buckets.length; i++) {
|
|
@@ -132,11 +135,11 @@ export class AbstractStreamTestContext {
|
|
|
132
135
|
if (typeof start == 'string') {
|
|
133
136
|
start = BigInt(start);
|
|
134
137
|
}
|
|
135
|
-
const
|
|
136
|
-
const
|
|
137
|
-
const map = [bucketRequest(
|
|
138
|
+
const syncConfigContent = this.getSyncConfigContent();
|
|
139
|
+
const checkpoint = await this.storage.getCheckpoint();
|
|
140
|
+
const map = [bucketRequest(syncConfigContent, bucket, start)];
|
|
138
141
|
const batch = this.storage.getBucketDataBatch(checkpoint, map);
|
|
139
|
-
const batches = await
|
|
142
|
+
const batches = await getBatchArray(batch);
|
|
140
143
|
return batches[0]?.chunkData.data ?? [];
|
|
141
144
|
}
|
|
142
145
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbstractStreamTestContext.js","sourceRoot":"","sources":["../../src/test-utils/AbstractStreamTestContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,mCAAmC,CAAC;AAC5E,OAAO,
|
|
1
|
+
{"version":3,"file":"AbstractStreamTestContext.js","sourceRoot":"","sources":["../../src/test-utils/AbstractStreamTestContext.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { InternalOpId, OplogEntry,
|
|
1
|
+
import { BucketDataBatchOptions, BucketDataRequest, InternalOpId, OplogEntry, ParsedSyncConfigSet, PersistedSyncConfigContent, ReplicationCheckpoint, SyncBucketDataChunk, SyncRulesBucketStorage } from '@powersync/service-core';
|
|
2
2
|
export declare class StorageDataHelpers {
|
|
3
3
|
storage: SyncRulesBucketStorage;
|
|
4
|
-
syncRules:
|
|
5
|
-
constructor(storage: SyncRulesBucketStorage, syncRules:
|
|
6
|
-
getBucketData(bucket: string, checkpoint:
|
|
7
|
-
getBucketsDataBatch(buckets: Record<string, InternalOpId>, checkpoint:
|
|
4
|
+
syncRules: PersistedSyncConfigContent | ParsedSyncConfigSet;
|
|
5
|
+
constructor(storage: SyncRulesBucketStorage, syncRules: PersistedSyncConfigContent | ParsedSyncConfigSet);
|
|
6
|
+
getBucketData(bucket: string, checkpoint: ReplicationCheckpoint, start?: InternalOpId | string | undefined): Promise<OplogEntry<import("@powersync/service-core").StoredOplogData>[]>;
|
|
7
|
+
getBucketsDataBatch(buckets: Record<string, InternalOpId>, checkpoint: ReplicationCheckpoint): Promise<(SyncBucketDataChunk | import("@powersync/service-core").SyncBucketDataBatchEnd)[]>;
|
|
8
|
+
getAllBucketData(requests: BucketDataRequest[], checkpoint: ReplicationCheckpoint, options?: BucketDataBatchOptions): Promise<SyncBucketDataChunk[]>;
|
|
8
9
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isBatchEnd } from '@powersync/service-core';
|
|
2
|
+
import { bucketRequest, getBatchArray } from './general-utils.js';
|
|
2
3
|
import { fromAsync } from './stream_utils.js';
|
|
3
4
|
export class StorageDataHelpers {
|
|
4
5
|
storage;
|
|
@@ -16,7 +17,7 @@ export class StorageDataHelpers {
|
|
|
16
17
|
let data = [];
|
|
17
18
|
while (true) {
|
|
18
19
|
const batch = this.storage.getBucketDataBatch(checkpoint, map);
|
|
19
|
-
const batches = await
|
|
20
|
+
const batches = await getBatchArray(batch);
|
|
20
21
|
data = data.concat(batches[0]?.chunkData.data ?? []);
|
|
21
22
|
if (batches.length == 0 || !batches[0].chunkData.has_more) {
|
|
22
23
|
break;
|
|
@@ -29,5 +30,42 @@ export class StorageDataHelpers {
|
|
|
29
30
|
const map = Object.entries(buckets).map(([bucket, start]) => bucketRequest(this.syncRules, bucket, start));
|
|
30
31
|
return fromAsync(this.storage.getBucketDataBatch(checkpoint, map));
|
|
31
32
|
}
|
|
33
|
+
async getAllBucketData(requests, checkpoint, options) {
|
|
34
|
+
let remainingBuckets = new Map(requests.map((r) => [r.bucket, r]));
|
|
35
|
+
let chunks = [];
|
|
36
|
+
while (true) {
|
|
37
|
+
let hasMore = false;
|
|
38
|
+
for await (let chunk of this.storage.getBucketDataBatch(checkpoint, [...remainingBuckets.values()], options)) {
|
|
39
|
+
if (isBatchEnd(chunk)) {
|
|
40
|
+
if (chunk.hasMore) {
|
|
41
|
+
hasMore = true;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
return chunks;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
chunks.push(chunk);
|
|
50
|
+
if (chunk.chunkData.has_more) {
|
|
51
|
+
hasMore = true;
|
|
52
|
+
const r = remainingBuckets.get(chunk.chunkData.bucket);
|
|
53
|
+
remainingBuckets.set(chunk.chunkData.bucket, {
|
|
54
|
+
start: BigInt(chunk.chunkData.next_after),
|
|
55
|
+
bucket: chunk.chunkData.bucket,
|
|
56
|
+
source: r.source
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
remainingBuckets.delete(chunk.chunkData.bucket);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (!hasMore) {
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return chunks;
|
|
69
|
+
}
|
|
32
70
|
}
|
|
33
71
|
//# sourceMappingURL=StorageDataHelpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StorageDataHelpers.js","sourceRoot":"","sources":["../../src/test-utils/StorageDataHelpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"StorageDataHelpers.js","sourceRoot":"","sources":["../../src/test-utils/StorageDataHelpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,7 @@ import { utils } from '@powersync/service-core';
|
|
|
7
7
|
* All other operations are replaced with a single CLEAR operation,
|
|
8
8
|
* summing their checksums, and using a 0 as an op_id.
|
|
9
9
|
*
|
|
10
|
-
* This is the function $r(B)$, as described in /docs/bucket-properties.md.
|
|
10
|
+
* This is the function $r(B)$, as described in /docs/storage/bucket-properties.md.
|
|
11
11
|
*/
|
|
12
12
|
export declare function reduceBucket(operations: utils.OplogEntry[]): utils.OplogEntry<utils.StoredOplogData>[];
|
|
13
13
|
/**
|
|
@@ -16,7 +16,7 @@ import { reduceBucket } from '@/util/utils.js';
|
|
|
16
16
|
import { expect } from 'vitest';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* Validate this property, as described in /docs/bucket-properties.md:
|
|
19
|
+
* Validate this property, as described in /docs/storage/bucket-properties.md:
|
|
20
20
|
*
|
|
21
21
|
* $r(B_{[..id_n]}) = r(r(B_{[..id_i]}) \cup B_{[id_{i+1}..id_n]}) \;\forall\; i \in [1..n]$
|
|
22
22
|
*
|
|
@@ -27,7 +27,7 @@ import { expect } from 'vitest';
|
|
|
27
27
|
export declare function validateBucket(bucket: utils.OplogEntry[]): void;
|
|
28
28
|
/**
|
|
29
29
|
* Validate these properties for a bucket $B$ and its compacted version $B'$,:
|
|
30
|
-
* as described in /docs/bucket-properties.md:
|
|
30
|
+
* as described in /docs/storage/bucket-properties.md:
|
|
31
31
|
*
|
|
32
32
|
* 1. $r(B) = r(B')$
|
|
33
33
|
* 2. $r(B_{[..c]}) = r(r(B_{[..c_i]}) \cup B'_{[c_i+1..c]}) \;\forall\; c_i \in B$
|
|
@@ -8,7 +8,7 @@ import { expect } from 'vitest';
|
|
|
8
8
|
* All other operations are replaced with a single CLEAR operation,
|
|
9
9
|
* summing their checksums, and using a 0 as an op_id.
|
|
10
10
|
*
|
|
11
|
-
* This is the function $r(B)$, as described in /docs/bucket-properties.md.
|
|
11
|
+
* This is the function $r(B)$, as described in /docs/storage/bucket-properties.md.
|
|
12
12
|
*/
|
|
13
13
|
export function reduceBucket(operations) {
|
|
14
14
|
let rowState = new Map();
|
|
@@ -60,7 +60,7 @@ import { reduceBucket } from '@/util/utils.js';
|
|
|
60
60
|
import { expect } from 'vitest';
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
|
-
* Validate this property, as described in /docs/bucket-properties.md:
|
|
63
|
+
* Validate this property, as described in /docs/storage/bucket-properties.md:
|
|
64
64
|
*
|
|
65
65
|
* $r(B_{[..id_n]}) = r(r(B_{[..id_i]}) \cup B_{[id_{i+1}..id_n]}) \;\forall\; i \in [1..n]$
|
|
66
66
|
*
|
|
@@ -82,7 +82,7 @@ export function validateBucket(bucket) {
|
|
|
82
82
|
}
|
|
83
83
|
/**
|
|
84
84
|
* Validate these properties for a bucket $B$ and its compacted version $B'$,:
|
|
85
|
-
* as described in /docs/bucket-properties.md:
|
|
85
|
+
* as described in /docs/storage/bucket-properties.md:
|
|
86
86
|
*
|
|
87
87
|
* 1. $r(B) = r(B')$
|
|
88
88
|
* 2. $r(B_{[..c]}) = r(r(B_{[..c_i]}) \cup B'_{[c_i+1..c]}) \;\forall\; c_i \in B$
|
|
@@ -2,15 +2,26 @@ import { BucketDataRequest, InternalOpId, storage, utils } from '@powersync/serv
|
|
|
2
2
|
import { GetQuerierOptions, RequestParameters } from '@powersync/service-sync-rules';
|
|
3
3
|
import * as bson from 'bson';
|
|
4
4
|
export declare const ZERO_LSN = "0/0";
|
|
5
|
-
export declare const PARSE_OPTIONS: storage.
|
|
5
|
+
export declare const PARSE_OPTIONS: storage.ParseSyncConfigOptions;
|
|
6
6
|
export declare const BATCH_OPTIONS: storage.CreateWriterOptions;
|
|
7
|
+
export declare function testCheckpoint(checkpoint: InternalOpId, lsn?: string | null): storage.ReplicationCheckpoint;
|
|
8
|
+
/**
|
|
9
|
+
* Deploy a sync config and return both the replication stream (for {@link storage.BucketStorageFactory.getInstance})
|
|
10
|
+
* and the deployed config content (for parsing / bucket requests).
|
|
11
|
+
*
|
|
12
|
+
* Replication streams and sync config content are separate concerns since one stream can hold multiple configs.
|
|
13
|
+
*/
|
|
14
|
+
export declare function deploySyncRules(factory: storage.BucketStorageFactory, options: storage.UpdateSyncRulesOptions): Promise<{
|
|
15
|
+
stream: storage.PersistedReplicationStream;
|
|
16
|
+
content: storage.PersistedSyncConfigContent;
|
|
17
|
+
}>;
|
|
7
18
|
/**
|
|
8
19
|
* With newer storage versions, we need actual test tables, resolved via the writer.
|
|
9
20
|
*/
|
|
10
21
|
export declare function resolveTestTable(writer: storage.BucketStorageBatch, name: string, replicaIdColumns: string[] | undefined, options: {
|
|
11
22
|
tableIdStrings: boolean;
|
|
12
23
|
}, idIndex?: number): Promise<storage.SourceTable>;
|
|
13
|
-
export declare function getBatchData(batch: utils.SyncBucketData[] | storage.SyncBucketDataChunk[] | storage.SyncBucketDataChunk): {
|
|
24
|
+
export declare function getBatchData(batch: utils.SyncBucketData[] | (storage.SyncBucketDataChunk | storage.SyncBucketDataBatchEnd)[] | storage.SyncBucketDataChunk): {
|
|
14
25
|
op_id: string;
|
|
15
26
|
op: "PUT" | "REMOVE" | "MOVE" | "CLEAR";
|
|
16
27
|
object_id: string | undefined;
|
|
@@ -20,12 +31,14 @@ export declare function getBatchData(batch: utils.SyncBucketData[] | storage.Syn
|
|
|
20
31
|
* Bucket names no longer purely depend on the sync config.
|
|
21
32
|
* This converts a bucket name like "global[]" into the actual bucket name, for use in tests.
|
|
22
33
|
*/
|
|
23
|
-
export declare function bucketRequest(syncRules: storage.
|
|
34
|
+
export declare function bucketRequest(syncRules: storage.PersistedSyncConfigContent | storage.ParsedSyncConfigSet, bucket: string, start?: InternalOpId | string | number): BucketDataRequest;
|
|
24
35
|
export declare function getBatchMeta(batch: utils.SyncBucketData[] | storage.SyncBucketDataChunk[] | storage.SyncBucketDataChunk): {
|
|
25
36
|
has_more: boolean;
|
|
26
37
|
after: string;
|
|
27
38
|
next_after: string;
|
|
28
39
|
} | null;
|
|
40
|
+
export declare function getBatchArray(data: AsyncIterable<storage.SyncBucketDataChunk | storage.SyncBucketDataBatchEnd>): Promise<storage.SyncBucketDataChunk[]>;
|
|
41
|
+
export declare function getSingleBatchItem(data: AsyncIterable<storage.SyncBucketDataChunk | storage.SyncBucketDataBatchEnd>): Promise<storage.SyncBucketDataChunk>;
|
|
29
42
|
/**
|
|
30
43
|
* Replica id in the old Postgres format, for backwards-compatible tests.
|
|
31
44
|
*/
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { JwtPayload, storage, utils } from '@powersync/service-core';
|
|
1
|
+
import { isBatchEnd, JwtPayload, storage, utils } from '@powersync/service-core';
|
|
2
2
|
import { RequestParameters } from '@powersync/service-sync-rules';
|
|
3
3
|
import * as bson from 'bson';
|
|
4
|
+
import { fromAsync } from './stream_utils.js';
|
|
4
5
|
export const ZERO_LSN = '0/0';
|
|
5
6
|
export const PARSE_OPTIONS = {
|
|
6
7
|
defaultSchema: 'public'
|
|
@@ -10,6 +11,26 @@ export const BATCH_OPTIONS = {
|
|
|
10
11
|
zeroLSN: ZERO_LSN,
|
|
11
12
|
storeCurrentData: true
|
|
12
13
|
};
|
|
14
|
+
export function testCheckpoint(checkpoint, lsn = null) {
|
|
15
|
+
return {
|
|
16
|
+
checkpoint,
|
|
17
|
+
lsn,
|
|
18
|
+
async getParameterSets() {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Deploy a sync config and return both the replication stream (for {@link storage.BucketStorageFactory.getInstance})
|
|
25
|
+
* and the deployed config content (for parsing / bucket requests).
|
|
26
|
+
*
|
|
27
|
+
* Replication streams and sync config content are separate concerns since one stream can hold multiple configs.
|
|
28
|
+
*/
|
|
29
|
+
export async function deploySyncRules(factory, options) {
|
|
30
|
+
const stream = await factory.updateSyncRules(options);
|
|
31
|
+
const content = stream.syncConfigContent[0];
|
|
32
|
+
return { stream, content };
|
|
33
|
+
}
|
|
13
34
|
/**
|
|
14
35
|
* With newer storage versions, we need actual test tables, resolved via the writer.
|
|
15
36
|
*/
|
|
@@ -61,7 +82,7 @@ export function getBatchData(batch) {
|
|
|
61
82
|
});
|
|
62
83
|
}
|
|
63
84
|
function isParsedSyncRules(syncRules) {
|
|
64
|
-
return syncRules.
|
|
85
|
+
return syncRules.syncConfigs !== undefined;
|
|
65
86
|
}
|
|
66
87
|
/**
|
|
67
88
|
* Bucket names no longer purely depend on the sync config.
|
|
@@ -73,9 +94,10 @@ export function bucketRequest(syncRules, bucket, start) {
|
|
|
73
94
|
const parameterStart = bucket.indexOf('[');
|
|
74
95
|
const definitionName = bucket.substring(0, parameterStart);
|
|
75
96
|
const parameters = bucket.substring(parameterStart);
|
|
76
|
-
const
|
|
97
|
+
const availableSources = parsed.syncConfigs.flatMap((config) => config.config.bucketDataSources);
|
|
98
|
+
const source = availableSources.find((b) => b.uniqueName === definitionName);
|
|
77
99
|
if (source == null) {
|
|
78
|
-
throw new Error(`Failed to find global bucket ${bucket}`);
|
|
100
|
+
throw new Error(`Failed to find global bucket ${bucket}. Available: ${availableSources.map((s) => s.uniqueName).join(',')}`);
|
|
79
101
|
}
|
|
80
102
|
const bucketName = hydrationState.getBucketSourceScope(source).bucketPrefix + parameters;
|
|
81
103
|
return {
|
|
@@ -95,6 +117,17 @@ export function getBatchMeta(batch) {
|
|
|
95
117
|
next_after: first.next_after
|
|
96
118
|
};
|
|
97
119
|
}
|
|
120
|
+
export async function getBatchArray(data) {
|
|
121
|
+
const array = await fromAsync(data);
|
|
122
|
+
return array.filter((c) => !isBatchEnd(c) && c.chunkData.data.length > 0);
|
|
123
|
+
}
|
|
124
|
+
export async function getSingleBatchItem(data) {
|
|
125
|
+
const array = await getBatchArray(data);
|
|
126
|
+
if (array.length != 1) {
|
|
127
|
+
throw new Error(`Expected a single batch item, got ${array.length}`);
|
|
128
|
+
}
|
|
129
|
+
return array[0];
|
|
130
|
+
}
|
|
98
131
|
function getFirst(batch) {
|
|
99
132
|
if (!Array.isArray(batch)) {
|
|
100
133
|
return batch.chunkData;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general-utils.js","sourceRoot":"","sources":["../../src/test-utils/general-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmC,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"general-utils.js","sourceRoot":"","sources":["../../src/test-utils/general-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { TestStorageConfig, TestStorageFactory } from '@powersync/service-core';
|
|
2
|
+
import { TestOptions } from 'vitest';
|
|
3
|
+
export interface StorageVersionTestContext {
|
|
4
|
+
factory: TestStorageFactory;
|
|
5
|
+
storageVersion: number;
|
|
6
|
+
}
|
|
7
|
+
export interface StorageCombinationTestConfig {
|
|
8
|
+
mongodb?: TestStorageConfig;
|
|
9
|
+
postgres?: TestStorageConfig;
|
|
10
|
+
}
|
|
11
|
+
export declare function describeStorageCombinations(config: StorageCombinationTestConfig, options: TestOptions & {
|
|
12
|
+
storageVersions?: number[];
|
|
13
|
+
}, fn: (context: StorageVersionTestContext) => void): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { STORAGE_VERSION_1, STORAGE_VERSION_2, STORAGE_VERSION_4 } from '@powersync/service-core';
|
|
2
|
+
import { describe } from 'vitest';
|
|
3
|
+
const MONGO_STORAGE_VERSIONS = [STORAGE_VERSION_1, STORAGE_VERSION_2, STORAGE_VERSION_4];
|
|
4
|
+
const POSTGRES_STORAGE_VERSIONS = [STORAGE_VERSION_1, STORAGE_VERSION_2];
|
|
5
|
+
export function describeStorageCombinations(config, options, fn) {
|
|
6
|
+
const describeFactory = (storageName, storage, supportedStorageVersions) => {
|
|
7
|
+
const storageVersions = (options.storageVersions ?? supportedStorageVersions).filter((version) => supportedStorageVersions.includes(version));
|
|
8
|
+
describe(`${storageName} storage`, options, function () {
|
|
9
|
+
for (const storageVersion of storageVersions) {
|
|
10
|
+
describe(`storage v${storageVersion}`, function () {
|
|
11
|
+
fn({
|
|
12
|
+
factory: storage.factory,
|
|
13
|
+
storageVersion
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
if (config.mongodb) {
|
|
20
|
+
describeFactory('mongodb', config.mongodb, MONGO_STORAGE_VERSIONS);
|
|
21
|
+
}
|
|
22
|
+
if (config.postgres) {
|
|
23
|
+
describeFactory('postgres', config.postgres, POSTGRES_STORAGE_VERSIONS);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=storage-combinations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-combinations.js","sourceRoot":"","sources":["../../src/test-utils/storage-combinations.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,EAGlB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAe,MAAM,QAAQ,CAAC;AAE/C,MAAM,sBAAsB,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AACzF,MAAM,yBAAyB,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;AAYzE,MAAM,UAAU,2BAA2B,CACzC,MAAoC,EACpC,OAAqD,EACrD,EAAgD;IAEhD,MAAM,eAAe,GAAG,CAAC,WAAmB,EAAE,OAA0B,EAAE,wBAAkC,EAAE,EAAE;QAC9G,MAAM,eAAe,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,wBAAwB,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAC/F,wBAAwB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAC3C,CAAC;QACF,QAAQ,CAAC,GAAG,WAAW,UAAU,EAAE,OAAO,EAAE;YAC1C,KAAK,MAAM,cAAc,IAAI,eAAe,EAAE,CAAC;gBAC7C,QAAQ,CAAC,YAAY,cAAc,EAAE,EAAE;oBACrC,EAAE,CAAC;wBACD,OAAO,EAAE,OAAO,CAAC,OAAO;wBACxB,cAAc;qBACf,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACpB,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,yBAAyB,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC"}
|