@apollo/client 4.0.0-alpha.8 → 4.0.0-alpha.9

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.
Files changed (49) hide show
  1. package/.changeset/forty-tomatoes-punch.md +5 -0
  2. package/.changeset/fuzzy-tips-sit.md +5 -0
  3. package/.changeset/khaki-keys-deliver.md +5 -0
  4. package/.changeset/large-plants-know.md +5 -0
  5. package/.changeset/mean-lizards-think.md +5 -0
  6. package/.changeset/pre.json +6 -0
  7. package/.changeset/thin-peas-hear.md +16 -0
  8. package/CHANGELOG.md +29 -0
  9. package/__cjs/core/ObservableQuery.cjs +91 -28
  10. package/__cjs/core/ObservableQuery.cjs.map +1 -1
  11. package/__cjs/core/ObservableQuery.d.cts +2 -1
  12. package/__cjs/core/QueryManager.cjs +2 -2
  13. package/__cjs/core/QueryManager.cjs.map +1 -1
  14. package/__cjs/core/watchQueryOptions.d.cts +2 -2
  15. package/__cjs/react/hooks/useLazyQuery.cjs +17 -20
  16. package/__cjs/react/hooks/useLazyQuery.cjs.map +1 -1
  17. package/__cjs/react/hooks/useLazyQuery.d.cts +1 -1
  18. package/__cjs/react/hooks/useMutation.d.cts +1 -1
  19. package/__cjs/react/hooks/useQuery.d.cts +1 -1
  20. package/__cjs/react/query-preloader/createQueryPreloader.cjs +1 -0
  21. package/__cjs/react/query-preloader/createQueryPreloader.cjs.map +1 -1
  22. package/__cjs/react/types/types.documentation.d.cts +2 -2
  23. package/__cjs/testing/matchers/arrayWithLength.cjs +15 -0
  24. package/__cjs/testing/matchers/arrayWithLength.cjs.map +1 -0
  25. package/__cjs/testing/matchers/arrayWithLength.d.cts +3 -0
  26. package/__cjs/testing/matchers/index.cjs +2 -0
  27. package/__cjs/testing/matchers/index.cjs.map +1 -1
  28. package/__cjs/version.cjs +1 -1
  29. package/core/ObservableQuery.d.ts +2 -1
  30. package/core/ObservableQuery.js +91 -28
  31. package/core/ObservableQuery.js.map +1 -1
  32. package/core/QueryManager.js +2 -2
  33. package/core/QueryManager.js.map +1 -1
  34. package/core/watchQueryOptions.d.ts +2 -2
  35. package/package.json +1 -1
  36. package/react/hooks/useLazyQuery.d.ts +1 -1
  37. package/react/hooks/useLazyQuery.js +17 -20
  38. package/react/hooks/useLazyQuery.js.map +1 -1
  39. package/react/hooks/useMutation.d.ts +1 -1
  40. package/react/hooks/useQuery.d.ts +1 -1
  41. package/react/query-preloader/createQueryPreloader.js +1 -0
  42. package/react/query-preloader/createQueryPreloader.js.map +1 -1
  43. package/react/types/types.documentation.d.ts +2 -2
  44. package/testing/matchers/arrayWithLength.d.ts +3 -0
  45. package/testing/matchers/arrayWithLength.js +11 -0
  46. package/testing/matchers/arrayWithLength.js.map +1 -0
  47. package/testing/matchers/index.js +2 -0
  48. package/testing/matchers/index.js.map +1 -1
  49. package/version.js +1 -1
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@apollo/client": patch
3
+ ---
4
+
5
+ The returned `networkStatus` in `useLazyQuery` is now set to `setVariables` when calling the `useLazyQuery` `execute` function for the first time with variables.
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@apollo/client": patch
3
+ ---
4
+
5
+ Ensure `ObservableQuery` stops polling if switching to a `standby` `fetchPolicy`. When switching back to a non-`standby` `fetchPolicy`, polling will resume.
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@apollo/client": major
3
+ ---
4
+
5
+ An initial loading state is now emitted from `ObservableQuery` when subscribing if `notifyOnNetworkStatusChange` is set to `true`.
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@apollo/client": patch
3
+ ---
4
+
5
+ Ensure a loading state is emitted when calling the `execute` function after changing clients in `useLazyQuery`.
@@ -0,0 +1,5 @@
1
+ ---
2
+ "@apollo/client": patch
3
+ ---
4
+
5
+ Ensure `useLazyQuery` does not return a `partial` property which is not specified by the result type.
@@ -26,9 +26,11 @@
26
26
  "fluffy-shoes-applaud",
