@archie/react-sdk 0.1.3 → 0.2.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/README.md CHANGED
@@ -21,6 +21,7 @@ Built on top of [`@archie/js-sdk`](../js-sdk), this package provides a fully rea
21
21
  - [useRest](#userest)
22
22
  - [useRestQuery](#userestquery)
23
23
  - [useRestMutation](#userestmutation)
24
+ - [useNotifications](#usenotifications)
24
25
  - [Components](#components)
25
26
  - [AuthGuard](#authguard)
26
27
  - [Re-exported Types](#re-exported-types)
@@ -538,6 +539,114 @@ await execute(payload, { headers: { 'x-idempotency-key': uuid() } });
538
539
 
539
540
  ---
540
541
 
542
+ ### useNotifications
543
+
544
+ Subscribes to live in-app notifications and manages read state. Opens a WebSocket channel on mount and closes it on unmount.
545
+
546
+ ```tsx
547
+ const { user } = useAuth();
548
+ const receiverId = user?.id ?? '';
549
+
550
+ const {
551
+ notifications,
552
+ latest,
553
+ unreadCount,
554
+ isLoading,
555
+ error,
556
+ connectionState,
557
+ markAsRead,
558
+ markAllAsRead,
559
+ refetch,
560
+ } = useNotifications(receiverId, { enabled: !!user, limit: 20 });
561
+ ```
562
+
563
+ **Options:**
564
+
565
+ | Option | Type | Default | Description |
566
+ | ---------------- | --------------------------- | ------- | ---------------------------------------------------------------------- |
567
+ | `enabled` | `boolean` | `true` | Set `false` to skip loading and subscription (e.g. while user is null) |
568
+ | `unreadOnly` | `boolean` | `false` | Initial load returns only unread notifications |
569
+ | `limit` | `number` | — | Max items to load in the initial fetch |
570
+ | `onNotification` | `(n: Notification) => void` | — | Called for each new live notification (e.g. for toasts or sounds) |
571
+
572
+ **Returns:**
573
+
574
+ | Field | Type | Description |
575
+ | ----------------- | ------------------------------- | ----------------------------------------------------------------------------------------- |
576
+ | `notifications` | `Notification[]` | History + live arrivals, most-recent first, deduplicated by `id` |
577
+ | `latest` | `Notification \| null` | Last notification received live (convenient for toasts) |
578
+ | `unreadCount` | `number` | Live unread count — updates automatically |
579
+ | `isLoading` | `boolean` | True during initial history load |
580
+ | `error` | `ArchieError \| null` | Error from the latest failed operation |
581
+ | `connectionState` | `ConnectionState` | `'CONNECTING' \| 'CONNECTED' \| 'DISCONNECTED' \| 'RECONNECTING'` |
582
+ | `markAsRead` | `(id: string) => Promise<void>` | Mark one notification read; updates local state optimistically |
583
+ | `markAllAsRead` | `() => Promise<void>` | Mark all loaded notifications read; reconciles `unreadCount` with the server (normally 0) |
584
+ | `refetch` | `() => Promise<void>` | Reload the notification history |
585
+
586
+ **Example — notification bell with unread badge:**
587
+
588
+ ```tsx
589
+ import { useAuth, useNotifications } from '@archie/react-sdk';
590
+
591
+ function NotificationBell() {
592
+ const { user } = useAuth();
593
+ const receiverId = user?.id ?? '';
594
+ const { unreadCount, connectionState } = useNotifications(receiverId, { enabled: !!user });
595
+
596
+ return (
597
+ <button aria-label="Notifications">
598
+ <BellIcon />
599
+ {unreadCount > 0 && <span className="badge">{unreadCount > 99 ? '99+' : unreadCount}</span>}
600
+ {connectionState !== 'CONNECTED' && <span className="dot reconnecting" />}
601
+ </button>
602
+ );
603
+ }
604
+ ```
605
+
606
+ **Example — notification list with mark-as-read:**
607
+
608
+ ```tsx
609
+ function NotificationList() {
610
+ const { user } = useAuth();
611
+ const receiverId = user?.id ?? '';
612
+ const { notifications, isLoading, unreadCount, markAsRead, markAllAsRead } = useNotifications(
613
+ receiverId,
614
+ { enabled: !!user, limit: 20 },
615
+ );
616
+
617
+ if (isLoading) return <Spinner />;
618
+
619
+ return (
620
+ <div>
621
+ <header>
622
+ <span>{unreadCount} unread</span>
623
+ <button onClick={() => markAllAsRead()} disabled={unreadCount === 0}>
624
+ Mark all read
625
+ </button>
626
+ </header>
627
+ <ul>
628
+ {notifications.map((n) => (
629
+ <li
630
+ key={n.id}
631
+ className={n.isRead ? 'read' : 'unread'}
632
+ onClick={() => !n.isRead && markAsRead(n.id)}
633
+ >
634
+ <p>{n.actionText ?? n.notificationKey}</p>
635
+ <time>{new Date(n.createdAt).toLocaleString()}</time>
636
+ </li>
637
+ ))}
638
+ </ul>
639
+ </div>
640
+ );
641
+ }
642
+ ```
643
+
644
+ > **Always call the hook unconditionally** (React rules of hooks). When there is no authenticated user, pass `receiverId=''` and `enabled: false` — the hook will not load or subscribe.
645
+
646
+ > **Security note.** Before rendering `n.actionUrl` as a link, validate the scheme is `http:` or `https:`. Never allow `javascript:` or `data:` URLs. Treat `n.metadata` and `n.params` as untrusted server data. See the [js-sdk README Security section](../js-sdk/README.md#security--trust-model) for a safe-URL helper.
647
+
648
+ ---
649
+
541
650
  ## Components
542
651
 
543
652
  ### AuthGuard
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { ArchieClient, Session, User, AuthSignInParams, ArchieError, AuthSignUpParams, AuthConfirmParams, AuthRecoverParams, AuthResetPasswordParams, ConnectionState, FileUploadOptions, FileUploadResult, IRestModule, RestRequestOptions } from '@archie/js-sdk';
2
+ import { ArchieClient, Session, User, AuthSignInParams, ArchieError, AuthSignUpParams, AuthConfirmParams, AuthRecoverParams, AuthResetPasswordParams, ConnectionState, FileUploadOptions, FileUploadResult, IRestModule, RestRequestOptions, Notification } from '@archie/js-sdk';
3
3
  export { ArchieClient, ArchieClientOptions, ArchieError, AuthConfirmParams, AuthError, AuthEvent, AuthEventCallback, AuthRecoverParams, AuthResetPasswordParams, AuthSignInParams, AuthSignUpParams, BrowserLocalStorage, ConnectionState, ConnectionStateCallback, CsvUploadOptions, FileUploadOptions, FileUploadResult, GraphQLError, GraphQLRawRequest, GraphQLRequestOptions, GraphQLResponse, IAuthModule, IFileModule, IGraphQLModule, IHttpClient, IRealtimeModule, IRestModule, Logger, MemoryStorage, NetworkError, RealtimeChannel, RealtimeEvent, RestRequestOptions, Session, StorageAdapter, Subscription, SubscriptionCallbacks, TokenAccessor, User, createClient } from '@archie/js-sdk';
4
4
 
5
5
  /**
@@ -250,6 +250,34 @@ interface UseRestMutationReturn<T> {
250
250
  */
251
251
  declare function useRestMutation<T = unknown>(path: string, method?: 'POST' | 'PUT' | 'PATCH' | 'DELETE'): UseRestMutationReturn<T>;
252
252
 
253
+ interface UseNotificationsOptions {
254
+ enabled?: boolean;
255
+ unreadOnly?: boolean;
256
+ limit?: number;
257
+ onNotification?: (notification: Notification) => void;
258
+ }
259
+ interface UseNotificationsReturn {
260
+ notifications: Notification[];
261
+ latest: Notification | null;
262
+ unreadCount: number;
263
+ isLoading: boolean;
264
+ error: ArchieError | null;
265
+ connectionState: ConnectionState;
266
+ markAsRead: (id: string) => Promise<void>;
267
+ markAllAsRead: () => Promise<void>;
268
+ refetch: () => Promise<void>;
269
+ }
270
+ /**
271
+ * Subscribe to a user's in-app notifications: loads the existing list,
272
+ * then streams new ones live. Returns idiomatic React state.
273
+ *
274
+ * @example
275
+ * ```tsx
276
+ * const { notifications, unreadCount, markAsRead } = useNotifications(user.id);
277
+ * ```
278
+ */
279
+ declare function useNotifications(receiverId: string, options?: UseNotificationsOptions): UseNotificationsReturn;
280
+
253
281
  interface AuthGuardProps {
254
282
  /** Content to show when authenticated (and authorized if roles specified). */
255
283
  children: React.ReactNode;
@@ -272,4 +300,4 @@ interface AuthGuardProps {
272
300
  */
273
301
  declare function AuthGuard({ children, fallback, loadingComponent, requiredRoles, }: AuthGuardProps): React.FunctionComponentElement<React.FragmentProps>;
274
302
 
275
- export { ArchieProvider, type ArchieProviderProps, AuthGuard, type AuthGuardProps, QueryCache, useArchieClient, useAuth, useFileUpload, useMutation, useQuery, useRest, useRestMutation, useRestQuery, useSubscription };
303
+ export { ArchieProvider, type ArchieProviderProps, AuthGuard, type AuthGuardProps, QueryCache, type UseNotificationsOptions, type UseNotificationsReturn, useArchieClient, useAuth, useFileUpload, useMutation, useNotifications, useQuery, useRest, useRestMutation, useRestQuery, useSubscription };
package/dist/index.js CHANGED
@@ -465,6 +465,132 @@ function useRestMutation(path, method = "POST") {
465
465
  }, []);
466
466
  return { execute, data, error, isLoading, reset };
467
467
  }
468
+ function useNotifications(receiverId, options) {
469
+ const { client } = useArchieContext();
470
+ const [notifications, setNotifications] = useState([]);
471
+ const [latest, setLatest] = useState(null);
472
+ const [unreadCount, setUnreadCount] = useState(0);
473
+ const [isLoading, setIsLoading] = useState(options?.enabled !== false);
474
+ const [error, setError] = useState(null);
475
+ const [connectionState, setConnectionState] = useState(
476
+ () => client.realtime.currentState
477
+ );
478
+ const enabled = options?.enabled !== false;
479
+ const unreadOnly = options?.unreadOnly ?? false;
480
+ const limit = options?.limit;
481
+ const optionsRef = useRef(options);
482
+ optionsRef.current = options;
483
+ const notificationsRef = useRef([]);
484
+ notificationsRef.current = notifications;
485
+ const seenIdsRef = useRef(/* @__PURE__ */ new Set());
486
+ useEffect(() => {
487
+ setNotifications([]);
488
+ setLatest(null);
489
+ setUnreadCount(0);
490
+ seenIdsRef.current = /* @__PURE__ */ new Set();
491
+ }, [receiverId]);
492
+ const load = useCallback(async () => {
493
+ const [listResult, unread] = await Promise.all([
494
+ client.notifications.list(receiverId, { unreadOnly, first: limit }),
495
+ client.notifications.getUnreadCount(receiverId)
496
+ ]);
497
+ return { listResult, unread };
498
+ }, [client, receiverId, unreadOnly, limit]);
499
+ useEffect(() => {
500
+ if (!enabled) {
501
+ setIsLoading(false);
502
+ return;
503
+ }
504
+ let active = true;
505
+ setIsLoading(true);
506
+ load().then(({ listResult, unread }) => {
507
+ if (!active) return;
508
+ setNotifications(listResult.items);
509
+ seenIdsRef.current = new Set(listResult.items.map((n) => n.id));
510
+ setUnreadCount(unread);
511
+ setError(null);
512
+ }).catch((err) => {
513
+ if (active) setError(err);
514
+ }).finally(() => {
515
+ if (active) setIsLoading(false);
516
+ });
517
+ return () => {
518
+ active = false;
519
+ };
520
+ }, [enabled, load]);
521
+ useEffect(() => {
522
+ if (!enabled) return;
523
+ const unsubConnection = client.realtime.onConnectionStateChange(setConnectionState);
524
+ setConnectionState(client.realtime.currentState);
525
+ const channel = client.notifications.subscribe(receiverId, {
526
+ onError: (err) => setError(err)
527
+ });
528
+ channel.on("*", (notification) => {
529
+ if (seenIdsRef.current.has(notification.id)) return;
530
+ seenIdsRef.current.add(notification.id);
531
+ setNotifications((prev) => [notification, ...prev]);
532
+ setLatest(notification);
533
+ if (!notification.isRead) setUnreadCount((c) => c + 1);
534
+ optionsRef.current?.onNotification?.(notification);
535
+ });
536
+ return () => {
537
+ channel.unsubscribe();
538
+ unsubConnection();
539
+ };
540
+ }, [client, receiverId, enabled]);
541
+ const markAsRead = useCallback(
542
+ async (id) => {
543
+ const wasUnread = notificationsRef.current.find((n) => n.id === id)?.isRead === false;
544
+ try {
545
+ await client.notifications.markAsRead(id);
546
+ setNotifications(
547
+ (prev) => prev.map((n) => n.id === id && !n.isRead ? { ...n, isRead: true } : n)
548
+ );
549
+ if (wasUnread) setUnreadCount((c) => Math.max(0, c - 1));
550
+ } catch (err) {
551
+ setError(err);
552
+ throw err;
553
+ }
554
+ },
555
+ [client]
556
+ );
557
+ const markAllAsRead = useCallback(async () => {
558
+ try {
559
+ await client.notifications.markAllAsRead(receiverId);
560
+ setNotifications((prev) => prev.map((n) => n.isRead ? n : { ...n, isRead: true }));
561
+ const count = await client.notifications.getUnreadCount(receiverId);
562
+ setUnreadCount(count);
563
+ } catch (err) {
564
+ setError(err);
565
+ throw err;
566
+ }
567
+ }, [client, receiverId]);
568
+ const refetch = useCallback(async () => {
569
+ setIsLoading(true);
570
+ try {
571
+ const { listResult, unread } = await load();
572
+ setNotifications(listResult.items);
573
+ seenIdsRef.current = new Set(listResult.items.map((n) => n.id));
574
+ setUnreadCount(unread);
575
+ setError(null);
576
+ } catch (err) {
577
+ setError(err);
578
+ } finally {
579
+ setIsLoading(false);
580
+ }
581
+ }, [load]);
582
+ return {
583
+ notifications,
584
+ latest,
585
+ unreadCount,
586
+ isLoading,
587
+ error,
588
+ connectionState,
589
+ markAsRead,
590
+ markAllAsRead,
591
+ refetch
592
+ };
593
+ }
468
594
  function AuthGuard({
469
595
  children,
470
596
  fallback = null,
@@ -487,6 +613,6 @@ function AuthGuard({
487
613
  return React2.createElement(React2.Fragment, null, children);
488
614
  }
489
615
 
490
- export { ArchieProvider, AuthGuard, QueryCache, useArchieClient, useAuth, useFileUpload, useMutation, useQuery, useRest, useRestMutation, useRestQuery, useSubscription };
616
+ export { ArchieProvider, AuthGuard, QueryCache, useArchieClient, useAuth, useFileUpload, useMutation, useNotifications, useQuery, useRest, useRestMutation, useRestQuery, useSubscription };
491
617
  //# sourceMappingURL=index.js.map
492
618
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/query-cache.ts","../src/provider.tsx","../src/hooks/useArchieClient.ts","../src/hooks/useAuth.ts","../src/hooks/useQuery.ts","../src/hooks/useMutation.ts","../src/hooks/useSubscription.ts","../src/hooks/useFileUpload.ts","../src/hooks/useRest.ts","../src/components/AuthGuard.tsx"],"names":["React","useMemo","useState","useCallback","useEffect","useRef"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * In-memory query cache with in-flight request deduplication and stale-while-revalidate.\n * @internal\n */\n\ninterface CacheEntry<T = unknown> {\n data: T;\n timestamp: number;\n}\n\nexport class QueryCache {\n private cache = new Map<string, CacheEntry>();\n private inflight = new Map<string, Promise<unknown>>();\n private staleTime = 0;\n\n static key(query: string, variables?: Record<string, unknown>): string {\n return `${query}::${variables ? JSON.stringify(variables) : ''}`;\n }\n\n get<T>(key: string): CacheEntry<T> | undefined {\n return this.cache.get(key) as CacheEntry<T> | undefined;\n }\n\n set<T>(key: string, data: T): void {\n this.cache.set(key, { data, timestamp: Date.now() });\n }\n\n isFresh(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (this.staleTime === 0) return false;\n return Date.now() - entry.timestamp < this.staleTime;\n }\n\n /**\n * Deduplicate in-flight requests: if an identical fetch is already pending,\n * return the same promise. Otherwise, run `fetcher` and share the promise.\n */\n async dedup<T>(key: string, fetcher: () => Promise<T>): Promise<T> {\n const existing = this.inflight.get(key);\n if (existing) return existing as Promise<T>;\n\n const promise = fetcher().finally(() => {\n this.inflight.delete(key);\n });\n\n this.inflight.set(key, promise);\n return promise;\n }\n\n getInflight<T>(key: string): Promise<T> | undefined {\n return this.inflight.get(key) as Promise<T> | undefined;\n }\n\n invalidate(querySubstring: string): void {\n for (const key of this.cache.keys()) {\n if (key.includes(querySubstring)) {\n this.cache.delete(key);\n }\n }\n }\n\n clear(): void {\n this.cache.clear();\n this.inflight.clear();\n }\n}\n","import React, { createContext, useContext, useEffect, useState, useMemo } from 'react';\nimport type { ArchieClient, Session, AuthEvent } from '@archie/js-sdk';\nimport { QueryCache } from './lib/query-cache';\n\n// ─── Context ──────────────────────────────────────────────────\n\ninterface ArchieContextValue {\n client: ArchieClient;\n session: Session | null;\n isLoading: boolean;\n cache: QueryCache;\n}\n\nexport const ArchieContext = createContext<ArchieContextValue | null>(null);\n\n// ─── Provider ─────────────────────────────────────────────────\n\nexport interface ArchieProviderProps {\n client: ArchieClient;\n children: React.ReactNode;\n /** @internal Inject a custom cache (useful for testing). */\n cache?: QueryCache;\n}\n\n/**\n * ArchieProvider — wraps your React app to provide the Archie client and session state.\n *\n * @example\n * ```tsx\n * import { createClient } from '@archie/js-sdk'\n * import { ArchieProvider } from '@archie/react-sdk'\n *\n * const archie = createClient({ projectId: '...' })\n *\n * function App() {\n * return (\n * <ArchieProvider client={archie}>\n * <MyApp />\n * </ArchieProvider>\n * )\n * }\n * ```\n */\nexport function ArchieProvider({ client, children, cache: injectedCache }: ArchieProviderProps) {\n const [session, setSession] = useState<Session | null>(client.auth.getSession());\n const [isLoading, setIsLoading] = useState(true);\n const defaultCache = useMemo(() => new QueryCache(), [client]);\n const cache = injectedCache ?? defaultCache;\n\n useEffect(() => {\n client.auth.waitForInit().then(() => {\n setSession(client.auth.getSession());\n setIsLoading(false);\n });\n\n const unsubscribe = client.auth.onAuthStateChange(\n (_event: AuthEvent, newSession: Session | null) => {\n setSession(newSession);\n },\n );\n\n return unsubscribe;\n }, [client]);\n\n const value = useMemo<ArchieContextValue>(\n () => ({ client, session, isLoading, cache }),\n [client, session, isLoading, cache],\n );\n\n return React.createElement(ArchieContext.Provider, { value }, children);\n}\n\n/**\n * Internal hook to access the Archie context.\n * @throws if used outside ArchieProvider\n * @internal\n */\nexport function useArchieContext(): ArchieContextValue {\n const context = useContext(ArchieContext);\n if (!context) {\n throw new Error(\n 'useArchieClient must be used within an <ArchieProvider>. ' +\n 'Wrap your app with <ArchieProvider client={archieClient}>.',\n );\n }\n return context;\n}\n","import { useArchieContext } from '../provider';\nimport type { ArchieClient } from '@archie/js-sdk';\n\n/**\n * Returns the ArchieClient instance from context.\n * Must be used within an ArchieProvider.\n *\n * @throws Error if used outside ArchieProvider\n */\nexport function useArchieClient(): ArchieClient {\n const { client } = useArchieContext();\n return client;\n}\n","import { useCallback, useMemo } from 'react';\nimport { useArchieContext } from '../provider';\nimport type {\n User,\n Session,\n AuthSignUpParams,\n AuthSignInParams,\n AuthConfirmParams,\n AuthRecoverParams,\n AuthResetPasswordParams,\n ArchieError,\n} from '@archie/js-sdk';\n\ninterface UseAuthReturn {\n user: User | null;\n session: Session | null;\n isLoading: boolean;\n isAuthenticated: boolean;\n signIn: (\n params: AuthSignInParams,\n ) => Promise<{ session: Session | null; error: ArchieError | null }>;\n signUp: (\n params: AuthSignUpParams,\n ) => Promise<{ data: { userId: string; message: string } | null; error: ArchieError | null }>;\n signOut: () => Promise<void>;\n confirmSignUp: (\n params: AuthConfirmParams,\n ) => Promise<{ session: Session | null; error: ArchieError | null }>;\n recoverPassword: (\n params: AuthRecoverParams,\n ) => Promise<{ data: { message: string } | null; error: ArchieError | null }>;\n resetPassword: (\n params: AuthResetPasswordParams,\n ) => Promise<{ data: { message: string } | null; error: ArchieError | null }>;\n refreshSession: () => Promise<{ session: Session | null; error: ArchieError | null }>;\n}\n\n/**\n * Hook for authentication state and operations.\n * All methods return `{ data/session, error }` (never throws).\n */\nexport function useAuth(): UseAuthReturn {\n const { client, session, isLoading } = useArchieContext();\n\n const signIn = useCallback(\n async (params: AuthSignInParams) => {\n try {\n const result = await client.auth.signIn(params);\n return { session: result.session, error: null };\n } catch (err) {\n return { session: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const signUp = useCallback(\n async (params: AuthSignUpParams) => {\n try {\n const result = await client.auth.signUp(params);\n return { data: result, error: null };\n } catch (err) {\n return { data: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const signOut = useCallback(async () => {\n await client.auth.signOut();\n }, [client]);\n\n const confirmSignUp = useCallback(\n async (params: AuthConfirmParams) => {\n try {\n const result = await client.auth.confirmSignUp(params);\n return { session: result.session, error: null };\n } catch (err) {\n return { session: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const recoverPassword = useCallback(\n async (params: AuthRecoverParams) => {\n try {\n const result = await client.auth.recoverPassword(params);\n return { data: result, error: null };\n } catch (err) {\n return { data: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const resetPassword = useCallback(\n async (params: AuthResetPasswordParams) => {\n try {\n const result = await client.auth.resetPassword(params);\n return { data: result, error: null };\n } catch (err) {\n return { data: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const refreshSession = useCallback(async () => {\n try {\n const result = await client.auth.refreshSession();\n return { session: result.session, error: null };\n } catch (err) {\n return { session: null, error: err as ArchieError };\n }\n }, [client]);\n\n return useMemo(\n () => ({\n user: session?.user ?? null,\n session,\n isLoading,\n isAuthenticated: session !== null,\n signIn,\n signUp,\n signOut,\n confirmSignUp,\n recoverPassword,\n resetPassword,\n refreshSession,\n }),\n [\n session,\n isLoading,\n signIn,\n signUp,\n signOut,\n confirmSignUp,\n recoverPassword,\n resetPassword,\n refreshSession,\n ],\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { useArchieContext } from '../provider';\nimport { QueryCache } from '../lib/query-cache';\nimport type { ArchieError } from '@archie/js-sdk';\n\ninterface UseQueryOptions<T> {\n enabled?: boolean;\n refetchInterval?: number;\n refetchOnWindowFocus?: boolean;\n onSuccess?: (data: T) => void;\n onError?: (error: ArchieError) => void;\n}\n\ninterface UseQueryReturn<T> {\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n isRefetching: boolean;\n refetch: () => Promise<void>;\n}\n\n/**\n * Declarative GraphQL query hook with caching and stale-while-revalidate.\n *\n * @example\n * ```tsx\n * const { data, isLoading } = useQuery<{ users: User[] }>(\n * 'query { users { id email name } }',\n * { limit: 10 }\n * )\n * ```\n */\nexport function useQuery<T = unknown>(\n gql: string,\n variables?: Record<string, unknown>,\n options?: UseQueryOptions<T>,\n): UseQueryReturn<T> {\n const { client, session, cache } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [isRefetching, setIsRefetching] = useState(false);\n\n const enabled = options?.enabled !== false;\n\n const variablesKey = variables ? JSON.stringify(variables) : '';\n const cacheKey = QueryCache.key(gql, variables);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const fetchData = useCallback(\n async (isRefetch = false) => {\n if (!enabled) return;\n\n if (isRefetch) {\n setIsRefetching(true);\n } else {\n setIsLoading(true);\n }\n\n try {\n const result = await cache.dedup(cacheKey, () => client.graphql.query<T>(gql, variables));\n if (result.error) {\n setError(result.error);\n setData(null);\n optionsRef.current?.onError?.(result.error);\n } else {\n setData(result.data);\n setError(null);\n cache.set(cacheKey, result.data);\n optionsRef.current?.onSuccess?.(result.data as T);\n }\n } catch (err) {\n setError(err as ArchieError);\n setData(null);\n } finally {\n setIsLoading(false);\n setIsRefetching(false);\n }\n },\n [client, gql, variablesKey, enabled, cacheKey, cache],\n );\n\n // Initial fetch & refetch on variable change\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n\n const cached = cache.get<T>(cacheKey);\n if (cached) {\n setData(cached.data);\n setIsLoading(false);\n fetchData(true);\n } else {\n fetchData(false);\n }\n }, [cacheKey, enabled]);\n\n // Refetch on auth state change (new token)\n const prevSessionRef = useRef(session?.accessToken);\n useEffect(() => {\n if (\n enabled &&\n prevSessionRef.current !== session?.accessToken &&\n prevSessionRef.current !== undefined\n ) {\n fetchData(true);\n }\n prevSessionRef.current = session?.accessToken;\n }, [session?.accessToken, enabled]);\n\n // Polling (refetchInterval)\n useEffect(() => {\n if (!enabled || !options?.refetchInterval) return;\n\n const interval = setInterval(() => {\n fetchData(true);\n }, options.refetchInterval);\n\n return () => clearInterval(interval);\n }, [enabled, options?.refetchInterval]);\n\n // Refetch on window focus\n useEffect(() => {\n if (!enabled || !options?.refetchOnWindowFocus) return;\n if (typeof window === 'undefined') return;\n\n const handleFocus = () => fetchData(true);\n window.addEventListener('focus', handleFocus);\n return () => window.removeEventListener('focus', handleFocus);\n }, [enabled, options?.refetchOnWindowFocus]);\n\n const refetch = useCallback(() => fetchData(true), [fetchData]);\n\n return { data, error, isLoading, isRefetching, refetch };\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError } from '@archie/js-sdk';\n\ninterface UseMutationOptions<T> {\n onSuccess?: (data: T) => void;\n onError?: (error: ArchieError) => void;\n onSettled?: () => void;\n /** Query substrings to invalidate (forcing refetch) after a successful mutation. */\n invalidateQueries?: string[];\n}\n\ninterface UseMutationReturn<T> {\n mutate: (variables?: Record<string, unknown>) => void;\n mutateAsync: (variables?: Record<string, unknown>) => Promise<T | null>;\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n reset: () => void;\n}\n\n/**\n * Hook for GraphQL mutations.\n *\n * @example\n * ```tsx\n * const { mutate, isLoading } = useMutation<{ createUser: User }>(\n * 'mutation($data: CreateUserInput!) { createUser(data: $data) { id email } }',\n * { invalidateQueries: ['users'] }\n * )\n *\n * mutate({ data: { email: 'new@user.com', name: 'John' } })\n * ```\n */\nexport function useMutation<T = unknown>(\n gql: string,\n options?: UseMutationOptions<T>,\n): UseMutationReturn<T> {\n const { client, cache } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const execute = useCallback(\n async (variables?: Record<string, unknown>): Promise<T | null> => {\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await client.graphql.mutate<T>(gql, variables);\n\n if (result.error) {\n setError(result.error);\n setData(null);\n optionsRef.current?.onError?.(result.error);\n optionsRef.current?.onSettled?.();\n return null;\n }\n\n setData(result.data);\n setError(null);\n optionsRef.current?.onSuccess?.(result.data as T);\n\n if (optionsRef.current?.invalidateQueries) {\n for (const queryKey of optionsRef.current.invalidateQueries) {\n cache.invalidate(queryKey);\n }\n }\n\n optionsRef.current?.onSettled?.();\n return result.data;\n } catch (err) {\n const archieErr = err as ArchieError;\n setError(archieErr);\n setData(null);\n optionsRef.current?.onError?.(archieErr);\n optionsRef.current?.onSettled?.();\n return null;\n } finally {\n setIsLoading(false);\n }\n },\n [client, gql, cache],\n );\n\n const mutate = useCallback(\n (variables?: Record<string, unknown>) => {\n execute(variables);\n },\n [execute],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsLoading(false);\n }, []);\n\n return { mutate, mutateAsync: execute, data, error, isLoading, reset };\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, ConnectionState } from '@archie/js-sdk';\n\ninterface UseSubscriptionOptions<T> {\n enabled?: boolean;\n onData?: (data: T) => void;\n onError?: (error: ArchieError) => void;\n}\n\ninterface UseSubscriptionReturn<T> {\n data: T | null;\n error: ArchieError | null;\n connectionState: ConnectionState;\n}\n\n/**\n * Hook for real-time GraphQL subscriptions.\n * Subscribes on mount, unsubscribes on unmount.\n *\n * @example\n * ```tsx\n * const { data } = useSubscription<{ orderUpdated: Order }>(\n * 'subscription { orderUpdated { id status total } }'\n * )\n * ```\n */\nexport function useSubscription<T = unknown>(\n gql: string,\n variables?: Record<string, unknown>,\n options?: UseSubscriptionOptions<T>,\n): UseSubscriptionReturn<T> {\n const { client } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [connectionState, setConnectionState] = useState<ConnectionState>('DISCONNECTED');\n\n const enabled = options?.enabled !== false;\n const variablesKey = variables ? JSON.stringify(variables) : '';\n\n // Track latest callbacks to avoid stale closures\n const callbacksRef = useRef(options);\n callbacksRef.current = options;\n\n useEffect(() => {\n if (!enabled) return;\n\n const unsub = client.realtime.onConnectionStateChange(setConnectionState);\n\n const subscription = client.realtime.subscribe<T>(gql, variables, {\n onData: (newData: T) => {\n setData(newData);\n setError(null);\n callbacksRef.current?.onData?.(newData);\n },\n onError: (err) => {\n setError(err);\n callbacksRef.current?.onError?.(err);\n },\n onComplete: () => {\n // Subscription completed server-side\n },\n });\n\n return () => {\n subscription.unsubscribe();\n unsub();\n };\n }, [client, gql, variablesKey, enabled]);\n\n return { data, error, connectionState };\n}\n","import { useState, useCallback } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, FileUploadOptions, FileUploadResult } from '@archie/js-sdk';\n\ninterface UseFileUploadReturn {\n upload: (file: File | Blob, options?: FileUploadOptions) => Promise<void>;\n progress: number;\n isUploading: boolean;\n data: FileUploadResult | null;\n error: ArchieError | null;\n reset: () => void;\n}\n\n/**\n * Hook for file uploads.\n *\n * @example\n * ```tsx\n * const { upload, isUploading, data } = useFileUpload()\n *\n * <input type=\"file\" onChange={(e) => upload(e.target.files[0])} />\n * {isUploading && <Spinner />}\n * ```\n */\nexport function useFileUpload(): UseFileUploadReturn {\n const { client } = useArchieContext();\n const [progress, setProgress] = useState(0);\n const [isUploading, setIsUploading] = useState(false);\n const [data, setData] = useState<FileUploadResult | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n\n const upload = useCallback(\n async (file: File | Blob, options?: FileUploadOptions) => {\n setIsUploading(true);\n setProgress(0);\n setError(null);\n setData(null);\n\n try {\n const result = await client.files.upload(file, options);\n\n setData(result);\n setProgress(100);\n } catch (err) {\n setError(err as ArchieError);\n } finally {\n setIsUploading(false);\n }\n },\n [client],\n );\n\n const reset = useCallback(() => {\n setProgress(0);\n setIsUploading(false);\n setData(null);\n setError(null);\n }, []);\n\n return { upload, progress, isUploading, data, error, reset };\n}\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, RestRequestOptions, IRestModule } from '@archie/js-sdk';\n\n// ─── useRest (base) ──────────────────────────────────────────\n\n/**\n * Returns the REST module from the Archie client.\n * Provides direct access to `get`, `post`, `put`, `patch`, `delete`.\n *\n * @example\n * ```tsx\n * const rest = useRest()\n * const data = await rest.get('/api/products')\n * await rest.post('/api/products', { name: 'Widget' })\n * ```\n */\nexport function useRest(): IRestModule {\n const { client } = useArchieContext();\n return useMemo(() => client.rest, [client]);\n}\n\n// ─── useRestQuery ─────────────────────────────────────────────\n\ninterface UseRestQueryReturn<T> {\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n refetch: () => Promise<void>;\n}\n\n/**\n * Declarative hook for GET requests to custom REST APIs.\n */\nexport function useRestQuery<T = unknown>(\n path: string,\n options?: RestRequestOptions & { enabled?: boolean },\n): UseRestQueryReturn<T> {\n const { client } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const enabled = options?.enabled !== false;\n\n const fetchData = useCallback(async () => {\n if (!enabled) return;\n setIsLoading(true);\n\n try {\n const result = await client.rest.get<T>(path, options);\n setData(result);\n setError(null);\n } catch (err) {\n setError(err as ArchieError);\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, path, enabled]);\n\n useEffect(() => {\n if (enabled) {\n fetchData();\n } else {\n setIsLoading(false);\n }\n }, [fetchData, enabled]);\n\n return { data, error, isLoading, refetch: fetchData };\n}\n\n// ─── useRestMutation ──────────────────────────────────────────\n\ninterface UseRestMutationReturn<T> {\n execute: (body?: unknown, overrideOptions?: RestRequestOptions) => Promise<T | null>;\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n reset: () => void;\n}\n\n/**\n * Imperative hook for POST/PUT/PATCH/DELETE requests to custom REST APIs.\n */\nexport function useRestMutation<T = unknown>(\n path: string,\n method: 'POST' | 'PUT' | 'PATCH' | 'DELETE' = 'POST',\n): UseRestMutationReturn<T> {\n const { client } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n const execute = useCallback(\n async (body?: unknown, overrideOptions?: RestRequestOptions): Promise<T | null> => {\n setIsLoading(true);\n setError(null);\n\n try {\n let result: T;\n switch (method) {\n case 'POST':\n result = await client.rest.post<T>(path, body, overrideOptions);\n break;\n case 'PUT':\n result = await client.rest.put<T>(path, body, overrideOptions);\n break;\n case 'PATCH':\n result = await client.rest.patch<T>(path, body, overrideOptions);\n break;\n case 'DELETE':\n result = await client.rest.delete<T>(path, overrideOptions);\n break;\n }\n\n setData(result);\n setError(null);\n return result;\n } catch (err) {\n const archieErr = err as ArchieError;\n setError(archieErr);\n setData(null);\n return null;\n } finally {\n setIsLoading(false);\n }\n },\n [client, path, method],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsLoading(false);\n }, []);\n\n return { execute, data, error, isLoading, reset };\n}\n","import React from 'react';\nimport { useAuth } from '../hooks/useAuth';\n\nexport interface AuthGuardProps {\n /** Content to show when authenticated (and authorized if roles specified). */\n children: React.ReactNode;\n /** Content to show when NOT authenticated. */\n fallback?: React.ReactNode;\n /** Content to show while session is loading. */\n loadingComponent?: React.ReactNode;\n /** If specified, user must have at least one of these roles. */\n requiredRoles?: string[];\n}\n\n/**\n * AuthGuard component — conditionally renders children based on auth state.\n *\n * @example\n * ```tsx\n * <AuthGuard fallback={<LoginPage />} requiredRoles={['admin']}>\n * <AdminPanel />\n * </AuthGuard>\n * ```\n */\nexport function AuthGuard({\n children,\n fallback = null,\n loadingComponent = null,\n requiredRoles,\n}: AuthGuardProps) {\n const { user, isLoading, isAuthenticated } = useAuth();\n\n if (isLoading) {\n return React.createElement(React.Fragment, null, loadingComponent);\n }\n\n if (!isAuthenticated || !user) {\n return React.createElement(React.Fragment, null, fallback);\n }\n\n // Check roles if required\n if (requiredRoles && requiredRoles.length > 0) {\n const hasRequiredRole = requiredRoles.some((role) => user.roles.includes(role));\n if (!hasRequiredRole) {\n return React.createElement(React.Fragment, null, fallback);\n }\n }\n\n return React.createElement(React.Fragment, null, children);\n}\n"]}
1
+ {"version":3,"sources":["../src/lib/query-cache.ts","../src/provider.tsx","../src/hooks/useArchieClient.ts","../src/hooks/useAuth.ts","../src/hooks/useQuery.ts","../src/hooks/useMutation.ts","../src/hooks/useSubscription.ts","../src/hooks/useFileUpload.ts","../src/hooks/useRest.ts","../src/hooks/useNotifications.ts","../src/components/AuthGuard.tsx"],"names":["React","useMemo","useState","useCallback","useEffect","useRef"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * In-memory query cache with in-flight request deduplication and stale-while-revalidate.\n * @internal\n */\n\ninterface CacheEntry<T = unknown> {\n data: T;\n timestamp: number;\n}\n\nexport class QueryCache {\n private cache = new Map<string, CacheEntry>();\n private inflight = new Map<string, Promise<unknown>>();\n private staleTime = 0;\n\n static key(query: string, variables?: Record<string, unknown>): string {\n return `${query}::${variables ? JSON.stringify(variables) : ''}`;\n }\n\n get<T>(key: string): CacheEntry<T> | undefined {\n return this.cache.get(key) as CacheEntry<T> | undefined;\n }\n\n set<T>(key: string, data: T): void {\n this.cache.set(key, { data, timestamp: Date.now() });\n }\n\n isFresh(key: string): boolean {\n const entry = this.cache.get(key);\n if (!entry) return false;\n if (this.staleTime === 0) return false;\n return Date.now() - entry.timestamp < this.staleTime;\n }\n\n /**\n * Deduplicate in-flight requests: if an identical fetch is already pending,\n * return the same promise. Otherwise, run `fetcher` and share the promise.\n */\n async dedup<T>(key: string, fetcher: () => Promise<T>): Promise<T> {\n const existing = this.inflight.get(key);\n if (existing) return existing as Promise<T>;\n\n const promise = fetcher().finally(() => {\n this.inflight.delete(key);\n });\n\n this.inflight.set(key, promise);\n return promise;\n }\n\n getInflight<T>(key: string): Promise<T> | undefined {\n return this.inflight.get(key) as Promise<T> | undefined;\n }\n\n invalidate(querySubstring: string): void {\n for (const key of this.cache.keys()) {\n if (key.includes(querySubstring)) {\n this.cache.delete(key);\n }\n }\n }\n\n clear(): void {\n this.cache.clear();\n this.inflight.clear();\n }\n}\n","import React, { createContext, useContext, useEffect, useState, useMemo } from 'react';\nimport type { ArchieClient, Session, AuthEvent } from '@archie/js-sdk';\nimport { QueryCache } from './lib/query-cache';\n\n// ─── Context ──────────────────────────────────────────────────\n\ninterface ArchieContextValue {\n client: ArchieClient;\n session: Session | null;\n isLoading: boolean;\n cache: QueryCache;\n}\n\nexport const ArchieContext = createContext<ArchieContextValue | null>(null);\n\n// ─── Provider ─────────────────────────────────────────────────\n\nexport interface ArchieProviderProps {\n client: ArchieClient;\n children: React.ReactNode;\n /** @internal Inject a custom cache (useful for testing). */\n cache?: QueryCache;\n}\n\n/**\n * ArchieProvider — wraps your React app to provide the Archie client and session state.\n *\n * @example\n * ```tsx\n * import { createClient } from '@archie/js-sdk'\n * import { ArchieProvider } from '@archie/react-sdk'\n *\n * const archie = createClient({ projectId: '...' })\n *\n * function App() {\n * return (\n * <ArchieProvider client={archie}>\n * <MyApp />\n * </ArchieProvider>\n * )\n * }\n * ```\n */\nexport function ArchieProvider({ client, children, cache: injectedCache }: ArchieProviderProps) {\n const [session, setSession] = useState<Session | null>(client.auth.getSession());\n const [isLoading, setIsLoading] = useState(true);\n const defaultCache = useMemo(() => new QueryCache(), [client]);\n const cache = injectedCache ?? defaultCache;\n\n useEffect(() => {\n client.auth.waitForInit().then(() => {\n setSession(client.auth.getSession());\n setIsLoading(false);\n });\n\n const unsubscribe = client.auth.onAuthStateChange(\n (_event: AuthEvent, newSession: Session | null) => {\n setSession(newSession);\n },\n );\n\n return unsubscribe;\n }, [client]);\n\n const value = useMemo<ArchieContextValue>(\n () => ({ client, session, isLoading, cache }),\n [client, session, isLoading, cache],\n );\n\n return React.createElement(ArchieContext.Provider, { value }, children);\n}\n\n/**\n * Internal hook to access the Archie context.\n * @throws if used outside ArchieProvider\n * @internal\n */\nexport function useArchieContext(): ArchieContextValue {\n const context = useContext(ArchieContext);\n if (!context) {\n throw new Error(\n 'useArchieClient must be used within an <ArchieProvider>. ' +\n 'Wrap your app with <ArchieProvider client={archieClient}>.',\n );\n }\n return context;\n}\n","import { useArchieContext } from '../provider';\nimport type { ArchieClient } from '@archie/js-sdk';\n\n/**\n * Returns the ArchieClient instance from context.\n * Must be used within an ArchieProvider.\n *\n * @throws Error if used outside ArchieProvider\n */\nexport function useArchieClient(): ArchieClient {\n const { client } = useArchieContext();\n return client;\n}\n","import { useCallback, useMemo } from 'react';\nimport { useArchieContext } from '../provider';\nimport type {\n User,\n Session,\n AuthSignUpParams,\n AuthSignInParams,\n AuthConfirmParams,\n AuthRecoverParams,\n AuthResetPasswordParams,\n ArchieError,\n} from '@archie/js-sdk';\n\ninterface UseAuthReturn {\n user: User | null;\n session: Session | null;\n isLoading: boolean;\n isAuthenticated: boolean;\n signIn: (\n params: AuthSignInParams,\n ) => Promise<{ session: Session | null; error: ArchieError | null }>;\n signUp: (\n params: AuthSignUpParams,\n ) => Promise<{ data: { userId: string; message: string } | null; error: ArchieError | null }>;\n signOut: () => Promise<void>;\n confirmSignUp: (\n params: AuthConfirmParams,\n ) => Promise<{ session: Session | null; error: ArchieError | null }>;\n recoverPassword: (\n params: AuthRecoverParams,\n ) => Promise<{ data: { message: string } | null; error: ArchieError | null }>;\n resetPassword: (\n params: AuthResetPasswordParams,\n ) => Promise<{ data: { message: string } | null; error: ArchieError | null }>;\n refreshSession: () => Promise<{ session: Session | null; error: ArchieError | null }>;\n}\n\n/**\n * Hook for authentication state and operations.\n * All methods return `{ data/session, error }` (never throws).\n */\nexport function useAuth(): UseAuthReturn {\n const { client, session, isLoading } = useArchieContext();\n\n const signIn = useCallback(\n async (params: AuthSignInParams) => {\n try {\n const result = await client.auth.signIn(params);\n return { session: result.session, error: null };\n } catch (err) {\n return { session: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const signUp = useCallback(\n async (params: AuthSignUpParams) => {\n try {\n const result = await client.auth.signUp(params);\n return { data: result, error: null };\n } catch (err) {\n return { data: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const signOut = useCallback(async () => {\n await client.auth.signOut();\n }, [client]);\n\n const confirmSignUp = useCallback(\n async (params: AuthConfirmParams) => {\n try {\n const result = await client.auth.confirmSignUp(params);\n return { session: result.session, error: null };\n } catch (err) {\n return { session: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const recoverPassword = useCallback(\n async (params: AuthRecoverParams) => {\n try {\n const result = await client.auth.recoverPassword(params);\n return { data: result, error: null };\n } catch (err) {\n return { data: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const resetPassword = useCallback(\n async (params: AuthResetPasswordParams) => {\n try {\n const result = await client.auth.resetPassword(params);\n return { data: result, error: null };\n } catch (err) {\n return { data: null, error: err as ArchieError };\n }\n },\n [client],\n );\n\n const refreshSession = useCallback(async () => {\n try {\n const result = await client.auth.refreshSession();\n return { session: result.session, error: null };\n } catch (err) {\n return { session: null, error: err as ArchieError };\n }\n }, [client]);\n\n return useMemo(\n () => ({\n user: session?.user ?? null,\n session,\n isLoading,\n isAuthenticated: session !== null,\n signIn,\n signUp,\n signOut,\n confirmSignUp,\n recoverPassword,\n resetPassword,\n refreshSession,\n }),\n [\n session,\n isLoading,\n signIn,\n signUp,\n signOut,\n confirmSignUp,\n recoverPassword,\n resetPassword,\n refreshSession,\n ],\n );\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport { useArchieContext } from '../provider';\nimport { QueryCache } from '../lib/query-cache';\nimport type { ArchieError } from '@archie/js-sdk';\n\ninterface UseQueryOptions<T> {\n enabled?: boolean;\n refetchInterval?: number;\n refetchOnWindowFocus?: boolean;\n onSuccess?: (data: T) => void;\n onError?: (error: ArchieError) => void;\n}\n\ninterface UseQueryReturn<T> {\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n isRefetching: boolean;\n refetch: () => Promise<void>;\n}\n\n/**\n * Declarative GraphQL query hook with caching and stale-while-revalidate.\n *\n * @example\n * ```tsx\n * const { data, isLoading } = useQuery<{ users: User[] }>(\n * 'query { users { id email name } }',\n * { limit: 10 }\n * )\n * ```\n */\nexport function useQuery<T = unknown>(\n gql: string,\n variables?: Record<string, unknown>,\n options?: UseQueryOptions<T>,\n): UseQueryReturn<T> {\n const { client, session, cache } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [isRefetching, setIsRefetching] = useState(false);\n\n const enabled = options?.enabled !== false;\n\n const variablesKey = variables ? JSON.stringify(variables) : '';\n const cacheKey = QueryCache.key(gql, variables);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const fetchData = useCallback(\n async (isRefetch = false) => {\n if (!enabled) return;\n\n if (isRefetch) {\n setIsRefetching(true);\n } else {\n setIsLoading(true);\n }\n\n try {\n const result = await cache.dedup(cacheKey, () => client.graphql.query<T>(gql, variables));\n if (result.error) {\n setError(result.error);\n setData(null);\n optionsRef.current?.onError?.(result.error);\n } else {\n setData(result.data);\n setError(null);\n cache.set(cacheKey, result.data);\n optionsRef.current?.onSuccess?.(result.data as T);\n }\n } catch (err) {\n setError(err as ArchieError);\n setData(null);\n } finally {\n setIsLoading(false);\n setIsRefetching(false);\n }\n },\n [client, gql, variablesKey, enabled, cacheKey, cache],\n );\n\n // Initial fetch & refetch on variable change\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n\n const cached = cache.get<T>(cacheKey);\n if (cached) {\n setData(cached.data);\n setIsLoading(false);\n fetchData(true);\n } else {\n fetchData(false);\n }\n }, [cacheKey, enabled]);\n\n // Refetch on auth state change (new token)\n const prevSessionRef = useRef(session?.accessToken);\n useEffect(() => {\n if (\n enabled &&\n prevSessionRef.current !== session?.accessToken &&\n prevSessionRef.current !== undefined\n ) {\n fetchData(true);\n }\n prevSessionRef.current = session?.accessToken;\n }, [session?.accessToken, enabled]);\n\n // Polling (refetchInterval)\n useEffect(() => {\n if (!enabled || !options?.refetchInterval) return;\n\n const interval = setInterval(() => {\n fetchData(true);\n }, options.refetchInterval);\n\n return () => clearInterval(interval);\n }, [enabled, options?.refetchInterval]);\n\n // Refetch on window focus\n useEffect(() => {\n if (!enabled || !options?.refetchOnWindowFocus) return;\n if (typeof window === 'undefined') return;\n\n const handleFocus = () => fetchData(true);\n window.addEventListener('focus', handleFocus);\n return () => window.removeEventListener('focus', handleFocus);\n }, [enabled, options?.refetchOnWindowFocus]);\n\n const refetch = useCallback(() => fetchData(true), [fetchData]);\n\n return { data, error, isLoading, isRefetching, refetch };\n}\n","import { useState, useCallback, useRef } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError } from '@archie/js-sdk';\n\ninterface UseMutationOptions<T> {\n onSuccess?: (data: T) => void;\n onError?: (error: ArchieError) => void;\n onSettled?: () => void;\n /** Query substrings to invalidate (forcing refetch) after a successful mutation. */\n invalidateQueries?: string[];\n}\n\ninterface UseMutationReturn<T> {\n mutate: (variables?: Record<string, unknown>) => void;\n mutateAsync: (variables?: Record<string, unknown>) => Promise<T | null>;\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n reset: () => void;\n}\n\n/**\n * Hook for GraphQL mutations.\n *\n * @example\n * ```tsx\n * const { mutate, isLoading } = useMutation<{ createUser: User }>(\n * 'mutation($data: CreateUserInput!) { createUser(data: $data) { id email } }',\n * { invalidateQueries: ['users'] }\n * )\n *\n * mutate({ data: { email: 'new@user.com', name: 'John' } })\n * ```\n */\nexport function useMutation<T = unknown>(\n gql: string,\n options?: UseMutationOptions<T>,\n): UseMutationReturn<T> {\n const { client, cache } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const execute = useCallback(\n async (variables?: Record<string, unknown>): Promise<T | null> => {\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await client.graphql.mutate<T>(gql, variables);\n\n if (result.error) {\n setError(result.error);\n setData(null);\n optionsRef.current?.onError?.(result.error);\n optionsRef.current?.onSettled?.();\n return null;\n }\n\n setData(result.data);\n setError(null);\n optionsRef.current?.onSuccess?.(result.data as T);\n\n if (optionsRef.current?.invalidateQueries) {\n for (const queryKey of optionsRef.current.invalidateQueries) {\n cache.invalidate(queryKey);\n }\n }\n\n optionsRef.current?.onSettled?.();\n return result.data;\n } catch (err) {\n const archieErr = err as ArchieError;\n setError(archieErr);\n setData(null);\n optionsRef.current?.onError?.(archieErr);\n optionsRef.current?.onSettled?.();\n return null;\n } finally {\n setIsLoading(false);\n }\n },\n [client, gql, cache],\n );\n\n const mutate = useCallback(\n (variables?: Record<string, unknown>) => {\n execute(variables);\n },\n [execute],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsLoading(false);\n }, []);\n\n return { mutate, mutateAsync: execute, data, error, isLoading, reset };\n}\n","import { useState, useEffect, useRef } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, ConnectionState } from '@archie/js-sdk';\n\ninterface UseSubscriptionOptions<T> {\n enabled?: boolean;\n onData?: (data: T) => void;\n onError?: (error: ArchieError) => void;\n}\n\ninterface UseSubscriptionReturn<T> {\n data: T | null;\n error: ArchieError | null;\n connectionState: ConnectionState;\n}\n\n/**\n * Hook for real-time GraphQL subscriptions.\n * Subscribes on mount, unsubscribes on unmount.\n *\n * @example\n * ```tsx\n * const { data } = useSubscription<{ orderUpdated: Order }>(\n * 'subscription { orderUpdated { id status total } }'\n * )\n * ```\n */\nexport function useSubscription<T = unknown>(\n gql: string,\n variables?: Record<string, unknown>,\n options?: UseSubscriptionOptions<T>,\n): UseSubscriptionReturn<T> {\n const { client } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [connectionState, setConnectionState] = useState<ConnectionState>('DISCONNECTED');\n\n const enabled = options?.enabled !== false;\n const variablesKey = variables ? JSON.stringify(variables) : '';\n\n // Track latest callbacks to avoid stale closures\n const callbacksRef = useRef(options);\n callbacksRef.current = options;\n\n useEffect(() => {\n if (!enabled) return;\n\n const unsub = client.realtime.onConnectionStateChange(setConnectionState);\n\n const subscription = client.realtime.subscribe<T>(gql, variables, {\n onData: (newData: T) => {\n setData(newData);\n setError(null);\n callbacksRef.current?.onData?.(newData);\n },\n onError: (err) => {\n setError(err);\n callbacksRef.current?.onError?.(err);\n },\n onComplete: () => {\n // Subscription completed server-side\n },\n });\n\n return () => {\n subscription.unsubscribe();\n unsub();\n };\n }, [client, gql, variablesKey, enabled]);\n\n return { data, error, connectionState };\n}\n","import { useState, useCallback } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, FileUploadOptions, FileUploadResult } from '@archie/js-sdk';\n\ninterface UseFileUploadReturn {\n upload: (file: File | Blob, options?: FileUploadOptions) => Promise<void>;\n progress: number;\n isUploading: boolean;\n data: FileUploadResult | null;\n error: ArchieError | null;\n reset: () => void;\n}\n\n/**\n * Hook for file uploads.\n *\n * @example\n * ```tsx\n * const { upload, isUploading, data } = useFileUpload()\n *\n * <input type=\"file\" onChange={(e) => upload(e.target.files[0])} />\n * {isUploading && <Spinner />}\n * ```\n */\nexport function useFileUpload(): UseFileUploadReturn {\n const { client } = useArchieContext();\n const [progress, setProgress] = useState(0);\n const [isUploading, setIsUploading] = useState(false);\n const [data, setData] = useState<FileUploadResult | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n\n const upload = useCallback(\n async (file: File | Blob, options?: FileUploadOptions) => {\n setIsUploading(true);\n setProgress(0);\n setError(null);\n setData(null);\n\n try {\n const result = await client.files.upload(file, options);\n\n setData(result);\n setProgress(100);\n } catch (err) {\n setError(err as ArchieError);\n } finally {\n setIsUploading(false);\n }\n },\n [client],\n );\n\n const reset = useCallback(() => {\n setProgress(0);\n setIsUploading(false);\n setData(null);\n setError(null);\n }, []);\n\n return { upload, progress, isUploading, data, error, reset };\n}\n","import { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, RestRequestOptions, IRestModule } from '@archie/js-sdk';\n\n// ─── useRest (base) ──────────────────────────────────────────\n\n/**\n * Returns the REST module from the Archie client.\n * Provides direct access to `get`, `post`, `put`, `patch`, `delete`.\n *\n * @example\n * ```tsx\n * const rest = useRest()\n * const data = await rest.get('/api/products')\n * await rest.post('/api/products', { name: 'Widget' })\n * ```\n */\nexport function useRest(): IRestModule {\n const { client } = useArchieContext();\n return useMemo(() => client.rest, [client]);\n}\n\n// ─── useRestQuery ─────────────────────────────────────────────\n\ninterface UseRestQueryReturn<T> {\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n refetch: () => Promise<void>;\n}\n\n/**\n * Declarative hook for GET requests to custom REST APIs.\n */\nexport function useRestQuery<T = unknown>(\n path: string,\n options?: RestRequestOptions & { enabled?: boolean },\n): UseRestQueryReturn<T> {\n const { client } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n\n const enabled = options?.enabled !== false;\n\n const fetchData = useCallback(async () => {\n if (!enabled) return;\n setIsLoading(true);\n\n try {\n const result = await client.rest.get<T>(path, options);\n setData(result);\n setError(null);\n } catch (err) {\n setError(err as ArchieError);\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, path, enabled]);\n\n useEffect(() => {\n if (enabled) {\n fetchData();\n } else {\n setIsLoading(false);\n }\n }, [fetchData, enabled]);\n\n return { data, error, isLoading, refetch: fetchData };\n}\n\n// ─── useRestMutation ──────────────────────────────────────────\n\ninterface UseRestMutationReturn<T> {\n execute: (body?: unknown, overrideOptions?: RestRequestOptions) => Promise<T | null>;\n data: T | null;\n error: ArchieError | null;\n isLoading: boolean;\n reset: () => void;\n}\n\n/**\n * Imperative hook for POST/PUT/PATCH/DELETE requests to custom REST APIs.\n */\nexport function useRestMutation<T = unknown>(\n path: string,\n method: 'POST' | 'PUT' | 'PATCH' | 'DELETE' = 'POST',\n): UseRestMutationReturn<T> {\n const { client } = useArchieContext();\n const [data, setData] = useState<T | null>(null);\n const [error, setError] = useState<ArchieError | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n\n const execute = useCallback(\n async (body?: unknown, overrideOptions?: RestRequestOptions): Promise<T | null> => {\n setIsLoading(true);\n setError(null);\n\n try {\n let result: T;\n switch (method) {\n case 'POST':\n result = await client.rest.post<T>(path, body, overrideOptions);\n break;\n case 'PUT':\n result = await client.rest.put<T>(path, body, overrideOptions);\n break;\n case 'PATCH':\n result = await client.rest.patch<T>(path, body, overrideOptions);\n break;\n case 'DELETE':\n result = await client.rest.delete<T>(path, overrideOptions);\n break;\n }\n\n setData(result);\n setError(null);\n return result;\n } catch (err) {\n const archieErr = err as ArchieError;\n setError(archieErr);\n setData(null);\n return null;\n } finally {\n setIsLoading(false);\n }\n },\n [client, path, method],\n );\n\n const reset = useCallback(() => {\n setData(null);\n setError(null);\n setIsLoading(false);\n }, []);\n\n return { execute, data, error, isLoading, reset };\n}\n","import { useState, useEffect, useRef, useCallback } from 'react';\nimport { useArchieContext } from '../provider';\nimport type { ArchieError, ConnectionState, Notification } from '@archie/js-sdk';\n\nexport interface UseNotificationsOptions {\n enabled?: boolean;\n unreadOnly?: boolean;\n limit?: number;\n onNotification?: (notification: Notification) => void;\n}\n\nexport interface UseNotificationsReturn {\n notifications: Notification[];\n latest: Notification | null;\n unreadCount: number;\n isLoading: boolean;\n error: ArchieError | null;\n connectionState: ConnectionState;\n markAsRead: (id: string) => Promise<void>;\n markAllAsRead: () => Promise<void>;\n refetch: () => Promise<void>;\n}\n\n/**\n * Subscribe to a user's in-app notifications: loads the existing list,\n * then streams new ones live. Returns idiomatic React state.\n *\n * @example\n * ```tsx\n * const { notifications, unreadCount, markAsRead } = useNotifications(user.id);\n * ```\n */\nexport function useNotifications(\n receiverId: string,\n options?: UseNotificationsOptions,\n): UseNotificationsReturn {\n const { client } = useArchieContext();\n const [notifications, setNotifications] = useState<Notification[]>([]);\n const [latest, setLatest] = useState<Notification | null>(null);\n const [unreadCount, setUnreadCount] = useState(0);\n const [isLoading, setIsLoading] = useState(options?.enabled !== false);\n const [error, setError] = useState<ArchieError | null>(null);\n const [connectionState, setConnectionState] = useState<ConnectionState>(\n () => client.realtime.currentState,\n );\n\n const enabled = options?.enabled !== false;\n const unreadOnly = options?.unreadOnly ?? false;\n const limit = options?.limit;\n\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const notificationsRef = useRef<Notification[]>([]);\n notificationsRef.current = notifications;\n\n const seenIdsRef = useRef<Set<string>>(new Set());\n\n // Reset local state when the receiver changes (never show the prior user's data)\n useEffect(() => {\n setNotifications([]);\n setLatest(null);\n setUnreadCount(0);\n seenIdsRef.current = new Set();\n }, [receiverId]);\n\n const load = useCallback(async () => {\n const [listResult, unread] = await Promise.all([\n client.notifications.list(receiverId, { unreadOnly, first: limit }),\n client.notifications.getUnreadCount(receiverId),\n ]);\n return { listResult, unread };\n }, [client, receiverId, unreadOnly, limit]);\n\n // Data load — re-runs on list params; cancellable so stale results never win\n useEffect(() => {\n if (!enabled) {\n setIsLoading(false);\n return;\n }\n let active = true;\n setIsLoading(true);\n load()\n .then(({ listResult, unread }) => {\n if (!active) return;\n setNotifications(listResult.items);\n seenIdsRef.current = new Set(listResult.items.map((n) => n.id));\n setUnreadCount(unread);\n setError(null);\n })\n .catch((err) => {\n if (active) setError(err as ArchieError);\n })\n .finally(() => {\n if (active) setIsLoading(false);\n });\n return () => {\n active = false;\n };\n }, [enabled, load]);\n\n // Live subscription — only re-runs on client/receiverId/enabled, NOT on list params\n useEffect(() => {\n if (!enabled) return;\n const unsubConnection = client.realtime.onConnectionStateChange(setConnectionState);\n setConnectionState(client.realtime.currentState);\n\n const channel = client.notifications.subscribe(receiverId, {\n onError: (err) => setError(err),\n });\n channel.on('*', (notification: Notification) => {\n if (seenIdsRef.current.has(notification.id)) return; // ignore duplicates entirely\n seenIdsRef.current.add(notification.id);\n setNotifications((prev) => [notification, ...prev]);\n setLatest(notification);\n if (!notification.isRead) setUnreadCount((c) => c + 1);\n optionsRef.current?.onNotification?.(notification);\n });\n\n return () => {\n channel.unsubscribe();\n unsubConnection();\n };\n }, [client, receiverId, enabled]);\n\n const markAsRead = useCallback(\n async (id: string) => {\n const wasUnread = notificationsRef.current.find((n) => n.id === id)?.isRead === false;\n try {\n await client.notifications.markAsRead(id);\n setNotifications((prev) =>\n prev.map((n) => (n.id === id && !n.isRead ? { ...n, isRead: true } : n)),\n );\n if (wasUnread) setUnreadCount((c) => Math.max(0, c - 1));\n } catch (err) {\n setError(err as ArchieError);\n throw err;\n }\n },\n [client],\n );\n\n const markAllAsRead = useCallback(async () => {\n try {\n await client.notifications.markAllAsRead(receiverId);\n setNotifications((prev) => prev.map((n) => (n.isRead ? n : { ...n, isRead: true })));\n // Reconcile against the authoritative server count rather than assuming 0\n const count = await client.notifications.getUnreadCount(receiverId);\n setUnreadCount(count);\n } catch (err) {\n setError(err as ArchieError);\n throw err;\n }\n }, [client, receiverId]);\n\n const refetch = useCallback(async () => {\n setIsLoading(true);\n try {\n const { listResult, unread } = await load();\n setNotifications(listResult.items);\n seenIdsRef.current = new Set(listResult.items.map((n) => n.id));\n setUnreadCount(unread);\n setError(null);\n } catch (err) {\n setError(err as ArchieError);\n } finally {\n setIsLoading(false);\n }\n }, [load]);\n\n return {\n notifications,\n latest,\n unreadCount,\n isLoading,\n error,\n connectionState,\n markAsRead,\n markAllAsRead,\n refetch,\n };\n}\n","import React from 'react';\nimport { useAuth } from '../hooks/useAuth';\n\nexport interface AuthGuardProps {\n /** Content to show when authenticated (and authorized if roles specified). */\n children: React.ReactNode;\n /** Content to show when NOT authenticated. */\n fallback?: React.ReactNode;\n /** Content to show while session is loading. */\n loadingComponent?: React.ReactNode;\n /** If specified, user must have at least one of these roles. */\n requiredRoles?: string[];\n}\n\n/**\n * AuthGuard component — conditionally renders children based on auth state.\n *\n * @example\n * ```tsx\n * <AuthGuard fallback={<LoginPage />} requiredRoles={['admin']}>\n * <AdminPanel />\n * </AuthGuard>\n * ```\n */\nexport function AuthGuard({\n children,\n fallback = null,\n loadingComponent = null,\n requiredRoles,\n}: AuthGuardProps) {\n const { user, isLoading, isAuthenticated } = useAuth();\n\n if (isLoading) {\n return React.createElement(React.Fragment, null, loadingComponent);\n }\n\n if (!isAuthenticated || !user) {\n return React.createElement(React.Fragment, null, fallback);\n }\n\n // Check roles if required\n if (requiredRoles && requiredRoles.length > 0) {\n const hasRequiredRole = requiredRoles.some((role) => user.roles.includes(role));\n if (!hasRequiredRole) {\n return React.createElement(React.Fragment, null, fallback);\n }\n }\n\n return React.createElement(React.Fragment, null, children);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archie/react-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Archie BAAS - React hooks, provider & components",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,7 @@
20
20
  ],
21
21
  "peerDependencies": {
22
22
  "react": ">=18.0.0",
23
- "@archie/js-sdk": "0.1.3"
23
+ "@archie/js-sdk": "0.2.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "react": "^19.0.0",
@@ -32,7 +32,7 @@
32
32
  "@testing-library/react": "^16.0.0",
33
33
  "@testing-library/jest-dom": "^6.0.0",
34
34
  "jsdom": "^25.0.0",
35
- "@archie/js-sdk": "0.1.3"
35
+ "@archie/js-sdk": "0.2.0"
36
36
  },
37
37
  "sideEffects": false,
38
38
  "keywords": [