@apollo/client 4.3.3 → 4.3.4

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 (79) hide show
  1. package/CHANGELOG.md +20 -0
  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 +4 -1
  5. package/__cjs/cache/core/types/Cache.d.cts +5 -0
  6. package/__cjs/cache/inmemory/entityStore.cjs +4 -4
  7. package/__cjs/cache/inmemory/inMemoryCache.cjs +15 -5
  8. package/__cjs/cache/inmemory/inMemoryCache.cjs.map +1 -1
  9. package/__cjs/cache/inmemory/inMemoryCache.d.cts +3 -1
  10. package/__cjs/cache/inmemory/key-extractor.cjs +1 -1
  11. package/__cjs/cache/inmemory/policies.cjs +5 -5
  12. package/__cjs/cache/inmemory/readFromStore.cjs +28 -10
  13. package/__cjs/cache/inmemory/readFromStore.cjs.map +1 -1
  14. package/__cjs/cache/inmemory/types.d.cts +7 -2
  15. package/__cjs/cache/inmemory/writeToStore.cjs +29 -14
  16. package/__cjs/cache/inmemory/writeToStore.cjs.map +1 -1
  17. package/__cjs/cache/inmemory/writeToStore.d.cts +5 -2
  18. package/__cjs/core/ApolloClient.cjs +14 -14
  19. package/__cjs/core/ObservableQuery.cjs +8 -8
  20. package/__cjs/core/QueryInfo.cjs +13 -32
  21. package/__cjs/core/QueryInfo.cjs.map +1 -1
  22. package/__cjs/core/QueryManager.cjs +12 -12
  23. package/__cjs/core/RefetchEventManager.cjs +3 -3
  24. package/__cjs/incremental/handlers/defer20220824.cjs +15 -2
  25. package/__cjs/incremental/handlers/defer20220824.cjs.map +1 -1
  26. package/__cjs/incremental/handlers/defer20220824.d.cts +5 -1
  27. package/__cjs/incremental/handlers/graphql17Alpha9.cjs +58 -14
  28. package/__cjs/incremental/handlers/graphql17Alpha9.cjs.map +1 -1
  29. package/__cjs/incremental/handlers/graphql17Alpha9.d.cts +23 -12
  30. package/__cjs/incremental/handlers/notImplemented.cjs +1 -1
  31. package/__cjs/incremental/types.d.cts +19 -1
  32. package/__cjs/invariantErrorCodes.cjs +64 -58
  33. package/__cjs/utilities/internal/index.cjs.map +1 -1
  34. package/__cjs/utilities/internal/index.d.cts +0 -1
  35. package/__cjs/version.cjs +1 -1
  36. package/cache/core/cache.d.ts +4 -1
  37. package/cache/core/cache.js +1 -1
  38. package/cache/core/cache.js.map +1 -1
  39. package/cache/core/types/Cache.d.ts +5 -0
  40. package/cache/core/types/Cache.js.map +1 -1
  41. package/cache/inmemory/entityStore.js +4 -4
  42. package/cache/inmemory/inMemoryCache.d.ts +3 -1
  43. package/cache/inmemory/inMemoryCache.js +15 -5
  44. package/cache/inmemory/inMemoryCache.js.map +1 -1
  45. package/cache/inmemory/key-extractor.js +1 -1
  46. package/cache/inmemory/policies.js +5 -5
  47. package/cache/inmemory/readFromStore.js +28 -10
  48. package/cache/inmemory/readFromStore.js.map +1 -1
  49. package/cache/inmemory/types.d.ts +7 -2
  50. package/cache/inmemory/types.js.map +1 -1
  51. package/cache/inmemory/writeToStore.d.ts +5 -2
  52. package/cache/inmemory/writeToStore.js +30 -15
  53. package/cache/inmemory/writeToStore.js.map +1 -1
  54. package/core/ApolloClient.js +14 -14
  55. package/core/ObservableQuery.js +8 -8
  56. package/core/QueryInfo.js +14 -33
  57. package/core/QueryInfo.js.map +1 -1
  58. package/core/QueryManager.js +12 -12
  59. package/core/RefetchEventManager.js +3 -3
  60. package/incremental/handlers/defer20220824.d.ts +5 -1
  61. package/incremental/handlers/defer20220824.js +15 -2
  62. package/incremental/handlers/defer20220824.js.map +1 -1
  63. package/incremental/handlers/graphql17Alpha9.d.ts +23 -12
  64. package/incremental/handlers/graphql17Alpha9.js +58 -14
  65. package/incremental/handlers/graphql17Alpha9.js.map +1 -1
  66. package/incremental/handlers/notImplemented.js +1 -1
  67. package/incremental/types.d.ts +19 -1
  68. package/incremental/types.js.map +1 -1
  69. package/invariantErrorCodes.js +64 -58
  70. package/package.json +1 -1
  71. package/utilities/internal/index.d.ts +0 -1
  72. package/utilities/internal/index.js.map +1 -1
  73. package/version.js +1 -1
  74. package/__cjs/utilities/internal/types/DeferInfo.cjs +0 -3
  75. package/__cjs/utilities/internal/types/DeferInfo.cjs.map +0 -1
  76. package/__cjs/utilities/internal/types/DeferInfo.d.cts +0 -10
  77. package/utilities/internal/types/DeferInfo.d.ts +0 -10
  78. package/utilities/internal/types/DeferInfo.js +0 -2
  79. package/utilities/internal/types/DeferInfo.js.map +0 -1
