@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.
package/dist/index.mjs CHANGED
@@ -225,15 +225,37 @@ var MessageParser = class {
225
225
  parse(messages, schema) {
226
226
  return JSON.parse(messages, (key, value) => {
227
227
  if ((key === `value` || key === `old_value`) && typeof value === `object` && value !== null) {
228
- const row = value;
229
- Object.keys(row).forEach((key2) => {
230
- row[key2] = this.parseRow(key2, row[key2], schema);
231
- });
232
- if (this.transformer) value = this.transformer(value);
228
+ return this.transformMessageValue(value, schema);
233
229
  }
234
230
  return value;
235
231
  });
236
232
  }
233
+ /**
234
+ * Parse an array of ChangeMessages from a snapshot response.
235
+ * Applies type parsing and transformations to the value and old_value properties.
236
+ */
237
+ parseSnapshotData(messages, schema) {
238
+ return messages.map((message) => {
239
+ const msg = message;
240
+ if (msg.value && typeof msg.value === `object` && msg.value !== null) {
241
+ msg.value = this.transformMessageValue(msg.value, schema);
242
+ }
243
+ if (msg.old_value && typeof msg.old_value === `object` && msg.old_value !== null) {
244
+ msg.old_value = this.transformMessageValue(msg.old_value, schema);
245
+ }
246
+ return msg;
247
+ });
248
+ }
249
+ /**
250
+ * Transform a message value or old_value object by parsing its columns.
251
+ */
252
+ transformMessageValue(value, schema) {
253
+ const row = value;
254
+ Object.keys(row).forEach((key) => {
255
+ row[key] = this.parseRow(key, row[key], schema);
256
+ });
257
+ return this.transformer ? this.transformer(row) : row;
258
+ }
237
259
  // Parses the message values using the provided parser based on the schema information
238
260
  parseRow(key, value, schema) {
239
261
  var _b;
@@ -781,7 +803,7 @@ function canonicalShapeKey(url) {
781
803
  cleanUrl.searchParams.sort();
782
804
  return cleanUrl.toString();
783
805
  }
784
- 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;
806
+ 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;
785
807
  var ShapeStream = class {
786
808
  constructor(options) {
787
809
  __privateAdd(this, _ShapeStream_instances);
@@ -928,7 +950,7 @@ var ShapeStream = class {
928
950
  });
929
951
  }
930
952
  /**
931
- * Request a snapshot for subset of data.
953
+ * Request a snapshot for subset of data and inject it into the subscribed data stream.
932
954
  *
933
955
  * Only available when mode is `changes_only`.
934
956
  * Returns the insertion point & the data, but more importantly injects the data
@@ -955,8 +977,7 @@ var ShapeStream = class {
955
977
  if (__privateGet(this, _activeSnapshotRequests) === 1) {
956
978
  __privateMethod(this, _ShapeStream_instances, pause_fn).call(this);
957
979
  }
958
- const { fetchUrl, requestHeaders } = yield __privateMethod(this, _ShapeStream_instances, constructUrl_fn).call(this, this.options.url, true, opts);
959
- const { metadata, data } = yield __privateMethod(this, _ShapeStream_instances, fetchSnapshot_fn).call(this, fetchUrl, requestHeaders);
980
+ const { metadata, data } = yield this.fetchSnapshot(opts);
960
981
  const dataWithEndBoundary = data.concat([
961
982
  { headers: __spreadValues({ control: `snapshot-end` }, metadata) }
962
983
  ]);
@@ -977,6 +998,44 @@ var ShapeStream = class {
977
998
  }
978
999
  });
979
1000
  }
1001
+ /**
1002
+ * Fetch a snapshot for subset of data.
1003
+ * Returns the metadata and the data, but does not inject it into the subscribed data stream.
1004
+ *
1005
+ * @param opts - The options for the snapshot request.
1006
+ * @returns The metadata and the data for the snapshot.
1007
+ */
1008
+ fetchSnapshot(opts) {
1009
+ return __async(this, null, function* () {
1010
+ var _a;
1011
+ const { fetchUrl, requestHeaders } = yield __privateMethod(this, _ShapeStream_instances, constructUrl_fn).call(this, this.options.url, true, opts);
1012
+ const response = yield __privateGet(this, _fetchClient2).call(this, fetchUrl.toString(), {
1013
+ headers: requestHeaders
1014
+ });
1015
+ if (!response.ok) {
1016
+ throw new FetchError(
1017
+ response.status,
1018
+ void 0,
1019
+ void 0,
1020
+ Object.fromEntries([...response.headers.entries()]),
1021
+ fetchUrl.toString()
1022
+ );
1023
+ }
1024
+ const schema = (_a = __privateGet(this, _schema)) != null ? _a : getSchemaFromHeaders(response.headers, {
1025
+ required: true,
1026
+ url: fetchUrl.toString()
1027
+ });
1028
+ const { metadata, data: rawData } = yield response.json();
1029
+ const data = __privateGet(this, _messageParser).parseSnapshotData(
1030
+ rawData,
1031
+ schema
1032
+ );
1033
+ return {
1034
+ metadata,
1035
+ data
1036
+ };
1037
+ });
1038
+ }
980
1039
  };
981
1040
  _error = new WeakMap();
982
1041
  _fetchClient2 = new WeakMap();
@@ -1151,7 +1210,8 @@ constructUrl_fn = function(url, resumingFromPause, subsetParams) {
1151
1210
  }
1152
1211
  fetchUrl.searchParams.set(OFFSET_QUERY_PARAM, __privateGet(this, _lastOffset));
1153
1212
  fetchUrl.searchParams.set(LOG_MODE_QUERY_PARAM, __privateGet(this, _mode));
1154
- if (__privateGet(this, _isUpToDate)) {
1213
+ const isSnapshotRequest = subsetParams !== void 0;
1214
+ if (__privateGet(this, _isUpToDate) && !isSnapshotRequest) {
1155
1215
  if (!__privateGet(this, _isRefreshing) && !resumingFromPause) {
1156
1216
  fetchUrl.searchParams.set(LIVE_QUERY_PARAM, `true`);
1157
1217
  }
@@ -1208,11 +1268,7 @@ onInitialResponse_fn = function(response) {
1208
1268
  if (liveCacheBuster) {
1209
1269
  __privateSet(this, _liveCacheBuster, liveCacheBuster);
1210
1270
  }
1211
- const getSchema = () => {
1212
- const schemaHeader = headers.get(SHAPE_SCHEMA_HEADER);
1213
- return schemaHeader ? JSON.parse(schemaHeader) : {};
1214
- };
1215
- __privateSet(this, _schema, (_a = __privateGet(this, _schema)) != null ? _a : getSchema());
1271
+ __privateSet(this, _schema, (_a = __privateGet(this, _schema)) != null ? _a : getSchemaFromHeaders(headers));
1216
1272
  if (status === 204) {
1217
1273
  __privateSet(this, _lastSyncedAt, Date.now());
1218
1274
  }
@@ -1440,33 +1496,20 @@ reset_fn = function(handle) {
1440
1496
  __privateSet(this, _consecutiveShortSseConnections, 0);
1441
1497
  __privateSet(this, _sseFallbackToLongPolling, false);
1442
1498
  };
1443
- fetchSnapshot_fn = function(url, headers) {
1444
- return __async(this, null, function* () {
1445
- const response = yield __privateGet(this, _fetchClient2).call(this, url.toString(), { headers });
1446
- if (!response.ok) {
1447
- throw new FetchError(
1448
- response.status,
1449
- void 0,
1450
- void 0,
1451
- Object.fromEntries([...response.headers.entries()]),
1452
- url.toString()
1453
- );
1454
- }
1455
- const { metadata, data } = yield response.json();
1456
- const batch = __privateGet(this, _messageParser).parse(
1457
- JSON.stringify(data),
1458
- __privateGet(this, _schema)
1459
- );
1460
- return {
1461
- metadata,
1462
- data: batch
1463
- };
1464
- });
1465
- };
1466
1499
  ShapeStream.Replica = {
1467
1500
  FULL: `full`,
1468
1501
  DEFAULT: `default`
1469
1502
  };
1503
+ function getSchemaFromHeaders(headers, options) {
1504
+ const schemaHeader = headers.get(SHAPE_SCHEMA_HEADER);
1505
+ if (!schemaHeader) {
1506
+ if ((options == null ? void 0 : options.required) && (options == null ? void 0 : options.url)) {
1507
+ throw new MissingHeadersError(options.url, [SHAPE_SCHEMA_HEADER]);
1508
+ }
1509
+ return {};
1510
+ }
1511
+ return JSON.parse(schemaHeader);
1512
+ }
1470
1513
  function validateParams(params) {
1471
1514
  if (!params) return;
1472
1515
  const reservedParams = Object.keys(params).filter(