]> git.r.bdr.sh - rbdr/forum/blob - src/lib/stores/apollo.ts
c75dd8723652313e43eee311b82ba3db8f64f445
[rbdr/forum] / src / lib / stores / apollo.ts
1 import { ApolloError } from '@apollo/client/core';
2 import { readable } from 'svelte/store';
3 import { client } from '$lib/config/apollo';
4 import type { DocumentNode, ApolloQueryResult } from '@apollo/client/core';
5
6 import type { Readable } from 'svelte/store';
7
8 /*
9 * This is a generic store for use with apollo
10 */
11
12 type ApolloStoreConfiguration<Type> = {
13 key: string;
14 query: DocumentNode;
15 initialValue?: Type | void;
16 variables?: object;
17 };
18
19 type ApolloStoreState<Type> = {
20 loading: boolean;
21 data: Type | void;
22 error: Error | void;
23 };
24
25 export const store = function store<Type>({
26 key,
27 query,
28 initialValue = null,
29 variables = {}
30 }: ApolloStoreConfiguration<Type>): Readable<ApolloStoreState<Type>> {
31 const initialState: ApolloStoreState<Type> = {
32 loading: true,
33 data: initialValue,
34 error: undefined
35 };
36
37 return readable(initialState, (set) => {
38 const handleError = function (error: Error) {
39 return set({
40 loading: false,
41 data: initialValue,
42 error
43 });
44 };
45
46 client.watchQuery({ query, variables }).subscribe(
47 (result: ApolloQueryResult<Type>) => {
48 if (result.errors) {
49 const error = new ApolloError({ graphQLErrors: result.errors });
50 return handleError(error);
51 }
52
53 set({
54 loading: false,
55 data: result.data[key].edges.map((item) => item.node),
56 error: undefined
57 });
58 },
59 (error: Error) => handleError(error)
60 );
61 });
62 };