graphql-persisted 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/errors.js ADDED
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertOperationHash = exports.ExpectedPreloadedQueryError = exports.MissingNormalizeMetaError = exports.UnknownOperationError = exports.MissingMetaError = exports.GraphQLQueryError = void 0;
4
+ class GraphQLQueryError extends Error {
5
+ }
6
+ exports.GraphQLQueryError = GraphQLQueryError;
7
+ /**
8
+ * Thrown in situations where we are expecting graphql-normalize metadata
9
+ * to be available, but it isn't yet available.
10
+ */
11
+ class MissingMetaError extends Error {
12
+ constructor(queryName) {
13
+ super(`Cannot readQuery('${queryName}') without graphql-normalize metadata.`);
14
+ }
15
+ }
16
+ exports.MissingMetaError = MissingMetaError;
17
+ class UnknownOperationError extends Error {
18
+ constructor(operationName, operationType) {
19
+ super(`Unknown ${operationType} operation ${operationName}, not found in the hash of operations`);
20
+ }
21
+ }
22
+ exports.UnknownOperationError = UnknownOperationError;
23
+ class MissingNormalizeMetaError extends Error {
24
+ constructor(operationName, operationType) {
25
+ super(`extensions.graphqlNormalizeMeta is was expected for the ${operationName} ${operationType}.\n You must configure your GraphQLQueryCache with the "meta" property, or add this as part of your repsonse payload`);
26
+ }
27
+ }
28
+ exports.MissingNormalizeMetaError = MissingNormalizeMetaError;
29
+ class ExpectedPreloadedQueryError extends GraphQLQueryError {
30
+ constructor(queryName) {
31
+ super(`Expected query ${queryName} to be preloaded with preloadQuery`);
32
+ }
33
+ }
34
+ exports.ExpectedPreloadedQueryError = ExpectedPreloadedQueryError;
35
+ function assertOperationHash(hash, operationType, operationName) {
36
+ if (!hash) {
37
+ throw new UnknownOperationError(operationName, operationType);
38
+ }
39
+ }
40
+ exports.assertOperationHash = assertOperationHash;
@@ -0,0 +1,12 @@
1
+ export type FragmentType<Frag extends keyof GraphQLQuery.FragmentRegistry> = GraphQLQuery.FragmentRegistry[Frag] extends infer FragType ? FragType extends {
2
+ ' $fragmentName'?: infer TKey;
3
+ } ? TKey extends string ? {
4
+ ' $fragmentRefs'?: {
5
+ [key in TKey]: FragType;
6
+ };
7
+ } : never : never : never;
8
+ export declare function unwrapFragment<Frag extends keyof GraphQLQuery.FragmentRegistry>(_fragmentName: Frag, fragmentType: FragmentType<Frag>): GraphQLQuery.FragmentRegistry[Frag];
9
+ export declare function unwrapFragment<Frag extends keyof GraphQLQuery.FragmentRegistry>(_fragmentName: Frag, fragmentType: FragmentType<Frag> | null | undefined): GraphQLQuery.FragmentRegistry[Frag] | null | undefined;
10
+ export declare function unwrapFragment<Frag extends keyof GraphQLQuery.FragmentRegistry>(_fragmentName: Frag, fragmentType: ReadonlyArray<FragmentType<Frag>>): ReadonlyArray<GraphQLQuery.FragmentRegistry[Frag]>;
11
+ export declare function unwrapFragment<Frag extends keyof GraphQLQuery.FragmentRegistry>(_fragmentName: Frag, fragmentType: ReadonlyArray<FragmentType<Frag>> | null | undefined): ReadonlyArray<GraphQLQuery.FragmentRegistry[Frag]> | null | undefined;
12
+ export declare function castFragmentData<F extends keyof GraphQLQuery.FragmentRegistry, FT extends GraphQLQuery.FragmentRegistry[F]>(_fragmentName: F, data: FT): FragmentType<F>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.castFragmentData = exports.unwrapFragment = void 0;
4
+ function unwrapFragment(_fragmentName, fragmentType) {
5
+ return fragmentType;
6
+ }
7
+ exports.unwrapFragment = unwrapFragment;
8
+ function castFragmentData(_fragmentName, data) {
9
+ return data;
10
+ }
11
+ exports.castFragmentData = castFragmentData;
@@ -0,0 +1,48 @@
1
+ import type { GraphQLPreloadedQueryResult, GraphQLQueryLazyResult, GraphQLQueryResult, ExecutionOptions, PersistedQueryOptions, QueryVariables, GraphQLMutationResult, ExecuteMutationOptions } from './types';
2
+ /**
3
+ * Loads a preloaded query. Like useQuery, except it throws if the
4
+ * query does not already exist in the cache.
5
+ *
6
+ * This hook keeps track of the value of the last render, so we're always guaranteed
7
+ * to have data here, even if it's potentially stale.
8
+ */
9
+ export declare const usePreloadedPersistedQuery: <QueryName extends never>(query: QueryName, options: PersistedQueryOptions & QueryVariables<QueryName>) => GraphQLPreloadedQueryResult<QueryName>;
10
+ /**
11
+ * Retrieves the persisted query from the cache,
12
+ * creating it from the cache if we don't have a mounted version
13
+ *
14
+ * Fetches the query if:
15
+ *
16
+ * 1. We don't already have the operation fetched in the cache
17
+ * 2. The query is considered stale based on:
18
+ * a) The TTL setting
19
+ * b) A mutation which invalidates the query
20
+ */
21
+ export declare const usePersistedQuery: <QueryName extends never>(queryName: QueryName, options: PersistedQueryOptions & QueryVariables<QueryName>) => GraphQLQueryResult<QueryName>;
22
+ /**
23
+ * TODO: Not working yet
24
+ * Creates a container for a query that isn't fetched immediately,
25
+ * but provides a loadQuery function to call
26
+ */
27
+ export declare const useLazyPersistedQuery: <QueryName extends never>(query: QueryName) => GraphQLQueryLazyResult<QueryName>;
28
+ /**
29
+ * Executes a persisted mutation, keeping track of mutations in-flight to ensure
30
+ * we don't execute the same mutation multiple times with the same values
31
+ * in the same component
32
+ */
33
+ export declare const usePersistedMutation: <MutationName extends never>(mutationName: MutationName, options?: ExecutionOptions) => {
34
+ execute: (vars: GraphQLQuery.OperationVariables[MutationName], opts?: ExecuteMutationOptions) => Promise<GraphQLMutationResult<MutationName>>;
35
+ isExecuting: boolean;
36
+ };
37
+ /**
38
+ * TODO: Subscription management
39
+ */
40
+ export declare const usePersistedSubscription: <SubscriptionName extends never>(subscriptionName: SubscriptionName) => never;
41
+ type UseOnMutationFn<M> = () => void;
42
+ /**
43
+ * Hook called when a mutation is issued, anywhere in the application.
44
+ * Useful for one-off situations where we want to subscribe and refetch something
45
+ * based on a mutation event
46
+ */
47
+ export declare const useOnMutation: <M extends "*">(mutation: M | M[], fn: UseOnMutationFn<M>) => void;
48
+ export {};
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useOnMutation = exports.usePersistedSubscription = exports.usePersistedMutation = exports.useLazyPersistedQuery = exports.usePersistedQuery = exports.usePreloadedPersistedQuery = void 0;
4
+ const context_1 = require("./context");
5
+ const react_1 = require("react");
6
+ const errors_1 = require("./errors");
7
+ const helpers_1 = require("./helpers");
8
+ /**
9
+ * Loads a preloaded query. Like useQuery, except it throws if the
10
+ * query does not already exist in the cache.
11
+ *
12
+ * This hook keeps track of the value of the last render, so we're always guaranteed
13
+ * to have data here, even if it's potentially stale.
14
+ */
15
+ const usePreloadedPersistedQuery = (query, options) => {
16
+ const result = (0, exports.usePersistedQuery)(query, options);
17
+ const lastData = (0, react_1.useRef)(result.data);
18
+ const data = result.data ?? lastData.current;
19
+ if (!data) {
20
+ throw new errors_1.ExpectedPreloadedQueryError(query);
21
+ }
22
+ (0, react_1.useEffect)(() => {
23
+ if (result.data) {
24
+ lastData.current = result.data;
25
+ }
26
+ }, [result.data]);
27
+ return { ...result, data };
28
+ };
29
+ exports.usePreloadedPersistedQuery = usePreloadedPersistedQuery;
30
+ /**
31
+ * Retrieves the persisted query from the cache,
32
+ * creating it from the cache if we don't have a mounted version
33
+ *
34
+ * Fetches the query if:
35
+ *
36
+ * 1. We don't already have the operation fetched in the cache
37
+ * 2. The query is considered stale based on:
38
+ * a) The TTL setting
39
+ * b) A mutation which invalidates the query
40
+ */
41
+ const usePersistedQuery = (queryName, options) => {
42
+ const cache = (0, context_1.useGraphQLQueryCache)();
43
+ const optionsRef = (0, react_1.useRef)(options);
44
+ // Ensure we always have the latest options in the optionsRef
45
+ (0, react_1.useEffect)(() => {
46
+ optionsRef.current = options;
47
+ });
48
+ // We need the variables stringified anyway to persist in the cache
49
+ // simplest to just stringify them here
50
+ const variableString = (0, react_1.useMemo)(() => (0, helpers_1.serializeVariables)(options.variables ?? {}), [options.variables]);
51
+ // Read the query result from the cache
52
+ const readQueryResult = (0, react_1.useMemo)(() => {
53
+ return cache.tryReadQuery({
54
+ queryName,
55
+ variables: variableString,
56
+ options: optionsRef.current,
57
+ });
58
+ }, [queryName, variableString, cache]);
59
+ const [queryResult, setQueryResult] = (0, react_1.useState)(readQueryResult);
60
+ (0, react_1.useEffect)(() => {
61
+ setQueryResult(readQueryResult);
62
+ }, [readQueryResult]);
63
+ // If we don't have the query on mount, we fetch it.
64
+ // We "subscribe" to the query so we'll receive
65
+ // updates when the query values change, it becomes stale,
66
+ // or it is refetched
67
+ (0, react_1.useEffect)(() => {
68
+ return cache.subscribeToQuery({
69
+ queryName,
70
+ variables: variableString,
71
+ onUpdate: setQueryResult,
72
+ options: optionsRef.current,
73
+ });
74
+ }, [queryName, cache, queryResult, variableString]);
75
+ return {
76
+ ...queryResult,
77
+ fetched: Boolean(queryResult),
78
+ }; // GraphQLQuery.QueryRegistry[QueryName];
79
+ };
80
+ exports.usePersistedQuery = usePersistedQuery;
81
+ /**
82
+ * TODO: Not working yet
83
+ * Creates a container for a query that isn't fetched immediately,
84
+ * but provides a loadQuery function to call
85
+ */
86
+ const useLazyPersistedQuery = (query) => {
87
+ const data = (0, react_1.useRef)(undefined);
88
+ const cache = (0, context_1.useGraphQLQueryCache)();
89
+ // const state = useState<'pending' | 'fetched' | 'loading' | 'stale'>('pending')
90
+ const [stale, setIsStale] = (0, react_1.useState)(false);
91
+ const [fetched, setIsFetched] = (0, react_1.useState)(false);
92
+ const [loading, setIsLoading] = (0, react_1.useState)(false);
93
+ const loadQuery = (0, react_1.useCallback)((variables) => {
94
+ return new Promise((resolve) => {
95
+ cache.readOrFetchQuery({ queryName: query, variables: (0, helpers_1.serializeVariables)(variables), options: {} });
96
+ });
97
+ }, [cache, query]);
98
+ const errors = undefined;
99
+ return {
100
+ data: data.current,
101
+ errors,
102
+ loadQuery,
103
+ loading,
104
+ stale,
105
+ fetched,
106
+ };
107
+ };
108
+ exports.useLazyPersistedQuery = useLazyPersistedQuery;
109
+ /**
110
+ * Executes a persisted mutation, keeping track of mutations in-flight to ensure
111
+ * we don't execute the same mutation multiple times with the same values
112
+ * in the same component
113
+ */
114
+ const usePersistedMutation = (mutationName, options) => {
115
+ const cache = (0, context_1.useGraphQLQueryCache)();
116
+ // Keeps track of whether we're executing the mutation or not, useful
117
+ // for showing loading states when we know the mutation is in-flight
118
+ const [isExecuting, setIsExecuting] = (0, react_1.useState)(0);
119
+ const executingRef = (0, react_1.useRef)(new Map());
120
+ const optionsRef = (0, react_1.useRef)(options);
121
+ (0, react_1.useEffect)(() => {
122
+ optionsRef.current = options;
123
+ });
124
+ const execute = (0, react_1.useCallback)(async (vars, opts = {}) => {
125
+ const { skipDedupeGuard = false } = opts;
126
+ setIsExecuting((v) => v + 1);
127
+ const inFlightVars = (0, helpers_1.serializeVariables)(vars);
128
+ const executing = executingRef.current.get(inFlightVars);
129
+ if (executing && !skipDedupeGuard) {
130
+ return executing;
131
+ }
132
+ const inFlight = cache.executeMutation(mutationName, vars, optionsRef.current).finally(() => {
133
+ if (!skipDedupeGuard) {
134
+ executingRef.current.delete(inFlightVars);
135
+ }
136
+ setIsExecuting((v) => v - 1);
137
+ });
138
+ if (!skipDedupeGuard) {
139
+ executingRef.current.set(inFlightVars, inFlight);
140
+ }
141
+ return inFlight;
142
+ }, [cache, mutationName]);
143
+ return {
144
+ execute,
145
+ isExecuting: Boolean(isExecuting > 0),
146
+ };
147
+ };
148
+ exports.usePersistedMutation = usePersistedMutation;
149
+ /**
150
+ * TODO: Subscription management
151
+ */
152
+ const usePersistedSubscription = (subscriptionName) => {
153
+ throw new Error(`usePersistedSubscription(${subscriptionName}) not yet supported`);
154
+ };
155
+ exports.usePersistedSubscription = usePersistedSubscription;
156
+ /**
157
+ * Hook called when a mutation is issued, anywhere in the application.
158
+ * Useful for one-off situations where we want to subscribe and refetch something
159
+ * based on a mutation event
160
+ */
161
+ const useOnMutation = (mutation, fn) => {
162
+ const fnRef = (0, react_1.useRef)(fn);
163
+ const cache = (0, context_1.useGraphQLQueryCache)();
164
+ (0, react_1.useEffect)(() => {
165
+ fnRef.current = fn;
166
+ });
167
+ const mutationDeps = Array.isArray(mutation) ? mutation : [mutation];
168
+ (0, react_1.useEffect)(() => {
169
+ return () => {
170
+ //
171
+ };
172
+ // eslint-disable-next-line react-hooks/exhaustive-deps
173
+ }, [cache, ...mutationDeps]);
174
+ };
175
+ exports.useOnMutation = useOnMutation;
@@ -0,0 +1,4 @@
1
+ import type { SerializedVariables } from './types';
2
+ export declare function serializeVariables(vars: object): SerializedVariables;
3
+ export declare function variableString(val: SerializedVariables | object): SerializedVariables;
4
+ export declare function variableObject(val: SerializedVariables | object): any;
package/cjs/helpers.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.variableObject = exports.variableString = exports.serializeVariables = void 0;
4
+ const graphql_normalize_1 = require("graphql-normalize");
5
+ function serializeVariables(vars) {
6
+ return (0, graphql_normalize_1.stringifyVariables)(vars);
7
+ }
8
+ exports.serializeVariables = serializeVariables;
9
+ function variableString(val) {
10
+ return typeof val === 'string' ? val : serializeVariables(val);
11
+ }
12
+ exports.variableString = variableString;
13
+ function variableObject(val) {
14
+ return typeof val === 'string' ? JSON.parse(val) : val;
15
+ }
16
+ exports.variableObject = variableObject;
package/cjs/index.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { usePersistedQuery, usePersistedMutation, usePreloadedPersistedQuery, useOnMutation, usePersistedSubscription, } from './graphqlHooks.js';
2
+ export { unwrapFragment, castFragmentData } from './fragmentData.js';
3
+ export type { FragmentType } from './fragmentData.js';
4
+ export { GraphQLQueryCache } from './GraphQLQueryCache.js';
5
+ export { useGraphQLQueryCache, GraphQLQueryProvider } from './context.js';
6
+ export type { GraphQLPreloadedQueryResult, GraphQLQueryResult, GraphQLQueryCacheConfig } from './types.js';
7
+ import type * as GraphQLQueryTypes from './types.js';
8
+ export type { GraphQLQueryTypes };
package/cjs/index.js ADDED
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GraphQLQueryProvider = exports.useGraphQLQueryCache = exports.GraphQLQueryCache = exports.castFragmentData = exports.unwrapFragment = exports.usePersistedSubscription = exports.useOnMutation = exports.usePreloadedPersistedQuery = exports.usePersistedMutation = exports.usePersistedQuery = void 0;
4
+ var graphqlHooks_js_1 = require("./graphqlHooks.js");
5
+ Object.defineProperty(exports, "usePersistedQuery", { enumerable: true, get: function () { return graphqlHooks_js_1.usePersistedQuery; } });
6
+ Object.defineProperty(exports, "usePersistedMutation", { enumerable: true, get: function () { return graphqlHooks_js_1.usePersistedMutation; } });
7
+ Object.defineProperty(exports, "usePreloadedPersistedQuery", { enumerable: true, get: function () { return graphqlHooks_js_1.usePreloadedPersistedQuery; } });
8
+ Object.defineProperty(exports, "useOnMutation", { enumerable: true, get: function () { return graphqlHooks_js_1.useOnMutation; } });
9
+ Object.defineProperty(exports, "usePersistedSubscription", { enumerable: true, get: function () { return graphqlHooks_js_1.usePersistedSubscription; } });
10
+ var fragmentData_js_1 = require("./fragmentData.js");
11
+ Object.defineProperty(exports, "unwrapFragment", { enumerable: true, get: function () { return fragmentData_js_1.unwrapFragment; } });
12
+ Object.defineProperty(exports, "castFragmentData", { enumerable: true, get: function () { return fragmentData_js_1.castFragmentData; } });
13
+ var GraphQLQueryCache_js_1 = require("./GraphQLQueryCache.js");
14
+ Object.defineProperty(exports, "GraphQLQueryCache", { enumerable: true, get: function () { return GraphQLQueryCache_js_1.GraphQLQueryCache; } });
15
+ var context_js_1 = require("./context.js");
16
+ Object.defineProperty(exports, "useGraphQLQueryCache", { enumerable: true, get: function () { return context_js_1.useGraphQLQueryCache; } });
17
+ Object.defineProperty(exports, "GraphQLQueryProvider", { enumerable: true, get: function () { return context_js_1.GraphQLQueryProvider; } });
package/cjs/types.d.ts ADDED
@@ -0,0 +1,205 @@
1
+ import type { NormalizeMetaShape } from 'graphql-normalize';
2
+ import type { FormattedExecutionResult, GraphQLFormattedError } from 'graphql';
3
+ import type { GraphQLQueryError } from './errors';
4
+ declare global {
5
+ namespace GraphQLQuery {
6
+ interface QueryRegistry {
7
+ }
8
+ interface MutationRegistry {
9
+ }
10
+ interface SubscriptionRegistry {
11
+ }
12
+ interface OperationVariables {
13
+ }
14
+ interface FragmentRegistry {
15
+ }
16
+ }
17
+ }
18
+ export interface GraphQLOperationStoreShape<TData = unknown> {
19
+ operationType: 'query' | 'mutation' | 'subscription';
20
+ operationName: string;
21
+ meta: NormalizeMetaShape;
22
+ data?: TData | null;
23
+ errors?: ReadonlyArray<GraphQLFormattedError>;
24
+ extensions?: Record<string, unknown>;
25
+ variableValues: object;
26
+ lastFetchedAt?: Date;
27
+ stale: boolean;
28
+ }
29
+ export interface GraphQLCacheShape {
30
+ /**
31
+ * Normalized representation of the values for fields across all operations
32
+ */
33
+ fields: Record<string, unknown>;
34
+ /**
35
+ * Mapping of the operations we've seen
36
+ */
37
+ operations: Record<string, GraphQLOperationStoreShape<any>>;
38
+ /**
39
+ * "OperationName:meta" mapping
40
+ */
41
+ meta: Record<string, NormalizeMetaShape>;
42
+ }
43
+ export interface GraphQLHydratedCacheShape extends GraphQLCacheShape {
44
+ hydrated: Record<string, Record<string, string>>;
45
+ }
46
+ export interface GraphQLQueryCacheConfig {
47
+ /**
48
+ * The endpoint of our GraphQL Application
49
+ * @default /graphql
50
+ */
51
+ endpoint?: string;
52
+ /**
53
+ * Allows providing our own implementation of "fetch"
54
+ */
55
+ fetcher?: typeof fetch;
56
+ /**
57
+ * If we're Server-Side Rendering this code, we can serialize
58
+ * the GraphQLQueryCache and send down with the client bundle,
59
+ * so clients are able to re-hydrate and skip refetching
60
+ */
61
+ hydratedCache?: GraphQLCacheShape;
62
+ /**
63
+ * A mapping of graphql-normalize metadata, if we decide to provide
64
+ * it rather than sending it down alongside the query
65
+ *
66
+ * https://github.com/tgriesser/graphql-normalize
67
+ */
68
+ meta?: Record<string, any>;
69
+ /**
70
+ * Mapping of Query Name to hash of the query to execute
71
+ */
72
+ persistedOperations: Record<string, string>;
73
+ /**
74
+ * Reverse mapping of hashes to documents, useful in development situations
75
+ * where we might not have the hashes persisted on the server yet
76
+ */
77
+ persistedDocuments?: Record<string, string>;
78
+ /**
79
+ * Rather than having a mutation keep track of the queries it needs to invalidate,
80
+ * the invalidateOnMutation can specify that this query becomes "invalidated" when,
81
+ * a mutation, or specific mutation occurs, meaning the next time it's mounted,
82
+ * it'll be refetched
83
+ */
84
+ queryInvalidation?: Partial<{
85
+ [Q in keyof GraphQLQuery.QueryRegistry]: QueryInvalidationFn<Q>;
86
+ }>;
87
+ /**
88
+ * When the mutation executes and returns, allows us to invalidate queries,
89
+ * meaning they will be marked as "stale" and will be lazily refetched
90
+ * on subsequent renders.
91
+ */
92
+ mutationInvalidation?: Partial<{
93
+ [M in keyof GraphQLQuery.MutationRegistry]: MutationInvalidationFn<M>;
94
+ }>;
95
+ /**
96
+ * When an error happens in the query layer, it will run through this error handler.
97
+ */
98
+ globalOnError?: (e: GraphQLQueryError) => void;
99
+ }
100
+ export type QueryInvalidationFn<Q extends keyof GraphQLQuery.QueryRegistry = keyof GraphQLQuery.QueryRegistry> = <M extends keyof GraphQLQuery.MutationRegistry>(mutationName: M, mutationVariables: GraphQLQuery.OperationVariables[M], queryVariables: GraphQLQuery.OperationVariables[Q]) => boolean;
101
+ export type MutationInvalidationFn<M extends keyof GraphQLQuery.MutationRegistry = keyof GraphQLQuery.MutationRegistry> = <Q extends keyof GraphQLQuery.QueryRegistry>(queryName: Q, queryVariables: GraphQLQuery.OperationVariables[Q], mutationVariables: GraphQLQuery.OperationVariables[M]) => boolean;
102
+ export interface FetchError {
103
+ name: string;
104
+ message: string;
105
+ stack?: string;
106
+ status?: number;
107
+ statusText?: string;
108
+ }
109
+ export interface GraphQLOperationResult<Result> extends FormattedExecutionResult<Result> {
110
+ fetchError?: FetchError;
111
+ }
112
+ export type GraphQLMutationResult<MutationName extends keyof GraphQLQuery.MutationRegistry> = GraphQLOperationResult<GraphQLQuery.MutationRegistry[MutationName]>;
113
+ export interface GraphQLQueryResult<QueryName extends keyof GraphQLQuery.QueryRegistry> extends GraphQLOperationResult<GraphQLQuery.QueryRegistry[QueryName]> {
114
+ fetched: boolean;
115
+ }
116
+ export interface GraphQLQueryLazyResult<QueryName extends keyof GraphQLQuery.QueryRegistry> extends GraphQLQueryResult<QueryName> {
117
+ stale: boolean;
118
+ loading: boolean;
119
+ loadQuery: (variables: GraphQLQuery.OperationVariables[QueryName]) => Promise<FormattedExecutionResult<GraphQLQuery.QueryRegistry[QueryName]>>;
120
+ }
121
+ export interface GraphQLPreloadedQueryResult<QueryName extends keyof GraphQLQuery.QueryRegistry> extends GraphQLQueryResult<QueryName> {
122
+ data: GraphQLQuery.QueryRegistry[QueryName];
123
+ }
124
+ export type MaybePromise<T> = T | Promise<T>;
125
+ export interface GraphQLRequestBody {
126
+ query?: string;
127
+ variables: any;
128
+ operationName?: string;
129
+ extensions?: Record<string, any>;
130
+ }
131
+ export interface ExecutionOptions {
132
+ onError?: (e: GraphQLQueryError) => void;
133
+ }
134
+ export type QueryVariables<QueryName extends keyof GraphQLQuery.QueryRegistry> = QueryName extends keyof GraphQLQuery.OperationVariables ? GraphQLQuery.OperationVariables[QueryName] extends {
135
+ [key: string]: never;
136
+ } ? {
137
+ variables?: unknown;
138
+ } : {
139
+ variables: GraphQLQuery.OperationVariables[QueryName];
140
+ } : never;
141
+ export interface PersistedQueryOptions extends ExecutionOptions {
142
+ /**
143
+ * TTL in milliseconds for the query, after this we'll mark the query
144
+ * as "stale" and revalidate
145
+ */
146
+ ttl?: number;
147
+ /**
148
+ * Poll interval to refetch the query, in milliseconds.
149
+ */
150
+ pollInterval?: number;
151
+ }
152
+ export interface ReadQueryArgs<Q extends keyof GraphQLQuery.QueryRegistry> {
153
+ /**
154
+ *
155
+ */
156
+ queryName: Q;
157
+ /**
158
+ *
159
+ */
160
+ variables: SerializedVariables | GraphQLQuery.OperationVariables[Q];
161
+ /**
162
+ *
163
+ */
164
+ options: PersistedQueryOptions;
165
+ }
166
+ export interface SubscribeToQueryArgs<Q extends keyof GraphQLQuery.QueryRegistry> extends ReadQueryArgs<Q> {
167
+ /**
168
+ * The result of readQuery, used to check whether the query is stale
169
+ */
170
+ queryResult?: GraphQLQuery.QueryRegistry[Q];
171
+ /**
172
+ * Invoked when the values for this query are updated
173
+ */
174
+ onUpdate: (nextVal: GraphQLOperationResult<Q>) => any;
175
+ }
176
+ export type InvalidateQueryArgs = keyof GraphQLQuery.QueryRegistry | Array<keyof GraphQLQuery.QueryRegistry>;
177
+ export type SerializedVariables = string & {
178
+ __brand: 'SerializedVariables';
179
+ };
180
+ export type MutationTuple = {
181
+ [K in keyof GraphQLQuery.MutationRegistry]: [K, GraphQLQuery.OperationVariables[K]];
182
+ }[keyof GraphQLQuery.MutationRegistry];
183
+ export type SubscriptionTuple = {
184
+ [K in keyof GraphQLQuery.SubscriptionRegistry]: [K, GraphQLQuery.OperationVariables[K]];
185
+ }[keyof GraphQLQuery.SubscriptionRegistry];
186
+ export interface ExecuteMutationOptions {
187
+ /**
188
+ * By default, we check to ensure the mutation isn't already in-flight with the
189
+ * same variables
190
+ */
191
+ skipDedupeGuard?: boolean;
192
+ }
193
+ export type PreloadQueryOptions<Q extends keyof GraphQLQuery.QueryRegistry = keyof GraphQLQuery.QueryRegistry> = {
194
+ /**
195
+ * If we have the operation, but we know it's stale, we'll typically refetch
196
+ * and return the promise for the refetch. if "blockIfStale" is false, we will
197
+ * resolve immediately and refetch in the background
198
+ *
199
+ * @default true
200
+ */
201
+ blockIfStale?: boolean;
202
+ } & QueryVariables<Q>;
203
+ export type HasVariables<V extends keyof GraphQLQuery.OperationVariables> = {
204
+ [K in keyof GraphQLQuery.OperationVariables[V]]: GraphQLQuery.OperationVariables[V][K];
205
+ }[keyof GraphQLQuery.OperationVariables[V]] extends never ? false : true;
package/cjs/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,62 @@
1
+ import type { GraphQLCacheShape, GraphQLMutationResult, GraphQLOperationResult, GraphQLQueryCacheConfig, GraphQLQueryResult, InvalidateQueryArgs, MaybePromise, ExecutionOptions, ReadQueryArgs, SerializedVariables, SubscribeToQueryArgs, PreloadQueryOptions } from './types';
2
+ /**
3
+ * Manages the cached normalized state, and the execution of
4
+ * data accessed by different components
5
+ */
6
+ export declare class GraphQLQueryCache {
7
+ #private;
8
+ constructor(config: GraphQLQueryCacheConfig);
9
+ /**
10
+ * Invalidates a query by name or predicate fn
11
+ */
12
+ invalidateQuery(toInvalidate: InvalidateQueryArgs): void;
13
+ /**
14
+ * Invalidates a query by name or predicate fn
15
+ */
16
+ refetchQuery(toRefetch: InvalidateQueryArgs): void;
17
+ /**
18
+ * JSON.stringify(queryCache) produces the data we need
19
+ * to rehydrate the Client
20
+ */
21
+ toJSON(): GraphQLCacheShape;
22
+ /**
23
+ * Attempts to read a query from the cache, returning undefined
24
+ * if we are unable to for any reason. Used in initial hook execution
25
+ * where we don't want any side-effects, incase we're doing SSR
26
+ */
27
+ tryReadQuery<Q extends keyof GraphQLQuery.QueryRegistry>(args: ReadQueryArgs<Q>): GraphQLOperationResult<Q> | undefined;
28
+ /**
29
+ * Reads the query from the cache. Throws an error if we are unable
30
+ * to read the data, due to an incomplete result or lack of operation
31
+ * metadata
32
+ */
33
+ readQuery<Q extends keyof GraphQLQuery.QueryRegistry>(args: ReadQueryArgs<Q>): GraphQLOperationResult<Q>;
34
+ /**
35
+ * Reads the query from the cache if any of the following conditions are met:
36
+ * a) We already have the result of this query in the operation cache
37
+ * b) We have the necessary metadata, as well as all of the necessary fields info to complete
38
+ * this query from the field cache
39
+ */
40
+ readOrFetchQuery<Q extends keyof GraphQLQuery.QueryRegistry>(args: ReadQueryArgs<Q>): GraphQLOperationResult<Q> | Promise<GraphQLOperationResult<Q>>;
41
+ /**
42
+ * Loads the query if it's not already in the cache,
43
+ * useful when hydrating the cache outside of a component
44
+ */
45
+ preloadQuery<Q extends keyof GraphQLQuery.QueryRegistry>(queryName: Q, options: PreloadQueryOptions<Q>): MaybePromise<GraphQLOperationResult<Q>>;
46
+ fetchQuery<Q extends keyof GraphQLQuery.QueryRegistry>(args: ReadQueryArgs<Q>): Promise<GraphQLOperationResult<Q>>;
47
+ /**
48
+ * Executes a mutation, returning the result of that mutation
49
+ */
50
+ executeMutation<M extends keyof GraphQLQuery.MutationRegistry>(mutationName: M, variables: SerializedVariables | object, options?: ExecutionOptions): Promise<GraphQLMutationResult<M>>;
51
+ /**
52
+ * Executes a query, returning the result of that query
53
+ */
54
+ executeQuery<Q extends keyof GraphQLQuery.QueryRegistry>(queryName: Q, variables: SerializedVariables | GraphQLQuery.OperationVariables[Q]): Promise<GraphQLQueryResult<Q>>;
55
+ executeSubscription(): Promise<void>;
56
+ /**
57
+ * "Subscribes" to a query, meaning that when there are updates to fields in the
58
+ * field cache, we'll re-materialize the known value of the query. We'll also
59
+ * process based on configuration options, such as TTL, invalidateOnMutation
60
+ */
61
+ subscribeToQuery<Q extends keyof GraphQLQuery.QueryRegistry>(args: SubscribeToQueryArgs<Q>): () => void;
62
+ }