@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
@@ -571,12 +571,30 @@ class SyncStatus {
571
571
  return {
572
572
  connected: this.connected,
573
573
  connecting: this.connecting,
574
- dataFlow: this.dataFlowStatus,
574
+ dataFlow: {
575
+ ...this.dataFlowStatus,
576
+ uploadError: this.serializeError(this.dataFlowStatus.uploadError),
577
+ downloadError: this.serializeError(this.dataFlowStatus.downloadError)
578
+ },
575
579
  lastSyncedAt: this.lastSyncedAt,
576
580
  hasSynced: this.hasSynced,
577
581
  priorityStatusEntries: this.priorityStatusEntries
578
582
  };
579
583
  }
584
+ /**
585
+ * Not all errors are serializable over a MessagePort. E.g. some `DomExceptions` fail to be passed across workers.
586
+ * This explicitly serializes errors in the SyncStatus.
587
+ */
588
+ serializeError(error) {
589
+ if (typeof error == 'undefined') {
590
+ return undefined;
591
+ }
592
+ return {
593
+ name: error.name,
594
+ message: error.message,
595
+ stack: error.stack
596
+ };
597
+ }
580
598
  static comparePriorities(a, b) {
581
599
  return b.priority - a.priority; // Reverse because higher priorities have lower numbers
582
600
  }
@@ -1931,7 +1949,7 @@ var hasRequiredFrames;
1931
1949
  function requireFrames () {
1932
1950
  if (hasRequiredFrames) return Frames;
1933
1951
  hasRequiredFrames = 1;
1934
- (function (exports) {
1952
+ (function (exports$1) {
1935
1953
  /*
1936
1954
  * Copyright 2021-2022 the original author or authors.
1937
1955
  *
@@ -1947,8 +1965,8 @@ function requireFrames () {
1947
1965
  * See the License for the specific language governing permissions and
1948
1966
  * limitations under the License.
1949
1967
  */
1950
- Object.defineProperty(exports, "__esModule", { value: true });
1951
- exports.Frame = exports.Lengths = exports.Flags = exports.FrameTypes = void 0;
1968
+ Object.defineProperty(exports$1, "__esModule", { value: true });
1969
+ exports$1.Frame = exports$1.Lengths = exports$1.Flags = exports$1.FrameTypes = void 0;
1952
1970
  var FrameTypes;
1953
1971
  (function (FrameTypes) {
1954
1972
  FrameTypes[FrameTypes["RESERVED"] = 0] = "RESERVED";
@@ -1967,7 +1985,7 @@ function requireFrames () {
1967
1985
  FrameTypes[FrameTypes["RESUME"] = 13] = "RESUME";
1968
1986
  FrameTypes[FrameTypes["RESUME_OK"] = 14] = "RESUME_OK";
1969
1987
  FrameTypes[FrameTypes["EXT"] = 63] = "EXT";
1970
- })(FrameTypes = exports.FrameTypes || (exports.FrameTypes = {}));
1988
+ })(FrameTypes = exports$1.FrameTypes || (exports$1.FrameTypes = {}));
1971
1989
  (function (Flags) {
1972
1990
  Flags[Flags["NONE"] = 0] = "NONE";
1973
1991
  Flags[Flags["COMPLETE"] = 64] = "COMPLETE";
@@ -1978,7 +1996,7 @@ function requireFrames () {
1978
1996
  Flags[Flags["NEXT"] = 32] = "NEXT";
1979
1997
  Flags[Flags["RESPOND"] = 128] = "RESPOND";
1980
1998
  Flags[Flags["RESUME_ENABLE"] = 128] = "RESUME_ENABLE";
1981
- })(exports.Flags || (exports.Flags = {}));
1999
+ })(exports$1.Flags || (exports$1.Flags = {}));
1982
2000
  (function (Flags) {
1983
2001
  function hasMetadata(flags) {
1984
2002
  return (flags & Flags.METADATA) === Flags.METADATA;
@@ -2012,13 +2030,13 @@ function requireFrames () {
2012
2030
  return (flags & Flags.RESUME_ENABLE) === Flags.RESUME_ENABLE;
2013
2031
  }
2014
2032
  Flags.hasResume = hasResume;
2015
- })(exports.Flags || (exports.Flags = {}));
2033
+ })(exports$1.Flags || (exports$1.Flags = {}));
2016
2034
  (function (Lengths) {
2017
2035
  Lengths[Lengths["FRAME"] = 3] = "FRAME";
2018
2036
  Lengths[Lengths["HEADER"] = 6] = "HEADER";
2019
2037
  Lengths[Lengths["METADATA"] = 3] = "METADATA";
2020
2038
  Lengths[Lengths["REQUEST"] = 3] = "REQUEST";
2021
- })(exports.Lengths || (exports.Lengths = {}));
2039
+ })(exports$1.Lengths || (exports$1.Lengths = {}));
2022
2040
  (function (Frame) {
2023
2041
  function isConnection(frame) {
2024
2042
  return frame.streamId === 0;
@@ -2029,7 +2047,7 @@ function requireFrames () {
2029
2047
  frame.type <= FrameTypes.REQUEST_CHANNEL);
2030
2048
  }
2031
2049
  Frame.isRequest = isRequest;
2032
- })(exports.Frame || (exports.Frame = {}));
2050
+ })(exports$1.Frame || (exports$1.Frame = {}));
2033
2051
 
2034
2052
  } (Frames));
2035
2053
  return Frames;
