jotai-query-toolkit
Version:
A toolkit for opinionated ways to use Jotai, react-query, and next.js
135 lines (121 loc) • 8.84 kB
TypeScript
import { NextPageContext, GetServerSidePropsContext, GetStaticPropsContext, NextPage, GetStaticProps, GetStaticPropsResult, GetServerSideProps, GetServerSidePropsResult } from 'next';
import * as react_query from 'react-query';
import { QueryClient, QueryKey } from 'react-query';
import { Atom } from 'jotai/core/atom';
import * as jotai from 'jotai';
import * as react from 'react';
import * as querystring from 'querystring';
declare type QueryPropsDefault = unknown | undefined;
declare type Fetcher<Data = unknown, QueryProps = QueryPropsDefault> = (ctx: NextPageContext | GetServerSidePropsContext | GetStaticPropsContext, queryProps?: QueryProps, queryClient?: QueryClient) => Promise<Data> | Data;
declare type GetQueryKey<QueryProps = QueryPropsDefault> = (ctx: NextPageContext | GetServerSidePropsContext | GetStaticPropsContext, queryProps?: QueryProps, queryClient?: QueryClient) => QueryKey | Promise<QueryKey | undefined> | undefined;
declare type Query<Data = unknown, QueryProps = QueryPropsDefault> = [
queryKey: GetQueryKey<QueryProps> | QueryKey | undefined,
fetcher: Fetcher<Data, QueryProps>
];
declare type Queries<QueryProps = QueryPropsDefault> = Readonly<Query<QueryProps>>[];
declare type GetQueries<QueryProps = QueryPropsDefault> = (ctx: NextPageContext | GetServerSidePropsContext | GetStaticPropsContext, queryProps?: QueryProps, queryClient?: QueryClient) => Queries<QueryProps> | Promise<Queries<QueryProps>> | null;
declare type QueryPropsGetter<QueryProps> = (context: NextPageContext | GetServerSidePropsContext | GetStaticPropsContext, queryClient: QueryClient) => QueryProps | Promise<QueryProps>;
interface GetInitialPropsFromQueriesOptions<QueryProps> {
getQueries: GetQueries<QueryProps> | Queries<QueryProps>;
ctx: NextPageContext | GetServerSidePropsContext | GetStaticPropsContext;
getQueryProps?: QueryPropsGetter<QueryProps>;
queryClient: QueryClient;
}
declare type InitialValuesAtomBuilder<Key = string> = [
propKey: Key,
atomBuilder: (propData: unknown) => readonly [Atom<unknown>, unknown]
];
declare type GetInitialProps<PageProps> = (context: NextPageContext) => PageProps | Promise<PageProps>;
declare function getInitialQueryProps<QueryProps = undefined, PageProps = any>(getQueries: Queries<QueryProps> | GetQueries<QueryProps>, getQueryProps?: QueryPropsGetter<QueryProps>): (getInitialProps?: GetInitialProps<PageProps> | undefined) => (ctx: NextPageContext) => Promise<PageProps>;
/**
* withInitialQueries
*
* This is a higher-order-component (HoC) that wraps a next.js page with queries that
* are then fetched on the server and injected into a Jotai Provider.
*
* @typeParam QueryProps - optional, these types are for the generic global query props that each query has access to
* @typeParam PageProps - the next.js page props
* @param WrappedComponent - The next.js page component to wrap
* @param initialValuesAtomBuilders - Optional values to add to our provider
* @param getInitialProps - Optional getInitialProps to be passed down to the wrapper
*/
declare function withInitialQueries<QueryProps = unknown, PageProps = Record<string, unknown>>(WrappedComponent: NextPage<PageProps>, initialValuesAtomBuilders?: InitialValuesAtomBuilder[], getInitialProps?: GetInitialProps<PageProps>): (getQueries?: Queries<QueryProps> | GetQueries<QueryProps> | undefined, getQueryProps?: QueryPropsGetter<QueryProps> | undefined) => NextPage<PageProps>;
declare const IS_SSR: boolean;
/**
* getInitialPropsFromQueries
*
* This is the main function that gives us a great developer and user experience when it comes to
* fetching data on the server and making use of it on the client via atom state.
*
* This method will either find an existing bit of data/state cached via react-query
* or it will fetch the data via the async fetcher provided to it.
*
* This is important because we only want to fetch our data in `getInitialProps` if there is no cached data.
*
*```typescript
* SomeNextPage.getInitialProps = async (context: NextPageContext) => {
* const queries = [[SomeEnum.SomeKey, async () => fetchData()]];
* const pageProps = await getInitialPropsFromQueries(queries);
*
* return pageProps
* }
* ```
* @param options - {@link GetInitialPropsFromQueriesOptions} the object of options for this method
* @return Returns an object of the hashed query keys and data result from the fetcher associated with it, to be consumed by {@see useQueryInitialValues}
*/
declare function getInitialPropsFromQueries<QueryProps = QueryPropsDefault>(options: GetInitialPropsFromQueriesOptions<QueryProps>): Promise<Record<string, any>>;
/**
* this function gets the QueryCache from our react-query queryClient
* and looks for a query that might already be cached and returns it
*
* @param queryKey - {@link QueryKey} the query key we're interested in
* @param queryClient - {@link QueryClient} the query client to check against
*/
declare function getSingleCachedQueryData<Data = unknown>(queryKey: QueryKey, queryClient: QueryClient): Data | undefined;
/**
* this function gets the QueryCache from our react-query queryClient
* and looks for any of the queries passed that might already be cached and returns thems
*
* @param queryKeys - {@link QueryKey} the query key we're interested in
* @param queryClient - {@link QueryClient} the query client to check against
*/
declare function getCachedQueryData(queryKeys: QueryKey[], queryClient: QueryClient): Record<string, any> | undefined;
/**
* Helper function to extract a query key's data from the response of {@link getInitialPropsFromQueries}
*
* @param queryKey - {@link QueryKey} the query key we're interested in
* @param queryArray - An object where each key is a hashed query key and the value is the data associated with it
*/
declare function getDataFromQueryArray<Data>(queryKey: QueryKey, queryArray: Record<string, unknown>): Data;
/**
* useQueryInitialValues
*
* This hook is made to be used on next.js pages only to provide the initial data for our query atoms.
* Note: This should only be used by advanced users, withInitialQueries makes use of this internally.
*
* ```typescript
* const queryKeys = [SomeEnum.SomeKey];
* const props = { '["SomeEnum.SomeKey"]": { foo: "bar' } }; // this will be autogenerated via {@link getInitialPropsFromQueries}`
* const initialValues = useQueryInitialValues(queryKeys, props);
* ```
*
* @param props - the data generated from {@link getInitialPropsFromQueries}, should not be created manually.
*/
declare function useQueryInitialValues(props?: Record<string, unknown>): Iterable<readonly [Atom<unknown>, unknown]>;
declare function buildInitialValueAtoms(props: Record<string, unknown>, atomBuilders: InitialValuesAtomBuilder[]): (readonly [jotai.Atom<unknown>, unknown])[];
declare const JqtDevtools: react.MemoExoticComponent<() => react.FunctionComponentElement<react_query.QueryClientProviderProps> | null>;
declare function getStaticQueryProps<QueryProps = undefined, PageProps = any>(getQueries: Queries<QueryProps> | GetQueries<QueryProps>, getQueryProps?: QueryPropsGetter<QueryProps>): (getStaticProps?: GetStaticProps<PageProps, querystring.ParsedUrlQuery> | undefined) => (ctx: GetStaticPropsContext) => Promise<GetStaticPropsResult<PageProps>>;
declare function getServerSideQueryProps<QueryProps = undefined, PageProps = any>(getQueries?: Queries<QueryProps> | GetQueries<QueryProps>, getQueryProps?: QueryPropsGetter<QueryProps>): (getServerSideProps?: GetServerSideProps<PageProps, querystring.ParsedUrlQuery> | undefined) => (ctx: GetServerSidePropsContext) => Promise<GetServerSidePropsResult<PageProps>>;
/**
* withInitialQueryData
*
* This is a higher-order-component (HoC) that wraps a next.js page with queries that
* are then fetched on the server and injected into a Jotai Provider.
*
* @typeParam QueryProps - optional, these types are for the generic global query props that each query has access to
* @typeParam PageProps - the next.js page props
* @param WrappedComponent - The next.js page component to wrap
* @param initialValuesAtomBuilders - Optional values to add to our provider
*/
declare function withInitialQueryData<QueryProps = unknown, PageProps = Record<string, unknown>>(WrappedComponent: NextPage<PageProps>, initialValuesAtomBuilders?: InitialValuesAtomBuilder[]): NextPage<PageProps, PageProps>;
export { Fetcher, GetInitialPropsFromQueriesOptions, GetQueries, GetQueryKey, IS_SSR, InitialValuesAtomBuilder, JqtDevtools, Queries, Query, QueryPropsDefault, QueryPropsGetter, buildInitialValueAtoms, getCachedQueryData, getDataFromQueryArray, getInitialPropsFromQueries, getInitialQueryProps, getServerSideQueryProps, getSingleCachedQueryData, getStaticQueryProps, useQueryInitialValues, withInitialQueries, withInitialQueryData };