@sanity/client 6.27.2 → 6.27.3-canary.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/client",
3
- "version": "6.27.2",
3
+ "version": "6.27.3-canary.0",
4
4
  "description": "Client for retrieving, creating and patching data from Sanity.io",
5
5
  "keywords": [
6
6
  "sanity",
@@ -130,7 +130,7 @@
130
130
  "@rollup/plugin-commonjs": "^28.0.2",
131
131
  "@rollup/plugin-node-resolve": "^16.0.0",
132
132
  "@sanity/client-latest": "npm:@sanity/client@latest",
133
- "@sanity/pkg-utils": "^7.0.3",
133
+ "@sanity/pkg-utils": "^7.0.4",
134
134
  "@types/json-diff": "^1.0.3",
135
135
  "@types/node": "^22.9.0",
136
136
  "@typescript-eslint/eslint-plugin": "^8.22.0",
@@ -153,7 +153,7 @@
153
153
  "prettier": "^3.4.2",
154
154
  "prettier-plugin-packagejson": "^2.5.8",
155
155
  "rimraf": "^5.0.7",
156
- "rollup": "^4.32.0",
156
+ "rollup": "^4.32.1",
157
157
  "sse-channel": "^4.0.0",
158
158
  "terser": "^5.37.0",
159
159
  "typescript": "5.7.3",
package/src/data/live.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {catchError, concat, EMPTY, mergeMap, Observable, of} from 'rxjs'
2
- import {map} from 'rxjs/operators'
2
+ import {finalize, map} from 'rxjs/operators'
3
3
 
4
4
  import {CorsOriginError} from '../http/errors'
5
5
  import type {ObservableSanityClient, SanityClient} from '../SanityClient'
@@ -11,6 +11,7 @@ import type {
11
11
  LiveEventWelcome,
12
12
  SyncTag,
13
13
  } from '../types'
14
+ import {shareReplayLatest} from '../util/shareReplayLatest'
14
15
  import {_getDataUrl} from './dataMethods'
15
16
  import {connectEventSource} from './eventsource'
16
17
  import {eventSourcePolyfill} from './eventsourcePolyfill'
@@ -81,6 +82,13 @@ export class LiveClient {
81
82
  esOptions.withCredentials = true
82
83
  }
83
84
 
85
+ const key = `${url.href}::${JSON.stringify(esOptions)}`
86
+ const existing = eventsCache.get(key)
87
+
88
+ if (existing) {
89
+ return existing
90
+ }
91
+
84
92
  const initEventSource = () =>
85
93
  // use polyfill if there is no global EventSource or if we need to set headers
86
94
  (typeof EventSource === 'undefined' || esOptions.headers
@@ -118,7 +126,14 @@ export class LiveClient {
118
126
  throw new CorsOriginError({projectId: projectId!})
119
127
  }),
120
128
  )
121
- return concat(checkCors, events)
129
+ const observable = concat(checkCors, events).pipe(
130
+ shareReplayLatest({
131
+ predicate: (event) => event.type === 'welcome',
132
+ }),
133
+ finalize(() => eventsCache.delete(key)),
134
+ )
135
+ eventsCache.set(key, observable)
136
+ return observable
122
137
  }
123
138
  }
124
139
 
@@ -140,3 +155,5 @@ function fetchObservable(url: URL, init: RequestInit) {
140
155
  return () => controller.abort()
141
156
  })
142
157
  }
