Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(react): consume new action plans from api client #632

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions packages/api-client-core/src/AnyClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export interface AnyClient {
mutate(graphQL: string, variables?: Record<string, any>): Promise<any>;
transaction<T>(callback: (transaction: GadgetTransaction) => Promise<T>): Promise<T>;
internal: InternalModelManagerNamespace;
apiClientCoreVersion?: string;
[$modelRelationships]?: { [modelName: string]: { [apiIdentifier: string]: { type: string; model: string } } };
}

Expand Down
13 changes: 12 additions & 1 deletion packages/api-client-core/src/GadgetFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ export type AsyncRecord<T extends RecordShape> = PromiseOrLiveIterator<GadgetRec
export type AsyncNullableRecord<T extends RecordShape> = PromiseOrLiveIterator<GadgetRecord<T> | null>;
export type AsyncRecordList<T extends RecordShape> = PromiseOrLiveIterator<GadgetRecordList<T>>;

export interface GQLBuilderResult {
query: string;
variables: Record<string, any>;
}

export interface FindOneFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
<Options extends OptionsT>(fieldValue: string, options?: LimitToKnownKeys<Options, OptionsT>): AsyncRecord<any>;

type: "findOne";
findByVariableName: string;
operationName: string;
Expand All @@ -19,6 +23,7 @@ export interface FindOneFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
selectionType: SelectionT;
optionsType: OptionsT;
schemaType: SchemaT | null;
plan?: <Options extends OptionsT>(fieldValue: string, options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
}

export interface MaybeFindOneFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
Expand All @@ -33,6 +38,7 @@ export interface MaybeFindOneFunction<OptionsT, SelectionT, SchemaT, DefaultsT>
selectionType: SelectionT;
optionsType: OptionsT;
schemaType: SchemaT | null;
plan?: <Options extends OptionsT>(fieldValue: string, options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
}

export interface FindManyFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
Expand All @@ -46,6 +52,7 @@ export interface FindManyFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
selectionType: SelectionT;
optionsType: OptionsT;
schemaType: SchemaT | null;
plan?: <Options extends OptionsT>(options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
}

export interface FindFirstFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
Expand All @@ -59,6 +66,7 @@ export interface FindFirstFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
selectionType: SelectionT;
optionsType: OptionsT;
schemaType: SchemaT | null;
plan?: <Options extends OptionsT>(options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
}

export interface MaybeFindFirstFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
Expand All @@ -72,6 +80,7 @@ export interface MaybeFindFirstFunction<OptionsT, SelectionT, SchemaT, DefaultsT
selectionType: SelectionT;
optionsType: OptionsT;
schemaType: SchemaT | null;
plan?: <Options extends OptionsT>(options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
}

export interface ActionWithIdAndVariables<OptionsT, VariablesT> {
Expand Down Expand Up @@ -122,6 +131,7 @@ export interface ActionFunctionMetadata<OptionsT, VariablesT, SelectionT, Schema
paramOnlyVariables?: readonly string[];
hasReturnType?: HasReturnType;
singleActionFunctionName?: string;
plan?: <Options extends OptionsT>(options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
/** @deprecated */
hasCreateOrUpdateEffect?: boolean;
}
Expand Down Expand Up @@ -162,6 +172,7 @@ export interface GetFunction<OptionsT, SelectionT, SchemaT, DefaultsT> {
selectionType: SelectionT;
optionsType: OptionsT;
schemaType: SchemaT | null;
plan?: <Options extends OptionsT>(options?: LimitToKnownKeys<Options, OptionsT>) => GQLBuilderResult;
}

export interface GlobalActionFunction<VariablesT> {
Expand Down
17 changes: 5 additions & 12 deletions packages/react/src/useAction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import type { ActionFunction, DefaultSelection, GadgetRecord, LimitToKnownKeys, Select } from "@gadgetinc/api-client-core";
import {
actionOperation,
capitalizeIdentifier,
disambiguateActionVariables,
get,
Expand Down Expand Up @@ -64,17 +63,11 @@ export const useAction = <

const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return actionOperation(
action.operationName,
action.defaultSelection,
action.modelApiIdentifier,
action.modelSelectionField,
action.variables,
memoizedOptions,
action.namespace,
action.isBulk,
action.hasReturnType
);
if (action.plan) {
return action.plan(memoizedOptions);
} else {
throw new Error("Incompatible client passed to useAction hook, please use an api client with version >= 0.17.0")
}
}, [action, memoizedOptions]);

const [result, runMutation] = useGadgetMutation<
Expand Down
16 changes: 5 additions & 11 deletions packages/react/src/useBulkAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,11 @@ export const useBulkAction = <
> => {
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return actionOperation(
action.operationName,
action.defaultSelection,
action.modelApiIdentifier,
action.modelSelectionField,
action.variables,
memoizedOptions,
action.namespace,
action.isBulk,
action.hasReturnType
);
if (action.plan) {
return action.plan(memoizedOptions);
} else {
throw new Error("Incompatible client passed to useBulkAction hook, please use an api client with version >= 0.17.0")
}
}, [action, memoizedOptions]);

