@fluxbase/sdk-react 0.0.1-rc.6 → 0.0.1-rc.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/use-auth.ts CHANGED
@@ -2,132 +2,149 @@
2
2
  * Authentication hooks for Fluxbase SDK
3
3
  */
4
4
 
5
- import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
6
- import { useFluxbaseClient } from './context'
7
- import type { SignInCredentials, SignUpCredentials, User, AuthSession } from '@fluxbase/sdk'
5
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
6
+ import { useFluxbaseClient } from "./context";
7
+ import type {
8
+ SignInCredentials,
9
+ SignUpCredentials,
10
+ User,
11
+ AuthSession,
12
+ } from "@fluxbase/sdk";
8
13
 
9
14
  /**
10
15
  * Hook to get the current user
11
16
  */
12
17
  export function useUser() {
13
- const client = useFluxbaseClient()
18
+ const client = useFluxbaseClient();
14
19
 
15
20
  return useQuery({
16
- queryKey: ['fluxbase', 'auth', 'user'],
21
+ queryKey: ["fluxbase", "auth", "user"],
17
22
  queryFn: async () => {
18
- const session = client.auth.getSession()
19
- if (!session) {
20
- return null
23
+ const { data } = await client.auth.getSession();
24
+ if (!data?.session) {
25
+ return null;
21
26
  }
22
27
 
23
28
  try {
24
- return await client.auth.getCurrentUser()
29
+ const result = await client.auth.getCurrentUser();
30
+ return result.data?.user ?? null;
25
31
  } catch {
26
- return null
32
+ return null;
27
33
  }
28
34
  },
29
35
  staleTime: 1000 * 60 * 5, // 5 minutes
30
- })
36
+ });
31
37
  }
32
38
 
33
39
  /**
34
40
  * Hook to get the current session
35
41
  */
36
42
  export function useSession() {
37
- const client = useFluxbaseClient()
43
+ const client = useFluxbaseClient();
38
44
 
39
45
  return useQuery<AuthSession | null>({
40
- queryKey: ['fluxbase', 'auth', 'session'],
41
- queryFn: () => client.auth.getSession(),
46
+ queryKey: ["fluxbase", "auth", "session"],
47
+ queryFn: async () => {
48
+ const { data } = await client.auth.getSession();
49
+ return data?.session ?? null;
50
+ },
42
51
  staleTime: 1000 * 60 * 5, // 5 minutes
43
- })
52
+ });
44
53
  }
45
54
 
46
55
  /**
47
56
  * Hook for signing in
48
57
  */
49
58
  export function useSignIn() {
50
- const client = useFluxbaseClient()
51
- const queryClient = useQueryClient()
59
+ const client = useFluxbaseClient();
60
+ const queryClient = useQueryClient();
52
61
 
53
62
  return useMutation({
54
63
  mutationFn: async (credentials: SignInCredentials) => {
55
- return await client.auth.signIn(credentials)
64
+ return await client.auth.signIn(credentials);
56
65
  },
57
66
  onSuccess: (session) => {
58
- queryClient.setQueryData(['fluxbase', 'auth', 'session'], session)
67
+ queryClient.setQueryData(["fluxbase", "auth", "session"], session);
59
68
  // Only set user if this is a complete auth session (not 2FA required)
60
- if ('user' in session) {
61
- queryClient.setQueryData(['fluxbase', 'auth', 'user'], session.user)
69
+ if ("user" in session) {
70
+ queryClient.setQueryData(["fluxbase", "auth", "user"], session.user);
62
71
  }
63
72
  },
64
- })
73
+ });
65
74
  }
66
75
 
67
76
  /**
68
77
  * Hook for signing up
69
78
  */
