1import { setContext, getContext } from 'svelte';
2import type { ClientOptions } from '@urql/core';
3import { Client } from '@urql/core';
4
5const _contextKey = '$$_urql';
6
7/** Returns a provided {@link Client}.
8 *
9 * @remarks
10 * `getContextClient` returns the {@link Client} that’s previously
11 * been provided on Svelte’s context with {@link setContextClient}.
12 *
13 * This is useful to create a `Client` on Svelte’s context once, and
14 * then pass it to all GraphQL store functions without importing it
15 * from a singleton export.
16 *
17 * @throws
18 * In development, if `getContextClient` can’t get a {@link Client}
19 * from Svelte’s context, an error will be thrown.
20 */
21export const getContextClient = (): Client => {
22 const client = getContext(_contextKey);
23 if (process.env.NODE_ENV !== 'production' && !client) {
24 throw new Error(
25 'No urql Client was found in Svelte context. Did you forget to call setContextClient?'
26 );
27 }
28
29 return client as Client;
30};
31
32/** Provides a {@link Client} to a component’s children.
33 *
34 * @remarks
35 * `setContextClient` updates the Svelte context to provide
36 * a {@link Client} to be later retrieved using the
37 * {@link getContextClient} function.
38 */
39export const setContextClient = (client: Client): void => {
40 setContext(_contextKey, client);
41};
42
43/** Creates a {@link Client} and provides it to a component’s children.
44 *
45 * @param args - a {@link ClientOptions} object to create a `Client` with.
46 * @returns the created {@link Client}.
47 *
48 * @remarks
49 * `initContextClient` is a convenience wrapper around
50 * `setContextClient` that accepts {@link ClientOptions},
51 * creates a {@link Client} and provides it to be later
52 * retrieved using the {@link getContextClient} function.
53 */
54export const initContextClient = (args: ClientOptions): Client => {
55 const client = new Client(args);
56 setContextClient(client);
57 return client;
58};