const [result, runMutation] = useGadgetMutation<
Expand Down
14 changes: 5 additions & 9 deletions packages/react/src/useFindBy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,11 @@ export const useFindBy = <
> => {
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return findOneByFieldOperation(
finder.operationName,
finder.findByVariableName,
value,
finder.defaultSelection,
finder.modelApiIdentifier,
memoizedOptions,
finder.namespace
);
if (finder.plan) {
return finder.plan(value, memoizedOptions)
} else {
throw new Error("Incompatible client passed to useFindBy hook, please use an api client with version >= 0.17.0")
}
}, [finder, value, memoizedOptions]);

const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, options));
Expand Down
21 changes: 9 additions & 12 deletions packages/react/src/useFindFirst.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DefaultSelection, FindFirstFunction, GadgetRecord, LimitToKnownKeys, Select } from "@gadgetinc/api-client-core";
import { findManyOperation, get, hydrateConnection, namespaceDataPath } from "@gadgetinc/api-client-core";
import { get, hydrateConnection, namespaceDataPath } from "@gadgetinc/api-client-core";
import { useMemo } from "react";
import { useGadgetQuery } from "./useGadgetQuery.js";
import { useStructuralMemo } from "./useStructuralMemo.js";
Expand Down Expand Up @@ -41,19 +41,16 @@ export const useFindFirst = <
): ReadHookResult<
GadgetRecord<Select<Exclude<F["schemaType"], null | undefined>, DefaultSelection<F["selectionType"], Options, F["defaultSelection"]>>>
> => {
const firstOptions = { ...options, first: 1 };
const memoizedOptions = useStructuralMemo(firstOptions);
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return findManyOperation(
manager.findFirst.operationName,
manager.findFirst.defaultSelection,
manager.findFirst.modelApiIdentifier,
memoizedOptions,
manager.findFirst.namespace
);
if (manager.findFirst.plan) {
return manager.findFirst.plan(memoizedOptions);
} else {
throw new Error("Incompatible client passed to useFindFirst hook, please use an api client with version >= 0.17.0")
}
}, [manager, memoizedOptions]);

const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, firstOptions));
const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, options));

const result = useMemo(() => {
const dataPath = namespaceDataPath([manager.findFirst.operationName], manager.findFirst.namespace);
Expand All @@ -70,7 +67,7 @@ export const useFindFirst = <
const error = ErrorWrapper.errorIfDataAbsent(rawResult, dataPath, options?.pause);

return { ...rawResult, data, error };
}, [manager.findFirst.operationName, options?.pause, rawResult]);
}, [manager.findFirst.namespace, manager.findFirst.operationName, options?.pause, rawResult]);

return [result, refresh];
};
12 changes: 5 additions & 7 deletions packages/react/src/useFindMany.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,11 @@ export const useFindMany = <
> => {
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return findManyOperation(
manager.findMany.operationName,
manager.findMany.defaultSelection,
manager.findMany.modelApiIdentifier,
memoizedOptions,
manager.findMany.namespace
);
if (manager.findMany.plan) {
return manager.findMany.plan(memoizedOptions);
} else {
throw new Error("Incompatible client passed to useFindMany hook, please use an api client with version >= 0.17.0")
}
}, [manager, memoizedOptions]);

