aboutsummaryrefslogtreecommitdiff
path: root/src/lib/stores/apollo.ts
blob: 4ef1986bec301e15b9bba6778734ad84b2bc61b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { ApolloError } from '@apollo/client/core';
import { readable } from 'svelte/store';
import { client } from '$lib/config/apollo';
import type { DocumentNode, ApolloQueryResult } from '@apollo/client/core';

import type { Readable } from 'svelte/store';

/*
 * This is a generic store for use with apollo
 */

type ApolloStoreConfiguration<Type> = {
	key: string;
	query: DocumentNode;
	initialValue?: Type | void;
	variables?: object;
};

type ApolloStoreState<Type> = {
	loading: boolean;
	data: Type | void;
	error: Error | void;
};

export const store = function store<Type>({
	key,
	query,
	initialValue = null,
	variables = {}
}: ApolloStoreConfiguration<Type>): Readable<ApolloStoreState<Type>> {
	const initialState: ApolloStoreState<Type> = {
		loading: true,
		data: initialValue,
		error: undefined
	};

	return readable(initialState, (set) => {
		const handleError = function (error: Error) {
			return set({
				loading: false,
				data: initialValue,
				error
			});
		};

		client.watchQuery({ query, variables }).subscribe(
			(result: ApolloQueryResult<Type>) => {
				if (result.errors) {
					const error = new ApolloError({ graphQLErrors: result.errors });
					return handleError(error);
				}

				set({
					loading: false,
					data: result.data[key],
					error: undefined
				});
			},
			(error: Error) => handleError(error)
		);
	});
};