aboutsummaryrefslogtreecommitdiff
path: root/src/lib/stores/apollo.ts
blob: 12463c334fca5e21d35bc8f885bd6dceb674b260 (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
63
64
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)
      );
    }
  );
};