@eventuras/fides-auth-react 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Losol AS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # @eventuras/fides-auth-react
2
+
3
+ React hooks for [`@eventuras/fides-auth`](../fides-auth) — thin bindings over the
4
+ framework-agnostic building blocks:
5
+
6
+ - **`createAuthStoreHooks(store)`** → `useAuthStore` / `useAuthActions` for an
7
+ [`@eventuras/fides-auth-store`](../fides-auth-store) auth store.
8
+ - **`useSessionMonitor(store, checkAuthStatus, config?)`** → runs
9
+ `startSessionMonitor` with `useEffect` cleanup.
10
+ - **`useHeartbeat(config?)`** → runs the `@eventuras/fides-auth` heartbeat engine
11
+ to keep the session alive for active users.
12
+
13
+ The heavy logic lives in the packages these wrap (the heartbeat engine in
14
+ `@eventuras/fides-auth`, the store and session monitor in
15
+ `@eventuras/fides-auth-store`); this package only adds the React lifecycle glue.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ pnpm add @eventuras/fides-auth-react
21
+ ```
22
+
23
+ `react`, `@xstate/store`, and `@xstate/store-react` are peer dependencies.
24
+
25
+ ## Usage
26
+
27
+ ```tsx
28
+ 'use client';
29
+ import {
30
+ createAuthStoreHooks,
31
+ useSessionMonitor,
32
+ useHeartbeat,
33
+ } from '@eventuras/fides-auth-react';
34
+ import { authStore, checkAuthStatus } from './auth';
35
+
36
+ export const { useAuthStore, useAuthActions } = createAuthStoreHooks(authStore);
37
+
38
+ export function AuthProvider({ children }: { children: React.ReactNode }) {
39
+ useSessionMonitor(authStore, checkAuthStatus);
40
+ useHeartbeat({
41
+ onSessionExpired: () => authStore.send({ type: 'sessionExpired' }),
42
+ });
43
+ return <>{children}</>;
44
+ }
45
+
46
+ function Profile() {
47
+ const auth = useAuthStore();
48
+ const { logout } = useAuthActions();
49
+ if (auth.isInitializing) return null;
50
+ return auth.isAuthenticated ? (
51
+ <button onClick={logout}>Log out {auth.user?.name}</button>
52
+ ) : (
53
+ <a href='/login'>Log in</a>
54
+ );
55
+ }
56
+ ```
@@ -0,0 +1,63 @@
1
+ import { SessionUser, createAuthStore } from '@eventuras/fides-auth-store';
2
+ /**
3
+ * Return type for store-based auth hooks
4
+ */
5
+ export type AuthStoreSelector = {
6
+ isAuthenticated: boolean;
7
+ isAdmin: boolean;
8
+ user: SessionUser | null;
9
+ error: string | null;
10
+ lastChecked: Date | null;
11
+ isInitializing: boolean;
12
+ };
13
+ /**
14
+ * Actions for store-based auth
15
+ */
16
+ export type AuthStoreActions = {
17
+ loginSuccess: (user: SessionUser) => void;
18
+ logout: () => void;
19
+ sessionExpired: () => void;
20
+ authSuccess: (user: SessionUser) => void;
21
+ authFailed: (error?: string) => void;
22
+ setError: (error: string) => void;
23
+ clearError: () => void;
24
+ };
25
+ /**
26
+ * Creates React hooks for interacting with the auth store
27
+ *
28
+ * @param store - The XState store instance
29
+ * @returns Object containing useAuthStore hook
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const authStore = createAuthStore({
34
+ * checkAuthStatus: getAuthStatus,
35
+ * });
36
+ *
37
+ * export const { useAuthStore } = createAuthStoreHooks(authStore);
38
+ *
39
+ * // In component
40
+ * function MyComponent() {
41
+ * const auth = useAuthStore();
42
+ *
43
+ * if (auth.error) {
44
+ * toast.error(auth.error);
45
+ * }
46
+ *
47
+ * if (auth.isInitializing) {
48
+ * return <Spinner />;
49
+ * }
50
+ *
51
+ * return (
52
+ * <div>
53
+ * {auth.isAuthenticated ? `Hello ${auth.user?.name}` : 'Please login'}
54
+ * </div>
55
+ * );
56
+ * }
57
+ * ```
58
+ */
59
+ export declare function createAuthStoreHooks(store: ReturnType<typeof createAuthStore>): {
60
+ useAuthStore: () => AuthStoreSelector;
61
+ useAuthActions: () => AuthStoreActions;
62
+ };
63
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEhF;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC1C,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IACzC,UAAU,EAAE,CAAC,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC;wBAInD,iBAAiB;0BAQf,gBAAgB;EAgB5C"}
package/dist/hooks.js ADDED
@@ -0,0 +1,78 @@
1
+ import { useSelector } from "@xstate/store-react";
2
+ //#region src/hooks.ts
3
+ /**
4
+ * Creates React hooks for interacting with the auth store
5
+ *
6
+ * @param store - The XState store instance
7
+ * @returns Object containing useAuthStore hook
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * const authStore = createAuthStore({
12
+ * checkAuthStatus: getAuthStatus,
13
+ * });
14
+ *
15
+ * export const { useAuthStore } = createAuthStoreHooks(authStore);
16
+ *
17
+ * // In component
18
+ * function MyComponent() {
19
+ * const auth = useAuthStore();
20
+ *
21
+ * if (auth.error) {
22
+ * toast.error(auth.error);
23
+ * }
24
+ *
25
+ * if (auth.isInitializing) {
26
+ * return <Spinner />;
27
+ * }
28
+ *
29
+ * return (
30
+ * <div>
31
+ * {auth.isAuthenticated ? `Hello ${auth.user?.name}` : 'Please login'}
32
+ * </div>
33
+ * );
34
+ * }
35
+ * ```
36
+ */
37
+ function createAuthStoreHooks(store) {
38
+ /**
39
+ * Hook to access the auth store state
40
+ */
41
+ function useAuthStore() {
42
+ return useSelector(store, (snapshot) => snapshot).context;
43
+ }
44
+ /**
45
+ * Hook to get auth store actions
46
+ */
47
+ function useAuthActions() {
48
+ return {
49
+ loginSuccess: (user) => store.send({
50
+ type: "loginSuccess",
51
+ user
52
+ }),
53
+ logout: () => store.send({ type: "logout" }),
54
+ sessionExpired: () => store.send({ type: "sessionExpired" }),
55
+ authSuccess: (user) => store.send({
56
+ type: "authSuccess",
57
+ user
58
+ }),
59
+ authFailed: (error) => store.send({
60
+ type: "authFailed",
61
+ error
62
+ }),
63
+ setError: (error) => store.send({
64
+ type: "setError",
65
+ error
66
+ }),
67
+ clearError: () => store.send({ type: "clearError" })
68
+ };
69
+ }
70
+ return {
71
+ useAuthStore,
72
+ useAuthActions
73
+ };
74
+ }
75
+ //#endregion
76
+ export { createAuthStoreHooks };
77
+
78
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["import { useSelector as useStoreSelector } from '@xstate/store-react';\nimport type { SessionUser, createAuthStore } from '@eventuras/fides-auth-store';\n\n/**\n * Return type for store-based auth hooks\n */\nexport type AuthStoreSelector = {\n isAuthenticated: boolean;\n isAdmin: boolean;\n user: SessionUser | null;\n error: string | null;\n lastChecked: Date | null;\n isInitializing: boolean;\n};\n\n/**\n * Actions for store-based auth\n */\nexport type AuthStoreActions = {\n loginSuccess: (user: SessionUser) => void;\n logout: () => void;\n sessionExpired: () => void;\n authSuccess: (user: SessionUser) => void;\n authFailed: (error?: string) => void;\n setError: (error: string) => void;\n clearError: () => void;\n};\n\n/**\n * Creates React hooks for interacting with the auth store\n *\n * @param store - The XState store instance\n * @returns Object containing useAuthStore hook\n *\n * @example\n * ```typescript\n * const authStore = createAuthStore({\n * checkAuthStatus: getAuthStatus,\n * });\n *\n * export const { useAuthStore } = createAuthStoreHooks(authStore);\n *\n * // In component\n * function MyComponent() {\n * const auth = useAuthStore();\n *\n * if (auth.error) {\n * toast.error(auth.error);\n * }\n *\n * if (auth.isInitializing) {\n * return <Spinner />;\n * }\n *\n * return (\n * <div>\n * {auth.isAuthenticated ? `Hello ${auth.user?.name}` : 'Please login'}\n * </div>\n * );\n * }\n * ```\n */\nexport function createAuthStoreHooks(store: ReturnType<typeof createAuthStore>) {\n /**\n * Hook to access the auth store state\n */\n function useAuthStore(): AuthStoreSelector {\n const snapshot = useStoreSelector(store, (snapshot) => snapshot);\n return snapshot.context;\n }\n\n /**\n * Hook to get auth store actions\n */\n function useAuthActions(): AuthStoreActions {\n return {\n loginSuccess: (user: SessionUser) => store.send({ type: 'loginSuccess', user }),\n logout: () => store.send({ type: 'logout' }),\n sessionExpired: () => store.send({ type: 'sessionExpired' }),\n authSuccess: (user: SessionUser) => store.send({ type: 'authSuccess', user }),\n authFailed: (error?: string) => store.send({ type: 'authFailed', error }),\n setError: (error: string) => store.send({ type: 'setError', error }),\n clearError: () => store.send({ type: 'clearError' }),\n };\n }\n\n return {\n useAuthStore,\n useAuthActions,\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,SAAgB,qBAAqB,OAA2C;;;;CAI9E,SAAS,eAAkC;EAEzC,OADiB,YAAiB,QAAQ,aAAa,QAChD,EAAS;CAClB;;;;CAKA,SAAS,iBAAmC;EAC1C,OAAO;GACL,eAAe,SAAsB,MAAM,KAAK;IAAE,MAAM;IAAgB;GAAK,CAAC;GAC9E,cAAc,MAAM,KAAK,EAAE,MAAM,SAAS,CAAC;GAC3C,sBAAsB,MAAM,KAAK,EAAE,MAAM,iBAAiB,CAAC;GAC3D,cAAc,SAAsB,MAAM,KAAK;IAAE,MAAM;IAAe;GAAK,CAAC;GAC5E,aAAa,UAAmB,MAAM,KAAK;IAAE,MAAM;IAAc;GAAM,CAAC;GACxE,WAAW,UAAkB,MAAM,KAAK;IAAE,MAAM;IAAY;GAAM,CAAC;GACnE,kBAAkB,MAAM,KAAK,EAAE,MAAM,aAAa,CAAC;EACrD;CACF;CAEA,OAAO;EACL;EACA;CACF;AACF"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * React bindings for @eventuras/fides-auth.
3
+ *
4
+ * Thin React hooks over the framework-agnostic building blocks:
5
+ * - {@link createAuthStoreHooks} — `useAuthStore` / `useAuthActions` over an
6
+ * `@eventuras/fides-auth-store` auth store.
7
+ * - {@link useSessionMonitor} — runs `startSessionMonitor` with `useEffect` cleanup.
8
+ * - {@link useHeartbeat} — runs the `@eventuras/fides-auth` heartbeat engine.
9
+ *
10
+ * Pair these with `@eventuras/fides-auth-store` (the store + status checks) and a
11
+ * server adapter such as `@eventuras/fides-auth-next` (cookies, route handlers).
12
+ *
13
+ * @example
14
+ * ```tsx
15
+ * 'use client';
16
+ * import { createAuthStoreHooks, useSessionMonitor, useHeartbeat } from '@eventuras/fides-auth-react';
17
+ * import { authStore, checkAuthStatus } from './auth';
18
+ *
19
+ * export const { useAuthStore, useAuthActions } = createAuthStoreHooks(authStore);
20
+ *
21
+ * export function AuthProvider({ children }: { children: React.ReactNode }) {
22
+ * useSessionMonitor(authStore, checkAuthStatus);
23
+ * useHeartbeat({ onSessionExpired: () => authStore.send({ type: 'sessionExpired' }) });
24
+ * return <>{children}</>;
25
+ * }
26
+ * ```
27
+ */
28
+ export { createAuthStoreHooks, type AuthStoreSelector, type AuthStoreActions, } from './hooks';
29
+ export { useSessionMonitor } from './use-session-monitor';
30
+ export { useHeartbeat, type HeartbeatConfig } from './use-heartbeat';
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ import { createAuthStoreHooks } from "./hooks.js";
2
+ import { useSessionMonitor } from "./use-session-monitor.js";
3
+ import { useHeartbeat } from "./use-heartbeat.js";
4
+ export { createAuthStoreHooks, useHeartbeat, useSessionMonitor };
@@ -0,0 +1,27 @@
1
+ import { HeartbeatConfig } from '@eventuras/fides-auth/heartbeat';
2
+ export type { HeartbeatConfig };
3
+ /**
4
+ * React wrapper around the framework-agnostic {@link createHeartbeat} engine.
5
+ *
6
+ * Starts the heartbeat on mount and stops it on unmount. Callbacks are read
7
+ * through a ref so changing their identity between renders does not restart the
8
+ * engine; the primitive options are the effect's dependencies.
9
+ *
10
+ * Intended to be paired with {@link useSessionMonitor}: the monitor *detects*
11
+ * session loss; this hook *prevents* it for active users. See
12
+ * {@link HeartbeatConfig} for the tuning knobs.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * 'use client';
17
+ * import { useHeartbeat, useSessionMonitor } from '@eventuras/fides-auth-react';
18
+ *
19
+ * function AuthProvider({ children }) {
20
+ * useSessionMonitor(authStore, checkAuthStatus);
21
+ * useHeartbeat({ onSessionExpired: () => authStore.send({ type: 'sessionExpired' }) });
22
+ * return <>{children}</>;
23
+ * }
24
+ * ```
25
+ */
26
+ export declare function useHeartbeat(config?: HeartbeatConfig): void;
27
+ //# sourceMappingURL=use-heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-heartbeat.d.ts","sourceRoot":"","sources":["../src/use-heartbeat.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAExF,YAAY,EAAE,eAAe,EAAE,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,eAAoB,GAAG,IAAI,CAsC/D"}
@@ -0,0 +1,58 @@
1
+ "use client";
2
+ import { useEffect, useRef } from "react";
3
+ import { createHeartbeat } from "@eventuras/fides-auth/heartbeat";
4
+ //#region src/use-heartbeat.ts
5
+ /**
6
+ * React wrapper around the framework-agnostic {@link createHeartbeat} engine.
7
+ *
8
+ * Starts the heartbeat on mount and stops it on unmount. Callbacks are read
9
+ * through a ref so changing their identity between renders does not restart the
10
+ * engine; the primitive options are the effect's dependencies.
11
+ *
12
+ * Intended to be paired with {@link useSessionMonitor}: the monitor *detects*
13
+ * session loss; this hook *prevents* it for active users. See
14
+ * {@link HeartbeatConfig} for the tuning knobs.
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * 'use client';
19
+ * import { useHeartbeat, useSessionMonitor } from '@eventuras/fides-auth-react';
20
+ *
21
+ * function AuthProvider({ children }) {
22
+ * useSessionMonitor(authStore, checkAuthStatus);
23
+ * useHeartbeat({ onSessionExpired: () => authStore.send({ type: 'sessionExpired' }) });
24
+ * return <>{children}</>;
25
+ * }
26
+ * ```
27
+ */
28
+ function useHeartbeat(config = {}) {
29
+ const { endpoint, fraction, minSkewMs, minRefreshIntervalMs, idleThresholdMs, initialExpiresAt, loggerNamespace } = config;
30
+ const callbacksRef = useRef(config);
31
+ callbacksRef.current = config;
32
+ useEffect(() => {
33
+ return createHeartbeat({
34
+ endpoint,
35
+ fraction,
36
+ minSkewMs,
37
+ minRefreshIntervalMs,
38
+ idleThresholdMs,
39
+ initialExpiresAt,
40
+ loggerNamespace,
41
+ onSessionExpired: () => callbacksRef.current.onSessionExpired?.(),
42
+ onRefreshed: () => callbacksRef.current.onRefreshed?.(),
43
+ onError: (error) => callbacksRef.current.onError?.(error)
44
+ }).stop;
45
+ }, [
46
+ endpoint,
47
+ fraction,
48
+ minSkewMs,
49
+ minRefreshIntervalMs,
50
+ idleThresholdMs,
51
+ initialExpiresAt,
52
+ loggerNamespace
53
+ ]);
54
+ }
55
+ //#endregion
56
+ export { useHeartbeat };
57
+
58
+ //# sourceMappingURL=use-heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-heartbeat.js","names":[],"sources":["../src/use-heartbeat.ts"],"sourcesContent":["'use client';\n\nimport { useEffect, useRef } from 'react';\nimport { createHeartbeat, type HeartbeatConfig } from '@eventuras/fides-auth/heartbeat';\n\nexport type { HeartbeatConfig };\n\n/**\n * React wrapper around the framework-agnostic {@link createHeartbeat} engine.\n *\n * Starts the heartbeat on mount and stops it on unmount. Callbacks are read\n * through a ref so changing their identity between renders does not restart the\n * engine; the primitive options are the effect's dependencies.\n *\n * Intended to be paired with {@link useSessionMonitor}: the monitor *detects*\n * session loss; this hook *prevents* it for active users. See\n * {@link HeartbeatConfig} for the tuning knobs.\n *\n * @example\n * ```tsx\n * 'use client';\n * import { useHeartbeat, useSessionMonitor } from '@eventuras/fides-auth-react';\n *\n * function AuthProvider({ children }) {\n * useSessionMonitor(authStore, checkAuthStatus);\n * useHeartbeat({ onSessionExpired: () => authStore.send({ type: 'sessionExpired' }) });\n * return <>{children}</>;\n * }\n * ```\n */\nexport function useHeartbeat(config: HeartbeatConfig = {}): void {\n const {\n endpoint,\n fraction,\n minSkewMs,\n minRefreshIntervalMs,\n idleThresholdMs,\n initialExpiresAt,\n loggerNamespace,\n } = config;\n\n // Keep callbacks current without re-running the effect when their identities change.\n const callbacksRef = useRef(config);\n callbacksRef.current = config;\n\n useEffect(() => {\n const handle = createHeartbeat({\n endpoint,\n fraction,\n minSkewMs,\n minRefreshIntervalMs,\n idleThresholdMs,\n initialExpiresAt,\n loggerNamespace,\n onSessionExpired: () => callbacksRef.current.onSessionExpired?.(),\n onRefreshed: () => callbacksRef.current.onRefreshed?.(),\n onError: (error) => callbacksRef.current.onError?.(error),\n });\n return handle.stop;\n }, [\n endpoint,\n fraction,\n minSkewMs,\n minRefreshIntervalMs,\n idleThresholdMs,\n initialExpiresAt,\n loggerNamespace,\n ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,aAAa,SAA0B,CAAC,GAAS;CAC/D,MAAM,EACJ,UACA,UACA,WACA,sBACA,iBACA,kBACA,oBACE;CAGJ,MAAM,eAAe,OAAO,MAAM;CAClC,aAAa,UAAU;CAEvB,gBAAgB;EAad,OAZe,gBAAgB;GAC7B;GACA;GACA;GACA;GACA;GACA;GACA;GACA,wBAAwB,aAAa,QAAQ,mBAAmB;GAChE,mBAAmB,aAAa,QAAQ,cAAc;GACtD,UAAU,UAAU,aAAa,QAAQ,UAAU,KAAK;EAC1D,CACO,EAAO;CAChB,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;AACH"}
@@ -0,0 +1,26 @@
1
+ import { SessionMonitorConfig, AuthStatus, createAuthStore } from '@eventuras/fides-auth-store';
2
+ /**
3
+ * React hook for session monitoring with automatic cleanup
4
+ *
5
+ * @param store - The auth store to update
6
+ * @param checkAuthStatus - Function to check authentication status
7
+ * @param config - Optional configuration
8
+ *
9
+ * @example
10
+ * ```typescript
11
+ * import { useSessionMonitor } from '@eventuras/fides-auth-react';
12
+ *
13
+ * function App() {
14
+ * useSessionMonitor(authStore, checkAuthStatus, {
15
+ * interval: 30_000,
16
+ * onSessionExpired: () => {
17
+ * toast.warn('Your session has expired');
18
+ * }
19
+ * });
20
+ *
21
+ * return <div>...</div>;
22
+ * }
23
+ * ```
24
+ */
25
+ export declare function useSessionMonitor(store: ReturnType<typeof createAuthStore>, checkAuthStatus: () => Promise<AuthStatus>, config?: SessionMonitorConfig): void;
26
+ //# sourceMappingURL=use-session-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-monitor.d.ts","sourceRoot":"","sources":["../src/use-session-monitor.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,oBAAoB,EACzB,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,EACzC,eAAe,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,EAC1C,MAAM,GAAE,oBAAyB,GAChC,IAAI,CAIN"}
@@ -0,0 +1,40 @@
1
+ "use client";
2
+ import { useEffect } from "react";
3
+ import { startSessionMonitor } from "@eventuras/fides-auth-store";
4
+ //#region src/use-session-monitor.ts
5
+ /**
6
+ * React hook for session monitoring with automatic cleanup
7
+ *
8
+ * @param store - The auth store to update
9
+ * @param checkAuthStatus - Function to check authentication status
10
+ * @param config - Optional configuration
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * import { useSessionMonitor } from '@eventuras/fides-auth-react';
15
+ *
16
+ * function App() {
17
+ * useSessionMonitor(authStore, checkAuthStatus, {
18
+ * interval: 30_000,
19
+ * onSessionExpired: () => {
20
+ * toast.warn('Your session has expired');
21
+ * }
22
+ * });
23
+ *
24
+ * return <div>...</div>;
25
+ * }
26
+ * ```
27
+ */
28
+ function useSessionMonitor(store, checkAuthStatus, config = {}) {
29
+ useEffect(() => {
30
+ return startSessionMonitor(store, checkAuthStatus, config);
31
+ }, [
32
+ store,
33
+ checkAuthStatus,
34
+ config
35
+ ]);
36
+ }
37
+ //#endregion
38
+ export { useSessionMonitor };
39
+
40
+ //# sourceMappingURL=use-session-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-session-monitor.js","names":[],"sources":["../src/use-session-monitor.ts"],"sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport {\n startSessionMonitor,\n type SessionMonitorConfig,\n type AuthStatus,\n type createAuthStore,\n} from '@eventuras/fides-auth-store';\n\n/**\n * React hook for session monitoring with automatic cleanup\n *\n * @param store - The auth store to update\n * @param checkAuthStatus - Function to check authentication status\n * @param config - Optional configuration\n *\n * @example\n * ```typescript\n * import { useSessionMonitor } from '@eventuras/fides-auth-react';\n *\n * function App() {\n * useSessionMonitor(authStore, checkAuthStatus, {\n * interval: 30_000,\n * onSessionExpired: () => {\n * toast.warn('Your session has expired');\n * }\n * });\n *\n * return <div>...</div>;\n * }\n * ```\n */\nexport function useSessionMonitor(\n store: ReturnType<typeof createAuthStore>,\n checkAuthStatus: () => Promise<AuthStatus>,\n config: SessionMonitorConfig = {}\n): void {\n useEffect(() => {\n return startSessionMonitor(store, checkAuthStatus, config);\n }, [store, checkAuthStatus, config]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,kBACd,OACA,iBACA,SAA+B,CAAC,GAC1B;CACN,gBAAgB;EACd,OAAO,oBAAoB,OAAO,iBAAiB,MAAM;CAC3D,GAAG;EAAC;EAAO;EAAiB;CAAM,CAAC;AACrC"}
package/package.json ADDED
@@ -0,0 +1,70 @@
1
+ {
2
+ "name": "@eventuras/fides-auth-react",
3
+ "version": "0.1.0",
4
+ "description": "React hooks for @eventuras/fides-auth — auth store bindings, session monitoring, and heartbeat",
5
+ "keywords": [
6
+ "authentication",
7
+ "oauth",
8
+ "oidc",
9
+ "session",
10
+ "react",
11
+ "hooks",
12
+ "xstate"
13
+ ],
14
+ "homepage": "https://github.com/losol/fides-auth/tree/main/packages/fides-auth-react#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/losol/fides-auth/issues"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/losol/fides-auth.git",
21
+ "directory": "packages/fides-auth-react"
22
+ },
23
+ "license": "MIT",
24
+ "author": "losol <losol@users.noreply.github.com>",
25
+ "sideEffects": false,
26
+ "type": "module",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js"
31
+ }
32
+ },
33
+ "main": "./dist/index.js",
34
+ "types": "./dist/index.d.ts",
35
+ "files": [
36
+ "dist",
37
+ "LICENSE",
38
+ "README.md"
39
+ ],
40
+ "dependencies": {
41
+ "@eventuras/logger": "^0.8.1",
42
+ "@xstate/store-react": "^2.0.0",
43
+ "@eventuras/fides-auth": "0.9.0",
44
+ "@eventuras/fides-auth-store": "0.1.0"
45
+ },
46
+ "peerDependencies": {
47
+ "@xstate/store": "^4.0.0",
48
+ "@xstate/store-react": "^2.0.0",
49
+ "react": "^19.0.0"
50
+ },
51
+ "devDependencies": {
52
+ "@types/react": "^19.2.14",
53
+ "@xstate/store": "^4.0.0",
54
+ "@xstate/store-react": "^2.0.0",
55
+ "react": "^19.2.0",
56
+ "vite": "^8.0.8",
57
+ "vitest": "^4.1.6",
58
+ "@eventuras/typescript-config": "1.0.0",
59
+ "@eventuras/vite-config": "0.2.2"
60
+ },
61
+ "engines": {
62
+ "node": ">=18"
63
+ },
64
+ "scripts": {
65
+ "build": "vite build",
66
+ "dev": "vite build --watch",
67
+ "test": "vitest run",
68
+ "test:watch": "vitest"
69
+ }
70
+ }