158
+
159
+ const eventsCache = new Map<string, Observable<LiveEvent>>()
package/src/types.ts CHANGED
@@ -1291,7 +1291,6 @@ export interface LiveEventMessage {
1291
1291
  export interface LiveEventWelcome {
1292
1292
  type: 'welcome'
1293
1293
  }
1294
-
1295
1294
  /** @public */
1296
1295
  export type LiveEvent = LiveEventRestart | LiveEventReconnect | LiveEventMessage | LiveEventWelcome
1297
1296
 
@@ -0,0 +1,71 @@
1
+ import {
2
+ finalize,
3
+ merge,
4
+ type MonoTypeOperatorFunction,
5
+ Observable,
6
+ share,
7
+ type ShareConfig,
8
+ tap,
9
+ } from 'rxjs'
10
+
11
+ export type ShareReplayLatestConfig<T> = ShareConfig<T> & {predicate: (value: T) => boolean}
12
+
13
+ /**
14
+ * A variant of share that takes a predicate function to determine which value to replay to new subscribers
15
+ * @param predicate - Predicate function to determine which value to replay
16
+ */
17
+ export function shareReplayLatest<T>(predicate: (value: T) => boolean): MonoTypeOperatorFunction<T>
18
+
19
+ /**
20
+ * A variant of share that takes a predicate function to determine which value to replay to new subscribers
21
+ * @param config - ShareConfig with additional predicate function
22
+ */
23
+ export function shareReplayLatest<T>(
24
+ config: ShareReplayLatestConfig<T>,
25
+ ): MonoTypeOperatorFunction<T>
26
+
27
+ /**
28
+ * A variant of share that takes a predicate function to determine which value to replay to new subscribers
29
+ * @param configOrPredicate - Predicate function to determine which value to replay
30
+ * @param config - Optional ShareConfig
31
+ */
32
+ export function shareReplayLatest<T>(
33
+ configOrPredicate: ShareReplayLatestConfig<T> | ShareReplayLatestConfig<T>['predicate'],
34
+ config?: ShareConfig<T>,
35
+ ) {
36
+ return _shareReplayLatest(
37
+ typeof configOrPredicate === 'function'
38
+ ? {predicate: configOrPredicate, ...config}
39
+ : configOrPredicate,
40
+ )
41
+ }
42
+ function _shareReplayLatest<T>(config: ShareReplayLatestConfig<T>): MonoTypeOperatorFunction<T> {
43
+ return (source: Observable<T>) => {
44
+ let latest: T | undefined
45
+ let emitted = false
46
+
47
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
48
+ const {predicate, ...shareConfig} = config
49
+
50
+ const wrapped = source.pipe(
51
+ tap((value) => {
52
+ if (config.predicate(value)) {
53
+ emitted = true
54
+ latest = value
55
+ }
56
+ }),
57
+ finalize(() => {
58
+ emitted = false
59
+ latest = undefined
60
+ }),
61
+ share(shareConfig),
62
+ )
63
+ const emitLatest = new Observable<T>((subscriber) => {
64
+ if (emitted) {
65
+ subscriber.next(latest)
66
+ }
67
+ subscriber.complete()
68
+ })
69
+ return merge(wrapped, emitLatest)
70
+ }
71
+ }
@@ -1113,6 +1113,9 @@
1113
1113
  function popScheduler(args) {
1114
1114
  return isScheduler(last(args)) ? args.pop() : undefined;
1115
1115
  }
1116
+ function popNumber(args, defaultValue) {
1117
+ return typeof last(args) === 'number' ? args.pop() : defaultValue;
1118
+ }
1116
1119
 
1117
1120
  var isArrayLike = (function (x) { return x && typeof x.length === 'number' && typeof x !== 'function'; });
1118
1121
 
@@ -1619,6 +1622,7 @@
1619
1622
  }
1620
1623
 
1621
1624
  function mergeAll(concurrent) {
1625
+ if (concurrent === undefined) { concurrent = Infinity; }
1622
1626
  return mergeMap(identity, concurrent);
1623
1627
  }
1624
1628
 
@@ -1659,6 +1663,24 @@
1659
1663
  });
1660
1664
  }
1661
1665
 
1666
+ function merge() {
1667
+ var args = [];
1668
+ for (var _i = 0; _i < arguments.length; _i++) {
1669
+ args[_i] = arguments[_i];
1670
+ }
1671
+ var scheduler = popScheduler(args);
1672
+ var concurrent = popNumber(args, Infinity);
1673
+ var sources = args;
1674
+ return !sources.length
1675
+ ?
1676
+ EMPTY
1677
+ : sources.length === 1
1678
+ ?
1679
+ innerFrom(sources[0])
1680
+ :
1681
+ mergeAll(concurrent)(from(sources, scheduler));
1682
+ }
1683
+
1662
1684
  var isArray$1 = Array.isArray;
1663
1685
  function argsOrArgArray(args) {
1664
1686
  return args.length === 1 && isArray$1(args[0]) ? args[0] : args;
@@ -1716,6 +1738,17 @@
1716
1738
  return combineLatest.apply(undefined, __spreadArray([], __read(otherSources)));
1717
1739
  }
1718
1740
 
1741
+ function finalize(callback) {
1742
+ return operate(function (source, subscriber) {
1743
+ try {
1744
+ source.subscribe(subscriber);
1745
+ }
1746
+ finally {
1747
+ subscriber.add(callback);
1748
+ }
1749
+ });
1750
+ }
1751
+
1719
1752
  function share(options) {
1720
1753
  if (options === undefined) { options = {}; }
1721
1754
  var _a = options.connector, connector = _a === undefined ? function () { return new Subject(); } : _a, _b = options.resetOnError, resetOnError = _b === undefined ? true : _b, _c = options.resetOnComplete, resetOnComplete = _c === undefined ? true : _c, _d = options.resetOnRefCountZero, resetOnRefCountZero = _d === undefined ? true : _d;
@@ -1810,6 +1843,42 @@
1810
1843
  });
1811
1844
  }
1812
1845
 