70
79
  export function useSignUp() {
71
- const client = useFluxbaseClient()
72
- const queryClient = useQueryClient()
80
+ const client = useFluxbaseClient();
81
+ const queryClient = useQueryClient();
73
82
 
74
83
  return useMutation({
75
84
  mutationFn: async (credentials: SignUpCredentials) => {
76
- return await client.auth.signUp(credentials)
85
+ return await client.auth.signUp(credentials);
77
86
  },
78
- onSuccess: (session) => {
79
- queryClient.setQueryData(['fluxbase', 'auth', 'session'], session)
80
- queryClient.setQueryData(['fluxbase', 'auth', 'user'], session.user)
87
+ onSuccess: (response) => {
88
+ if (response.data) {
89
+ queryClient.setQueryData(
90
+ ["fluxbase", "auth", "session"],
91
+ response.data.session,
92
+ );
93
+ queryClient.setQueryData(
94
+ ["fluxbase", "auth", "user"],
95
+ response.data.user,
96
+ );
97
+ }
81
98
  },
82
- })
99
+ });
83
100
  }
84
101
 
85
102
  /**
86
103
  * Hook for signing out
87
104
  */
88
105
  export function useSignOut() {
89
- const client = useFluxbaseClient()
90
- const queryClient = useQueryClient()
106
+ const client = useFluxbaseClient();
107
+ const queryClient = useQueryClient();
91
108
 
92
109
  return useMutation({
93
110
  mutationFn: async () => {
94
- await client.auth.signOut()
111
+ await client.auth.signOut();
95
112
  },
96
113
  onSuccess: () => {
97
- queryClient.setQueryData(['fluxbase', 'auth', 'session'], null)
98
- queryClient.setQueryData(['fluxbase', 'auth', 'user'], null)
99
- queryClient.invalidateQueries({ queryKey: ['fluxbase'] })
114
+ queryClient.setQueryData(["fluxbase", "auth", "session"], null);
115
+ queryClient.setQueryData(["fluxbase", "auth", "user"], null);
116
+ queryClient.invalidateQueries({ queryKey: ["fluxbase"] });
100
117
  },
101
- })
118
+ });
102
119
  }
103
120
 
104
121
  /**
105
122
  * Hook for updating the current user
106
123
  */
107
124
  export function useUpdateUser() {
108
- const client = useFluxbaseClient()
109
- const queryClient = useQueryClient()
125
+ const client = useFluxbaseClient();
126
+ const queryClient = useQueryClient();
110
127
 
111
128
  return useMutation({
112
- mutationFn: async (data: Partial<Pick<User, 'email' | 'metadata'>>) => {
113
- return await client.auth.updateUser(data)
129
+ mutationFn: async (data: Partial<Pick<User, "email" | "metadata">>) => {
130
+ return await client.auth.updateUser(data);
114
131
  },
115
132
  onSuccess: (user) => {
116
- queryClient.setQueryData(['fluxbase', 'auth', 'user'], user)
133
+ queryClient.setQueryData(["fluxbase", "auth", "user"], user);
117
134
  },
118
- })
135
+ });
119
136
  }
120
137
 
121
138
  /**
122
139
  * Combined auth hook with all auth state and methods
123
140
  */
124
141
  export function useAuth() {
125
- const { data: user, isLoading: isLoadingUser } = useUser()
126
- const { data: session, isLoading: isLoadingSession } = useSession()
127
- const signIn = useSignIn()
128
- const signUp = useSignUp()
129
- const signOut = useSignOut()
130
- const updateUser = useUpdateUser()
142
+ const { data: user, isLoading: isLoadingUser } = useUser();
143
+ const { data: session, isLoading: isLoadingSession } = useSession();
144
+ const signIn = useSignIn();
145
+ const signUp = useSignUp();
146
+ const signOut = useSignOut();
147
+ const updateUser = useUpdateUser();
131
148
 
132
149
  return {
133
150
  user,
@@ -142,5 +159,5 @@ export function useAuth() {
142
159
  isSigningUp: signUp.isPending,
143
160
  isSigningOut: signOut.isPending,
144
161
  isUpdating: updateUser.isPending,
145
- }
162
+ };
146
163
  }
@@ -2,99 +2,113 @@
2
2
  * Realtime subscription hooks for Fluxbase SDK
