Skip to content

Commit

Permalink
feat(packages/react): support operation name
Browse files Browse the repository at this point in the history
  • Loading branch information
vicary committed Nov 27, 2022
1 parent 1fbba64 commit d46ef12
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/purple-mugs-travel.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@gqty/react': minor
---

feat(packages/react): support GraphQL operation names
3 changes: 3 additions & 0 deletions packages/react/src/mutation/useMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export interface UseMutationOptions<TData> {
* @default false
*/
nonSerializableVariables?: boolean;
/** Optional operation name for this mutation request. */
operationName?: string;
}

export interface UseMutationState<TData> {
Expand Down Expand Up @@ -215,6 +217,7 @@ export function createUseMutation<
noCache: optsRef.current.noCache,
refetch: true,
nonSerializableVariables: optsRef.current.nonSerializableVariables,
operationName: optsRef.current.operationName,
}).then(
async (data) => {
const refetchingQueries = callRefetchQueries();
Expand Down
16 changes: 16 additions & 0 deletions packages/react/src/query/useQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface UseQueryOptions<
suspense?: boolean;
staleWhileRevalidate?: boolean | object | number | string | null;
onError?: OnErrorHandler;
operationName?: string;
prepare?: (helpers: UseQueryPrepareHelpers<GeneratedSchema>) => void;
}

Expand Down Expand Up @@ -80,6 +81,7 @@ export function createUseQuery<
staleWhileRevalidate = defaultStaleWhileRevalidate,
onError,
prepare,
operationName,
}: UseQueryOptions<GeneratedSchema> = {}): UseQueryReturnValue<GeneratedSchema> {
const [$state] = React.useState<Writeable<UseQueryState>>(() => {
const state: Writeable<UseQueryState> = {
Expand All @@ -101,6 +103,18 @@ export function createUseQuery<
updateOnFetchPromise: true,
});

const removeOperationNameInterceptor = React.useMemo(() => {
const interceptor = interceptorManager.createInterceptor();

interceptor.selectionAddListeners.add((selection) => {
selection.operationName = operationName;
});

return () => {
interceptorManager.removeInterceptor(interceptor);
};
}, [operationName]);

if (prepare) {
try {
prepare(prepareHelpers);
Expand All @@ -112,6 +126,8 @@ export function createUseQuery<
}
}

useIsomorphicLayoutEffect(removeOperationNameInterceptor);

useIsomorphicLayoutEffect(() => {
return scheduler.errors.subscribeErrors((ev) => {
switch (ev.type) {
Expand Down
12 changes: 10 additions & 2 deletions packages/react/src/subscription/useSubscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ export interface UseSubscription<
subscription: object;
}
> {
(): GeneratedSchema['subscription'];
(opts?: UseSubscriptionOptions): GeneratedSchema['subscription'];
}

export interface UseSubscriptionOptions {
operationName?: string;
}

export function createUseSubscription<
Expand All @@ -36,7 +40,7 @@ export function createUseSubscription<
client.subscription;

const useSubscription: UseSubscription<GeneratedSchema> =
function useSubscription() {
function useSubscription(opts?: UseSubscriptionOptions) {
const forceUpdate = useForceUpdate({
doTimeout: true,
});
Expand All @@ -46,6 +50,10 @@ export function createUseSubscription<

Promise.resolve(interceptor).then(removeInterceptor);

interceptor.selectionAddListeners.add((selection) => {
selection.operationName = opts?.operationName;
});

interceptor.selectionAddListeners.add((selection) => {
if (selection.type === 2) hookSelections.add(selection);
});
Expand Down
24 changes: 24 additions & 0 deletions packages/react/test/useQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,27 @@ test('Basic Suspense', async () => {

expect(result.current).toBe('hello world');
});

it.only('should fetches with operation name', async () => {
let fetchedQuery: string | undefined;
const { useQuery } = await createReactTestClient(undefined, (query) => {
fetchedQuery = query;
return { data: { hello: 'hello world' } };
});

const { result, waitForNextUpdate } = renderHook(() => {
const query = useQuery({
operationName: 'TestQuery',
suspense: true,
});

return query.hello;
});

expect(result.current).toBe(undefined);

await waitForNextUpdate();

expect(fetchedQuery).toBe('query TestQuery{hello}');
expect(result.current).toBe('hello world');
});

0 comments on commit d46ef12

Please sign in to comment.