@powersync/service-core 0.0.0-dev-20241007145127 → 0.0.0-dev-20241015084348
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 +9 -5
- package/dist/api/diagnostics.js +167 -105
- package/dist/api/diagnostics.js.map +1 -1
- package/dist/entry/commands/compact-action.js +73 -9
- package/dist/entry/commands/compact-action.js.map +1 -1
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.d.ts +3 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js +31 -0
- package/dist/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.js.map +1 -0
- package/dist/replication/AbstractReplicationJob.d.ts +1 -1
- package/dist/replication/AbstractReplicationJob.js.map +1 -1
- package/dist/replication/AbstractReplicator.d.ts +2 -2
- package/dist/replication/AbstractReplicator.js +66 -3
- package/dist/replication/AbstractReplicator.js.map +1 -1
- package/dist/replication/ReplicationEngine.js.map +1 -1
- package/dist/replication/replication-index.d.ts +1 -1
- package/dist/replication/replication-index.js +1 -1
- package/dist/replication/replication-index.js.map +1 -1
- package/dist/routes/endpoints/checkpointing.js +5 -2
- package/dist/routes/endpoints/checkpointing.js.map +1 -1
- package/dist/runner/teardown.js +66 -4
- package/dist/runner/teardown.js.map +1 -1
- package/dist/storage/BucketStorage.d.ts +25 -7
- package/dist/storage/BucketStorage.js.map +1 -1
- package/dist/storage/MongoBucketStorage.d.ts +12 -5
- package/dist/storage/MongoBucketStorage.js +44 -23
- package/dist/storage/MongoBucketStorage.js.map +1 -1
- package/dist/storage/ReplicationEventPayload.d.ts +14 -0
- package/dist/storage/ReplicationEventPayload.js +2 -0
- package/dist/storage/ReplicationEventPayload.js.map +1 -0
- package/dist/storage/SourceTable.d.ts +8 -0
- package/dist/storage/SourceTable.js +9 -1
- package/dist/storage/SourceTable.js.map +1 -1
- package/dist/storage/StorageEngine.d.ts +10 -2
- package/dist/storage/StorageEngine.js +23 -3
- package/dist/storage/StorageEngine.js.map +1 -1
- package/dist/storage/StorageProvider.d.ts +9 -2
- package/dist/storage/mongo/MongoBucketBatch.d.ts +12 -4
- package/dist/storage/mongo/MongoBucketBatch.js +59 -21
- package/dist/storage/mongo/MongoBucketBatch.js.map +1 -1
- package/dist/storage/mongo/MongoStorageProvider.d.ts +1 -1
- package/dist/storage/mongo/MongoStorageProvider.js +3 -2
- package/dist/storage/mongo/MongoStorageProvider.js.map +1 -1
- package/dist/storage/mongo/MongoSyncBucketStorage.d.ts +3 -2
- package/dist/storage/mongo/MongoSyncBucketStorage.js +71 -10
- package/dist/storage/mongo/MongoSyncBucketStorage.js.map +1 -1
- package/dist/storage/mongo/MongoWriteCheckpointAPI.d.ts +18 -0
- package/dist/storage/mongo/MongoWriteCheckpointAPI.js +90 -0
- package/dist/storage/mongo/MongoWriteCheckpointAPI.js.map +1 -0
- package/dist/storage/mongo/db.d.ts +3 -2
- package/dist/storage/mongo/db.js +1 -0
- package/dist/storage/mongo/db.js.map +1 -1
- package/dist/storage/mongo/models.d.ts +7 -1
- package/dist/storage/storage-index.d.ts +2 -0
- package/dist/storage/storage-index.js +2 -0
- package/dist/storage/storage-index.js.map +1 -1
- package/dist/storage/write-checkpoint.d.ts +55 -0
- package/dist/storage/write-checkpoint.js +16 -0
- package/dist/storage/write-checkpoint.js.map +1 -0
- package/dist/util/config/compound-config-collector.js +2 -1
- package/dist/util/config/compound-config-collector.js.map +1 -1
- package/dist/util/config/types.d.ts +1 -0
- package/package.json +5 -5
- package/src/api/diagnostics.ts +1 -1
- package/src/entry/commands/compact-action.ts +4 -2
- package/src/migrations/db/migrations/1727099539247-custom-write-checkpoint-index.ts +37 -0
- package/src/replication/AbstractReplicationJob.ts +2 -2
- package/src/replication/AbstractReplicator.ts +5 -4
- package/src/replication/ReplicationEngine.ts +1 -1
- package/src/replication/replication-index.ts +1 -1
- package/src/routes/endpoints/checkpointing.ts +5 -2
- package/src/runner/teardown.ts +3 -3
- package/src/storage/BucketStorage.ts +32 -9
- package/src/storage/MongoBucketStorage.ts +70 -29
- package/src/storage/ReplicationEventPayload.ts +16 -0
- package/src/storage/SourceTable.ts +10 -1
- package/src/storage/StorageEngine.ts +34 -5
- package/src/storage/StorageProvider.ts +10 -2
- package/src/storage/mongo/MongoBucketBatch.ts +82 -27
- package/src/storage/mongo/MongoStorageProvider.ts +4 -3
- package/src/storage/mongo/MongoSyncBucketStorage.ts +17 -15
- package/src/storage/mongo/MongoWriteCheckpointAPI.ts +136 -0
- package/src/storage/mongo/db.ts +4 -1
- package/src/storage/mongo/models.ts +8 -1
- package/src/storage/storage-index.ts +2 -0
- package/src/storage/write-checkpoint.ts +67 -0
- package/src/util/config/compound-config-collector.ts +2 -1
- package/src/util/config/types.ts +1 -0
- package/test/src/data_storage.test.ts +42 -10
- package/test/src/util.ts +1 -2
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import * as framework from '@powersync/lib-services-framework';
|
|
2
|
+
import { WriteCheckpointMode } from '../write-checkpoint.js';
|
|
3
|
+
export class MongoWriteCheckpointAPI {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.db = options.db;
|
|
6
|
+
this.mode = options.mode;
|
|
7
|
+
}
|
|
8
|
+
async batchCreateCustomWriteCheckpoints(checkpoints) {
|
|
9
|
+
return batchCreateCustomWriteCheckpoints(this.db, checkpoints);
|
|
10
|
+
}
|
|
11
|
+
async createCustomWriteCheckpoint(options) {
|
|
12
|
+
if (this.mode !== WriteCheckpointMode.CUSTOM) {
|
|
13
|
+
throw new framework.errors.ValidationError(`Creating a custom Write Checkpoint when the current Write Checkpoint mode is set to "${this.mode}"`);
|
|
14
|
+
}
|
|
15
|
+
const { checkpoint, user_id, sync_rules_id } = options;
|
|
16
|
+
const doc = await this.db.custom_write_checkpoints.findOneAndUpdate({
|
|
17
|
+
user_id: user_id,
|
|
18
|
+
sync_rules_id
|
|
19
|
+
}, {
|
|
20
|
+
$set: {
|
|
21
|
+
checkpoint
|
|
22
|
+
}
|
|
23
|
+
}, { upsert: true, returnDocument: 'after' });
|
|
24
|
+
return doc.checkpoint;
|
|
25
|
+
}
|
|
26
|
+
async createManagedWriteCheckpoint(checkpoint) {
|
|
27
|
+
if (this.mode !== WriteCheckpointMode.MANAGED) {
|
|
28
|
+
throw new framework.errors.ValidationError(`Creating a managed Write Checkpoint when the current Write Checkpoint mode is set to "${this.mode}"`);
|
|
29
|
+
}
|
|
30
|
+
const { user_id, heads: lsns } = checkpoint;
|
|
31
|
+
const doc = await this.db.write_checkpoints.findOneAndUpdate({
|
|
32
|
+
user_id: user_id
|
|
33
|
+
}, {
|
|
34
|
+
$set: {
|
|
35
|
+
lsns
|
|
36
|
+
},
|
|
37
|
+
$inc: {
|
|
38
|
+
client_id: 1n
|
|
39
|
+
}
|
|
40
|
+
}, { upsert: true, returnDocument: 'after' });
|
|
41
|
+
return doc.client_id;
|
|
42
|
+
}
|
|
43
|
+
async lastWriteCheckpoint(filters) {
|
|
44
|
+
switch (this.mode) {
|
|
45
|
+
case WriteCheckpointMode.CUSTOM:
|
|
46
|
+
if (false == 'sync_rules_id' in filters) {
|
|
47
|
+
throw new framework.errors.ValidationError(`Sync rules ID is required for custom Write Checkpoint filtering`);
|
|
48
|
+
}
|
|
49
|
+
return this.lastCustomWriteCheckpoint(filters);
|
|
50
|
+
case WriteCheckpointMode.MANAGED:
|
|
51
|
+
if (false == 'heads' in filters) {
|
|
52
|
+
throw new framework.errors.ValidationError(`Replication HEAD is required for managed Write Checkpoint filtering`);
|
|
53
|
+
}
|
|
54
|
+
return this.lastManagedWriteCheckpoint(filters);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async lastCustomWriteCheckpoint(filters) {
|
|
58
|
+
const { user_id, sync_rules_id } = filters;
|
|
59
|
+
const lastWriteCheckpoint = await this.db.custom_write_checkpoints.findOne({
|
|
60
|
+
user_id,
|
|
61
|
+
sync_rules_id
|
|
62
|
+
});
|
|
63
|
+
return lastWriteCheckpoint?.checkpoint ?? null;
|
|
64
|
+
}
|
|
65
|
+
async lastManagedWriteCheckpoint(filters) {
|
|
66
|
+
const { user_id } = filters;
|
|
67
|
+
const lastWriteCheckpoint = await this.db.write_checkpoints.findOne({
|
|
68
|
+
user_id: user_id
|
|
69
|
+
});
|
|
70
|
+
return lastWriteCheckpoint?.client_id ?? null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export async function batchCreateCustomWriteCheckpoints(db, checkpoints) {
|
|
74
|
+
if (!checkpoints.length) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
await db.custom_write_checkpoints.bulkWrite(checkpoints.map((checkpointOptions) => ({
|
|
78
|
+
updateOne: {
|
|
79
|
+
filter: { user_id: checkpointOptions.user_id, sync_rules_id: checkpointOptions.sync_rules_id },
|
|
80
|
+
update: {
|
|
81
|
+
$set: {
|
|
82
|
+
checkpoint: checkpointOptions.checkpoint,
|
|
83
|
+
sync_rules_id: checkpointOptions.sync_rules_id
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
upsert: true
|
|
87
|
+
}
|
|
88
|
+
})));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=MongoWriteCheckpointAPI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MongoWriteCheckpointAPI.js","sourceRoot":"","sources":["../../../src/storage/mongo/MongoWriteCheckpointAPI.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as mongo from 'mongodb';
|
|
2
|
-
import * as locks from '../../locks/locks-index.js';
|
|
3
|
-
import { BucketDataDocument, BucketParameterDocument, CurrentDataDocument, IdSequenceDocument, InstanceDocument, SourceTableDocument, SyncRuleDocument, WriteCheckpointDocument } from './models.js';
|
|
4
2
|
import { configFile } from '@powersync/service-types';
|
|
3
|
+
import * as locks from '../../locks/locks-index.js';
|
|
4
|
+
import { BucketDataDocument, BucketParameterDocument, CurrentDataDocument, CustomWriteCheckpointDocument, IdSequenceDocument, InstanceDocument, SourceTableDocument, SyncRuleDocument, WriteCheckpointDocument } from './models.js';
|
|
5
5
|
export interface PowerSyncMongoOptions {
|
|
6
6
|
/**
|
|
7
7
|
* Optional - uses the database from the MongoClient connection URI if not specified.
|
|
@@ -16,6 +16,7 @@ export declare class PowerSyncMongo {
|
|
|
16
16
|
readonly op_id_sequence: mongo.Collection<IdSequenceDocument>;
|
|
17
17
|
readonly sync_rules: mongo.Collection<SyncRuleDocument>;
|
|
18
18
|
readonly source_tables: mongo.Collection<SourceTableDocument>;
|
|
19
|
+
readonly custom_write_checkpoints: mongo.Collection<CustomWriteCheckpointDocument>;
|
|
19
20
|
readonly write_checkpoints: mongo.Collection<WriteCheckpointDocument>;
|
|
20
21
|
readonly instance: mongo.Collection<InstanceDocument>;
|
|
21
22
|
readonly locks: mongo.Collection<locks.Lock>;
|
package/dist/storage/mongo/db.js
CHANGED
|
@@ -16,6 +16,7 @@ export class PowerSyncMongo {
|
|
|
16
16
|
this.op_id_sequence = db.collection('op_id_sequence');
|
|
17
17
|
this.sync_rules = db.collection('sync_rules');
|
|
18
18
|
this.source_tables = db.collection('source_tables');
|
|
19
|
+
this.custom_write_checkpoints = db.collection('custom_write_checkpoints');
|
|
19
20
|
this.write_checkpoints = db.collection('write_checkpoints');
|
|
20
21
|
this.instance = db.collection('instance');
|
|
21
22
|
this.locks = this.db.collection('locks');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/mongo/db.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/storage/mongo/db.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAa3C,OAAO,EAAE,wBAAwB,EAAE,MAAM,WAAW,CAAC;AASrD,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;IAezB,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,wBAAwB,GAAG,EAAE,CAAC,UAAU,CAAC,0BAA0B,CAAC,CAAC;QAC1E,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,5 +1,5 @@
|
|
|
1
|
-
import * as bson from 'bson';
|
|
2
1
|
import { SqliteJsonValue } from '@powersync/service-sync-rules';
|
|
2
|
+
import * as bson from 'bson';
|
|
3
3
|
/**
|
|
4
4
|
* Replica id uniquely identifying a row on the source database.
|
|
5
5
|
*
|
|
@@ -139,6 +139,12 @@ export interface SyncRuleDocument {
|
|
|
139
139
|
last_fatal_error: string | null;
|
|
140
140
|
content: string;
|
|
141
141
|
}
|
|
142
|
+
export interface CustomWriteCheckpointDocument {
|
|
143
|
+
_id: bson.ObjectId;
|
|
144
|
+
user_id: string;
|
|
145
|
+
checkpoint: bigint;
|
|
146
|
+
sync_rules_id: number;
|
|
147
|
+
}
|
|
142
148
|
export interface WriteCheckpointDocument {
|
|
143
149
|
_id: bson.ObjectId;
|
|
144
150
|
user_id: string;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './BucketStorage.js';
|
|
2
2
|
export * from './MongoBucketStorage.js';
|
|
3
|
+
export * from './ReplicationEventPayload.js';
|
|
3
4
|
export * from './SourceEntity.js';
|
|
4
5
|
export * from './SourceTable.js';
|
|
5
6
|
export * from './StorageEngine.js';
|
|
@@ -16,3 +17,4 @@ export * from './mongo/OperationBatch.js';
|
|
|
16
17
|
export * from './mongo/PersistedBatch.js';
|
|
17
18
|
export * from './mongo/util.js';
|
|
18
19
|
export * from './mongo/config.js';
|
|
20
|
+
export * from './write-checkpoint.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from './BucketStorage.js';
|
|
2
2
|
export * from './MongoBucketStorage.js';
|
|
3
|
+
export * from './ReplicationEventPayload.js';
|
|
3
4
|
export * from './SourceEntity.js';
|
|
4
5
|
export * from './SourceTable.js';
|
|
5
6
|
export * from './StorageEngine.js';
|
|
@@ -16,4 +17,5 @@ export * from './mongo/OperationBatch.js';
|
|
|
16
17
|
export * from './mongo/PersistedBatch.js';
|
|
17
18
|
export * from './mongo/util.js';
|
|
18
19
|
export * from './mongo/config.js';
|
|
20
|
+
export * from './write-checkpoint.js';
|
|
19
21
|
//# 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,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"storage-index.js","sourceRoot":"","sources":["../../src/storage/storage-index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC;AACxC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AAEnC,cAAc,eAAe,CAAC;AAC9B,cAAc,mBAAmB,CAAC;AAClC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,oCAAoC,CAAC;AACnD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,iCAAiC,CAAC;AAChD,cAAc,mCAAmC,CAAC;AAClD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export declare enum WriteCheckpointMode {
|
|
2
|
+
/**
|
|
3
|
+
* Raw mappings of `user_id` to `write_checkpoint`s should
|
|
4
|
+
* be supplied for each set of sync rules.
|
|
5
|
+
*/
|
|
6
|
+
CUSTOM = "manual",
|
|
7
|
+
/**
|
|
8
|
+
* Write checkpoints are stored as a mapping of `user_id` plus
|
|
9
|
+
* replication HEAD (lsn in Postgres) to an automatically generated
|
|
10
|
+
* incrementing `write_checkpoint` (stored as`client_id`).
|
|
11
|
+
*/
|
|
12
|
+
MANAGED = "managed"
|
|
13
|
+
}
|
|
14
|
+
export interface BaseWriteCheckpointIdentifier {
|
|
15
|
+
/**
|
|
16
|
+
* Identifier for User's account.
|
|
17
|
+
*/
|
|
18
|
+
user_id: string;
|
|
19
|
+
}
|
|
20
|
+
export interface CustomWriteCheckpointFilters extends BaseWriteCheckpointIdentifier {
|
|
21
|
+
/**
|
|
22
|
+
* Sync rules which were active when this checkpoint was created.
|
|
23
|
+
*/
|
|
24
|
+
sync_rules_id: number;
|
|
25
|
+
}
|
|
26
|
+
export interface CustomWriteCheckpointOptions extends CustomWriteCheckpointFilters {
|
|
27
|
+
/**
|
|
28
|
+
* A supplied incrementing Write Checkpoint number
|
|
29
|
+
*/
|
|
30
|
+
checkpoint: bigint;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Options for creating a custom Write Checkpoint in a batch.
|
|
34
|
+
* A {@link BucketStorageBatch} is already associated with a Sync Rules instance.
|
|
35
|
+
* The `sync_rules_id` is not required here.
|
|
36
|
+
*/
|
|
37
|
+
export type BatchedCustomWriteCheckpointOptions = Omit<CustomWriteCheckpointOptions, 'sync_rules_id'>;
|
|
38
|
+
/**
|
|
39
|
+
* Managed Write Checkpoints are a mapping of User ID to replication HEAD
|
|
40
|
+
*/
|
|
41
|
+
export interface ManagedWriteCheckpointFilters extends BaseWriteCheckpointIdentifier {
|
|
42
|
+
/**
|
|
43
|
+
* Replication HEAD(s) at the creation of the checkpoint.
|
|
44
|
+
*/
|
|
45
|
+
heads: Record<string, string>;
|
|
46
|
+
}
|
|
47
|
+
export type ManagedWriteCheckpointOptions = ManagedWriteCheckpointFilters;
|
|
48
|
+
export type LastWriteCheckpointFilters = CustomWriteCheckpointFilters | ManagedWriteCheckpointFilters;
|
|
49
|
+
export interface WriteCheckpointAPI {
|
|
50
|
+
batchCreateCustomWriteCheckpoints(checkpoints: CustomWriteCheckpointOptions[]): Promise<void>;
|
|
51
|
+
createCustomWriteCheckpoint(checkpoint: CustomWriteCheckpointOptions): Promise<bigint>;
|
|
52
|
+
createManagedWriteCheckpoint(checkpoint: ManagedWriteCheckpointOptions): Promise<bigint>;
|
|
53
|
+
lastWriteCheckpoint(filters: LastWriteCheckpointFilters): Promise<bigint | null>;
|
|
54
|
+
}
|
|
55
|
+
export declare const DEFAULT_WRITE_CHECKPOINT_MODE = WriteCheckpointMode.MANAGED;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export var WriteCheckpointMode;
|
|
2
|
+
(function (WriteCheckpointMode) {
|
|
3
|
+
/**
|
|
4
|
+
* Raw mappings of `user_id` to `write_checkpoint`s should
|
|
5
|
+
* be supplied for each set of sync rules.
|
|
6
|
+
*/
|
|
7
|
+
WriteCheckpointMode["CUSTOM"] = "manual";
|
|
8
|
+
/**
|
|
9
|
+
* Write checkpoints are stored as a mapping of `user_id` plus
|
|
10
|
+
* replication HEAD (lsn in Postgres) to an automatically generated
|
|
11
|
+
* incrementing `write_checkpoint` (stored as`client_id`).
|
|
12
|
+
*/
|
|
13
|
+
WriteCheckpointMode["MANAGED"] = "managed";
|
|
14
|
+
})(WriteCheckpointMode || (WriteCheckpointMode = {}));
|
|
15
|
+
export const DEFAULT_WRITE_CHECKPOINT_MODE = WriteCheckpointMode.MANAGED;
|
|
16
|
+
//# sourceMappingURL=write-checkpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-checkpoint.js","sourceRoot":"","sources":["../../src/storage/write-checkpoint.ts"],"names":[],"mappings":"AAAA,MAAM,CAAN,IAAY,mBAYX;AAZD,WAAY,mBAAmB;IAC7B;;;OAGG;IACH,wCAAiB,CAAA;IACjB;;;;OAIG;IACH,0CAAmB,CAAA;AACrB,CAAC,EAZW,mBAAmB,KAAnB,mBAAmB,QAY9B;AAsDD,MAAM,CAAC,MAAM,6BAA6B,GAAG,mBAAmB,CAAC,OAAO,CAAC"}
|
|
@@ -75,7 +75,8 @@ export class CompoundConfigCollector {
|
|
|
75
75
|
},
|
|
76
76
|
// TODO maybe move this out of the connection or something
|
|
77
77
|
// slot_name_prefix: connections[0]?.slot_name_prefix ?? 'powersync_'
|
|
78
|
-
slot_name_prefix: 'powersync_'
|
|
78
|
+
slot_name_prefix: 'powersync_',
|
|
79
|
+
parameters: baseConfig.parameters ?? {}
|
|
79
80
|
};
|
|
80
81
|
return config;
|
|
81
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compound-config-collector.js","sourceRoot":"","sources":["../../../src/util/config/compound-config-collector.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"compound-config-collector.js","sourceRoot":"","sources":["../../../src/util/config/compound-config-collector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAE3D,OAAO,KAAK,IAAI,MAAM,0BAA0B,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAC;AACrF,OAAO,EAAE,uBAAuB,EAAE,MAAM,gDAAgD,CAAC;AACzF,OAAO,EAAE,yBAAyB,EAAE,MAAM,kDAAkD,CAAC;AAC7F,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AAC5F,OAAO,EAAE,4BAA4B,EAAE,MAAM,sDAAsD,CAAC;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,kDAAkD,CAAC;AA4B5F,MAAM,iBAAiB,GAAG,eAAe,CAAC;AAE1C,MAAM,yBAAyB,GAAmC;IAChE,gBAAgB,EAAE,CAAC,IAAI,qBAAqB,EAAE,EAAE,IAAI,yBAAyB,EAAE,EAAE,IAAI,uBAAuB,EAAE,CAAC;IAC/G,mBAAmB,EAAE;QACnB,IAAI,wBAAwB,EAAE;QAC9B,IAAI,4BAA4B,EAAE;QAClC,IAAI,wBAAwB,EAAE;KAC/B;CACF,CAAC;AAEF,MAAM,OAAO,uBAAuB;IAClC,YAAsB,UAA0C,yBAAyB;QAAnE,YAAO,GAAP,OAAO,CAA4D;IAAG,CAAC;IAE7F;;OAEG;IACH,KAAK,CAAC,aAAa,CAAC,eAA6B,EAAE;QACjD,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;QAE9D,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,EAAE,WAAW,IAAI,EAAE,CAAC;QAC9D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QAClF,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAE/C,MAAM,SAAS,GAAG,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAC3D,MAAM,eAAe,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE5E,UAAU,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAEhC,IAAI,SAAS,GAAG,UAAU,CAAC,WAAW,EAAE,QAAQ,IAAI,EAAE,CAAC;QACvD,IAAI,OAAO,SAAS,IAAI,QAAQ,EAAE,CAAC;YACjC,SAAS,GAAG,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAED,KAAK,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;YAC1B,UAAU,CAAC,GAAG,CACZ,IAAI,IAAI,CAAC,kBAAkB,CACzB,IAAI,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,gBAAgB,EAAE,CAAC,CAClG,CACF,CAAC;QACJ,CAAC;QAED,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,IAAI,iBAAiB,CAAC,CAAC;QAE1G,IAAI,MAAgC,CAAC;QACrC,IAAI,UAAU,CAAC,GAAG,EAAE,SAAS,IAAI,UAAU,IAAI,IAAI,IAAI,UAAU,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;YAC/E,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QACpD,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;QAEzE,IAAI,aAAa,GAAa,UAAU,CAAC,WAAW,EAAE,QAAQ,IAAI,EAAE,CAAC;QAErE,IAAI,MAAM,GAA4B;YACpC,WAAW,EAAE,UAAU;YACvB,WAAW,EAAE,UAAU,CAAC,WAAW,EAAE,WAAW,IAAI,EAAE;YACtD,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,eAAe,EAAE,QAAQ;YACzB,+DAA+D;YAC/D,mEAAmE;YACnE,mBAAmB,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC;YACvD,UAAU,EAAE,UAAU,CAAC,GAAG,EAAE,MAAM,IAAI,EAAE;YACxC,GAAG,EAAE;gBACH,SAAS,EAAE,UAAU,CAAC,GAAG,EAAE,SAAS,IAAI,KAAK;gBAC7C,WAAW,EAAE,UAAU,CAAC,GAAG,EAAE,WAAW,IAAI,KAAK;gBACjD,aAAa,EAAE,UAAU,CAAC,GAAG,EAAE,aAAa;gBAC5C,QAAQ,EAAE,UAAU,CAAC,GAAG,EAAE,QAAQ,IAAI,KAAK;gBAC3C,OAAO,EAAE,MAAM;aAChB;YACD,IAAI,EAAE,UAAU,CAAC,IAAI,IAAI,IAAI;YAC7B,UAAU;YACV,aAAa;YAEb,oBAAoB,EAAE,IAAI,EAAE,QAAQ;YACpC,QAAQ,EAAE,UAAU,CAAC,QAAQ,IAAI,EAAE;YACnC,UAAU,EAAE,UAAU,CAAC,UAAU;YACjC,SAAS,EAAE;gBACT,yBAAyB,EAAE,UAAU,CAAC,SAAS,EAAE,yBAAyB,IAAI,KAAK;gBACnF,yBAAyB,EACvB,UAAU,CAAC,SAAS,EAAE,yBAAyB,IAAI,0CAA0C;aAChG;YACD,0DAA0D;YAC1D,qEAAqE;YACrE,gBAAgB,EAAE,YAAY;YAC9B,UAAU,EAAE,UAAU,CAAC,UAAU,IAAI,EAAE;SACxC,CAAC;QAEF,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;OAGG;IACO,KAAK,CAAC,iBAAiB,CAAC,aAA2B;QAC3D,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,CAAC;YACtD,IAAI,CAAC;gBACH,MAAM,UAAU,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;gBAC1D,IAAI,UAAU,EAAE,CAAC;oBACf,OAAO,UAAU,CAAC;gBACpB,CAAC;gBACD,MAAM,CAAC,KAAK,CACV,2CAA2C,SAAS,CAAC,IAAI,iDAAiD,CAC3G,CAAC;YACJ,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,yCAAyC;gBACzC,MAAM,IAAI,KAAK,CAAC,kCAAkC,SAAS,CAAC,IAAI,8BAA8B,EAAE,EAAE,CAAC,CAAC;YACtG,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,uFAAuF,CAAC,CAAC;IAC3G,CAAC;IAES,KAAK,CAAC,gBAAgB,CAC9B,UAAsC,EACtC,YAA0B;QAE1B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,CAAC;YACzD,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,OAAO,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;gBACjE,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,MAAM,CAAC;gBAChB,CAAC;gBACD,MAAM,CAAC,KAAK,CACV,qCAAqC,SAAS,CAAC,IAAI,iDAAiD,CACrG,CAAC;YACJ,CAAC;YAAC,OAAO,EAAE,EAAE,CAAC;gBACZ,yCAAyC;gBACzC,MAAM,IAAI,KAAK,CAAC,sCAAsC,SAAS,CAAC,IAAI,8BAA8B,EAAE,EAAE,CAAC,CAAC;YAC1G,CAAC;QACH,CAAC;QACD,OAAO;YACL,OAAO,EAAE,KAAK;SACf,CAAC;IACJ,CAAC;CACF"}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"version": "0.0.0-dev-
|
|
8
|
+
"version": "0.0.0-dev-20241015084348",
|
|
9
9
|
"main": "dist/index.js",
|
|
10
10
|
"license": "FSL-1.1-Apache-2.0",
|
|
11
11
|
"type": "module",
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
"uuid": "^9.0.1",
|
|
34
34
|
"winston": "^3.13.0",
|
|
35
35
|
"yaml": "^2.3.2",
|
|
36
|
-
"@powersync/lib-services-framework": "0.0.0-dev-
|
|
36
|
+
"@powersync/lib-services-framework": "0.0.0-dev-20241015084348",
|
|
37
37
|
"@powersync/service-jsonbig": "0.17.10",
|
|
38
|
-
"@powersync/service-rsocket-router": "0.0.0-dev-
|
|
39
|
-
"@powersync/service-sync-rules": "0.0.0-dev-
|
|
40
|
-
"@powersync/service-types": "0.0.0-dev-
|
|
38
|
+
"@powersync/service-rsocket-router": "0.0.0-dev-20241015084348",
|
|
39
|
+
"@powersync/service-sync-rules": "0.0.0-dev-20241015084348",
|
|
40
|
+
"@powersync/service-types": "0.0.0-dev-20241015084348"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/async": "^3.2.24",
|
package/src/api/diagnostics.ts
CHANGED
|
@@ -57,7 +57,7 @@ export async function getSyncRulesStatus(
|
|
|
57
57
|
// This method can run under some situations if no connection is configured yet.
|
|
58
58
|
// It will return a default tag in such a case. This default tag is not module specific.
|
|
59
59
|
const tag = sourceConfig.tag ?? DEFAULT_TAG;
|
|
60
|
-
|
|
60
|
+
using systemStorage = live_status ? bucketStorage.getInstance(sync_rules) : undefined;
|
|
61
61
|
const status = await systemStorage?.getStatus();
|
|
62
62
|
let replication_lag_bytes: number | undefined = undefined;
|
|
63
63
|
|
|
@@ -36,13 +36,15 @@ export function registerCompactAction(program: Command) {
|
|
|
36
36
|
const client = psdb.client;
|
|
37
37
|
await client.connect();
|
|
38
38
|
try {
|
|
39
|
-
const bucketStorage = new storage.MongoBucketStorage(psdb, {
|
|
39
|
+
const bucketStorage = new storage.MongoBucketStorage(psdb, {
|
|
40
|
+
slot_name_prefix: configuration.slot_name_prefix
|
|
41
|
+
});
|
|
40
42
|
const active = await bucketStorage.getActiveSyncRulesContent();
|
|
41
43
|
if (active == null) {
|
|
42
44
|
logger.info('No active instance to compact');
|
|
43
45
|
return;
|
|
44
46
|
}
|
|
45
|
-
|
|
47
|
+
using p = bucketStorage.getInstance(active);
|
|
46
48
|
logger.info('Performing compaction...');
|
|
47
49
|
await p.compact({ memoryLimitMB: COMPACT_MEMORY_LIMIT_MB });
|
|
48
50
|
logger.info('Successfully compacted storage.');
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as storage from '../../../storage/storage-index.js';
|
|
2
|
+
import * as utils from '../../../util/util-index.js';
|
|
3
|
+
|
|
4
|
+
const INDEX_NAME = 'user_sync_rule_unique';
|
|
5
|
+
|
|
6
|
+
export const up = async (context: utils.MigrationContext) => {
|
|
7
|
+
const { runner_config } = context;
|
|
8
|
+
const config = await utils.loadConfig(runner_config);
|
|
9
|
+
const db = storage.createPowerSyncMongo(config.storage);
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
await db.custom_write_checkpoints.createIndex(
|
|
13
|
+
{
|
|
14
|
+
user_id: 1,
|
|
15
|
+
sync_rules_id: 1
|
|
16
|
+
},
|
|
17
|
+
{ name: INDEX_NAME, unique: true }
|
|
18
|
+
);
|
|
19
|
+
} finally {
|
|
20
|
+
await db.client.close();
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const down = async (context: utils.MigrationContext) => {
|
|
25
|
+
const { runner_config } = context;
|
|
26
|
+
const config = await utils.loadConfig(runner_config);
|
|
27
|
+
|
|
28
|
+
const db = storage.createPowerSyncMongo(config.storage);
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
if (await db.custom_write_checkpoints.indexExists(INDEX_NAME)) {
|
|
32
|
+
await db.custom_write_checkpoints.dropIndex(INDEX_NAME);
|
|
33
|
+
}
|
|
34
|
+
} finally {
|
|
35
|
+
await db.client.close();
|
|
36
|
+
}
|
|
37
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as storage from '../storage/storage-index.js';
|
|
2
|
-
import { ErrorRateLimiter } from './ErrorRateLimiter.js';
|
|
3
1
|
import { container, logger } from '@powersync/lib-services-framework';
|
|
4
2
|
import winston from 'winston';
|
|
3
|
+
import * as storage from '../storage/storage-index.js';
|
|
4
|
+
import { ErrorRateLimiter } from './ErrorRateLimiter.js';
|
|
5
5
|
|
|
6
6
|
export interface AbstractReplicationJobOptions {
|
|
7
7
|
id: string;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { container, logger } from '@powersync/lib-services-framework';
|
|
1
2
|
import { hrtime } from 'node:process';
|
|
3
|
+
import winston from 'winston';
|
|
2
4
|
import * as storage from '../storage/storage-index.js';
|
|
3
|
-
import {
|
|
5
|
+
import { StorageEngine } from '../storage/storage-index.js';
|
|
4
6
|
import { SyncRulesProvider } from '../util/config/sync-rules/sync-rules-provider.js';
|
|
5
|
-
import winston from 'winston';
|
|
6
7
|
import { AbstractReplicationJob } from './AbstractReplicationJob.js';
|
|
7
|
-
import { StorageEngine } from '../storage/storage-index.js';
|
|
8
8
|
import { ErrorRateLimiter } from './ErrorRateLimiter.js';
|
|
9
9
|
|
|
10
10
|
// 5 minutes
|
|
@@ -192,6 +192,7 @@ export abstract class AbstractReplicator<T extends AbstractReplicationJob = Abst
|
|
|
192
192
|
try {
|
|
193
193
|
await job.stop();
|
|
194
194
|
await this.terminateSyncRules(job.storage);
|
|
195
|
+
job.storage[Symbol.dispose]();
|
|
195
196
|
} catch (e) {
|
|
196
197
|
// This will be retried
|
|
197
198
|
this.logger.warn('Failed to terminate old replication job}', e);
|
|
@@ -202,7 +203,7 @@ export abstract class AbstractReplicator<T extends AbstractReplicationJob = Abst
|
|
|
202
203
|
const stopped = await this.storage.getStoppedSyncRules();
|
|
203
204
|
for (let syncRules of stopped) {
|
|
204
205
|
try {
|
|
205
|
-
|
|
206
|
+
using syncRuleStorage = this.storage.getInstance(syncRules);
|
|
206
207
|
await this.terminateSyncRules(syncRuleStorage);
|
|
207
208
|
} catch (e) {
|
|
208
209
|
this.logger.warn(`Failed clean up replication config for sync rule: ${syncRules.id}`, e);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AbstractReplicator } from './AbstractReplicator.js';
|
|
2
1
|
import { logger } from '@powersync/lib-services-framework';
|
|
2
|
+
import { AbstractReplicator } from './AbstractReplicator.js';
|
|
3
3
|
|
|
4
4
|
export class ReplicationEngine {
|
|
5
5
|
private readonly replicators: Map<string, AbstractReplicator> = new Map();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as t from 'ts-codec';
|
|
2
1
|
import { logger, router, schema } from '@powersync/lib-services-framework';
|
|
2
|
+
import * as t from 'ts-codec';
|
|
3
3
|
|
|
4
4
|
import * as util from '../../util/util-index.js';
|
|
5
5
|
import { authUser } from '../auth.js';
|
|
@@ -63,7 +63,10 @@ export const writeCheckpoint2 = routeDefinition({
|
|
|
63
63
|
storageEngine: { activeBucketStorage }
|
|
64
64
|
} = service_context;
|
|
65
65
|
|
|
66
|
-
const writeCheckpoint = await activeBucketStorage.
|
|
66
|
+
const writeCheckpoint = await activeBucketStorage.createManagedWriteCheckpoint({
|
|
67
|
+
user_id: full_user_id,
|
|
68
|
+
heads: { '1': currentCheckpoint }
|
|
69
|
+
});
|
|
67
70
|
logger.info(`Write checkpoint 2: ${JSON.stringify({ currentCheckpoint, id: String(full_user_id) })}`);
|
|
68
71
|
|
|
69
72
|
return {
|
package/src/runner/teardown.ts
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
// 2. Delete the storage
|
|
5
5
|
|
|
6
6
|
import { container, logger } from '@powersync/lib-services-framework';
|
|
7
|
+
import timers from 'timers/promises';
|
|
7
8
|
import * as modules from '../modules/modules-index.js';
|
|
8
|
-
import * as system from '../system/system-index.js';
|
|
9
9
|
import * as storage from '../storage/storage-index.js';
|
|
10
|
+
import * as system from '../system/system-index.js';
|
|
10
11
|
import * as utils from '../util/util-index.js';
|
|
11
|
-
import timers from 'timers/promises';
|
|
12
12
|
|
|
13
13
|
export async function teardown(runnerConfig: utils.RunnerConfig) {
|
|
14
14
|
try {
|
|
@@ -51,7 +51,7 @@ async function terminateSyncRules(storageFactory: storage.BucketStorageFactory,
|
|
|
51
51
|
|
|
52
52
|
// Mark the sync rules as terminated
|
|
53
53
|
for (let syncRules of combinedSyncRules) {
|
|
54
|
-
|
|
54
|
+
using syncRulesStorage = storageFactory.getInstance(syncRules);
|
|
55
55
|
// The storage will be dropped at the end of the teardown, so we don't need to clear it here
|
|
56
56
|
await syncRulesStorage.terminate({ clearStorage: false });
|
|
57
57
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DisposableListener, DisposableObserverClient } from '@powersync/lib-services-framework';
|
|
1
2
|
import {
|
|
2
3
|
EvaluatedParameters,
|
|
3
4
|
EvaluatedRow,
|
|
@@ -8,11 +9,19 @@ import {
|
|
|
8
9
|
ToastableSqliteRow
|
|
9
10
|
} from '@powersync/service-sync-rules';
|
|
10
11
|
import * as util from '../util/util-index.js';
|
|
11
|
-
import {
|
|
12
|
+
import { ReplicationEventPayload } from './ReplicationEventPayload.js';
|
|
12
13
|
import { SourceEntityDescriptor } from './SourceEntity.js';
|
|
13
|
-
import {
|
|
14
|
+
import { SourceTable } from './SourceTable.js';
|
|
15
|
+
import { BatchedCustomWriteCheckpointOptions, ReplicaId, WriteCheckpointAPI } from './storage-index.js';
|
|
16
|
+
|
|
17
|
+
export interface BucketStorageFactoryListener extends DisposableListener {
|
|
18
|
+
syncStorageCreated: (storage: SyncRulesBucketStorage) => void;
|
|
19
|
+
replicationEvent: (event: ReplicationEventPayload) => void;
|
|
20
|
+
}
|
|
14
21
|
|
|
15
|
-
export interface BucketStorageFactory
|
|
22
|
+
export interface BucketStorageFactory
|
|
23
|
+
extends DisposableObserverClient<BucketStorageFactoryListener>,
|
|
24
|
+
WriteCheckpointAPI {
|
|
16
25
|
/**
|
|
17
26
|
* Update sync rules from configuration, if changed.
|
|
18
27
|
*/
|
|
@@ -81,10 +90,9 @@ export interface BucketStorageFactory {
|
|
|
81
90
|
*/
|
|
82
91
|
getActiveCheckpoint(): Promise<ActiveCheckpoint>;
|
|
83
92
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Yields the latest user write checkpoint whenever the sync checkpoint updates.
|
|
95
|
+
*/
|
|
88
96
|
watchWriteCheckpoint(user_id: string, signal: AbortSignal): AsyncIterable<WriteCheckpoint>;
|
|
89
97
|
|
|
90
98
|
/**
|
|
@@ -194,7 +202,11 @@ export interface StartBatchOptions extends ParseSyncRulesOptions {
|
|
|
194
202
|
zeroLSN: string;
|
|
195
203
|
}
|
|
196
204
|
|
|
197
|
-
export interface
|
|
205
|
+
export interface SyncRulesBucketStorageListener extends DisposableListener {
|
|
206
|
+
batchStarted: (batch: BucketStorageBatch) => void;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export interface SyncRulesBucketStorage extends DisposableObserverClient<SyncRulesBucketStorageListener> {
|
|
198
210
|
readonly group_id: number;
|
|
199
211
|
readonly slot_name: string;
|
|
200
212
|
|
|
@@ -293,7 +305,11 @@ export interface FlushedResult {
|
|
|
293
305
|
flushed_op: string;
|
|
294
306
|
}
|
|
295
307
|
|
|
296
|
-
export interface
|
|
308
|
+
export interface BucketBatchStorageListener extends DisposableListener {
|
|
309
|
+
replicationEvent: (payload: ReplicationEventPayload) => void;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export interface BucketStorageBatch extends DisposableObserverClient<BucketBatchStorageListener> {
|
|
297
313
|
/**
|
|
298
314
|
* Save an op, and potentially flush.
|
|
299
315
|
*
|
|
@@ -345,6 +361,11 @@ export interface BucketStorageBatch {
|
|
|
345
361
|
lastCheckpointLsn: string | null;
|
|
346
362
|
|
|
347
363
|
markSnapshotDone(tables: SourceTable[], no_checkpoint_before_lsn: string): Promise<SourceTable[]>;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Queues the creation of a custom Write Checkpoint. This will be persisted after operations are flushed.
|
|
367
|
+
*/
|
|
368
|
+
addCustomWriteCheckpoint(checkpoint: BatchedCustomWriteCheckpointOptions): void;
|
|
348
369
|
}
|
|
349
370
|
|
|
350
371
|
export interface SaveParameterData {
|
|
@@ -362,6 +383,8 @@ export interface SaveBucketData {
|
|
|
362
383
|
evaluated: EvaluatedRow[];
|
|
363
384
|
}
|
|
364
385
|
|
|
386
|
+
export type SaveOp = 'insert' | 'update' | 'delete';
|
|
387
|
+
|
|
365
388
|
export type SaveOptions = SaveInsert | SaveUpdate | SaveDelete;
|
|
366
389
|
|
|
367
390
|
export interface SaveInsert {
|