From 97155aa8fa3d987b7fbc63ce4aa40065f9d83c22 Mon Sep 17 00:00:00 2001 From: IzumiSy Date: Mon, 6 Jan 2025 16:52:34 +0900 Subject: [PATCH] Abstract GQL client interface --- packages/fabrix/src/fetcher.ts | 29 -------- packages/fabrix/src/fetcher.tsx | 123 ++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+), 29 deletions(-) delete mode 100644 packages/fabrix/src/fetcher.ts create mode 100644 packages/fabrix/src/fetcher.tsx diff --git a/packages/fabrix/src/fetcher.ts b/packages/fabrix/src/fetcher.ts deleted file mode 100644 index 88a4ddce..00000000 --- a/packages/fabrix/src/fetcher.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { DocumentNode } from "graphql"; -import { useClient, useQuery } from "urql"; - -export const useDataFetch = (props: { - query: DocumentNode | string; - variables?: Record; -}) => { - const [{ data, fetching, error }] = useQuery({ - query: props.query, - variables: props.variables, - }); - - return { - fetching, - error, - data, - }; -}; - -export type Value = - | Record - | Array>; -export type FabrixComponentData = { - [key: string]: Value; -}; - -export const useFabrixClient = () => { - return useClient(); -}; diff --git a/packages/fabrix/src/fetcher.tsx b/packages/fabrix/src/fetcher.tsx new file mode 100644 index 00000000..3a391fd7 --- /dev/null +++ b/packages/fabrix/src/fetcher.tsx @@ -0,0 +1,123 @@ +import { addTypenameFieldExchange } from "@exchanges/addTypename"; +import { removeDirectivesExchange } from "@exchanges/removeDirectives"; +import { removeTypenameFromVariableExchange } from "@exchanges/removeTypenameFromVariable"; +import { Loader } from "@renderers/shared"; +import { DocumentNode } from "graphql"; +import { ReactNode } from "react"; +import { useClient, useQuery } from "urql"; +import { Client as UrqlClient, fetchExchange, cacheExchange } from "urql"; + +export const useDataFetch = (props: FetcherProps) => { + const [{ data, fetching, error }] = useQuery({ + query: props.query, + variables: props.variables, + }); + + return { + fetching, + error, + data, + }; +}; + +export type Value = + | Record + | Array>; +export type FabrixComponentData = { + [key: string]: Value; +}; + +export const useFabrixClient = () => { + return useClient(); +}; + +type FetcherProps = { + query: DocumentNode | string; + variables?: Record; +}; + +type FabrixRequestResult = { + data: FabrixComponentData | undefined; + error: Error | undefined; +}; + +interface FabrixClient { + getClient(): { + mutate: (props: FetcherProps) => Promise; + query: (props: FetcherProps) => Promise; + }; + + getFetcherComponent(): ( + props: FetcherProps & { + children: (props: { data: FabrixComponentData | undefined }) => ReactNode; + }, + ) => ReactNode; +} + +export class URQLClient implements FabrixClient { + private client: UrqlClient; + + constructor(private readonly url: string) { + this.client = new UrqlClient({ + url, + exchanges: [ + cacheExchange, + removeDirectivesExchange(["fabrixView", "fabrixList", "fabrixForm"]), + addTypenameFieldExchange, + removeTypenameFromVariableExchange, + fetchExchange, + ], + }); + } + + getClient() { + return { + mutate: async (props: FetcherProps) => { + const r = await this.client.mutation( + props.query, + props.variables, + ); + return { + data: r.data, + error: r.error, + }; + }, + + query: async (props: FetcherProps) => { + const r = await this.client.query( + props.query, + props.variables, + ); + return { + data: r.data, + error: r.error, + }; + }, + }; + } + + getFetcherComponent() { + return ( + props: FetcherProps & { + children: (props: { + data: FabrixComponentData | undefined; + }) => ReactNode; + }, + ) => { + const [{ data, fetching, error }] = useQuery({ + query: props.query, + variables: props.variables, + }); + + if (fetching || !data) { + return ; + } + + if (error) { + throw error; + } + + return props.children({ data }); + }; + } +}