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