@apollo/client 4.0.6 → 4.1.0-alpha.1

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 (121) hide show
  1. package/CHANGELOG.md +43 -4
  2. package/__cjs/cache/core/cache.cjs +1 -1
  3. package/__cjs/cache/core/cache.cjs.map +1 -1
  4. package/__cjs/cache/core/cache.d.cts +19 -0
  5. package/__cjs/cache/inmemory/entityStore.cjs +3 -3
  6. package/__cjs/cache/inmemory/entityStore.cjs.map +1 -1
  7. package/__cjs/cache/inmemory/inMemoryCache.cjs +3 -0
  8. package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
  9. package/__cjs/cache/inmemory/inMemoryCache.d.cts +1 -0
  10. package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
  11. package/__cjs/cache/inmemory/key-extractor.cjs.map +1 -1
  12. package/__cjs/cache/inmemory/policies.cjs +4 -4
  13. package/__cjs/cache/inmemory/policies.cjs.map +1 -1
  14. package/__cjs/cache/inmemory/readFromStore.cjs +2 -2
  15. package/__cjs/cache/inmemory/writeToStore.cjs +5 -5
  16. package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  17. package/__cjs/core/ApolloClient.cjs +14 -13
  18. package/__cjs/core/ApolloClient.cjs.map +1 -1
  19. package/__cjs/core/ApolloClient.d.cts +12 -0
  20. package/__cjs/core/ObservableQuery.cjs +157 -110
  21. package/__cjs/core/ObservableQuery.cjs.map +1 -1
  22. package/__cjs/core/ObservableQuery.d.cts +1 -0
  23. package/__cjs/core/QueryManager.cjs +19 -17
  24. package/__cjs/core/QueryManager.cjs.map +1 -1
  25. package/__cjs/incremental/handlers/defer20220824.cjs +20 -9
  26. package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
  27. package/__cjs/incremental/handlers/defer20220824.d.cts +14 -5
  28. package/__cjs/incremental/handlers/graphql17Alpha9.cjs +181 -0
  29. package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -0
  30. package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +97 -0
  31. package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
  32. package/__cjs/incremental/index.cjs +3 -1
  33. package/__cjs/incremental/index.cjs.map +1 -1
  34. package/__cjs/incremental/index.d.cts +1 -0
  35. package/__cjs/invariantErrorCodes.cjs +75 -59
  36. package/__cjs/link/core/ApolloLink.cjs +3 -3
  37. package/__cjs/link/http/checkFetcher.cjs +1 -1
  38. package/__cjs/link/http/parseAndCheckHttpResponse.cjs +1 -1
  39. package/__cjs/link/persisted-queries/index.cjs +2 -2
  40. package/__cjs/link/ws/index.cjs +1 -1
  41. package/__cjs/local-state/LocalState.cjs +28 -14
  42. package/__cjs/local-state/LocalState.cjs.map +1 -1
  43. package/__cjs/local-state/LocalState.d.cts +3 -2
  44. package/__cjs/react/hooks/useReactiveVar.cjs +1 -2
  45. package/__cjs/react/hooks/useReactiveVar.cjs.map +1 -1
  46. package/__cjs/react/hooks/useReactiveVar.d.cts +1 -2
  47. package/__cjs/react/internal/cache/QueryReference.cjs +16 -0
  48. package/__cjs/react/internal/cache/QueryReference.cjs.map +1 -1
  49. package/__cjs/react/internal/cache/QueryReference.d.cts +1 -0
  50. package/__cjs/testing/core/mocking/mockLink.cjs.map +1 -1
  51. package/__cjs/testing/core/mocking/mockLink.d.cts +1 -3
  52. package/__cjs/utilities/internal/DeepMerger.cjs +10 -1
  53. package/__cjs/utilities/internal/DeepMerger.cjs.map +1 -1
  54. package/__cjs/utilities/internal/DeepMerger.d.cts +14 -2
  55. package/__cjs/utilities/internal/getStoreKeyName.cjs +1 -0
  56. package/__cjs/utilities/internal/getStoreKeyName.cjs.map +1 -1
  57. package/__cjs/version.cjs +1 -1
  58. package/__cjs/version.cjs.map +1 -1
  59. package/cache/core/cache.d.ts +19 -0
  60. package/cache/core/cache.js +1 -1
  61. package/cache/core/cache.js.map +1 -1
  62. package/cache/inmemory/entityStore.js +3 -3
  63. package/cache/inmemory/entityStore.js.map +1 -1
  64. package/cache/inmemory/inMemoryCache.d.ts +1 -0
  65. package/cache/inmemory/inMemoryCache.js +3 -0
  66. package/cache/inmemory/inMemoryCache.js.map +1 -1
  67. package/cache/inmemory/key-extractor.js +1 -1
  68. package/cache/inmemory/key-extractor.js.map +1 -1
  69. package/cache/inmemory/policies.js +4 -4
  70. package/cache/inmemory/policies.js.map +1 -1
  71. package/cache/inmemory/readFromStore.js +2 -2
  72. package/cache/inmemory/writeToStore.js +5 -5
  73. package/cache/inmemory/writeToStore.js.map +1 -1
  74. package/core/ApolloClient.d.ts +12 -0
  75. package/core/ApolloClient.js +14 -13
  76. package/core/ApolloClient.js.map +1 -1
  77. package/core/ObservableQuery.d.ts +1 -0
  78. package/core/ObservableQuery.js +159 -112
  79. package/core/ObservableQuery.js.map +1 -1
  80. package/core/QueryManager.js +19 -17
  81. package/core/QueryManager.js.map +1 -1
  82. package/incremental/handlers/defer20220824.d.ts +14 -5
  83. package/incremental/handlers/defer20220824.js +20 -9
  84. package/incremental/handlers/defer20220824.js.map +1 -1
  85. package/incremental/handlers/graphql17Alpha9.d.ts +97 -0
  86. package/incremental/handlers/graphql17Alpha9.js +177 -0
  87. package/incremental/handlers/graphql17Alpha9.js.map +1 -0
  88. package/incremental/handlers/notImplemented.js +1 -1
  89. package/incremental/index.d.ts +1 -0
  90. package/incremental/index.js +3 -2
  91. package/incremental/index.js.map +1 -1
  92. package/invariantErrorCodes.js +75 -59
  93. package/link/core/ApolloLink.js +3 -3
  94. package/link/http/checkFetcher.js +1 -1
  95. package/link/http/parseAndCheckHttpResponse.js +1 -1
  96. package/link/persisted-queries/index.js +2 -2
  97. package/link/ws/index.js +1 -1
  98. package/local-state/LocalState.d.ts +3 -2
  99. package/local-state/LocalState.js +28 -14
  100. package/local-state/LocalState.js.map +1 -1
  101. package/package.json +1 -1
  102. package/react/hooks/useReactiveVar.d.ts +1 -2
  103. package/react/hooks/useReactiveVar.js +1 -2
  104. package/react/hooks/useReactiveVar.js.map +1 -1
  105. package/react/hooks-compiled/useReactiveVar.d.ts +1 -2
  106. package/react/hooks-compiled/useReactiveVar.js +1 -2
  107. package/react/hooks-compiled/useReactiveVar.js.map +1 -1
  108. package/react/internal/cache/QueryReference.d.ts +1 -0
  109. package/react/internal/cache/QueryReference.js +16 -0
  110. package/react/internal/cache/QueryReference.js.map +1 -1
  111. package/testing/core/mocking/mockLink.d.ts +1 -3
  112. package/testing/core/mocking/mockLink.js.map +1 -1
  113. package/utilities/internal/DeepMerger.d.ts +14 -2
  114. package/utilities/internal/DeepMerger.js +10 -1
  115. package/utilities/internal/DeepMerger.js.map +1 -1
  116. package/utilities/internal/getStoreKeyName.js +1 -0
  117. package/utilities/internal/getStoreKeyName.js.map +1 -1
  118. package/utilities/internal/globals/global.js +2 -2
  119. package/utilities/internal/globals/global.js.map +1 -1
  120. package/version.js +1 -1
  121. package/version.js.map +1 -1
