Skip to content

Commit

Permalink
V2: Replace disableQuery with skipToken (#428)
Browse files Browse the repository at this point in the history
  • Loading branch information
timostamm authored Sep 30, 2024
1 parent a274573 commit c9f20cd
Show file tree
Hide file tree
Showing 18 changed files with 131 additions and 118 deletions.
1 change: 0 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ const config = {
"@typescript-eslint/prefer-readonly-parameter-types": "off", // not realistic
"@typescript-eslint/explicit-module-boundary-types": "off", // inference and conformance testing cover this well
"@typescript-eslint/explicit-function-return-type": "off", // inference and conformance testing cover this well
"@typescript-eslint/no-unused-expressions": "off", // necessary component of some exports, e.g. DisableQuery
"@typescript-eslint/no-type-alias": "off", // this rule turns off things that are absolutely required by this project such as conditional types and literals
"@typescript-eslint/no-throw-literal": "off", // unfortunately this rule doesn't understand returns from `unreachableCase`
"@typescript-eslint/no-magic-numbers": "off", // literal values are used in CSS-in-JS, tests, and library constants
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ Use this helper to get the default transport that's currently attached to the Re
```ts
function useQuery<I extends Message<I>, O extends Message<O>>(
methodSig: MethodUnaryDescriptor<I, O>,
input?: DisableQuery | PartialMessage<I>,
input?: SkipToken | PartialMessage<I>,
options?: {
transport?: Transport;
callOptions?: CallOptions;
Expand All @@ -217,7 +217,7 @@ function useInfiniteQuery<
Input extends PartialMessage<I> & Required<Pick<PartialMessage<I>, ParamKey>>,
>(
methodSig: MethodUnaryDescriptor<I, O>,
input: DisableQuery | Input,
input: SkipToken | Input,
options: {
pageParamKey: ParamKey;
transport?: Transport;
Expand Down Expand Up @@ -256,7 +256,7 @@ Any additional `options` you pass to `useMutation` will be merged with the optio
```ts
function createConnectQueryKey<I extends Message<I>, O extends Message<O>>(
methodDescriptor: Pick<MethodUnaryDescriptor<I, O>, "I" | "name" | "service">,
input?: DisableQuery | PartialMessage<I> | undefined,
input?: SkipToken | PartialMessage<I> | undefined,
): ConnectQueryKey<I>;
```

Expand All @@ -270,7 +270,7 @@ function createConnectInfiniteQueryKey<
O extends Message<O>,
>(
methodDescriptor: Pick<MethodUnaryDescriptor<I, O>, "I" | "name" | "service">,
input: DisableQuery | PartialMessage<I>,
input: SkipToken | PartialMessage<I>,
pageParamKey: keyof PartialMessage<I>,
): ConnectInfiniteQueryKey<I>;
```
Expand Down Expand Up @@ -322,7 +322,7 @@ queryClient.setQueryData(
```ts
function createQueryOptions<I extends Message<I>, O extends Message<O>>(
methodSig: MethodUnaryDescriptor<I, O>,
input: DisableQuery | PartialMessage<I> | undefined,
input: SkipToken | PartialMessage<I> | undefined,
{
transport,
callOptions,
Expand Down Expand Up @@ -365,7 +365,7 @@ function createInfiniteQueryOptions<
Input extends PartialMessage<I> & Required<Pick<PartialMessage<I>, ParamKey>>,
>(
methodSig: MethodUnaryDescriptor<I, O>,
input: DisableQuery | Input,
input: SkipToken | Input,
{
transport,
getNextPageParam,
Expand Down
3 changes: 1 addition & 2 deletions examples/react/basic/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,5 @@
"types": ["node"],
"declaration": true // necessary to check if generated code can be published
},
"include": ["src", "./*.config.ts", "__mocks__"],
"references": [{ "path": "./tsconfig.node.json" }]
"include": ["src", "./*.config.ts", "__mocks__"]
}
9 changes: 0 additions & 9 deletions examples/react/basic/tsconfig.node.json

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,10 @@ export default defineConfig({
plugins: [react()],
test: {
environment: "jsdom",
typecheck: {
enabled: true,
// Mofidied to typecheck definition files as well as source files
include: ["**/*.{test,spec}?(-d).?(c|m)[jt]s?(x)"],
},
},
});
6 changes: 3 additions & 3 deletions packages/connect-query/src/connect-query-key.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
// limitations under the License.

import { create } from "@bufbuild/protobuf";
import { skipToken } from "@tanstack/react-query";
import { describe, expect, it } from "vitest";

import { createConnectQueryKey } from "./connect-query-key.js";
import { ElizaService, SayRequestSchema } from "./gen/eliza_pb.js";
import { disableQuery } from "./utils.js";

describe("makeQueryKey", () => {
const methodDescriptor = {
Expand Down Expand Up @@ -46,8 +46,8 @@ describe("makeQueryKey", () => {
]);
});

it("makes a query key with a disabled input", () => {
const key = createConnectQueryKey(methodDescriptor, disableQuery);
it("makes a query key with a skipToken", () => {
const key = createConnectQueryKey(methodDescriptor, skipToken);
expect(key).toStrictEqual([
ElizaService.typeName,
"name",
Expand Down
10 changes: 5 additions & 5 deletions packages/connect-query/src/connect-query-key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import type {
MessageShape,
} from "@bufbuild/protobuf";
import { create } from "@bufbuild/protobuf";
import type { SkipToken } from "@tanstack/react-query";
import { skipToken } from "@tanstack/react-query";

import type { MethodUnaryDescriptor } from "./method-unary-descriptor.js";
import type { DisableQuery } from "./utils.js";
import { disableQuery } from "./utils.js";

/**
* TanStack Query requires query keys in order to decide when the query should automatically update.
Expand Down Expand Up @@ -55,12 +55,12 @@ export function createConnectQueryKey<
O extends DescMessage,
>(
schema: Pick<MethodUnaryDescriptor<I, O>, "input" | "parent" | "name">,
input?: DisableQuery | MessageInitShape<I> | undefined,
input?: SkipToken | MessageInitShape<I> | undefined,
): ConnectQueryKey<I> {
return [
schema.parent.typeName,
schema.name,
create(schema.input, input === disableQuery || !input ? undefined : input),
create(schema.input, input === skipToken || !input ? undefined : input),
];
}

Expand All @@ -82,7 +82,7 @@ export function createConnectInfiniteQueryKey<
O extends DescMessage,
>(
schema: Pick<MethodUnaryDescriptor<I, O>, "input" | "parent" | "name">,
input?: DisableQuery | MessageInitShape<I> | undefined,
input?: SkipToken | MessageInitShape<I> | undefined,
): ConnectInfiniteQueryKey<I> {
return [...createConnectQueryKey(schema, input), "infinite"];
}
46 changes: 24 additions & 22 deletions packages/connect-query/src/create-use-infinite-query-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ import type {
GetNextPageParamFunction,
InfiniteData,
QueryFunction,
SkipToken,
UseInfiniteQueryOptions,
UseQueryOptions,
UseSuspenseInfiniteQueryOptions,
} from "@tanstack/react-query";
import { skipToken } from "@tanstack/react-query";

import { callUnaryMethod } from "./call-unary-method.js";
import {
Expand All @@ -34,7 +36,7 @@ import {
} from "./connect-query-key.js";
import type { MethodUnaryDescriptor } from "./method-unary-descriptor.js";
import { createStructuralSharing } from "./structural-sharing.js";
import { assert, type DisableQuery, disableQuery } from "./utils.js";
import { assert } from "./utils.js";

/**
* Options specific to connect-query
Expand Down Expand Up @@ -103,7 +105,7 @@ function createUnaryInfiniteQueryFn<
ParamKey extends keyof MessageInitShape<I>,
>(
schema: MethodUnaryDescriptor<I, O>,
input: DisableQuery | MessageInitShape<I>,
input: MessageInitShape<I>,
{
callOptions,
transport,
Expand All @@ -119,7 +121,6 @@ function createUnaryInfiniteQueryFn<
MessageInitShape<I>[ParamKey]
> {
return async (context) => {
assert(input !== disableQuery, "Disabled query cannot be fetched");
assert("pageParam" in context, "pageParam must be part of context");

const inputCombinedWithPageParam = {
Expand All @@ -138,9 +139,6 @@ function createUnaryInfiniteQueryFn<

/**
* Query the method provided. Maps to useInfiniteQuery on tanstack/react-query
*
* @param schema
* @returns
*/
export function createUseInfiniteQueryOptions<
I extends DescMessage,
Expand All @@ -149,7 +147,7 @@ export function createUseInfiniteQueryOptions<
>(
schema: MethodUnaryDescriptor<I, O>,
input:
| DisableQuery
| SkipToken
| (MessageInitShape<I> & Required<Pick<MessageInitShape<I>, ParamKey>>),
{
transport,
Expand All @@ -164,38 +162,42 @@ export function createUseInfiniteQueryOptions<
ParamKey
>["getNextPageParam"];
queryKey: ConnectInfiniteQueryKey<I>;
queryFn: QueryFunction<
MessageShape<O>,
ConnectInfiniteQueryKey<I>,
MessageInitShape<I>[ParamKey]
>;
structuralSharing?: Exclude<UseQueryOptions["structuralSharing"], undefined>;
queryFn:
| QueryFunction<
MessageShape<O>,
ConnectInfiniteQueryKey<I>,
MessageInitShape<I>[ParamKey]
>
| SkipToken;
structuralSharing: Exclude<UseQueryOptions["structuralSharing"], undefined>;
initialPageParam: MessageInitShape<I>[ParamKey];
enabled?: false;
} {
const queryKey = createConnectInfiniteQueryKey(
schema,
input === disableQuery
input === skipToken
? undefined
: {
...input,
[pageParamKey]: undefined,
},
);
const structuralSharing = createStructuralSharing(schema.output);
const queryFn =
input === skipToken
? skipToken
: createUnaryInfiniteQueryFn(schema, input, {
transport,
callOptions,
pageParamKey,
});
return {
getNextPageParam,
initialPageParam:
input === disableQuery
input === skipToken
? (undefined as MessageInitShape<I>[ParamKey])
: (input[pageParamKey] as MessageInitShape<I>[ParamKey]),
queryKey,
queryFn: createUnaryInfiniteQueryFn(schema, input, {
transport,
callOptions,
pageParamKey,
}),
queryFn,
structuralSharing,
...(input === disableQuery ? { enabled: false } : undefined),
};
}
46 changes: 46 additions & 0 deletions packages/connect-query/src/create-use-query-options.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2021-2023 The Connect Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { skipToken } from "@tanstack/react-query";
import { describe, expect, it } from "vitest";

import { createConnectQueryKey } from "./connect-query-key.js";
import { createUseQueryOptions } from "./create-use-query-options.js";
import { ElizaService } from "./gen/eliza_pb.js";
import { mockEliza } from "./test/test-utils.js";

// TODO: maybe create a helper to take a service and method and generate this.
const sayMethodDescriptor = ElizaService.method.say;

const mockedElizaTransport = mockEliza();

describe("createUseQueryOptions", () => {
it("honors skipToken", () => {
const opt = createUseQueryOptions(sayMethodDescriptor, skipToken, {
transport: mockedElizaTransport,
});
expect(opt.queryFn).toBe(skipToken);
});
it("sets queryKey", () => {
const want = createConnectQueryKey(sayMethodDescriptor, { sentence: "hi" });
const opt = createUseQueryOptions(
sayMethodDescriptor,
{ sentence: "hi" },
{
transport: mockedElizaTransport,
},
);
expect(opt.queryKey).toStrictEqual(want);
});
});
23 changes: 11 additions & 12 deletions packages/connect-query/src/create-use-query-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,17 @@ import type {
import type { CallOptions, ConnectError, Transport } from "@connectrpc/connect";
import type {
QueryFunction,
SkipToken,
UseQueryOptions,
UseSuspenseQueryOptions,
} from "@tanstack/react-query";
import { skipToken } from "@tanstack/react-query";

import { callUnaryMethod } from "./call-unary-method.js";
import type { ConnectQueryKey } from "./connect-query-key.js";
import { createConnectQueryKey } from "./connect-query-key.js";
import type { MethodUnaryDescriptor } from "./method-unary-descriptor.js";
import { createStructuralSharing } from "./structural-sharing.js";
import { assert, type DisableQuery, disableQuery } from "./utils.js";

export interface ConnectQueryOptions {
/** The transport to be used for the fetching. */
Expand Down Expand Up @@ -76,7 +77,7 @@ export type CreateSuspenseQueryOptions<

function createUnaryQueryFn<I extends DescMessage, O extends DescMessage>(
schema: MethodUnaryDescriptor<I, O>,
input: DisableQuery | MessageInitShape<I> | undefined,
input: MessageInitShape<I> | undefined,
{
callOptions,
transport,
Expand All @@ -86,7 +87,6 @@ function createUnaryQueryFn<I extends DescMessage, O extends DescMessage>(
},
): QueryFunction<MessageShape<O>, ConnectQueryKey<I>> {
return async (context) => {
assert(input !== disableQuery, "Disabled query cannot be fetched");
return callUnaryMethod(schema, input, {
callOptions: {
...callOptions,
Expand All @@ -105,7 +105,7 @@ export function createUseQueryOptions<
O extends DescMessage,
>(
schema: MethodUnaryDescriptor<I, O>,
input: DisableQuery | MessageInitShape<I> | undefined,
input: SkipToken | MessageInitShape<I> | undefined,
{
transport,
callOptions,
Expand All @@ -114,19 +114,18 @@ export function createUseQueryOptions<
},
): {
queryKey: ConnectQueryKey<I>;
queryFn: QueryFunction<MessageShape<O>, ConnectQueryKey<I>>;
structuralSharing?: Exclude<UseQueryOptions["structuralSharing"], undefined>;
enabled?: false;
queryFn: QueryFunction<MessageShape<O>, ConnectQueryKey<I>> | SkipToken;
structuralSharing: Exclude<UseQueryOptions["structuralSharing"], undefined>;
} {
const queryKey = createConnectQueryKey(schema, input);
const structuralSharing = createStructuralSharing(schema.output);
const queryFn =
input === skipToken
? skipToken
: createUnaryQueryFn(schema, input, { transport, callOptions });
return {
queryKey,
queryFn: createUnaryQueryFn(schema, input, {
transport,
callOptions,
}),
queryFn,
structuralSharing,
...(input === disableQuery ? { enabled: false } : undefined),
};
}
Loading

0 comments on commit c9f20cd

Please sign in to comment.