const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, options));
Expand Down
17 changes: 7 additions & 10 deletions packages/react/src/useFindOne.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DefaultSelection, FindOneFunction, GadgetRecord, LimitToKnownKeys, Select } from "@gadgetinc/api-client-core";
import { findOneOperation, get, hydrateRecord, namespaceDataPath } from "@gadgetinc/api-client-core";
import { get, hydrateRecord, namespaceDataPath } from "@gadgetinc/api-client-core";
import { useMemo } from "react";
import { useGadgetQuery } from "./useGadgetQuery.js";
import { useStructuralMemo } from "./useStructuralMemo.js";
Expand Down Expand Up @@ -44,14 +44,11 @@ export const useFindOne = <
> => {
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return findOneOperation(
manager.findOne.operationName,
id,
manager.findOne.defaultSelection,
manager.findOne.modelApiIdentifier,
memoizedOptions,
manager.findOne.namespace
);
if (manager.findOne.plan) {
return manager.findOne.plan(id, memoizedOptions);
} else {
throw new Error("Incompatible client passed to useFindOne hook, please use an api client with version >= 0.17.0")
}
}, [manager, id, memoizedOptions]);

const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, options));
Expand All @@ -66,7 +63,7 @@ export const useFindOne = <
const error = ErrorWrapper.errorIfDataAbsent(rawResult, dataPath, options?.pause);

return { ...rawResult, data, error };
}, [manager.findOne.operationName, rawResult, options?.pause]);
}, [manager.findOne.operationName, manager.findOne.namespace, rawResult, options?.pause]);

return [result, refresh];
};
19 changes: 8 additions & 11 deletions packages/react/src/useMaybeFindFirst.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DefaultSelection, FindFirstFunction, GadgetRecord, LimitToKnownKeys, Select } from "@gadgetinc/api-client-core";
import { findManyOperation, get, hydrateConnection, namespaceDataPath } from "@gadgetinc/api-client-core";
import { get, hydrateConnection, namespaceDataPath } from "@gadgetinc/api-client-core";
import { useMemo } from "react";
import { useGadgetQuery } from "./useGadgetQuery.js";
import { useStructuralMemo } from "./useStructuralMemo.js";
Expand Down Expand Up @@ -41,19 +41,16 @@ export const useMaybeFindFirst = <
): ReadHookResult<null | GadgetRecord<
Select<Exclude<F["schemaType"], null | undefined>, DefaultSelection<F["selectionType"], Options, F["defaultSelection"]>>
>> => {
const firstOptions = { ...options, first: 1 };
const memoizedOptions = useStructuralMemo(firstOptions);
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return findManyOperation(
manager.findFirst.operationName,
manager.findFirst.defaultSelection,
manager.findFirst.modelApiIdentifier,
memoizedOptions,
manager.findFirst.namespace
);
if (manager.findFirst.plan) {
return manager.findFirst.plan(memoizedOptions);
} else {
throw new Error("Incompatible client passed to useMaybeFindFirst hook, please use an api client with version >= 0.17.0")
}
}, [manager, memoizedOptions]);

const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, firstOptions));
const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, memoizedOptions));

const result = useMemo(() => {
const dataPath = namespaceDataPath([manager.findFirst.operationName], manager.findFirst.namespace);
Expand Down
15 changes: 6 additions & 9 deletions packages/react/src/useMaybeFindOne.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { DefaultSelection, FindOneFunction, GadgetRecord, LimitToKnownKeys, Select } from "@gadgetinc/api-client-core";
import { findOneOperation, get, hydrateRecord, namespaceDataPath } from "@gadgetinc/api-client-core";
import { get, hydrateRecord, namespaceDataPath } from "@gadgetinc/api-client-core";
import { useMemo } from "react";
import { useGadgetQuery } from "./useGadgetQuery.js";
import { useStructuralMemo } from "./useStructuralMemo.js";
Expand Down Expand Up @@ -44,14 +44,11 @@ export const useMaybeFindOne = <
>> => {
const memoizedOptions = useStructuralMemo(options);
const plan = useMemo(() => {
return findOneOperation(
manager.findOne.operationName,
id,
manager.findOne.defaultSelection,
manager.findOne.modelApiIdentifier,
memoizedOptions,
manager.findOne.namespace
);
if (manager.findOne.plan) {
return manager.findOne.plan(id, memoizedOptions);
} else {
throw new Error("Incompatible client passed to useMaybeFindOne hook, please use an api client with version >= 0.17.0")
}
}, [manager, id, memoizedOptions]);

const [rawResult, refresh] = useGadgetQuery(useQueryArgs(plan, options));
Expand Down
Loading