@@ -2040,7 +2058,7 @@ var hasRequiredCodecs;
2040
2058
  function requireCodecs () {
2041
2059
  if (hasRequiredCodecs) return Codecs;
2042
2060
  hasRequiredCodecs = 1;
2043
- (function (exports) {
2061
+ (function (exports$1) {
2044
2062
  var __generator = (Codecs && Codecs.__generator) || function (thisArg, body) {
2045
2063
  var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
2046
2064
  return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
@@ -2068,22 +2086,22 @@ function requireCodecs () {
2068
2086
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
2069
2087
  }
2070
2088
  };
2071
- Object.defineProperty(exports, "__esModule", { value: true });
2072
- exports.Deserializer = exports.sizeOfFrame = exports.serializeFrame = exports.deserializeFrame = exports.serializeFrameWithLength = exports.deserializeFrames = exports.deserializeFrameWithLength = exports.writeUInt64BE = exports.readUInt64BE = exports.writeUInt24BE = exports.readUInt24BE = exports.MAX_VERSION = exports.MAX_TTL = exports.MAX_STREAM_ID = exports.MAX_RESUME_LENGTH = exports.MAX_REQUEST_N = exports.MAX_REQUEST_COUNT = exports.MAX_MIME_LENGTH = exports.MAX_METADATA_LENGTH = exports.MAX_LIFETIME = exports.MAX_KEEPALIVE = exports.MAX_CODE = exports.FRAME_TYPE_OFFFSET = exports.FLAGS_MASK = void 0;
2089
+ Object.defineProperty(exports$1, "__esModule", { value: true });
2090
+ exports$1.Deserializer = exports$1.sizeOfFrame = exports$1.serializeFrame = exports$1.deserializeFrame = exports$1.serializeFrameWithLength = exports$1.deserializeFrames = exports$1.deserializeFrameWithLength = exports$1.writeUInt64BE = exports$1.readUInt64BE = exports$1.writeUInt24BE = exports$1.readUInt24BE = exports$1.MAX_VERSION = exports$1.MAX_TTL = exports$1.MAX_STREAM_ID = exports$1.MAX_RESUME_LENGTH = exports$1.MAX_REQUEST_N = exports$1.MAX_REQUEST_COUNT = exports$1.MAX_MIME_LENGTH = exports$1.MAX_METADATA_LENGTH = exports$1.MAX_LIFETIME = exports$1.MAX_KEEPALIVE = exports$1.MAX_CODE = exports$1.FRAME_TYPE_OFFFSET = exports$1.FLAGS_MASK = void 0;
2073
2091
  var Frames_1 = requireFrames();
2074
- exports.FLAGS_MASK = 0x3ff; // low 10 bits
2075
- exports.FRAME_TYPE_OFFFSET = 10; // frame type is offset 10 bytes within the uint16 containing type + flags
2076
- exports.MAX_CODE = 0x7fffffff; // uint31
2077
- exports.MAX_KEEPALIVE = 0x7fffffff; // uint31
2078
- exports.MAX_LIFETIME = 0x7fffffff; // uint31
2079
- exports.MAX_METADATA_LENGTH = 0xffffff; // uint24
2080
- exports.MAX_MIME_LENGTH = 0xff; // int8
2081
- exports.MAX_REQUEST_COUNT = 0x7fffffff; // uint31
2082
- exports.MAX_REQUEST_N = 0x7fffffff; // uint31
2083
- exports.MAX_RESUME_LENGTH = 0xffff; // uint16
2084
- exports.MAX_STREAM_ID = 0x7fffffff; // uint31
2085
- exports.MAX_TTL = 0x7fffffff; // uint31
2086
- exports.MAX_VERSION = 0xffff; // uint16
2092
+ exports$1.FLAGS_MASK = 0x3ff; // low 10 bits
2093
+ exports$1.FRAME_TYPE_OFFFSET = 10; // frame type is offset 10 bytes within the uint16 containing type + flags
2094
+ exports$1.MAX_CODE = 0x7fffffff; // uint31
2095
+ exports$1.MAX_KEEPALIVE = 0x7fffffff; // uint31
2096
+ exports$1.MAX_LIFETIME = 0x7fffffff; // uint31
2097
+ exports$1.MAX_METADATA_LENGTH = 0xffffff; // uint24
2098
+ exports$1.MAX_MIME_LENGTH = 0xff; // int8
2099
+ exports$1.MAX_REQUEST_COUNT = 0x7fffffff; // uint31
2100
+ exports$1.MAX_REQUEST_N = 0x7fffffff; // uint31
2101
+ exports$1.MAX_RESUME_LENGTH = 0xffff; // uint16
2102
+ exports$1.MAX_STREAM_ID = 0x7fffffff; // uint31
2103
+ exports$1.MAX_TTL = 0x7fffffff; // uint31
2104
+ exports$1.MAX_VERSION = 0xffff; // uint16
2087
2105
  /**
2088
2106
  * Mimimum value that would overflow bitwise operators (2^32).
2089
2107
  */
@@ -2097,7 +2115,7 @@ function requireCodecs () {
2097
2115
  var val3 = buffer.readUInt8(offset + 2);
2098
2116
  return val1 | val2 | val3;
2099
2117
  }
2100
- exports.readUInt24BE = readUInt24BE;
2118
+ exports$1.readUInt24BE = readUInt24BE;
2101
2119
  /**
2102
2120
  * Writes a uint24 to a buffer starting at the given offset, returning the
2103
2121
  * offset of the next byte.
@@ -2107,7 +2125,7 @@ function requireCodecs () {
2107
2125
  offset = buffer.writeUInt8((value >>> 8) & 0xff, offset); // 2nd byte
2108
2126
  return buffer.writeUInt8(value & 0xff, offset); // 1st byte
2109
2127
  }
2110
- exports.writeUInt24BE = writeUInt24BE;
2128
+ exports$1.writeUInt24BE = writeUInt24BE;
2111
2129
  /**
2112
2130
  * Read a uint64 (technically supports up to 53 bits per JS number
2113
2131
  * representation).
@@ -2117,7 +2135,7 @@ function requireCodecs () {
2117
2135
  var low = buffer.readUInt32BE(offset + 4);
2118
2136
  return high * BITWISE_OVERFLOW + low;
2119
2137
  }
2120
- exports.readUInt64BE = readUInt64BE;
2138
+ exports$1.readUInt64BE = readUInt64BE;
2121
2139
  /**
2122
2140
  * Write a uint64 (technically supports up to 53 bits per JS number
2123
2141
  * representation).
@@ -2128,7 +2146,7 @@ function requireCodecs () {
2128
2146
  offset = buffer.writeUInt32BE(high, offset); // first half of uint64
2129
2147
  return buffer.writeUInt32BE(low, offset); // second half of uint64
2130
2148
  }
2131
- exports.writeUInt64BE = writeUInt64BE;
2149
+ exports$1.writeUInt64BE = writeUInt64BE;
2132
2150
  /**
2133
2151
  * Frame header is:
2134
2152
  * - stream id (uint32 = 4)
@@ -2146,7 +2164,7 @@ function requireCodecs () {
2146
2164
  var frameLength = readUInt24BE(buffer, 0);
2147
2165
  return deserializeFrame(buffer.slice(UINT24_SIZE, UINT24_SIZE + frameLength));
2148
2166
  }
2149
- exports.deserializeFrameWithLength = deserializeFrameWithLength;
2167
+ exports$1.deserializeFrameWithLength = deserializeFrameWithLength;
2150
2168
  /**
2151
2169
  * Given a buffer that may contain zero or more length-prefixed frames followed
2152
2170
  * by zero or more bytes of a (partial) subsequent frame, returns an array of
@@ -2179,7 +2197,7 @@ function requireCodecs () {
2179
2197
  }
2180
2198
  });
2181
2199
  }
2182
- exports.deserializeFrames = deserializeFrames;
2200
+ exports$1.deserializeFrames = deserializeFrames;
2183
2201
  /**
2184
2202
  * Writes a frame to a buffer with a length prefix.
2185
2203
  */
@@ -2190,7 +2208,7 @@ function requireCodecs () {
2190
2208
  buffer.copy(lengthPrefixed, UINT24_SIZE);
2191
2209
  return lengthPrefixed;
2192
2210
  }
2193
- exports.serializeFrameWithLength = serializeFrameWithLength;
2211
+ exports$1.serializeFrameWithLength = serializeFrameWithLength;
2194
2212
  /**
2195
2213
  * Read a frame from the buffer.
2196
2214
  */
@@ -2205,8 +2223,8 @@ function requireCodecs () {
2205
2223
  // );
2206
2224
  var typeAndFlags = buffer.readUInt16BE(offset);
2207
2225
  offset += 2;
2208
- var type = typeAndFlags >>> exports.FRAME_TYPE_OFFFSET; // keep highest 6 bits
2209
- var flags = typeAndFlags & exports.FLAGS_MASK; // keep lowest 10 bits
2226
+ var type = typeAndFlags >>> exports$1.FRAME_TYPE_OFFFSET; // keep highest 6 bits
2227
+ var flags = typeAndFlags & exports$1.FLAGS_MASK; // keep lowest 10 bits
2210
2228
  switch (type) {
2211
2229
  case Frames_1.FrameTypes.SETUP:
2212
2230
  return deserializeSetupFrame(buffer, streamId, flags);
@@ -2243,7 +2261,7 @@ function requireCodecs () {
2243
2261
  // );
2244
2262
  }
2245
2263
  }
2246
- exports.deserializeFrame = deserializeFrame;
2264
+ exports$1.deserializeFrame = deserializeFrame;
2247
2265
  /**
2248
2266
  * Convert the frame to a (binary) buffer.
2249
2267
  */
@@ -2282,7 +2300,7 @@ function requireCodecs () {
2282
2300
  // );
2283
2301
  }
2284
2302
  }
2285
- exports.serializeFrame = serializeFrame;
2303
+ exports$1.serializeFrame = serializeFrame;
2286
2304
  /**
2287
2305
  * Byte size of frame without size prefix
2288
2306
  */
@@ -2321,7 +2339,7 @@ function requireCodecs () {
2321
2339
  // );
2322
2340
  }
2323
2341
  }
2324
- exports.sizeOfFrame = sizeOfFrame;
2342
+ exports$1.sizeOfFrame = sizeOfFrame;
2325
2343
  /**
2326
2344
  * Writes a SETUP frame into a new buffer and returns it.
2327
2345
  *
@@ -2956,7 +2974,7 @@ function requireCodecs () {
2956
2974
  function writeHeader(frame, buffer) {
2957
2975
  var offset = buffer.writeInt32BE(frame.streamId, 0);
2958
2976
  // shift frame to high 6 bits, extract lowest 10 bits from flags
2959
- return buffer.writeUInt16BE((frame.type << exports.FRAME_TYPE_OFFFSET) | (frame.flags & exports.FLAGS_MASK), offset);
2977
+ return buffer.writeUInt16BE((frame.type << exports$1.FRAME_TYPE_OFFFSET) | (frame.flags & exports$1.FLAGS_MASK), offset);
2960
2978
  }
2961
2979
  /**
2962
2980
  * Determine the length of the payload section of a frame. Only applies to
@@ -3037,7 +3055,7 @@ function requireCodecs () {
3037
3055
  };
3038
3056
  return Deserializer;
3039
3057
  }());
3040
- exports.Deserializer = Deserializer;
3058
+ exports$1.Deserializer = Deserializer;
3041
3059
 
3042
3060
  } (Codecs));
3043
3061
  return Codecs;
@@ -3183,7 +3201,7 @@ var hasRequiredErrors;
3183
3201
  function requireErrors () {
3184
3202
  if (hasRequiredErrors) return Errors;
3185
3203
  hasRequiredErrors = 1;
3186
- (function (exports) {
3204
+ (function (exports$1) {
3187
3205
  /*
3188
3206
  * Copyright 2021-2022 the original author or authors.
3189
3207
  *
@@ -3214,8 +3232,8 @@ function requireErrors () {
3214
3232
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
3215
3233
  };
3216
3234
  })();
3217
- Object.defineProperty(exports, "__esModule", { value: true });
3218
- exports.ErrorCodes = exports.RSocketError = void 0;
3235
+ Object.defineProperty(exports$1, "__esModule", { value: true });
3236
+ exports$1.ErrorCodes = exports$1.RSocketError = void 0;
3219
3237
  var RSocketError = /** @class */ (function (_super) {
3220
3238
  __extends(RSocketError, _super);
3221
3239
  function RSocketError(code, message) {
@@ -3225,7 +3243,7 @@ function requireErrors () {
3225
3243
  }
3226
3244
  return RSocketError;
3227
3245
  }(Error));
3228
- exports.RSocketError = RSocketError;
3246
+ exports$1.RSocketError = RSocketError;
3229
3247
  (function (ErrorCodes) {
3230
3248
  ErrorCodes[ErrorCodes["RESERVED"] = 0] = "RESERVED";
3231
3249
  ErrorCodes[ErrorCodes["INVALID_SETUP"] = 1] = "INVALID_SETUP";
@@ -3239,7 +3257,7 @@ function requireErrors () {
3239
3257
  ErrorCodes[ErrorCodes["CANCELED"] = 515] = "CANCELED";
3240
3258
  ErrorCodes[ErrorCodes["INVALID"] = 516] = "INVALID";
3241
3259
  ErrorCodes[ErrorCodes["RESERVED_EXTENSION"] = 4294967295] = "RESERVED_EXTENSION";
3242
- })(exports.ErrorCodes || (exports.ErrorCodes = {}));
3260
+ })(exports$1.ErrorCodes || (exports$1.ErrorCodes = {}));
3243
3261
 
3244
3262
  } (Errors));
3245
3263
  return Errors;
@@ -3281,7 +3299,7 @@ var hasRequiredClientServerMultiplexerDemultiplexer;
3281
3299
  function requireClientServerMultiplexerDemultiplexer () {
3282
3300
  if (hasRequiredClientServerMultiplexerDemultiplexer) return ClientServerMultiplexerDemultiplexer;
3283
3301
  hasRequiredClientServerMultiplexerDemultiplexer = 1;
3284
- (function (exports) {
3302
+ (function (exports$1) {
3285
3303
  /*
3286
3304
  * Copyright 2021-2022 the original author or authors.
3287
3305
  *
@@ -3348,8 +3366,8 @@ function requireClientServerMultiplexerDemultiplexer () {
3348
3366
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
3349
3367
  }
3350
3368
  };
3351
- Object.defineProperty(exports, "__esModule", { value: true });
3352
- exports.ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer = exports.ResumableClientServerInputMultiplexerDemultiplexer = exports.ClientServerInputMultiplexerDemultiplexer = exports.StreamIdGenerator = void 0;
3369
+ Object.defineProperty(exports$1, "__esModule", { value: true });
3370
+ exports$1.ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer = exports$1.ResumableClientServerInputMultiplexerDemultiplexer = exports$1.ClientServerInputMultiplexerDemultiplexer = exports$1.StreamIdGenerator = void 0;
3353
3371
  var _1 = requireDist();
3354
3372
  var Deferred_1 = requireDeferred();
3355
3373
  var Errors_1 = requireErrors();
@@ -3372,7 +3390,7 @@ function requireClientServerMultiplexerDemultiplexer () {
3372
3390
  };
3373
3391
  return StreamIdGeneratorImpl;
3374
3392
  }());
3375
- })(exports.StreamIdGenerator || (exports.StreamIdGenerator = {}));
3393
+ })(exports$1.StreamIdGenerator || (exports$1.StreamIdGenerator = {}));
3376
3394
  var ClientServerInputMultiplexerDemultiplexer = /** @class */ (function (_super) {
3377
3395
  __extends(ClientServerInputMultiplexerDemultiplexer, _super);
3378
3396
  function ClientServerInputMultiplexerDemultiplexer(streamIdSupplier, outbound, closeable) {
@@ -3461,7 +3479,7 @@ function requireClientServerMultiplexerDemultiplexer () {
3461
3479
  };
3462
3480
  return ClientServerInputMultiplexerDemultiplexer;
3463
3481
  }(Deferred_1.Deferred));
3464
- exports.ClientServerInputMultiplexerDemultiplexer = ClientServerInputMultiplexerDemultiplexer;
3482
+ exports$1.ClientServerInputMultiplexerDemultiplexer = ClientServerInputMultiplexerDemultiplexer;
3465
3483
  var ResumableClientServerInputMultiplexerDemultiplexer = /** @class */ (function (_super) {
3466
3484
  __extends(ResumableClientServerInputMultiplexerDemultiplexer, _super);
3467
3485
  function ResumableClientServerInputMultiplexerDemultiplexer(streamIdSupplier, outbound, closeable, frameStore, token, sessionStoreOrReconnector, sessionTimeout) {
@@ -3618,7 +3636,7 @@ function requireClientServerMultiplexerDemultiplexer () {
3618
3636
  };
3619
3637
  return ResumableClientServerInputMultiplexerDemultiplexer;
3620
3638
  }(ClientServerInputMultiplexerDemultiplexer));
3621
- exports.ResumableClientServerInputMultiplexerDemultiplexer = ResumableClientServerInputMultiplexerDemultiplexer;
3639
+ exports$1.ResumableClientServerInputMultiplexerDemultiplexer = ResumableClientServerInputMultiplexerDemultiplexer;
3622
3640
  var ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer = /** @class */ (function () {
3623
3641
  function ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer(outbound, closeable, delegate) {
3624
3642
  this.outbound = outbound;
@@ -3675,7 +3693,7 @@ function requireClientServerMultiplexerDemultiplexer () {
3675
3693
  };
3676
3694
  return ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer;
3677
3695
  }());
3678
- exports.ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer = ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer;
3696
+ exports$1.ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer = ResumeOkAwaitingResumableClientServerInputMultiplexerDemultiplexer;
3679
3697
 
3680
3698
  } (ClientServerMultiplexerDemultiplexer));
3681
3699
  return ClientServerMultiplexerDemultiplexer;
@@ -6661,7 +6679,7 @@ var hasRequiredDist;
6661
6679
  function requireDist () {
6662
6680
  if (hasRequiredDist) return dist;
6663
6681
  hasRequiredDist = 1;
6664
- (function (exports) {
6682
+ (function (exports$1) {
6665
6683
  /*
6666
6684
  * Copyright 2021-2022 the original author or authors.
6667
6685
  *
@@ -6684,19 +6702,19 @@ function requireDist () {
6684
6702
  if (k2 === undefined) k2 = k;
6685
6703
  o[k2] = m[k];
6686
6704
  }));
6687
- var __exportStar = (dist && dist.__exportStar) || function(m, exports) {
6688
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
6705
+ var __exportStar = (dist && dist.__exportStar) || function(m, exports$1) {
6706
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports$1, p)) __createBinding(exports$1, m, p);
6689
6707
  };
6690
- Object.defineProperty(exports, "__esModule", { value: true });
6691
- __exportStar(requireCodecs(), exports);
6692
- __exportStar(requireCommon(), exports);
6693
- __exportStar(requireDeferred(), exports);
6694
- __exportStar(requireErrors(), exports);
6695
- __exportStar(requireFrames(), exports);
6696
- __exportStar(requireRSocket(), exports);
6697
- __exportStar(requireRSocketConnector(), exports);
6698
- __exportStar(requireRSocketServer(), exports);
6699
- __exportStar(requireTransport(), exports);
6708
+ Object.defineProperty(exports$1, "__esModule", { value: true });
6709
+ __exportStar(requireCodecs(), exports$1);
6710
+ __exportStar(requireCommon(), exports$1);
6711
+ __exportStar(requireDeferred(), exports$1);
6712
+ __exportStar(requireErrors(), exports$1);
6713
+ __exportStar(requireFrames(), exports$1);
6714
+ __exportStar(requireRSocket(), exports$1);
6715
+ __exportStar(requireRSocketConnector(), exports$1);
6716
+ __exportStar(requireRSocketServer(), exports$1);
6717
+ __exportStar(requireTransport(), exports$1);
6700
6718
 
6701
6719
  } (dist));
6702
6720
  return dist;
@@ -6704,7 +6722,7 @@ function requireDist () {
6704
6722
 
6705
6723
  var distExports = requireDist();
6706
6724
 
6707
- var version = "1.44.0";
6725
+ var version = "1.46.0";
6708
6726
  var PACKAGE = {
6709
6727
  version: version};
6710
6728
 
@@ -6775,6 +6793,16 @@ class DataStream extends BaseObserver {
6775
6793
  * @returns a Data payload or Null if the stream closed.
6776
6794
  */
6777
6795
  async read() {
6796
+ if (this.closed) {
6797
+ return null;
6798
+ }
6799
+ // Wait for any pending processing to complete first.
6800
+ // This ensures we register our listener before calling processQueue(),
6801
+ // avoiding a race where processQueue() sees no reader and returns early.
6802
+ if (this.processingPromise) {
6803
+ await this.processingPromise;
6804
+ }
6805
+ // Re-check after await - stream may have closed while we were waiting
6778
6806
  if (this.closed) {
6779
6807
  return null;
6780
6808
  }
@@ -6814,7 +6842,7 @@ class DataStream extends BaseObserver {
6814
6842
  }
6815
6843
  const promise = (this.processingPromise = this._processQueue());
6816
6844
  promise.finally(() => {
6817
- return (this.processingPromise = null);
6845
+ this.processingPromise = null;
6818
6846
  });
6819
6847
  return promise;
6820
6848
  }
@@ -6846,7 +6874,6 @@ class DataStream extends BaseObserver {
6846
6874
  this.notifyDataAdded = null;
6847
6875
  }
6848
6876
  if (this.dataQueue.length > 0) {
6849
- // Next tick
6850
6877
  setTimeout(() => this.processQueue());
6851
6878
  }
6852
6879
  }
@@ -7466,7 +7493,11 @@ class AbstractRemote {
7466
7493
  };
7467
7494
  const stream = new DataStream({
7468
7495
  logger: this.logger,
7469
- mapLine: mapLine
7496
+ mapLine: mapLine,
7497
+ pressure: {
7498
+ highWaterMark: 20,
7499
+ lowWaterMark: 10
7500
+ }
7470
7501
  });
7471
7502
  abortSignal?.addEventListener('abort', () => {
7472
7503
  closeReader();
@@ -7474,42 +7505,47 @@ class AbstractRemote {
7474
7505
  });
7475
7506
  const decoder = this.createTextDecoder();
7476
7507
  let buffer = '';
7477
- const l = stream.registerListener({
7478
- lowWater: async () => {
7479
- if (stream.closed || abortSignal?.aborted || readerReleased) {
7508
+ const consumeStream = async () => {
7509
+ while (!stream.closed && !abortSignal?.aborted && !readerReleased) {
7510
+ const { done, value } = await reader.read();
7511
+ if (done) {
7512
+ const remaining = buffer.trim();
7513
+ if (remaining.length != 0) {
7514
+ stream.enqueueData(remaining);
7515
+ }
7516
+ stream.close();
7517
+ await closeReader();
7480
7518
  return;
7481
7519
  }
7482
- try {
7483
- let didCompleteLine = false;
7484
- while (!didCompleteLine) {
7485
- const { done, value } = await reader.read();
7486
- if (done) {
7487
- const remaining = buffer.trim();
7488
- if (remaining.length != 0) {
7489
- stream.enqueueData(remaining);
7490
- }
7491
- stream.close();
7492
- await closeReader();
7493
- return;
7494
- }
7495
- const data = decoder.decode(value, { stream: true });
7496
- buffer += data;
7497
- const lines = buffer.split('\n');
7498
- for (var i = 0; i < lines.length - 1; i++) {
7499
- var l = lines[i].trim();
7500
- if (l.length > 0) {
7501
- stream.enqueueData(l);
7502
- didCompleteLine = true;
7503
- }
7504
- }
7505
- buffer = lines[lines.length - 1];
7520
+ const data = decoder.decode(value, { stream: true });
7521
+ buffer += data;
7522
+ const lines = buffer.split('\n');
7523
+ for (var i = 0; i < lines.length - 1; i++) {
7524
+ var l = lines[i].trim();
7525
+ if (l.length > 0) {
7526
+ stream.enqueueData(l);
7506
7527
  }
7507
7528
  }
7508
- catch (ex) {
7509
- stream.close();
7510
- throw ex;
7529
+ buffer = lines[lines.length - 1];
7530
+ // Implement backpressure by waiting for the low water mark to be reached
7531
+ if (stream.dataQueue.length > stream.highWatermark) {
7532
+ await new Promise((resolve) => {
7533
+ const dispose = stream.registerListener({
7534
+ lowWater: async () => {
7535
+ resolve();
7536
+ dispose();
7537
+ },
7538
+ closed: () => {
7539
+ resolve();
7540
+ dispose();
7541
+ }
7542
+ });
7543
+ });
7511
7544
  }
7512
- },
7545
+ }
7546
+ };
7547
+ consumeStream().catch(ex => this.logger.error('Error consuming stream', ex));
7548
+ const l = stream.registerListener({
7513
7549
  closed: () => {
7514
7550
  closeReader();
7515
7551
  l?.();
@@ -7588,18 +7624,17 @@ exports.SyncClientImplementation = void 0;
7588
7624
  *
7589
7625
  * This is the default option.
7590
7626
  *
7591
- * @deprecated Don't use {@link SyncClientImplementation.JAVASCRIPT} directly. Instead, use
7592
- * {@link DEFAULT_SYNC_CLIENT_IMPLEMENTATION} or omit the option. The explicit choice to use
7593
- * the JavaScript-based sync implementation will be removed from a future version of the SDK.
7627
+ * @deprecated We recommend the {@link RUST} client implementation for all apps. If you have issues with
7628
+ * the Rust client, please file an issue or reach out to us. The JavaScript client will be removed in a future
7629
+ * version of the PowerSync SDK.
7594
7630
  */
7595
7631
  SyncClientImplementation["JAVASCRIPT"] = "js";
7596
7632
  /**
7597
7633
  * This implementation offloads the sync line decoding and handling into the PowerSync
7598
7634
  * core extension.
7599
7635
  *
7600
- * @experimental
7601
- * While this implementation is more performant than {@link SyncClientImplementation.JAVASCRIPT},
7602
- * it has seen less real-world testing and is marked as __experimental__ at the moment.
7636
+ * This option is more performant than the {@link JAVASCRIPT} client, enabled by default and the
7637
+ * recommended client implementation for all apps.
7603
7638
  *
7604
7639
  * ## Compatibility warning
7605
7640
  *
@@ -7617,13 +7652,9 @@ exports.SyncClientImplementation = void 0;
7617
7652
  SyncClientImplementation["RUST"] = "rust";
7618
7653
  })(exports.SyncClientImplementation || (exports.SyncClientImplementation = {}));
7619
7654
  /**
7620
- * The default {@link SyncClientImplementation} to use.
7621
- *
7622
- * Please use this field instead of {@link SyncClientImplementation.JAVASCRIPT} directly. A future version
7623
- * of the PowerSync SDK will enable {@link SyncClientImplementation.RUST} by default and remove the JavaScript
7624
- * option.
7655
+ * The default {@link SyncClientImplementation} to use, {@link SyncClientImplementation.RUST}.
7625
7656
  */
7626
- const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = exports.SyncClientImplementation.JAVASCRIPT;
7657
+ const DEFAULT_SYNC_CLIENT_IMPLEMENTATION = exports.SyncClientImplementation.RUST;
7627
7658
  const DEFAULT_CRUD_UPLOAD_THROTTLE_MS = 1000;
7628
7659
  const DEFAULT_RETRY_DELAY_MS = 5000;
7629
7660
  const DEFAULT_STREAMING_SYNC_OPTIONS = {
@@ -8033,6 +8064,9 @@ The next upload iteration will be delayed.`);
8033
8064
  if (rawTables != null && rawTables.length) {
8034
8065
  this.logger.warn('Raw tables require the Rust-based sync client. The JS client will ignore them.');
8035
8066
  }
8067
+ if (this.activeStreams.length) {
8068
+ this.logger.error('Sync streams require `clientImplementation: SyncClientImplementation.RUST` when connecting.');
8069
+ }
8036
8070
  this.logger.debug('Streaming sync iteration started');
8037
8071
  this.options.adapter.startSession();
8038
8072
  let [req, bucketMap] = await this.collectLocalBucketState();
@@ -8548,6 +8582,27 @@ The next upload iteration will be delayed.`);
8548
8582
  }
8549
8583
  }
8550
8584
 
8585
+ const CLAIM_STORE = new Map();
8586
+ /**
8587
+ * @internal
8588
+ * @experimental
8589
+ */
8590
+ const MEMORY_TRIGGER_CLAIM_MANAGER = {
8591
+ async obtainClaim(identifier) {
8592
+ if (CLAIM_STORE.has(identifier)) {
8593
+ throw new Error(`A claim is already present for ${identifier}`);
8594
+ }
8595
+ const release = async () => {
8596
+ CLAIM_STORE.delete(identifier);
8597
+ };
8598
+ CLAIM_STORE.set(identifier, release);
8599
+ return release;
8600
+ },
8601
+ async checkClaim(identifier) {
8602
+ return CLAIM_STORE.has(identifier);
8603
+ }
8604
+ };
8605
+
8551
8606
  /**
8552
8607
  * SQLite operations to track changes for with {@link TriggerManager}
8553
8608
  * @experimental
@@ -8559,9 +8614,20 @@ exports.DiffTriggerOperation = void 0;
8559
8614
  DiffTriggerOperation["DELETE"] = "DELETE";
8560
8615
  })(exports.DiffTriggerOperation || (exports.DiffTriggerOperation = {}));
8561
8616
 
8617
+ const DEFAULT_TRIGGER_MANAGER_CONFIGURATION = {
8618
+ useStorageByDefault: false
8619
+ };
8620
+ const TRIGGER_CLEANUP_INTERVAL_MS = 120_000; // 2 minutes
8621
+ /**
8622
+ * @internal
8623
+ * @experimental
8624
+ */
8562
8625
  class TriggerManagerImpl {
8563
8626
  options;
8564
8627
  schema;
8628
+ defaultConfig;
8629
+ cleanupTimeout;
8630
+ isDisposed;
8565
8631
  constructor(options) {
8566
8632
  this.options = options;
8567
8633
  this.schema = options.schema;
@@ -8570,6 +8636,33 @@ class TriggerManagerImpl {
8570
8636
  this.schema = schema;
8571
8637
  }
8572
8638
  });
8639
+ this.isDisposed = false;
8640
+ /**
8641
+ * Configure a cleanup to run on an interval.
8642
+ * The interval is configured using setTimeout to take the async
8643
+ * execution time of the callback into account.
8644
+ */
8645
+ this.defaultConfig = DEFAULT_TRIGGER_MANAGER_CONFIGURATION;
8646
+ const cleanupCallback = async () => {
8647
+ this.cleanupTimeout = null;
8648
+ if (this.isDisposed) {
8649
+ return;
8650
+ }
8651
+ try {
8652
+ await this.cleanupResources();
8653
+ }
8654
+ catch (ex) {
8655
+ this.db.logger.error(`Caught error while attempting to cleanup triggers`, ex);
8656
+ }
8657
+ finally {
8658
+ // if not closed, set another timeout
8659
+ if (this.isDisposed) {
8660
+ return;
8661
+ }
8662
+ this.cleanupTimeout = setTimeout(cleanupCallback, TRIGGER_CLEANUP_INTERVAL_MS);
8663
+ }
8664
+ };
8665
+ this.cleanupTimeout = setTimeout(cleanupCallback, TRIGGER_CLEANUP_INTERVAL_MS);
8573
8666
  }
8574
8667
  get db() {
8575
8668
  return this.options.db;
@@ -8587,13 +8680,95 @@ class TriggerManagerImpl {
8587
8680
  await tx.execute(/* sql */ `DROP TRIGGER IF EXISTS ${triggerId}; `);
8588
8681
  }
8589
8682
  }
8683
+ dispose() {
8684
+ this.isDisposed = true;
8685
+ if (this.cleanupTimeout) {
8686
+ clearTimeout(this.cleanupTimeout);
8687
+ }
8688
+ }
8689
+ /**
8690
+ * Updates default config settings for platform specific use-cases.
8691
+ */
8692
+ updateDefaults(config) {
8693
+ this.defaultConfig = {
8694
+ ...this.defaultConfig,
8695
+ ...config
8696
+ };
8697
+ }
8698
+ generateTriggerName(operation, destinationTable, triggerId) {
8699
+ return `__ps_temp_trigger_${operation.toLowerCase()}__${destinationTable}__${triggerId}`;
8700
+ }
8701
+ /**
8702
+ * Cleanup any SQLite triggers or tables that are no longer in use.
8703
+ */
8704
+ async cleanupResources() {
8705
+ // we use the database here since cleanupResources is called during the PowerSyncDatabase initialization
8706
+ await this.db.database.writeLock(async (ctx) => {
8707
+ /**
8708
+ * Note: We only cleanup persisted triggers. These are tracked in the sqlite_master table.
8709
+ * temporary triggers will not be affected by this.
8710
+ * Query all triggers that match our naming pattern
8711
+ */
8712
+ const triggers = await ctx.getAll(/* sql */ `
8713
+ SELECT
8714
+ name
8715
+ FROM
8716
+ sqlite_master
8717
+ WHERE
8718
+ type = 'trigger'
8719
+ AND name LIKE '__ps_temp_trigger_%'
8720
+ `);
8721
+ /** Use regex to extract table names and IDs from trigger names
8722
+ * Trigger naming convention: __ps_temp_trigger_<operation>__<destination_table>__<id>
8723
+ */
8724
+ const triggerPattern = /^__ps_temp_trigger_(?:insert|update|delete)__(.+)__([a-f0-9_]{36})$/i;
8725
+ const trackedItems = new Map();
8726
+ for (const trigger of triggers) {
8727
+ const match = trigger.name.match(triggerPattern);
8728
+ if (match) {
8729
+ const [, table, id] = match;
8730
+ // Collect all trigger names for each id combo
8731
+ const existing = trackedItems.get(id);
8732
+ if (existing) {
8733
+ existing.triggerNames.push(trigger.name);
8734
+ }
8735
+ else {
8736
+ trackedItems.set(id, { table, id, triggerNames: [trigger.name] });
8737
+ }
8738
+ }
8739
+ }
8740
+ for (const trackedItem of trackedItems.values()) {
8741
+ // check if there is anything holding on to this item
8742
+ const hasClaim = await this.options.claimManager.checkClaim(trackedItem.id);
8743
+ if (hasClaim) {
8744
+ // This does not require cleanup
8745
+ continue;
8746
+ }
8747
+ this.db.logger.debug(`Clearing resources for trigger ${trackedItem.id} with table ${trackedItem.table}`);
8748
+ // We need to delete the triggers and table
8749
+ for (const triggerName of trackedItem.triggerNames) {
8750
+ await ctx.execute(`DROP TRIGGER IF EXISTS ${triggerName}`);
8751
+ }
8752
+ await ctx.execute(`DROP TABLE IF EXISTS ${trackedItem.table}`);
8753
+ }
8754
+ });
8755
+ }
8590
8756
  async createDiffTrigger(options) {
8591
8757
  await this.db.waitForReady();
8592
- const { source, destination, columns, when, hooks } = options;
8758
+ const { source, destination, columns, when, hooks,
8759
+ // Fall back to the provided default if not given on this level
8760
+ useStorage = this.defaultConfig.useStorageByDefault } = options;
8593
8761
  const operations = Object.keys(when);
8594
8762
  if (operations.length == 0) {
8595
8763
  throw new Error('At least one WHEN operation must be specified for the trigger.');
8596
8764
  }
8765
+ /**
8766
+ * The clause to use when executing
8767
+ * CREATE ${tableTriggerTypeClause} TABLE
8768
+ * OR
8769
+ * CREATE ${tableTriggerTypeClause} TRIGGER
8770
+ */
8771
+ const tableTriggerTypeClause = !useStorage ? 'TEMP' : '';
8597
8772
  const whenClauses = Object.fromEntries(Object.entries(when).map(([operation, filter]) => [operation, `WHEN ${filter}`]));
8598
8773
  /**
8599
8774
  * Allow specifying the View name as the source.
@@ -8607,6 +8782,7 @@ class TriggerManagerImpl {
8607
8782
  const internalSource = sourceDefinition.internalName;
8608
8783
  const triggerIds = [];
8609
8784
  const id = await this.getUUID();
8785
+ const releaseStorageClaim = useStorage ? await this.options.claimManager.obtainClaim(id) : null;
8610
8786
  /**
8611
8787
  * We default to replicating all columns if no columns array is provided.
8612
8788
  */
@@ -8639,26 +8815,27 @@ class TriggerManagerImpl {
8639
8815
  return this.db.writeLock(async (tx) => {
8640
8816
  await this.removeTriggers(tx, triggerIds);
8641
8817
  await tx.execute(/* sql */ `DROP TABLE IF EXISTS ${destination};`);
8818
+ await releaseStorageClaim?.();
8642
8819
  });
8643
8820
  };
8644
8821
  const setup = async (tx) => {
8645
8822
  // Allow user code to execute in this lock context before the trigger is created.
8646
8823
  await hooks?.beforeCreate?.(tx);
8647
8824
  await tx.execute(/* sql */ `
8648
- CREATE TEMP TABLE ${destination} (
8825
+ CREATE ${tableTriggerTypeClause} TABLE ${destination} (
8649
8826
  operation_id INTEGER PRIMARY KEY AUTOINCREMENT,
8650
8827
  id TEXT,
8651
8828
  operation TEXT,
8652
8829
  timestamp TEXT,
8653
8830
  value TEXT,
8654
8831
  previous_value TEXT
8655
- );
8832
+ )
8656
8833
  `);
8657
8834
  if (operations.includes(exports.DiffTriggerOperation.INSERT)) {
8658
- const insertTriggerId = `ps_temp_trigger_insert_${id}`;
8835
+ const insertTriggerId = this.generateTriggerName(exports.DiffTriggerOperation.INSERT, destination, id);
8659
8836
  triggerIds.push(insertTriggerId);
8660
8837
  await tx.execute(/* sql */ `
8661
- CREATE TEMP TRIGGER ${insertTriggerId} AFTER INSERT ON ${internalSource} ${whenClauses[exports.DiffTriggerOperation.INSERT]} BEGIN
8838
+ CREATE ${tableTriggerTypeClause} TRIGGER ${insertTriggerId} AFTER INSERT ON ${internalSource} ${whenClauses[exports.DiffTriggerOperation.INSERT]} BEGIN
8662
8839
  INSERT INTO
8663
8840
  ${destination} (id, operation, timestamp, value)
8664
8841
  VALUES
@@ -8669,14 +8846,14 @@ class TriggerManagerImpl {
8669
8846
  ${jsonFragment('NEW')}
8670
8847
  );
8671
8848
 
8672
- END;
8849
+ END
8673
8850
  `);
8674
8851
  }
8675
8852
  if (operations.includes(exports.DiffTriggerOperation.UPDATE)) {
8676
- const updateTriggerId = `ps_temp_trigger_update_${id}`;
8853
+ const updateTriggerId = this.generateTriggerName(exports.DiffTriggerOperation.UPDATE, destination, id);
8677
8854
  triggerIds.push(updateTriggerId);
8678
8855
  await tx.execute(/* sql */ `
8679
- CREATE TEMP TRIGGER ${updateTriggerId} AFTER
8856
+ CREATE ${tableTriggerTypeClause} TRIGGER ${updateTriggerId} AFTER
8680
8857
  UPDATE ON ${internalSource} ${whenClauses[exports.DiffTriggerOperation.UPDATE]} BEGIN
8681
8858
  INSERT INTO
8682
8859
  ${destination} (id, operation, timestamp, value, previous_value)
@@ -8693,11 +8870,11 @@ class TriggerManagerImpl {
8693
8870
  `);
8694
8871
  }
8695
8872
  if (operations.includes(exports.DiffTriggerOperation.DELETE)) {
8696
- const deleteTriggerId = `ps_temp_trigger_delete_${id}`;
8873
+ const deleteTriggerId = this.generateTriggerName(exports.DiffTriggerOperation.DELETE, destination, id);
8697
8874
  triggerIds.push(deleteTriggerId);
8698
8875
  // Create delete trigger for basic JSON
8699
8876
  await tx.execute(/* sql */ `
8700
- CREATE TEMP TRIGGER ${deleteTriggerId} AFTER DELETE ON ${internalSource} ${whenClauses[exports.DiffTriggerOperation.DELETE]} BEGIN
8877
+ CREATE ${tableTriggerTypeClause} TRIGGER ${deleteTriggerId} AFTER DELETE ON ${internalSource} ${whenClauses[exports.DiffTriggerOperation.DELETE]} BEGIN
8701
8878
  INSERT INTO
8702
8879
  ${destination} (id, operation, timestamp, value)
8703
8880
  VALUES
@@ -8741,7 +8918,7 @@ class TriggerManagerImpl {
8741
8918
  // If no array is provided, we use all columns from the source table.
8742
8919
  const contextColumns = columns ?? sourceDefinition.columns.map((col) => col.name);
8743
8920
  const id = await this.getUUID();
8744
- const destination = `ps_temp_track_${source}_${id}`;
8921
+ const destination = `__ps_temp_track_${source}_${id}`;
8745
8922
  // register an onChange before the trigger is created
8746
8923
  const abortController = new AbortController();
8747
8924
  const abortOnChange = () => abortController.abort();
@@ -8896,6 +9073,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
8896
9073
  * Allows creating SQLite triggers which can be used to track various operations on SQLite tables.
8897
9074
  */
8898
9075
  triggers;
9076
+ triggersImpl;
8899
9077
  logger;
8900
9078
  constructor(options) {
8901
9079
  super();
@@ -8959,9 +9137,10 @@ class AbstractPowerSyncDatabase extends BaseObserver {
8959
9137
  logger: this.logger
8960
9138
  });
8961
9139
  this._isReadyPromise = this.initialize();
8962
- this.triggers = new TriggerManagerImpl({
9140
+ this.triggers = this.triggersImpl = new TriggerManagerImpl({
8963
9141
  db: this,
8964
- schema: this.schema
9142
+ schema: this.schema,
9143
+ ...this.generateTriggerManagerConfig()
8965
9144
  });
8966
9145
  }
8967
9146
  /**
@@ -8987,6 +9166,15 @@ class AbstractPowerSyncDatabase extends BaseObserver {
8987
9166
  get connecting() {
8988
9167
  return this.currentStatus?.connecting || false;
8989
9168
  }
9169
+ /**
9170
+ * Generates a base configuration for {@link TriggerManagerImpl}.
9171
+ * Implementations should override this if necessary.
9172
+ */
9173
+ generateTriggerManagerConfig() {
9174
+ return {
9175
+ claimManager: MEMORY_TRIGGER_CLAIM_MANAGER
9176
+ };
9177
+ }
8990
9178
  /**
8991
9179
  * @returns A promise which will resolve once initialization is completed.
8992
9180
  */
@@ -9047,14 +9235,15 @@ class AbstractPowerSyncDatabase extends BaseObserver {
9047
9235
  async initialize() {
9048
9236
  await this._initialize();
9049
9237
  await this.bucketStorageAdapter.init();
9050
- await this._loadVersion();
9238
+ await this.loadVersion();
9051
9239
  await this.updateSchema(this.options.schema);
9052
9240
  await this.resolveOfflineSyncStatus();
9053
9241
  await this.database.execute('PRAGMA RECURSIVE_TRIGGERS=TRUE');
9242
+ await this.triggersImpl.cleanupResources();
9054
9243
  this.ready = true;
9055
9244
  this.iterateListeners((cb) => cb.initialized?.());
9056
9245
  }
9057
- async _loadVersion() {
9246
+ async loadVersion() {
9058
9247
  try {
9059
9248
  const { version } = await this.database.get('SELECT powersync_rs_version() as version');
9060
9249
  this.sdkVersion = version;
@@ -9170,7 +9359,6 @@ class AbstractPowerSyncDatabase extends BaseObserver {
9170
9359
  await this.disconnect();
9171
9360
  await this.waitForReady();
9172
9361
  const { clearLocal } = options;
9173
- // TODO DB name, verify this is necessary with extension
9174
9362
  await this.database.writeTransaction(async (tx) => {
9175
9363
  await tx.execute('SELECT powersync_clear(?)', [clearLocal ? 1 : 0]);
9176
9364
  });
@@ -9202,6 +9390,7 @@ class AbstractPowerSyncDatabase extends BaseObserver {
9202
9390
  if (this.closed) {
9203
9391
  return;
9204
9392
  }
9393
+ this.triggersImpl.dispose();
9205
9394
  await this.iterateAsyncListeners(async (cb) => cb.closing?.());
9206
9395
  const { disconnect } = options;
9207
9396
  if (disconnect) {
@@ -10193,6 +10382,27 @@ class SyncDataBatch {
10193
10382
  }
10194
10383
  }
10195
10384
 
10385
+ /**
10386
+ * Thrown when an underlying database connection is closed.
10387
+ * This is particularly relevant when worker connections are marked as closed while
10388
+ * operations are still in progress.
10389
+ */
10390
+ class ConnectionClosedError extends Error {
10391
+ static NAME = 'ConnectionClosedError';
10392
+ static MATCHES(input) {
10393
+ /**
10394
+ * If there are weird package issues which cause multiple versions of classes to be present, the instanceof
10395
+ * check might fail. This also performs a failsafe check.
10396
+ * This might also happen if the Error is serialized and parsed over a bridging channel like a MessagePort.
10397
+ */
10398
+ return (input instanceof ConnectionClosedError || (input instanceof Error && input.name == ConnectionClosedError.NAME));
10399
+ }
10400
+ constructor(message) {
10401
+ super(message);
10402
+ this.name = ConnectionClosedError.NAME;
10403
+ }
10404
+ }
10405
+
10196
10406
  // https://www.sqlite.org/lang_expr.html#castexpr
10197
10407
  exports.ColumnType = void 0;
10198
10408
  (function (ColumnType) {
@@ -10756,6 +10966,7 @@ exports.AbstractStreamingSyncImplementation = AbstractStreamingSyncImplementatio
10756
10966
  exports.ArrayComparator = ArrayComparator;
10757
10967
  exports.BaseObserver = BaseObserver;
10758
10968
  exports.Column = Column;
10969
+ exports.ConnectionClosedError = ConnectionClosedError;
10759
10970
  exports.ConnectionManager = ConnectionManager;
10760
10971
  exports.ControlledExecutor = ControlledExecutor;
10761
10972
  exports.CrudBatch = CrudBatch;
@@ -10791,9 +11002,11 @@ exports.InvalidSQLCharacters = InvalidSQLCharacters;
10791
11002
  exports.LogLevel = LogLevel;
10792
11003
  exports.MAX_AMOUNT_OF_COLUMNS = MAX_AMOUNT_OF_COLUMNS;
10793
11004
  exports.MAX_OP_ID = MAX_OP_ID;
11005
+ exports.MEMORY_TRIGGER_CLAIM_MANAGER = MEMORY_TRIGGER_CLAIM_MANAGER;
10794
11006
  exports.OnChangeQueryProcessor = OnChangeQueryProcessor;
10795
11007
  exports.OpType = OpType;
10796
11008
  exports.OplogEntry = OplogEntry;
11009
+ exports.RawTable = RawTable;
10797
11010
  exports.Schema = Schema;
10798
11011
  exports.SqliteBucketStorage = SqliteBucketStorage;
10799
11012
  exports.SyncDataBatch = SyncDataBatch;
@@ -10802,6 +11015,7 @@ exports.SyncProgress = SyncProgress;
10802
11015
  exports.SyncStatus = SyncStatus;
10803
11016
  exports.Table = Table;
10804
11017
  exports.TableV2 = TableV2;
11018
+ exports.TriggerManagerImpl = TriggerManagerImpl;
10805
11019
  exports.UploadQueueStats = UploadQueueStats;
10806
11020
  exports.column = column;
10807
11021
  exports.compilableQueryWatch = compilableQueryWatch;