@electric-sql/client 1.0.3 → 1.0.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.
@@ -245,6 +245,12 @@ function isControlMessage(message) {
245
245
  function isUpToDateMessage(message) {
246
246
  return isControlMessage(message) && message.headers.control === `up-to-date`;
247
247
  }
248
+ function getOffset(message) {
249
+ const lsn = Number(message.headers.global_last_seen_lsn);
250
+ if (lsn && !isNaN(lsn)) {
251
+ return `${lsn}_0`;
252
+ }
253
+ }
248
254
 
249
255
  // src/constants.ts
250
256
  var LIVE_CACHE_BUSTER_HEADER = `electric-cursor`;
@@ -261,7 +267,9 @@ var TABLE_QUERY_PARAM = `table`;
261
267
  var WHERE_QUERY_PARAM = `where`;
262
268
  var REPLICA_PARAM = `replica`;
263
269
  var WHERE_PARAMS_PARAM = `params`;
270
+ var EXPERIMENTAL_LIVE_SSE_QUERY_PARAM = `experimental_live_sse`;
264
271
  var FORCE_DISCONNECT_AND_REFRESH = `force-disconnect-and-refresh`;
272
+ var PAUSE_STREAM = `pause-stream`;
265
273
 
266
274
  // src/fetch.ts
267
275
  var HTTP_RETRY_STATUS_CODES = [429];
@@ -270,7 +278,7 @@ var BackoffDefaults = {
270
278
  maxDelay: 1e4,
271
279
  multiplier: 1.3
272
280
  };
273
- function createFetchWithBackoff(fetchClient, backoffOptions = BackoffDefaults) {
281
+ function createFetchWithBackoff(fetchClient, backoffOptions = BackoffDefaults, sseMode = false) {
274
282
  const {
275
283
  initialDelay,
276
284
  maxDelay,
@@ -288,7 +296,11 @@ function createFetchWithBackoff(fetchClient, backoffOptions = BackoffDefaults) {
288
296
  try {
289
297
  const result = await fetchClient(...args);
290
298
  if (result.ok) return result;
291
- else throw await FetchError.fromResponse(result, url.toString());
299
+ const err = await FetchError.fromResponse(result, url.toString());
300
+ if (err.status === 409 && sseMode) {
301
+ err.json = [err.json];
302
+ }
303
+ throw err;
292
304
  } catch (e) {
293
305
  onFailedAttempt == null ? void 0 : onFailedAttempt();
294
306
  if ((_a = options == null ? void 0 : options.signal) == null ? void 0 : _a.aborted) {
@@ -486,6 +498,9 @@ function noop() {
486
498
  }
487
499
 
488
500
  // src/client.ts
501
+ import {
502
+ fetchEventSource
503
+ } from "@microsoft/fetch-event-source";
489
504
  var RESERVED_PARAMS = /* @__PURE__ */ new Set([
490
505
  LIVE_CACHE_BUSTER_QUERY_PARAM,
491
506
  SHAPE_HANDLE_QUERY_PARAM,
@@ -522,15 +537,18 @@ async function resolveHeaders(headers) {
522
537
  );
523
538
  return Object.fromEntries(resolvedEntries);
524
539
  }
525
- var _error, _fetchClient2, _messageParser, _subscribers, _started, _lastOffset, _liveCacheBuster, _lastSyncedAt, _isUpToDate, _connected, _shapeHandle, _schema, _onError, _requestAbortController, _isRefreshing, _tickPromise, _tickPromiseResolver, _tickPromiseRejecter, _ShapeStream_instances, start_fn, nextTick_fn, publish_fn, sendErrorToSubscribers_fn, reset_fn;
540
+ var _error, _fetchClient2, _sseFetchClient, _messageParser, _subscribers, _started, _state, _lastOffset, _liveCacheBuster, _lastSyncedAt, _isUpToDate, _connected, _shapeHandle, _schema, _onError, _requestAbortController, _isRefreshing, _tickPromise, _tickPromiseResolver, _tickPromiseRejecter, _messageChain, _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, publish_fn, sendErrorToSubscribers_fn, subscribeToVisibilityChanges_fn, reset_fn;
526
541
  var ShapeStream = class {
542
+ // promise chain for incoming messages
527
543
  constructor(options) {
528
544
  __privateAdd(this, _ShapeStream_instances);
529
545
  __privateAdd(this, _error, null);
530
546
  __privateAdd(this, _fetchClient2);
547
+ __privateAdd(this, _sseFetchClient);
531
548
  __privateAdd(this, _messageParser);
532
549
  __privateAdd(this, _subscribers, /* @__PURE__ */ new Map());
533
550
  __privateAdd(this, _started, false);
551
+ __privateAdd(this, _state, `active`);
534
552
  __privateAdd(this, _lastOffset);
535
553
  __privateAdd(this, _liveCacheBuster);
536
554
  // Seconds since our Electric Epoch 😎
@@ -546,6 +564,7 @@ var ShapeStream = class {
546
564
  __privateAdd(this, _tickPromise);
547
565
  __privateAdd(this, _tickPromiseResolver);
548
566
  __privateAdd(this, _tickPromiseRejecter);
567
+ __privateAdd(this, _messageChain, Promise.resolve([]));
549
568
  var _a, _b, _c;
550
569
  this.options = __spreadValues({ subscribe: true }, options);
551
570
  validateOptions(this.options);
@@ -555,18 +574,31 @@ var ShapeStream = class {
555
574
  __privateSet(this, _messageParser, new MessageParser(options.parser));
556
575
  __privateSet(this, _onError, this.options.onError);
557
576
  const baseFetchClient = (_b = options.fetchClient) != null ? _b : (...args) => fetch(...args);
558
- const fetchWithBackoffClient = createFetchWithBackoff(baseFetchClient, __spreadProps(__spreadValues({}, (_c = options.backoffOptions) != null ? _c : BackoffDefaults), {
577
+ const backOffOpts = __spreadProps(__spreadValues({}, (_c = options.backoffOptions) != null ? _c : BackoffDefaults), {
559
578
  onFailedAttempt: () => {
560
579
  var _a2, _b2;
561
580
  __privateSet(this, _connected, false);
562
581
  (_b2 = (_a2 = options.backoffOptions) == null ? void 0 : _a2.onFailedAttempt) == null ? void 0 : _b2.call(_a2);
563
582
  }
564
- }));
583
+ });
584
+ const fetchWithBackoffClient = createFetchWithBackoff(
585
+ baseFetchClient,
586
+ backOffOpts
587
+ );
565
588
  __privateSet(this, _fetchClient2, createFetchWithConsumedMessages(
566
589
  createFetchWithResponseHeadersCheck(
567
590
  createFetchWithChunkBuffer(fetchWithBackoffClient)
568
591
  )
569
592
  ));
593
+ const sseFetchWithBackoffClient = createFetchWithBackoff(
594
+ baseFetchClient,
595
+ backOffOpts,
596
+ true
597
+ );
598
+ __privateSet(this, _sseFetchClient, createFetchWithResponseHeadersCheck(
599
+ createFetchWithChunkBuffer(sseFetchWithBackoffClient)
600
+ ));
601
+ __privateMethod(this, _ShapeStream_instances, subscribeToVisibilityChanges_fn).call(this);
570
602
  }
571
603
  get shapeHandle() {
572
604
  return __privateGet(this, _shapeHandle);
@@ -612,6 +644,9 @@ var ShapeStream = class {
612
644
  hasStarted() {
613
645
  return __privateGet(this, _started);
614
646
  }
647
+ isPaused() {
648
+ return __privateGet(this, _state) === `paused`;
649
+ }
615
650
  /**
616
651
  * Refreshes the shape stream.
617
652
  * This preemptively aborts any ongoing long poll and reconnects without
@@ -630,9 +665,11 @@ var ShapeStream = class {
630
665
  };
631
666
  _error = new WeakMap();
632
667
  _fetchClient2 = new WeakMap();
668
+ _sseFetchClient = new WeakMap();
633
669
  _messageParser = new WeakMap();
634
670
  _subscribers = new WeakMap();
635
671
  _started = new WeakMap();
672
+ _state = new WeakMap();
636
673
  _lastOffset = new WeakMap();
637
674
  _liveCacheBuster = new WeakMap();
638
675
  _lastSyncedAt = new WeakMap();
@@ -646,133 +683,13 @@ _isRefreshing = new WeakMap();
646
683
  _tickPromise = new WeakMap();
647
684
  _tickPromiseResolver = new WeakMap();
648
685
  _tickPromiseRejecter = new WeakMap();
686
+ _messageChain = new WeakMap();
649
687
  _ShapeStream_instances = new WeakSet();
650
688
  start_fn = async function() {
651
- var _a, _b, _c, _d, _e;
652
- if (__privateGet(this, _started)) throw new Error(`Cannot start stream twice`);
689
+ var _a;
653
690
  __privateSet(this, _started, true);
654
691
  try {
655
- while (!((_a = this.options.signal) == null ? void 0 : _a.aborted) && !__privateGet(this, _isUpToDate) || this.options.subscribe) {
656
- const { url, signal } = this.options;
657
- const [requestHeaders, params] = await Promise.all([
658
- resolveHeaders(this.options.headers),
659
- this.options.params ? toInternalParams(convertWhereParamsToObj(this.options.params)) : void 0
660
- ]);
661
- if (params) {
662
- validateParams(params);
663
- }
664
- const fetchUrl = new URL(url);
665
- if (params) {
666
- if (params.table)
667
- setQueryParam(fetchUrl, TABLE_QUERY_PARAM, params.table);
668
- if (params.where)
669
- setQueryParam(fetchUrl, WHERE_QUERY_PARAM, params.where);
670
- if (params.columns)
671
- setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, params.columns);
672
- if (params.replica)
673
- setQueryParam(fetchUrl, REPLICA_PARAM, params.replica);
674
- if (params.params)
675
- setQueryParam(fetchUrl, WHERE_PARAMS_PARAM, params.params);
676
- const customParams = __spreadValues({}, params);
677
- delete customParams.table;
678
- delete customParams.where;
679
- delete customParams.columns;
680
- delete customParams.replica;
681
- delete customParams.params;
682
- for (const [key, value] of Object.entries(customParams)) {
683
- setQueryParam(fetchUrl, key, value);
684
- }
685
- }
686
- fetchUrl.searchParams.set(OFFSET_QUERY_PARAM, __privateGet(this, _lastOffset));
687
- if (__privateGet(this, _isUpToDate)) {
688
- if (!__privateGet(this, _isRefreshing)) {
689
- fetchUrl.searchParams.set(LIVE_QUERY_PARAM, `true`);
690
- }
691
- fetchUrl.searchParams.set(
692
- LIVE_CACHE_BUSTER_QUERY_PARAM,
693
- __privateGet(this, _liveCacheBuster)
694
- );
695
- }
696
- if (__privateGet(this, _shapeHandle)) {
697
- fetchUrl.searchParams.set(
698
- SHAPE_HANDLE_QUERY_PARAM,
699
- __privateGet(this, _shapeHandle)
700
- );
701
- }
702
- fetchUrl.searchParams.sort();
703
- __privateSet(this, _requestAbortController, new AbortController());
704
- let abortListener;
705
- if (signal) {
706
- abortListener = () => {
707
- var _a2;
708
- (_a2 = __privateGet(this, _requestAbortController)) == null ? void 0 : _a2.abort(signal.reason);
709
- };
710
- signal.addEventListener(`abort`, abortListener, { once: true });
711
- if (signal.aborted) {
712
- (_b = __privateGet(this, _requestAbortController)) == null ? void 0 : _b.abort(signal.reason);
713
- }
714
- }
715
- let response;
716
- try {
717
- response = await __privateGet(this, _fetchClient2).call(this, fetchUrl.toString(), {
718
- signal: __privateGet(this, _requestAbortController).signal,
719
- headers: requestHeaders
720
- });
721
- __privateSet(this, _connected, true);
722
- } catch (e) {
723
- if ((e instanceof FetchError || e instanceof FetchBackoffAbortError) && __privateGet(this, _requestAbortController).signal.aborted && __privateGet(this, _requestAbortController).signal.reason === FORCE_DISCONNECT_AND_REFRESH) {
724
- continue;
725
- }
726
- if (e instanceof FetchBackoffAbortError) break;
727
- if (!(e instanceof FetchError)) throw e;
728
- if (e.status == 409) {
729
- const newShapeHandle = e.headers[SHAPE_HANDLE_HEADER];
730
- __privateMethod(this, _ShapeStream_instances, reset_fn).call(this, newShapeHandle);
731
- await __privateMethod(this, _ShapeStream_instances, publish_fn).call(this, e.json);
732
- continue;
733
- } else {
734
- __privateMethod(this, _ShapeStream_instances, sendErrorToSubscribers_fn).call(this, e);
735
- throw e;
736
- }
737
- } finally {
738
- if (abortListener && signal) {
739
- signal.removeEventListener(`abort`, abortListener);
740
- }
741
- __privateSet(this, _requestAbortController, void 0);
742
- }
743
- const { headers, status } = response;
744
- const shapeHandle = headers.get(SHAPE_HANDLE_HEADER);
745
- if (shapeHandle) {
746
- __privateSet(this, _shapeHandle, shapeHandle);
747
- }
748
- const lastOffset = headers.get(CHUNK_LAST_OFFSET_HEADER);
749
- if (lastOffset) {
750
- __privateSet(this, _lastOffset, lastOffset);
751
- }
752
- const liveCacheBuster = headers.get(LIVE_CACHE_BUSTER_HEADER);
753
- if (liveCacheBuster) {
754
- __privateSet(this, _liveCacheBuster, liveCacheBuster);
755
- }
756
- const getSchema = () => {
757
- const schemaHeader = headers.get(SHAPE_SCHEMA_HEADER);
758
- return schemaHeader ? JSON.parse(schemaHeader) : {};
759
- };
760
- __privateSet(this, _schema, (_c = __privateGet(this, _schema)) != null ? _c : getSchema());
761
- if (status === 204) {
762
- __privateSet(this, _lastSyncedAt, Date.now());
763
- }
764
- const messages = await response.text() || `[]`;
765
- const batch = __privateGet(this, _messageParser).parse(messages, __privateGet(this, _schema));
766
- if (batch.length > 0) {
767
- const lastMessage = batch[batch.length - 1];
768
- if (isUpToDateMessage(lastMessage)) {
769
- __privateSet(this, _lastSyncedAt, Date.now());
770
- __privateSet(this, _isUpToDate, true);
771
- }
772
- await __privateMethod(this, _ShapeStream_instances, publish_fn).call(this, batch);
773
- }
774
- (_d = __privateGet(this, _tickPromiseResolver)) == null ? void 0 : _d.call(this);
775
- }
692
+ await __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
776
693
  } catch (err) {
777
694
  __privateSet(this, _error, err);
778
695
  if (__privateGet(this, _onError)) {
@@ -793,7 +710,222 @@ start_fn = async function() {
793
710
  throw err;
794
711
  } finally {
795
712
  __privateSet(this, _connected, false);
796
- (_e = __privateGet(this, _tickPromiseRejecter)) == null ? void 0 : _e.call(this);
713
+ (_a = __privateGet(this, _tickPromiseRejecter)) == null ? void 0 : _a.call(this);
714
+ }
715
+ };
716
+ requestShape_fn = async function() {
717
+ var _a, _b;
718
+ if (__privateGet(this, _state) === `pause-requested`) {
719
+ __privateSet(this, _state, `paused`);
720
+ return;
721
+ }
722
+ if (!this.options.subscribe && (((_a = this.options.signal) == null ? void 0 : _a.aborted) || __privateGet(this, _isUpToDate))) {
723
+ return;
724
+ }
725
+ const resumingFromPause = __privateGet(this, _state) === `paused`;
726
+ __privateSet(this, _state, `active`);
727
+ const { url, signal } = this.options;
728
+ const { fetchUrl, requestHeaders } = await __privateMethod(this, _ShapeStream_instances, constructUrl_fn).call(this, url, resumingFromPause);
729
+ const abortListener = await __privateMethod(this, _ShapeStream_instances, createAbortListener_fn).call(this, signal);
730
+ const requestAbortController = __privateGet(this, _requestAbortController);
731
+ try {
732
+ await __privateMethod(this, _ShapeStream_instances, fetchShape_fn).call(this, {
733
+ fetchUrl,
734
+ requestAbortController,
735
+ headers: requestHeaders,
736
+ resumingFromPause: true
737
+ });
738
+ } catch (e) {
739
+ if ((e instanceof FetchError || e instanceof FetchBackoffAbortError) && requestAbortController.signal.aborted && requestAbortController.signal.reason === FORCE_DISCONNECT_AND_REFRESH) {
740
+ return __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
741
+ }
742
+ if (e instanceof FetchBackoffAbortError) {
743
+ if (requestAbortController.signal.aborted && requestAbortController.signal.reason === PAUSE_STREAM) {
744
+ __privateSet(this, _state, `paused`);
745
+ }
746
+ return;
747
+ }
748
+ if (!(e instanceof FetchError)) throw e;
749
+ if (e.status == 409) {
750
+ const newShapeHandle = e.headers[SHAPE_HANDLE_HEADER];
751
+ __privateMethod(this, _ShapeStream_instances, reset_fn).call(this, newShapeHandle);
752
+ await __privateMethod(this, _ShapeStream_instances, publish_fn).call(this, e.json);
753
+ return __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
754
+ } else {
755
+ __privateMethod(this, _ShapeStream_instances, sendErrorToSubscribers_fn).call(this, e);
756
+ throw e;
757
+ }
758
+ } finally {
759
+ if (abortListener && signal) {
760
+ signal.removeEventListener(`abort`, abortListener);
761
+ }
762
+ __privateSet(this, _requestAbortController, void 0);
763
+ }
764
+ (_b = __privateGet(this, _tickPromiseResolver)) == null ? void 0 : _b.call(this);
765
+ return __privateMethod(this, _ShapeStream_instances, requestShape_fn).call(this);
766
+ };
767
+ constructUrl_fn = async function(url, resumingFromPause) {
768
+ const [requestHeaders, params] = await Promise.all([
769
+ resolveHeaders(this.options.headers),
770
+ this.options.params ? toInternalParams(convertWhereParamsToObj(this.options.params)) : void 0
771
+ ]);
772
+ if (params) {
773
+ validateParams(params);
774
+ }
775
+ const fetchUrl = new URL(url);
776
+ if (params) {
777
+ if (params.table) setQueryParam(fetchUrl, TABLE_QUERY_PARAM, params.table);
778
+ if (params.where) setQueryParam(fetchUrl, WHERE_QUERY_PARAM, params.where);
779
+ if (params.columns)
780
+ setQueryParam(fetchUrl, COLUMNS_QUERY_PARAM, params.columns);
781
+ if (params.replica) setQueryParam(fetchUrl, REPLICA_PARAM, params.replica);
782
+ if (params.params)
783
+ setQueryParam(fetchUrl, WHERE_PARAMS_PARAM, params.params);
784
+ const customParams = __spreadValues({}, params);
785
+ delete customParams.table;
786
+ delete customParams.where;
787
+ delete customParams.columns;
788
+ delete customParams.replica;
789
+ delete customParams.params;
790
+ for (const [key, value] of Object.entries(customParams)) {
791
+ setQueryParam(fetchUrl, key, value);
792
+ }
793
+ }
794
+ fetchUrl.searchParams.set(OFFSET_QUERY_PARAM, __privateGet(this, _lastOffset));
795
+ if (__privateGet(this, _isUpToDate)) {
796
+ if (!__privateGet(this, _isRefreshing) && !resumingFromPause) {
797
+ fetchUrl.searchParams.set(LIVE_QUERY_PARAM, `true`);
798
+ }
799
+ fetchUrl.searchParams.set(
800
+ LIVE_CACHE_BUSTER_QUERY_PARAM,
801
+ __privateGet(this, _liveCacheBuster)
802
+ );
803
+ }
804
+ if (__privateGet(this, _shapeHandle)) {
805
+ fetchUrl.searchParams.set(SHAPE_HANDLE_QUERY_PARAM, __privateGet(this, _shapeHandle));
806
+ }
807
+ fetchUrl.searchParams.sort();
808
+ return {
809
+ fetchUrl,
810
+ requestHeaders
811
+ };
812
+ };
813
+ createAbortListener_fn = async function(signal) {
814
+ var _a;
815
+ __privateSet(this, _requestAbortController, new AbortController());
816
+ if (signal) {
817
+ const abortListener = () => {
818
+ var _a2;
819
+ (_a2 = __privateGet(this, _requestAbortController)) == null ? void 0 : _a2.abort(signal.reason);
820
+ };
821
+ signal.addEventListener(`abort`, abortListener, { once: true });
822
+ if (signal.aborted) {
823
+ (_a = __privateGet(this, _requestAbortController)) == null ? void 0 : _a.abort(signal.reason);
824
+ }
825
+ return abortListener;
826
+ }
827
+ };
828
+ onInitialResponse_fn = async function(response) {
829
+ var _a;
830
+ const { headers, status } = response;
831
+ const shapeHandle = headers.get(SHAPE_HANDLE_HEADER);
832
+ if (shapeHandle) {
833
+ __privateSet(this, _shapeHandle, shapeHandle);
834
+ }
835
+ const lastOffset = headers.get(CHUNK_LAST_OFFSET_HEADER);
836
+ if (lastOffset) {
837
+ __privateSet(this, _lastOffset, lastOffset);
838
+ }
839
+ const liveCacheBuster = headers.get(LIVE_CACHE_BUSTER_HEADER);
840
+ if (liveCacheBuster) {
841
+ __privateSet(this, _liveCacheBuster, liveCacheBuster);
842
+ }
843
+ const getSchema = () => {
844
+ const schemaHeader = headers.get(SHAPE_SCHEMA_HEADER);
845
+ return schemaHeader ? JSON.parse(schemaHeader) : {};
846
+ };
847
+ __privateSet(this, _schema, (_a = __privateGet(this, _schema)) != null ? _a : getSchema());
848
+ if (status === 204) {
849
+ __privateSet(this, _lastSyncedAt, Date.now());
850
+ }
851
+ };
852
+ onMessages_fn = async function(messages, schema, isSseMessage = false) {
853
+ const batch = __privateGet(this, _messageParser).parse(messages, schema);
854
+ if (batch.length > 0) {
855
+ const lastMessage = batch[batch.length - 1];
856
+ if (isUpToDateMessage(lastMessage)) {
857
+ if (isSseMessage) {
858
+ const offset = getOffset(lastMessage);
859
+ if (offset) {
860
+ __privateSet(this, _lastOffset, offset);
861
+ }
862
+ }
863
+ __privateSet(this, _lastSyncedAt, Date.now());
864
+ __privateSet(this, _isUpToDate, true);
865
+ }
866
+ await __privateMethod(this, _ShapeStream_instances, publish_fn).call(this, batch);
867
+ }
868
+ };
869
+ fetchShape_fn = async function(opts) {
870
+ if (__privateGet(this, _isUpToDate) && this.options.experimentalLiveSse && !__privateGet(this, _isRefreshing) && !opts.resumingFromPause) {
871
+ opts.fetchUrl.searchParams.set(EXPERIMENTAL_LIVE_SSE_QUERY_PARAM, `true`);
872
+ return __privateMethod(this, _ShapeStream_instances, requestShapeSSE_fn).call(this, opts);
873
+ }
874
+ return __privateMethod(this, _ShapeStream_instances, requestShapeLongPoll_fn).call(this, opts);
875
+ };
876
+ requestShapeLongPoll_fn = async function(opts) {
877
+ const { fetchUrl, requestAbortController, headers } = opts;
878
+ const response = await __privateGet(this, _fetchClient2).call(this, fetchUrl.toString(), {
879
+ signal: requestAbortController.signal,
880
+ headers
881
+ });
882
+ __privateSet(this, _connected, true);
883
+ await __privateMethod(this, _ShapeStream_instances, onInitialResponse_fn).call(this, response);
884
+ const schema = __privateGet(this, _schema);
885
+ const res = await response.text();
886
+ const messages = res || `[]`;
887
+ await __privateMethod(this, _ShapeStream_instances, onMessages_fn).call(this, messages, schema);
888
+ };
889
+ requestShapeSSE_fn = async function(opts) {
890
+ const { fetchUrl, requestAbortController, headers } = opts;
891
+ const fetch2 = __privateGet(this, _sseFetchClient);
892
+ try {
893
+ await fetchEventSource(fetchUrl.toString(), {
894
+ headers,
895
+ fetch: fetch2,
896
+ onopen: async (response) => {
897
+ __privateSet(this, _connected, true);
898
+ await __privateMethod(this, _ShapeStream_instances, onInitialResponse_fn).call(this, response);
899
+ },
900
+ onmessage: (event) => {
901
+ if (event.data) {
902
+ const messages = `[${event.data}]`;
903
+ const schema = __privateGet(this, _schema);
904
+ __privateMethod(this, _ShapeStream_instances, onMessages_fn).call(this, messages, schema, true);
905
+ }
906
+ },
907
+ onerror: (error) => {
908
+ throw error;
909
+ },
910
+ signal: requestAbortController.signal
911
+ });
912
+ } catch (error) {
913
+ if (requestAbortController.signal.aborted) {
914
+ throw new FetchBackoffAbortError();
915
+ }
916
+ throw error;
917
+ }
918
+ };
919
+ pause_fn = function() {
920
+ var _a;
921
+ if (__privateGet(this, _started) && __privateGet(this, _state) === `active`) {
922
+ __privateSet(this, _state, `pause-requested`);
923
+ (_a = __privateGet(this, _requestAbortController)) == null ? void 0 : _a.abort(PAUSE_STREAM);
924
+ }
925
+ };
926
+ resume_fn = function() {
927
+ if (__privateGet(this, _started) && __privateGet(this, _state) === `paused`) {
928
+ __privateMethod(this, _ShapeStream_instances, start_fn).call(this);
797
929
  }
798
930
  };
799
931
  nextTick_fn = async function() {
@@ -812,23 +944,38 @@ nextTick_fn = async function() {
812
944
  return __privateGet(this, _tickPromise);
813
945
  };
814
946
  publish_fn = async function(messages) {
815
- await Promise.all(
816
- Array.from(__privateGet(this, _subscribers).values()).map(async ([callback, __]) => {
817
- try {
818
- await callback(messages);
819
- } catch (err) {
820
- queueMicrotask(() => {
821
- throw err;
822
- });
823
- }
824
- })
825
- );
947
+ __privateSet(this, _messageChain, __privateGet(this, _messageChain).then(
948
+ () => Promise.all(
949
+ Array.from(__privateGet(this, _subscribers).values()).map(async ([callback, __]) => {
950
+ try {
951
+ await callback(messages);
952
+ } catch (err) {
953
+ queueMicrotask(() => {
954
+ throw err;
955
+ });
956
+ }
957
+ })
958
+ )
959
+ ));
960
+ return __privateGet(this, _messageChain);
826
961
  };
827
962
  sendErrorToSubscribers_fn = function(error) {
828
963
  __privateGet(this, _subscribers).forEach(([_, errorFn]) => {
829
964
  errorFn == null ? void 0 : errorFn(error);
830
965
  });
831
966
  };
967
+ subscribeToVisibilityChanges_fn = function() {
968
+ if (typeof document === `object` && typeof document.hidden === `boolean` && typeof document.addEventListener === `function`) {
969
+ const visibilityHandler = () => {
970
+ if (document.hidden) {
971
+ __privateMethod(this, _ShapeStream_instances, pause_fn).call(this);
972
+ } else {
973
+ __privateMethod(this, _ShapeStream_instances, resume_fn).call(this);
974
+ }
975
+ };
976
+ document.addEventListener(`visibilitychange`, visibilityHandler);
977
+ }
978
+ };
832
979
  /**
833
980
  * Resets the state of the stream, optionally with a provided
834
981
  * shape handle