fauxbase-react 0.4.0
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/dist/index.cjs +254 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +68 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.js +245 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
|
|
5
|
+
// src/context.ts
|
|
6
|
+
var FauxbaseContext = react.createContext(null);
|
|
7
|
+
function FauxbaseProvider(props) {
|
|
8
|
+
const registryRef = { current: /* @__PURE__ */ new Map() };
|
|
9
|
+
const value = {
|
|
10
|
+
client: props.client,
|
|
11
|
+
invalidate: (service) => {
|
|
12
|
+
const subscribers = registryRef.current.get(service);
|
|
13
|
+
if (subscribers) {
|
|
14
|
+
for (const fn of subscribers) {
|
|
15
|
+
fn();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
subscribe: (service, refetchFn) => {
|
|
20
|
+
if (!registryRef.current.has(service)) {
|
|
21
|
+
registryRef.current.set(service, /* @__PURE__ */ new Set());
|
|
22
|
+
}
|
|
23
|
+
registryRef.current.get(service).add(refetchFn);
|
|
24
|
+
return () => {
|
|
25
|
+
registryRef.current.get(service)?.delete(refetchFn);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
return react.createElement(FauxbaseContext.Provider, { value }, props.children);
|
|
30
|
+
}
|
|
31
|
+
function useFauxbaseContext() {
|
|
32
|
+
const ctx = react.useContext(FauxbaseContext);
|
|
33
|
+
if (!ctx) {
|
|
34
|
+
throw new Error("useFauxbaseContext must be used within a FauxbaseProvider");
|
|
35
|
+
}
|
|
36
|
+
return ctx;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/use-fauxbase.ts
|
|
40
|
+
function useFauxbase() {
|
|
41
|
+
const ctx = useFauxbaseContext();
|
|
42
|
+
return ctx.client;
|
|
43
|
+
}
|
|
44
|
+
function useList(service, query, options) {
|
|
45
|
+
const ctx = useFauxbaseContext();
|
|
46
|
+
const [items, setItems] = react.useState([]);
|
|
47
|
+
const [meta, setMeta] = react.useState(null);
|
|
48
|
+
const [loading, setLoading] = react.useState(true);
|
|
49
|
+
const [error, setError] = react.useState(null);
|
|
50
|
+
const mountedRef = react.useRef(true);
|
|
51
|
+
const enabled = options?.enabled !== false;
|
|
52
|
+
const fetch = react.useCallback(async () => {
|
|
53
|
+
if (!enabled) return;
|
|
54
|
+
setLoading(true);
|
|
55
|
+
setError(null);
|
|
56
|
+
try {
|
|
57
|
+
const result = await service.list(query);
|
|
58
|
+
if (mountedRef.current) {
|
|
59
|
+
setItems(result.items);
|
|
60
|
+
setMeta(result.meta);
|
|
61
|
+
}
|
|
62
|
+
} catch (err) {
|
|
63
|
+
if (mountedRef.current) {
|
|
64
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
65
|
+
}
|
|
66
|
+
} finally {
|
|
67
|
+
if (mountedRef.current) {
|
|
68
|
+
setLoading(false);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}, [service, JSON.stringify(query), enabled]);
|
|
72
|
+
react.useEffect(() => {
|
|
73
|
+
const unsub = ctx.subscribe(service, fetch);
|
|
74
|
+
return unsub;
|
|
75
|
+
}, [ctx, service, fetch]);
|
|
76
|
+
react.useEffect(() => {
|
|
77
|
+
mountedRef.current = true;
|
|
78
|
+
fetch();
|
|
79
|
+
return () => {
|
|
80
|
+
mountedRef.current = false;
|
|
81
|
+
};
|
|
82
|
+
}, [fetch]);
|
|
83
|
+
react.useEffect(() => {
|
|
84
|
+
if (!options?.refetchInterval || !enabled) return;
|
|
85
|
+
const id = setInterval(fetch, options.refetchInterval);
|
|
86
|
+
return () => clearInterval(id);
|
|
87
|
+
}, [fetch, options?.refetchInterval, enabled]);
|
|
88
|
+
return { items, meta, loading, error, refetch: fetch };
|
|
89
|
+
}
|
|
90
|
+
function useGet(service, id, options) {
|
|
91
|
+
const ctx = useFauxbaseContext();
|
|
92
|
+
const [data, setData] = react.useState(null);
|
|
93
|
+
const [loading, setLoading] = react.useState(true);
|
|
94
|
+
const [error, setError] = react.useState(null);
|
|
95
|
+
const mountedRef = react.useRef(true);
|
|
96
|
+
const enabled = options?.enabled !== false && id != null;
|
|
97
|
+
const fetch = react.useCallback(async () => {
|
|
98
|
+
if (!enabled || !id) {
|
|
99
|
+
setData(null);
|
|
100
|
+
setLoading(false);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
setLoading(true);
|
|
104
|
+
setError(null);
|
|
105
|
+
try {
|
|
106
|
+
const result = await service.get(id);
|
|
107
|
+
if (mountedRef.current) {
|
|
108
|
+
setData(result.data);
|
|
109
|
+
}
|
|
110
|
+
} catch (err) {
|
|
111
|
+
if (mountedRef.current) {
|
|
112
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
113
|
+
setData(null);
|
|
114
|
+
}
|
|
115
|
+
} finally {
|
|
116
|
+
if (mountedRef.current) {
|
|
117
|
+
setLoading(false);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}, [service, id, enabled]);
|
|
121
|
+
react.useEffect(() => {
|
|
122
|
+
const unsub = ctx.subscribe(service, fetch);
|
|
123
|
+
return unsub;
|
|
124
|
+
}, [ctx, service, fetch]);
|
|
125
|
+
react.useEffect(() => {
|
|
126
|
+
mountedRef.current = true;
|
|
127
|
+
fetch();
|
|
128
|
+
return () => {
|
|
129
|
+
mountedRef.current = false;
|
|
130
|
+
};
|
|
131
|
+
}, [fetch]);
|
|
132
|
+
return { data, loading, error, refetch: fetch };
|
|
133
|
+
}
|
|
134
|
+
function useMutation(service) {
|
|
135
|
+
const ctx = useFauxbaseContext();
|
|
136
|
+
const [loading, setLoading] = react.useState(false);
|
|
137
|
+
const [error, setError] = react.useState(null);
|
|
138
|
+
const create = react.useCallback(async (data) => {
|
|
139
|
+
setLoading(true);
|
|
140
|
+
setError(null);
|
|
141
|
+
try {
|
|
142
|
+
const result = await service.create(data);
|
|
143
|
+
ctx.invalidate(service);
|
|
144
|
+
return result.data;
|
|
145
|
+
} catch (err) {
|
|
146
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
147
|
+
setError(e);
|
|
148
|
+
throw e;
|
|
149
|
+
} finally {
|
|
150
|
+
setLoading(false);
|
|
151
|
+
}
|
|
152
|
+
}, [service, ctx]);
|
|
153
|
+
const update = react.useCallback(async (id, data) => {
|
|
154
|
+
setLoading(true);
|
|
155
|
+
setError(null);
|
|
156
|
+
try {
|
|
157
|
+
const result = await service.update(id, data);
|
|
158
|
+
ctx.invalidate(service);
|
|
159
|
+
return result.data;
|
|
160
|
+
} catch (err) {
|
|
161
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
162
|
+
setError(e);
|
|
163
|
+
throw e;
|
|
164
|
+
} finally {
|
|
165
|
+
setLoading(false);
|
|
166
|
+
}
|
|
167
|
+
}, [service, ctx]);
|
|
168
|
+
const remove = react.useCallback(async (id) => {
|
|
169
|
+
setLoading(true);
|
|
170
|
+
setError(null);
|
|
171
|
+
try {
|
|
172
|
+
const result = await service.delete(id);
|
|
173
|
+
ctx.invalidate(service);
|
|
174
|
+
return result.data;
|
|
175
|
+
} catch (err) {
|
|
176
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
177
|
+
setError(e);
|
|
178
|
+
throw e;
|
|
179
|
+
} finally {
|
|
180
|
+
setLoading(false);
|
|
181
|
+
}
|
|
182
|
+
}, [service, ctx]);
|
|
183
|
+
return { create, update, remove, loading, error };
|
|
184
|
+
}
|
|
185
|
+
function useAuth() {
|
|
186
|
+
const ctx = useFauxbaseContext();
|
|
187
|
+
const authService = ctx.client.auth;
|
|
188
|
+
if (!authService) {
|
|
189
|
+
throw new Error("useAuth requires auth to be configured in createClient");
|
|
190
|
+
}
|
|
191
|
+
const [, forceUpdate] = react.useState(0);
|
|
192
|
+
const [loading, setLoading] = react.useState(false);
|
|
193
|
+
const [error, setError] = react.useState(null);
|
|
194
|
+
const rerender = react.useCallback(() => forceUpdate((n) => n + 1), []);
|
|
195
|
+
const login = react.useCallback(async (credentials) => {
|
|
196
|
+
setLoading(true);
|
|
197
|
+
setError(null);
|
|
198
|
+
try {
|
|
199
|
+
const user = await authService.login(credentials);
|
|
200
|
+
rerender();
|
|
201
|
+
return user;
|
|
202
|
+
} catch (err) {
|
|
203
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
204
|
+
setError(e);
|
|
205
|
+
throw e;
|
|
206
|
+
} finally {
|
|
207
|
+
setLoading(false);
|
|
208
|
+
}
|
|
209
|
+
}, [authService, rerender]);
|
|
210
|
+
const register = react.useCallback(async (data) => {
|
|
211
|
+
setLoading(true);
|
|
212
|
+
setError(null);
|
|
213
|
+
try {
|
|
214
|
+
const user = await authService.register(data);
|
|
215
|
+
rerender();
|
|
216
|
+
return user;
|
|
217
|
+
} catch (err) {
|
|
218
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
219
|
+
setError(e);
|
|
220
|
+
throw e;
|
|
221
|
+
} finally {
|
|
222
|
+
setLoading(false);
|
|
223
|
+
}
|
|
224
|
+
}, [authService, rerender]);
|
|
225
|
+
const logout = react.useCallback(() => {
|
|
226
|
+
authService.logout();
|
|
227
|
+
rerender();
|
|
228
|
+
}, [authService, rerender]);
|
|
229
|
+
const hasRole = react.useCallback((role) => {
|
|
230
|
+
return authService.hasRole(role);
|
|
231
|
+
}, [authService]);
|
|
232
|
+
return {
|
|
233
|
+
user: authService.currentUser,
|
|
234
|
+
isLoggedIn: authService.isLoggedIn,
|
|
235
|
+
token: authService.token,
|
|
236
|
+
login,
|
|
237
|
+
register,
|
|
238
|
+
logout,
|
|
239
|
+
hasRole,
|
|
240
|
+
loading,
|
|
241
|
+
error
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
exports.FauxbaseContext = FauxbaseContext;
|
|
246
|
+
exports.FauxbaseProvider = FauxbaseProvider;
|
|
247
|
+
exports.useAuth = useAuth;
|
|
248
|
+
exports.useFauxbase = useFauxbase;
|
|
249
|
+
exports.useFauxbaseContext = useFauxbaseContext;
|
|
250
|
+
exports.useGet = useGet;
|
|
251
|
+
exports.useList = useList;
|
|
252
|
+
exports.useMutation = useMutation;
|
|
253
|
+
//# sourceMappingURL=index.cjs.map
|
|
254
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/use-fauxbase.ts","../src/use-list.ts","../src/use-get.ts","../src/use-mutation.ts","../src/use-auth.ts"],"names":["createContext","createElement","useContext","useState","useRef","useCallback","useEffect"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createContext, createElement, useContext } from 'react';\nimport type { Service } from 'fauxbase';\nimport type { FauxbaseContextValue } from './types';\n\n// --- Context ---\n\nexport const FauxbaseContext = createContext<FauxbaseContextValue | null>(null);\n\n// --- Provider ---\n\nexport function FauxbaseProvider(props: {\n client: any;\n children: React.ReactNode;\n}) {\n // Invalidation registry: Service → Set of refetch callbacks\n const registryRef = { current: new Map<Service<any>, Set<() => void>>() };\n\n const value: FauxbaseContextValue = {\n client: props.client,\n invalidate: (service: Service<any>) => {\n const subscribers = registryRef.current.get(service);\n if (subscribers) {\n for (const fn of subscribers) {\n fn();\n }\n }\n },\n subscribe: (service: Service<any>, refetchFn: () => void) => {\n if (!registryRef.current.has(service)) {\n registryRef.current.set(service, new Set());\n }\n registryRef.current.get(service)!.add(refetchFn);\n return () => {\n registryRef.current.get(service)?.delete(refetchFn);\n };\n },\n };\n\n return createElement(FauxbaseContext.Provider, { value }, props.children);\n}\n\n// --- Hook ---\n\nexport function useFauxbaseContext(): FauxbaseContextValue {\n const ctx = useContext(FauxbaseContext);\n if (!ctx) {\n throw new Error('useFauxbaseContext must be used within a FauxbaseProvider');\n }\n return ctx;\n}\n","import { useFauxbaseContext } from './context';\n\nexport function useFauxbase() {\n const ctx = useFauxbaseContext();\n return ctx.client;\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { Service, Entity, QueryParams, PageMeta } from 'fauxbase';\nimport type { UseListResult, UseListOptions } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useList<T extends Entity>(\n service: Service<T>,\n query?: QueryParams,\n options?: UseListOptions,\n): UseListResult<T> {\n const ctx = useFauxbaseContext();\n const [items, setItems] = useState<T[]>([]);\n const [meta, setMeta] = useState<PageMeta | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const enabled = options?.enabled !== false;\n\n const fetch = useCallback(async () => {\n if (!enabled) return;\n setLoading(true);\n setError(null);\n try {\n const result = await service.list(query);\n if (mountedRef.current) {\n setItems(result.items);\n setMeta(result.meta);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [service, JSON.stringify(query), enabled]);\n\n // Subscribe for invalidation\n useEffect(() => {\n const unsub = ctx.subscribe(service, fetch);\n return unsub;\n }, [ctx, service, fetch]);\n\n // Fetch on mount and query change\n useEffect(() => {\n mountedRef.current = true;\n fetch();\n return () => { mountedRef.current = false; };\n }, [fetch]);\n\n // Refetch interval\n useEffect(() => {\n if (!options?.refetchInterval || !enabled) return;\n const id = setInterval(fetch, options.refetchInterval);\n return () => clearInterval(id);\n }, [fetch, options?.refetchInterval, enabled]);\n\n return { items, meta, loading, error, refetch: fetch };\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { Service, Entity } from 'fauxbase';\nimport type { UseGetResult, UseGetOptions } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useGet<T extends Entity>(\n service: Service<T>,\n id: string | null | undefined,\n options?: UseGetOptions,\n): UseGetResult<T> {\n const ctx = useFauxbaseContext();\n const [data, setData] = useState<T | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const enabled = options?.enabled !== false && id != null;\n\n const fetch = useCallback(async () => {\n if (!enabled || !id) {\n setData(null);\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const result = await service.get(id);\n if (mountedRef.current) {\n setData(result.data);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setData(null);\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [service, id, enabled]);\n\n // Subscribe for invalidation\n useEffect(() => {\n const unsub = ctx.subscribe(service, fetch);\n return unsub;\n }, [ctx, service, fetch]);\n\n // Fetch on mount and id change\n useEffect(() => {\n mountedRef.current = true;\n fetch();\n return () => { mountedRef.current = false; };\n }, [fetch]);\n\n return { data, loading, error, refetch: fetch };\n}\n","import { useState, useCallback } from 'react';\nimport type { Service, Entity } from 'fauxbase';\nimport type { UseMutationResult } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useMutation<T extends Entity>(\n service: Service<T>,\n): UseMutationResult<T> {\n const ctx = useFauxbaseContext();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const create = useCallback(async (data: Partial<T>): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const result = await service.create(data);\n ctx.invalidate(service);\n return result.data;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [service, ctx]);\n\n const update = useCallback(async (id: string, data: Partial<T>): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const result = await service.update(id, data);\n ctx.invalidate(service);\n return result.data;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [service, ctx]);\n\n const remove = useCallback(async (id: string): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const result = await service.delete(id);\n ctx.invalidate(service);\n return result.data;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [service, ctx]);\n\n return { create, update, remove, loading, error };\n}\n","import { useState, useCallback } from 'react';\nimport type { Entity } from 'fauxbase';\nimport type { UseAuthResult } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useAuth<T extends Entity>(): UseAuthResult<T> {\n const ctx = useFauxbaseContext();\n const authService = ctx.client.auth;\n\n if (!authService) {\n throw new Error('useAuth requires auth to be configured in createClient');\n }\n\n const [, forceUpdate] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const rerender = useCallback(() => forceUpdate(n => n + 1), []);\n\n const login = useCallback(async (credentials: { email: string; password: string }): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const user = await authService.login(credentials);\n rerender();\n return user;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [authService, rerender]);\n\n const register = useCallback(async (data: Partial<T>): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const user = await authService.register(data);\n rerender();\n return user;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [authService, rerender]);\n\n const logout = useCallback(() => {\n authService.logout();\n rerender();\n }, [authService, rerender]);\n\n const hasRole = useCallback((role: string): boolean => {\n return authService.hasRole(role);\n }, [authService]);\n\n return {\n user: authService.currentUser as T | null,\n isLoggedIn: authService.isLoggedIn,\n token: authService.token,\n login,\n register,\n logout,\n hasRole,\n loading,\n error,\n };\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Service, PageMeta, Entity, QueryParams } from 'fauxbase';
|
|
3
|
+
|
|
4
|
+
interface UseListResult<T> {
|
|
5
|
+
items: T[];
|
|
6
|
+
meta: PageMeta | null;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
error: Error | null;
|
|
9
|
+
refetch: () => void;
|
|
10
|
+
}
|
|
11
|
+
interface UseGetResult<T> {
|
|
12
|
+
data: T | null;
|
|
13
|
+
loading: boolean;
|
|
14
|
+
error: Error | null;
|
|
15
|
+
refetch: () => void;
|
|
16
|
+
}
|
|
17
|
+
interface UseMutationResult<T> {
|
|
18
|
+
create: (data: Partial<T>) => Promise<T>;
|
|
19
|
+
update: (id: string, data: Partial<T>) => Promise<T>;
|
|
20
|
+
remove: (id: string) => Promise<T>;
|
|
21
|
+
loading: boolean;
|
|
22
|
+
error: Error | null;
|
|
23
|
+
}
|
|
24
|
+
interface UseAuthResult<T> {
|
|
25
|
+
user: T | null;
|
|
26
|
+
isLoggedIn: boolean;
|
|
27
|
+
token: string | null;
|
|
28
|
+
login: (credentials: {
|
|
29
|
+
email: string;
|
|
30
|
+
password: string;
|
|
31
|
+
}) => Promise<T>;
|
|
32
|
+
register: (data: Partial<T>) => Promise<T>;
|
|
33
|
+
logout: () => void;
|
|
34
|
+
hasRole: (role: string) => boolean;
|
|
35
|
+
loading: boolean;
|
|
36
|
+
error: Error | null;
|
|
37
|
+
}
|
|
38
|
+
interface UseListOptions {
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
refetchInterval?: number;
|
|
41
|
+
}
|
|
42
|
+
interface UseGetOptions {
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
}
|
|
45
|
+
interface FauxbaseContextValue {
|
|
46
|
+
client: any;
|
|
47
|
+
invalidate: (service: Service<any>) => void;
|
|
48
|
+
subscribe: (service: Service<any>, refetchFn: () => void) => () => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
declare const FauxbaseContext: react.Context<FauxbaseContextValue | null>;
|
|
52
|
+
declare function FauxbaseProvider(props: {
|
|
53
|
+
client: any;
|
|
54
|
+
children: React.ReactNode;
|
|
55
|
+
}): react.FunctionComponentElement<react.ProviderProps<FauxbaseContextValue | null>>;
|
|
56
|
+
declare function useFauxbaseContext(): FauxbaseContextValue;
|
|
57
|
+
|
|
58
|
+
declare function useFauxbase(): any;
|
|
59
|
+
|
|
60
|
+
declare function useList<T extends Entity>(service: Service<T>, query?: QueryParams, options?: UseListOptions): UseListResult<T>;
|
|
61
|
+
|
|
62
|
+
declare function useGet<T extends Entity>(service: Service<T>, id: string | null | undefined, options?: UseGetOptions): UseGetResult<T>;
|
|
63
|
+
|
|
64
|
+
declare function useMutation<T extends Entity>(service: Service<T>): UseMutationResult<T>;
|
|
65
|
+
|
|
66
|
+
declare function useAuth<T extends Entity>(): UseAuthResult<T>;
|
|
67
|
+
|
|
68
|
+
export { FauxbaseContext, type FauxbaseContextValue, FauxbaseProvider, type UseAuthResult, type UseGetOptions, type UseGetResult, type UseListOptions, type UseListResult, type UseMutationResult, useAuth, useFauxbase, useFauxbaseContext, useGet, useList, useMutation };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Service, PageMeta, Entity, QueryParams } from 'fauxbase';
|
|
3
|
+
|
|
4
|
+
interface UseListResult<T> {
|
|
5
|
+
items: T[];
|
|
6
|
+
meta: PageMeta | null;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
error: Error | null;
|
|
9
|
+
refetch: () => void;
|
|
10
|
+
}
|
|
11
|
+
interface UseGetResult<T> {
|
|
12
|
+
data: T | null;
|
|
13
|
+
loading: boolean;
|
|
14
|
+
error: Error | null;
|
|
15
|
+
refetch: () => void;
|
|
16
|
+
}
|
|
17
|
+
interface UseMutationResult<T> {
|
|
18
|
+
create: (data: Partial<T>) => Promise<T>;
|
|
19
|
+
update: (id: string, data: Partial<T>) => Promise<T>;
|
|
20
|
+
remove: (id: string) => Promise<T>;
|
|
21
|
+
loading: boolean;
|
|
22
|
+
error: Error | null;
|
|
23
|
+
}
|
|
24
|
+
interface UseAuthResult<T> {
|
|
25
|
+
user: T | null;
|
|
26
|
+
isLoggedIn: boolean;
|
|
27
|
+
token: string | null;
|
|
28
|
+
login: (credentials: {
|
|
29
|
+
email: string;
|
|
30
|
+
password: string;
|
|
31
|
+
}) => Promise<T>;
|
|
32
|
+
register: (data: Partial<T>) => Promise<T>;
|
|
33
|
+
logout: () => void;
|
|
34
|
+
hasRole: (role: string) => boolean;
|
|
35
|
+
loading: boolean;
|
|
36
|
+
error: Error | null;
|
|
37
|
+
}
|
|
38
|
+
interface UseListOptions {
|
|
39
|
+
enabled?: boolean;
|
|
40
|
+
refetchInterval?: number;
|
|
41
|
+
}
|
|
42
|
+
interface UseGetOptions {
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
}
|
|
45
|
+
interface FauxbaseContextValue {
|
|
46
|
+
client: any;
|
|
47
|
+
invalidate: (service: Service<any>) => void;
|
|
48
|
+
subscribe: (service: Service<any>, refetchFn: () => void) => () => void;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
declare const FauxbaseContext: react.Context<FauxbaseContextValue | null>;
|
|
52
|
+
declare function FauxbaseProvider(props: {
|
|
53
|
+
client: any;
|
|
54
|
+
children: React.ReactNode;
|
|
55
|
+
}): react.FunctionComponentElement<react.ProviderProps<FauxbaseContextValue | null>>;
|
|
56
|
+
declare function useFauxbaseContext(): FauxbaseContextValue;
|
|
57
|
+
|
|
58
|
+
declare function useFauxbase(): any;
|
|
59
|
+
|
|
60
|
+
declare function useList<T extends Entity>(service: Service<T>, query?: QueryParams, options?: UseListOptions): UseListResult<T>;
|
|
61
|
+
|
|
62
|
+
declare function useGet<T extends Entity>(service: Service<T>, id: string | null | undefined, options?: UseGetOptions): UseGetResult<T>;
|
|
63
|
+
|
|
64
|
+
declare function useMutation<T extends Entity>(service: Service<T>): UseMutationResult<T>;
|
|
65
|
+
|
|
66
|
+
declare function useAuth<T extends Entity>(): UseAuthResult<T>;
|
|
67
|
+
|
|
68
|
+
export { FauxbaseContext, type FauxbaseContextValue, FauxbaseProvider, type UseAuthResult, type UseGetOptions, type UseGetResult, type UseListOptions, type UseListResult, type UseMutationResult, useAuth, useFauxbase, useFauxbaseContext, useGet, useList, useMutation };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { createContext, createElement, useContext, useState, useRef, useCallback, useEffect } from 'react';
|
|
2
|
+
|
|
3
|
+
// src/context.ts
|
|
4
|
+
var FauxbaseContext = createContext(null);
|
|
5
|
+
function FauxbaseProvider(props) {
|
|
6
|
+
const registryRef = { current: /* @__PURE__ */ new Map() };
|
|
7
|
+
const value = {
|
|
8
|
+
client: props.client,
|
|
9
|
+
invalidate: (service) => {
|
|
10
|
+
const subscribers = registryRef.current.get(service);
|
|
11
|
+
if (subscribers) {
|
|
12
|
+
for (const fn of subscribers) {
|
|
13
|
+
fn();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
subscribe: (service, refetchFn) => {
|
|
18
|
+
if (!registryRef.current.has(service)) {
|
|
19
|
+
registryRef.current.set(service, /* @__PURE__ */ new Set());
|
|
20
|
+
}
|
|
21
|
+
registryRef.current.get(service).add(refetchFn);
|
|
22
|
+
return () => {
|
|
23
|
+
registryRef.current.get(service)?.delete(refetchFn);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return createElement(FauxbaseContext.Provider, { value }, props.children);
|
|
28
|
+
}
|
|
29
|
+
function useFauxbaseContext() {
|
|
30
|
+
const ctx = useContext(FauxbaseContext);
|
|
31
|
+
if (!ctx) {
|
|
32
|
+
throw new Error("useFauxbaseContext must be used within a FauxbaseProvider");
|
|
33
|
+
}
|
|
34
|
+
return ctx;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/use-fauxbase.ts
|
|
38
|
+
function useFauxbase() {
|
|
39
|
+
const ctx = useFauxbaseContext();
|
|
40
|
+
return ctx.client;
|
|
41
|
+
}
|
|
42
|
+
function useList(service, query, options) {
|
|
43
|
+
const ctx = useFauxbaseContext();
|
|
44
|
+
const [items, setItems] = useState([]);
|
|
45
|
+
const [meta, setMeta] = useState(null);
|
|
46
|
+
const [loading, setLoading] = useState(true);
|
|
47
|
+
const [error, setError] = useState(null);
|
|
48
|
+
const mountedRef = useRef(true);
|
|
49
|
+
const enabled = options?.enabled !== false;
|
|
50
|
+
const fetch = useCallback(async () => {
|
|
51
|
+
if (!enabled) return;
|
|
52
|
+
setLoading(true);
|
|
53
|
+
setError(null);
|
|
54
|
+
try {
|
|
55
|
+
const result = await service.list(query);
|
|
56
|
+
if (mountedRef.current) {
|
|
57
|
+
setItems(result.items);
|
|
58
|
+
setMeta(result.meta);
|
|
59
|
+
}
|
|
60
|
+
} catch (err) {
|
|
61
|
+
if (mountedRef.current) {
|
|
62
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
63
|
+
}
|
|
64
|
+
} finally {
|
|
65
|
+
if (mountedRef.current) {
|
|
66
|
+
setLoading(false);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}, [service, JSON.stringify(query), enabled]);
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const unsub = ctx.subscribe(service, fetch);
|
|
72
|
+
return unsub;
|
|
73
|
+
}, [ctx, service, fetch]);
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
mountedRef.current = true;
|
|
76
|
+
fetch();
|
|
77
|
+
return () => {
|
|
78
|
+
mountedRef.current = false;
|
|
79
|
+
};
|
|
80
|
+
}, [fetch]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (!options?.refetchInterval || !enabled) return;
|
|
83
|
+
const id = setInterval(fetch, options.refetchInterval);
|
|
84
|
+
return () => clearInterval(id);
|
|
85
|
+
}, [fetch, options?.refetchInterval, enabled]);
|
|
86
|
+
return { items, meta, loading, error, refetch: fetch };
|
|
87
|
+
}
|
|
88
|
+
function useGet(service, id, options) {
|
|
89
|
+
const ctx = useFauxbaseContext();
|
|
90
|
+
const [data, setData] = useState(null);
|
|
91
|
+
const [loading, setLoading] = useState(true);
|
|
92
|
+
const [error, setError] = useState(null);
|
|
93
|
+
const mountedRef = useRef(true);
|
|
94
|
+
const enabled = options?.enabled !== false && id != null;
|
|
95
|
+
const fetch = useCallback(async () => {
|
|
96
|
+
if (!enabled || !id) {
|
|
97
|
+
setData(null);
|
|
98
|
+
setLoading(false);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
setLoading(true);
|
|
102
|
+
setError(null);
|
|
103
|
+
try {
|
|
104
|
+
const result = await service.get(id);
|
|
105
|
+
if (mountedRef.current) {
|
|
106
|
+
setData(result.data);
|
|
107
|
+
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
if (mountedRef.current) {
|
|
110
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
111
|
+
setData(null);
|
|
112
|
+
}
|
|
113
|
+
} finally {
|
|
114
|
+
if (mountedRef.current) {
|
|
115
|
+
setLoading(false);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}, [service, id, enabled]);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
const unsub = ctx.subscribe(service, fetch);
|
|
121
|
+
return unsub;
|
|
122
|
+
}, [ctx, service, fetch]);
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
mountedRef.current = true;
|
|
125
|
+
fetch();
|
|
126
|
+
return () => {
|
|
127
|
+
mountedRef.current = false;
|
|
128
|
+
};
|
|
129
|
+
}, [fetch]);
|
|
130
|
+
return { data, loading, error, refetch: fetch };
|
|
131
|
+
}
|
|
132
|
+
function useMutation(service) {
|
|
133
|
+
const ctx = useFauxbaseContext();
|
|
134
|
+
const [loading, setLoading] = useState(false);
|
|
135
|
+
const [error, setError] = useState(null);
|
|
136
|
+
const create = useCallback(async (data) => {
|
|
137
|
+
setLoading(true);
|
|
138
|
+
setError(null);
|
|
139
|
+
try {
|
|
140
|
+
const result = await service.create(data);
|
|
141
|
+
ctx.invalidate(service);
|
|
142
|
+
return result.data;
|
|
143
|
+
} catch (err) {
|
|
144
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
145
|
+
setError(e);
|
|
146
|
+
throw e;
|
|
147
|
+
} finally {
|
|
148
|
+
setLoading(false);
|
|
149
|
+
}
|
|
150
|
+
}, [service, ctx]);
|
|
151
|
+
const update = useCallback(async (id, data) => {
|
|
152
|
+
setLoading(true);
|
|
153
|
+
setError(null);
|
|
154
|
+
try {
|
|
155
|
+
const result = await service.update(id, data);
|
|
156
|
+
ctx.invalidate(service);
|
|
157
|
+
return result.data;
|
|
158
|
+
} catch (err) {
|
|
159
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
160
|
+
setError(e);
|
|
161
|
+
throw e;
|
|
162
|
+
} finally {
|
|
163
|
+
setLoading(false);
|
|
164
|
+
}
|
|
165
|
+
}, [service, ctx]);
|
|
166
|
+
const remove = useCallback(async (id) => {
|
|
167
|
+
setLoading(true);
|
|
168
|
+
setError(null);
|
|
169
|
+
try {
|
|
170
|
+
const result = await service.delete(id);
|
|
171
|
+
ctx.invalidate(service);
|
|
172
|
+
return result.data;
|
|
173
|
+
} catch (err) {
|
|
174
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
175
|
+
setError(e);
|
|
176
|
+
throw e;
|
|
177
|
+
} finally {
|
|
178
|
+
setLoading(false);
|
|
179
|
+
}
|
|
180
|
+
}, [service, ctx]);
|
|
181
|
+
return { create, update, remove, loading, error };
|
|
182
|
+
}
|
|
183
|
+
function useAuth() {
|
|
184
|
+
const ctx = useFauxbaseContext();
|
|
185
|
+
const authService = ctx.client.auth;
|
|
186
|
+
if (!authService) {
|
|
187
|
+
throw new Error("useAuth requires auth to be configured in createClient");
|
|
188
|
+
}
|
|
189
|
+
const [, forceUpdate] = useState(0);
|
|
190
|
+
const [loading, setLoading] = useState(false);
|
|
191
|
+
const [error, setError] = useState(null);
|
|
192
|
+
const rerender = useCallback(() => forceUpdate((n) => n + 1), []);
|
|
193
|
+
const login = useCallback(async (credentials) => {
|
|
194
|
+
setLoading(true);
|
|
195
|
+
setError(null);
|
|
196
|
+
try {
|
|
197
|
+
const user = await authService.login(credentials);
|
|
198
|
+
rerender();
|
|
199
|
+
return user;
|
|
200
|
+
} catch (err) {
|
|
201
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
202
|
+
setError(e);
|
|
203
|
+
throw e;
|
|
204
|
+
} finally {
|
|
205
|
+
setLoading(false);
|
|
206
|
+
}
|
|
207
|
+
}, [authService, rerender]);
|
|
208
|
+
const register = useCallback(async (data) => {
|
|
209
|
+
setLoading(true);
|
|
210
|
+
setError(null);
|
|
211
|
+
try {
|
|
212
|
+
const user = await authService.register(data);
|
|
213
|
+
rerender();
|
|
214
|
+
return user;
|
|
215
|
+
} catch (err) {
|
|
216
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
217
|
+
setError(e);
|
|
218
|
+
throw e;
|
|
219
|
+
} finally {
|
|
220
|
+
setLoading(false);
|
|
221
|
+
}
|
|
222
|
+
}, [authService, rerender]);
|
|
223
|
+
const logout = useCallback(() => {
|
|
224
|
+
authService.logout();
|
|
225
|
+
rerender();
|
|
226
|
+
}, [authService, rerender]);
|
|
227
|
+
const hasRole = useCallback((role) => {
|
|
228
|
+
return authService.hasRole(role);
|
|
229
|
+
}, [authService]);
|
|
230
|
+
return {
|
|
231
|
+
user: authService.currentUser,
|
|
232
|
+
isLoggedIn: authService.isLoggedIn,
|
|
233
|
+
token: authService.token,
|
|
234
|
+
login,
|
|
235
|
+
register,
|
|
236
|
+
logout,
|
|
237
|
+
hasRole,
|
|
238
|
+
loading,
|
|
239
|
+
error
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
export { FauxbaseContext, FauxbaseProvider, useAuth, useFauxbase, useFauxbaseContext, useGet, useList, useMutation };
|
|
244
|
+
//# sourceMappingURL=index.js.map
|
|
245
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/context.ts","../src/use-fauxbase.ts","../src/use-list.ts","../src/use-get.ts","../src/use-mutation.ts","../src/use-auth.ts"],"names":["useState","useRef","useCallback","useEffect"],"mappings":"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","file":"index.js","sourcesContent":["import { createContext, createElement, useContext } from 'react';\nimport type { Service } from 'fauxbase';\nimport type { FauxbaseContextValue } from './types';\n\n// --- Context ---\n\nexport const FauxbaseContext = createContext<FauxbaseContextValue | null>(null);\n\n// --- Provider ---\n\nexport function FauxbaseProvider(props: {\n client: any;\n children: React.ReactNode;\n}) {\n // Invalidation registry: Service → Set of refetch callbacks\n const registryRef = { current: new Map<Service<any>, Set<() => void>>() };\n\n const value: FauxbaseContextValue = {\n client: props.client,\n invalidate: (service: Service<any>) => {\n const subscribers = registryRef.current.get(service);\n if (subscribers) {\n for (const fn of subscribers) {\n fn();\n }\n }\n },\n subscribe: (service: Service<any>, refetchFn: () => void) => {\n if (!registryRef.current.has(service)) {\n registryRef.current.set(service, new Set());\n }\n registryRef.current.get(service)!.add(refetchFn);\n return () => {\n registryRef.current.get(service)?.delete(refetchFn);\n };\n },\n };\n\n return createElement(FauxbaseContext.Provider, { value }, props.children);\n}\n\n// --- Hook ---\n\nexport function useFauxbaseContext(): FauxbaseContextValue {\n const ctx = useContext(FauxbaseContext);\n if (!ctx) {\n throw new Error('useFauxbaseContext must be used within a FauxbaseProvider');\n }\n return ctx;\n}\n","import { useFauxbaseContext } from './context';\n\nexport function useFauxbase() {\n const ctx = useFauxbaseContext();\n return ctx.client;\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { Service, Entity, QueryParams, PageMeta } from 'fauxbase';\nimport type { UseListResult, UseListOptions } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useList<T extends Entity>(\n service: Service<T>,\n query?: QueryParams,\n options?: UseListOptions,\n): UseListResult<T> {\n const ctx = useFauxbaseContext();\n const [items, setItems] = useState<T[]>([]);\n const [meta, setMeta] = useState<PageMeta | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const enabled = options?.enabled !== false;\n\n const fetch = useCallback(async () => {\n if (!enabled) return;\n setLoading(true);\n setError(null);\n try {\n const result = await service.list(query);\n if (mountedRef.current) {\n setItems(result.items);\n setMeta(result.meta);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [service, JSON.stringify(query), enabled]);\n\n // Subscribe for invalidation\n useEffect(() => {\n const unsub = ctx.subscribe(service, fetch);\n return unsub;\n }, [ctx, service, fetch]);\n\n // Fetch on mount and query change\n useEffect(() => {\n mountedRef.current = true;\n fetch();\n return () => { mountedRef.current = false; };\n }, [fetch]);\n\n // Refetch interval\n useEffect(() => {\n if (!options?.refetchInterval || !enabled) return;\n const id = setInterval(fetch, options.refetchInterval);\n return () => clearInterval(id);\n }, [fetch, options?.refetchInterval, enabled]);\n\n return { items, meta, loading, error, refetch: fetch };\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { Service, Entity } from 'fauxbase';\nimport type { UseGetResult, UseGetOptions } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useGet<T extends Entity>(\n service: Service<T>,\n id: string | null | undefined,\n options?: UseGetOptions,\n): UseGetResult<T> {\n const ctx = useFauxbaseContext();\n const [data, setData] = useState<T | null>(null);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n const mountedRef = useRef(true);\n\n const enabled = options?.enabled !== false && id != null;\n\n const fetch = useCallback(async () => {\n if (!enabled || !id) {\n setData(null);\n setLoading(false);\n return;\n }\n setLoading(true);\n setError(null);\n try {\n const result = await service.get(id);\n if (mountedRef.current) {\n setData(result.data);\n }\n } catch (err) {\n if (mountedRef.current) {\n setError(err instanceof Error ? err : new Error(String(err)));\n setData(null);\n }\n } finally {\n if (mountedRef.current) {\n setLoading(false);\n }\n }\n }, [service, id, enabled]);\n\n // Subscribe for invalidation\n useEffect(() => {\n const unsub = ctx.subscribe(service, fetch);\n return unsub;\n }, [ctx, service, fetch]);\n\n // Fetch on mount and id change\n useEffect(() => {\n mountedRef.current = true;\n fetch();\n return () => { mountedRef.current = false; };\n }, [fetch]);\n\n return { data, loading, error, refetch: fetch };\n}\n","import { useState, useCallback } from 'react';\nimport type { Service, Entity } from 'fauxbase';\nimport type { UseMutationResult } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useMutation<T extends Entity>(\n service: Service<T>,\n): UseMutationResult<T> {\n const ctx = useFauxbaseContext();\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const create = useCallback(async (data: Partial<T>): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const result = await service.create(data);\n ctx.invalidate(service);\n return result.data;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [service, ctx]);\n\n const update = useCallback(async (id: string, data: Partial<T>): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const result = await service.update(id, data);\n ctx.invalidate(service);\n return result.data;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [service, ctx]);\n\n const remove = useCallback(async (id: string): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const result = await service.delete(id);\n ctx.invalidate(service);\n return result.data;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [service, ctx]);\n\n return { create, update, remove, loading, error };\n}\n","import { useState, useCallback } from 'react';\nimport type { Entity } from 'fauxbase';\nimport type { UseAuthResult } from './types';\nimport { useFauxbaseContext } from './context';\n\nexport function useAuth<T extends Entity>(): UseAuthResult<T> {\n const ctx = useFauxbaseContext();\n const authService = ctx.client.auth;\n\n if (!authService) {\n throw new Error('useAuth requires auth to be configured in createClient');\n }\n\n const [, forceUpdate] = useState(0);\n const [loading, setLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n\n const rerender = useCallback(() => forceUpdate(n => n + 1), []);\n\n const login = useCallback(async (credentials: { email: string; password: string }): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const user = await authService.login(credentials);\n rerender();\n return user;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [authService, rerender]);\n\n const register = useCallback(async (data: Partial<T>): Promise<T> => {\n setLoading(true);\n setError(null);\n try {\n const user = await authService.register(data);\n rerender();\n return user;\n } catch (err) {\n const e = err instanceof Error ? err : new Error(String(err));\n setError(e);\n throw e;\n } finally {\n setLoading(false);\n }\n }, [authService, rerender]);\n\n const logout = useCallback(() => {\n authService.logout();\n rerender();\n }, [authService, rerender]);\n\n const hasRole = useCallback((role: string): boolean => {\n return authService.hasRole(role);\n }, [authService]);\n\n return {\n user: authService.currentUser as T | null,\n isLoggedIn: authService.isLoggedIn,\n token: authService.token,\n login,\n register,\n logout,\n hasRole,\n loading,\n error,\n };\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fauxbase-react",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.cjs",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": ["dist"],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsup",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"test:coverage": "vitest run --coverage",
|
|
21
|
+
"clean": "rm -rf dist"
|
|
22
|
+
},
|
|
23
|
+
"peerDependencies": {
|
|
24
|
+
"react": ">=18",
|
|
25
|
+
"fauxbase": ">=0.4.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"react": "^18.3.0",
|
|
29
|
+
"react-dom": "^18.3.0",
|
|
30
|
+
"@types/react": "^18.3.0",
|
|
31
|
+
"@types/react-dom": "^18.3.0",
|
|
32
|
+
"@testing-library/react": "^16.0.0",
|
|
33
|
+
"fauxbase": "workspace:*",
|
|
34
|
+
"jsdom": "^25.0.0",
|
|
35
|
+
"tsup": "^8.0.0",
|
|
36
|
+
"vitest": "^3.0.0",
|
|
37
|
+
"@vitest/coverage-v8": "^3.0.0",
|
|
38
|
+
"typescript": "^5.7.0"
|
|
39
|
+
}
|
|
40
|
+
}
|