@mearie/core 0.6.4 → 0.6.6

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.
@@ -400,9 +400,9 @@ const takeUntil = (notifier) => {
400
400
  const complete = () => {
401
401
  if (completed) return;
402
402
  completed = true;
403
- if (sourceSubscription) sourceSubscription.unsubscribe();
404
403
  if (notifierSubscription) notifierSubscription.unsubscribe();
405
404
  sink.complete();
405
+ if (sourceSubscription) sourceSubscription.unsubscribe();
406
406
  };
407
407
  notifierSubscription = notifier({
408
408
  next() {
@@ -709,4 +709,28 @@ const make = (subscriber) => {
709
709
  };
710
710
 
711
711
  //#endregion
712
- export { mergeMap as C, filter as S, compose as _, finalize as a, merge as b, share as c, map as d, peek as f, subscribe as g, publish as h, fromValue as i, takeUntil as l, collect as m, fromSubscription as n, initialize as o, collectAll as p, makeSubject as r, switchMap as s, make as t, take as u, fromArray as v, pipe as w, fromPromise as x, tap as y };
712
+ //#region src/stream/sources/from-abort-signal.ts
713
+ /**
714
+ * Creates a source that emits when the given AbortSignal is aborted.
715
+ * If the signal is already aborted, emits immediately.
716
+ * @param signal - The AbortSignal to observe.
717
+ * @returns A Source that emits once when the signal aborts.
718
+ */
719
+ const fromAbortSignal = (signal) => {
720
+ return make(({ next, complete }) => {
721
+ if (signal.aborted) {
722
+ next(void 0);
723
+ complete();
724
+ return () => {};
725
+ }
726
+ const handler = () => {
727
+ next(void 0);
728
+ complete();
729
+ };
730
+ signal.addEventListener("abort", handler);
731
+ return () => signal.removeEventListener("abort", handler);
732
+ });
733
+ };
734
+
735
+ //#endregion
736
+ export { filter as C, fromPromise as S, pipe as T, subscribe as _, fromValue as a, tap as b, switchMap as c, take as d, map as f, publish as g, collect as h, makeSubject as i, share as l, collectAll as m, make as n, finalize as o, peek as p, fromSubscription as r, initialize as s, fromAbortSignal as t, takeUntil as u, compose as v, mergeMap as w, merge as x, fromArray as y };
@@ -402,4 +402,13 @@ declare const make: <T>(subscriber: (observer: {
402
402
  complete: () => void;
403
403
  }) => () => void) => Source<T>;
404
404
  //#endregion
405
- export { Subscription as A, Observer as C, Operator as D, pipe as E, Sink as O, publish as S, compose as T, filter as _, makeSubject as a, collectAll as b, finalize as c, switchMap as d, mergeMap as f, take as g, takeUntil as h, Subject as i, Source as k, initialize as l, share as m, fromPromise as n, fromArray as o, merge as p, fromSubscription as r, fromValue as s, make as t, tap as u, map as v, subscribe as w, collect as x, peek as y };
405
+ //#region src/stream/sources/from-abort-signal.d.ts
406
+ /**
407
+ * Creates a source that emits when the given AbortSignal is aborted.
408
+ * If the signal is already aborted, emits immediately.
409
+ * @param signal - The AbortSignal to observe.
410
+ * @returns A Source that emits once when the signal aborts.
411
+ */
412
+ declare const fromAbortSignal: (signal: AbortSignal) => Source<void>;
413
+ //#endregion
414
+ export { Source as A, publish as C, pipe as D, compose as E, Operator as O, collect as S, subscribe as T, take as _, Subject as a, peek as b, fromValue as c, tap as d, switchMap as f, takeUntil as g, share as h, fromSubscription as i, Subscription as j, Sink as k, finalize as l, merge as m, make as n, makeSubject as o, mergeMap as p, fromPromise as r, fromArray as s, fromAbortSignal as t, initialize as u, filter as v, Observer as w, collectAll as x, map as y };
@@ -401,9 +401,9 @@ const takeUntil = (notifier) => {
401
401
  const complete = () => {
402
402
  if (completed) return;
403
403
  completed = true;
404
- if (sourceSubscription) sourceSubscription.unsubscribe();
405
404
  if (notifierSubscription) notifierSubscription.unsubscribe();
406
405
  sink.complete();
406
+ if (sourceSubscription) sourceSubscription.unsubscribe();
407
407
  };
408
408
  notifierSubscription = notifier({
409
409
  next() {
@@ -709,6 +709,30 @@ const make = (subscriber) => {
709
709
  };
710
710
  };
711
711
 
712
+ //#endregion
713
+ //#region src/stream/sources/from-abort-signal.ts
714
+ /**
715
+ * Creates a source that emits when the given AbortSignal is aborted.
716
+ * If the signal is already aborted, emits immediately.
717
+ * @param signal - The AbortSignal to observe.
718
+ * @returns A Source that emits once when the signal aborts.
719
+ */
720
+ const fromAbortSignal = (signal) => {
721
+ return make(({ next, complete }) => {
722
+ if (signal.aborted) {
723
+ next(void 0);
724
+ complete();
725
+ return () => {};
726
+ }
727
+ const handler = () => {
728
+ next(void 0);
729
+ complete();
730
+ };
731
+ signal.addEventListener("abort", handler);
732
+ return () => signal.removeEventListener("abort", handler);
733
+ });
734
+ };
735
+
712
736
  //#endregion
713
737
  Object.defineProperty(exports, 'collect', {
714
738
  enumerable: true,
@@ -740,6 +764,12 @@ Object.defineProperty(exports, 'finalize', {
740
764
  return finalize;
741
765
  }
742
766
  });
767
+ Object.defineProperty(exports, 'fromAbortSignal', {
768
+ enumerable: true,
769
+ get: function () {
770
+ return fromAbortSignal;
771
+ }
772
+ });
743
773
  Object.defineProperty(exports, 'fromArray', {
744
774
  enumerable: true,
745
775
  get: function () {
@@ -402,4 +402,13 @@ declare const make: <T>(subscriber: (observer: {
402
402
  complete: () => void;
403
403
  }) => () => void) => Source<T>;
404
404
  //#endregion
405
- export { Subscription as A, Observer as C, Operator as D, pipe as E, Sink as O, publish as S, compose as T, filter as _, makeSubject as a, collectAll as b, finalize as c, switchMap as d, mergeMap as f, take as g, takeUntil as h, Subject as i, Source as k, initialize as l, share as m, fromPromise as n, fromArray as o, merge as p, fromSubscription as r, fromValue as s, make as t, tap as u, map as v, subscribe as w, collect as x, peek as y };
405
+ //#region src/stream/sources/from-abort-signal.d.ts
406
+ /**
407
+ * Creates a source that emits when the given AbortSignal is aborted.
408
+ * If the signal is already aborted, emits immediately.
409
+ * @param signal - The AbortSignal to observe.
410
+ * @returns A Source that emits once when the signal aborts.
411
+ */
412
+ declare const fromAbortSignal: (signal: AbortSignal) => Source<void>;
413
+ //#endregion
414
+ export { Source as A, publish as C, pipe as D, compose as E, Operator as O, collect as S, subscribe as T, take as _, Subject as a, peek as b, fromValue as c, tap as d, switchMap as f, takeUntil as g, share as h, fromSubscription as i, Subscription as j, Sink as k, finalize as l, merge as m, make as n, makeSubject as o, mergeMap as p, fromPromise as r, fromArray as s, fromAbortSignal as t, initialize as u, filter as v, Observer as w, collectAll as x, map as y };
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_make = require('./make-DxW2Pxe-.cjs');
2
+ const require_from_abort_signal = require('./from-abort-signal-CtLzHe8K.cjs');
3
3
 
4
4
  //#region src/errors.ts
5
5
  /**
@@ -143,11 +143,11 @@ const httpExchange = (options) => {
143
143
  name: "http",
144
144
  io: (ops$) => {
145
145
  const inflight = /* @__PURE__ */ new Map();
146
- return require_make.merge(require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && (op.artifact.kind === "query" || op.artifact.kind === "mutation")), require_make.mergeMap((op) => {
146
+ return require_from_abort_signal.merge(require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && (op.artifact.kind === "query" || op.artifact.kind === "mutation")), require_from_abort_signal.mergeMap((op) => {
147
147
  inflight.get(op.key)?.abort();
148
148
  const controller = new AbortController();
149
149
  inflight.set(op.key, controller);
150
- return require_make.fromPromise(executeFetch({
150
+ return require_from_abort_signal.fromPromise(executeFetch({
151
151
  url,
152
152
  fetchFn,
153
153
  fetchOptions: {
@@ -161,7 +161,7 @@ const httpExchange = (options) => {
161
161
  inflight.delete(op.key);
162
162
  return result;
163
163
  }));
164
- }), require_make.filter((result) => result !== null)), require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown" || op.variant === "request" && (op.artifact.kind === "subscription" || op.artifact.kind === "fragment")), require_make.tap((op) => {
164
+ }), require_from_abort_signal.filter((result) => result !== null)), require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "teardown" || op.variant === "request" && (op.artifact.kind === "subscription" || op.artifact.kind === "fragment")), require_from_abort_signal.tap((op) => {
165
165
  if (op.variant === "teardown") {
166
166
  inflight.get(op.key)?.abort();
167
167
  inflight.delete(op.key);
@@ -265,14 +265,17 @@ const dedupExchange = () => {
265
265
  io: (ops$) => {
266
266
  const operations = /* @__PURE__ */ new Map();
267
267
  const resolved = /* @__PURE__ */ new Set();
268
- return require_make.pipe(require_make.merge(require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && (op.artifact.kind === "mutation" || op.artifact.kind === "fragment"))), require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && op.artifact.kind !== "mutation" && op.artifact.kind !== "fragment"), require_make.filter((op) => {
268
+ return require_from_abort_signal.pipe(require_from_abort_signal.merge(require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && (op.artifact.kind === "mutation" || op.artifact.kind === "fragment"))), require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && op.artifact.kind !== "mutation" && op.artifact.kind !== "fragment"), require_from_abort_signal.filter((op) => {
269
269
  const dedupKey = makeDedupKey(op);
270
270
  const isInflight = operations.has(dedupKey) && !resolved.has(dedupKey);
271
271
  if (isInflight) operations.get(dedupKey).add(op.key);
272
272
  else operations.set(dedupKey, new Set([op.key]));
273
273
  if (!isInflight) resolved.delete(dedupKey);
274
274
  return (op.metadata.dedup?.skip ?? false) || !isInflight;
275
- }), delay(0)), require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown"), require_make.filter((teardown) => {
275
+ }), delay(0), require_from_abort_signal.filter((op) => {
276
+ const dedupKey = makeDedupKey(op);
277
+ return operations.get(dedupKey)?.has(op.key) ?? false;
278
+ })), require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "teardown"), require_from_abort_signal.filter((teardown) => {
276
279
  for (const [dedupKey, subs] of operations.entries()) if (subs.delete(teardown.key)) {
277
280
  if (subs.size === 0) {
278
281
  operations.delete(dedupKey);
@@ -282,11 +285,11 @@ const dedupExchange = () => {
282
285
  return false;
283
286
  }
284
287
  return true;
285
- }))), forward, require_make.mergeMap((result) => {
286
- if (result.operation.variant !== "request" || result.operation.artifact.kind === "mutation" || result.operation.artifact.kind === "fragment") return require_make.fromValue(result);
288
+ }))), forward, require_from_abort_signal.mergeMap((result) => {
289
+ if (result.operation.variant !== "request" || result.operation.artifact.kind === "mutation" || result.operation.artifact.kind === "fragment") return require_from_abort_signal.fromValue(result);
287
290
  const dedupKey = makeDedupKey(result.operation);
288
291
  resolved.add(dedupKey);
289
- return require_make.fromArray([...operations.get(dedupKey) ?? /* @__PURE__ */ new Set()].map((key) => ({
292
+ return require_from_abort_signal.fromArray([...operations.get(dedupKey) ?? /* @__PURE__ */ new Set()].map((key) => ({
290
293
  ...result,
291
294
  operation: {
292
295
  ...result.operation,
@@ -559,6 +562,13 @@ const resolveTypename = (selections, data) => {
559
562
  return data.__typename;
560
563
  };
561
564
  const normalize = (schemaMeta, selections, storage, data, variables, accessor) => {
565
+ const accessorNotified = accessor ? /* @__PURE__ */ new Map() : void 0;
566
+ const callAccessor = (storageKey, fieldKey, oldValue, newValue) => {
567
+ const key = `${storageKey}\0${fieldKey}`;
568
+ if (accessorNotified.has(key) && isEqual(accessorNotified.get(key), newValue)) return;
569
+ accessorNotified.set(key, newValue);
570
+ accessor(storageKey, fieldKey, oldValue, newValue);
571
+ };
562
572
  const resolveEntityKey = (typename, data) => {
563
573
  if (!typename) return null;
564
574
  const entityMeta = schemaMeta.entities[typename];
@@ -585,9 +595,9 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
585
595
  if (fieldTypename && schemaMeta.entities[fieldTypename] && !resolveEntityKey(fieldTypename, fieldValue) && isEntityLink(storage[storageKey]?.[fieldKey])) continue;
586
596
  }
587
597
  const oldValue = storageKey === null ? void 0 : storage[storageKey]?.[fieldKey];
588
- if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue))) accessor?.(storageKey, fieldKey, oldValue, fieldValue);
598
+ if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue))) callAccessor?.(storageKey, fieldKey, oldValue, fieldValue);
589
599
  fields[fieldKey] = selection.selections ? normalizeField(null, selection.selections, fieldValue, selection.type) : fieldValue;
590
- if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey])) accessor?.(storageKey, fieldKey, oldValue, fields[fieldKey]);
600
+ if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey])) callAccessor?.(storageKey, fieldKey, oldValue, fields[fieldKey]);
591
601
  } else if (selection.kind === "FragmentSpread" || selection.kind === "InlineFragment" && selection.on === typename) {
592
602
  const inner = normalizeField(storageKey, selection.selections, value);
593
603
  if (!isEntityLink(inner)) mergeFields(fields, inner);
@@ -602,10 +612,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
602
612
  return fields;
603
613
  };
604
614
  const fields = normalizeField(RootFieldKey, selections, data);
605
- storage[RootFieldKey] = {
606
- ...storage[RootFieldKey],
607
- ...fields
608
- };
615
+ mergeFields(storage[RootFieldKey], fields);
609
616
  };
610
617
 
611
618
  //#endregion
@@ -969,7 +976,7 @@ const diffSnapshots = (oldData, newData, entityArrayChanges) => {
969
976
  patches.push(...arrayPatches);
970
977
  for (const [i, item] of cur.entries()) {
971
978
  const entityKey = newKeys[i];
972
- diff(entityKey ? oldByKey.get(entityKey) : void 0, item, [...path, i]);
979
+ if (entityKey && oldByKey.has(entityKey)) diff(oldByKey.get(entityKey), item, [...path, i]);
973
980
  }
974
981
  };
975
982
  diff(oldData, newData, []);
@@ -1015,7 +1022,7 @@ const processScalarChanges = (changes, registry, subscriptions, storage) => {
1015
1022
  let patchValue = change.newValue;
1016
1023
  if (entry.selections && (isNormalizedRecord(change.newValue) || Array.isArray(change.newValue) && change.newValue.some((v) => isNormalizedRecord(v)))) {
1017
1024
  const mergedValue = storage[change.storageKey]?.[change.fieldKey] ?? change.newValue;
1018
- const { data } = denormalize(entry.selections, {}, mergedValue, sub.variables);
1025
+ const { data } = denormalize(entry.selections, storage, mergedValue, sub.variables);
1019
1026
  patchValue = data;
1020
1027
  }
1021
1028
  const patches = result.get(entry.subscriptionId) ?? [];
@@ -1591,10 +1598,11 @@ var Cache = class {
1591
1598
  */
1592
1599
  hydrate(snapshot) {
1593
1600
  const { storage } = snapshot;
1594
- for (const [key, fields] of Object.entries(storage)) this.#storage[key] = {
1595
- ...this.#storage[key],
1596
- ...fields
1597
- };
1601
+ for (const [key, fields] of Object.entries(storage)) {
1602
+ const existing = this.#storage[key];
1603
+ if (existing) mergeFields(existing, fields, true);
1604
+ else this.#storage[key] = fields;
1605
+ }
1598
1606
  }
1599
1607
  /**
1600
1608
  * Clears all cache data.
@@ -1721,15 +1729,15 @@ const cacheExchange = (options = {}) => {
1721
1729
  },
1722
1730
  io: (ops$) => {
1723
1731
  const subscriptionHasData = /* @__PURE__ */ new Map();
1724
- const refetch$ = require_make.makeSubject();
1725
- const fragment$ = require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && op.artifact.kind === "fragment"), require_make.mergeMap((op) => {
1732
+ const refetch$ = require_from_abort_signal.makeSubject();
1733
+ const fragment$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && op.artifact.kind === "fragment"), require_from_abort_signal.mergeMap((op) => {
1726
1734
  const fragmentRef = op.metadata?.fragment?.ref;
1727
- if (!fragmentRef) return require_make.fromValue({
1735
+ if (!fragmentRef) return require_from_abort_signal.fromValue({
1728
1736
  operation: op,
1729
1737
  errors: [new ExchangeError("Fragment operation missing fragment.ref in metadata. This usually happens when the wrong fragment reference was passed.", { exchangeName: "cache" })]
1730
1738
  });
1731
1739
  if (isFragmentRefArray(fragmentRef)) {
1732
- const results = require_make.makeSubject();
1740
+ const results = require_from_abort_signal.makeSubject();
1733
1741
  const unsubscribes = [];
1734
1742
  for (const [index, ref] of fragmentRef.entries()) {
1735
1743
  const listener = (notification) => {
@@ -1757,23 +1765,23 @@ const cacheExchange = (options = {}) => {
1757
1765
  unsubscribes.push(unsubscribe);
1758
1766
  }
1759
1767
  const { data: initialData, stale: initialStale } = cache.readFragments(op.artifact, fragmentRef);
1760
- const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_make.tap(() => {
1768
+ const teardown$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_from_abort_signal.tap(() => {
1761
1769
  for (const unsub of unsubscribes) unsub();
1762
1770
  results.complete();
1763
1771
  }));
1764
- return require_make.pipe(require_make.merge(require_make.fromValue({
1772
+ return require_from_abort_signal.pipe(require_from_abort_signal.merge(require_from_abort_signal.fromValue({
1765
1773
  operation: op,
1766
1774
  data: initialData,
1767
1775
  ...initialStale && { metadata: { cache: { stale: true } } },
1768
1776
  errors: []
1769
- }), results.source), require_make.takeUntil(teardown$));
1777
+ }), results.source), require_from_abort_signal.takeUntil(teardown$));
1770
1778
  }
1771
- if (!isFragmentRef(fragmentRef)) return require_make.fromValue({
1779
+ if (!isFragmentRef(fragmentRef)) return require_from_abort_signal.fromValue({
1772
1780
  operation: op,
1773
1781
  data: fragmentRef,
1774
1782
  errors: []
1775
1783
  });
1776
- const results = require_make.makeSubject();
1784
+ const results = require_from_abort_signal.makeSubject();
1777
1785
  const listener = (notification) => {
1778
1786
  if (notification.type === "patch") results.next({
1779
1787
  operation: op,
@@ -1791,23 +1799,23 @@ const cacheExchange = (options = {}) => {
1791
1799
  }
1792
1800
  };
1793
1801
  const { data, stale, unsubscribe } = cache.subscribeFragment(op.artifact, fragmentRef, listener);
1794
- const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_make.tap(() => {
1802
+ const teardown$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((operation) => operation.variant === "teardown" && operation.key === op.key), require_from_abort_signal.tap(() => {
1795
1803
  unsubscribe();
1796
1804
  results.complete();
1797
1805
  }));
1798
- return require_make.pipe(require_make.merge(data === null ? empty() : require_make.fromValue({
1806
+ return require_from_abort_signal.pipe(require_from_abort_signal.merge(data === null ? empty() : require_from_abort_signal.fromValue({
1799
1807
  operation: op,
1800
1808
  data,
1801
1809
  ...stale && { metadata: { cache: { stale: true } } },
1802
1810
  errors: []
1803
- }), results.source), require_make.takeUntil(teardown$));
1811
+ }), results.source), require_from_abort_signal.takeUntil(teardown$));
1804
1812
  }));
1805
- const nonCache$ = require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && (op.artifact.kind === "mutation" || op.artifact.kind === "subscription" || op.artifact.kind === "query" && fetchPolicy === "network-only")), require_make.tap((op) => {
1813
+ const nonCache$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && (op.artifact.kind === "mutation" || op.artifact.kind === "subscription" || op.artifact.kind === "query" && fetchPolicy === "network-only")), require_from_abort_signal.tap((op) => {
1806
1814
  if (op.artifact.kind === "mutation" && op.metadata?.cache?.optimisticResponse) cache.writeOptimistic(op.key, op.artifact, op.variables, op.metadata.cache.optimisticResponse);
1807
1815
  }));
1808
- const query$ = require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && op.artifact.kind === "query" && fetchPolicy !== "network-only"), require_make.share());
1809
- return require_make.merge(fragment$, require_make.pipe(query$, require_make.mergeMap((op) => {
1810
- const results = require_make.makeSubject();
1816
+ const query$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && op.artifact.kind === "query" && fetchPolicy !== "network-only"), require_from_abort_signal.share());
1817
+ return require_from_abort_signal.merge(fragment$, require_from_abort_signal.pipe(query$, require_from_abort_signal.mergeMap((op) => {
1818
+ const results = require_from_abort_signal.makeSubject();
1811
1819
  const listener = (notification) => {
1812
1820
  if (notification.type === "patch") {
1813
1821
  if (!subscriptionHasData.get(op.key)) return;
@@ -1831,34 +1839,34 @@ const cacheExchange = (options = {}) => {
1831
1839
  };
1832
1840
  const { data, stale, unsubscribe } = cache.subscribeQuery(op.artifact, op.variables, listener);
1833
1841
  subscriptionHasData.set(op.key, data !== null);
1834
- const teardown$ = require_make.pipe(ops$, require_make.filter((o) => o.variant === "teardown" && o.key === op.key), require_make.tap(() => {
1842
+ const teardown$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((o) => o.variant === "teardown" && o.key === op.key), require_from_abort_signal.tap(() => {
1835
1843
  unsubscribe();
1836
1844
  subscriptionHasData.delete(op.key);
1837
1845
  results.complete();
1838
1846
  }));
1839
- const stream$ = require_make.pipe(require_make.merge(data === null ? fetchPolicy === "cache-only" ? require_make.fromValue({
1847
+ const stream$ = require_from_abort_signal.pipe(require_from_abort_signal.merge(data === null ? fetchPolicy === "cache-only" ? require_from_abort_signal.fromValue({
1840
1848
  operation: op,
1841
1849
  data: null,
1842
1850
  errors: []
1843
- }) : empty() : require_make.fromValue({
1851
+ }) : empty() : require_from_abort_signal.fromValue({
1844
1852
  operation: op,
1845
1853
  data,
1846
1854
  ...stale && { metadata: { cache: { stale: true } } },
1847
1855
  errors: []
1848
- }), results.source), require_make.takeUntil(teardown$));
1856
+ }), results.source), require_from_abort_signal.takeUntil(teardown$));
1849
1857
  if (stale) refetch$.next(op);
1850
1858
  return stream$;
1851
- }), require_make.filter(() => fetchPolicy === "cache-only" || fetchPolicy === "cache-and-network" || fetchPolicy === "cache-first")), require_make.pipe(require_make.merge(nonCache$, require_make.pipe(query$, require_make.filter((op) => {
1859
+ }), require_from_abort_signal.filter(() => fetchPolicy === "cache-only" || fetchPolicy === "cache-and-network" || fetchPolicy === "cache-first")), require_from_abort_signal.pipe(require_from_abort_signal.merge(nonCache$, require_from_abort_signal.pipe(query$, require_from_abort_signal.filter((op) => {
1852
1860
  const { data } = cache.readQuery(op.artifact, op.variables);
1853
1861
  return fetchPolicy === "cache-and-network" || data === null;
1854
- })), require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown")), refetch$.source), forward, require_make.mergeMap((result) => {
1862
+ })), require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "teardown")), refetch$.source), forward, require_from_abort_signal.mergeMap((result) => {
1855
1863
  if (result.operation.variant === "request" && result.operation.artifact.kind === "mutation" && result.operation.metadata?.cache?.optimisticResponse) cache.removeOptimistic(result.operation.key);
1856
1864
  if (result.operation.variant === "request" && result.data) cache.writeQuery(result.operation.artifact, result.operation.variables, result.data);
1857
- if (result.operation.variant !== "request" || result.operation.artifact.kind !== "query" || fetchPolicy === "network-only" || !!(result.errors && result.errors.length > 0)) return require_make.fromValue(result);
1865
+ if (result.operation.variant !== "request" || result.operation.artifact.kind !== "query" || fetchPolicy === "network-only" || !!(result.errors && result.errors.length > 0)) return require_from_abort_signal.fromValue(result);
1858
1866
  if (subscriptionHasData.get(result.operation.key)) {
1859
1867
  const { data } = cache.readQuery(result.operation.artifact, result.operation.variables);
1860
1868
  if (data !== null) return empty();
1861
- return require_make.fromValue({
1869
+ return require_from_abort_signal.fromValue({
1862
1870
  operation: result.operation,
1863
1871
  data: void 0,
1864
1872
  errors: [new ExchangeError("Cache failed to denormalize the network response. This is likely a bug in the cache normalizer.", { exchangeName: "cache" })]
@@ -1866,11 +1874,11 @@ const cacheExchange = (options = {}) => {
1866
1874
  }
1867
1875
  subscriptionHasData.set(result.operation.key, true);
1868
1876
  const { data } = cache.readQuery(result.operation.artifact, result.operation.variables);
1869
- if (data !== null) return require_make.fromValue({
1877
+ if (data !== null) return require_from_abort_signal.fromValue({
1870
1878
  ...result,
1871
1879
  data
1872
1880
  });
1873
- return require_make.fromValue({
1881
+ return require_from_abort_signal.fromValue({
1874
1882
  operation: result.operation,
1875
1883
  data: void 0,
1876
1884
  errors: [new ExchangeError("Cache failed to denormalize the network response. This is likely a bug in the cache normalizer.", { exchangeName: "cache" })]
@@ -1889,15 +1897,15 @@ const retryExchange = (options = {}) => {
1889
1897
  return ({ forward }) => ({
1890
1898
  name: "retry",
1891
1899
  io: (ops$) => {
1892
- const { source: retries$, next } = require_make.makeSubject();
1900
+ const { source: retries$, next } = require_from_abort_signal.makeSubject();
1893
1901
  const tornDown = /* @__PURE__ */ new Set();
1894
- const teardown$ = require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown"), require_make.tap((op) => {
1902
+ const teardown$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "teardown"), require_from_abort_signal.tap((op) => {
1895
1903
  tornDown.add(op.key);
1896
1904
  }));
1897
- return require_make.pipe(require_make.merge(require_make.pipe(ops$, require_make.filter((op) => op.variant === "request")), require_make.pipe(retries$, require_make.filter((op) => !tornDown.has(op.key)), require_make.mergeMap((op) => {
1898
- const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key));
1899
- return require_make.pipe(require_make.fromValue(op), delay(op.metadata.retry.delay), require_make.takeUntil(teardown$));
1900
- })), teardown$), forward, require_make.filter((result) => {
1905
+ return require_from_abort_signal.pipe(require_from_abort_signal.merge(require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request")), require_from_abort_signal.pipe(retries$, require_from_abort_signal.filter((op) => !tornDown.has(op.key)), require_from_abort_signal.mergeMap((op) => {
1906
+ const teardown$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((operation) => operation.variant === "teardown" && operation.key === op.key));
1907
+ return require_from_abort_signal.pipe(require_from_abort_signal.fromValue(op), delay(op.metadata.retry.delay), require_from_abort_signal.takeUntil(teardown$));
1908
+ })), teardown$), forward, require_from_abort_signal.filter((result) => {
1901
1909
  if (!result.errors || result.errors.length === 0) return true;
1902
1910
  if (result.operation.variant === "request" && result.operation.artifact.kind === "mutation") return true;
1903
1911
  const attempt = result.operation.metadata.retry?.attempt ?? 0;
@@ -1926,7 +1934,7 @@ const fragmentExchange = () => {
1926
1934
  return ({ forward }) => ({
1927
1935
  name: "fragment",
1928
1936
  io: (ops$) => {
1929
- return require_make.merge(require_make.pipe(ops$, require_make.filter((op) => op.variant === "request" && op.artifact.kind === "fragment"), require_make.map((op) => {
1937
+ return require_from_abort_signal.merge(require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "request" && op.artifact.kind === "fragment"), require_from_abort_signal.map((op) => {
1930
1938
  const fragmentRef = op.metadata.fragment?.ref;
1931
1939
  if (!fragmentRef) return {
1932
1940
  operation: op,
@@ -1936,7 +1944,7 @@ const fragmentExchange = () => {
1936
1944
  operation: op,
1937
1945
  data: fragmentRef
1938
1946
  };
1939
- })), require_make.pipe(ops$, require_make.filter((op) => op.variant === "teardown" || op.artifact.kind !== "fragment"), forward));
1947
+ })), require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant === "teardown" || op.artifact.kind !== "fragment"), forward));
1940
1948
  }
1941
1949
  });
1942
1950
  };
@@ -2013,7 +2021,7 @@ const requiredExchange = () => {
2013
2021
  return ({ forward }) => ({
2014
2022
  name: "required",
2015
2023
  io: (ops$) => {
2016
- return require_make.pipe(ops$, forward, require_make.map((result) => {
2024
+ return require_from_abort_signal.pipe(ops$, forward, require_from_abort_signal.map((result) => {
2017
2025
  if (result.operation.variant !== "request" || !result.data) return result;
2018
2026
  try {
2019
2027
  return {
@@ -2066,9 +2074,9 @@ const subscriptionExchange = (options) => {
2066
2074
  return ({ forward }) => ({
2067
2075
  name: "subscription",
2068
2076
  io: (ops$) => {
2069
- return require_make.merge(require_make.pipe(ops$, require_make.filter(shouldHandle), require_make.mergeMap((op) => {
2070
- const teardown$ = require_make.pipe(ops$, require_make.filter((operation) => operation.variant === "teardown" && operation.key === op.key));
2071
- return require_make.pipe(require_make.make((observer) => {
2077
+ return require_from_abort_signal.merge(require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter(shouldHandle), require_from_abort_signal.mergeMap((op) => {
2078
+ const teardown$ = require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((operation) => operation.variant === "teardown" && operation.key === op.key));
2079
+ return require_from_abort_signal.pipe(require_from_abort_signal.make((observer) => {
2072
2080
  let unsubscribe;
2073
2081
  let completed = false;
2074
2082
  const doSubscribe = () => {
@@ -2122,8 +2130,8 @@ const subscriptionExchange = (options) => {
2122
2130
  completed = true;
2123
2131
  unsubscribe?.();
2124
2132
  };
2125
- }), require_make.takeUntil(teardown$));
2126
- })), require_make.pipe(ops$, require_make.filter((op) => !shouldHandle(op)), forward));
2133
+ }), require_from_abort_signal.takeUntil(teardown$));
2134
+ })), require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => !shouldHandle(op)), forward));
2127
2135
  }
2128
2136
  });
2129
2137
  };
@@ -2143,7 +2151,7 @@ const composeExchanges = (options, input) => {
2143
2151
  });
2144
2152
  if ("extension" in result) extensions.set(result.name, result.extension);
2145
2153
  return (ops$) => {
2146
- return require_make.pipe(ops$, require_make.share(), result.io, require_make.share());
2154
+ return require_from_abort_signal.pipe(ops$, require_from_abort_signal.share(), result.io, require_from_abort_signal.share());
2147
2155
  };
2148
2156
  }, input.forward),
2149
2157
  extensions
@@ -2219,13 +2227,13 @@ const scalarExchange = () => {
2219
2227
  return ({ forward, client }) => ({
2220
2228
  name: "scalar",
2221
2229
  io: (ops$) => {
2222
- return require_make.pipe(ops$, require_make.map((op) => {
2230
+ return require_from_abort_signal.pipe(ops$, require_from_abort_signal.map((op) => {
2223
2231
  if (op.variant !== "request" || !op.artifact.variableDefs || !client.scalars) return op;
2224
2232
  return {
2225
2233
  ...op,
2226
2234
  variables: serialize(client.schema, op.artifact.variableDefs, client.scalars, op.variables)
2227
2235
  };
2228
- }), forward, require_make.map((result) => {
2236
+ }), forward, require_from_abort_signal.map((result) => {
2229
2237
  if (result.operation.variant !== "request" || !result.data || !client.scalars) return result;
2230
2238
  return {
2231
2239
  ...result,
@@ -2242,7 +2250,7 @@ const terminalExchange = () => {
2242
2250
  return () => ({
2243
2251
  name: "terminal",
2244
2252
  io: (ops$) => {
2245
- return require_make.pipe(ops$, require_make.filter((op) => op.variant !== "teardown"), require_make.mergeMap((op) => require_make.fromValue({
2253
+ return require_from_abort_signal.pipe(ops$, require_from_abort_signal.filter((op) => op.variant !== "teardown"), require_from_abort_signal.mergeMap((op) => require_from_abort_signal.fromValue({
2246
2254
  operation: op,
2247
2255
  errors: [new ExchangeError("No terminal exchange found in exchange chain. Did you forget to add httpExchange to your exchanges array?", { exchangeName: "terminal" })]
2248
2256
  })));
@@ -2284,7 +2292,7 @@ var Client = class {
2284
2292
  client: this
2285
2293
  });
2286
2294
  this.#extensions = extensions;
2287
- this.operations$ = require_make.makeSubject();
2295
+ this.operations$ = require_from_abort_signal.makeSubject();
2288
2296
  this.results$ = io(this.operations$.source);
2289
2297
  }
2290
2298
  get schema() {
@@ -2305,20 +2313,22 @@ var Client = class {
2305
2313
  variables: variables ?? {}
2306
2314
  };
2307
2315
  }
2308
- executeOperation(operation) {
2309
- return require_make.pipe(this.results$, require_make.initialize(() => this.operations$.next(operation)), require_make.filter((result) => result.operation.key === operation.key), require_make.finalize(() => this.operations$.next({
2316
+ executeOperation(operation, options) {
2317
+ let source = require_from_abort_signal.pipe(this.results$, require_from_abort_signal.initialize(() => this.operations$.next(operation)), require_from_abort_signal.filter((result) => result.operation.key === operation.key));
2318
+ if (options?.signal) source = require_from_abort_signal.pipe(source, require_from_abort_signal.takeUntil(require_from_abort_signal.fromAbortSignal(options.signal)));
2319
+ return require_from_abort_signal.pipe(source, require_from_abort_signal.finalize(() => this.operations$.next({
2310
2320
  variant: "teardown",
2311
2321
  key: operation.key,
2312
2322
  metadata: {}
2313
- })), require_make.share());
2323
+ })), require_from_abort_signal.share());
2314
2324
  }
2315
2325
  executeQuery(artifact, ...[variables, options]) {
2316
2326
  const operation = this.createOperation(artifact, variables, options?.metadata);
2317
- return this.executeOperation(operation);
2327
+ return this.executeOperation(operation, { signal: options?.signal });
2318
2328
  }
2319
2329
  executeMutation(artifact, ...[variables, options]) {
2320
2330
  const operation = this.createOperation(artifact, variables, options?.metadata);
2321
- return this.executeOperation(operation);
2331
+ return this.executeOperation(operation, { signal: options?.signal });
2322
2332
  }
2323
2333
  executeSubscription(artifact, ...[variables, options]) {
2324
2334
  const operation = this.createOperation(artifact, variables, options?.metadata);
@@ -2338,14 +2348,30 @@ var Client = class {
2338
2348
  return this.executeOperation(operation);
2339
2349
  }
2340
2350
  async query(artifact, ...[variables, options]) {
2351
+ const signal = options?.signal;
2352
+ signal?.throwIfAborted();
2341
2353
  const operation = this.createOperation(artifact, variables, options?.metadata);
2342
- const result = await require_make.pipe(this.executeOperation(operation), require_make.take(1), require_make.collect);
2354
+ let result;
2355
+ try {
2356
+ result = await require_from_abort_signal.pipe(this.executeOperation(operation, { signal }), require_from_abort_signal.take(1), require_from_abort_signal.collect);
2357
+ } catch (err) {
2358
+ if (signal?.aborted) throw signal.reason;
2359
+ throw err;
2360
+ }
2343
2361
  if (result.errors && result.errors.length > 0) throw new AggregatedError(result.errors);
2344
2362
  return result.data;
2345
2363
  }
2346
2364
  async mutation(artifact, ...[variables, options]) {
2365
+ const signal = options?.signal;
2366
+ signal?.throwIfAborted();
2347
2367
  const operation = this.createOperation(artifact, variables, options?.metadata);
2348
- const result = await require_make.pipe(this.executeOperation(operation), require_make.take(1), require_make.collect);
2368
+ let result;
2369
+ try {
2370
+ result = await require_from_abort_signal.pipe(this.executeOperation(operation, { signal }), require_from_abort_signal.take(1), require_from_abort_signal.collect);
2371
+ } catch (err) {
2372
+ if (signal?.aborted) throw signal.reason;
2373
+ throw err;
2374
+ }
2349
2375
  if (result.errors && result.errors.length > 0) throw new AggregatedError(result.errors);
2350
2376
  return result.data;
2351
2377
  }
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { k as Source } from "./make-BhxZYW3l.cjs";
1
+ import { A as Source } from "./from-abort-signal-CsSc5Ee6.cjs";
2
2
  import { Artifact, Artifact as Artifact$1, ArtifactKind, ArtifactKind as ArtifactKind$1, DataOf, DataOf as DataOf$1, FragmentRefs, FragmentRefs as FragmentRefs$1, SchemaMeta, SchemaMeta as SchemaMeta$1, VariablesOf, VariablesOf as VariablesOf$1 } from "@mearie/shared";
3
3
 
4
4
  //#region src/errors.d.ts
@@ -67,9 +67,11 @@ type ScalarsConfig<TMeta extends SchemaMeta$1 = SchemaMeta$1> = { [K in keyof TM
67
67
  type QueryOptions<T extends Artifact$1<'query'> = Artifact$1<'query'>> = {
68
68
  initialData?: DataOf$1<T>;
69
69
  metadata?: OperationMetadata;
70
+ signal?: AbortSignal;
70
71
  };
71
72
  type MutationOptions<T extends Artifact$1<'mutation'> = Artifact$1<'mutation'>> = {
72
73
  metadata?: OperationMetadata<T>;
74
+ signal?: AbortSignal;
73
75
  };
74
76
  type SubscriptionOptions = {
75
77
  metadata?: OperationMetadata;
@@ -94,7 +96,9 @@ declare class Client<TMeta extends SchemaMeta$1 = SchemaMeta$1> {
94
96
  get scalars(): ScalarsConfig<TMeta> | undefined;
95
97
  private createOperationKey;
96
98
  createOperation(artifact: Artifact$1, variables?: unknown, metadata?: Record<string, unknown>): Operation;
97
- executeOperation(operation: Operation): Source<OperationResult>;
99
+ executeOperation(operation: Operation, options?: {
100
+ signal?: AbortSignal;
101
+ }): Source<OperationResult>;
98
102
  executeQuery<T extends Artifact$1<'query'>>(artifact: T, ...[variables, options]: VariablesOf$1<T> extends undefined ? [undefined?, QueryOptions<T>?] : [VariablesOf$1<T>, QueryOptions<T>?]): Source<OperationResult>;
99
103
  executeMutation<T extends Artifact$1<'mutation'>>(artifact: T, ...[variables, options]: VariablesOf$1<T> extends undefined ? [undefined?, MutationOptions<T>?] : [VariablesOf$1<T>, MutationOptions<T>?]): Source<OperationResult>;
100
104
  executeSubscription<T extends Artifact$1<'subscription'>>(artifact: T, ...[variables, options]: VariablesOf$1<T> extends undefined ? [undefined?, SubscriptionOptions?] : [VariablesOf$1<T>, SubscriptionOptions?]): Source<OperationResult>;
package/dist/index.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { k as Source } from "./make-Ve8TkMHJ.mjs";
1
+ import { A as Source } from "./from-abort-signal-ZiBY-b44.mjs";
2
2
  import { Artifact, Artifact as Artifact$1, ArtifactKind, ArtifactKind as ArtifactKind$1, DataOf, DataOf as DataOf$1, FragmentRefs, FragmentRefs as FragmentRefs$1, SchemaMeta, SchemaMeta as SchemaMeta$1, VariablesOf, VariablesOf as VariablesOf$1 } from "@mearie/shared";
3
3
 
4
4
  //#region src/errors.d.ts
@@ -67,9 +67,11 @@ type ScalarsConfig<TMeta extends SchemaMeta$1 = SchemaMeta$1> = { [K in keyof TM
67
67
  type QueryOptions<T extends Artifact$1<'query'> = Artifact$1<'query'>> = {
68
68
  initialData?: DataOf$1<T>;
69
69
  metadata?: OperationMetadata;
70
+ signal?: AbortSignal;
70
71
  };
71
72
  type MutationOptions<T extends Artifact$1<'mutation'> = Artifact$1<'mutation'>> = {
72
73
  metadata?: OperationMetadata<T>;
74
+ signal?: AbortSignal;
73
75
  };
74
76
  type SubscriptionOptions = {
75
77
  metadata?: OperationMetadata;
@@ -94,7 +96,9 @@ declare class Client<TMeta extends SchemaMeta$1 = SchemaMeta$1> {
94
96
  get scalars(): ScalarsConfig<TMeta> | undefined;
95
97
  private createOperationKey;
96
98
  createOperation(artifact: Artifact$1, variables?: unknown, metadata?: Record<string, unknown>): Operation;
97
- executeOperation(operation: Operation): Source<OperationResult>;
99
+ executeOperation(operation: Operation, options?: {
100
+ signal?: AbortSignal;
101
+ }): Source<OperationResult>;
98
102
  executeQuery<T extends Artifact$1<'query'>>(artifact: T, ...[variables, options]: VariablesOf$1<T> extends undefined ? [undefined?, QueryOptions<T>?] : [VariablesOf$1<T>, QueryOptions<T>?]): Source<OperationResult>;
99
103
  executeMutation<T extends Artifact$1<'mutation'>>(artifact: T, ...[variables, options]: VariablesOf$1<T> extends undefined ? [undefined?, MutationOptions<T>?] : [VariablesOf$1<T>, MutationOptions<T>?]): Source<OperationResult>;
100
104
  executeSubscription<T extends Artifact$1<'subscription'>>(artifact: T, ...[variables, options]: VariablesOf$1<T> extends undefined ? [undefined?, SubscriptionOptions?] : [VariablesOf$1<T>, SubscriptionOptions?]): Source<OperationResult>;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { C as mergeMap, S as filter, a as finalize, b as merge, c as share, d as map, i as fromValue, l as takeUntil, m as collect, o as initialize, r as makeSubject, t as make, u as take, v as fromArray, w as pipe, x as fromPromise, y as tap } from "./make-C7I1YIXm.mjs";
1
+ import { C as filter, S as fromPromise, T as pipe, a as fromValue, b as tap, d as take, f as map, h as collect, i as makeSubject, l as share, n as make, o as finalize, s as initialize, t as fromAbortSignal, u as takeUntil, w as mergeMap, x as merge, y as fromArray } from "./from-abort-signal-ClRa7iWd.mjs";
2
2
 
3
3
  //#region src/errors.ts
4
4
  /**
@@ -271,7 +271,10 @@ const dedupExchange = () => {
271
271
  else operations.set(dedupKey, new Set([op.key]));
272
272
  if (!isInflight) resolved.delete(dedupKey);
273
273
  return (op.metadata.dedup?.skip ?? false) || !isInflight;
274
- }), delay(0)), pipe(ops$, filter((op) => op.variant === "teardown"), filter((teardown) => {
274
+ }), delay(0), filter((op) => {
275
+ const dedupKey = makeDedupKey(op);
276
+ return operations.get(dedupKey)?.has(op.key) ?? false;
277
+ })), pipe(ops$, filter((op) => op.variant === "teardown"), filter((teardown) => {
275
278
  for (const [dedupKey, subs] of operations.entries()) if (subs.delete(teardown.key)) {
276
279
  if (subs.size === 0) {
277
280
  operations.delete(dedupKey);
@@ -558,6 +561,13 @@ const resolveTypename = (selections, data) => {
558
561
  return data.__typename;
559
562
  };
560
563
  const normalize = (schemaMeta, selections, storage, data, variables, accessor) => {
564
+ const accessorNotified = accessor ? /* @__PURE__ */ new Map() : void 0;
565
+ const callAccessor = (storageKey, fieldKey, oldValue, newValue) => {
566
+ const key = `${storageKey}\0${fieldKey}`;
567
+ if (accessorNotified.has(key) && isEqual(accessorNotified.get(key), newValue)) return;
568
+ accessorNotified.set(key, newValue);
569
+ accessor(storageKey, fieldKey, oldValue, newValue);
570
+ };
561
571
  const resolveEntityKey = (typename, data) => {
562
572
  if (!typename) return null;
563
573
  const entityMeta = schemaMeta.entities[typename];
@@ -584,9 +594,9 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
584
594
  if (fieldTypename && schemaMeta.entities[fieldTypename] && !resolveEntityKey(fieldTypename, fieldValue) && isEntityLink(storage[storageKey]?.[fieldKey])) continue;
585
595
  }
586
596
  const oldValue = storageKey === null ? void 0 : storage[storageKey]?.[fieldKey];
587
- if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue))) accessor?.(storageKey, fieldKey, oldValue, fieldValue);
597
+ if (storageKey !== null && (!selection.selections || isNullish(oldValue) || isNullish(fieldValue))) callAccessor?.(storageKey, fieldKey, oldValue, fieldValue);
588
598
  fields[fieldKey] = selection.selections ? normalizeField(null, selection.selections, fieldValue, selection.type) : fieldValue;
589
- if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey])) accessor?.(storageKey, fieldKey, oldValue, fields[fieldKey]);
599
+ if (storageKey !== null && selection.selections && !isNullish(oldValue) && !isNullish(fieldValue) && !isEntityLink(fields[fieldKey]) && !isEqual(oldValue, fields[fieldKey])) callAccessor?.(storageKey, fieldKey, oldValue, fields[fieldKey]);
590
600
  } else if (selection.kind === "FragmentSpread" || selection.kind === "InlineFragment" && selection.on === typename) {
591
601
  const inner = normalizeField(storageKey, selection.selections, value);
592
602
  if (!isEntityLink(inner)) mergeFields(fields, inner);
@@ -601,10 +611,7 @@ const normalize = (schemaMeta, selections, storage, data, variables, accessor) =
601
611
  return fields;
602
612
  };
603
613
  const fields = normalizeField(RootFieldKey, selections, data);
604
- storage[RootFieldKey] = {
605
- ...storage[RootFieldKey],
606
- ...fields
607
- };
614
+ mergeFields(storage[RootFieldKey], fields);
608
615
  };
609
616
 
610
617
  //#endregion
@@ -968,7 +975,7 @@ const diffSnapshots = (oldData, newData, entityArrayChanges) => {
968
975
  patches.push(...arrayPatches);
969
976
  for (const [i, item] of cur.entries()) {
970
977
  const entityKey = newKeys[i];
971
- diff(entityKey ? oldByKey.get(entityKey) : void 0, item, [...path, i]);
978
+ if (entityKey && oldByKey.has(entityKey)) diff(oldByKey.get(entityKey), item, [...path, i]);
972
979
  }
973
980
  };
974
981
  diff(oldData, newData, []);
@@ -1014,7 +1021,7 @@ const processScalarChanges = (changes, registry, subscriptions, storage) => {
1014
1021
  let patchValue = change.newValue;
1015
1022
  if (entry.selections && (isNormalizedRecord(change.newValue) || Array.isArray(change.newValue) && change.newValue.some((v) => isNormalizedRecord(v)))) {
1016
1023
  const mergedValue = storage[change.storageKey]?.[change.fieldKey] ?? change.newValue;
1017
- const { data } = denormalize(entry.selections, {}, mergedValue, sub.variables);
1024
+ const { data } = denormalize(entry.selections, storage, mergedValue, sub.variables);
1018
1025
  patchValue = data;
1019
1026
  }
1020
1027
  const patches = result.get(entry.subscriptionId) ?? [];
@@ -1590,10 +1597,11 @@ var Cache = class {
1590
1597
  */
1591
1598
  hydrate(snapshot) {
1592
1599
  const { storage } = snapshot;
1593
- for (const [key, fields] of Object.entries(storage)) this.#storage[key] = {
1594
- ...this.#storage[key],
1595
- ...fields
1596
- };
1600
+ for (const [key, fields] of Object.entries(storage)) {
1601
+ const existing = this.#storage[key];
1602
+ if (existing) mergeFields(existing, fields, true);
1603
+ else this.#storage[key] = fields;
1604
+ }
1597
1605
  }
1598
1606
  /**
1599
1607
  * Clears all cache data.
@@ -2304,8 +2312,10 @@ var Client = class {
2304
2312
  variables: variables ?? {}
2305
2313
  };
2306
2314
  }
2307
- executeOperation(operation) {
2308
- return pipe(this.results$, initialize(() => this.operations$.next(operation)), filter((result) => result.operation.key === operation.key), finalize(() => this.operations$.next({
2315
+ executeOperation(operation, options) {
2316
+ let source = pipe(this.results$, initialize(() => this.operations$.next(operation)), filter((result) => result.operation.key === operation.key));
2317
+ if (options?.signal) source = pipe(source, takeUntil(fromAbortSignal(options.signal)));
2318
+ return pipe(source, finalize(() => this.operations$.next({
2309
2319
  variant: "teardown",
2310
2320
  key: operation.key,
2311
2321
  metadata: {}
@@ -2313,11 +2323,11 @@ var Client = class {
2313
2323
  }
2314
2324
  executeQuery(artifact, ...[variables, options]) {
2315
2325
  const operation = this.createOperation(artifact, variables, options?.metadata);
2316
- return this.executeOperation(operation);
2326
+ return this.executeOperation(operation, { signal: options?.signal });
2317
2327
  }
2318
2328
  executeMutation(artifact, ...[variables, options]) {
2319
2329
  const operation = this.createOperation(artifact, variables, options?.metadata);
2320
- return this.executeOperation(operation);
2330
+ return this.executeOperation(operation, { signal: options?.signal });
2321
2331
  }
2322
2332
  executeSubscription(artifact, ...[variables, options]) {
2323
2333
  const operation = this.createOperation(artifact, variables, options?.metadata);
@@ -2337,14 +2347,30 @@ var Client = class {
2337
2347
  return this.executeOperation(operation);
2338
2348
  }
2339
2349
  async query(artifact, ...[variables, options]) {
2350
+ const signal = options?.signal;
2351
+ signal?.throwIfAborted();
2340
2352
  const operation = this.createOperation(artifact, variables, options?.metadata);
2341
- const result = await pipe(this.executeOperation(operation), take(1), collect);
2353
+ let result;
2354
+ try {
2355
+ result = await pipe(this.executeOperation(operation, { signal }), take(1), collect);
2356
+ } catch (err) {
2357
+ if (signal?.aborted) throw signal.reason;
2358
+ throw err;
2359
+ }
2342
2360
  if (result.errors && result.errors.length > 0) throw new AggregatedError(result.errors);
2343
2361
  return result.data;
2344
2362
  }
2345
2363
  async mutation(artifact, ...[variables, options]) {
2364
+ const signal = options?.signal;
2365
+ signal?.throwIfAborted();
2346
2366
  const operation = this.createOperation(artifact, variables, options?.metadata);
2347
- const result = await pipe(this.executeOperation(operation), take(1), collect);
2367
+ let result;
2368
+ try {
2369
+ result = await pipe(this.executeOperation(operation, { signal }), take(1), collect);
2370
+ } catch (err) {
2371
+ if (signal?.aborted) throw signal.reason;
2372
+ throw err;
2373
+ }
2348
2374
  if (result.errors && result.errors.length > 0) throw new AggregatedError(result.errors);
2349
2375
  return result.data;
2350
2376
  }
@@ -1,27 +1,28 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_make = require('../make-DxW2Pxe-.cjs');
2
+ const require_from_abort_signal = require('../from-abort-signal-CtLzHe8K.cjs');
3
3
 
4
- exports.collect = require_make.collect;
5
- exports.collectAll = require_make.collectAll;
6
- exports.compose = require_make.compose;
7
- exports.filter = require_make.filter;
8
- exports.finalize = require_make.finalize;
9
- exports.fromArray = require_make.fromArray;
10
- exports.fromPromise = require_make.fromPromise;
11
- exports.fromSubscription = require_make.fromSubscription;
12
- exports.fromValue = require_make.fromValue;
13
- exports.initialize = require_make.initialize;
14
- exports.make = require_make.make;
15
- exports.makeSubject = require_make.makeSubject;
16
- exports.map = require_make.map;
17
- exports.merge = require_make.merge;
18
- exports.mergeMap = require_make.mergeMap;
19
- exports.peek = require_make.peek;
20
- exports.pipe = require_make.pipe;
21
- exports.publish = require_make.publish;
22
- exports.share = require_make.share;
23
- exports.subscribe = require_make.subscribe;
24
- exports.switchMap = require_make.switchMap;
25
- exports.take = require_make.take;
26
- exports.takeUntil = require_make.takeUntil;
27
- exports.tap = require_make.tap;
4
+ exports.collect = require_from_abort_signal.collect;
5
+ exports.collectAll = require_from_abort_signal.collectAll;
6
+ exports.compose = require_from_abort_signal.compose;
7
+ exports.filter = require_from_abort_signal.filter;
8
+ exports.finalize = require_from_abort_signal.finalize;
9
+ exports.fromAbortSignal = require_from_abort_signal.fromAbortSignal;
10
+ exports.fromArray = require_from_abort_signal.fromArray;
11
+ exports.fromPromise = require_from_abort_signal.fromPromise;
12
+ exports.fromSubscription = require_from_abort_signal.fromSubscription;
13
+ exports.fromValue = require_from_abort_signal.fromValue;
14
+ exports.initialize = require_from_abort_signal.initialize;
15
+ exports.make = require_from_abort_signal.make;
16
+ exports.makeSubject = require_from_abort_signal.makeSubject;
17
+ exports.map = require_from_abort_signal.map;
18
+ exports.merge = require_from_abort_signal.merge;
19
+ exports.mergeMap = require_from_abort_signal.mergeMap;
20
+ exports.peek = require_from_abort_signal.peek;
21
+ exports.pipe = require_from_abort_signal.pipe;
22
+ exports.publish = require_from_abort_signal.publish;
23
+ exports.share = require_from_abort_signal.share;
24
+ exports.subscribe = require_from_abort_signal.subscribe;
25
+ exports.switchMap = require_from_abort_signal.switchMap;
26
+ exports.take = require_from_abort_signal.take;
27
+ exports.takeUntil = require_from_abort_signal.takeUntil;
28
+ exports.tap = require_from_abort_signal.tap;
@@ -1,2 +1,2 @@
1
- import { A as Subscription, C as Observer, D as Operator, E as pipe, O as Sink, S as publish, T as compose, _ as filter, a as makeSubject, b as collectAll, c as finalize, d as switchMap, f as mergeMap, g as take, h as takeUntil, i as Subject, k as Source, l as initialize, m as share, n as fromPromise, o as fromArray, p as merge, r as fromSubscription, s as fromValue, t as make, u as tap, v as map, w as subscribe, x as collect, y as peek } from "../make-BhxZYW3l.cjs";
2
- export { type Observer, type Operator, type Sink, type Source, type Subject, type Subscription, collect, collectAll, compose, filter, finalize, fromArray, fromPromise, fromSubscription, fromValue, initialize, make, makeSubject, map, merge, mergeMap, peek, pipe, publish, share, subscribe, switchMap, take, takeUntil, tap };
1
+ import { A as Source, C as publish, D as pipe, E as compose, O as Operator, S as collect, T as subscribe, _ as take, a as Subject, b as peek, c as fromValue, d as tap, f as switchMap, g as takeUntil, h as share, i as fromSubscription, j as Subscription, k as Sink, l as finalize, m as merge, n as make, o as makeSubject, p as mergeMap, r as fromPromise, s as fromArray, t as fromAbortSignal, u as initialize, v as filter, w as Observer, x as collectAll, y as map } from "../from-abort-signal-CsSc5Ee6.cjs";
2
+ export { type Observer, type Operator, type Sink, type Source, type Subject, type Subscription, collect, collectAll, compose, filter, finalize, fromAbortSignal, fromArray, fromPromise, fromSubscription, fromValue, initialize, make, makeSubject, map, merge, mergeMap, peek, pipe, publish, share, subscribe, switchMap, take, takeUntil, tap };
@@ -1,2 +1,2 @@
1
- import { A as Subscription, C as Observer, D as Operator, E as pipe, O as Sink, S as publish, T as compose, _ as filter, a as makeSubject, b as collectAll, c as finalize, d as switchMap, f as mergeMap, g as take, h as takeUntil, i as Subject, k as Source, l as initialize, m as share, n as fromPromise, o as fromArray, p as merge, r as fromSubscription, s as fromValue, t as make, u as tap, v as map, w as subscribe, x as collect, y as peek } from "../make-Ve8TkMHJ.mjs";
2
- export { type Observer, type Operator, type Sink, type Source, type Subject, type Subscription, collect, collectAll, compose, filter, finalize, fromArray, fromPromise, fromSubscription, fromValue, initialize, make, makeSubject, map, merge, mergeMap, peek, pipe, publish, share, subscribe, switchMap, take, takeUntil, tap };
1
+ import { A as Source, C as publish, D as pipe, E as compose, O as Operator, S as collect, T as subscribe, _ as take, a as Subject, b as peek, c as fromValue, d as tap, f as switchMap, g as takeUntil, h as share, i as fromSubscription, j as Subscription, k as Sink, l as finalize, m as merge, n as make, o as makeSubject, p as mergeMap, r as fromPromise, s as fromArray, t as fromAbortSignal, u as initialize, v as filter, w as Observer, x as collectAll, y as map } from "../from-abort-signal-ZiBY-b44.mjs";
2
+ export { type Observer, type Operator, type Sink, type Source, type Subject, type Subscription, collect, collectAll, compose, filter, finalize, fromAbortSignal, fromArray, fromPromise, fromSubscription, fromValue, initialize, make, makeSubject, map, merge, mergeMap, peek, pipe, publish, share, subscribe, switchMap, take, takeUntil, tap };
@@ -1,3 +1,3 @@
1
- import { C as mergeMap, S as filter, _ as compose, a as finalize, b as merge, c as share, d as map, f as peek, g as subscribe, h as publish, i as fromValue, l as takeUntil, m as collect, n as fromSubscription, o as initialize, p as collectAll, r as makeSubject, s as switchMap, t as make, u as take, v as fromArray, w as pipe, x as fromPromise, y as tap } from "../make-C7I1YIXm.mjs";
1
+ import { C as filter, S as fromPromise, T as pipe, _ as subscribe, a as fromValue, b as tap, c as switchMap, d as take, f as map, g as publish, h as collect, i as makeSubject, l as share, m as collectAll, n as make, o as finalize, p as peek, r as fromSubscription, s as initialize, t as fromAbortSignal, u as takeUntil, v as compose, w as mergeMap, x as merge, y as fromArray } from "../from-abort-signal-ClRa7iWd.mjs";
2
2
 
3
- export { collect, collectAll, compose, filter, finalize, fromArray, fromPromise, fromSubscription, fromValue, initialize, make, makeSubject, map, merge, mergeMap, peek, pipe, publish, share, subscribe, switchMap, take, takeUntil, tap };
3
+ export { collect, collectAll, compose, filter, finalize, fromAbortSignal, fromArray, fromPromise, fromSubscription, fromValue, initialize, make, makeSubject, map, merge, mergeMap, peek, pipe, publish, share, subscribe, switchMap, take, takeUntil, tap };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mearie/core",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "Type-safe, zero-overhead GraphQL client",
5
5
  "keywords": [
6
6
  "graphql",