@electric-sql/client 1.2.0 → 1.2.2

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.d.ts CHANGED
@@ -20,9 +20,31 @@ type NormalizedPgSnapshot = {
20
20
  xip_list: bigint[];
21
21
  };
22
22
  interface Header {
23
- [key: Exclude<string, `operation` | `control`>]: Value;
23
+ [key: Exclude<string, `operation` | `control` | `event`>]: Value;
24
24
  }
25
25
  type Operation = `insert` | `update` | `delete`;
26
+ /**
27
+ * A tag is a string identifying a reason for this row to be part of the shape.
28
+ *
29
+ * Tags can be composite, but they are always sent as a single string. Compound tags
30
+ * are separated by `|`. It's up to the client to split the tag into its components
31
+ * in order to react to move-outs correctly. Tag parts are guaranteed to not contain an
32
+ * unescaped `|` character (escaped as `\\|`) or be a literal `*`.
33
+ *
34
+ * Composite tag width is guaranteed to be fixed for a given shape.
35
+ */
36
+ type MoveTag = string;
37
+ /**
38
+ * A move-out pattern is a position and a value. The position is the index of the column
39
+ * that is being moved out. The value is the value of the column that is being moved out.
40
+ *
41
+ * Tag width and value order is fixed for a given shape, so the client can determine
42
+ * which tags match this pattern.
43
+ */
44
+ type MoveOutPattern = {
45
+ pos: number;
46
+ value: string;
47
+ };
26
48
  type ControlMessage = {
27
49
  headers: (Header & {
28
50
  control: `up-to-date` | `must-refetch`;
@@ -31,6 +53,12 @@ type ControlMessage = {
31
53
  control: `snapshot-end`;
32
54
  } & PostgresSnapshot);
33
55
  };
56
+ type EventMessage = {
57
+ headers: Header & {
58
+ event: `move-out`;
59
+ patterns: MoveOutPattern[];
60
+ };
61
+ };
34
62
  type ChangeMessage<T extends Row<unknown> = Row> = {
35
63
  key: string;
36
64
  value: T;
@@ -38,9 +66,12 @@ type ChangeMessage<T extends Row<unknown> = Row> = {
38
66
  headers: Header & {
39
67
  operation: Operation;
40
68
  txids?: number[];
69
+ /** Tags will always be present for changes if the shape has a subquery in its where clause, and are omitted otherwise.*/
70
+ tags?: MoveTag[];
71
+ removed_tags?: MoveTag[];
41
72
  };
42
73
  };
43
- type Message<T extends Row<unknown> = Row> = ControlMessage | ChangeMessage<T>;
74
+ type Message<T extends Row<unknown> = Row> = ControlMessage | EventMessage | ChangeMessage<T>;
44
75
  /**
45
76
  * Common properties for all columns.
46
77
  * `dims` is the number of dimensions of the column. Only provided if the column is an array.
@@ -808,4 +839,4 @@ declare function isControlMessage<T extends Row<unknown> = Row>(message: Message
808
839
  */
809
840
  declare function isVisibleInSnapshot(txid: number | bigint | `${bigint}`, snapshot: PostgresSnapshot | NormalizedPgSnapshot): boolean;
810
841
 
811
- export { BackoffDefaults, type BackoffOptions, type BitColumn, type BpcharColumn, type ChangeMessage, type ColumnInfo, type ColumnMapper, type CommonColumnProps, type ControlMessage, ELECTRIC_PROTOCOL_QUERY_PARAMS, type ExternalHeadersRecord, type ExternalParamsRecord, FetchError, type GetExtensions, type IntervalColumn, type IntervalColumnWithPrecision, type LogMode, type MaybePromise, type Message, type NormalizedPgSnapshot, type NumericColumn, type Offset, type Operation, type PostgresParams, type PostgresSnapshot, type RegularColumn, type Row, type Schema, Shape, type ShapeChangedCallback, type ShapeData, ShapeStream, type ShapeStreamInterface, type ShapeStreamOptions, type SnapshotMetadata, type SubsetParams, type TimeColumn, type TypedMessages, type Value, type VarcharColumn, camelToSnake, createColumnMapper, isChangeMessage, isControlMessage, isVisibleInSnapshot, resolveValue, snakeCamelMapper, snakeToCamel };
842
+ export { BackoffDefaults, type BackoffOptions, type BitColumn, type BpcharColumn, type ChangeMessage, type ColumnInfo, type ColumnMapper, type CommonColumnProps, type ControlMessage, ELECTRIC_PROTOCOL_QUERY_PARAMS, type EventMessage, type ExternalHeadersRecord, type ExternalParamsRecord, FetchError, type GetExtensions, type IntervalColumn, type IntervalColumnWithPrecision, type LogMode, type MaybePromise, type Message, type MoveOutPattern, type MoveTag, type NormalizedPgSnapshot, type NumericColumn, type Offset, type Operation, type PostgresParams, type PostgresSnapshot, type RegularColumn, type Row, type Schema, Shape, type ShapeChangedCallback, type ShapeData, ShapeStream, type ShapeStreamInterface, type ShapeStreamOptions, type SnapshotMetadata, type SubsetParams, type TimeColumn, type TypedMessages, type Value, type VarcharColumn, camelToSnake, createColumnMapper, isChangeMessage, isControlMessage, isVisibleInSnapshot, resolveValue, snakeCamelMapper, snakeToCamel };
@@ -270,6 +270,10 @@ function makeNullableParser(parser, columnInfo, columnName) {
270
270
  }
271
271
 
272
272
  // src/column-mapper.ts
273
+ function quoteIdentifier(identifier) {
274
+ const escaped = identifier.replace(/"/g, `""`);
275
+ return `"${escaped}"`;
276
+ }
273
277
  function snakeToCamel(str) {
274
278
  var _a, _b, _c, _d;
275
279
  const leadingUnderscores = (_b = (_a = str.match(/^_+/)) == null ? void 0 : _a[0]) != null ? _b : ``;
@@ -1417,7 +1421,7 @@ requestShape_fn = async function() {
1417
1421
  return __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
1418
1422
  };
1419
1423
  constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
1420
- var _a, _b, _c;
1424
+ var _a, _b, _c, _d;
1421
1425
  const [requestHeaders, params] = await Promise.all([
1422
1426
  resolveHeaders(this.options.headers),
1423
1427
  this.options.params ? toInternalParams(convertWhereParamsToObj(this.options.params)) : void 0
@@ -1433,8 +1437,21 @@ constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
1433
1437
  );
1434
1438
  setQueryParam(fetchUrl, WHERE_QUERY_PARAM, encodedWhere);
1435
1439
  }
1436
- if (params.columns)
1437
- setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, params.columns);
1440
+ if (params.columns) {
1441
+ const originalColumns = await resolveValue((_b = this.options.params) == null ? void 0 : _b.columns);
1442
+ if (Array.isArray(originalColumns)) {
1443
+ let encodedColumns = originalColumns.map(String);
1444
+ if (this.options.columnMapper) {
1445
+ encodedColumns = encodedColumns.map(
1446
+ this.options.columnMapper.encode
1447
+ );
1448
+ }
1449
+ const serializedColumns = encodedColumns.map(quoteIdentifier).join(`,`);
1450
+ setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, serializedColumns);
1451
+ } else {
1452
+ setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, params.columns);
1453
+ }
1454
+ }
1438
1455
  if (params.replica) setQueryParam(fetchUrl, REPLICA_PARAM, params.replica);
1439
1456
  if (params.params)
1440
1457
  setQueryParam(fetchUrl, WHERE_PARAMS_PARAM, params.params);
@@ -1452,7 +1469,7 @@ constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
1452
1469
  if (subsetParams.where && typeof subsetParams.where === `string`) {
1453
1470
  const encodedWhere = encodeWhereClause(
1454
1471
  subsetParams.where,
1455
- (_b = this.options.columnMapper) == null ? void 0 : _b.encode
1472
+ (_c = this.options.columnMapper) == null ? void 0 : _c.encode
1456
1473
  );
1457
1474
  setQueryParam(fetchUrl, SUBSET_PARAM_WHERE, encodedWhere);
1458
1475
  }
@@ -1468,7 +1485,7 @@ constructUrl_fn = async function(url, resumingFromPause, subsetParams) {
1468
1485
  if (subsetParams.orderBy && typeof subsetParams.orderBy === `string`) {
1469
1486
  const encodedOrderBy = encodeWhereClause(
1470
1487
  subsetParams.orderBy,
1471
- (_c = this.options.columnMapper) == null ? void 0 : _c.encode
1488
+ (_d = this.options.columnMapper) == null ? void 0 : _d.encode
1472
1489
  );
1473
1490
  setQueryParam(fetchUrl, SUBSET_PARAM_ORDER_BY, encodedOrderBy);
1474
1491
  }
@@ -1607,10 +1624,13 @@ requestShapeSSE_fn = async function(opts) {
1607
1624
  const { fetchUrl, requestAbortController, headers } = opts;
1608
1625
  const fetch2 = __privateGet(this, _sseFetchClient);
1609
1626
  __privateSet(this, _lastSseConnectionStartTime, Date.now());
1627
+ const sseHeaders = __spreadProps(__spreadValues({}, headers), {
1628
+ Accept: `text/event-stream`
1629
+ });
1610
1630
  try {
1611
1631
  let buffer = [];
1612
1632
  await fetchEventSource(fetchUrl.toString(), {
1613
- headers,
1633
+ headers: sseHeaders,
1614
1634
  fetch: fetch2,
1615
1635
  onopen: async (response) => {
1616
1636
  __privateSet(this, _connected, true);