@@ -99,7 +99,7 @@ export class QueryManager {
99
99
  */
100
100
  stop() {
101
101
  this.obsQueries.forEach((oq) => oq.stop());
102
- this.cancelPendingFetches(newInvariantError(93));
102
+ this.cancelPendingFetches(newInvariantError(94));
103
103
  }
104
104
  cancelPendingFetches(error) {
105
105
  this.fetchCancelFns.forEach((cancel) => cancel(error));
@@ -112,7 +112,7 @@ export class QueryManager {
112
112
  variables = this.getVariables(mutation, variables);
113
113
  if (hasClientExports) {
114
114
  if (__DEV__) {
115
- invariant(this.localState, 94, getOperationName(mutation, "(anonymous)"));
115
+ invariant(this.localState, 95, getOperationName(mutation, "(anonymous)"));
116
116
  }
117
117
  variables = await this.localState.getExportedVariables({
118
118
  client: this.client,
@@ -345,7 +345,7 @@ export class QueryManager {
345
345
  // depend on values that previously existed in the data portion of the
346
346
  // store. So, we cancel the promises and observers that we have issued
347
347
  // so far and not yet resolved (in the case of queries).
348
- this.cancelPendingFetches(newInvariantError(95));
348
+ this.cancelPendingFetches(newInvariantError(96));
349
349
  this.obsQueries.forEach((observableQuery) => {
350
350
  // Set loading to true so listeners don't trigger unless they want
351
351
  // results with partial data.
@@ -415,10 +415,10 @@ export class QueryManager {
415
415
  if (!included) {
416
416
  const queryName = queryNames.get(nameOrQueryString);
417
417
  if (queryName) {
418
- __DEV__ && invariant.warn(96, queryName);
418
+ __DEV__ && invariant.warn(97, queryName);
419
419
  }
420
420
  else {
421
- __DEV__ && invariant.warn(97);
421
+ __DEV__ && invariant.warn(98);
422
422
  }
423
423
  }
424
424
  });
@@ -447,7 +447,7 @@ export class QueryManager {
447
447
  if (__DEV__) {
448
448
  invariant(
449
449
  !this.getDocumentInfo(query).hasClientExports || this.localState,
450
- 98,
450
+ 99,
451
451
  getOperationName(query, "(anonymous)")
452
452
  );
453
453
  }
@@ -592,14 +592,14 @@ export class QueryManager {
592
592
  if (__DEV__) {
593
593
  invariant(
594
594
  this.localState,
595
- 99,
595
+ 100,
596
596
  operation[0].toUpperCase() + operation.slice(1),
597
597
  operationName ?? "(anonymous)"
598
598
  );
599
599
  }
600
600
  invariant(
601
601
  !hasIncrementalDirective,
602
- 100,
602
+ 101,
603
603
  operation[0].toUpperCase() + operation.slice(1),
604
604
  operationName ?? "(anonymous)"
605
605
  );
@@ -767,7 +767,7 @@ export class QueryManager {
767
767
  // we deprecated and removed LocalState.
768
768
  if (this.getDocumentInfo(normalized.query).hasClientExports) {
769
769
  if (__DEV__) {
770
- invariant(this.localState, 101, getOperationName(normalized.query, "(anonymous)"));
770
+ invariant(this.localState, 102, getOperationName(normalized.query, "(anonymous)"));
771
771
  }
772
772
  observable = from(this.localState.getExportedVariables({
773
773
  client: this.client,
@@ -940,7 +940,7 @@ export class QueryManager {
940
940
  !isFullyUnmaskedOperation(document) &&
941
941
  !this.noCacheWarningsByCause.has(cause)) {
942
942
  this.noCacheWarningsByCause.add(cause);
943
- __DEV__ && invariant.warn(102, getOperationName(document, `Unnamed ${operationType ?? "operation"}`));
943
+ __DEV__ && invariant.warn(103, getOperationName(document, `Unnamed ${operationType ?? "operation"}`));
944
944
  }
945
945
  }
946
946
  return (this.dataMasking ?
@@ -1003,7 +1003,7 @@ export class QueryManager {
1003
1003
  (diff.complete || returnPartialData) &&
1004
1004
  this.getDocumentInfo(query).hasForcedResolvers) {
1005
1005
  if (__DEV__) {
1006
- invariant(this.localState, 103, getOperationName(query, "(anonymous)"));
1006
+ invariant(this.localState, 104, getOperationName(query, "(anonymous)"));
1007
1007
  }
1008
1008
  onCacheHit();
1009
1009
  return from(this.localState.execute({
@@ -1124,7 +1124,7 @@ function validateDidEmitValue() {
1124
1124
  didEmitValue = true;
1125
1125
  },
1126
1126
  complete() {
1127
- invariant(didEmitValue, 104);
1127
+ invariant(didEmitValue, 105);
1128
1128
  },
1129
1129
  });
1130
1130
  }
@@ -27,7 +27,7 @@ export class RefetchEventManager {
27
27
  }
28
28
  if (this.client) {
29
29
  if (__DEV__) {
30
- __DEV__ && invariant.warn(105);
30
+ __DEV__ && invariant.warn(106);
31
31
  }
32
32
  this.disconnect();
33
33
  }
@@ -96,13 +96,13 @@ export class RefetchEventManager {
96
96
  const [payload] = args;
97
97
  if (!this.client) {
98
98
  if (__DEV__) {
99
- __DEV__ && invariant.warn(106, source);
99
+ __DEV__ && invariant.warn(107, source);
100
100
  }
101
101
  return;
102
102
  }
103
103
  if (!this.hasSource(source)) {
104
104
  if (__DEV__) {
105
- __DEV__ && invariant.warn(107, source);
105
+ __DEV__ && invariant.warn(108, source);
106
106
  }
107
107
  return;
108
108
  }
@@ -41,13 +41,17 @@ export declare namespace Defer20220824Handler {
41
41
  type Chunk<TData extends Record<string, unknown>> = InitialResult<TData> | SubsequentResult<TData>;
42
42
  }
43
43
  declare class DeferRequest<TData extends Record<string, unknown>> implements Incremental.IncrementalRequest<Defer20220824Handler.Chunk<TData>, TData> {
44
+ private hasDefer;
44
45
  hasNext: boolean;
46
+ private hasFailedDefer;
47
+ constructor({ query }: Incremental.StartRequestOptions);
45
48
  private errors;
46
49
  private extensions;
47
50
  private data;
48
51
  private ignoredImpossibleStreamPaths;
49
52
  private merge;
50
53
  handle(cacheData: TData | DeepPartial<TData> | null | undefined, chunk: Defer20220824Handler.Chunk<TData>): FormattedExecutionResult<TData>;
54
+ isDeferPending: () => boolean;
51
55
  }
52
56
  /**
53
57
  * This handler implements the `@defer` directive as specified in this historical commit:
@@ -57,7 +61,7 @@ export declare class Defer20220824Handler implements Incremental.Handler<Defer20
57
61
  isIncrementalResult(result: Record<string, any>): result is Defer20220824Handler.SubsequentResult | Defer20220824Handler.InitialResult;
58
62
  extractErrors(result: ApolloLink.Result<any>): GraphQLFormattedError[] | undefined;
59
63
  prepareRequest(request: ApolloLink.Request): ApolloLink.Request;
60
- startRequest<TData extends Record<string, unknown>>(_: Incremental.StartRequestOptions): DeferRequest<TData>;
64
+ startRequest<TData extends Record<string, unknown>>(opts: Incremental.StartRequestOptions): DeferRequest<TData>;
61
65
  }
62
66
  export declare function hasIncrementalChunks(result: Record<string, any>): result is Required<Defer20220824Handler.SubsequentResult>;
63
67
  export {};
@@ -1,6 +1,11 @@
1
1
  import { DeepMerger, hasDirectives, isNonEmptyArray, } from "@apollo/client/utilities/internal";
2
2
  class DeferRequest {
3
+ hasDefer;
3
4
  hasNext = true;
5
+ hasFailedDefer = false;
6
+ constructor({ query }) {
7
+ this.hasDefer = hasDirectives(["defer"], query);
8
+ }
4
9
  errors = [];
5
10
  extensions = {};
6
11
  data = {};
@@ -40,6 +45,9 @@ class DeferRequest {
40
45
  continue;
41
46
  }
42
47
  }
48
+ if ("data" in incremental && incremental.data === null) {
49
+ this.hasFailedDefer = true;
50
+ }
43
51
  let data = "items" in incremental ? incremental.items
44
52
  // Ensure `data: null` isn't merged for `@defer` responses by
45
53
  // falling back to `undefined`
@@ -72,6 +80,11 @@ class DeferRequest {
72
80
  }
73
81
  return result;
74
82
  }
83
+ // This protocol can't identify individual `@defer`/`@stream` boundaries by
84
+ // `path`/`label`, so we can't answer whether a *specific* boundary is
85
+ // pending - only whether *anything* might still be coming (`hasNext`), or
86
+ // whether a boundary failed and will never arrive (`hasFailedDefer`).
87
+ isDeferPending = () => this.hasDefer && (this.hasNext || this.hasFailedDefer);
75
88
  }
76
89
  /**
77
90
  * This handler implements the `@defer` directive as specified in this historical commit:
@@ -111,8 +124,8 @@ export class Defer20220824Handler {
111
124
  }
112
125
  return request;
113
126
  }
114
- startRequest(_) {
115
- return new DeferRequest();
127
+ startRequest(opts) {
128
+ return new DeferRequest(opts);
116
129
  }
117
130
  }
118
131
  // only exported for use in tests
@@ -1 +1 @@
1
- {"version":3,"file":"defer20220824.js","sourceRoot":"","sources":["../../../src/incremental/handlers/defer20220824.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FormattedExecutionResult, GraphQLFormattedError } from \"graphql\";\n\nimport type { ApolloLink } from \"@apollo/client/link\";\nimport type { DeepPartial, HKT } from \"@apollo/client/utilities\";\nimport {\n DeepMerger,\n hasDirectives,\n isNonEmptyArray,\n} from \"@apollo/client/utilities/internal\";\n\nimport type { Incremental } from \"../types.js\";\n\nexport declare namespace Defer20220824Handler {\n interface Defer20220824Result extends HKT {\n arg1: unknown; // TData\n arg2: unknown; // TExtensions\n return: Defer20220824Handler.Chunk<Record<string, unknown>>;\n }\n export interface TypeOverrides {\n AdditionalApolloLinkResultTypes: Defer20220824Result;\n }\n\n export type InitialResult<TData = Record<string, unknown>> = {\n data?: TData | null | undefined;\n errors?: ReadonlyArray<GraphQLFormattedError>;\n extensions?: Record<string, unknown>;\n hasNext: boolean;\n incremental?: ReadonlyArray<IncrementalResult<TData>>;\n };\n\n export type SubsequentResult<TData = Record<string, unknown>> = {\n extensions?: Record<string, unknown>;\n hasNext: boolean;\n incremental?: Array<IncrementalResult<TData>>;\n };\n\n export type IncrementalDeferResult<TData = Record<string, unknown>> = {\n data?: TData | null;\n errors?: ReadonlyArray<GraphQLFormattedError>;\n extensions?: Record<string, unknown>;\n path?: Incremental.Path;\n label?: string;\n };\n\n export type IncrementalStreamResult<TData = Array<unknown>> = {\n errors?: ReadonlyArray<GraphQLFormattedError>;\n items?: TData;\n path?: Incremental.Path;\n label?: string;\n extensions?: Record<string, unknown>;\n };\n\n export type IncrementalResult<TData = Record<string, unknown>> =\n | IncrementalDeferResult<TData>\n | IncrementalStreamResult<TData>;\n\n export type Chunk<TData extends Record<string, unknown>> =\n | InitialResult<TData>\n | SubsequentResult<TData>;\n}\n\nclass DeferRequest<TData extends Record<string, unknown>>\n implements\n Incremental.IncrementalRequest<Defer20220824Handler.Chunk<TData>, TData>\n{\n public hasNext = true;\n\n private errors: Array<GraphQLFormattedError> = [];\n private extensions: Record<string, any> = {};\n private data: any = {};\n // This tracks paths for `@stream` arrays that returns items: null due to\n // errors thrown for non-null array items. We stop processing future updates\n // to these stream arrays to prevent creating sparse arrays or inserting\n // `null` for an expected non-null value which could cause runtime crashes.\n private ignoredImpossibleStreamPaths = new Set<string>();\n\n private merge(\n normalized: FormattedExecutionResult<TData>,\n atPath?: DeepMerger.MergeOptions[\"atPath\"]\n ) {\n if (normalized.data !== undefined) {\n this.data = new DeepMerger({ arrayMerge: \"truncate\" }).merge(\n this.data,\n normalized.data,\n { atPath }\n );\n }\n if (normalized.errors) {\n this.errors.push(...normalized.errors);\n }\n Object.assign(this.extensions, normalized.extensions);\n }\n\n handle(\n // we'll get `undefined` here in case of a `no-cache` fetch policy,\n // so we'll continue with the last value this request had accumulated\n cacheData: TData | DeepPartial<TData> | null | undefined = this.data,\n chunk: Defer20220824Handler.Chunk<TData>\n ): FormattedExecutionResult<TData> {\n this.hasNext = chunk.hasNext;\n this.data = cacheData;\n\n if (hasIncrementalChunks(chunk)) {\n for (const incremental of chunk.incremental) {\n const { path, errors, extensions } = incremental;\n\n if (\"items\" in incremental) {\n // Remove the array index from the end of the array since each future\n // chunk sends a different array index. This normalizes the path to\n // ensure we ignore updates to this field if `items` is `null`.\n const stringPath = path?.slice(0, -1).join(\".\") ?? \"\";\n\n if (incremental.items === null) {\n this.ignoredImpossibleStreamPaths.add(stringPath);\n }\n\n if (this.ignoredImpossibleStreamPaths.has(stringPath)) {\n this.merge({ errors, extensions });\n continue;\n }\n }\n\n let data: any =\n \"items\" in incremental ? incremental.items\n // Ensure `data: null` isn't merged for `@defer` responses by\n // falling back to `undefined`\n : \"data\" in incremental ? incremental.data ?? undefined\n : undefined;\n\n if (path && typeof path.at(-1) === \"number\" && Array.isArray(data)) {\n const startingIdx = path.at(-1) as number;\n data.forEach((item, idx) => {\n this.merge({ data: item }, [\n ...path!.slice(0, -1),\n startingIdx + idx,\n ]);\n });\n } else {\n this.merge({ data }, path);\n }\n\n this.merge({ errors, extensions });\n }\n } else {\n this.merge(chunk);\n }\n\n const result: FormattedExecutionResult<TData> = { data: this.data };\n\n if (isNonEmptyArray(this.errors)) {\n result.errors = this.errors;\n }\n\n if (Object.keys(this.extensions).length > 0) {\n result.extensions = this.extensions;\n }\n\n return result;\n }\n}\n\n/**\n * This handler implements the `@defer` directive as specified in this historical commit:\n * https://github.com/graphql/graphql-spec/tree/48cf7263a71a683fab03d45d309fd42d8d9a6659/spec\n */\nexport class Defer20220824Handler\n implements Incremental.Handler<Defer20220824Handler.Chunk<any>>\n{\n isIncrementalResult(\n result: Record<string, any>\n ): result is\n | Defer20220824Handler.SubsequentResult\n | Defer20220824Handler.InitialResult {\n return \"hasNext\" in result;\n }\n\n extractErrors(result: ApolloLink.Result<any>) {\n const acc: GraphQLFormattedError[] = [];\n const push = ({\n errors,\n }: {\n errors?: ReadonlyArray<GraphQLFormattedError>;\n }) => {\n if (errors) {\n acc.push(...errors);\n }\n };\n if (this.isIncrementalResult(result)) {\n if (\"errors\" in result) {\n push(result);\n }\n if (hasIncrementalChunks(result)) {\n result.incremental.forEach(push);\n }\n }\n if (acc.length) {\n return acc;\n }\n }\n\n prepareRequest(request: ApolloLink.Request): ApolloLink.Request {\n if (hasDirectives([\"defer\", \"stream\"], request.query)) {\n const context = request.context ?? {};\n const http = (context.http ??= {});\n http.accept = [\n \"multipart/mixed;deferSpec=20220824\",\n ...(http.accept || []),\n ];\n }\n\n return request;\n }\n startRequest<TData extends Record<string, unknown>>(\n _: Incremental.StartRequestOptions\n ) {\n return new DeferRequest<TData>();\n }\n}\n\n// only exported for use in tests\nexport function hasIncrementalChunks(\n result: Record<string, any>\n): result is Required<Defer20220824Handler.SubsequentResult> {\n return isNonEmptyArray(result.incremental);\n}\n"]}
1
+ {"version":3,"file":"defer20220824.js","sourceRoot":"","sources":["../../../src/incremental/handlers/defer20220824.ts"],"names":[],"mappings":"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","sourcesContent":["import type { FormattedExecutionResult, GraphQLFormattedError } from \"graphql\";\n\nimport type { ApolloLink } from \"@apollo/client/link\";\nimport type { DeepPartial, HKT } from \"@apollo/client/utilities\";\nimport {\n DeepMerger,\n hasDirectives,\n isNonEmptyArray,\n} from \"@apollo/client/utilities/internal\";\n\nimport type { Incremental } from \"../types.js\";\n\nexport declare namespace Defer20220824Handler {\n interface Defer20220824Result extends HKT {\n arg1: unknown; // TData\n arg2: unknown; // TExtensions\n return: Defer20220824Handler.Chunk<Record<string, unknown>>;\n }\n export interface TypeOverrides {\n AdditionalApolloLinkResultTypes: Defer20220824Result;\n }\n\n export type InitialResult<TData = Record<string, unknown>> = {\n data?: TData | null | undefined;\n errors?: ReadonlyArray<GraphQLFormattedError>;\n extensions?: Record<string, unknown>;\n hasNext: boolean;\n incremental?: ReadonlyArray<IncrementalResult<TData>>;\n };\n\n export type SubsequentResult<TData = Record<string, unknown>> = {\n extensions?: Record<string, unknown>;\n hasNext: boolean;\n incremental?: Array<IncrementalResult<TData>>;\n };\n\n export type IncrementalDeferResult<TData = Record<string, unknown>> = {\n data?: TData | null;\n errors?: ReadonlyArray<GraphQLFormattedError>;\n extensions?: Record<string, unknown>;\n path?: Incremental.Path;\n label?: string;\n };\n\n export type IncrementalStreamResult<TData = Array<unknown>> = {\n errors?: ReadonlyArray<GraphQLFormattedError>;\n items?: TData;\n path?: Incremental.Path;\n label?: string;\n extensions?: Record<string, unknown>;\n };\n\n export type IncrementalResult<TData = Record<string, unknown>> =\n | IncrementalDeferResult<TData>\n | IncrementalStreamResult<TData>;\n\n export type Chunk<TData extends Record<string, unknown>> =\n | InitialResult<TData>\n | SubsequentResult<TData>;\n}\n\nclass DeferRequest<TData extends Record<string, unknown>>\n implements\n Incremental.IncrementalRequest<Defer20220824Handler.Chunk<TData>, TData>\n{\n private hasDefer: boolean;\n public hasNext = true;\n private hasFailedDefer = false;\n\n constructor({ query }: Incremental.StartRequestOptions) {\n this.hasDefer = hasDirectives([\"defer\"], query);\n }\n\n private errors: Array<GraphQLFormattedError> = [];\n private extensions: Record<string, any> = {};\n private data: any = {};\n // This tracks paths for `@stream` arrays that returns items: null due to\n // errors thrown for non-null array items. We stop processing future updates\n // to these stream arrays to prevent creating sparse arrays or inserting\n // `null` for an expected non-null value which could cause runtime crashes.\n private ignoredImpossibleStreamPaths = new Set<string>();\n\n private merge(\n normalized: FormattedExecutionResult<TData>,\n atPath?: DeepMerger.MergeOptions[\"atPath\"]\n ) {\n if (normalized.data !== undefined) {\n this.data = new DeepMerger({ arrayMerge: \"truncate\" }).merge(\n this.data,\n normalized.data,\n { atPath }\n );\n }\n if (normalized.errors) {\n this.errors.push(...normalized.errors);\n }\n Object.assign(this.extensions, normalized.extensions);\n }\n\n handle(\n // we'll get `undefined` here in case of a `no-cache` fetch policy,\n // so we'll continue with the last value this request had accumulated\n cacheData: TData | DeepPartial<TData> | null | undefined = this.data,\n chunk: Defer20220824Handler.Chunk<TData>\n ): FormattedExecutionResult<TData> {\n this.hasNext = chunk.hasNext;\n this.data = cacheData;\n\n if (hasIncrementalChunks(chunk)) {\n for (const incremental of chunk.incremental) {\n const { path, errors, extensions } = incremental;\n\n if (\"items\" in incremental) {\n // Remove the array index from the end of the array since each future\n // chunk sends a different array index. This normalizes the path to\n // ensure we ignore updates to this field if `items` is `null`.\n const stringPath = path?.slice(0, -1).join(\".\") ?? \"\";\n\n if (incremental.items === null) {\n this.ignoredImpossibleStreamPaths.add(stringPath);\n }\n\n if (this.ignoredImpossibleStreamPaths.has(stringPath)) {\n this.merge({ errors, extensions });\n continue;\n }\n }\n\n if (\"data\" in incremental && incremental.data === null) {\n this.hasFailedDefer = true;\n }\n\n let data: any =\n \"items\" in incremental ? incremental.items\n // Ensure `data: null` isn't merged for `@defer` responses by\n // falling back to `undefined`\n : \"data\" in incremental ? incremental.data ?? undefined\n : undefined;\n\n if (path && typeof path.at(-1) === \"number\" && Array.isArray(data)) {\n const startingIdx = path.at(-1) as number;\n data.forEach((item, idx) => {\n this.merge({ data: item }, [\n ...path!.slice(0, -1),\n startingIdx + idx,\n ]);\n });\n } else {\n this.merge({ data }, path);\n }\n\n this.merge({ errors, extensions });\n }\n } else {\n this.merge(chunk);\n }\n\n const result: FormattedExecutionResult<TData> = { data: this.data };\n\n if (isNonEmptyArray(this.errors)) {\n result.errors = this.errors;\n }\n\n if (Object.keys(this.extensions).length > 0) {\n result.extensions = this.extensions;\n }\n\n return result;\n }\n\n // This protocol can't identify individual `@defer`/`@stream` boundaries by\n // `path`/`label`, so we can't answer whether a *specific* boundary is\n // pending - only whether *anything* might still be coming (`hasNext`), or\n // whether a boundary failed and will never arrive (`hasFailedDefer`).\n isDeferPending = () => this.hasDefer && (this.hasNext || this.hasFailedDefer);\n}\n\n/**\n * This handler implements the `@defer` directive as specified in this historical commit:\n * https://github.com/graphql/graphql-spec/tree/48cf7263a71a683fab03d45d309fd42d8d9a6659/spec\n */\nexport class Defer20220824Handler\n implements Incremental.Handler<Defer20220824Handler.Chunk<any>>\n{\n isIncrementalResult(\n result: Record<string, any>\n ): result is\n | Defer20220824Handler.SubsequentResult\n | Defer20220824Handler.InitialResult {\n return \"hasNext\" in result;\n }\n\n extractErrors(result: ApolloLink.Result<any>) {\n const acc: GraphQLFormattedError[] = [];\n const push = ({\n errors,\n }: {\n errors?: ReadonlyArray<GraphQLFormattedError>;\n }) => {\n if (errors) {\n acc.push(...errors);\n }\n };\n if (this.isIncrementalResult(result)) {\n if (\"errors\" in result) {\n push(result);\n }\n if (hasIncrementalChunks(result)) {\n result.incremental.forEach(push);\n }\n }\n if (acc.length) {\n return acc;\n }\n }\n\n prepareRequest(request: ApolloLink.Request): ApolloLink.Request {\n if (hasDirectives([\"defer\", \"stream\"], request.query)) {\n const context = request.context ?? {};\n const http = (context.http ??= {});\n http.accept = [\n \"multipart/mixed;deferSpec=20220824\",\n ...(http.accept || []),\n ];\n }\n\n return request;\n }\n startRequest<TData extends Record<string, unknown>>(\n opts: Incremental.StartRequestOptions\n ) {\n return new DeferRequest<TData>(opts);\n }\n}\n\n// only exported for use in tests\nexport function hasIncrementalChunks(\n result: Record<string, any>\n): result is Required<Defer20220824Handler.SubsequentResult> {\n return isNonEmptyArray(result.incremental);\n}\n"]}
@@ -58,9 +58,18 @@ declare class IncrementalRequest<TData> implements Incremental.IncrementalReques
58
58
  private errors;
59
59
  private extensions;
60
60
  private pendingMap;
61
+ private deferredByPathAndLabel;
61
62
  private completedMap;
62
63
  private _streamInfo;
63
64
  private streamPositions;
65
+ private deferLabels;
66
+ /**
67
+ * @internal
68
+ *
69
+ * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
70
+ */
71
+ tracksPending: boolean;
72
+ constructor({ query }: Incremental.StartRequestOptions);
64
73
  /**
65
74
  * @internal
66
75
  *
@@ -72,17 +81,19 @@ declare class IncrementalRequest<TData> implements Incremental.IncrementalReques
72
81
  *
73
82
  * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
74
83
  */
75
- getPendingWithInfo(): ({
76
- type: "stream";
77
- path: Incremental.Path;
78
- delivered?: undefined;
79
- label?: undefined;
80
- } | {
81
- type: "defer";
82
- delivered: boolean;
83
- path: Incremental.Path;
84
- label: string | undefined;
85
- })[];
84
+ markStreamedPendingForTruncation(): void;
85
+ private pendingDeferCount;
86
+ /**
87
+ * @internal
88
+ *
89
+ * @privateRemarks
90
+ * Important: this function is used as a reactivity dependency in the `readFromStore.prune*` methods.
91
+ * It needs to be a different instance for each instance of `IncrementalRequest`,
92
+ * so it cannot be a normal class/prototype method, but it has to be an instance property.
93
+ *
94
+ * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
95
+ */
96
+ isDeferPending: (path?: Incremental.Path, label?: string | undefined) => boolean;
86
97
  handle(cacheData: TData | DeepPartial<TData> | null | undefined, chunk: GraphQL17Alpha9Handler.Chunk<TData>): FormattedExecutionResult<TData>;
87
98
  private merge;
88
99
  }
@@ -115,7 +126,7 @@ export declare class GraphQL17Alpha9Handler implements Incremental.Handler<Graph
115
126
  *
116
127
  * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
117
128
  */
118
- startRequest<TData>(_: Incremental.StartRequestOptions): IncrementalRequest<TData>;
129
+ startRequest<TData>(opts: Incremental.StartRequestOptions): IncrementalRequest<TData>;
119
130
  }
120
131
  export {};
121
132
  //# sourceMappingURL=graphql17Alpha9.d.ts.map
@@ -1,3 +1,5 @@
1
+ import { Trie } from "@wry/trie";
2
+ import { visit } from "graphql";
1
3
  import { DocumentTransform } from "@apollo/client/utilities";
2
4
  import { addDeferFragmentLabels, DeepMerger, makeStreamInfoTrie, streamInfoSymbol, } from "@apollo/client/utilities/internal";
3
5
  import { hasDirectives, isNonEmptyArray, } from "@apollo/client/utilities/internal";
@@ -8,6 +10,7 @@ class IncrementalRequest {
8
10
  errors = [];
9
11
  extensions = {};
10
12
  pendingMap = new Map();
13
+ deferredByPathAndLabel = new Trie(false, () => ({}));
11
14
  completedMap = new Map();
12
15
  _streamInfo = makeStreamInfoTrie();
13
16
  // `streamPositions` maps `pending.id` to the index that should be set by the
@@ -18,6 +21,25 @@ class IncrementalRequest {
18
21
  // updated by the cache between a streamed chunk aren't overwritten by merges
19
22
  // of future stream items from already merged stream items.
20
23
  streamPositions = {};
24
+ deferLabels = new Set();
25
+ /**
26
+ * @internal
27
+ *
28
+ * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
29
+ */
30
+ tracksPending = true;
31
+ constructor({ query }) {
32
+ visit(query, {
33
+ Directive: (node) => {
34
+ const name = node.name.value;
35
+ if (name === "defer") {
36
+ const labelNode = node.arguments?.find((arg) => arg.name.value === "label");
37
+ invariant(labelNode && labelNode.value.kind === "StringValue", 68);
38
+ this.deferLabels.add(labelNode.value.value);
39
+ }
40
+ },
41
+ });
42
+ }
21
43
  /**
22
44
  * @internal
23
45
  *
@@ -31,25 +53,44 @@ class IncrementalRequest {
31
53
  *
32
54
  * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
33
55
  */
34
- getPendingWithInfo() {
35
- return Array.from(this.pendingMap.values()).map((pending) => {
56
+ markStreamedPendingForTruncation() {
57
+ const streamInfo = this.streamInfo;
58
+ if (!streamInfo)
59
+ return;
60
+ for (const pending of this.pendingMap.values()) {
36
61
  if (pending.id in this.streamPositions) {
37
- return { type: "stream", path: pending.path };
62
+ streamInfo.lookupArray(pending.path).state.truncate = true;
38
63
  }
39
- return {
40
- type: "defer",
41
- delivered: !!this.completedMap.get(pending.id),
42
- path: pending.path,
43
- label: pending.label,
44
- };
45
- });
64
+ }
46
65
  }
66
+ pendingDeferCount = 0;
67
+ /**
68
+ * @internal
69
+ *
70
+ * @privateRemarks
71
+ * Important: this function is used as a reactivity dependency in the `readFromStore.prune*` methods.
72
+ * It needs to be a different instance for each instance of `IncrementalRequest`,
73
+ * so it cannot be a normal class/prototype method, but it has to be an instance property.
74
+ *
75
+ * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
76
+ */
77
+ isDeferPending = (path, label) => {
78
+ if (!path) {
79
+ return !!this.pendingDeferCount;
80
+ }
81
+ const found = this.deferredByPathAndLabel.peek(...path, label);
82
+ return !!found && this.completedMap.get(found.id) !== true;
83
+ };
47
84
  handle(cacheData = this.data, chunk) {
48
85
  this.hasNext = chunk.hasNext;
49
86
  this.data = cacheData;
50
87
  if (chunk.pending) {
51
88
  for (const pending of chunk.pending) {
52
89
  this.pendingMap.set(pending.id, pending);
90
+ if (pending.label != null && this.deferLabels.has(pending.label)) {
91
+ this.deferredByPathAndLabel.lookup(...pending.path, pending.label).id = pending.id;
92
+ this.pendingDeferCount++;
93
+ }
53
94
  if ("data" in chunk) {
54
95
  const dataAtPath = pending.path.reduce((data, key) => data[key], chunk.data);
55
96
  if (Array.isArray(dataAtPath)) {
@@ -67,7 +108,7 @@ class IncrementalRequest {
67
108
  if (hasIncrementalChunks(chunk)) {
68
109
  for (const incremental of chunk.incremental) {
69
110
  const pending = this.pendingMap.get(incremental.id);
70
- invariant(pending, 68);
111
+ invariant(pending, 69);
71
112
  const path = pending.path.concat(incremental.subPath ?? []);
72
113
  let data;
73
114
  if ("items" in incremental) {
@@ -121,9 +162,12 @@ class IncrementalRequest {
121
162
  }
122
163
  if ("completed" in chunk && chunk.completed) {
123
164
  for (const completed of chunk.completed) {
124
- const { path } = this.pendingMap.get(completed.id);
165
+ const { path, label } = this.pendingMap.get(completed.id);
125
166
  const streamPosition = this.streamPositions[completed.id];
126
167
  this.completedMap.set(completed.id, !completed.errors);
168
+ if (label != null && this.deferLabels.has(label) && !completed.errors) {
169
+ this.pendingDeferCount--;
170
+ }
127
171
  // Truncate any stream arrays in case the chunk only contains `hasNext`
128
172
  // and `completed`.
129
173
  if (streamPosition !== undefined) {
@@ -241,8 +285,8 @@ export class GraphQL17Alpha9Handler {
241
285
  *
242
286
  * @deprecated This is an internal API and should not be used directly. This can be removed or changed at any time.
243
287
  */
244
- startRequest(_) {
245
- return new IncrementalRequest();
288
+ startRequest(opts) {
289
+ return new IncrementalRequest(opts);
246
290
  }
247
291
  }
248
292
  function hasIncrementalChunks(result) {