27
27
  "forty-hairs-occur",
28
28
  "forty-shrimps-fry",
29
+ "forty-tomatoes-punch",
29
30
  "four-ghosts-watch",
30
31
  "fresh-moose-hope",
31
32
  "funny-jeans-invent",
33
+ "fuzzy-tips-sit",
32
34
  "giant-apes-thank",
33
35
  "giant-bags-share",
34
36
  "good-dolphins-peel",
@@ -39,8 +41,10 @@
39
41
  "hot-cycles-notice",
40
42
  "itchy-drinks-refuse",
41
43
  "itchy-roses-accept",
44
+ "khaki-keys-deliver",
42
45
  "khaki-spies-work",
43
46
  "kind-fishes-develop",
47
+ "large-plants-know",
44
48
  "late-trainers-peel",
45
49
  "light-apes-rescue",
46
50
  "light-dolphins-taste",
@@ -50,6 +54,7 @@
50
54
  "lucky-hats-push",
51
55
  "many-buses-allow",
52
56
  "many-papayas-hide",
57
+ "mean-lizards-think",
53
58
  "metal-needles-search",
54
59
  "mighty-penguins-wink",
55
60
  "modern-feet-do",
@@ -98,6 +103,7 @@
98
103
  "tame-points-work",
99
104
  "tender-swans-flash",
100
105
  "thick-books-grin",
106
+ "thin-peas-hear",
101
107
  "tidy-squids-poke",
102
108
  "tough-rockets-allow",
103
109
  "tough-taxis-smoke",
@@ -0,0 +1,16 @@
1
+ ---
2
+ "@apollo/client": major
3
+ ---
4
+
5
+ `notifyOnNetworkStatusChange` now defaults to `true`. This means that loading states will be emitted (core API) or rendered (React) by default when calling `refetch`, `fetchMore`, etc. To maintain the old behavior, set `notifyOnNetworkStatusChange` to `false` in `defaultOptions`.
6
+
7
+ ```ts
8
+ new ApolloClient({
9
+ defaultOptions: {
10
+ watchQuery: {
11
+ // Use the v3 default
12
+ notifyOnNetworkStatusChange: false
13
+ }
14
+ }
15
+ })
16
+ ```
package/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # @apollo/client
2
2
 
