@apollo/client 4.0.5 → 4.1.0-alpha.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.
Files changed (76) hide show
  1. package/CHANGELOG.md +27 -2
  2. package/__cjs/cache/core/cache.cjs +1 -1
  3. package/__cjs/cache/inmemory/entityStore.cjs +3 -3
  4. package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
  5. package/__cjs/cache/inmemory/policies.cjs +4 -4
  6. package/__cjs/cache/inmemory/policies.cjs.map +1 -1
  7. package/__cjs/cache/inmemory/readFromStore.cjs +2 -2
  8. package/__cjs/cache/inmemory/writeToStore.cjs +5 -5
  9. package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  10. package/__cjs/core/ApolloClient.cjs +12 -12
  11. package/__cjs/core/ObservableQuery.cjs +157 -106
  12. package/__cjs/core/ObservableQuery.cjs.map +1 -1
  13. package/__cjs/core/ObservableQuery.d.cts +1 -0
  14. package/__cjs/core/QueryManager.cjs +12 -12
  15. package/__cjs/incremental/handlers/defer20220824.cjs +20 -9
  16. package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
  17. package/__cjs/incremental/handlers/defer20220824.d.cts +14 -5
  18. package/__cjs/incremental/handlers/graphql17Alpha9.cjs +181 -0
  19. package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -0
  20. package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +97 -0
  21. package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
  22. package/__cjs/incremental/index.cjs +3 -1
  23. package/__cjs/incremental/index.cjs.map +1 -1
  24. package/__cjs/incremental/index.d.cts +1 -0
  25. package/__cjs/invariantErrorCodes.cjs +51 -45
  26. package/__cjs/react/internal/cache/QueryReference.cjs +16 -0
  27. package/__cjs/react/internal/cache/QueryReference.cjs.map +1 -1
  28. package/__cjs/react/internal/cache/QueryReference.d.cts +1 -0
  29. package/__cjs/testing/core/mocking/mockLink.cjs.map +1 -1
  30. package/__cjs/testing/core/mocking/mockLink.d.cts +1 -3
  31. package/__cjs/utilities/internal/DeepMerger.cjs +10 -1
  32. package/__cjs/utilities/internal/DeepMerger.cjs.map +1 -1
  33. package/__cjs/utilities/internal/DeepMerger.d.cts +14 -2
  34. package/__cjs/utilities/internal/getStoreKeyName.cjs +1 -0
  35. package/__cjs/utilities/internal/getStoreKeyName.cjs.map +1 -1
  36. package/__cjs/version.cjs +1 -1
  37. package/__cjs/version.cjs.map +1 -1
  38. package/cache/core/cache.js +1 -1
  39. package/cache/inmemory/entityStore.js +3 -3
  40. package/cache/inmemory/key-extractor.js +1 -1
  41. package/cache/inmemory/policies.js +4 -4
  42. package/cache/inmemory/policies.js.map +1 -1
  43. package/cache/inmemory/readFromStore.js +2 -2
  44. package/cache/inmemory/writeToStore.js +5 -5
  45. package/cache/inmemory/writeToStore.js.map +1 -1
  46. package/core/ApolloClient.js +12 -12
  47. package/core/ObservableQuery.d.ts +1 -0
  48. package/core/ObservableQuery.js +159 -108
  49. package/core/ObservableQuery.js.map +1 -1
  50. package/core/QueryManager.js +12 -12
  51. package/incremental/handlers/defer20220824.d.ts +14 -5
  52. package/incremental/handlers/defer20220824.js +20 -9
  53. package/incremental/handlers/defer20220824.js.map +1 -1
  54. package/incremental/handlers/graphql17Alpha9.d.ts +97 -0
  55. package/incremental/handlers/graphql17Alpha9.js +177 -0
  56. package/incremental/handlers/graphql17Alpha9.js.map +1 -0
  57. package/incremental/handlers/notImplemented.js +1 -1
  58. package/incremental/index.d.ts +1 -0
  59. package/incremental/index.js +3 -2
  60. package/incremental/index.js.map +1 -1
  61. package/invariantErrorCodes.js +51 -45
  62. package/package.json +1 -1
  63. package/react/internal/cache/QueryReference.d.ts +1 -0
  64. package/react/internal/cache/QueryReference.js +16 -0
  65. package/react/internal/cache/QueryReference.js.map +1 -1
  66. package/testing/core/mocking/mockLink.d.ts +1 -3
  67. package/testing/core/mocking/mockLink.js.map +1 -1
  68. package/utilities/internal/DeepMerger.d.ts +14 -2
  69. package/utilities/internal/DeepMerger.js +10 -1
  70. package/utilities/internal/DeepMerger.js.map +1 -1
  71. package/utilities/internal/getStoreKeyName.js +1 -0
  72. package/utilities/internal/getStoreKeyName.js.map +1 -1
  73. package/utilities/internal/globals/global.js +2 -2
  74. package/utilities/internal/globals/global.js.map +1 -1
  75. package/version.js +1 -1
  76. package/version.js.map +1 -1
