summaryrefslogtreecommitdiff
path: root/frontend/src/lib/session.svelte.ts
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-17 14:32:37 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-17 14:32:37 +0800
commit5c0ba37eda80d39e6ceca59bb1d5f4942f858995 (patch)
tree948723f9cedf7ccb0707fa6ee516bd30fe20fd10 /frontend/src/lib/session.svelte.ts
downloadstrategy-lab-5c0ba37eda80d39e6ceca59bb1d5f4942f858995.tar.gz
chore: establish Strategy Lab source baseline (development, not release)
Diffstat (limited to 'frontend/src/lib/session.svelte.ts')
-rw-r--r--frontend/src/lib/session.svelte.ts45
1 files changed, 45 insertions, 0 deletions
diff --git a/frontend/src/lib/session.svelte.ts b/frontend/src/lib/session.svelte.ts
new file mode 100644
index 0000000..47b452f
--- /dev/null
+++ b/frontend/src/lib/session.svelte.ts
@@ -0,0 +1,45 @@
+import type { User } from './types';
+import { getMe } from './client';
+
+class SessionStore {
+ me = $state<User | null>(null);
+ status = $state<'loading' | 'anon' | 'authed'>('loading');
+
+ async refresh(): Promise<User | null> {
+ try {
+ const { user } = await getMe();
+ if (!user || typeof user.id !== 'string' || user.id.length === 0) {
+ this.clear();
+ return null;
+ }
+ this.me = user;
+ this.status = 'authed';
+ return user;
+ } catch (e) {
+ const status = (e as { status?: number }).status ?? 0;
+ if (status === 0) {
+ // network/protocol error: keep previous state so UI can show retry instead
+ if (this.status === 'loading') this.clear();
+ return null;
+ }
+ this.clear();
+ return null;
+ }
+ }
+
+ clear() {
+ this.me = null;
+ this.status = 'anon';
+ }
+
+ set(u: User | null) {
+ if (u && typeof u.id === 'string' && u.id.length > 0) {
+ this.me = u;
+ this.status = 'authed';
+ } else {
+ this.clear();
+ }
+ }
+}
+
+export const session: SessionStore = new SessionStore();