aboutsummaryrefslogtreecommitdiff
path: root/src/lib/stores
diff options
context:
space:
mode:
authorRuben Beltran del Rio <ruben@unlimited.pizza>2022-05-31 01:04:10 +0200
committerRuben Beltran del Rio <ruben@unlimited.pizza>2022-05-31 01:04:10 +0200
commit852ee620f0a2f6a83cf83eba860ca951b66bb7e2 (patch)
tree3b1db871625c89f08c3c6422c135f84ec116943b /src/lib/stores
parentd2cd7f1b4c318ac8587ab3dc1dec4a44b6d592fe (diff)
Use supabase
Diffstat (limited to 'src/lib/stores')
-rw-r--r--src/lib/stores/apollo.ts62
-rw-r--r--src/lib/stores/forums.ts21
-rw-r--r--src/lib/stores/posts.ts24
-rw-r--r--src/lib/stores/response_builder.ts37
-rw-r--r--src/lib/stores/supabase.ts38
-rw-r--r--src/lib/stores/tags.ts13
-rw-r--r--src/lib/stores/topics.ts33
-rw-r--r--src/lib/stores/users.ts13
8 files changed, 162 insertions, 79 deletions
diff --git a/src/lib/stores/apollo.ts b/src/lib/stores/apollo.ts
deleted file mode 100644
index c75dd87..0000000
--- a/src/lib/stores/apollo.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-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].edges.map((item) => item.node),
- error: undefined
- });
- },
- (error: Error) => handleError(error)
- );
- });
-};
diff --git a/src/lib/stores/forums.ts b/src/lib/stores/forums.ts
index 0ff09f7..40a3f2c 100644
--- a/src/lib/stores/forums.ts
+++ b/src/lib/stores/forums.ts
@@ -1,9 +1,18 @@
-import { store } from './apollo';
-import { GET_FORUM, GET_FORUMS } from '$lib/data/queries';
+import { createClient } from '@supabase/supabase-js'
+import { single, collection } from './supabase';
+import { supabase } from '$lib/config/config';
import type { Forum } from '$lib/data/types';
-export const getForum = (id: string) =>
- store<Forum>({ key: 'forum', query: GET_FORUM, variables: { id } });
-export const getForums = () =>
- store<Forum[]>({ key: 'forumsCollection', query: GET_FORUMS, initialValue: [] });
+const client = createClient(supabase.url, supabase.key);
+
+export const forum = (id: string, withTopics = false) => single<Forum>(client
+ .from('forums')
+ .select(withTopics ? `*,
+ topics (
+ *
+ )
+ `: '*' )
+ .eq('id', id),
+ null);
+export const forums = collection<Forum>(client.from('forums').select('*'), []);
diff --git a/src/lib/stores/posts.ts b/src/lib/stores/posts.ts
index 718e1e5..f592dca 100644
--- a/src/lib/stores/posts.ts
+++ b/src/lib/stores/posts.ts
@@ -1,7 +1,23 @@
-import { store } from './apollo';
-import { GET_POST } from '$lib/data/queries';
+import { createClient } from '@supabase/supabase-js'
+import { single, collection } from './supabase';
+import { supabase } from '$lib/config/config';
import type { Post } from '$lib/data/types';
-export const getPost = (id: string) =>
- store<Post>({ key: 'post', query: GET_POST, variables: { id } });
+const client = createClient(supabase.url, supabase.key);
+
+export const post = (id: string, withTopic = false) => single<Post>(client
+ .from('posts')
+ .select(withTopic ? `*,
+ topic:topic_id (
+ *
+ )
+ `: '*' )
+ .eq('id', id),
+ null);
+export const postsForTopic = (id: string) => collection<Post>(client
+ .from('posts')
+ .select('*')
+ .eq('topic_id', id)
+ .order('created_at', { ascending: true }),
+ []);
diff --git a/src/lib/stores/response_builder.ts b/src/lib/stores/response_builder.ts
new file mode 100644
index 0000000..1e12243
--- /dev/null
+++ b/src/lib/stores/response_builder.ts
@@ -0,0 +1,37 @@
+/**
+ * Utilities to build responses
+ */
+
+interface AnyError {
+ message: string
+};
+
+export type StoreState<Type> = {
+ loading: boolean;
+ data: Type | void;
+ error: AnyError | void;
+};
+
+export function initialResponse<T> (initialState: T): StoreState<T> {
+ return {
+ loading: true,
+ data: initialState,
+ error: undefined
+ };
+}
+
+export function errorResponse<T> (error: AnyError): StoreState<T> {
+ return {
+ loading: false,
+ data: undefined,
+ error
+ };
+}
+
+export function response<T> (data: T): StoreState<T> {
+ return {
+ loading: false,
+ data,
+ error: undefined
+ };
+}
diff --git a/src/lib/stores/supabase.ts b/src/lib/stores/supabase.ts
new file mode 100644
index 0000000..804141f
--- /dev/null
+++ b/src/lib/stores/supabase.ts
@@ -0,0 +1,38 @@
+import { readable } from 'svelte/store';
+import { initialResponse, errorResponse, response } from './response_builder';
+
+import type { Readable } from 'svelte/store';
+import type { PostgrestFilterBuilder } from '@supabase/postgrest-js';
+import type { StoreState } from './response_builder';
+
+export function collection<T> (query: PostgrestFilterBuilder<T>, initialValue: T[]): Readable<StoreState<T[]>> {
+
+ return readable(initialResponse<T[]>(initialValue), (set) => {
+
+ (async function() {
+ const { data, error } = await query;
+
+ if (error) {
+ return set(errorResponse<T[]>(error));
+ }
+
+ set(response<T[]>(data));
+ })()
+ });
+}
+
+export function single<T> (query: PostgrestFilterBuilder<T>, initialValue: T): Readable<StoreState<T>> {
+
+ return readable(initialResponse<T>(initialValue), (set) => {
+
+ (async function() {
+ const { data, error } = await query.single();
+
+ if (error) {
+ return set(errorResponse<T>(error));
+ }
+
+ set(response<T>(data));
+ })()
+ });
+}
diff --git a/src/lib/stores/tags.ts b/src/lib/stores/tags.ts
index c96da2d..0b528e8 100644
--- a/src/lib/stores/tags.ts
+++ b/src/lib/stores/tags.ts
@@ -1,6 +1,13 @@
-import { store } from './apollo';
-import { GET_TAG } from '$lib/data/queries';
+import { createClient } from '@supabase/supabase-js'
+import { collection } from './supabase';
+import { supabase } from '$lib/config/config';
import type { Tag } from '$lib/data/types';
-export const getTag = (id: string) => store<Tag>({ key: 'tag', query: GET_TAG, variables: { id } });
+const client = createClient(supabase.url, supabase.key);
+
+export const tagsForTopic = (id: string) => collection<Tag>(client
+ .from('topic_tags')
+ .select('*')
+ .eq('topic_id', id),
+ []);
diff --git a/src/lib/stores/topics.ts b/src/lib/stores/topics.ts
index 0e39769..04c1e9e 100644
--- a/src/lib/stores/topics.ts
+++ b/src/lib/stores/topics.ts
@@ -1,7 +1,32 @@
-import { store } from './apollo';
-import { GET_TOPIC } from '$lib/data/queries';
+import { createClient } from '@supabase/supabase-js'
+import { single, collection } from './supabase';
+import { supabase } from '$lib/config/config';
import type { Topic } from '$lib/data/types';
-export const getTopic = (id: string) =>
- store<Topic>({ key: 'topic', query: GET_TOPIC, variables: { id } });
+const client = createClient(supabase.url, supabase.key);
+
+export const topic = (id: string, withPosts = false) => single<Topic>(client
+ .from('topics')
+ .select(withPosts ? `*,
+ forum: forums (*),
+ tags: topic_tags (*),
+ posts (
+ *,
+ author:author_id (*)
+ )
+ `: '*' )
+ .eq('id', id),
+ null);
+export const topicsForForum = (id: string) => collection<Topic>(client
+ .from('topics')
+ .select('*')
+ .eq('forum_id', id),
+ []);
+export const topicsForTag = (id: string) => collection<Topic>(client
+ .from('topics')
+ .select(`
+ *,tags!inner(*)
+ `)
+ .eq('tags.tag', id),
+ []);
diff --git a/src/lib/stores/users.ts b/src/lib/stores/users.ts
new file mode 100644
index 0000000..2a56cb5
--- /dev/null
+++ b/src/lib/stores/users.ts
@@ -0,0 +1,13 @@
+import { createClient } from '@supabase/supabase-js'
+import { single } from './supabase';
+import { supabase } from '$lib/config/config';
+
+import type { User } from '$lib/data/types';
+
+const client = createClient(supabase.url, supabase.key);
+
+export const user = (id: string) => single<User>(client
+ .from('users')
+ .select('*')
+ .eq('id', id),
+ null);