1import type { Readable, Writable } from 'svelte/store';
2import type { AnyVariables, OperationResult } from '@urql/core';
3import type { Source } from 'wonka';
4import { make } from 'wonka';
5
6/** An {@link OperationResult} with an added {@link OperationResultState.fetching} flag.
7 *
8 * @remarks
9 * Stores will contain a readable state based on {@link OperationResult | OperationResults}
10 * they received.
11 */
12export interface OperationResultState<
13 Data = any,
14 Variables extends AnyVariables = AnyVariables,
15> extends OperationResult<Data, Variables> {
16 /** Indicates whether the store is waiting for a new {@link OperationResult}.
17 *
18 * @remarks
19 * When a store starts executing a GraphQL operation, `fetching` is
20 * set to `true` until a result arrives.
21 *
22 * Hint: This is subtly different than whether the operation is actually
23 * fetching, and doesn’t indicate whether an operation is being re-executed
24 * in the background. For this, see {@link OperationResult.stale}.
25 */
26 fetching: boolean;
27}
28
29/** A Readable store of {@link OperationResultState}. */
30export type OperationResultStore<
31 Data = any,
32 Variables extends AnyVariables = AnyVariables,
33> = Readable<OperationResultState<Data, Variables>>;
34
35/** Consumes a {@link Readable} as a {@link Source}.
36 * @internal
37 */
38export const fromStore = <T>(store$: Readable<T>): Source<T> =>
39 make(observer => store$.subscribe(observer.next));
40
41export const initialResult = {
42 operation: undefined,
43 fetching: false,
44 data: undefined,
45 error: undefined,
46 extensions: undefined,
47 hasNext: false,
48 stale: false,
49};
50
51/** A pausable Svelte store.
52 *
53 * @remarks
54 * The {@link queryStore} and {@link useSubscription} store allow
55 * you to pause execution and resume it later on, which is managed
56 * by a `pause` option passed to them.
57 *
58 * A `Pauseable` allows execution of GraphQL operations to be paused,
59 * which means a {@link OperationResultStore} won’t update with new
60 * results or execute new operations, and to be resumed later on.
61 */
62export interface Pausable {
63 /** Indicates whether a store is currently paused.
64 *
65 * @remarks
66 * When a {@link OperationResultStore} has been paused, it will stop
67 * receiving updates from the {@link Client} and won’t execute GraphQL
68 * operations, until this writable becomes `true` or
69 * {@link Pausable.resume} is called.
70 *
71 * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for
72 * documentation on the `Pausable`.
73 */
74 isPaused$: Writable<boolean>;
75 /** Pauses a GraphQL operation to stop it from executing.
76 *
77 * @remarks
78 * Pauses an {@link OperationResultStore}’s GraphQL operation, which
79 * stops it from receiving updates from the {@link Client} and to stop
80 * an ongoing operation.
81 *
82 * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for
83 * documentation on the `Pausable`.
84 */
85 pause(): void;
86 /** Resumes a paused GraphQL operation if it’s currently paused.
87 *
88 * @remarks
89 * Resumes or starts {@link OperationResultStore}’s GraphQL operation,
90 * if it’s currently paused.
91 *
92 * @see {@link https://urql.dev/goto/docs/basics/svelte#pausing-queries} for
93 * documentation on the `Pausable`.
94 */
95 resume(): void;
96}
97
98/** Creates a {@link Pausable}.
99 * @internal
100 */
101export const createPausable = (isPaused$: Writable<boolean>): Pausable => ({
102 isPaused$,
103 pause() {
104 isPaused$.set(true);
105 },
106 resume() {
107 isPaused$.set(false);
108 },
109});