3
+ ## 4.0.0-alpha.9
4
+
5
+ ### Major Changes
6
+
7
+ - [#12536](https://github.com/apollographql/apollo-client/pull/12536) [`e14205a`](https://github.com/apollographql/apollo-client/commit/e14205ad5909f95aa04684acd0ca2f25956ee50c) Thanks [@jerelmiller](https://github.com/jerelmiller)! - An initial loading state is now emitted from `ObservableQuery` when subscribing if `notifyOnNetworkStatusChange` is set to `true`.
8
+
9
+ - [#12512](https://github.com/apollographql/apollo-client/pull/12512) [`e809b71`](https://github.com/apollographql/apollo-client/commit/e809b71aa9a02917a286afdbb03d5be8e5947c53) Thanks [@jerelmiller](https://github.com/jerelmiller)! - `notifyOnNetworkStatusChange` now defaults to `true`. This means that loading states will be emitted (core API) or rendered (React) by default when calling `refetch`, `fetchMore`, etc. To maintain the old behavior, set `notifyOnNetworkStatusChange` to `false` in `defaultOptions`.
10
+
11
+ ```ts
12
+ new ApolloClient({
13
+ defaultOptions: {
14
+ watchQuery: {
15
+ // Use the v3 default
16
+ notifyOnNetworkStatusChange: false,
17
+ },
18
+ },
19
+ });
20
+ ```
21
+
22
+ ### Patch Changes
23
+
24
+ - [#12536](https://github.com/apollographql/apollo-client/pull/12536) [`e14205a`](https://github.com/apollographql/apollo-client/commit/e14205ad5909f95aa04684acd0ca2f25956ee50c) Thanks [@jerelmiller](https://github.com/jerelmiller)! - The returned `networkStatus` in `useLazyQuery` is now set to `setVariables` when calling the `useLazyQuery` `execute` function for the first time with variables.
25
+
26
+ - [#12536](https://github.com/apollographql/apollo-client/pull/12536) [`e14205a`](https://github.com/apollographql/apollo-client/commit/e14205ad5909f95aa04684acd0ca2f25956ee50c) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Ensure `ObservableQuery` stops polling if switching to a `standby` `fetchPolicy`. When switching back to a non-`standby` `fetchPolicy`, polling will resume.
27
+
28
+ - [#12536](https://github.com/apollographql/apollo-client/pull/12536) [`e14205a`](https://github.com/apollographql/apollo-client/commit/e14205ad5909f95aa04684acd0ca2f25956ee50c) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Ensure a loading state is emitted when calling the `execute` function after changing clients in `useLazyQuery`.
29
+
30
+ - [#12542](https://github.com/apollographql/apollo-client/pull/12542) [`afb4fce`](https://github.com/apollographql/apollo-client/commit/afb4fce08859b2c6eebf288230a7c35b7acf2da6) Thanks [@jerelmiller](https://github.com/jerelmiller)! - Ensure `useLazyQuery` does not return a `partial` property which is not specified by the result type.
31
+
3
32
  ## 4.0.0-alpha.8
4
33
 
5
34
  ### Major Changes
@@ -17,6 +17,7 @@ const equalByQuery_js_1 = require("./equalByQuery.cjs");
17
17
  const networkStatus_js_1 = require("./networkStatus.cjs");
18
18
  const { assign, hasOwnProperty } = Object;
19
19
  const newNetworkStatusSymbol = Symbol();
20
+ const uninitialized = {};
20
21
  class ObservableQuery {
21
22
  /**
22
23
  * @internal
@@ -46,7 +47,6 @@ class ObservableQuery {
46
47
  }
47
48
  subject;
48
49
  observable;
49
- initialResult;
50
50
  isTornDown;
51
51
  queryManager;
52
52
  subscriptions = new Set();
@@ -60,14 +60,8 @@ class ObservableQuery {
60
60
  networkStatus;
61
61
  constructor({ queryManager, queryInfo, options, }) {
62
62
  this.networkStatus = networkStatus_js_1.NetworkStatus.loading;
63
- this.initialResult = {
64
- data: undefined,
65
- loading: true,
66
- networkStatus: this.networkStatus,
67
- partial: true,
68
- };
69
63
  let startedInactive = ObservableQuery.inactiveOnCreation.getValue();
70
- this.subject = new rxjs_1.BehaviorSubject(this.initialResult);
64
+ this.subject = new rxjs_1.BehaviorSubject(uninitialized);
71
65
  this.observable = this.subject.pipe((0, rxjs_1.tap)({
72
66
  subscribe: () => {
73
67
  if (startedInactive) {
@@ -75,6 +69,22 @@ class ObservableQuery {
75
69
  startedInactive = false;
76
70
  }
77
71
  if (!this.subject.observed) {
72
+ if (this.subject.value === uninitialized) {
73
+ // Emitting a value in the `subscribe` callback of `tap` gives
74
+ // the subject a chance to save this initial result without
75
+ // emitting the placeholder value since this callback is executed
76
+ // before `tap` subscribes to the source observable (the subject).
77
+ // `reobserve` also has the chance to update this value if it
78
+ // synchronously emits one (usually due to reporting a cache
79
+ // value).
80
+ //
81
+ // We don't initialize the `BehaviorSubject` with
82
+ // `getInitialResult` because its possible the cache might have
83
+ // updated between when the `ObservableQuery` was instantiated and
84
+ // when it is subscribed to. Updating the value here ensures we
85
+ // report the most up-to-date result from the cache.
86
+ this.subject.next(this.getInitialResult());
87
+ }
78
88
  this.reobserve();
79
89
  // TODO: See if we can rework updatePolling to better handle this.
80
90
  // reobserve calls updatePolling but this `subscribe` callback is
@@ -89,19 +99,14 @@ class ObservableQuery {
89
99
  this.tearDownQuery();
90
100
  }
91
101
  },
92
- }),
93
- // TODO: Conditionally filter when notifyOnNetworkStatusChange is true or
94
- // not. We want to emit the loading result if notifyOnNetworkStatusChange
95
- // is true.
96
- (0, rxjs_1.filter)((result) =>
97
- // TODO: Remove this behavior when unifying loading state for notifyOnNetworkStatusChange
98
- (this.options.fetchPolicy === "no-cache" &&
99
- this.options.notifyOnNetworkStatusChange) ||
100
- // TODO: Remove this behavior when unifying loading state for notifyOnNetworkStatusChange
101
- (this.options.fetchPolicy === "network-only" &&
102
- !this.queryManager.prioritizeCacheValues &&
103
- this.queryInfo.getDiff().complete) ||
104
- result !== this.initialResult));
102
+ }), (0, rxjs_1.filter)((result) => {
103
+ return (this.options.fetchPolicy !== "standby" &&
104
+ (this.options.notifyOnNetworkStatusChange ||
105
+ !result.loading ||
106
+ // data could be defined for cache-and-network fetch policies
107
+ // when emitting the cache result while loading the network result
108
+ !!result.data));
109
+ }));
105
110
  this["@@observable"] = () => this;
106
111
  if (Symbol.observable) {
107
112
  this[Symbol.observable] = () => this;
@@ -146,6 +151,50 @@ class ObservableQuery {
146
151
  resetDiff() {
147
152
  this.queryInfo.resetDiff();
148
153
  }
154
+ getInitialResult() {
155
+ const fetchPolicy = this.queryManager.prioritizeCacheValues ?
156
+ "cache-first"
157
+ : this.options.fetchPolicy;
158
+ const defaultResult = {
159
+ data: undefined,
160
+ loading: true,
161
+ networkStatus: networkStatus_js_1.NetworkStatus.loading,
162
+ partial: true,
163
+ };
164
+ const cacheResult = () => {
165
+ const diff = this.queryInfo.getDiff();
166
+ return this.maskResult({
167
+ data:
168
+ // TODO: queryInfo.getDiff should handle this since cache.diff returns a
169
+ // null when returnPartialData is false
170
+ this.options.returnPartialData || diff.complete ?
171
+ diff.result ?? undefined
172
+ : undefined,
173
+ loading: !diff.complete,
174
+ networkStatus: diff.complete ? networkStatus_js_1.NetworkStatus.ready : networkStatus_js_1.NetworkStatus.loading,
175
+ partial: !diff.complete,
176
+ });
177
+ };
178
+ switch (fetchPolicy) {
179
+ case "cache-only":
180
+ case "cache-first":
181
+ return cacheResult();
182
+ case "cache-and-network":
183
+ return {
184
+ ...cacheResult(),
185
+ loading: true,
186
+ networkStatus: networkStatus_js_1.NetworkStatus.loading,
187
+ };
188
+ case "standby":
189
+ return {
190
+ ...defaultResult,
191
+ loading: false,
192
+ networkStatus: networkStatus_js_1.NetworkStatus.ready,
193
+ };
194
+ default:
195
+ return defaultResult;
196
+ }
197
+ }
149
198
  getCurrentFullResult(saveAsLastResult = true) {
150
199
  // Use the last result as long as the variables match this.variables.
151
200
  const lastResult = this.getLastResult(true);
@@ -321,6 +370,7 @@ class ObservableQuery {
321
370
  // fetchMore to provide an updateQuery callback that determines how
322
371
  // the data gets written to the cache.
323
372
  fetchPolicy: "no-cache",
373
+ notifyOnNetworkStatusChange: this.options.notifyOnNetworkStatusChange,
324
374
  };
325
375
  combinedOptions.query = this.transformDocument(combinedOptions.query);
326
376
  const qid = this.queryManager.generateQueryId();
@@ -613,10 +663,7 @@ class ObservableQuery {
613
663
  }
614
664
  const { pollingInfo, options: { pollInterval }, } = this;
615
665
  if (!pollInterval || !this.hasObservers()) {
616
- if (pollingInfo) {
617
- clearTimeout(pollingInfo.timeout);
618
- delete this.pollingInfo;
619
- }
666
+ this.cancelPolling();
620
667
  return;
621
668
  }
622
669
  if (pollingInfo && pollingInfo.interval === pollInterval) {
@@ -654,6 +701,13 @@ class ObservableQuery {
654
701
  };
655
702
  poll();
656
703
  }
704
+ // This differs from stopPolling in that it does not set pollInterval to 0
705
+ cancelPolling() {
706
+ if (this.pollingInfo) {
707
+ clearTimeout(this.pollingInfo.timeout);
708
+ delete this.pollingInfo;
709
+ }
710
+ }
657
711
  updateLastResult(newResult, variables = this.variables) {
658
712
  let error = this.getLastError();
659
713
  // Preserve this.last.error unless the variables have changed.
@@ -705,6 +759,7 @@ class ObservableQuery {
705
759
  // We want to ensure we can re-run the custom document transforms the next
706
760
  // time a request is made against the original query.
707
761
  const query = this.transformDocument(options.query);
762
+ const { fetchPolicy } = options;
708
763
  this.lastQuery = query;
709
764
  if (!useDisposableObservable) {
710
765
  // We can skip calling updatePolling if we're not changing this.options.
@@ -715,10 +770,10 @@ class ObservableQuery {
715
770
  newOptions.variables &&
716
771
  !(0, equality_1.equal)(newOptions.variables, oldVariables) &&
717
772
  // Don't mess with the fetchPolicy if it's currently "standby".
718
- options.fetchPolicy !== "standby" &&
773
+ fetchPolicy !== "standby" &&
719
774
  // If we're changing the fetchPolicy anyway, don't try to change it here
720
775
  // using applyNextFetchPolicy. The explicit options.fetchPolicy wins.
721
- (options.fetchPolicy === oldFetchPolicy ||
776
+ (fetchPolicy === oldFetchPolicy ||
722
777
  // A `nextFetchPolicy` function has even higher priority, though,
723
778
  // so in that case `applyNextFetchPolicy` must be called.
724
779
  typeof options.nextFetchPolicy === "function")) {
@@ -736,6 +791,14 @@ class ObservableQuery {
736
791
  !(0, equality_1.equal)(newOptions.variables, oldVariables)) {
737
792
  newNetworkStatus = networkStatus_js_1.NetworkStatus.setVariables;
738
793
  }
794
+ // QueryManager does not emit any values for standby fetch policies so we
795
+ // want ensure that the networkStatus remains ready.
796
+ if (fetchPolicy === "standby") {
797
+ newNetworkStatus = networkStatus_js_1.NetworkStatus.ready;
798
+ }
799
+ }
800
+ if (fetchPolicy === "standby") {
801
+ this.cancelPolling();
739
802
  }
740
803
  this.networkStatus = newNetworkStatus;
741
804
  this.waitForOwnResult &&= skipCacheDataFor(options.fetchPolicy);
@@ -745,7 +808,7 @@ class ObservableQuery {
745
808
  }
746
809
  };
747
810
  const variables = options.variables && { ...options.variables };
748
- const { notifyOnNetworkStatusChange = false } = options;
811
+ const { notifyOnNetworkStatusChange = true } = options;
749
812
  const { observable, fromLink } = this.fetch(options, newNetworkStatus, notifyOnNetworkStatusChange &&
750
813
  oldNetworkStatus !== newNetworkStatus &&
751
814
  (0, networkStatus_js_1.isNetworkRequestInFlight)(newNetworkStatus), query);