@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/CHANGELOG.md +1 -1
- package/README.md +27 -14
- package/dist/index.d.mts +45 -65
- package/dist/index.d.ts +45 -65
- package/dist/index.js +138 -135
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +111 -101
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +0 -7
- package/src/use-admin-auth.ts +62 -51
- package/src/use-auth.ts +66 -49
- package/src/use-realtime.ts +58 -44
- package/src/use-storage.ts +211 -82
- package/src/use-users.ts +11 -4
- package/typedoc.json +2 -4
- package/src/use-rpc.ts +0 -109
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
|
|
6
|
-
import { useFluxbaseClient } from
|
|
7
|
-
import type {
|
|
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: [
|
|
21
|
+
queryKey: ["fluxbase", "auth", "user"],
|
|
17
22
|
queryFn: async () => {
|
|
18
|
-
const
|
|
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
|
-
|
|
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: [
|
|
41
|
-
queryFn: () =>
|
|
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([
|
|
67
|
+
queryClient.setQueryData(["fluxbase", "auth", "session"], session);
|
|
59
68
|
// Only set user if this is a complete auth session (not 2FA required)
|
|
60
|
-
if (
|
|
61
|
-
queryClient.setQueryData([
|
|
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: (
|
|
79
|
-
|
|
80
|
-
|
|
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([
|
|
98
|
-
queryClient.setQueryData([
|
|
99
|
-
queryClient.invalidateQueries({ queryKey: [
|
|
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,
|
|
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([
|
|
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
|
}
|
package/src/use-realtime.ts
CHANGED
|
@@ -2,99 +2,113 @@
|
|
|
2
2
|
* Realtime subscription hooks for Fluxbase SDK
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { useEffect, useRef } from
|
|
6
|
-
import { useQueryClient } from
|
|
7
|
-
import { useFluxbaseClient } from
|
|
8
|
-
import type {
|
|
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?:
|
|
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>(
|
|
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:
|
|
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 || [
|
|
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
|
-
}, [
|
|
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,
|
|
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:
|
|
121
|
-
options?: Omit<UseRealtimeOptions,
|
|
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:
|
|
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:
|
|
137
|
-
options?: Omit<UseRealtimeOptions,
|
|
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:
|
|
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:
|
|
153
|
-
options?: Omit<UseRealtimeOptions,
|
|
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:
|
|
172
|
+
event: "DELETE",
|
|
159
173
|
callback,
|
|
160
|
-
})
|
|
174
|
+
});
|
|
161
175
|
}
|