1846
+ function tap(observerOrNext, error, complete) {
1847
+ var tapObserver = isFunction(observerOrNext) || error || complete
1848
+ ?
1849
+ { next: observerOrNext, error: error, complete: complete }
1850
+ : observerOrNext;
1851
+ return tapObserver
1852
+ ? operate(function (source, subscriber) {
1853
+ var _a;
1854
+ (_a = tapObserver.subscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
1855
+ var isUnsub = true;
1856
+ source.subscribe(createOperatorSubscriber(subscriber, function (value) {
1857
+ var _a;
1858
+ (_a = tapObserver.next) === null || _a === void 0 ? void 0 : _a.call(tapObserver, value);
1859
+ subscriber.next(value);
1860
+ }, function () {
1861
+ var _a;
1862
+ isUnsub = false;
1863
+ (_a = tapObserver.complete) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
1864
+ subscriber.complete();
1865
+ }, function (err) {
1866
+ var _a;
1867
+ isUnsub = false;
1868
+ (_a = tapObserver.error) === null || _a === void 0 ? void 0 : _a.call(tapObserver, err);
1869
+ subscriber.error(err);
1870
+ }, function () {
1871
+ var _a, _b;
1872
+ if (isUnsub) {
1873
+ (_a = tapObserver.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
1874
+ }
1875
+ (_b = tapObserver.finalize) === null || _b === void 0 ? void 0 : _b.call(tapObserver);
1876
+ }));
1877
+ })
1878
+ :
1879
+ identity;
1880
+ }
1881
+
1813
1882
  var s = { 0: 8203, 1: 8204, 2: 8205, 3: 8290, 4: 8291, 5: 8288, 6: 65279, 7: 8289, 8: 119155, 9: 119156, a: 119157, b: 119158, c: 119159, d: 119160, e: 119161, f: 119162 }, c = { 0: 8203, 1: 8204, 2: 8205, 3: 65279 }, u = new Array(4).fill(String.fromCodePoint(c[0])).join("");
1814
1883
  function E(t) {
1815
1884
  let e = JSON.stringify(t);
@@ -2350,9 +2419,9 @@ ${selectionOpts}`);
2350
2419
  reset() {
2351
2420
  return this.operations = {}, this;
2352
2421
  }
2353
- _assign(op, props, merge = true) {
2422
+ _assign(op, props, merge2 = true) {
2354
2423
  return validateObject(op, props), this.operations = Object.assign({}, this.operations, {
2355
- [op]: Object.assign({}, merge && this.operations[op] || {}, props)
2424
+ [op]: Object.assign({}, merge2 && this.operations[op] || {}, props)
2356
2425
  }), this;
2357
2426
  }
2358
2427
  _set(op, props) {
@@ -2869,6 +2938,28 @@ ${selectionOpts}`);
2869
2938
  )
2870
2939
  );
2871
2940
  }
2941
+ function shareReplayLatest(configOrPredicate, config) {
2942
+ return _shareReplayLatest(
2943
+ typeof configOrPredicate == "function" ? { predicate: configOrPredicate, ...config } : configOrPredicate
2944
+ );
2945
+ }
2946
+ function _shareReplayLatest(config) {
2947
+ return (source) => {
2948
+ let latest, emitted = false;
2949
+ const { predicate, ...shareConfig } = config, wrapped = source.pipe(
2950
+ tap((value) => {
2951
+ config.predicate(value) && (emitted = true, latest = value);
2952
+ }),
2953
+ finalize(() => {
2954
+ emitted = false, latest = undefined;
2955
+ }),
2956
+ share(shareConfig)
2957
+ ), emitLatest = new Observable((subscriber) => {
2958
+ emitted && subscriber.next(latest), subscriber.complete();
2959
+ });
2960
+ return merge(wrapped, emitLatest);
2961
+ };
2962
+ }
2872
2963
  const requiredApiVersion = "2021-03-25";
2873
2964
  class LiveClient {
2874
2965
  #client;
@@ -2903,6 +2994,9 @@ ${selectionOpts}`);
2903
2994
  includeDrafts && token && (esOptions.headers = {
2904
2995
  Authorization: `Bearer ${token}`
2905
2996
  }), includeDrafts && withCredentials && (esOptions.withCredentials = true);
2997
+ const key = `${url.href}::${JSON.stringify(esOptions)}`, existing = eventsCache.get(key);
2998
+ if (existing)
2999
+ return existing;
2906
3000
  const events = connectEventSource(() => (
2907
3001
  // use polyfill if there is no global EventSource or if we need to set headers
2908
3002
  (typeof EventSource > "u" || esOptions.headers ? eventSourcePolyfill : of(EventSource)).pipe(map((EventSource2) => new EventSource2(url.href, esOptions)))
@@ -2930,8 +3024,13 @@ ${selectionOpts}`);
2930
3024
  catchError(() => {
2931
3025
  throw new CorsOriginError({ projectId: projectId2 });
2932
3026
  })
3027
+ ), observable2 = concat(checkCors, events).pipe(
3028
+ shareReplayLatest({
3029
+ predicate: (event) => event.type === "welcome"
3030
+ }),
3031
+ finalize(() => eventsCache.delete(key))
2933
3032
  );
2934
- return concat(checkCors, events);
3033
+ return eventsCache.set(key, observable2), observable2;
2935
3034
  }
2936
3035
  }
2937
3036
  function fetchObservable(url, init) {
@@ -2947,6 +3046,7 @@ ${selectionOpts}`);
2947
3046
  ), () => controller.abort();
2948
3047
  });
2949
3048
  }
3049
+ const eventsCache = /* @__PURE__ */ new Map();
2950
3050
  class ObservableDatasetsClient {
2951
3051
  #client;
2952
3052
  #httpRequest;