@powersync/common 1.44.0 → 1.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/bundle.cjs +442 -2057
  2. package/dist/bundle.cjs.map +1 -1
  3. package/dist/bundle.mjs +439 -2058
  4. package/dist/bundle.mjs.map +1 -1
  5. package/dist/bundle.node.cjs +341 -127
  6. package/dist/bundle.node.cjs.map +1 -1
  7. package/dist/bundle.node.mjs +338 -128
  8. package/dist/bundle.node.mjs.map +1 -1
  9. package/dist/index.d.cts +263 -164
  10. package/lib/client/AbstractPowerSyncDatabase.d.ts +9 -2
  11. package/lib/client/AbstractPowerSyncDatabase.js +18 -5
  12. package/lib/client/AbstractPowerSyncDatabase.js.map +1 -1
  13. package/lib/client/ConnectionManager.d.ts +1 -1
  14. package/lib/client/ConnectionManager.js.map +1 -1
  15. package/lib/client/sync/stream/AbstractRemote.js +41 -32
  16. package/lib/client/sync/stream/AbstractRemote.js.map +1 -1
  17. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.d.ts +7 -12
  18. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js +10 -12
  19. package/lib/client/sync/stream/AbstractStreamingSyncImplementation.js.map +1 -1
  20. package/lib/client/triggers/MemoryTriggerClaimManager.d.ts +6 -0
  21. package/lib/client/triggers/MemoryTriggerClaimManager.js +21 -0
  22. package/lib/client/triggers/MemoryTriggerClaimManager.js.map +1 -0
  23. package/lib/client/triggers/TriggerManager.d.ts +37 -0
  24. package/lib/client/triggers/TriggerManagerImpl.d.ts +24 -3
  25. package/lib/client/triggers/TriggerManagerImpl.js +133 -11
  26. package/lib/client/triggers/TriggerManagerImpl.js.map +1 -1
  27. package/lib/db/ConnectionClosedError.d.ts +10 -0
  28. package/lib/db/ConnectionClosedError.js +21 -0
  29. package/lib/db/ConnectionClosedError.js.map +1 -0
  30. package/lib/db/crud/SyncStatus.d.ts +11 -2
  31. package/lib/db/crud/SyncStatus.js +19 -1
  32. package/lib/db/crud/SyncStatus.js.map +1 -1
  33. package/lib/index.d.ts +4 -0
  34. package/lib/index.js +4 -0
  35. package/lib/index.js.map +1 -1
  36. package/lib/utils/DataStream.js +11 -2
  37. package/lib/utils/DataStream.js.map +1 -1
  38. package/package.json +4 -3
  39. package/src/client/AbstractPowerSyncDatabase.ts +21 -6
  40. package/src/client/ConnectionManager.ts +1 -1
  41. package/src/client/sync/stream/AbstractRemote.ts +47 -35
  42. package/src/client/sync/stream/AbstractStreamingSyncImplementation.ts +11 -15
  43. package/src/client/triggers/MemoryTriggerClaimManager.ts +25 -0
  44. package/src/client/triggers/TriggerManager.ts +50 -6
  45. package/src/client/triggers/TriggerManagerImpl.ts +177 -13
  46. package/src/db/ConnectionClosedError.ts +23 -0
  47. package/src/db/crud/SyncStatus.ts +22 -3
  48. package/src/index.ts +4 -0
  49. package/src/utils/DataStream.ts +13 -2
package/dist/index.d.cts CHANGED
@@ -448,6 +448,73 @@ interface BucketStorageAdapter extends BaseObserverInterface<BucketStorageListen
448
448
  control(op: PowerSyncControlCommand, payload: string | Uint8Array | null): Promise<string>;
449
449
  }
450
450
 
451
+ type DataStreamOptions<ParsedData, SourceData> = {
452
+ mapLine?: (line: SourceData) => ParsedData;
453
+ /**
454
+ * Close the stream if any consumer throws an error
455
+ */
456
+ closeOnError?: boolean;
457
+ pressure?: {
458
+ highWaterMark?: number;
459
+ lowWaterMark?: number;
460
+ };
461
+ logger?: ILogger;
462
+ };
463
+ type DataStreamCallback<Data extends any = any> = (data: Data) => Promise<void>;
464
+ interface DataStreamListener<Data extends any = any> extends BaseListener {
465
+ data: (data: Data) => Promise<void>;
466
+ closed: () => void;
467
+ error: (error: Error) => void;
468
+ highWater: () => Promise<void>;
469
+ lowWater: () => Promise<void>;
470
+ }
471
+ declare const DEFAULT_PRESSURE_LIMITS: {
472
+ highWater: number;
473
+ lowWater: number;
474
+ };
475
+ /**
476
+ * A very basic implementation of a data stream with backpressure support which does not use
477
+ * native JS streams or async iterators.
478
+ * This is handy for environments such as React Native which need polyfills for the above.
479
+ */
480
+ declare class DataStream<ParsedData, SourceData = any> extends BaseObserver<DataStreamListener<ParsedData>> {
481
+ protected options?: DataStreamOptions<ParsedData, SourceData> | undefined;
482
+ dataQueue: SourceData[];
483
+ protected isClosed: boolean;
484
+ protected processingPromise: Promise<void> | null;
485
+ protected notifyDataAdded: (() => void) | null;
486
+ protected logger: ILogger;
487
+ protected mapLine: (line: SourceData) => ParsedData;
488
+ constructor(options?: DataStreamOptions<ParsedData, SourceData> | undefined);
489
+ get highWatermark(): number;
490
+ get lowWatermark(): number;
491
+ get closed(): boolean;
492
+ close(): Promise<void>;
493
+ /**
494
+ * Enqueues data for the consumers to read
495
+ */
496
+ enqueueData(data: SourceData): void;
497
+ /**
498
+ * Reads data once from the data stream
499
+ * @returns a Data payload or Null if the stream closed.
500
+ */
501
+ read(): Promise<ParsedData | null>;
502
+ /**
503
+ * Executes a callback for each data item in the stream
504
+ */
505
+ forEach(callback: DataStreamCallback<ParsedData>): () => void;
506
+ protected processQueue(): Promise<void> | undefined;
507
+ protected hasDataReader(): boolean;
508
+ protected _processQueue(): Promise<void>;
509
+ protected iterateAsyncErrored(cb: (l: Partial<DataStreamListener<ParsedData>>) => Promise<void>): Promise<void>;
510
+ }
511
+
512
+ interface PowerSyncCredentials {
513
+ endpoint: string;
514
+ token: string;
515
+ expiresAt?: Date;
516
+ }
517
+
451
518
  /**
452
519
  * For sync2.json
453
520
  */