@@ -79,8 +79,8 @@ class ApolloClient {
79
79
  */
80
80
  constructor(options) {
81
81
  if (environment_1.__DEV__) {
82
- (0, invariant_1.invariant)(options.cache, 65);
83
- (0, invariant_1.invariant)(options.link, 66);
82
+ (0, invariant_1.invariant)(options.cache, 66);
83
+ (0, invariant_1.invariant)(options.link, 67);
84
84
  }
85
85
  const { cache, documentTransform, ssrMode = false, ssrForceFetchDelay = 0, queryDeduplication = true, defaultOptions, defaultContext, assumeImmutableResults = cache.assumeImmutableResults, localState, devtools, dataMasking, link, incrementalHandler = new incremental_1.NotImplementedHandler(), } = options;
86
86
  this.link = link;
@@ -240,13 +240,13 @@ class ApolloClient {
240
240
  options = (0, internal_1.mergeOptions)(this.defaultOptions.query, options);
241
241
  }
242
242
  if (environment_1.__DEV__) {
243
- (0, invariant_1.invariant)(options.fetchPolicy !== "cache-and-network", 67);
244
- (0, invariant_1.invariant)(options.fetchPolicy !== "standby", 68);
245
- (0, invariant_1.invariant)(options.query, 69);
246
- (0, invariant_1.invariant)(options.query.kind === "Document", 70);
247
- (0, invariant_1.invariant)(!options.returnPartialData, 71);
248
- (0, invariant_1.invariant)(!options.pollInterval, 72);
249
- (0, invariant_1.invariant)(!options.notifyOnNetworkStatusChange, 73);
243
+ (0, invariant_1.invariant)(options.fetchPolicy !== "cache-and-network", 68);
244
+ (0, invariant_1.invariant)(options.fetchPolicy !== "standby", 69);
245
+ (0, invariant_1.invariant)(options.query, 70);
246
+ (0, invariant_1.invariant)(options.query.kind === "Document", 71);
247
+ (0, invariant_1.invariant)(!options.returnPartialData, 72);
248
+ (0, invariant_1.invariant)(!options.pollInterval, 73);
249
+ (0, invariant_1.invariant)(!options.notifyOnNetworkStatusChange, 74);
250
250
  }
251
251
  return this.queryManager.query(options);
252
252
  }
@@ -264,9 +264,9 @@ class ApolloClient {
264
264
  errorPolicy: "none",
265
265
  }, this.defaultOptions.mutate), options);
266
266
  if (environment_1.__DEV__) {
267
- (0, invariant_1.invariant)(optionsWithDefaults.mutation, 74);
267
+ (0, invariant_1.invariant)(optionsWithDefaults.mutation, 75);
268
268
  (0, invariant_1.invariant)(optionsWithDefaults.fetchPolicy === "network-only" ||
269
- optionsWithDefaults.fetchPolicy === "no-cache", 75);
269
+ optionsWithDefaults.fetchPolicy === "no-cache", 76);
270
270
  }
