sveltekit-supabase icon indicating copy to clipboard operation
sveltekit-supabase copied to clipboard

session store

Open david-plugge opened this issue 3 years ago • 0 comments
trafficstars

I just leave this here for now

/src/lib/helper.ts

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

export function dedupeDerived<T, R>(
	store: Readable<T>,
	fn: (data: T) => R = (data) => data as unknown as R
): Readable<R> {
	let value: R;
	return derived(store, (data, set) => {
		const newValue = fn(data);
		if (value !== newValue) {
			value = newValue;
			set(value);
		}
	});
}

/src/lib/stores.ts

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

// App.SupabaseSession = Session interface

export const session: Readable<App.SupabaseSession> = {
	subscribe(run, invalidate?) {
		const store = getContext<typeof session>('__SESSION__');
		return store.subscribe(run, invalidate);
	}
};

/src/routes/+layout.svelte

<script lang="ts">
	import { page } from '$app/stores';
	import { setContext } from 'svelte';
	import { dedupeDerived } from '$lib/helper';

    // we can´t use the imported session here
	const session = setContext(
		'__SESSION_',
		dedupeDerived(page, ($page) => $page.data.session)
	);
</script>

{#if $session.user}
	<a href="/account">Account</a>
{:else}
	<a href="/signin">Sign in</a>
{/if}

<slot />

/src/routes/+page.svelte

<script lang="ts">
	import { session } from '$lib/stores';
</script>

<pre>{JSON.stringify($session.user, null, 2)}</pre>

david-plugge avatar Sep 11 '22 12:09 david-plugge