]> git.r.bdr.sh - rbdr/forum/blobdiff - src/lib/stores/apollo.ts
Update / use typescript
[rbdr/forum] / src / lib / stores / apollo.ts
diff --git a/src/lib/stores/apollo.ts b/src/lib/stores/apollo.ts
new file mode 100644 (file)
index 0000000..12463c3
--- /dev/null
@@ -0,0 +1,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)
+      );
+    }
+  );
+};