@electric-sql/client 1.1.4 → 1.1.5

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.
@@ -256,15 +256,37 @@ var MessageParser = class {
256
256
  parse(messages, schema) {
257
257
  return JSON.parse(messages, (key, value) => {
258
258
  if ((key === `value` || key === `old_value`) && typeof value === `object` && value !== null) {
259
- const row = value;
260
- Object.keys(row).forEach((key2) => {
261
- row[key2] = this.parseRow(key2, row[key2], schema);
262
- });
263
- if (this.transformer) value = this.transformer(value);
259
+ return this.transformMessageValue(value, schema);
264
260
  }
265
261
  return value;
266
262
  });
267
263
  }
264
+ /**
265
+ * Parse an array of ChangeMessages from a snapshot response.
266
+ * Applies type parsing and transformations to the value and old_value properties.
267
+ */
268
+ parseSnapshotData(messages, schema) {
269
+ return messages.map((message) => {
270
+ const msg = message;
271
+ if (msg.value && typeof msg.value === `object` && msg.value !== null) {
272
+ msg.value = this.transformMessageValue(msg.value, schema);
273
+ }
274
+ if (msg.old_value && typeof msg.old_value === `object` && msg.old_value !== null) {
275
+ msg.old_value = this.transformMessageValue(msg.old_value, schema);
276
+ }
277
+ return msg;
278
+ });
279
+ }
280
+ /**
281
+ * Transform a message value or old_value object by parsing its columns.
282
+ */
283
+ transformMessageValue(value, schema) {
284
+ const row = value;
285
+ Object.keys(row).forEach((key) => {
286
+ row[key] = this.parseRow(key, row[key], schema);
287
+ });
288
+ return this.transformer ? this.transformer(row) : row;
289
+ }
268
290
  // Parses the message values using the provided parser based on the schema information
269
291
  parseRow(key, value, schema) {
270
292
  var _b;
@@ -810,7 +832,7 @@ function canonicalShapeKey(url) {
810
832
  cleanUrl.searchParams.sort();
811
833
  return cleanUrl.toString();
812
834
  }
813
- var _error, _fetchClient2, _sseFetchClient, _messageParser, _subscribers, _started, _state, _lastOffset, _liveCacheBuster, _lastSyncedAt, _isUpToDate, _isMidStream, _connected, _shapeHandle, _mode, _schema, _onError, _requestAbortController, _isRefreshing, _tickPromise, _tickPromiseResolver, _tickPromiseRejecter, _messageChain, _snapshotTracker, _activeSnapshotRequests, _midStreamPromise, _midStreamPromiseResolver, _lastSseConnectionStartTime, _minSseConnectionDuration, _consecutiveShortSseConnections, _maxShortSseConnections, _sseFallbackToLongPolling, _sseBackoffBaseDelay, _sseBackoffMaxDelay, _unsubscribeFromVisibilityChanges, _ShapeStream_instances, start_fn, requestShape_fn, constructUrl_fn, createAbortListener_fn, onInitialResponse_fn, onMessages_fn, fetchShape_fn, requestShapeLongPoll_fn, requestShapeSSE_fn, pause_fn, resume_fn, nextTick_fn, waitForStreamEnd_fn, publish_fn, sendErrorToSubscribers_fn, subscribeToVisibilityChanges_fn, reset_fn, fetchSnapshot_fn;
835
+ var _error, _fetchClient2, _sseFetchClient, _messageParser, _subscribers, _started, _state, _lastOffset, _liveCacheBuster, _lastSyncedAt, _isUpToDate, _isMidStream, _connected, _shapeHandle, _mode, _schema, _onError, _requestAbortController, _isRefreshing, _tickPromise, _tickPromiseResolver, _tickPromiseRejecter, _messageChain, _snapshotTracker, _activeSnapshotRequests, _midStreamPromise, _midStreamPromiseResolver, _lastSseConnectionStartTime, _minSseConnectionDuration, _consecutiveShortSseConnections, _maxShortSseConnections, _sseFallbackToLongPolling, _sseBackoffBaseDelay, _sseBackoffMaxDelay, _unsubscribeFromVisibilityChanges, _ShapeStream_instances, start_fn, requestShape_fn, constructUrl_fn, createAbortListener_fn, onInitialResponse_fn, onMessages_fn, fetchShape_fn, requestShapeLongPoll_fn, requestShapeSSE_fn, pause_fn, resume_fn, nextTick_fn, waitForStreamEnd_fn, publish_fn, sendErrorToSubscribers_fn, subscribeToVisibilityChanges_fn, reset_fn;
814
836
  var ShapeStream = class {
815
837
  constructor(options) {
816
838
  __privateAdd(this, _ShapeStream_instances);
@@ -957,7 +979,7 @@ var ShapeStream = class {
957
979
  });
958
980
  }
959
981
  /**
960
- * Request a snapshot for subset of data.
982
+ * Request a snapshot for subset of data and inject it into the subscribed data stream.
961
983
  *
962
984
  * Only available when mode is `changes_only`.
963
985
  * Returns the insertion point & the data, but more importantly injects the data
@@ -984,8 +1006,7 @@ var ShapeStream = class {
984
1006
  if (__privateGet(this, _activeSnapshotRequests) === 1) {
985
1007
  __privateMethod(this, _ShapeStream_instances, pause_fn).call(this);
986
1008
  }
987
- const { fetchUrl, requestHeaders } = yield __privateMethod(this, _ShapeStream_instances, constructUrl_fn).call(this, this.options.url, true, opts);
988
- const { metadata, data } = yield __privateMethod(this, _ShapeStream_instances, fetchSnapshot_fn).call(this, fetchUrl, requestHeaders);
1009
+ const { metadata, data } = yield this.fetchSnapshot(opts);
989
1010
  const dataWithEndBoundary = data.concat([
990
1011
  { headers: __spreadValues({ control: `snapshot-end` }, metadata) }
991
1012
  ]);
@@ -1006,6 +1027,44 @@ var ShapeStream = class {
1006
1027
  }
1007
1028
  });
1008
1029
  }
1030
+ /**
1031
+ * Fetch a snapshot for subset of data.
1032
+ * Returns the metadata and the data, but does not inject it into the subscribed data stream.
1033
+ *
1034
+ * @param opts - The options for the snapshot request.
1035
+ * @returns The metadata and the data for the snapshot.
1036
+ */
1037
+ fetchSnapshot(opts) {
1038
+ return __async(this, null, function* () {
1039
+ var _a;
1040
+ const { fetchUrl, requestHeaders } = yield __privateMethod(this, _ShapeStream_instances, constructUrl_fn).call(this, this.options.url, true, opts);
1041
+ const response = yield __privateGet(this, _fetchClient2).call(this, fetchUrl.toString(), {
1042
+ headers: requestHeaders
1043
+ });
1044
+ if (!response.ok) {
1045
+ throw new FetchError(
1046
+ response.status,
1047
+ void 0,
1048
+ void 0,
1049
+ Object.fromEntries([...response.headers.entries()]),
1050
+ fetchUrl.toString()
1051
+ );
1052
+ }
1053
+ const schema = (_a = __privateGet(this, _schema)) != null ? _a : getSchemaFromHeaders(response.headers, {
1054
+ required: true,
1055
+ url: fetchUrl.toString()
1056
+ });
1057
+ const { metadata, data: rawData } = yield response.json();
1058
+ const data = __privateGet(this, _messageParser).parseSnapshotData(
1059
+ rawData,
1060
+ schema
1061
+ );
1062
+ return {
1063
+ metadata,
1064
+ data
1065
+ };
1066
+ });
1067
+ }
1009
1068
  };
1010
1069
  _error = new WeakMap();
1011
1070
  _fetchClient2 = new WeakMap();
@@ -1180,7 +1239,8 @@ constructUrl_fn = function(url, resumingFromPause, subsetParams) {
1180
1239
  }
1181
1240
  fetchUrl.searchParams.set(OFFSET_QUERY_PARAM, __privateGet(this, _lastOffset));
1182
1241
  fetchUrl.searchParams.set(LOG_MODE_QUERY_PARAM, __privateGet(this, _mode));
1183
- if (__privateGet(this, _isUpToDate)) {
1242
+ const isSnapshotRequest = subsetParams !== void 0;
1243
+ if (__privateGet(this, _isUpToDate) && !isSnapshotRequest) {
1184
1244
  if (!__privateGet(this, _isRefreshing) && !resumingFromPause) {
1185
1245
  fetchUrl.searchParams.set(LIVE_QUERY_PARAM, `true`);
1186
1246
  }
@@ -1237,11 +1297,7 @@ onInitialResponse_fn = function(response) {
1237
1297
  if (liveCacheBuster) {
1238
1298
  __privateSet(this, _liveCacheBuster, liveCacheBuster);
1239
1299
  }
1240
- const getSchema = () => {
1241
- const schemaHeader = headers.get(SHAPE_SCHEMA_HEADER);
1242
- return schemaHeader ? JSON.parse(schemaHeader) : {};
1243
- };
1244
- __privateSet(this, _schema, (_a = __privateGet(this, _schema)) != null ? _a : getSchema());
1300
+ __privateSet(this, _schema, (_a = __privateGet(this, _schema)) != null ? _a : getSchemaFromHeaders(headers));
1245
1301
  if (status === 204) {
1246
1302
  __privateSet(this, _lastSyncedAt, Date.now());
1247
1303
  }
@@ -1469,33 +1525,20 @@ reset_fn = function(handle) {
1469
1525
  __privateSet(this, _consecutiveShortSseConnections, 0);
1470
1526
  __privateSet(this, _sseFallbackToLongPolling, false);
1471
1527
  };
1472
- fetchSnapshot_fn = function(url, headers) {
1473
- return __async(this, null, function* () {
1474
- const response = yield __privateGet(this, _fetchClient2).call(this, url.toString(), { headers });
1475
- if (!response.ok) {
1476
- throw new FetchError(
1477
- response.status,
1478
- void 0,
1479
- void 0,
1480
- Object.fromEntries([...response.headers.entries()]),
1481
- url.toString()
1482
- );
1483
- }
1484
- const { metadata, data } = yield response.json();
1485
- const batch = __privateGet(this, _messageParser).parse(
1486
- JSON.stringify(data),
1487
- __privateGet(this, _schema)
1488
- );
1489
- return {
1490
- metadata,
1491
- data: batch
1492
- };
1493
- });
1494
- };
1495
1528
  ShapeStream.Replica = {
1496
1529
  FULL: `full`,
1497
1530
  DEFAULT: `default`
1498
1531
  };
1532
+ function getSchemaFromHeaders(headers, options) {
1533
+ const schemaHeader = headers.get(SHAPE_SCHEMA_HEADER);
1534
+ if (!schemaHeader) {
1535
+ if ((options == null ? void 0 : options.required) && (options == null ? void 0 : options.url)) {
1536
+ throw new MissingHeadersError(options.url, [SHAPE_SCHEMA_HEADER]);
1537
+ }
1538
+ return {};
1539
+ }
1540
+ return JSON.parse(schemaHeader);
1541
+ }
1499
1542
  function validateParams(params) {
1500
1543
  if (!params) return;
1501
1544
  const reservedParams = Object.keys(params).filter(