3
3
  */
4
4
 
5
- import { useEffect, useRef } from 'react'
6
- import { useQueryClient } from '@tanstack/react-query'
7
- import { useFluxbaseClient } from './context'
8
- import type { RealtimeCallback, RealtimeChangePayload } from '@fluxbase/sdk'
5
+ import { useEffect, useRef } from "react";
6
+ import { useQueryClient } from "@tanstack/react-query";
7
+ import { useFluxbaseClient } from "./context";
8
+ import type {
9
+ RealtimeCallback,
10
+ RealtimePostgresChangesPayload,
11
+ } from "@fluxbase/sdk";
9
12
 
10
13
  export interface UseRealtimeOptions {
11
14
  /**
12
15
  * The channel name (e.g., 'table:public.products')
13
16
  */
14
- channel: string
17
+ channel: string;
15
18
 
16
19
  /**
17
20
  * Event type to listen for ('INSERT', 'UPDATE', 'DELETE', or '*' for all)
18
21
  */
19
- event?: 'INSERT' | 'UPDATE' | 'DELETE' | '*'
22
+ event?: "INSERT" | "UPDATE" | "DELETE" | "*";
20
23
 
21
24
  /**
22
25
  * Callback function when an event is received
23
26
  */
24
- callback?: RealtimeCallback
27
+ callback?: RealtimeCallback;
25
28
 
26
29
  /**
27
30
  * Whether to automatically invalidate queries for the table
28
31
  * Default: true
29
32
  */
30
- autoInvalidate?: boolean
33
+ autoInvalidate?: boolean;
31
34
 
32
35
  /**
33
36
  * Custom query key to invalidate (if autoInvalidate is true)
34
37
  * Default: ['fluxbase', 'table', tableName]
35
38
  */
36
- invalidateKey?: unknown[]
39
+ invalidateKey?: unknown[];
37
40
 
38
41
  /**
39
42
  * Whether the subscription is enabled
40
43
  * Default: true
41
44
  */
42
- enabled?: boolean
45
+ enabled?: boolean;
43
46
  }
44
47
 
45
48
  /**
46
49
  * Hook to subscribe to realtime changes for a channel
47
50
  */
48
51
  export function useRealtime(options: UseRealtimeOptions) {
49
- const client = useFluxbaseClient()
50
- const queryClient = useQueryClient()
51
- const channelRef = useRef<ReturnType<typeof client.realtime.channel> | null>(null)
52
+ const client = useFluxbaseClient();
53
+ const queryClient = useQueryClient();
54
+ const channelRef = useRef<ReturnType<typeof client.realtime.channel> | null>(
55
+ null,
56
+ );
52
57
 
53
58
  const {
54
59
  channel: channelName,
55
- event = '*',
60
+ event = "*",
56
61
  callback,
57
62
  autoInvalidate = true,
58
63
  invalidateKey,
59
64
  enabled = true,
60
- } = options
65
+ } = options;
61
66
 
