@powersync/common 0.0.0-dev-20250922104723 → 0.0.0-dev-20250922105207
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/dist/bundle.cjs +4 -4
- package/dist/bundle.mjs +5 -5
- package/dist/index.d.cts +845 -1054
- package/lib/client/AbstractPowerSyncDatabase.d.ts +4 -16
- package/lib/client/AbstractPowerSyncDatabase.js +26 -36
- package/lib/client/ConnectionManager.d.ts +2 -26
- package/lib/client/ConnectionManager.js +2 -114
- package/lib/client/SQLOpenFactory.d.ts +2 -0
- package/lib/client/sync/bucket/BucketStorageAdapter.d.ts +1 -9
- package/lib/client/sync/bucket/BucketStorageAdapter.js +0 -1
- package/lib/client/sync/stream/AbstractRemote.js +0 -3
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +3 -24
- package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +39 -54
- package/lib/client/sync/stream/core-instruction.d.ts +1 -20
- package/lib/client/sync/stream/core-instruction.js +1 -26
- package/lib/client/triggers/TriggerManager.d.ts +1 -1
- package/lib/client/watched/WatchedQuery.d.ts +0 -2
- package/lib/client/watched/WatchedQuery.js +0 -1
- package/lib/client/watched/processors/AbstractQueryProcessor.d.ts +1 -2
- package/lib/client/watched/processors/AbstractQueryProcessor.js +15 -30
- package/lib/client/watched/processors/DifferentialQueryProcessor.js +1 -7
- package/lib/client/watched/processors/OnChangeQueryProcessor.js +1 -7
- package/lib/db/crud/SyncStatus.d.ts +1 -37
- package/lib/db/crud/SyncStatus.js +0 -61
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -1
- package/package.json +1 -1
- package/lib/client/sync/sync-streams.d.ts +0 -98
- package/lib/client/sync/sync-streams.js +0 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Logger from 'js-logger';
|
|
2
|
+
import { FULL_SYNC_PRIORITY } from '../../../db/crud/SyncProgress.js';
|
|
2
3
|
import { SyncStatus } from '../../../db/crud/SyncStatus.js';
|
|
3
4
|
import { AbortOperation } from '../../../utils/AbortOperation.js';
|
|
4
5
|
import { BaseObserver } from '../../../utils/BaseObserver.js';
|
|
@@ -6,7 +7,6 @@ import { throttleLeadingTrailing } from '../../../utils/async.js';
|
|
|
6
7
|
import { PowerSyncControlCommand } from '../bucket/BucketStorageAdapter.js';
|
|
7
8
|
import { SyncDataBucket } from '../bucket/SyncDataBucket.js';
|
|
8
9
|
import { FetchStrategy } from './AbstractRemote.js';
|
|
9
|
-
import { coreStatusToJs } from './core-instruction.js';
|
|
10
10
|
import { isStreamingKeepalive, isStreamingSyncCheckpoint, isStreamingSyncCheckpointComplete, isStreamingSyncCheckpointDiff, isStreamingSyncCheckpointPartiallyComplete, isStreamingSyncData } from './streaming-sync-types.js';
|
|
11
11
|
export var LockType;
|
|
12
12
|
(function (LockType) {
|
|
@@ -72,8 +72,7 @@ export const DEFAULT_STREAM_CONNECTION_OPTIONS = {
|
|
|
72
72
|
clientImplementation: DEFAULT_SYNC_CLIENT_IMPLEMENTATION,
|
|
73
73
|
fetchStrategy: FetchStrategy.Buffered,
|
|
74
74
|
params: {},
|
|
75
|
-
serializedSchema: undefined
|
|
76
|
-
includeDefaultStreams: true
|
|
75
|
+
serializedSchema: undefined
|
|
77
76
|
};
|
|
78
77
|
// The priority we assume when we receive checkpoint lines where no priority is set.
|
|
79
78
|
// This is the default priority used by the sync service, but can be set to an arbitrary
|
|
@@ -90,16 +89,13 @@ export class AbstractStreamingSyncImplementation extends BaseObserver {
|
|
|
90
89
|
crudUpdateListener;
|
|
91
90
|
streamingSyncPromise;
|
|
92
91
|
logger;
|
|
93
|
-
activeStreams;
|
|
94
92
|
isUploadingCrud = false;
|
|
95
93
|
notifyCompletedUploads;
|
|
96
|
-
handleActiveStreamsChange;
|
|
97
94
|
syncStatus;
|
|
98
95
|
triggerCrudUpload;
|
|
99
96
|
constructor(options) {
|
|
100
97
|
super();
|
|
101
|
-
this.options = options;
|
|
102
|
-
this.activeStreams = options.subscriptions;
|
|
98
|
+
this.options = { ...DEFAULT_STREAMING_SYNC_OPTIONS, ...options };
|
|
103
99
|
this.logger = options.logger ?? Logger.get('PowerSyncStream');
|
|
104
100
|
this.syncStatus = new SyncStatus({
|
|
105
101
|
connected: false,
|
|
@@ -347,12 +343,11 @@ The next upload iteration will be delayed.`);
|
|
|
347
343
|
while (true) {
|
|
348
344
|
this.updateSyncStatus({ connecting: true });
|
|
349
345
|
let shouldDelayRetry = true;
|
|
350
|
-
let result = null;
|
|
351
346
|
try {
|
|
352
347
|
if (signal?.aborted) {
|
|
353
348
|
break;
|
|
354
349
|
}
|
|
355
|
-
|
|
350
|
+
await this.streamingSyncIteration(nestedAbortController.signal, options);
|
|
356
351
|
// Continue immediately, streamingSyncIteration will wait before completing if necessary.
|
|
357
352
|
}
|
|
358
353
|
catch (ex) {
|
|
@@ -385,15 +380,13 @@ The next upload iteration will be delayed.`);
|
|
|
385
380
|
nestedAbortController.abort(new AbortOperation('Closing sync stream network requests before retry.'));
|
|
386
381
|
nestedAbortController = new AbortController();
|
|
387
382
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
await this.delayRetry(nestedAbortController.signal);
|
|
396
|
-
}
|
|
383
|
+
this.updateSyncStatus({
|
|
384
|
+
connected: false,
|
|
385
|
+
connecting: true // May be unnecessary
|
|
386
|
+
});
|
|
387
|
+
// On error, wait a little before retrying
|
|
388
|
+
if (shouldDelayRetry) {
|
|
389
|
+
await this.delayRetry(nestedAbortController.signal);
|
|
397
390
|
}
|
|
398
391
|
}
|
|
399
392
|
}
|
|
@@ -437,8 +430,8 @@ The next upload iteration will be delayed.`);
|
|
|
437
430
|
return hasMigrated;
|
|
438
431
|
}
|
|
439
432
|
}
|
|
440
|
-
streamingSyncIteration(signal, options) {
|
|
441
|
-
|
|
433
|
+
async streamingSyncIteration(signal, options) {
|
|
434
|
+
await this.obtainLock({
|
|
442
435
|
type: LockType.SYNC,
|
|
443
436
|
signal,
|
|
444
437
|
callback: async () => {
|
|
@@ -446,15 +439,12 @@ The next upload iteration will be delayed.`);
|
|
|
446
439
|
...DEFAULT_STREAM_CONNECTION_OPTIONS,
|
|
447
440
|
...(options ?? {})
|
|
448
441
|
};
|
|
449
|
-
|
|
450
|
-
this.updateSyncStatus({ clientImplementation });
|
|
451
|
-
if (clientImplementation == SyncClientImplementation.JAVASCRIPT) {
|
|
442
|
+
if (resolvedOptions.clientImplementation == SyncClientImplementation.JAVASCRIPT) {
|
|
452
443
|
await this.legacyStreamingSyncIteration(signal, resolvedOptions);
|
|
453
|
-
return null;
|
|
454
444
|
}
|
|
455
445
|
else {
|
|
456
446
|
await this.requireKeyFormat(true);
|
|
457
|
-
|
|
447
|
+
await this.rustSyncIteration(signal, resolvedOptions);
|
|
458
448
|
}
|
|
459
449
|
}
|
|
460
450
|
});
|
|
@@ -703,10 +693,6 @@ The next upload iteration will be delayed.`);
|
|
|
703
693
|
const remote = this.options.remote;
|
|
704
694
|
let receivingLines = null;
|
|
705
695
|
let hadSyncLine = false;
|
|
706
|
-
let hideDisconnectOnRestart = false;
|
|
707
|
-
if (signal.aborted) {
|
|
708
|
-
throw new AbortOperation('Connection request has been aborted');
|
|
709
|
-
}
|
|
710
696
|
const abortController = new AbortController();
|
|
711
697
|
signal.addEventListener('abort', () => abortController.abort());
|
|
712
698
|
// Pending sync lines received from the service, as well as local events that trigger a powersync_control
|
|
@@ -780,8 +766,6 @@ The next upload iteration will be delayed.`);
|
|
|
780
766
|
}
|
|
781
767
|
async function control(op, payload) {
|
|
782
768
|
const rawResponse = await adapter.control(op, payload ?? null);
|
|
783
|
-
const logger = syncImplementation.logger;
|
|
784
|
-
logger.trace('powersync_control', op, payload == null || typeof payload == 'string' ? payload : '<bytes>', rawResponse);
|
|
785
769
|
await handleInstructions(JSON.parse(rawResponse));
|
|
786
770
|
}
|
|
787
771
|
async function handleInstruction(instruction) {
|
|
@@ -799,7 +783,27 @@ The next upload iteration will be delayed.`);
|
|
|
799
783
|
}
|
|
800
784
|
}
|
|
801
785
|
else if ('UpdateSyncStatus' in instruction) {
|
|
802
|
-
|
|
786
|
+
function coreStatusToJs(status) {
|
|
787
|
+
return {
|
|
788
|
+
priority: status.priority,
|
|
789
|
+
hasSynced: status.has_synced ?? undefined,
|
|
790
|
+
lastSyncedAt: status?.last_synced_at != null ? new Date(status.last_synced_at * 1000) : undefined
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
const info = instruction.UpdateSyncStatus.status;
|
|
794
|
+
const coreCompleteSync = info.priority_status.find((s) => s.priority == FULL_SYNC_PRIORITY);
|
|
795
|
+
const completeSync = coreCompleteSync != null ? coreStatusToJs(coreCompleteSync) : null;
|
|
796
|
+
syncImplementation.updateSyncStatus({
|
|
797
|
+
connected: info.connected,
|
|
798
|
+
connecting: info.connecting,
|
|
799
|
+
dataFlow: {
|
|
800
|
+
downloading: info.downloading != null,
|
|
801
|
+
downloadProgress: info.downloading?.buckets
|
|
802
|
+
},
|
|
803
|
+
lastSyncedAt: completeSync?.lastSyncedAt,
|
|
804
|
+
hasSynced: completeSync?.hasSynced,
|
|
805
|
+
priorityStatusEntries: info.priority_status.map(coreStatusToJs)
|
|
806
|
+
});
|
|
803
807
|
}
|
|
804
808
|
else if ('EstablishSyncStream' in instruction) {
|
|
805
809
|
if (receivingLines != null) {
|
|
@@ -824,7 +828,6 @@ The next upload iteration will be delayed.`);
|
|
|
824
828
|
}
|
|
825
829
|
else if ('CloseSyncStream' in instruction) {
|
|
826
830
|
abortController.abort();
|
|
827
|
-
hideDisconnectOnRestart = instruction.CloseSyncStream.hide_disconnect;
|
|
828
831
|
}
|
|
829
832
|
else if ('FlushFileSystem' in instruction) {
|
|
830
833
|
// Not necessary on JS platforms.
|
|
@@ -843,11 +846,7 @@ The next upload iteration will be delayed.`);
|
|
|
843
846
|
}
|
|
844
847
|
}
|
|
845
848
|
try {
|
|
846
|
-
const options = {
|
|
847
|
-
parameters: resolvedOptions.params,
|
|
848
|
-
active_streams: this.activeStreams,
|
|
849
|
-
include_defaults: resolvedOptions.includeDefaultStreams
|
|
850
|
-
};
|
|
849
|
+
const options = { parameters: resolvedOptions.params };
|
|
851
850
|
if (resolvedOptions.serializedSchema) {
|
|
852
851
|
options.schema = resolvedOptions.serializedSchema;
|
|
853
852
|
}
|
|
@@ -857,21 +856,12 @@ The next upload iteration will be delayed.`);
|
|
|
857
856
|
controlInvocations.enqueueData({ command: PowerSyncControlCommand.NOTIFY_CRUD_UPLOAD_COMPLETED });
|
|
858
857
|
}
|
|
859
858
|
};
|
|
860
|
-
this.handleActiveStreamsChange = () => {
|
|
861
|
-
if (controlInvocations && !controlInvocations?.closed) {
|
|
862
|
-
controlInvocations.enqueueData({
|
|
863
|
-
command: PowerSyncControlCommand.UPDATE_SUBSCRIPTIONS,
|
|
864
|
-
payload: JSON.stringify(this.activeStreams)
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
};
|
|
868
859
|
await receivingLines;
|
|
869
860
|
}
|
|
870
861
|
finally {
|
|
871
|
-
this.notifyCompletedUploads =
|
|
862
|
+
this.notifyCompletedUploads = undefined;
|
|
872
863
|
await stop();
|
|
873
864
|
}
|
|
874
|
-
return { immediateRestart: hideDisconnectOnRestart };
|
|
875
865
|
}
|
|
876
866
|
async updateSyncStatusForStartingCheckpoint(checkpoint) {
|
|
877
867
|
const localProgress = await this.options.adapter.getBucketOperationProgress();
|
|
@@ -944,8 +934,7 @@ The next upload iteration will be delayed.`);
|
|
|
944
934
|
...this.syncStatus.dataFlowStatus,
|
|
945
935
|
...options.dataFlow
|
|
946
936
|
},
|
|
947
|
-
priorityStatusEntries: options.priorityStatusEntries ?? this.syncStatus.priorityStatusEntries
|
|
948
|
-
clientImplementation: options.clientImplementation ?? this.syncStatus.clientImplementation
|
|
937
|
+
priorityStatusEntries: options.priorityStatusEntries ?? this.syncStatus.priorityStatusEntries
|
|
949
938
|
});
|
|
950
939
|
if (!this.syncStatus.isEqual(updatedStatus)) {
|
|
951
940
|
this.syncStatus = updatedStatus;
|
|
@@ -976,8 +965,4 @@ The next upload iteration will be delayed.`);
|
|
|
976
965
|
timeoutId = setTimeout(endDelay, retryDelayMs);
|
|
977
966
|
});
|
|
978
967
|
}
|
|
979
|
-
updateSubscriptions(subscriptions) {
|
|
980
|
-
this.activeStreams = subscriptions;
|
|
981
|
-
this.handleActiveStreamsChange?.();
|
|
982
|
-
}
|
|
983
968
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { StreamingSyncRequest } from './streaming-sync-types.js';
|
|
2
|
-
import * as sync_status from '../../../db/crud/SyncStatus.js';
|
|
3
2
|
/**
|
|
4
3
|
* An internal instruction emitted by the sync client in the core extension in response to the JS
|
|
5
4
|
* SDK passing sync data into the extension.
|
|
@@ -13,9 +12,7 @@ export type Instruction = {
|
|
|
13
12
|
} | {
|
|
14
13
|
FetchCredentials: FetchCredentials;
|
|
15
14
|
} | {
|
|
16
|
-
CloseSyncStream:
|
|
17
|
-
hide_disconnect: boolean;
|
|
18
|
-
};
|
|
15
|
+
CloseSyncStream: any;
|
|
19
16
|
} | {
|
|
20
17
|
FlushFileSystem: any;
|
|
21
18
|
} | {
|
|
@@ -36,21 +33,6 @@ export interface CoreSyncStatus {
|
|
|
36
33
|
connecting: boolean;
|
|
37
34
|
priority_status: SyncPriorityStatus[];
|
|
38
35
|
downloading: DownloadProgress | null;
|
|
39
|
-
streams: CoreStreamSubscription[];
|
|
40
|
-
}
|
|
41
|
-
export interface CoreStreamSubscription {
|
|
42
|
-
progress: {
|
|
43
|
-
total: number;
|
|
44
|
-
downloaded: number;
|
|
45
|
-
};
|
|
46
|
-
name: string;
|
|
47
|
-
parameters: any;
|
|
48
|
-
priority: number | null;
|
|
49
|
-
active: boolean;
|
|
50
|
-
is_default: boolean;
|
|
51
|
-
has_explicit_subscription: boolean;
|
|
52
|
-
expires_at: number | null;
|
|
53
|
-
last_synced_at: number | null;
|
|
54
36
|
}
|
|
55
37
|
export interface SyncPriorityStatus {
|
|
56
38
|
priority: number;
|
|
@@ -69,4 +51,3 @@ export interface BucketProgress {
|
|
|
69
51
|
export interface FetchCredentials {
|
|
70
52
|
did_expire: boolean;
|
|
71
53
|
}
|
|
72
|
-
export declare function coreStatusToJs(status: CoreSyncStatus): sync_status.SyncStatusOptions;
|
|
@@ -1,26 +1 @@
|
|
|
1
|
-
|
|
2
|
-
function priorityToJs(status) {
|
|
3
|
-
return {
|
|
4
|
-
priority: status.priority,
|
|
5
|
-
hasSynced: status.has_synced ?? undefined,
|
|
6
|
-
lastSyncedAt: status.last_synced_at != null ? new Date(status.last_synced_at * 1000) : undefined
|
|
7
|
-
};
|
|
8
|
-
}
|
|
9
|
-
export function coreStatusToJs(status) {
|
|
10
|
-
const coreCompleteSync = status.priority_status.find((s) => s.priority == FULL_SYNC_PRIORITY);
|
|
11
|
-
const completeSync = coreCompleteSync != null ? priorityToJs(coreCompleteSync) : null;
|
|
12
|
-
return {
|
|
13
|
-
connected: status.connected,
|
|
14
|
-
connecting: status.connecting,
|
|
15
|
-
dataFlow: {
|
|
16
|
-
// We expose downloading as a boolean field, the core extension reports download information as a nullable
|
|
17
|
-
// download status. When that status is non-null, a download is in progress.
|
|
18
|
-
downloading: status.downloading != null,
|
|
19
|
-
downloadProgress: status.downloading?.buckets,
|
|
20
|
-
internalStreamSubscriptions: status.streams
|
|
21
|
-
},
|
|
22
|
-
lastSyncedAt: completeSync?.lastSyncedAt,
|
|
23
|
-
hasSynced: completeSync?.hasSynced,
|
|
24
|
-
priorityStatusEntries: status.priority_status.map(priorityToJs)
|
|
25
|
-
};
|
|
26
|
-
}
|
|
1
|
+
export {};
|
|
@@ -323,7 +323,7 @@ export interface TriggerManager {
|
|
|
323
323
|
* },
|
|
324
324
|
* onChange: async (context) => {
|
|
325
325
|
* // Fetches the todo records that were inserted during this diff
|
|
326
|
-
* const newTodos = await context.
|
|
326
|
+
* const newTodos = await context.getAll<Database['todos']>(`
|
|
327
327
|
* SELECT
|
|
328
328
|
* todos.*
|
|
329
329
|
* FROM
|
|
@@ -65,14 +65,12 @@ export declare enum WatchedQueryListenerEvent {
|
|
|
65
65
|
ON_DATA = "onData",
|
|
66
66
|
ON_ERROR = "onError",
|
|
67
67
|
ON_STATE_CHANGE = "onStateChange",
|
|
68
|
-
SETTINGS_WILL_UPDATE = "settingsWillUpdate",
|
|
69
68
|
CLOSED = "closed"
|
|
70
69
|
}
|
|
71
70
|
export interface WatchedQueryListener<Data> extends BaseListener {
|
|
72
71
|
[WatchedQueryListenerEvent.ON_DATA]?: (data: Data) => void | Promise<void>;
|
|
73
72
|
[WatchedQueryListenerEvent.ON_ERROR]?: (error: Error) => void | Promise<void>;
|
|
74
73
|
[WatchedQueryListenerEvent.ON_STATE_CHANGE]?: (state: WatchedQueryState<Data>) => void | Promise<void>;
|
|
75
|
-
[WatchedQueryListenerEvent.SETTINGS_WILL_UPDATE]?: () => void;
|
|
76
74
|
[WatchedQueryListenerEvent.CLOSED]?: () => void | Promise<void>;
|
|
77
75
|
}
|
|
78
76
|
export declare const DEFAULT_WATCH_THROTTLE_MS = 30;
|
|
@@ -3,7 +3,6 @@ export var WatchedQueryListenerEvent;
|
|
|
3
3
|
WatchedQueryListenerEvent["ON_DATA"] = "onData";
|
|
4
4
|
WatchedQueryListenerEvent["ON_ERROR"] = "onError";
|
|
5
5
|
WatchedQueryListenerEvent["ON_STATE_CHANGE"] = "onStateChange";
|
|
6
|
-
WatchedQueryListenerEvent["SETTINGS_WILL_UPDATE"] = "settingsWillUpdate";
|
|
7
6
|
WatchedQueryListenerEvent["CLOSED"] = "closed";
|
|
8
7
|
})(WatchedQueryListenerEvent || (WatchedQueryListenerEvent = {}));
|
|
9
8
|
export const DEFAULT_WATCH_THROTTLE_MS = 30;
|
|
@@ -40,7 +40,6 @@ export declare abstract class AbstractQueryProcessor<Data = unknown[], Settings
|
|
|
40
40
|
constructor(options: AbstractQueryProcessorOptions<Data, Settings>);
|
|
41
41
|
protected constructInitialState(): WatchedQueryState<Data>;
|
|
42
42
|
protected get reportFetching(): boolean;
|
|
43
|
-
protected updateSettingsInternal(settings: Settings, signal: AbortSignal): Promise<void>;
|
|
44
43
|
/**
|
|
45
44
|
* Updates the underlying query.
|
|
46
45
|
*/
|
|
@@ -54,7 +53,7 @@ export declare abstract class AbstractQueryProcessor<Data = unknown[], Settings
|
|
|
54
53
|
/**
|
|
55
54
|
* Configures base DB listeners and links the query to listeners.
|
|
56
55
|
*/
|
|
57
|
-
protected init(
|
|
56
|
+
protected init(): Promise<void>;
|
|
58
57
|
close(): Promise<void>;
|
|
59
58
|
/**
|
|
60
59
|
* Runs a callback and reports errors to the error listeners.
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { MetaBaseObserver } from '../../../utils/MetaBaseObserver.js';
|
|
2
|
-
import { WatchedQueryListenerEvent } from '../WatchedQuery.js';
|
|
3
2
|
/**
|
|
4
3
|
* Performs underlying watching and yields a stream of results.
|
|
5
4
|
* @internal
|
|
@@ -21,7 +20,7 @@ export class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
21
20
|
this._closed = false;
|
|
22
21
|
this.state = this.constructInitialState();
|
|
23
22
|
this.disposeListeners = null;
|
|
24
|
-
this.initialized = this.init(
|
|
23
|
+
this.initialized = this.init();
|
|
25
24
|
}
|
|
26
25
|
constructInitialState() {
|
|
27
26
|
return {
|
|
@@ -35,40 +34,25 @@ export class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
35
34
|
get reportFetching() {
|
|
36
35
|
return this.options.watchOptions.reportFetching ?? true;
|
|
37
36
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.options.watchOptions = settings;
|
|
44
|
-
this.iterateListeners((l) => l[WatchedQueryListenerEvent.SETTINGS_WILL_UPDATE]?.());
|
|
37
|
+
/**
|
|
38
|
+
* Updates the underlying query.
|
|
39
|
+
*/
|
|
40
|
+
async updateSettings(settings) {
|
|
41
|
+
await this.initialized;
|
|
45
42
|
if (!this.state.isFetching && this.reportFetching) {
|
|
46
43
|
await this.updateState({
|
|
47
44
|
isFetching: true
|
|
48
45
|
});
|
|
49
46
|
}
|
|
47
|
+
this.options.watchOptions = settings;
|
|
48
|
+
this.abortController.abort();
|
|
49
|
+
this.abortController = new AbortController();
|
|
50
50
|
await this.runWithReporting(() => this.linkQuery({
|
|
51
|
-
abortSignal: signal,
|
|
51
|
+
abortSignal: this.abortController.signal,
|
|
52
52
|
settings
|
|
53
53
|
}));
|
|
54
54
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Updates the underlying query.
|
|
57
|
-
*/
|
|
58
|
-
async updateSettings(settings) {
|
|
59
|
-
// Abort the previous request
|
|
60
|
-
this.abortController.abort();
|
|
61
|
-
// Keep track of this controller's abort status
|
|
62
|
-
const abortController = new AbortController();
|
|
63
|
-
// Allow this to be aborted externally
|
|
64
|
-
this.abortController = abortController;
|
|
65
|
-
await this.initialized;
|
|
66
|
-
return this.updateSettingsInternal(settings, abortController.signal);
|
|
67
|
-
}
|
|
68
55
|
async updateState(update) {
|
|
69
|
-
if (this._closed) {
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
56
|
if (typeof update.error !== 'undefined') {
|
|
73
57
|
await this.iterateAsyncListenersWithError(async (l) => l.onError?.(update.error));
|
|
74
58
|
// An error always stops for the current fetching state
|
|
@@ -84,7 +68,7 @@ export class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
84
68
|
/**
|
|
85
69
|
* Configures base DB listeners and links the query to listeners.
|
|
86
70
|
*/
|
|
87
|
-
async init(
|
|
71
|
+
async init() {
|
|
88
72
|
const { db } = this.options;
|
|
89
73
|
const disposeCloseListener = db.registerListener({
|
|
90
74
|
closing: async () => {
|
|
@@ -105,15 +89,16 @@ export class AbstractQueryProcessor extends MetaBaseObserver {
|
|
|
105
89
|
disposeSchemaListener();
|
|
106
90
|
};
|
|
107
91
|
// Initial setup
|
|
108
|
-
|
|
109
|
-
await this.
|
|
92
|
+
this.runWithReporting(async () => {
|
|
93
|
+
await this.updateSettings(this.options.watchOptions);
|
|
110
94
|
});
|
|
111
95
|
}
|
|
112
96
|
async close() {
|
|
113
|
-
this.
|
|
97
|
+
await this.initialized;
|
|
114
98
|
this.abortController.abort();
|
|
115
99
|
this.disposeListeners?.();
|
|
116
100
|
this.disposeListeners = null;
|
|
101
|
+
this._closed = true;
|
|
117
102
|
this.iterateListeners((l) => l.closed?.());
|
|
118
103
|
this.listeners.clear();
|
|
119
104
|
}
|
|
@@ -113,7 +113,7 @@ export class DifferentialQueryProcessor extends AbstractQueryProcessor {
|
|
|
113
113
|
});
|
|
114
114
|
db.onChangeWithCallback({
|
|
115
115
|
onChange: async () => {
|
|
116
|
-
if (this.closed
|
|
116
|
+
if (this.closed) {
|
|
117
117
|
return;
|
|
118
118
|
}
|
|
119
119
|
// This fires for each change of the relevant tables
|
|
@@ -130,9 +130,6 @@ export class DifferentialQueryProcessor extends AbstractQueryProcessor {
|
|
|
130
130
|
parameters: [...compiledQuery.parameters],
|
|
131
131
|
db: this.options.db
|
|
132
132
|
});
|
|
133
|
-
if (abortSignal.aborted) {
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
133
|
if (this.reportFetching) {
|
|
137
134
|
partialStateUpdate.isFetching = false;
|
|
138
135
|
}
|
|
@@ -148,9 +145,6 @@ export class DifferentialQueryProcessor extends AbstractQueryProcessor {
|
|
|
148
145
|
data: diff.all
|
|
149
146
|
});
|
|
150
147
|
}
|
|
151
|
-
if (this.state.error) {
|
|
152
|
-
partialStateUpdate.error = null;
|
|
153
|
-
}
|
|
154
148
|
if (Object.keys(partialStateUpdate).length > 0) {
|
|
155
149
|
await this.updateState(partialStateUpdate);
|
|
156
150
|
}
|
|
@@ -26,7 +26,7 @@ export class OnChangeQueryProcessor extends AbstractQueryProcessor {
|
|
|
26
26
|
});
|
|
27
27
|
db.onChangeWithCallback({
|
|
28
28
|
onChange: async () => {
|
|
29
|
-
if (this.closed
|
|
29
|
+
if (this.closed) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
// This fires for each change of the relevant tables
|
|
@@ -43,9 +43,6 @@ export class OnChangeQueryProcessor extends AbstractQueryProcessor {
|
|
|
43
43
|
parameters: [...compiledQuery.parameters],
|
|
44
44
|
db: this.options.db
|
|
45
45
|
});
|
|
46
|
-
if (abortSignal.aborted) {
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
46
|
if (this.reportFetching) {
|
|
50
47
|
partialStateUpdate.isFetching = false;
|
|
51
48
|
}
|
|
@@ -58,9 +55,6 @@ export class OnChangeQueryProcessor extends AbstractQueryProcessor {
|
|
|
58
55
|
data: result
|
|
59
56
|
});
|
|
60
57
|
}
|
|
61
|
-
if (this.state.error) {
|
|
62
|
-
partialStateUpdate.error = null;
|
|
63
|
-
}
|
|
64
58
|
if (Object.keys(partialStateUpdate).length > 0) {
|
|
65
59
|
await this.updateState(partialStateUpdate);
|
|
66
60
|
}
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { SyncClientImplementation } from '../../client/sync/stream/AbstractStreamingSyncImplementation.js';
|
|
3
|
-
import { InternalProgressInformation, ProgressWithOperations, SyncProgress } from './SyncProgress.js';
|
|
4
|
-
import { SyncStreamDescription, SyncSubscriptionDescription } from '../../client/sync/sync-streams.js';
|
|
1
|
+
import { InternalProgressInformation, SyncProgress } from './SyncProgress.js';
|
|
5
2
|
export type SyncDataFlowStatus = Partial<{
|
|
6
3
|
downloading: boolean;
|
|
7
4
|
uploading: boolean;
|
|
@@ -22,7 +19,6 @@ export type SyncDataFlowStatus = Partial<{
|
|
|
22
19
|
* Please use the {@link SyncStatus#downloadProgress} property to track sync progress.
|
|
23
20
|
*/
|
|
24
21
|
downloadProgress: InternalProgressInformation | null;
|
|
25
|
-
internalStreamSubscriptions: CoreStreamSubscription[] | null;
|
|
26
22
|
}>;
|
|
27
23
|
export interface SyncPriorityStatus {
|
|
28
24
|
priority: number;
|
|
@@ -36,18 +32,10 @@ export type SyncStatusOptions = {
|
|
|
36
32
|
lastSyncedAt?: Date;
|
|
37
33
|
hasSynced?: boolean;
|
|
38
34
|
priorityStatusEntries?: SyncPriorityStatus[];
|
|
39
|
-
clientImplementation?: SyncClientImplementation;
|
|
40
35
|
};
|
|
41
36
|
export declare class SyncStatus {
|
|
42
37
|
protected options: SyncStatusOptions;
|
|
43
38
|
constructor(options: SyncStatusOptions);
|
|
44
|
-
/**
|
|
45
|
-
* Returns the used sync client implementation (either the one implemented in JavaScript or the newer Rust-based
|
|
46
|
-
* implementation).
|
|
47
|
-
*
|
|
48
|
-
* This information is only available after a connection has been requested.
|
|
49
|
-
*/
|
|
50
|
-
get clientImplementation(): SyncClientImplementation | undefined;
|
|
51
39
|
/**
|
|
52
40
|
* Indicates if the client is currently connected to the PowerSync service.
|
|
53
41
|
*
|
|
@@ -102,23 +90,7 @@ export declare class SyncStatus {
|
|
|
102
90
|
* Please use the {@link SyncStatus#downloadProgress} property to track sync progress.
|
|
103
91
|
*/
|
|
104
92
|
downloadProgress: InternalProgressInformation | null;
|
|
105
|
-
internalStreamSubscriptions: CoreStreamSubscription[] | null;
|
|
106
93
|
}>;
|
|
107
|
-
/**
|
|
108
|
-
* All sync streams currently being tracked in teh database.
|
|
109
|
-
*
|
|
110
|
-
* This returns null when the database is currently being opened and we don't have reliable information about all
|
|
111
|
-
* included streams yet.
|
|
112
|
-
*
|
|
113
|
-
* @experimental Sync streams are currently in alpha.
|
|
114
|
-
*/
|
|
115
|
-
get syncStreams(): SyncStreamStatus[] | undefined;
|
|
116
|
-
/**
|
|
117
|
-
* If the `stream` appears in {@link syncStreams}, returns the current status for that stream.
|
|
118
|
-
*
|
|
119
|
-
* @experimental Sync streams are currently in alpha.
|
|
120
|
-
*/
|
|
121
|
-
forStream(stream: SyncStreamDescription): SyncStreamStatus | undefined;
|
|
122
94
|
/**
|
|
123
95
|
* Provides sync status information for all bucket priorities, sorted by priority (highest first).
|
|
124
96
|
*
|
|
@@ -176,11 +148,3 @@ export declare class SyncStatus {
|
|
|
176
148
|
toJSON(): SyncStatusOptions;
|
|
177
149
|
private static comparePriorities;
|
|
178
150
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Information about a sync stream subscription.
|
|
181
|
-
*/
|
|
182
|
-
export interface SyncStreamStatus {
|
|
183
|
-
progress: ProgressWithOperations | null;
|
|
184
|
-
subscription: SyncSubscriptionDescription;
|
|
185
|
-
priority: number | null;
|
|
186
|
-
}
|
|
@@ -4,15 +4,6 @@ export class SyncStatus {
|
|
|
4
4
|
constructor(options) {
|
|
5
5
|
this.options = options;
|
|
6
6
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Returns the used sync client implementation (either the one implemented in JavaScript or the newer Rust-based
|
|
9
|
-
* implementation).
|
|
10
|
-
*
|
|
11
|
-
* This information is only available after a connection has been requested.
|
|
12
|
-
*/
|
|
13
|
-
get clientImplementation() {
|
|
14
|
-
return this.options.clientImplementation;
|
|
15
|
-
}
|
|
16
7
|
/**
|
|
17
8
|
* Indicates if the client is currently connected to the PowerSync service.
|
|
18
9
|
*
|
|
@@ -68,27 +59,6 @@ export class SyncStatus {
|
|
|
68
59
|
uploading: false
|
|
69
60
|
});
|
|
70
61
|
}
|
|
71
|
-
/**
|
|
72
|
-
* All sync streams currently being tracked in teh database.
|
|
73
|
-
*
|
|
74
|
-
* This returns null when the database is currently being opened and we don't have reliable information about all
|
|
75
|
-
* included streams yet.
|
|
76
|
-
*
|
|
77
|
-
* @experimental Sync streams are currently in alpha.
|
|
78
|
-
*/
|
|
79
|
-
get syncStreams() {
|
|
80
|
-
return this.options.dataFlow?.internalStreamSubscriptions?.map((core) => new SyncStreamStatusView(this, core));
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* If the `stream` appears in {@link syncStreams}, returns the current status for that stream.
|
|
84
|
-
*
|
|
85
|
-
* @experimental Sync streams are currently in alpha.
|
|
86
|
-
*/
|
|
87
|
-
forStream(stream) {
|
|
88
|
-
const asJson = JSON.stringify(stream.parameters);
|
|
89
|
-
const raw = this.options.dataFlow?.internalStreamSubscriptions?.find((r) => r.name == stream.name && asJson == JSON.stringify(r.parameters));
|
|
90
|
-
return raw && new SyncStreamStatusView(this, raw);
|
|
91
|
-
}
|
|
92
62
|
/**
|
|
93
63
|
* Provides sync status information for all bucket priorities, sorted by priority (highest first).
|
|
94
64
|
*
|
|
@@ -198,34 +168,3 @@ export class SyncStatus {
|
|
|
198
168
|
return b.priority - a.priority; // Reverse because higher priorities have lower numbers
|
|
199
169
|
}
|
|
200
170
|
}
|
|
201
|
-
class SyncStreamStatusView {
|
|
202
|
-
status;
|
|
203
|
-
core;
|
|
204
|
-
subscription;
|
|
205
|
-
constructor(status, core) {
|
|
206
|
-
this.status = status;
|
|
207
|
-
this.core = core;
|
|
208
|
-
this.subscription = {
|
|
209
|
-
name: core.name,
|
|
210
|
-
parameters: core.parameters,
|
|
211
|
-
active: core.active,
|
|
212
|
-
isDefault: core.is_default,
|
|
213
|
-
hasExplicitSubscription: core.has_explicit_subscription,
|
|
214
|
-
expiresAt: core.expires_at != null ? new Date(core.expires_at * 1000) : null,
|
|
215
|
-
hasSynced: core.last_synced_at != null,
|
|
216
|
-
lastSyncedAt: core.last_synced_at != null ? new Date(core.last_synced_at * 1000) : null
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
get progress() {
|
|
220
|
-
if (this.status.dataFlowStatus.downloadProgress == null) {
|
|
221
|
-
// Don't make download progress public if we're not currently downloading.
|
|
222
|
-
return null;
|
|
223
|
-
}
|
|
224
|
-
const { total, downloaded } = this.core.progress;
|
|
225
|
-
const progress = total == 0 ? 0.0 : downloaded / total;
|
|
226
|
-
return { totalOperations: total, downloadedOperations: downloaded, downloadedFraction: progress };
|
|
227
|
-
}
|
|
228
|
-
get priority() {
|
|
229
|
-
return this.core.priority;
|
|
230
|
-
}
|
|
231
|
-
}
|
package/lib/index.d.ts
CHANGED
|
@@ -18,7 +18,6 @@ export * from './client/sync/bucket/SyncDataBucket.js';
|
|
|
18
18
|
export * from './client/sync/stream/AbstractRemote.js';
|
|
19
19
|
export * from './client/sync/stream/AbstractStreamingSyncImplementation.js';
|
|
20
20
|
export * from './client/sync/stream/streaming-sync-types.js';
|
|
21
|
-
export * from './client/sync/sync-streams.js';
|
|
22
21
|
export * from './client/ConnectionManager.js';
|
|
23
22
|
export { ProgressWithOperations, SyncProgress } from './db/crud/SyncProgress.js';
|
|
24
23
|
export * from './db/crud/SyncStatus.js';
|
package/lib/index.js
CHANGED
|
@@ -18,7 +18,6 @@ export * from './client/sync/bucket/SyncDataBucket.js';
|
|
|
18
18
|
export * from './client/sync/stream/AbstractRemote.js';
|
|
19
19
|
export * from './client/sync/stream/AbstractStreamingSyncImplementation.js';
|
|
20
20
|
export * from './client/sync/stream/streaming-sync-types.js';
|
|
21
|
-
export * from './client/sync/sync-streams.js';
|
|
22
21
|
export * from './client/ConnectionManager.js';
|
|
23
22
|
export { SyncProgress } from './db/crud/SyncProgress.js';
|
|
24
23
|
export * from './db/crud/SyncStatus.js';
|