271
271
  (0, internal_1.checkDocument)(optionsWithDefaults.mutation, graphql_1.OperationTypeNode.MUTATION);
272
272
  return this.queryManager.mutate(optionsWithDefaults);
@@ -491,7 +491,7 @@ class ApolloClient {
491
491
  // result.queries and result.results instead, you shouldn't have to worry
492
492
  // about preventing uncaught rejections for the Promise.all result.
493
493
  result.catch((error) => {
494
- __DEV__ && invariant_1.invariant.debug(76, error);
494
+ __DEV__ && invariant_1.invariant.debug(77, error);
495
495
  });
496
496
  return result;
497
497
  }
@@ -68,6 +68,9 @@ class ObservableQuery {
68
68
  get networkStatus() {
69
69
  return this.subject.getValue().result.networkStatus;
70
70
  }
71
+ get cache() {
72
+ return this.queryManager.cache;
73
+ }
71
74
  constructor({ queryManager, options, transformedQuery = queryManager.transform(options.query), }) {
72
75
  this.queryManager = queryManager;
73
76
  // active state
@@ -205,7 +208,7 @@ class ObservableQuery {
205
208
  * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
206
209
  */
207
210
  getCacheDiff({ optimistic = true } = {}) {
208
- return this.queryManager.cache.diff({
211
+ return this.cache.diff({
209
212
  query: this.query,
210
213
  variables: this.variables,
211
214
  returnPartialData: true,
@@ -316,7 +319,7 @@ class ObservableQuery {
316
319
  }
317
320
  },
318
321
  };
319
- const cancelWatch = this.queryManager.cache.watch(watch);
322
+ const cancelWatch = this.cache.watch(watch);
320
323
  this.unsubscribeFromCache = Object.assign(() => {
321
324
  this.unsubscribeFromCache = undefined;
322
325
  cancelWatch();
@@ -380,7 +383,7 @@ class ObservableQuery {
380
383
  const queryDef = (0, internal_1.getQueryDefinition)(this.query);
381
384
  const vars = queryDef.variableDefinitions;
382
385
  if (!vars || !vars.some((v) => v.variable.name.value === "variables")) {
383
- __DEV__ && invariant_1.invariant.warn(77, variables, queryDef.name?.value || queryDef);
386
+ __DEV__ && invariant_1.invariant.warn(78, variables, queryDef.name?.value || queryDef);
384
387
  }
385
388
  }
386
389
  if (variables && !(0, equality_1.equal)(this.variables, variables)) {
@@ -396,7 +399,7 @@ class ObservableQuery {
396
399
  fetchMore({ query, variables, context, errorPolicy, updateQuery, }) {
397
400
  (0, invariant_1.invariant)(
398
401
  this.options.fetchPolicy !== "cache-only",
399
- 78,
402
+ 79,
400
403
  (0, internal_1.getOperationName)(this.query, "(anonymous)")
401
404
  );
402
405
  const combinedOptions = {
@@ -430,7 +433,7 @@ class ObservableQuery {
430
433
  let wasUpdated = false;
431
434
  const isCached = this.options.fetchPolicy !== "no-cache";
432
435
  if (!isCached) {
433
- (0, invariant_1.invariant)(updateQuery, 79);
436
+ (0, invariant_1.invariant)(updateQuery, 80);
434
437
  }
435
438
  const { finalize, pushNotification } = this.pushOperation(networkStatus_js_1.NetworkStatus.fetchMore);
436
439
  pushNotification({
@@ -438,105 +441,153 @@ class ObservableQuery {
438
441
  kind: "N",
439
442
  value: {},
440
443
  }, { shouldEmit: 3 /* EmitBehavior.networkStatusChange */ });
441
- return this.queryManager
442
- .fetchQuery(combinedOptions, networkStatus_js_1.NetworkStatus.fetchMore)
443
- .then((fetchMoreResult) => {
444
- // disable the `fetchMore` override that is currently active
445
- // the next updates caused by this should not be `fetchMore` anymore,
446
- // but `ready` or whatever other calculated loading state is currently
447
- // appropriate
448
- finalize();
449
- if (isCached) {
450
- // Performing this cache update inside a cache.batch transaction ensures
451
- // any affected cache.watch watchers are notified at most once about any
452
- // updates. Most watchers will be using the QueryInfo class, which
453
- // responds to notifications by calling reobserveCacheFirst to deliver
454
- // fetchMore cache results back to this ObservableQuery.
455
- this.queryManager.cache.batch({
456
- update: (cache) => {
457
- if (updateQuery) {
458
- cache.updateQuery({
459
- query: this.query,
460
- variables: this.variables,
461
- returnPartialData: true,
462
- optimistic: false,
463
- }, (previous) => updateQuery(previous, {
464
- fetchMoreResult: fetchMoreResult.data,
465
- variables: combinedOptions.variables,
466
- }));
467
- }
468
- else {
469
- // If we're using a field policy instead of updateQuery, the only
470
- // thing we need to do is write the new data to the cache using
471
- // combinedOptions.variables (instead of this.variables, which is
472
- // what this.updateQuery uses, because it works by abusing the
473
- // original field value, keyed by the original variables).
474
- cache.writeQuery({
475
- query: combinedOptions.query,
476
- variables: combinedOptions.variables,
477
- data: fetchMoreResult.data,
478
- });
479
- }
480
- },
481
- onWatchUpdated: (watch) => {
482
- if (watch.watcher === this) {
483
- wasUpdated = true;
484
- }
485
- },
486
- });
487
- }
488
- else {
489
- // There is a possibility `lastResult` may not be set when
490
- // `fetchMore` is called which would cause this to crash. This should
491
- // only happen if we haven't previously reported a result. We don't
492
- // quite know what the right behavior should be here since this block
493
- // of code runs after the fetch result has executed on the network.
494
- // We plan to let it crash in the meantime.
495
- //
496
- // If we get bug reports due to the `data` property access on
497
- // undefined, this should give us a real-world scenario that we can
498
- // use to test against and determine the right behavior. If we do end
499
- // up changing this behavior, this may require, for example, an
500
- // adjustment to the types on `updateQuery` since that function
501
- // expects that the first argument always contains previous result
502
- // data, but not `undefined`.
503
- const lastResult = this.getCurrentResult();
504
- const data = updateQuery(lastResult.data, {
505
- fetchMoreResult: fetchMoreResult.data,
506
- variables: combinedOptions.variables,
507
- });
508
- // was reportResult
509
- pushNotification({
510
- kind: "N",
511
- value: {
512
- ...lastResult,
513
- networkStatus: networkStatus_js_1.NetworkStatus.ready,
514
- // will be overwritten anyways, just here for types sake
515
- loading: false,
516
- data: data,
517
- dataState: lastResult.dataState === "streaming" ? "streaming" : "complete",
518
- },
519
- source: "network",
520
- });
444
+ const { promise, operator } = getTrackingOperatorPromise((value) => {
445
+ switch (value.kind) {
446
+ case "E": {
447
+ throw value.error;
448
+ }
449
+ case "N": {
450
+ if (value.source !== "newNetworkStatus" && !value.value.loading) {
451
+ return value.value;
452
+ }
453
+ }
521
454
  }
522
- return this.maskResult(fetchMoreResult);
523
- })
455
+ });
456
+ const { observable } = this.queryManager.fetchObservableWithInfo(combinedOptions, { networkStatus: networkStatus_js_1.NetworkStatus.fetchMore });
457
+ const subscription = observable
458
+ .pipe(operator, (0, rxjs_1.filter)((notification) => notification.kind === "N" && notification.source === "network"))
459
+ .subscribe({
460
+ next: (notification) => {
461
+ wasUpdated = false;
462
+ const fetchMoreResult = notification.value;
463
+ if ((0, utilities_1.isNetworkRequestSettled)(notification.value.networkStatus)) {
464
+ finalize();
465
+ }
466
+ if (isCached) {
467
+ // Performing this cache update inside a cache.batch transaction ensures
468
+ // any affected cache.watch watchers are notified at most once about any
469
+ // updates. Most watchers will be using the QueryInfo class, which
470
+ // responds to notifications by calling reobserveCacheFirst to deliver
471
+ // fetchMore cache results back to this ObservableQuery.
472
+ this.cache.batch({
473
+ update: (cache) => {
474
+ if (updateQuery) {
475
+ cache.updateQuery({
476
+ query: this.query,
477
+ variables: this.variables,
478
+ returnPartialData: true,
479
+ optimistic: false,
480
+ }, (previous) => updateQuery(previous, {
481
+ fetchMoreResult: fetchMoreResult.data,
482
+ variables: combinedOptions.variables,
483
+ }));
484
+ }
485
+ else {
486
+ // If we're using a field policy instead of updateQuery, the only
487
+ // thing we need to do is write the new data to the cache using
488
+ // combinedOptions.variables (instead of this.variables, which is
489
+ // what this.updateQuery uses, because it works by abusing the
490
+ // original field value, keyed by the original variables).
491
+ cache.writeQuery({
492
+ query: combinedOptions.query,
493
+ variables: combinedOptions.variables,
494
+ data: fetchMoreResult.data,
495
+ });
496
+ }
497
+ },
498
+ onWatchUpdated: (watch, diff) => {
499
+ if (watch.watcher === this) {
500
+ wasUpdated = true;
501
+ const lastResult = this.getCurrentResult();
502
+ // Let the cache watch from resubscribeCache handle the final
503
+ // result
504
+ if ((0, utilities_1.isNetworkRequestInFlight)(fetchMoreResult.networkStatus)) {
505
+ pushNotification({
506
+ kind: "N",
507
+ source: "network",
508
+ value: {
509
+ ...lastResult,
510
+ networkStatus: (fetchMoreResult.networkStatus ===
511
+ networkStatus_js_1.NetworkStatus.error) ?
512
+ networkStatus_js_1.NetworkStatus.ready
513
+ : fetchMoreResult.networkStatus,
514
+ // will be overwritten anyways, just here for types sake
515
+ loading: false,
516
+ data: diff.result,
517
+ dataState: fetchMoreResult.dataState === "streaming" ?
518
+ "streaming"
519
+ : "complete",
520
+ },
521
+ });
522
+ }
523
+ }
524
+ },
525
+ });
526
+ }
527
+ else {
528
+ // There is a possibility `lastResult` may not be set when
529
+ // `fetchMore` is called which would cause this to crash. This should
530
+ // only happen if we haven't previously reported a result. We don't
531
+ // quite know what the right behavior should be here since this block
532
+ // of code runs after the fetch result has executed on the network.
533
+ // We plan to let it crash in the meantime.
534
+ //
535
+ // If we get bug reports due to the `data` property access on
536
+ // undefined, this should give us a real-world scenario that we can
537
+ // use to test against and determine the right behavior. If we do end
538
+ // up changing this behavior, this may require, for example, an
539
+ // adjustment to the types on `updateQuery` since that function
540
+ // expects that the first argument always contains previous result
541
+ // data, but not `undefined`.
542
+ const lastResult = this.getCurrentResult();
543
+ const data = updateQuery(lastResult.data, {
544
+ fetchMoreResult: fetchMoreResult.data,
545
+ variables: combinedOptions.variables,
546
+ });
547
+ pushNotification({
548
+ kind: "N",
549
+ value: {
550
+ ...lastResult,
551
+ networkStatus: networkStatus_js_1.NetworkStatus.ready,
552
+ // will be overwritten anyways, just here for types sake
553
+ loading: false,
554
+ data: data,
555
+ dataState: lastResult.dataState === "streaming" ?
556
+ "streaming"
557
+ : "complete",
558
+ },
559
+ source: "network",
560
+ });
561
+ }
562
+ },
563
+ });
564
+ return (0, internal_1.preventUnhandledRejection)(promise
565
+ .then((result) => (0, internal_1.toQueryResult)(this.maskResult(result)))
524
566
  .finally(() => {
525
- // call `finalize` a second time in case the `.then` case above was not reached
526
- finalize();
527
- // In case the cache writes above did not generate a broadcast
528
- // notification (which would have been intercepted by onWatchUpdated),
529
- // likely because the written data were the same as what was already in
530
- // the cache, we still want fetchMore to deliver its final loading:false
531
- // result with the unchanged data.
567
+ subscription.unsubscribe();
532
568
  if (isCached && !wasUpdated) {
533
- pushNotification({
534
- kind: "N",
535
- source: "newNetworkStatus",
536
- value: {},
537
- }, { shouldEmit: 1 /* EmitBehavior.force */ });
569
+ finalize();
570
+ const lastResult = this.getCurrentResult();
571
+ if (lastResult.networkStatus === networkStatus_js_1.NetworkStatus.streaming) {
572
+ pushNotification({
573
+ kind: "N",
574
+ source: "network",
575
+ value: {
576
+ ...lastResult,
577
+ dataState: "complete",
578
+ networkStatus: networkStatus_js_1.NetworkStatus.ready,
579
+ },
580
+ });
581
+ }
582
+ else {
583
+ pushNotification({
584
+ kind: "N",
585
+ source: "newNetworkStatus",
586
+ value: {},
587
+ }, { shouldEmit: 1 /* EmitBehavior.force */ });
588
+ }
538
589
  }
539
- });
590
+ }));
540
591
  }
541
592
  // XXX the subscription variables are separate from the query variables.
542
593
  // if you want to update subscription variables, right now you have to do that separately,
@@ -562,7 +613,7 @@ class ObservableQuery {
562
613
  onError(error);
563
614
  }
564
615
  else {
565
- invariant_1.invariant.error(80, error);
616
+ invariant_1.invariant.error(81, error);
566
617
  }
567
618
  return;
568
619
  }
@@ -640,7 +691,7 @@ class ObservableQuery {
640
691
  previousData: result,
641
692
  });
642
693
  if (newResult) {
643
- queryManager.cache.writeQuery({
694
+ this.cache.writeQuery({
644
695
  query: this.options.query,
645
696
  data: newResult,
646
697
  variables: this.variables,
@@ -806,7 +857,7 @@ class ObservableQuery {
806
857
  if (!this.didWarnCacheOnlyPolling &&
807
858
  pollInterval &&
808
859
  fetchPolicy === "cache-only") {
809
- __DEV__ && invariant_1.invariant.warn(81, (0, internal_1.getOperationName)(this.query, "(anonymous)"));
860
+ __DEV__ && invariant_1.invariant.warn(82, (0, internal_1.getOperationName)(this.query, "(anonymous)"));
810
861
  this.didWarnCacheOnlyPolling = true;
811
862
  }
812
863
  }
@@ -1073,8 +1124,8 @@ class ObservableQuery {
1073
1124
  const { dirty } = this;
1074
1125
  this.resetNotifications();
1075
1126
  if (dirty &&
1076
- (this.options.fetchPolicy == "cache-only" ||
1077
- this.options.fetchPolicy == "cache-and-network" ||
1127
+ (this.options.fetchPolicy === "cache-only" ||
1128
+ this.options.fetchPolicy === "cache-and-network" ||
1078
1129
  !this.activeOperations.size)) {
1079
1130
  const diff = this.getCacheDiff();
1080
1131
  if (
@@ -1303,7 +1354,7 @@ class ObservableQuery {
1303
1354
  exports.ObservableQuery = ObservableQuery;
1304
1355
  function logMissingFieldErrors(missing) {
1305
1356
  if (environment_1.__DEV__ && missing) {
1306
- __DEV__ && invariant_1.invariant.debug(82, missing);
1357
+ __DEV__ && invariant_1.invariant.debug(83, missing);
1307
1358
  }
1308
1359
  }
1309
1360
  function isEqualQuery(a, b) {