Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
2d6610d
Add graphql-alpha.9 as dev dependency
jerelmiller Sep 4, 2025
217905c
[WIP] copy over alpha.9 tests
jerelmiller Sep 4, 2025
66d6c9b
Update the remaining tests to work with the handler
jerelmiller Sep 4, 2025
12a710c
Add additional tests
jerelmiller Sep 4, 2025
225edff
Create stub of GraphQL17Alpha9Handler
jerelmiller Sep 4, 2025
fbbd08e
Add chunk types for alpha9
jerelmiller Sep 4, 2025
1626cf6
Add stub implementations for abstract methods
jerelmiller Sep 4, 2025
2681c69
Update types to be more compatible with graphql-js
jerelmiller Sep 4, 2025
6cb1c20
Fix type of completed result
jerelmiller Sep 4, 2025
ba85d93
Add initial implementation of merging
jerelmiller Sep 4, 2025
6d8c443
Add patch for types in v17-alpha9
jerelmiller Sep 4, 2025
9cd60c4
Add return type for async generator for run function
jerelmiller Sep 4, 2025
b039ee4
Add errors when merging
jerelmiller Sep 4, 2025
74cb0a4
Ensure errors are merged from incremental results
jerelmiller Sep 4, 2025
c17707f
Iterate completed after merging all incremental items
jerelmiller Sep 4, 2025
e7e11b7
Remove locations from error
jerelmiller Sep 4, 2025
21042b9
Fix incorrect data merged in
jerelmiller Sep 4, 2025
53bd6ce
Merge errors in completed array
jerelmiller Sep 4, 2025
978228a
Remove locations in error tests
jerelmiller Sep 4, 2025
706bda0
Fix incorrect assertion
jerelmiller Sep 4, 2025
e6731f8
Fix missing assertion in test
jerelmiller Sep 4, 2025
dba62d4
Fix incorrect assertion
jerelmiller Sep 4, 2025
ee5cb45
Update test to use actual schema fields
jerelmiller Sep 4, 2025
33ba203
Yield a regular result instead of return
jerelmiller Sep 4, 2025
11823bd
Ensure errors are serialized from helper
jerelmiller Sep 4, 2025
40213fa
Update test to match incremental behavior
jerelmiller Sep 4, 2025
6e6ff31
Update how path is calculated
jerelmiller Sep 4, 2025
fa0b687
Temp skip test
jerelmiller Sep 4, 2025
ec9792f
Move test to /defer.test.ts
jerelmiller Sep 4, 2025
8d61c1d
Update extractErrors
jerelmiller Sep 4, 2025
2610442
Rename merge
jerelmiller Sep 4, 2025
dbf5b7f
Make types mirror defer implementation
jerelmiller Sep 4, 2025
723c163
Update exports snapshot
jerelmiller Sep 4, 2025
a12de86
Split out helper for mocking an incremental stream
jerelmiller Sep 4, 2025
df5b353
Rename helper
jerelmiller Sep 4, 2025
f4a4a9f
Use updated helper in incremental utils
jerelmiller Sep 4, 2025
ba1f15e
Move mockDeferStream to own file
jerelmiller Sep 4, 2025
12e8ddb
Rename mockDeferStream to mockDefer20220824 everywhere
jerelmiller Sep 4, 2025
3ed6eb4
Rename file
jerelmiller Sep 4, 2025
b35c6e0
Add helper to mock newer defer implementation
jerelmiller Sep 4, 2025
260d296
Rename folder to multipart
jerelmiller Sep 4, 2025
dc0d1fd
Move mulipart subscription mock to own file
jerelmiller Sep 4, 2025
7b51170
Import directly to avoid another barrel file
jerelmiller Sep 4, 2025
005aa27
Format test files with typescript parser
jerelmiller Sep 4, 2025
4e36d7c
Update exports snapshot
jerelmiller Sep 4, 2025
8b9b314
Move useQuery defer tests to own file
jerelmiller Sep 4, 2025
66986d4
Replace MockSubscriptionLink with mock helper
jerelmiller Sep 4, 2025
0612a52
Add tests for useQuery with the new defer spec
jerelmiller Sep 5, 2025
af769e7
Port first defer test for useSuspenseQuery to own file
jerelmiller Sep 5, 2025
45bf6ab
Extract render helper
jerelmiller Sep 5, 2025
ae21e84
Migrate useSuspenseQuery defer tests to own file with renderStream
jerelmiller Sep 5, 2025
fec5d76
Ignore useSuspenseQuery subfile tests
jerelmiller Sep 5, 2025
0064d8f
Remove unneeded heck for React 19 in test
jerelmiller Sep 5, 2025
1d61c48
Remove unneeded non-null assertion
jerelmiller Sep 5, 2025
74ab3ca
Rename ErrorFallback to ErrorBoundary
jerelmiller Sep 5, 2025
7826689
Remove unneeded non-null assertion
jerelmiller Sep 5, 2025
51e9ff3
Add useSuspenseQuery tets for GraphQL17Alpha9Handler
jerelmiller Sep 5, 2025
61736c0
Copy useBackgroundQuery defer tests to own file
jerelmiller Sep 5, 2025
aa17427
Use the new helpers
jerelmiller Sep 5, 2025
da0113c
Use a pattern similar to useSuspenseQuery tests in useBackgroundQuery…
jerelmiller Sep 5, 2025
9ae7fa3
Use createClientWrapper helper in the defer test files
jerelmiller Sep 5, 2025
27e5faf
Add useBackgroundQuery tests for defer with updated spec
jerelmiller Sep 5, 2025
7f7f72c
Move useMutation defer tests to own file
jerelmiller Sep 5, 2025
013c568
Move useLoadableQuery defer tests to own file
jerelmiller Sep 5, 2025
3e0d4de
Move createQueryPreloader tests to own file
jerelmiller Sep 5, 2025
6b0e002
Use defer helpers instead of mock subscription link
jerelmiller Sep 5, 2025
560824e
Use render helper in useLoadableQuery similar to other tests
jerelmiller Sep 5, 2025
fe18741
Remove unused import
jerelmiller Sep 5, 2025
01d4325
Add a useLoadableQuery test suite for deferGraphQL17Alpha9
jerelmiller Sep 5, 2025
6e4ad15
Add a createQueryPreloader test suite for deferGraphQL17Alpha9
jerelmiller Sep 5, 2025
c217efa
Add a doc block
jerelmiller Sep 5, 2025
93ef59d
Mark methods as internal
jerelmiller Sep 5, 2025
102756e
Run extract api
jerelmiller Sep 5, 2025
16b4457
Update size limits
jerelmiller Sep 5, 2025
108e9f0
Formatting
jerelmiller Sep 5, 2025
bfacd3e
Fix lint errors
jerelmiller Sep 5, 2025
5c51186
Remove unused imports
jerelmiller Sep 5, 2025
cb0e021
Fix useSuspenseQuery test that just emitted errors
jerelmiller Sep 5, 2025
8a8927f
Move `@defer` tests from ApolloClient/* to client.watchQuery/defer202…
jerelmiller Sep 5, 2025
a8231c0
Restore multiple-results test
jerelmiller Sep 6, 2025
5e85248
Remove multiple-results tests from defer tests
jerelmiller Sep 6, 2025
bb6dd71
Add new spec format tests
jerelmiller Sep 6, 2025
a9c5e7d
Remove defer in tests that don't test defer
jerelmiller Sep 6, 2025
8de4546
Exclude useBackgroundQuery/useLoadableQuery subfolder tests from Reac…
jerelmiller Sep 8, 2025
7512b6b
Update test with new test utils
jerelmiller Sep 8, 2025
96120c5
Update error message
jerelmiller Sep 8, 2025
0772538
Use filter instead of indexOf and splice
jerelmiller Sep 8, 2025
b72deb0
Add tests for the new format for useMutation
jerelmiller Sep 8, 2025
b53ce0d
Remove export/check for hasIncrementalChunks
jerelmiller Sep 9, 2025
c7fba99
Add changeset
jerelmiller Sep 10, 2025
c4a4228
Update size limits
jerelmiller Sep 10, 2025
8052f24
Fix name of test file
jerelmiller Sep 10, 2025
e0890e6
Initialize a new DeepMerger each time
jerelmiller Sep 10, 2025
d59dd30
Fix incorrect assertion for useQuery test due to bug in handler
jerelmiller Sep 10, 2025
27fc9dc
Update size limits
jerelmiller Sep 10, 2025
000cef4
Fix duplicate errors in extractErrors from initial chunk
jerelmiller Sep 16, 2025
14e5a98
Update size limits
jerelmiller Sep 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions .api-reports/api-report-incremental.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,102 @@ class DeferRequest<TData extends Record<string, unknown>> implements Incremental
hasNext: boolean;
}

// @public (undocumented)
export namespace GraphQL17Alpha9Handler {
// (undocumented)
export type Chunk<TData> = InitialResult<TData> | SubsequentResult<TData>;
// (undocumented)
export interface CompletedResult {
// (undocumented)
errors?: ReadonlyArray<GraphQLFormattedError>;
// (undocumented)
id: string;
}
// (undocumented)
export interface GraphQL17Alpha9Result extends HKT {
// (undocumented)
arg1: unknown;
// (undocumented)
arg2: unknown;
// (undocumented)
return: GraphQL17Alpha9Handler.Chunk<Record<string, unknown>>;
}
// (undocumented)
export interface IncrementalDeferResult<TData = Record<string, unknown>> {
// (undocumented)
data: TData;
// (undocumented)
errors?: ReadonlyArray<GraphQLFormattedError>;
// (undocumented)
extensions?: Record<string, unknown>;
// (undocumented)
id: string;
// (undocumented)
subPath?: Incremental.Path;
}
// (undocumented)
export type IncrementalResult<TData = unknown> = IncrementalDeferResult<TData> | IncrementalStreamResult<TData>;
// (undocumented)
export interface IncrementalStreamResult<TData = ReadonlyArray<unknown>> {
// (undocumented)
errors?: ReadonlyArray<GraphQLFormattedError>;
// (undocumented)
extensions?: Record<string, unknown>;
// (undocumented)
id: string;
// (undocumented)
items: TData;
// (undocumented)
subPath?: Incremental.Path;
}
// (undocumented)
export type InitialResult<TData = Record<string, unknown>> = {
data: TData;
errors?: ReadonlyArray<GraphQLFormattedError>;
pending: ReadonlyArray<PendingResult>;
hasNext: boolean;
extensions?: Record<string, unknown>;
};
// (undocumented)
export interface PendingResult {
// (undocumented)
id: string;
// (undocumented)
label?: string;
// (undocumented)
path: Incremental.Path;
}
// (undocumented)
export type SubsequentResult<TData = unknown> = {
hasNext: boolean;
pending?: ReadonlyArray<PendingResult>;
incremental?: ReadonlyArray<IncrementalResult<TData>>;
completed?: ReadonlyArray<CompletedResult>;
extensions?: Record<string, unknown>;
};
// (undocumented)
export interface TypeOverrides {
// (undocumented)
AdditionalApolloLinkResultTypes: GraphQL17Alpha9Result;
}
}

// @public
export class GraphQL17Alpha9Handler implements Incremental.Handler<GraphQL17Alpha9Handler.Chunk<any>> {
// @internal @deprecated (undocumented)
extractErrors(result: ApolloLink.Result<any>): GraphQLFormattedError[] | undefined;
// @internal @deprecated (undocumented)
isIncrementalResult(result: ApolloLink.Result<any>): result is GraphQL17Alpha9Handler.InitialResult | GraphQL17Alpha9Handler.SubsequentResult;
// @internal @deprecated (undocumented)
prepareRequest(request: ApolloLink.Request): ApolloLink.Request;
// Warning: (ae-forgotten-export) The symbol "IncrementalRequest" needs to be exported by the entry point index.d.ts
//
// @internal @deprecated (undocumented)
startRequest<TData>(_: {
query: DocumentNode;
}): IncrementalRequest<TData>;
}

// @public (undocumented)
export namespace Incremental {
// @internal @deprecated (undocumented)
Expand All @@ -106,6 +202,14 @@ export namespace Incremental {
export type Path = ReadonlyArray<string | number>;
}

// @public (undocumented)
class IncrementalRequest<TData> implements Incremental.IncrementalRequest<GraphQL17Alpha9Handler.Chunk<TData>, TData> {
// (undocumented)
handle(cacheData: TData | DeepPartial<TData> | null | undefined, chunk: GraphQL17Alpha9Handler.Chunk<TData>): FormattedExecutionResult<TData>;
// (undocumented)
hasNext: boolean;
}

// @public (undocumented)
export namespace NotImplementedHandler {
// (undocumented)
Expand Down
17 changes: 17 additions & 0 deletions .changeset/little-yaks-decide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
"@apollo/client": minor
---

Support the newer incremental delivery format for the `@defer` directive implemented in `[email protected]`. Import the `GraphQL17Alpha9Handler` to use the newer incremental delivery format with `@defer`.

```ts
import { GraphQL17Alpha9Handler } from "@apollo/client/incremental";

const client = new ApolloClient({
// ...
incrementalHandler: new GraphQL17Alpha9Handler(),
});
```

> [!NOTE]
> In order to use the `GraphQL17Alpha9Handler`, the GraphQL server MUST implement the newer incremental delivery format. You may see errors or unusual behavior if you use the wrong handler. If you are using Apollo Router, continue to use the `Defer20220824Handler` because Apollo Router does not yet support the newer incremental delivery format.
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@
"parser": "typescript-with-jsdoc"
}
},
{
"files": ["**/__tests__/**/*.ts", "**/__tests__/**/*.tsx"],
"options": {
"parser": "typescript"
}
},
{
"files": ["*.mdx"],
"options": {
Expand Down
8 changes: 4 additions & 4 deletions .size-limits.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 43857,
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 38699,
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 33415,
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27498
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (CJS)": 44206,
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production) (CJS)": 39060,
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\"": 33462,
"import { ApolloClient, InMemoryCache, HttpLink } from \"@apollo/client\" (production)": 27490
}
3 changes: 3 additions & 0 deletions config/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,11 @@ const react17TestFileIgnoreList = [
"src/testing/experimental/__tests__/createTestSchema.test.tsx",
"src/react/hooks/__tests__/useSuspenseFragment.test.tsx",
"src/react/hooks/__tests__/useSuspenseQuery.test.tsx",
"src/react/hooks/__tests__/useSuspenseQuery/*",
"src/react/hooks/__tests__/useBackgroundQuery.test.tsx",
"src/react/hooks/__tests__/useBackgroundQuery/*",
"src/react/hooks/__tests__/useLoadableQuery.test.tsx",
"src/react/hooks/__tests__/useLoadableQuery/*",
"src/react/hooks/__tests__/useQueryRefHandlers.test.tsx",
"src/react/query-preloader/__tests__/createQueryPreloader.test.tsx",
"src/react/ssr/__tests__/prerenderStatic.test.tsx",
Expand Down
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@
"globals": "15.14.0",
"graphql": "16.9.0",
"graphql-17-alpha2": "npm:[email protected]",
"graphql-17-alpha9": "npm:[email protected]",
"graphql-ws": "6.0.3",
"jest": "29.7.0",
"jest-environment-jsdom": "29.7.0",
Expand Down
16 changes: 16 additions & 0 deletions patches/graphql-17-alpha9+17.0.0-alpha.9.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
diff --git a/node_modules/graphql-17-alpha9/execution/types.d.ts b/node_modules/graphql-17-alpha9/execution/types.d.ts
index 48ef2e9..6ef2ab3 100644
--- a/node_modules/graphql-17-alpha9/execution/types.d.ts
+++ b/node_modules/graphql-17-alpha9/execution/types.d.ts
@@ -95,9 +95,8 @@ export interface CompletedResult {
errors?: ReadonlyArray<GraphQLError>;
}
export interface FormattedCompletedResult {
- path: ReadonlyArray<string | number>;
- label?: string;
- errors?: ReadonlyArray<GraphQLError>;
+ id: string;
+ errors?: ReadonlyArray<GraphQLFormattedError>;
}
export declare function isPendingExecutionGroup(incrementalDataRecord: IncrementalDataRecord): incrementalDataRecord is PendingExecutionGroup;
export type CompletedExecutionGroup = SuccessfulExecutionGroup | FailedExecutionGroup;
4 changes: 3 additions & 1 deletion src/__tests__/__snapshots__/exports.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ exports[`exports of public entry points @apollo/client/incremental 1`] = `
Array [
"Defer20220824Handler",
"GraphQL17Alpha2Handler",
"GraphQL17Alpha9Handler",
"NotImplementedHandler",
]
`;
Expand Down Expand Up @@ -362,7 +363,8 @@ Array [
"enableFakeTimers",
"executeWithDefaultContext",
"markAsStreaming",
"mockDeferStream",
"mockDefer20220824",
"mockDeferStreamGraphQL17Alpha9",
"mockMultipartSubscriptionStream",
"renderAsync",
"renderHookAsync",
Expand Down
4 changes: 2 additions & 2 deletions src/__tests__/fetchMore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Defer20220824Handler } from "@apollo/client/incremental";
import { MockLink, MockSubscriptionLink } from "@apollo/client/testing";
import {
markAsStreaming,
mockDeferStream,
mockDefer20220824,
ObservableStream,
setupPaginatedCase,
} from "@apollo/client/testing/internal";
Expand Down Expand Up @@ -2478,7 +2478,7 @@ test("uses updateQuery to update the result of the query with no-cache queries",
});

test("calling `fetchMore` on an ObservableQuery that hasn't finished deferring yet will not put it into completed state", async () => {
const defer = mockDeferStream();
const defer = mockDefer20220824();
const baseLink = new MockSubscriptionLink();

const client = new ApolloClient({
Expand Down
Loading