@@ -588,94 +655,6 @@ interface CrudResponse {
588
655
  checkpoint?: OpId;
589
656
  }
590
657
 
591
- interface CoreStreamSubscription {
592
- progress: {
593
- total: number;
594
- downloaded: number;
595
- };
596
- name: string;
597
- parameters: any;
598
- priority: number | null;
599
- active: boolean;
600
- is_default: boolean;
601
- has_explicit_subscription: boolean;
602
- expires_at: number | null;
603
- last_synced_at: number | null;
604
- }
605
- interface BucketProgress {
606
- priority: number;
607
- at_last: number;
608
- since_last: number;
609
- target_count: number;
610
- }
611
-
612
- type DataStreamOptions<ParsedData, SourceData> = {
613
- mapLine?: (line: SourceData) => ParsedData;
614
- /**
615
- * Close the stream if any consumer throws an error
616
- */
617
- closeOnError?: boolean;
618
- pressure?: {
619
- highWaterMark?: number;
620
- lowWaterMark?: number;
621
- };
622
- logger?: ILogger;
623
- };
624
- type DataStreamCallback<Data extends any = any> = (data: Data) => Promise<void>;
625
- interface DataStreamListener<Data extends any = any> extends BaseListener {
626
- data: (data: Data) => Promise<void>;
627
- closed: () => void;
628
- error: (error: Error) => void;
629
- highWater: () => Promise<void>;
630
- lowWater: () => Promise<void>;
631
- }
632
- declare const DEFAULT_PRESSURE_LIMITS: {
633
- highWater: number;
634
- lowWater: number;
635
- };
636
- /**
637
- * A very basic implementation of a data stream with backpressure support which does not use
638
- * native JS streams or async iterators.
639
- * This is handy for environments such as React Native which need polyfills for the above.
640
- */
641
- declare class DataStream<ParsedData, SourceData = any> extends BaseObserver<DataStreamListener<ParsedData>> {
642
- protected options?: DataStreamOptions<ParsedData, SourceData> | undefined;
643
- dataQueue: SourceData[];
644
- protected isClosed: boolean;
645
- protected processingPromise: Promise<void> | null;
646
- protected notifyDataAdded: (() => void) | null;
647
- protected logger: ILogger;
648
- protected mapLine: (line: SourceData) => ParsedData;
649
- constructor(options?: DataStreamOptions<ParsedData, SourceData> | undefined);
650
- get highWatermark(): number;
651
- get lowWatermark(): number;
652
- get closed(): boolean;
653
- close(): Promise<void>;
654
- /**
655
- * Enqueues data for the consumers to read
656
- */
657
- enqueueData(data: SourceData): void;
658
- /**
659
- * Reads data once from the data stream
660
- * @returns a Data payload or Null if the stream closed.
661
- */
662
- read(): Promise<ParsedData | null>;
663
- /**
664
- * Executes a callback for each data item in the stream
665
- */
666
- forEach(callback: DataStreamCallback<ParsedData>): () => void;
667
- protected processQueue(): Promise<void> | undefined;
668
- protected hasDataReader(): boolean;
669
- protected _processQueue(): Promise<void>;
670
- protected iterateAsyncErrored(cb: (l: Partial<DataStreamListener<ParsedData>>) => Promise<void>): Promise<void>;
671
- }
672
-
673
- interface PowerSyncCredentials {
674
- endpoint: string;
675
- token: string;
676
- expiresAt?: Date;
677
- }
678
-
679
658
  type BSONImplementation = typeof BSON;