62
67
  useEffect(() => {
63
68
  if (!enabled) {
64
- return
69
+ return;
65
70
  }
66
71
 
67
72
  // Create channel and subscribe
68
- const channel = client.realtime.channel(channelName)
69
- channelRef.current = channel
73
+ const channel = client.realtime.channel(channelName);
74
+ channelRef.current = channel;
70
75
 
71
- const handleChange = (payload: RealtimeChangePayload) => {
76
+ const handleChange = (payload: RealtimePostgresChangesPayload) => {
72
77
  // Call user callback
73
78
  if (callback) {
74
- callback(payload)
79
+ callback(payload);
75
80
  }
76
81
 
77
82
  // Auto-invalidate queries if enabled
78
83
  if (autoInvalidate) {
79
84
  // Extract table name from channel (e.g., 'table:public.products' -> 'public.products')
80
- const tableName = channelName.replace(/^table:/, '')
85
+ const tableName = channelName.replace(/^table:/, "");
81
86
 
82
- const key = invalidateKey || ['fluxbase', 'table', tableName]
83
- queryClient.invalidateQueries({ queryKey: key })
87
+ const key = invalidateKey || ["fluxbase", "table", tableName];
88
+ queryClient.invalidateQueries({ queryKey: key });
84
89
  }
85
- }
90
+ };
86
91
 
87
- channel.on(event, handleChange).subscribe()
92
+ channel.on(event, handleChange).subscribe();
88
93
 
89
94
  return () => {
90
- channel.unsubscribe()
91
- channelRef.current = null
92
- }
93
- }, [client, channelName, event, callback, autoInvalidate, invalidateKey, queryClient, enabled])
95
+ channel.unsubscribe();
96
+ channelRef.current = null;
97
+ };
98
+ }, [
99
+ client,
100
+ channelName,
101
+ event,
102
+ callback,
103
+ autoInvalidate,
104
+ invalidateKey,
105
+ queryClient,
106
+ enabled,
107
+ ]);
94
108
 
95
109
  return {
96
110
  channel: channelRef.current,
97
- }
111
+ };
98
112
  }
99
113
 
100
114
  /**
@@ -104,12 +118,12 @@ export function useRealtime(options: UseRealtimeOptions) {
104
118
  */
105
119
  export function useTableSubscription(
106
120
  table: string,
107
- options?: Omit<UseRealtimeOptions, 'channel'>
121
+ options?: Omit<UseRealtimeOptions, "channel">,
108
122
  ) {
109
123
  return useRealtime({
110
124
  ...options,
111
125
  channel: `table:${table}`,
112
- })
126
+ });
113
127
  }
114
128
 
115
129
  /**
@@ -117,15 +131,15 @@ export function useTableSubscription(
117
131
  */
118
132
  export function useTableInserts(
119
133
  table: string,
120
- callback: (payload: RealtimeChangePayload) => void,
121
- options?: Omit<UseRealtimeOptions, 'channel' | 'event' | 'callback'>
134
+ callback: (payload: RealtimePostgresChangesPayload) => void,
135
+ options?: Omit<UseRealtimeOptions, "channel" | "event" | "callback">,
122
136
  ) {
123
137
  return useRealtime({
124
138
  ...options,
125
139
  channel: `table:${table}`,
126
- event: 'INSERT',
140
+ event: "INSERT",
127
141
  callback,
128
- })
142
+ });
129
143
  }
130
144
 
131
145
  /**
@@ -133,15 +147,15 @@ export function useTableInserts(
133
147
  */
134
148
  export function useTableUpdates(
135
149
  table: string,
136
- callback: (payload: RealtimeChangePayload) => void,
137
- options?: Omit<UseRealtimeOptions, 'channel' | 'event' | 'callback'>
150
+ callback: (payload: RealtimePostgresChangesPayload) => void,
151
+ options?: Omit<UseRealtimeOptions, "channel" | "event" | "callback">,
138
152
  ) {
139
153
  return useRealtime({
140
154
  ...options,
141
155
  channel: `table:${table}`,
142
- event: 'UPDATE',
156
+ event: "UPDATE",
143
157
  callback,
144
- })
158
+ });
145
159
  }
146
160
 
147
161
  /**
@@ -149,13 +163,13 @@ export function useTableUpdates(
149
163
  */
150
164
  export function useTableDeletes(
151
165
  table: string,
152
- callback: (payload: RealtimeChangePayload) => void,
153
- options?: Omit<UseRealtimeOptions, 'channel' | 'event' | 'callback'>
166
+ callback: (payload: RealtimePostgresChangesPayload) => void,
167
+ options?: Omit<UseRealtimeOptions, "channel" | "event" | "callback">,
154
168
  ) {
155
169
  return useRealtime({
156
170
  ...options,
157
171
  channel: `table:${table}`,
158
- event: 'DELETE',
172
+ event: "DELETE",
159
173
  callback,
160
- })
174
+ });
161
175
  }