@@ -1,6 +1,6 @@
1
1
  import { equal } from "@wry/equality";
2
- import { BehaviorSubject, Observable, share, Subject, tap } from "rxjs";
3
- import { isNetworkRequestInFlight } from "@apollo/client/utilities";
2
+ import { BehaviorSubject, filter, Observable, share, Subject, tap } from "rxjs";
3
+ import { isNetworkRequestInFlight, isNetworkRequestSettled, } from "@apollo/client/utilities";
4
4
  import { __DEV__ } from "@apollo/client/utilities/environment";
5
5
  import { compact, equalByQuery, filterMap, getOperationDefinition, getOperationName, getQueryDefinition, preventUnhandledRejection, toQueryResult, } from "@apollo/client/utilities/internal";
6
6
  import { invariant } from "@apollo/client/utilities/invariant";
@@ -60,6 +60,9 @@ export class ObservableQuery {
60
60
  get networkStatus() {
61
61
  return this.subject.getValue().result.networkStatus;
62
62
  }
63
+ get cache() {
64
+ return this.queryManager.cache;
65
+ }
63
66
  constructor({ queryManager, options, transformedQuery = queryManager.transform(options.query), }) {
64
67
  this.queryManager = queryManager;
65
68
  // active state
@@ -197,7 +200,7 @@ export class ObservableQuery {
197
200
  * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
198
201
  */
199
202
  getCacheDiff({ optimistic = true } = {}) {
200
- return this.queryManager.cache.diff({
203
+ return this.cache.diff({
201
204
  query: this.query,
202
205
  variables: this.variables,
203
206
  returnPartialData: true,
@@ -308,7 +311,7 @@ export class ObservableQuery {
308
311
  }
309
312
  },
310
313
  };
311
- const cancelWatch = this.queryManager.cache.watch(watch);
314
+ const cancelWatch = this.cache.watch(watch);
312
315
  this.unsubscribeFromCache = Object.assign(() => {
313
316
  this.unsubscribeFromCache = undefined;
314
317
  cancelWatch();
@@ -372,7 +375,7 @@ export class ObservableQuery {
372
375
  const queryDef = getQueryDefinition(this.query);
373
376
  const vars = queryDef.variableDefinitions;
374
377
  if (!vars || !vars.some((v) => v.variable.name.value === "variables")) {
375
- __DEV__ && invariant.warn(77, variables, queryDef.name?.value || queryDef);
378
+ __DEV__ && invariant.warn(80, variables, queryDef.name?.value || queryDef);
376
379
  }
377
380
  }
378
381
  if (variables && !equal(this.variables, variables)) {
@@ -388,7 +391,7 @@ export class ObservableQuery {
388
391
  fetchMore({ query, variables, context, errorPolicy, updateQuery, }) {
389
392
  invariant(
390
393
  this.options.fetchPolicy !== "cache-only",
391
- 78,
394
+ 81,
392
395
  getOperationName(this.query, "(anonymous)")
393
396
  );
394
397
  const combinedOptions = {
@@ -422,7 +425,7 @@ export class ObservableQuery {
422
425
  let wasUpdated = false;
423
426
  const isCached = this.options.fetchPolicy !== "no-cache";
424
427
  if (!isCached) {
425
- invariant(updateQuery, 79);
428
+ invariant(updateQuery, 82);
426
429
  }
427
430
  const { finalize, pushNotification } = this.pushOperation(NetworkStatus.fetchMore);
428
431
  pushNotification({
@@ -430,109 +433,153 @@ export class ObservableQuery {
430
433
  kind: "N",
431
434
  value: {},
432
435
  }, { shouldEmit: 3 /* EmitBehavior.networkStatusChange */ });
433
- return this.queryManager
434
- .fetchQuery(combinedOptions, NetworkStatus.fetchMore)
435
- .then((fetchMoreResult) => {
436
- // disable the `fetchMore` override that is currently active
437
- // the next updates caused by this should not be `fetchMore` anymore,
438
- // but `ready` or whatever other calculated loading state is currently
439
- // appropriate
440
- finalize();
441
- if (isCached) {
442
- // Separately getting a diff here before the batch - `onWatchUpdated` might be
443
- // called with an `undefined` `lastDiff` on the watcher if the cache was just subscribed to.
444
- const lastDiff = this.getCacheDiff();
445
- // Performing this cache update inside a cache.batch transaction ensures
446
- // any affected cache.watch watchers are notified at most once about any
447
- // updates. Most watchers will be using the QueryInfo class, which
448
- // responds to notifications by calling reobserveCacheFirst to deliver
449
- // fetchMore cache results back to this ObservableQuery.
450
- this.queryManager.cache.batch({
451
- update: (cache) => {
452
- if (updateQuery) {
453
- cache.updateQuery({
454
- query: this.query,
455
- variables: this.variables,
456
- returnPartialData: true,
457
- optimistic: false,
458
- }, (previous) => updateQuery(previous, {
459
- fetchMoreResult: fetchMoreResult.data,
460
- variables: combinedOptions.variables,
461
- }));
462
- }
463
- else {
464
- // If we're using a field policy instead of updateQuery, the only
465
- // thing we need to do is write the new data to the cache using
466
- // combinedOptions.variables (instead of this.variables, which is
467
- // what this.updateQuery uses, because it works by abusing the
468
- // original field value, keyed by the original variables).
469
- cache.writeQuery({
470
- query: combinedOptions.query,
471
- variables: combinedOptions.variables,
472
- data: fetchMoreResult.data,
473
- });
474
- }
475
- },
476
- onWatchUpdated: (watch, diff) => {
477
- if (watch.watcher === this &&
478
- !equal(diff.result, lastDiff.result)) {
479
- wasUpdated = true;
480
- }
481
- },
482
- });
483
- }
484
- else {
485
- // There is a possibility `lastResult` may not be set when
486
- // `fetchMore` is called which would cause this to crash. This should
487
- // only happen if we haven't previously reported a result. We don't
488
- // quite know what the right behavior should be here since this block
489
- // of code runs after the fetch result has executed on the network.
490
- // We plan to let it crash in the meantime.
491
- //
492
- // If we get bug reports due to the `data` property access on
493
- // undefined, this should give us a real-world scenario that we can
494
- // use to test against and determine the right behavior. If we do end
495
- // up changing this behavior, this may require, for example, an
496
- // adjustment to the types on `updateQuery` since that function
497
- // expects that the first argument always contains previous result
498
- // data, but not `undefined`.
499
- const lastResult = this.getCurrentResult();
500
- const data = updateQuery(lastResult.data, {
501
- fetchMoreResult: fetchMoreResult.data,
502
- variables: combinedOptions.variables,
503
- });
504
- // was reportResult
505
- pushNotification({
506
- kind: "N",
507
- value: {
508
- ...lastResult,
509
- networkStatus: NetworkStatus.ready,
510
- // will be overwritten anyways, just here for types sake
511
- loading: false,
512
- data: data,
513
- dataState: lastResult.dataState === "streaming" ? "streaming" : "complete",
514
- },
515
- source: "network",
516
- });
436
+ const { promise, operator } = getTrackingOperatorPromise((value) => {
437
+ switch (value.kind) {
438
+ case "E": {
439
+ throw value.error;
440
+ }
441
+ case "N": {
442
+ if (value.source !== "newNetworkStatus" && !value.value.loading) {
443
+ return value.value;
444
+ }
445
+ }
517
446
  }
518
- return this.maskResult(fetchMoreResult);
519
- })
447
+ });
448
+ const { observable } = this.queryManager.fetchObservableWithInfo(combinedOptions, { networkStatus: NetworkStatus.fetchMore });
449
+ const subscription = observable
450
+ .pipe(operator, filter((notification) => notification.kind === "N" && notification.source === "network"))
451
+ .subscribe({
452
+ next: (notification) => {
453
+ wasUpdated = false;
454
+ const fetchMoreResult = notification.value;
455
+ if (isNetworkRequestSettled(notification.value.networkStatus)) {
456
+ finalize();
457
+ }
458
+ if (isCached) {
459
+ // Performing this cache update inside a cache.batch transaction ensures
460
+ // any affected cache.watch watchers are notified at most once about any
461
+ // updates. Most watchers will be using the QueryInfo class, which
462
+ // responds to notifications by calling reobserveCacheFirst to deliver
463
+ // fetchMore cache results back to this ObservableQuery.
464
+ this.cache.batch({
465
+ update: (cache) => {
466
+ if (updateQuery) {
467
+ cache.updateQuery({
468
+ query: this.query,
469
+ variables: this.variables,
470
+ returnPartialData: true,
471
+ optimistic: false,
472
+ }, (previous) => updateQuery(previous, {
473
+ fetchMoreResult: fetchMoreResult.data,
474
+ variables: combinedOptions.variables,
475
+ }));
476
+ }
477
+ else {
478
+ // If we're using a field policy instead of updateQuery, the only
479
+ // thing we need to do is write the new data to the cache using
480
+ // combinedOptions.variables (instead of this.variables, which is
481
+ // what this.updateQuery uses, because it works by abusing the
482
+ // original field value, keyed by the original variables).
483
+ cache.writeQuery({
484
+ query: combinedOptions.query,
485
+ variables: combinedOptions.variables,
486
+ data: fetchMoreResult.data,
487
+ });
488
+ }
489
+ },
490
+ onWatchUpdated: (watch, diff) => {
491
+ if (watch.watcher === this) {
492
+ wasUpdated = true;
493
+ const lastResult = this.getCurrentResult();
494
+ // Let the cache watch from resubscribeCache handle the final
495
+ // result
496
+ if (isNetworkRequestInFlight(fetchMoreResult.networkStatus)) {
497
+ pushNotification({
498
+ kind: "N",
499
+ source: "network",
500
+ value: {
501
+ ...lastResult,
502
+ networkStatus: (fetchMoreResult.networkStatus ===
503
+ NetworkStatus.error) ?
504
+ NetworkStatus.ready
505
+ : fetchMoreResult.networkStatus,
506
+ // will be overwritten anyways, just here for types sake
507
+ loading: false,
508
+ data: diff.result,
509
+ dataState: fetchMoreResult.dataState === "streaming" ?
510
+ "streaming"
511
+ : "complete",
512
+ },
513
+ });
514
+ }
515
+ }
516
+ },
517
+ });
518
+ }
519
+ else {
520
+ // There is a possibility `lastResult` may not be set when
521
+ // `fetchMore` is called which would cause this to crash. This should
522
+ // only happen if we haven't previously reported a result. We don't
523
+ // quite know what the right behavior should be here since this block
524
+ // of code runs after the fetch result has executed on the network.
525
+ // We plan to let it crash in the meantime.
526
+ //
527
+ // If we get bug reports due to the `data` property access on
528
+ // undefined, this should give us a real-world scenario that we can
529
+ // use to test against and determine the right behavior. If we do end
530
+ // up changing this behavior, this may require, for example, an
531
+ // adjustment to the types on `updateQuery` since that function
532
+ // expects that the first argument always contains previous result
533
+ // data, but not `undefined`.
534
+ const lastResult = this.getCurrentResult();
535
+ const data = updateQuery(lastResult.data, {
536
+ fetchMoreResult: fetchMoreResult.data,
537
+ variables: combinedOptions.variables,
538
+ });
539
+ pushNotification({
540
+ kind: "N",
541
+ value: {
542
+ ...lastResult,
543
+ networkStatus: NetworkStatus.ready,
544
+ // will be overwritten anyways, just here for types sake
545
+ loading: false,
546
+ data: data,
547
+ dataState: lastResult.dataState === "streaming" ?
548
+ "streaming"
549
+ : "complete",
550
+ },
551
+ source: "network",
552
+ });
553
+ }
554
+ },
555
+ });
556
+ return preventUnhandledRejection(promise
557
+ .then((result) => toQueryResult(this.maskResult(result)))
520
558
  .finally(() => {
521
- // call `finalize` a second time in case the `.then` case above was not reached
522
- finalize();
523
- // In case the cache writes above did not generate a broadcast
524
- // notification (which would have been intercepted by onWatchUpdated),
525
- // likely because the written data were the same as what was already in
526
- // the cache, we still want fetchMore to deliver its final loading:false
527
- // result with the unchanged data.
559
+ subscription.unsubscribe();
528
560
  if (isCached && !wasUpdated) {
529
- pushNotification({
530
- kind: "N",
531
- source: "newNetworkStatus",
532
- value: {},
533
- }, { shouldEmit: 1 /* EmitBehavior.force */ });
561
+ finalize();
562
+ const lastResult = this.getCurrentResult();
563
+ if (lastResult.networkStatus === NetworkStatus.streaming) {
564
+ pushNotification({
565
+ kind: "N",
566
+ source: "network",
567
+ value: {
568
+ ...lastResult,
569
+ dataState: "complete",
570
+ networkStatus: NetworkStatus.ready,
571
+ },
572
+ });
573
+ }
574
+ else {
575
+ pushNotification({
576
+ kind: "N",
577
+ source: "newNetworkStatus",
578
+ value: {},
579
+ }, { shouldEmit: 1 /* EmitBehavior.force */ });
580
+ }
534
581
  }
535
- });
582
+ }));
536
583
  }
537
584
  // XXX the subscription variables are separate from the query variables.
538
585
  // if you want to update subscription variables, right now you have to do that separately,
@@ -558,7 +605,7 @@ export class ObservableQuery {
558
605
  onError(error);
559
606
  }
560
607
  else {
561
- invariant.error(80, error);
608
+ invariant.error(83, error);
562
609
  }
563
610
  return;
564
611
  }
@@ -636,7 +683,7 @@ export class ObservableQuery {
636
683
  previousData: result,
637
684
  });
638
685
  if (newResult) {
639
- queryManager.cache.writeQuery({
686
+ this.cache.writeQuery({
640
687
  query: this.options.query,
641
688
  data: newResult,
642
689
  variables: this.variables,
@@ -802,7 +849,7 @@ export class ObservableQuery {
802
849
  if (!this.didWarnCacheOnlyPolling &&
803
850
  pollInterval &&
804
851
  fetchPolicy === "cache-only") {
805
- __DEV__ && invariant.warn(81, getOperationName(this.query, "(anonymous)"));
852
+ __DEV__ && invariant.warn(84, getOperationName(this.query, "(anonymous)"));
806
853
  this.didWarnCacheOnlyPolling = true;
807
854
  }
808
855
  }
@@ -1069,8 +1116,8 @@ export class ObservableQuery {
1069
1116
  const { dirty } = this;
1070
1117
  this.resetNotifications();
1071
1118
  if (dirty &&
1072
- (this.options.fetchPolicy == "cache-only" ||
1073
- this.options.fetchPolicy == "cache-and-network" ||
1119
+ (this.options.fetchPolicy === "cache-only" ||
1120
+ this.options.fetchPolicy === "cache-and-network" ||
1074
1121
  !this.activeOperations.size)) {
1075
1122
  const diff = this.getCacheDiff();
1076
1123
  if (
@@ -1298,7 +1345,7 @@ export class ObservableQuery {
1298
1345
  }
1299
1346
  export function logMissingFieldErrors(missing) {
1300
1347
  if (__DEV__ && missing) {
1301
- __DEV__ && invariant.debug(82, missing);
1348
+ __DEV__ && invariant.debug(85, missing);
1302
1349
  }
1303
1350
  }
1304
1351
  function isEqualQuery(a, b) {