680
659
  type RemoteConnector = {
681
660
  fetchCredentials: () => Promise<PowerSyncCredentials | null>;
@@ -825,18 +804,17 @@ declare enum SyncClientImplementation {
825
804
  *
826
805
  * This is the default option.
827
806
  *
828
- * @deprecated Don't use {@link SyncClientImplementation.JAVASCRIPT} directly. Instead, use
829
- * {@link DEFAULT_SYNC_CLIENT_IMPLEMENTATION} or omit the option. The explicit choice to use
830
- * the JavaScript-based sync implementation will be removed from a future version of the SDK.
807
+ * @deprecated We recommend the {@link RUST} client implementation for all apps. If you have issues with
808
+ * the Rust client, please file an issue or reach out to us. The JavaScript client will be removed in a future
809
+ * version of the PowerSync SDK.
831
810
  */
832
811
  JAVASCRIPT = "js",
833
812
  /**
834
813
  * This implementation offloads the sync line decoding and handling into the PowerSync
835
814
  * core extension.
836
815
  *
837
- * @experimental
838
- * While this implementation is more performant than {@link SyncClientImplementation.JAVASCRIPT},
839
- * it has seen less real-world testing and is marked as __experimental__ at the moment.
816
+ * This option is more performant than the {@link JAVASCRIPT} client, enabled by default and the
817
+ * recommended client implementation for all apps.
840
818
  *
841
819
  * ## Compatibility warning
842
820
  *
@@ -854,13 +832,9 @@ declare enum SyncClientImplementation {
854
832
  RUST = "rust"
855
833
  }
856
834
  /**
857
- * The default {@link SyncClientImplementation} to use.
858
- *
859
- * Please use this field instead of {@link SyncClientImplementation.JAVASCRIPT} directly. A future version
860
- * of the PowerSync SDK will enable {@link SyncClientImplementation.RUST} by default and remove the JavaScript
861
- * option.
835
+ * The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
862
836
  */
863
- declare const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = SyncClientImplementation.JAVASCRIPT;
837
+ declare const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = SyncClientImplementation.RUST;
864
838
  /**
865
839
  * Abstract Lock to be implemented by various JS environments
866
840
  */
@@ -1050,68 +1024,25 @@ interface RustIterationResult {
1050
1024
  immediateRestart: boolean;
1051
1025
  }
1052
1026
 
1053
- /** @internal */
1054
- type InternalProgressInformation = Record<string, BucketProgress>;
1055
- /**
1056
- * Information about a progressing download made by the PowerSync SDK.
1057
- *
1058
- * To obtain these values, use {@link SyncProgress}, available through
1059
- * {@link SyncStatus#downloadProgress}.
1060
- */
1061
- interface ProgressWithOperations {
1062
- /**
1063
- * The total amount of operations to download for the current sync iteration
1064
- * to complete.
1065
- */
1066
- totalOperations: number;
1067
- /**
1068
- * The amount of operations that have already been downloaded.
1069
- */
1070
- downloadedOperations: number;
1071
- /**
1072
- * Relative progress, as {@link downloadedOperations} of {@link totalOperations}.
1073
- *
1074
- * This will be a number between `0.0` and `1.0` (inclusive).
1075
- *
1076
- * When this number reaches `1.0`, all changes have been received from the sync service.
1077
- * Actually applying these changes happens before the `downloadProgress` field is cleared from
1078
- * {@link SyncStatus}, so progress can stay at `1.0` for a short while before completing.
1079
- */
1080
- downloadedFraction: number;
1027
+ interface CoreStreamSubscription {
1028
+ progress: {
1029
+ total: number;
1030
+ downloaded: number;
1031
+ };
1032
+ name: string;
1033
+ parameters: any;
1034
+ priority: number | null;
1035
+ active: boolean;
1036
+ is_default: boolean;
1037
+ has_explicit_subscription: boolean;
1038
+ expires_at: number | null;
1039
+ last_synced_at: number | null;
1081
1040
  }
1082
- /**
1083
- * Provides realtime progress on how PowerSync is downloading rows.
1084
- *
1085
- * The progress until the next complete sync is available through the fields on {@link ProgressWithOperations},
1086
- * which this class implements.
1087
- * Additionally, the {@link SyncProgress.untilPriority} method can be used to otbain progress towards
1088
- * a specific priority (instead of the progress for the entire download).
1089
- *
1090
- * The reported progress always reflects the status towards the end of a sync iteration (after
1091
- * which a consistent snapshot of all buckets is available locally).
1092
- *
1093
- * In rare cases (in particular, when a [compacting](https://docs.powersync.com/usage/lifecycle-maintenance/compacting-buckets)
1094
- * operation takes place between syncs), it's possible for the returned numbers to be slightly
1095
- * inaccurate. For this reason, {@link SyncProgress} should be seen as an approximation of progress.
1096
- * The information returned is good enough to build progress bars, but not exact enough to track
1097
- * individual download counts.
1098
- *
1099
- * Also note that data is downloaded in bulk, which means that individual counters are unlikely
1100
- * to be updated one-by-one.
1101
- */
1102
- declare class SyncProgress implements ProgressWithOperations {
1103
- protected internal: InternalProgressInformation;
1104
- totalOperations: number;
1105
- downloadedOperations: number;
1106
- downloadedFraction: number;
1107
- constructor(internal: InternalProgressInformation);
1108
- /**
1109
- * Returns download progress towards all data up until the specified priority being received.
1110
- *
1111
- * The returned {@link ProgressWithOperations} tracks the target amount of operations that need
1112
- * to be downloaded in total and how many of them have already been received.
1113
- */
1114
- untilPriority(priority: number): ProgressWithOperations;
1041
+ interface BucketProgress {
1042
+ priority: number;
1043
+ at_last: number;
1044
+ since_last: number;
1045
+ target_count: number;
1115
1046
  }
1116
1047
 
1117
1048
  /**
@@ -1213,6 +1144,70 @@ interface SyncStreamSubscription extends SyncStreamDescription {
1213
1144
  unsubscribe(): void;
1214
1145
  }
1215
1146
 
1147
+ /** @internal */
1148
+ type InternalProgressInformation = Record<string, BucketProgress>;
1149
+ /**
1150
+ * Information about a progressing download made by the PowerSync SDK.
1151
+ *
1152
+ * To obtain these values, use {@link SyncProgress}, available through
1153
+ * {@link SyncStatus#downloadProgress}.
1154
+ */
1155
+ interface ProgressWithOperations {
1156
+ /**
1157
+ * The total amount of operations to download for the current sync iteration
1158
+ * to complete.
1159
+ */
1160
+ totalOperations: number;
1161
+ /**
1162
+ * The amount of operations that have already been downloaded.
1163
+ */
1164
+ downloadedOperations: number;
1165
+ /**
1166
+ * Relative progress, as {@link downloadedOperations} of {@link totalOperations}.
1167
+ *
1168
+ * This will be a number between `0.0` and `1.0` (inclusive).
1169
+ *
1170
+ * When this number reaches `1.0`, all changes have been received from the sync service.
1171
+ * Actually applying these changes happens before the `downloadProgress` field is cleared from
1172
+ * {@link SyncStatus}, so progress can stay at `1.0` for a short while before completing.
1173
+ */
1174
+ downloadedFraction: number;
1175
+ }
1176
+ /**
1177
+ * Provides realtime progress on how PowerSync is downloading rows.
1178
+ *
1179
+ * The progress until the next complete sync is available through the fields on {@link ProgressWithOperations},
1180
+ * which this class implements.
1181
+ * Additionally, the {@link SyncProgress.untilPriority} method can be used to otbain progress towards
1182
+ * a specific priority (instead of the progress for the entire download).
1183
+ *
1184
+ * The reported progress always reflects the status towards the end of a sync iteration (after
1185
+ * which a consistent snapshot of all buckets is available locally).
1186
+ *
1187
+ * In rare cases (in particular, when a [compacting](https://docs.powersync.com/usage/lifecycle-maintenance/compacting-buckets)
1188
+ * operation takes place between syncs), it's possible for the returned numbers to be slightly
1189
+ * inaccurate. For this reason, {@link SyncProgress} should be seen as an approximation of progress.
1190
+ * The information returned is good enough to build progress bars, but not exact enough to track
1191
+ * individual download counts.
1192
+ *
1193
+ * Also note that data is downloaded in bulk, which means that individual counters are unlikely
1194
+ * to be updated one-by-one.
1195
+ */
1196
+ declare class SyncProgress implements ProgressWithOperations {
1197
+ protected internal: InternalProgressInformation;
1198
+ totalOperations: number;
1199
+ downloadedOperations: number;
1200
+ downloadedFraction: number;
1201
+ constructor(internal: InternalProgressInformation);
1202
+ /**
1203
+ * Returns download progress towards all data up until the specified priority being received.
1204
+ *
1205
+ * The returned {@link ProgressWithOperations} tracks the target amount of operations that need
1206
+ * to be downloaded in total and how many of them have already been received.
1207
+ */
1208
+ untilPriority(priority: number): ProgressWithOperations;
1209
+ }
1210
+
1216
1211
  type SyncDataFlowStatus = Partial<{
1217
1212
  downloading: boolean;
1218
1213
  uploading: boolean;
@@ -1385,6 +1380,15 @@ declare class SyncStatus {
1385
1380
  * @returns {SyncStatusOptions} A plain object representation of the sync status
1386
1381
  */
1387
1382
  toJSON(): SyncStatusOptions;
1383
+ /**
1384
+ * Not all errors are serializable over a MessagePort. E.g. some `DomExceptions` fail to be passed across workers.
1385
+ * This explicitly serializes errors in the SyncStatus.
1386
+ */
1387
+ protected serializeError(error?: Error): {
1388
+ name: string;
1389
+ message: string;
1390
+ stack: string | undefined;
1391
+ } | undefined;
1388
1392
  private static comparePriorities;
1389
1393
  }
1390
1394
  /**
@@ -2618,6 +2622,11 @@ interface BaseCreateDiffTriggerOptions {
2618
2622
  * Hooks which allow execution during the trigger creation process.
2619
2623
  */
2620
2624
  hooks?: TriggerCreationHooks;
2625
+ /**
2626
+ * Use storage-backed (non-TEMP) tables and triggers that persist across sessions.
2627
+ * These resources are still automatically disposed when no longer claimed.
2628
+ */
2629
+ useStorage?: boolean;
2621
2630
  }
2622
2631
  /**
2623
2632
  * @experimental
@@ -2856,6 +2865,73 @@ interface TriggerManager {
2856
2865
  */
2857
2866
  trackTableDiff(options: TrackDiffOptions): Promise<TriggerRemoveCallback>;
2858
2867
  }
2868
+ /**
2869
+ * @experimental
2870
+ * @internal
2871
+ * Manages claims on persisted SQLite triggers and destination tables to enable proper cleanup
2872
+ * when they are no longer actively in use.
2873
+ *
2874
+ * When using persisted triggers (especially for OPFS multi-tab scenarios), we need a reliable way to determine which resources are still actively in use across different connections/tabs so stale resources can be safely cleaned up without interfering with active triggers.
2875
+ *
2876
+ * A cleanup process runs
2877
+ * on database creation (and every 2 minutes) that:
2878
+ * 1. Queries for existing managed persisted resources
2879
+ * 2. Checks with the claim manager if any consumer is actively using those resources
2880
+ * 3. Deletes unused resources
2881
+ */
2882
+ interface TriggerClaimManager {
2883
+ /**
2884
+ * Obtains or marks a claim on a certain identifier.
2885
+ * @returns a callback to release the claim.
2886
+ */
2887
+ obtainClaim: (identifier: string) => Promise<() => Promise<void>>;
2888
+ /**
2889
+ * Checks if a claim is present for an identifier.
2890
+ */
2891
+ checkClaim: (identifier: string) => Promise<boolean>;
2892
+ }
2893
+ /**
2894
+ * @experimental
2895
+ * @internal
2896
+ */
2897
+ interface TriggerManagerConfig {
2898
+ claimManager: TriggerClaimManager;
2899
+ }
2900
+
2901
+ type TriggerManagerImplOptions = TriggerManagerConfig & {
2902
+ db: AbstractPowerSyncDatabase;
2903
+ schema: Schema;
2904
+ };
2905
+ type TriggerManagerImplConfiguration = {
2906
+ useStorageByDefault: boolean;
2907
+ };
2908
+ /**
2909
+ * @internal
2910
+ * @experimental
2911
+ */
2912
+ declare class TriggerManagerImpl implements TriggerManager {
2913
+ protected options: TriggerManagerImplOptions;
2914
+ protected schema: Schema;
2915
+ protected defaultConfig: TriggerManagerImplConfiguration;
2916
+ protected cleanupTimeout: ReturnType<typeof setTimeout> | null;
2917
+ protected isDisposed: boolean;
2918
+ constructor(options: TriggerManagerImplOptions);
2919
+ protected get db(): AbstractPowerSyncDatabase;
2920
+ protected getUUID(): Promise<string>;
2921
+ protected removeTriggers(tx: LockContext, triggerIds: string[]): Promise<void>;
2922
+ dispose(): void;
2923
+ /**
2924
+ * Updates default config settings for platform specific use-cases.
2925
+ */
2926
+ updateDefaults(config: TriggerManagerImplConfiguration): void;
2927
+ protected generateTriggerName(operation: DiffTriggerOperation, destinationTable: string, triggerId: string): string;
2928
+ /**
2929
+ * Cleanup any SQLite triggers or tables that are no longer in use.
2930
+ */
2931
+ cleanupResources(): Promise<void>;
2932
+ createDiffTrigger(options: CreateDiffTriggerOptions): Promise<() => Promise<void>>;
2933
+ trackTableDiff(options: TrackDiffOptions): Promise<TriggerRemoveCallback>;
2934
+ }
2859
2935
 
2860
2936
  interface DisconnectAndClearOptions {
2861
2937
  /** When set to false, data in local-only tables is preserved. */
@@ -2992,6 +3068,7 @@ declare abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncD
2992
3068
  * Allows creating SQLite triggers which can be used to track various operations on SQLite tables.
2993
3069
  */
2994
3070
  readonly triggers: TriggerManager;
3071
+ protected triggersImpl: TriggerManagerImpl;
2995
3072
  logger: ILogger;
2996
3073
  constructor(options: PowerSyncDatabaseOptionsWithDBAdapter);
2997
3074
  constructor(options: PowerSyncDatabaseOptionsWithOpenFactory);
@@ -3018,6 +3095,11 @@ declare abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncD
3018
3095
  * Opens the DBAdapter given open options using a default open factory
3019
3096
  */
3020
3097
  protected abstract openDBAdapter(options: PowerSyncDatabaseOptionsWithSettings): DBAdapter;
3098
+ /**
3099
+ * Generates a base configuration for {@link TriggerManagerImpl}.
3100
+ * Implementations should override this if necessary.
3101
+ */
3102
+ protected generateTriggerManagerConfig(): TriggerManagerConfig;
3021
3103
  protected abstract generateSyncStreamImplementation(connector: PowerSyncBackendConnector, options: CreateSyncImplementationOptions & RequiredAdditionalConnectionOptions): StreamingSyncImplementation;
3022
3104
  protected abstract generateBucketStorageAdapter(): BucketStorageAdapter;
3023
3105
  /**
@@ -3051,7 +3133,7 @@ declare abstract class AbstractPowerSyncDatabase extends BaseObserver<PowerSyncD
3051
3133
  * This is to be automatically executed in the constructor.
3052
3134
  */
3053
3135
  protected initialize(): Promise<void>;
3054
- private _loadVersion;
3136
+ protected loadVersion(): Promise<void>;
3055
3137
  protected resolveOfflineSyncStatus(): Promise<void>;
3056
3138
  /**
3057
3139
  * Replace the schema with a new version. This is for advanced use cases - typically the schema should just be specified once in the constructor.
@@ -3531,6 +3613,23 @@ declare class SqliteBucketStorage extends BaseObserver<BucketStorageListener> im
3531
3613
  static _subkeyMigrationKey: string;
3532
3614
  }
3533
3615
 
3616
+ /**
3617
+ * Thrown when an underlying database connection is closed.
3618
+ * This is particularly relevant when worker connections are marked as closed while
3619
+ * operations are still in progress.
3620
+ */
3621
+ declare class ConnectionClosedError extends Error {
3622
+ static NAME: string;
3623
+ static MATCHES(input: any): boolean;
3624
+ constructor(message: string);
3625
+ }
3626
+
3627
+ /**
3628
+ * @internal
3629
+ * @experimental
3630
+ */
3631
+ declare const MEMORY_TRIGGER_CLAIM_MANAGER: TriggerClaimManager;
3632
+
3534
3633
  /**
3535
3634
  * Helper function for sanitizing UUID input strings.
3536
3635
  * Typically used with {@link sanitizeSQL}.
@@ -3668,5 +3767,5 @@ interface ParsedQuery {
3668
3767
  }
3669
3768
  declare const parseQuery: <T>(query: string | CompilableQuery<T>, parameters: any[]) => ParsedQuery;
3670
3769
 
3671
- export { AbortOperation, AbstractPowerSyncDatabase, AbstractPowerSyncDatabaseOpenFactory, AbstractQueryProcessor, AbstractRemote, AbstractStreamingSyncImplementation, ArrayComparator, BaseObserver, Column, ColumnType, ConnectionManager, ControlledExecutor, CrudBatch, CrudEntry, CrudTransaction, DEFAULT_CRUD_BATCH_LIMIT, DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_INDEX_COLUMN_OPTIONS, DEFAULT_INDEX_OPTIONS, DEFAULT_LOCK_TIMEOUT_MS, DEFAULT_POWERSYNC_CLOSE_OPTIONS, DEFAULT_POWERSYNC_DB_OPTIONS, DEFAULT_PRESSURE_LIMITS, DEFAULT_REMOTE_LOGGER, DEFAULT_REMOTE_OPTIONS, DEFAULT_RETRY_DELAY_MS, DEFAULT_ROW_COMPARATOR, DEFAULT_STREAMING_SYNC_OPTIONS, DEFAULT_STREAM_CONNECTION_OPTIONS, DEFAULT_SYNC_CLIENT_IMPLEMENTATION, DEFAULT_TABLE_OPTIONS, DEFAULT_WATCH_QUERY_OPTIONS, DEFAULT_WATCH_THROTTLE_MS, DataStream, DiffTriggerOperation, DifferentialQueryProcessor, EMPTY_DIFFERENTIAL, FalsyComparator, FetchImplementationProvider, FetchStrategy, GetAllQuery, Index, IndexedColumn, InvalidSQLCharacters, LockType, LogLevel, MAX_AMOUNT_OF_COLUMNS, MAX_OP_ID, OnChangeQueryProcessor, OpType, OpTypeEnum, OplogEntry, PSInternalTable, PowerSyncControlCommand, RowUpdateType, Schema, SqliteBucketStorage, SyncClientImplementation, SyncDataBatch, SyncDataBucket, SyncProgress, SyncStatus, SyncStreamConnectionMethod, Table, TableV2, UpdateType, UploadQueueStats, WatchedQueryListenerEvent, column, compilableQueryWatch, createBaseLogger, createLogger, extractTableUpdates, isBatchedUpdateNotification, isContinueCheckpointRequest, isDBAdapter, isPowerSyncDatabaseOptionsWithSettings, isSQLOpenFactory, isSQLOpenOptions, isStreamingKeepalive, isStreamingSyncCheckpoint, isStreamingSyncCheckpointComplete, isStreamingSyncCheckpointDiff, isStreamingSyncCheckpointPartiallyComplete, isStreamingSyncData, isSyncNewCheckpointRequest, parseQuery, runOnSchemaChange, sanitizeSQL, sanitizeUUID };
3672
- export type { AbstractQueryProcessorOptions, AbstractRemoteOptions, AbstractStreamingSyncImplementationOptions, AdditionalConnectionOptions, ArrayComparatorOptions, ArrayQueryDefinition, BSONImplementation, BaseColumnType, BaseConnectionOptions, BaseListener, BaseObserverInterface, BasePowerSyncDatabaseOptions, BaseTriggerDiffRecord, BatchedUpdateNotification, BucketChecksum, BucketDescription, BucketOperationProgress, BucketRequest, BucketState, BucketStorageAdapter, BucketStorageListener, Checkpoint, ChecksumCache, ColumnOptions, ColumnsType, CompilableQuery, CompilableQueryWatchHandler, CompiledQuery, ConnectionManagerListener, ConnectionManagerOptions, ConnectionManagerSyncImplementationResult, ContinueCheckpointRequest, ControlledExecutorOptions, CreateDiffTriggerOptions, CreateLoggerOptions, CreateSyncImplementationOptions, CrudRequest, CrudResponse, CrudUploadNotification, DBAdapter, DBAdapterListener, DBGetUtils, DBLockOptions, DataStreamCallback, DataStreamListener, DataStreamOptions, DifferentialQueryProcessorOptions, DifferentialWatchedQuery, DifferentialWatchedQueryComparator, DifferentialWatchedQueryListener, DifferentialWatchedQueryOptions, DifferentialWatchedQuerySettings, DisconnectAndClearOptions, Disposable, ExtractColumnValueType, ExtractedTriggerDiffRecord, FetchImplementation, GetAllQueryOptions, IndexColumnOptions, IndexOptions, IndexShorthand, InternalConnectionOptions, InternalSubscriptionAdapter, LinkQueryOptions, LockContext, LockOptions, MutableWatchedQueryState, OnChangeQueryProcessorOptions, OpId, OpTypeJSON, OplogEntryJSON, ParsedQuery, PowerSyncBackendConnector, PowerSyncCloseOptions, PowerSyncConnectionOptions, PowerSyncCredentials, PowerSyncDBListener, PowerSyncDatabaseOptions, PowerSyncDatabaseOptionsWithDBAdapter, PowerSyncDatabaseOptionsWithOpenFactory, PowerSyncDatabaseOptionsWithSettings, PowerSyncOpenFactoryOptions, ProgressWithOperations, Query, QueryParam, QueryResult, RemoteConnector, RequiredAdditionalConnectionOptions, RequiredPowerSyncConnectionOptions, RowType, SQLOnChangeOptions, SQLOpenFactory, SQLOpenOptions, SQLWatchOptions, SavedProgress, SchemaTableType, SocketSyncStreamOptions, StandardWatchedQuery, StandardWatchedQueryOptions, StreamingSyncCheckpoint, StreamingSyncCheckpointComplete, StreamingSyncCheckpointDiff, StreamingSyncCheckpointPartiallyComplete, StreamingSyncDataJSON, StreamingSyncImplementation, StreamingSyncImplementationListener, StreamingSyncKeepalive, StreamingSyncLine, StreamingSyncLineOrCrudUploadComplete, StreamingSyncRequest, StreamingSyncRequestParameterType, SubscribedStream, SyncDataBucketJSON, SyncDataFlowStatus, SyncLocalDatabaseResult, SyncNewCheckpointRequest, SyncPriorityStatus, SyncRequest, SyncResponse, SyncStatusOptions, SyncStream, SyncStreamDescription, SyncStreamOptions, SyncStreamStatus, SyncStreamSubscribeOptions, SyncStreamSubscription, SyncSubscriptionDescription, TableOptions, TableUpdateOperation, TableV2Options, TrackDiffOptions, TrackPreviousOptions, Transaction, TriggerCreationHooks, TriggerDiffDeleteRecord, TriggerDiffHandlerContext, TriggerDiffInsertRecord, TriggerDiffRecord, TriggerDiffUpdateRecord, TriggerManager, TriggerRemoveCallback, UpdateNotification, WatchCompatibleQuery, WatchExecuteOptions, WatchHandler, WatchOnChangeEvent, WatchOnChangeHandler, WatchedQuery, WatchedQueryComparator, WatchedQueryDifferential, WatchedQueryListener, WatchedQueryOptions, WatchedQueryRowDifferential, WatchedQuerySettings, WatchedQueryState, WithDiffOptions };
3770
+ export { AbortOperation, AbstractPowerSyncDatabase, AbstractPowerSyncDatabaseOpenFactory, AbstractQueryProcessor, AbstractRemote, AbstractStreamingSyncImplementation, ArrayComparator, BaseObserver, Column, ColumnType, ConnectionClosedError, ConnectionManager, ControlledExecutor, CrudBatch, CrudEntry, CrudTransaction, DEFAULT_CRUD_BATCH_LIMIT, DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_INDEX_COLUMN_OPTIONS, DEFAULT_INDEX_OPTIONS, DEFAULT_LOCK_TIMEOUT_MS, DEFAULT_POWERSYNC_CLOSE_OPTIONS, DEFAULT_POWERSYNC_DB_OPTIONS, DEFAULT_PRESSURE_LIMITS, DEFAULT_REMOTE_LOGGER, DEFAULT_REMOTE_OPTIONS, DEFAULT_RETRY_DELAY_MS, DEFAULT_ROW_COMPARATOR, DEFAULT_STREAMING_SYNC_OPTIONS, DEFAULT_STREAM_CONNECTION_OPTIONS, DEFAULT_SYNC_CLIENT_IMPLEMENTATION, DEFAULT_TABLE_OPTIONS, DEFAULT_WATCH_QUERY_OPTIONS, DEFAULT_WATCH_THROTTLE_MS, DataStream, DiffTriggerOperation, DifferentialQueryProcessor, EMPTY_DIFFERENTIAL, FalsyComparator, FetchImplementationProvider, FetchStrategy, GetAllQuery, Index, IndexedColumn, InvalidSQLCharacters, LockType, LogLevel, MAX_AMOUNT_OF_COLUMNS, MAX_OP_ID, MEMORY_TRIGGER_CLAIM_MANAGER, OnChangeQueryProcessor, OpType, OpTypeEnum, OplogEntry, PSInternalTable, PowerSyncControlCommand, RawTable, RowUpdateType, Schema, SqliteBucketStorage, SyncClientImplementation, SyncDataBatch, SyncDataBucket, SyncProgress, SyncStatus, SyncStreamConnectionMethod, Table, TableV2, TriggerManagerImpl, UpdateType, UploadQueueStats, WatchedQueryListenerEvent, column, compilableQueryWatch, createBaseLogger, createLogger, extractTableUpdates, isBatchedUpdateNotification, isContinueCheckpointRequest, isDBAdapter, isPowerSyncDatabaseOptionsWithSettings, isSQLOpenFactory, isSQLOpenOptions, isStreamingKeepalive, isStreamingSyncCheckpoint, isStreamingSyncCheckpointComplete, isStreamingSyncCheckpointDiff, isStreamingSyncCheckpointPartiallyComplete, isStreamingSyncData, isSyncNewCheckpointRequest, parseQuery, runOnSchemaChange, sanitizeSQL, sanitizeUUID };
3771
+ export type { AbstractQueryProcessorOptions, AbstractRemoteOptions, AbstractStreamingSyncImplementationOptions, AdditionalConnectionOptions, ArrayComparatorOptions, ArrayQueryDefinition, BSONImplementation, BaseColumnType, BaseConnectionOptions, BaseListener, BaseObserverInterface, BasePowerSyncDatabaseOptions, BaseTriggerDiffRecord, BatchedUpdateNotification, BucketChecksum, BucketDescription, BucketOperationProgress, BucketRequest, BucketState, BucketStorageAdapter, BucketStorageListener, Checkpoint, ChecksumCache, ColumnOptions, ColumnsType, CompilableQuery, CompilableQueryWatchHandler, CompiledQuery, ConnectionManagerListener, ConnectionManagerOptions, ConnectionManagerSyncImplementationResult, ContinueCheckpointRequest, ControlledExecutorOptions, CreateDiffTriggerOptions, CreateLoggerOptions, CreateSyncImplementationOptions, CrudRequest, CrudResponse, CrudUploadNotification, DBAdapter, DBAdapterListener, DBGetUtils, DBLockOptions, DataStreamCallback, DataStreamListener, DataStreamOptions, DifferentialQueryProcessorOptions, DifferentialWatchedQuery, DifferentialWatchedQueryComparator, DifferentialWatchedQueryListener, DifferentialWatchedQueryOptions, DifferentialWatchedQuerySettings, DisconnectAndClearOptions, Disposable, ExtractColumnValueType, ExtractedTriggerDiffRecord, FetchImplementation, GetAllQueryOptions, IndexColumnOptions, IndexOptions, IndexShorthand, InternalConnectionOptions, InternalSubscriptionAdapter, LinkQueryOptions, LockContext, LockOptions, MutableWatchedQueryState, OnChangeQueryProcessorOptions, OpId, OpTypeJSON, OplogEntryJSON, ParsedQuery, PendingStatement, PendingStatementParameter, PowerSyncBackendConnector, PowerSyncCloseOptions, PowerSyncConnectionOptions, PowerSyncCredentials, PowerSyncDBListener, PowerSyncDatabaseOptions, PowerSyncDatabaseOptionsWithDBAdapter, PowerSyncDatabaseOptionsWithOpenFactory, PowerSyncDatabaseOptionsWithSettings, PowerSyncOpenFactoryOptions, ProgressWithOperations, Query, QueryParam, QueryResult, RawTableType, RemoteConnector, RequiredAdditionalConnectionOptions, RequiredPowerSyncConnectionOptions, RowType, SQLOnChangeOptions, SQLOpenFactory, SQLOpenOptions, SQLWatchOptions, SavedProgress, SchemaTableType, SocketSyncStreamOptions, StandardWatchedQuery, StandardWatchedQueryOptions, StreamingSyncCheckpoint, StreamingSyncCheckpointComplete, StreamingSyncCheckpointDiff, StreamingSyncCheckpointPartiallyComplete, StreamingSyncDataJSON, StreamingSyncImplementation, StreamingSyncImplementationListener, StreamingSyncKeepalive, StreamingSyncLine, StreamingSyncLineOrCrudUploadComplete, StreamingSyncRequest, StreamingSyncRequestParameterType, SubscribedStream, SyncDataBucketJSON, SyncDataFlowStatus, SyncLocalDatabaseResult, SyncNewCheckpointRequest, SyncPriorityStatus, SyncRequest, SyncResponse, SyncStatusOptions, SyncStream, SyncStreamDescription, SyncStreamOptions, SyncStreamStatus, SyncStreamSubscribeOptions, SyncStreamSubscription, SyncSubscriptionDescription, TableOptions, TableUpdateOperation, TableV2Options, TrackDiffOptions, TrackPreviousOptions, Transaction, TriggerClaimManager, TriggerCreationHooks, TriggerDiffDeleteRecord, TriggerDiffHandlerContext, TriggerDiffInsertRecord, TriggerDiffRecord, TriggerDiffUpdateRecord, TriggerManager, TriggerManagerConfig, TriggerRemoveCallback, UpdateNotification, WatchCompatibleQuery, WatchExecuteOptions, WatchHandler, WatchOnChangeEvent, WatchOnChangeHandler, WatchedQuery, WatchedQueryComparator, WatchedQueryDifferential, WatchedQueryListener, WatchedQueryOptions, WatchedQueryRowDifferential, WatchedQuerySettings, WatchedQueryState, WithDiffOptions };
@@ -14,7 +14,8 @@ import { CrudBatch } from './sync/bucket/CrudBatch.js';
14
14
  import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
15
15
  import { InternalConnectionOptions, StreamingSyncImplementation, StreamingSyncImplementationListener, type AdditionalConnectionOptions, type PowerSyncConnectionOptions, type RequiredAdditionalConnectionOptions } from './sync/stream/AbstractStreamingSyncImplementation.js';
16
16
  import { SyncStream } from './sync/sync-streams.js';
17
- import { TriggerManager } from './triggers/TriggerManager.js';
17
+ import { TriggerManager, TriggerManagerConfig } from './triggers/TriggerManager.js';
18
+ import { TriggerManagerImpl } from './triggers/TriggerManagerImpl.js';
18
19
  import { WatchCompatibleQuery } from './watched/WatchedQuery.js';
19
20
  import { WatchedQueryComparator } from './watched/processors/comparators.js';
20
21
  export interface DisconnectAndClearOptions {
@@ -152,6 +153,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
152
153
  * Allows creating SQLite triggers which can be used to track various operations on SQLite tables.
153
154
  */
154
155
  readonly triggers: TriggerManager;
156
+ protected triggersImpl: TriggerManagerImpl;
155
157
  logger: ILogger;
156
158
  constructor(options: PowerSyncDatabaseOptionsWithDBAdapter);
157
159
  constructor(options: PowerSyncDatabaseOptionsWithOpenFactory);
@@ -178,6 +180,11 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
178
180
  * Opens the DBAdapter given open options using a default open factory
179
181
  */
180
182
  protected abstract openDBAdapter(options: PowerSyncDatabaseOptionsWithSettings): DBAdapter;
183
+ /**
184
+ * Generates a base configuration for {@link TriggerManagerImpl}.
185
+ * Implementations should override this if necessary.
186
+ */
187
+ protected generateTriggerManagerConfig(): TriggerManagerConfig;
181
188
  protected abstract generateSyncStreamImplementation(connector: PowerSyncBackendConnector, options: CreateSyncImplementationOptions & RequiredAdditionalConnectionOptions): StreamingSyncImplementation;
182
189
  protected abstract generateBucketStorageAdapter(): BucketStorageAdapter;
183
190
  /**
@@ -211,7 +218,7 @@ export declare abstract class AbstractPowerSyncDatabase extends BaseObserver<Pow
211
218
  * This is to be automatically executed in the constructor.
212
219
  */
213
220
  protected initialize(): Promise<void>;
214
- private _loadVersion;
221
+ protected loadVersion(): Promise<void>;
215
222
  protected resolveOfflineSyncStatus(): Promise<void>;
216
223
  /**
217
224
  * Replace the schema with a new version. This is for advanced use cases - typically the schema should just be specified once in the constructor.
@@ -16,6 +16,7 @@ import { CrudEntry } from './sync/bucket/CrudEntry.js';
16
16
  import { CrudTransaction } from './sync/bucket/CrudTransaction.js';
17
17
  import { DEFAULT_CRUD_UPLOAD_THROTTLE_MS, DEFAULT_RETRY_DELAY_MS } from './sync/stream/AbstractStreamingSyncImplementation.js';
18
18
  import { coreStatusToJs } from './sync/stream/core-instruction.js';
19
+ import { MEMORY_TRIGGER_CLAIM_MANAGER } from './triggers/MemoryTriggerClaimManager.js';
19
20
  import { TriggerManagerImpl } from './triggers/TriggerManagerImpl.js';
20
21
  import { DEFAULT_WATCH_THROTTLE_MS } from './watched/WatchedQuery.js';
21
22
  import { OnChangeQueryProcessor } from './watched/processors/OnChangeQueryProcessor.js';
@@ -87,6 +88,7 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
87
88
  * Allows creating SQLite triggers which can be used to track various operations on SQLite tables.
88
89
  */
89
90
  triggers;
91
+ triggersImpl;
90
92
  logger;
91
93
  constructor(options) {
92
94
  super();
@@ -150,9 +152,10 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
150
152
  logger: this.logger
151
153
  });
152
154
  this._isReadyPromise = this.initialize();
153
- this.triggers = new TriggerManagerImpl({
155
+ this.triggers = this.triggersImpl = new TriggerManagerImpl({
154
156
  db: this,
155
- schema: this.schema
157
+ schema: this.schema,
158
+ ...this.generateTriggerManagerConfig()
156
159
  });
157
160
  }
158
161
  /**
@@ -178,6 +181,15 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
178
181
  get connecting() {
179
182
  return this.currentStatus?.connecting || false;
180
183
  }
184
+ /**
185
+ * Generates a base configuration for {@link TriggerManagerImpl}.
186
+ * Implementations should override this if necessary.
187
+ */
188
+ generateTriggerManagerConfig() {
189
+ return {
190
+ claimManager: MEMORY_TRIGGER_CLAIM_MANAGER
191
+ };
192
+ }
181
193
  /**
182
194
  * @returns A promise which will resolve once initialization is completed.
183
195
  */
@@ -238,14 +250,15 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
238
250
  async initialize() {
239
251
  await this._initialize();
240
252
  await this.bucketStorageAdapter.init();
241
- await this._loadVersion();
253
+ await this.loadVersion();
242
254
  await this.updateSchema(this.options.schema);
243
255
  await this.resolveOfflineSyncStatus();
244
256
  await this.database.execute('PRAGMA RECURSIVE_TRIGGERS=TRUE');
257
+ await this.triggersImpl.cleanupResources();
245
258
  this.ready = true;
246
259
  this.iterateListeners((cb) => cb.initialized?.());
247
260
  }
248
- async _loadVersion() {
261
+ async loadVersion() {
249
262
  try {
250
263
  const { version } = await this.database.get('SELECT powersync_rs_version() as version');
251
264
  this.sdkVersion = version;
@@ -361,7 +374,6 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
361
374
  await this.disconnect();
362
375
  await this.waitForReady();
363
376
  const { clearLocal } = options;
364
- // TODO DB name, verify this is necessary with extension
365
377
  await this.database.writeTransaction(async (tx) => {
366
378
  await tx.execute('SELECT powersync_clear(?)', [clearLocal ? 1 : 0]);
367
379
  });
@@ -393,6 +405,7 @@ export class AbstractPowerSyncDatabase extends BaseObserver {
393
405
  if (this.closed) {
394
406
  return;
395
407
  }
408
+ this.triggersImpl.dispose();
396
409
  await this.iterateAsyncListeners(async (cb) => cb.closing?.());
397
410
  const { disconnect } = options;
398
411
  if (disconnect) {