@hipnation-truth/sdk 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/react.d.mts CHANGED
@@ -2,6 +2,194 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { ConvexReactClient } from 'convex/react';
4
4
 
5
+ /**
6
+ * React hooks for Truth SDK — reactive conversation + message data.
7
+ *
8
+ * Wraps Convex queries owned by the Truth backend so consumers (CommHub
9
+ * Expo frontend) get live-updating conversation lists, message threads,
10
+ * and unread totals without managing subscriptions themselves.
11
+ *
12
+ * **Hook contract:** every hook in this file returns
13
+ * `{ data, loading, error }`. `data` is `undefined` while loading and
14
+ * also when the underlying query is `"skip"`'d (caller didn't pass the
15
+ * required arg yet). `loading` is `true` only while a real subscription
16
+ * is in-flight; once `data` resolves (even to `null`) `loading` flips
17
+ * to `false`. `error` is reserved for SDK-side validation — Convex
18
+ * itself throws on subscribe rather than returning an error value, so
19
+ * unhandled query errors propagate as React errors and should be caught
20
+ * with an error boundary.
21
+ *
22
+ * **Backed by PR #110 schema (commit `41dbb59` on
23
+ * `feat/migrate-dialpad-webhook-and-messages-to-truth`):**
24
+ * - `conversations:listForUser` → `useConversations`
25
+ * - `conversations:getUnreadTotalForUser` → `useUnreadCount`
26
+ * - `conversations:getByPhonePair` → `useConversationByPhonePair`
27
+ * - `conversationMessages:getByConversationId` → `useMessages`
28
+ *
29
+ * **Deliberately NOT shipped here (no backend query yet — flagged in
30
+ * PR #111 body for follow-up):**
31
+ * - Single-conversation-by-id lookup. Convex `conversations` has no
32
+ * `get(id)` query — only `getByPhonePair`. CommHub uses phonePair as
33
+ * the primary handle, so the byPair flavor is what consumers need;
34
+ * if id-based lookup is needed later we can add a `conversations:get`
35
+ * in Truth.
36
+ * - Participants / "seen by" hook. The migrated schema has no
37
+ * `conversationParticipants` table — read state is per-user via
38
+ * `conversationReads` and there's no public list query for it yet.
39
+ * - `markRead` mutation. PR #110 declares `markRead` as
40
+ * `internalMutation`, so the frontend can't invoke it directly — it
41
+ * has to go through a Truth HTTP endpoint, or webhook-migrator needs
42
+ * to flip it to a public `mutation`. Flagged for a follow-up.
43
+ *
44
+ * Must be used within `<TruthProvider />` (see `./provider`).
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * import {
49
+ * useConversations,
50
+ * useConversationByPhonePair,
51
+ * useMessages,
52
+ * useUnreadCount,
53
+ * } from '@hipnation-truth/sdk/react';
54
+ *
55
+ * function Inbox({ userId }: { userId: string }) {
56
+ * const { data: convos, loading } = useConversations({ userId });
57
+ * const { data: unread } = useUnreadCount(userId);
58
+ * if (loading) return <Spinner />;
59
+ * return (
60
+ * <div>
61
+ * <Badge count={unread ?? 0} />
62
+ * {convos?.map((c) => <ConvoRow key={c.id} convo={c} />)}
63
+ * </div>
64
+ * );
65
+ * }
66
+ * ```
67
+ */
68
+ /**
69
+ * Row shape returned by `conversations:listForUser` — joins the base
70
+ * `conversations` row with the caller's per-user `conversationReads`
71
+ * entry so unread state lives on each item.
72
+ */
73
+ interface ConversationListItem {
74
+ /** Convex id of the conversation row. */
75
+ id: string;
76
+ patientPhone: string;
77
+ providerPhone: string;
78
+ /** Sorted-digit-pair key (commutative — same regardless of direction). */
79
+ phonePair: string;
80
+ /** Truth-side patient id, when the kinesis pipeline could resolve it. */
81
+ patientId: string | null;
82
+ /** ISO timestamp of the most recent message in the conversation. */
83
+ lastMessageAt: string;
84
+ /** Caller's unread count for this conversation. */
85
+ unreadCount: number;
86
+ /** ISO timestamp of when the caller last marked the conversation read. */
87
+ lastReadAt: string | null;
88
+ }
89
+ /**
90
+ * Raw `conversations` table row — what `getByPhonePair` returns. No
91
+ * unread / read joining; for that, prefer `useConversations`.
92
+ */
93
+ interface ConversationRow {
94
+ _id: string;
95
+ _creationTime: number;
96
+ patientPhone: string;
97
+ providerPhone: string;
98
+ phonePair: string;
99
+ patientId: string | null;
100
+ lastEventId: string | null;
101
+ lastMessageAt: string;
102
+ createdAt: string;
103
+ }
104
+ /**
105
+ * Message row returned by `conversationMessages:getByConversationId` —
106
+ * calls + SMS merged chronologically. Mirrors `ConversationMessage`
107
+ * already exported from the SDK; re-exported here under a clearer name
108
+ * for the new hook surface.
109
+ */
110
+ interface ConversationMessageRow {
111
+ kind: "call" | "sms";
112
+ id: string;
113
+ providerId: string;
114
+ state: string | null;
115
+ direction: string | null;
116
+ fromNumber: string | null;
117
+ toNumber: string | null;
118
+ voicemailLink: string | null;
119
+ duration: number | null;
120
+ text: string | null;
121
+ mms: boolean;
122
+ mmsUrl: string | null;
123
+ messageStatus: string | null;
124
+ occurredAt: string;
125
+ conversationId: string | null;
126
+ patientId: string | null;
127
+ }
128
+ interface UseQueryResult<T> {
129
+ /**
130
+ * Query data. `undefined` while loading or while the query is
131
+ * intentionally skipped (e.g. caller hasn't supplied `userId` yet).
132
+ */
133
+ data: T | undefined;
134
+ /** True only while a real subscription is in-flight. */
135
+ loading: boolean;
136
+ /**
137
+ * Reserved for client-side validation errors surfaced by the SDK
138
+ * itself. Convex query errors propagate as React errors and should
139
+ * be caught with an error boundary.
140
+ */
141
+ error: Error | undefined;
142
+ }
143
+ interface UseConversationsFilters {
144
+ /**
145
+ * Truth user id (the Better Auth subject). Pass `undefined` to skip
146
+ * the query — useful when the auth session is still loading.
147
+ */
148
+ userId: string | null | undefined;
149
+ /** Page size. Server caps at 100 by default. */
150
+ limit?: number;
151
+ }
152
+ interface UseMessagesOptions {
153
+ /** Page size. Server caps at 200 by default. */
154
+ limit?: number;
155
+ }
156
+ /**
157
+ * Subscribe to a user's conversations — joined with their per-conversation
158
+ * unread count, sorted by most recent message. Updates live as new
159
+ * SMS / calls land in Convex and the webhook bumps `unreadCount`.
160
+ *
161
+ * Returns `{ data: undefined, loading: false }` while the auth session
162
+ * resolves (`userId === undefined`); not an error, just a skip.
163
+ */
164
+ declare function useConversations(filters: UseConversationsFilters): UseQueryResult<ConversationListItem[]>;
165
+ /**
166
+ * Look up a single conversation by its normalized phonePair (sorted
167
+ * digit-pair, e.g. `"5125550123|6505551234"`). Returns `null` if no
168
+ * conversation exists yet for that pair.
169
+ *
170
+ * Use the `phonePairKey(patientPhone, providerPhone)` helper exposed by
171
+ * the Truth Convex module to derive the key from raw phone strings.
172
+ */
173
+ declare function useConversationByPhonePair(phonePair: string | null | undefined): UseQueryResult<ConversationRow | null>;
174
+ /**
175
+ * Subscribe to a paginated message stream for a single conversation.
176
+ * Calls + SMS merged chronologically, newest-first. Live as the
177
+ * kinesis consumer writes to `messageCalls` / `messageSms`.
178
+ *
179
+ * Pass the Convex `_id` of the conversation row (from
180
+ * `useConversations` / `useConversationByPhonePair`) as
181
+ * `conversationId`.
182
+ */
183
+ declare function useMessages(conversationId: string | null | undefined, options?: UseMessagesOptions): UseQueryResult<ConversationMessageRow[]>;
184
+ /**
185
+ * Subscribe to the user's total unread message count across all
186
+ * conversations. Backs the inbox tab badge in CommHub.
187
+ *
188
+ * Returns `0` when the underlying query resolves with no unread
189
+ * messages, `undefined` while loading or when `userId` is missing.
190
+ */
191
+ declare function useUnreadCount(userId: string | null | undefined): UseQueryResult<number>;
192
+
5
193
  /**
6
194
  * React hooks for Truth SDK — real-time Convex-backed data access.
7
195
  *
@@ -222,6 +410,61 @@ declare function useConversationMessages(input: {
222
410
  conversationId?: string;
223
411
  }, options?: UseConversationMessagesOptions): ConversationMessage[] | undefined;
224
412
 
413
+ /**
414
+ * useNotifications — Truth SDK React hook for push notifications.
415
+ *
416
+ * Shape-compatible with `expo-notifications` where practical so
417
+ * consumers port with minimal change. The hook dynamically imports
418
+ * `expo-notifications` so the SDK doesn't hard-depend on Expo —
419
+ * consumers running on a non-Expo runtime (e.g. a server test harness)
420
+ * can still import the SDK without Metro blowing up.
421
+ *
422
+ * Exposes:
423
+ * - permissionStatus — "granted" / "denied" / "undetermined"
424
+ * - devicePushToken — native APNs/FCM token (undefined until register)
425
+ * - register() — request permission, fetch token, register with Truth
426
+ * - unregister() — revoke the device
427
+ * - addReceivedListener / addResponseListener — re-exports of expo's
428
+ * - getBadgeCount / setBadgeCount — re-exports of expo's
429
+ *
430
+ * Web push (VAPID subscription) lands in Phase 3.
431
+ */
432
+ type PermissionStatus = "granted" | "denied" | "undetermined" | "unknown";
433
+ interface UseNotificationsOptions {
434
+ /** Truth API base URL, e.g. https://app.truth.communication-hub.com */
435
+ apiBaseUrl: string;
436
+ /** `hn_live_*` API key for the caller's application. */
437
+ apiKey: string;
438
+ /** Current user id — used when registering the device. */
439
+ userId: string | null | undefined;
440
+ /** Optional app version string stored on the device row. */
441
+ appVersion?: string;
442
+ /**
443
+ * Auto-register on mount when permission is already granted.
444
+ * Default: true. Set false if you want to control the registration
445
+ * lifecycle yourself.
446
+ */
447
+ autoRegister?: boolean;
448
+ /** VAPID public key for web push. Fetched automatically if omitted. */
449
+ vapidPublicKey?: string;
450
+ /** Path to the service worker file. Default: "/truth-sw.js" */
451
+ serviceWorkerPath?: string;
452
+ }
453
+ interface UseNotificationsResult {
454
+ permissionStatus: PermissionStatus;
455
+ devicePushToken: string | null;
456
+ register: () => Promise<{
457
+ ok: boolean;
458
+ reason?: string;
459
+ }>;
460
+ unregister: () => Promise<void>;
461
+ addReceivedListener: (listener: (n: unknown) => void) => () => void;
462
+ addResponseListener: (listener: (r: unknown) => void) => () => void;
463
+ getBadgeCount: () => Promise<number>;
464
+ setBadgeCount: (count: number) => Promise<void>;
465
+ }
466
+ declare function useNotifications(options: UseNotificationsOptions): UseNotificationsResult;
467
+
225
468
  interface TruthProviderProps {
226
469
  /** Truth environment — determines which Convex deployment to connect to */
227
470
  environment?: string;
@@ -652,4 +895,4 @@ interface PatientListOptions {
652
895
  cursor?: string;
653
896
  }
654
897
 
655
- export { type Appointment, type AppointmentListOptions, type ConversationMessage, type EventPayloadMap, type EventType, type Patient, type PatientListOptions, type Physician, type TrackOptions, TruthProvider, type TruthProviderProps, type TruthTrackingContextValue, TruthTrackingProvider, type TruthTrackingProviderProps, type UseAppointmentListOptions, type UseConversationMessagesOptions, type UsePatientBasicOptions, type UsePatientBasicResult, type UsePatientListOptions, type UsePatientMedicalOptions, type UsePatientPhotoOptions, useAppointment, useAppointmentByElationId, useAppointments, useConversationMessages, usePatient, usePatientBasic, usePatientByElationId, usePatientByHintId, usePatientMedical, usePatientPhoto, usePatients, usePharmacyByNcpdpId, usePhysicianByElationId, usePhysiciansByElationIds, useTruth };
898
+ export { type Appointment, type AppointmentListOptions, type ConversationListItem, type ConversationMessage, type ConversationMessageRow, type ConversationRow, type EventPayloadMap, type EventType, type Patient, type PatientListOptions, type PermissionStatus, type Physician, type TrackOptions, TruthProvider, type TruthProviderProps, type TruthTrackingContextValue, TruthTrackingProvider, type TruthTrackingProviderProps, type UseAppointmentListOptions, type UseConversationMessagesOptions, type UseConversationsFilters, type UseMessagesOptions, type UseNotificationsOptions, type UseNotificationsResult, type UsePatientBasicOptions, type UsePatientBasicResult, type UsePatientListOptions, type UsePatientMedicalOptions, type UsePatientPhotoOptions, type UseQueryResult, useAppointment, useAppointmentByElationId, useAppointments, useConversationByPhonePair, useConversationMessages, useConversations, useMessages, useNotifications, usePatient, usePatientBasic, usePatientByElationId, usePatientByHintId, usePatientMedical, usePatientPhoto, usePatients, usePharmacyByNcpdpId, usePhysicianByElationId, usePhysiciansByElationIds, useTruth, useUnreadCount };
package/dist/react.d.ts CHANGED
@@ -2,6 +2,194 @@ import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { ConvexReactClient } from 'convex/react';
4
4
 
5
+ /**
6
+ * React hooks for Truth SDK — reactive conversation + message data.
7
+ *
8
+ * Wraps Convex queries owned by the Truth backend so consumers (CommHub
9
+ * Expo frontend) get live-updating conversation lists, message threads,
10
+ * and unread totals without managing subscriptions themselves.
11
+ *
12
+ * **Hook contract:** every hook in this file returns
13
+ * `{ data, loading, error }`. `data` is `undefined` while loading and
14
+ * also when the underlying query is `"skip"`'d (caller didn't pass the
15
+ * required arg yet). `loading` is `true` only while a real subscription
16
+ * is in-flight; once `data` resolves (even to `null`) `loading` flips
17
+ * to `false`. `error` is reserved for SDK-side validation — Convex
18
+ * itself throws on subscribe rather than returning an error value, so
19
+ * unhandled query errors propagate as React errors and should be caught
20
+ * with an error boundary.
21
+ *
22
+ * **Backed by PR #110 schema (commit `41dbb59` on
23
+ * `feat/migrate-dialpad-webhook-and-messages-to-truth`):**
24
+ * - `conversations:listForUser` → `useConversations`
25
+ * - `conversations:getUnreadTotalForUser` → `useUnreadCount`
26
+ * - `conversations:getByPhonePair` → `useConversationByPhonePair`
27
+ * - `conversationMessages:getByConversationId` → `useMessages`
28
+ *
29
+ * **Deliberately NOT shipped here (no backend query yet — flagged in
30
+ * PR #111 body for follow-up):**
31
+ * - Single-conversation-by-id lookup. Convex `conversations` has no
32
+ * `get(id)` query — only `getByPhonePair`. CommHub uses phonePair as
33
+ * the primary handle, so the byPair flavor is what consumers need;
34
+ * if id-based lookup is needed later we can add a `conversations:get`
35
+ * in Truth.
36
+ * - Participants / "seen by" hook. The migrated schema has no
37
+ * `conversationParticipants` table — read state is per-user via
38
+ * `conversationReads` and there's no public list query for it yet.
39
+ * - `markRead` mutation. PR #110 declares `markRead` as
40
+ * `internalMutation`, so the frontend can't invoke it directly — it
41
+ * has to go through a Truth HTTP endpoint, or webhook-migrator needs
42
+ * to flip it to a public `mutation`. Flagged for a follow-up.
43
+ *
44
+ * Must be used within `<TruthProvider />` (see `./provider`).
45
+ *
46
+ * @example
47
+ * ```tsx
48
+ * import {
49
+ * useConversations,
50
+ * useConversationByPhonePair,
51
+ * useMessages,
52
+ * useUnreadCount,
53
+ * } from '@hipnation-truth/sdk/react';
54
+ *
55
+ * function Inbox({ userId }: { userId: string }) {
56
+ * const { data: convos, loading } = useConversations({ userId });
57
+ * const { data: unread } = useUnreadCount(userId);
58
+ * if (loading) return <Spinner />;
59
+ * return (
60
+ * <div>
61
+ * <Badge count={unread ?? 0} />
62
+ * {convos?.map((c) => <ConvoRow key={c.id} convo={c} />)}
63
+ * </div>
64
+ * );
65
+ * }
66
+ * ```
67
+ */
68
+ /**
69
+ * Row shape returned by `conversations:listForUser` — joins the base
70
+ * `conversations` row with the caller's per-user `conversationReads`
71
+ * entry so unread state lives on each item.
72
+ */
73
+ interface ConversationListItem {
74
+ /** Convex id of the conversation row. */
75
+ id: string;
76
+ patientPhone: string;
77
+ providerPhone: string;
78
+ /** Sorted-digit-pair key (commutative — same regardless of direction). */
79
+ phonePair: string;
80
+ /** Truth-side patient id, when the kinesis pipeline could resolve it. */
81
+ patientId: string | null;
82
+ /** ISO timestamp of the most recent message in the conversation. */
83
+ lastMessageAt: string;
84
+ /** Caller's unread count for this conversation. */
85
+ unreadCount: number;
86
+ /** ISO timestamp of when the caller last marked the conversation read. */
87
+ lastReadAt: string | null;
88
+ }
89
+ /**
90
+ * Raw `conversations` table row — what `getByPhonePair` returns. No
91
+ * unread / read joining; for that, prefer `useConversations`.
92
+ */
93
+ interface ConversationRow {
94
+ _id: string;
95
+ _creationTime: number;
96
+ patientPhone: string;
97
+ providerPhone: string;
98
+ phonePair: string;
99
+ patientId: string | null;
100
+ lastEventId: string | null;
101
+ lastMessageAt: string;
102
+ createdAt: string;
103
+ }
104
+ /**
105
+ * Message row returned by `conversationMessages:getByConversationId` —
106
+ * calls + SMS merged chronologically. Mirrors `ConversationMessage`
107
+ * already exported from the SDK; re-exported here under a clearer name
108
+ * for the new hook surface.
109
+ */
110
+ interface ConversationMessageRow {
111
+ kind: "call" | "sms";
112
+ id: string;
113
+ providerId: string;
114
+ state: string | null;
115
+ direction: string | null;
116
+ fromNumber: string | null;
117
+ toNumber: string | null;
118
+ voicemailLink: string | null;
119
+ duration: number | null;
120
+ text: string | null;
121
+ mms: boolean;
122
+ mmsUrl: string | null;
123
+ messageStatus: string | null;
124
+ occurredAt: string;
125
+ conversationId: string | null;
126
+ patientId: string | null;
127
+ }
128
+ interface UseQueryResult<T> {
129
+ /**
130
+ * Query data. `undefined` while loading or while the query is
131
+ * intentionally skipped (e.g. caller hasn't supplied `userId` yet).
132
+ */
133
+ data: T | undefined;
134
+ /** True only while a real subscription is in-flight. */
135
+ loading: boolean;
136
+ /**
137
+ * Reserved for client-side validation errors surfaced by the SDK
138
+ * itself. Convex query errors propagate as React errors and should
139
+ * be caught with an error boundary.
140
+ */
141
+ error: Error | undefined;
142
+ }
143
+ interface UseConversationsFilters {
144
+ /**
145
+ * Truth user id (the Better Auth subject). Pass `undefined` to skip
146
+ * the query — useful when the auth session is still loading.
147
+ */
148
+ userId: string | null | undefined;
149
+ /** Page size. Server caps at 100 by default. */
150
+ limit?: number;
151
+ }
152
+ interface UseMessagesOptions {
153
+ /** Page size. Server caps at 200 by default. */
154
+ limit?: number;
155
+ }
156
+ /**
157
+ * Subscribe to a user's conversations — joined with their per-conversation
158
+ * unread count, sorted by most recent message. Updates live as new
159
+ * SMS / calls land in Convex and the webhook bumps `unreadCount`.
160
+ *
161
+ * Returns `{ data: undefined, loading: false }` while the auth session
162
+ * resolves (`userId === undefined`); not an error, just a skip.
163
+ */
164
+ declare function useConversations(filters: UseConversationsFilters): UseQueryResult<ConversationListItem[]>;
165
+ /**
166
+ * Look up a single conversation by its normalized phonePair (sorted
167
+ * digit-pair, e.g. `"5125550123|6505551234"`). Returns `null` if no
168
+ * conversation exists yet for that pair.
169
+ *
170
+ * Use the `phonePairKey(patientPhone, providerPhone)` helper exposed by
171
+ * the Truth Convex module to derive the key from raw phone strings.
172
+ */
173
+ declare function useConversationByPhonePair(phonePair: string | null | undefined): UseQueryResult<ConversationRow | null>;
174
+ /**
175
+ * Subscribe to a paginated message stream for a single conversation.
176
+ * Calls + SMS merged chronologically, newest-first. Live as the
177
+ * kinesis consumer writes to `messageCalls` / `messageSms`.
178
+ *
179
+ * Pass the Convex `_id` of the conversation row (from
180
+ * `useConversations` / `useConversationByPhonePair`) as
181
+ * `conversationId`.
182
+ */
183
+ declare function useMessages(conversationId: string | null | undefined, options?: UseMessagesOptions): UseQueryResult<ConversationMessageRow[]>;
184
+ /**
185
+ * Subscribe to the user's total unread message count across all
186
+ * conversations. Backs the inbox tab badge in CommHub.
187
+ *
188
+ * Returns `0` when the underlying query resolves with no unread
189
+ * messages, `undefined` while loading or when `userId` is missing.
190
+ */
191
+ declare function useUnreadCount(userId: string | null | undefined): UseQueryResult<number>;
192
+
5
193
  /**
6
194
  * React hooks for Truth SDK — real-time Convex-backed data access.
7
195
  *
@@ -222,6 +410,61 @@ declare function useConversationMessages(input: {
222
410
  conversationId?: string;
223
411
  }, options?: UseConversationMessagesOptions): ConversationMessage[] | undefined;
224
412
 
413
+ /**
414
+ * useNotifications — Truth SDK React hook for push notifications.
415
+ *
416
+ * Shape-compatible with `expo-notifications` where practical so
417
+ * consumers port with minimal change. The hook dynamically imports
418
+ * `expo-notifications` so the SDK doesn't hard-depend on Expo —
419
+ * consumers running on a non-Expo runtime (e.g. a server test harness)
420
+ * can still import the SDK without Metro blowing up.
421
+ *
422
+ * Exposes:
423
+ * - permissionStatus — "granted" / "denied" / "undetermined"
424
+ * - devicePushToken — native APNs/FCM token (undefined until register)
425
+ * - register() — request permission, fetch token, register with Truth
426
+ * - unregister() — revoke the device
427
+ * - addReceivedListener / addResponseListener — re-exports of expo's
428
+ * - getBadgeCount / setBadgeCount — re-exports of expo's
429
+ *
430
+ * Web push (VAPID subscription) lands in Phase 3.
431
+ */
432
+ type PermissionStatus = "granted" | "denied" | "undetermined" | "unknown";
433
+ interface UseNotificationsOptions {
434
+ /** Truth API base URL, e.g. https://app.truth.communication-hub.com */
435
+ apiBaseUrl: string;
436
+ /** `hn_live_*` API key for the caller's application. */
437
+ apiKey: string;
438
+ /** Current user id — used when registering the device. */
439
+ userId: string | null | undefined;
440
+ /** Optional app version string stored on the device row. */
441
+ appVersion?: string;
442
+ /**
443
+ * Auto-register on mount when permission is already granted.
444
+ * Default: true. Set false if you want to control the registration
445
+ * lifecycle yourself.
446
+ */
447
+ autoRegister?: boolean;
448
+ /** VAPID public key for web push. Fetched automatically if omitted. */
449
+ vapidPublicKey?: string;
450
+ /** Path to the service worker file. Default: "/truth-sw.js" */
451
+ serviceWorkerPath?: string;
452
+ }
453
+ interface UseNotificationsResult {
454
+ permissionStatus: PermissionStatus;
455
+ devicePushToken: string | null;
456
+ register: () => Promise<{
457
+ ok: boolean;
458
+ reason?: string;
459
+ }>;
460
+ unregister: () => Promise<void>;
461
+ addReceivedListener: (listener: (n: unknown) => void) => () => void;
462
+ addResponseListener: (listener: (r: unknown) => void) => () => void;
463
+ getBadgeCount: () => Promise<number>;
464
+ setBadgeCount: (count: number) => Promise<void>;
465
+ }
466
+ declare function useNotifications(options: UseNotificationsOptions): UseNotificationsResult;
467
+
225
468
  interface TruthProviderProps {
226
469
  /** Truth environment — determines which Convex deployment to connect to */
227
470
  environment?: string;
@@ -652,4 +895,4 @@ interface PatientListOptions {
652
895
  cursor?: string;
653
896
  }
654
897
 
655
- export { type Appointment, type AppointmentListOptions, type ConversationMessage, type EventPayloadMap, type EventType, type Patient, type PatientListOptions, type Physician, type TrackOptions, TruthProvider, type TruthProviderProps, type TruthTrackingContextValue, TruthTrackingProvider, type TruthTrackingProviderProps, type UseAppointmentListOptions, type UseConversationMessagesOptions, type UsePatientBasicOptions, type UsePatientBasicResult, type UsePatientListOptions, type UsePatientMedicalOptions, type UsePatientPhotoOptions, useAppointment, useAppointmentByElationId, useAppointments, useConversationMessages, usePatient, usePatientBasic, usePatientByElationId, usePatientByHintId, usePatientMedical, usePatientPhoto, usePatients, usePharmacyByNcpdpId, usePhysicianByElationId, usePhysiciansByElationIds, useTruth };
898
+ export { type Appointment, type AppointmentListOptions, type ConversationListItem, type ConversationMessage, type ConversationMessageRow, type ConversationRow, type EventPayloadMap, type EventType, type Patient, type PatientListOptions, type PermissionStatus, type Physician, type TrackOptions, TruthProvider, type TruthProviderProps, type TruthTrackingContextValue, TruthTrackingProvider, type TruthTrackingProviderProps, type UseAppointmentListOptions, type UseConversationMessagesOptions, type UseConversationsFilters, type UseMessagesOptions, type UseNotificationsOptions, type UseNotificationsResult, type UsePatientBasicOptions, type UsePatientBasicResult, type UsePatientListOptions, type UsePatientMedicalOptions, type UsePatientPhotoOptions, type UseQueryResult, useAppointment, useAppointmentByElationId, useAppointments, useConversationByPhonePair, useConversationMessages, useConversations, useMessages, useNotifications, usePatient, usePatientBasic, usePatientByElationId, usePatientByHintId, usePatientMedical, usePatientPhoto, usePatients, usePharmacyByNcpdpId, usePhysicianByElationId, usePhysiciansByElationIds, useTruth, useUnreadCount };