@hipnation-truth/sdk 0.5.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/index.d.mts +201 -1
- package/dist/index.d.ts +201 -1
- package/dist/index.js +294 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +286 -2
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +281 -1
- package/dist/react.d.ts +281 -1
- package/dist/react.js +546 -58
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +527 -45
- package/dist/react.mjs.map +1 -1
- package/package.json +6 -3
package/dist/react.mjs
CHANGED
|
@@ -21,79 +21,136 @@ var __async = (__this, __arguments, generator) => {
|
|
|
21
21
|
});
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
// src/react/
|
|
24
|
+
// src/react/conversations.ts
|
|
25
25
|
import { useQuery } from "convex/react";
|
|
26
|
-
import { useEffect } from "react";
|
|
27
26
|
import { makeFunctionReference } from "convex/server";
|
|
28
|
-
var
|
|
29
|
-
var
|
|
30
|
-
var
|
|
31
|
-
var
|
|
32
|
-
var
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
var conversationsListForUserRef = makeFunctionReference("conversations:listForUser");
|
|
28
|
+
var conversationsGetUnreadTotalForUserRef = makeFunctionReference("conversations:getUnreadTotalForUser");
|
|
29
|
+
var conversationsGetByPhonePairRef = makeFunctionReference("conversations:getByPhonePair");
|
|
30
|
+
var conversationMessagesGetByConversationIdRef = makeFunctionReference("conversationMessages:getByConversationId");
|
|
31
|
+
var SKIP = "skip";
|
|
32
|
+
function toResult(value, skipped) {
|
|
33
|
+
if (skipped) {
|
|
34
|
+
return { data: void 0, loading: false, error: void 0 };
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
data: value,
|
|
38
|
+
loading: value === void 0,
|
|
39
|
+
error: void 0
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function useConversations(filters) {
|
|
43
|
+
const skipped = !filters.userId;
|
|
44
|
+
const result = useQuery(
|
|
45
|
+
conversationsListForUserRef,
|
|
46
|
+
skipped ? SKIP : {
|
|
47
|
+
userId: filters.userId,
|
|
48
|
+
limit: filters.limit
|
|
49
|
+
}
|
|
50
|
+
);
|
|
51
|
+
return toResult(result, skipped);
|
|
52
|
+
}
|
|
53
|
+
function useConversationByPhonePair(phonePair) {
|
|
54
|
+
const skipped = !phonePair;
|
|
55
|
+
const result = useQuery(
|
|
56
|
+
conversationsGetByPhonePairRef,
|
|
57
|
+
skipped ? SKIP : { phonePair }
|
|
58
|
+
);
|
|
59
|
+
return toResult(result, skipped);
|
|
60
|
+
}
|
|
61
|
+
function useMessages(conversationId, options) {
|
|
62
|
+
const skipped = !conversationId;
|
|
63
|
+
const result = useQuery(
|
|
64
|
+
conversationMessagesGetByConversationIdRef,
|
|
65
|
+
skipped ? SKIP : {
|
|
66
|
+
conversationId,
|
|
67
|
+
limit: options == null ? void 0 : options.limit
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
return toResult(result, skipped);
|
|
71
|
+
}
|
|
72
|
+
function useUnreadCount(userId) {
|
|
73
|
+
const skipped = !userId;
|
|
74
|
+
const result = useQuery(
|
|
75
|
+
conversationsGetUnreadTotalForUserRef,
|
|
76
|
+
skipped ? SKIP : { userId }
|
|
77
|
+
);
|
|
78
|
+
return toResult(result, skipped);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/react/hooks.ts
|
|
82
|
+
import { useQuery as useQuery2 } from "convex/react";
|
|
83
|
+
import { useEffect } from "react";
|
|
84
|
+
import { makeFunctionReference as makeFunctionReference2 } from "convex/server";
|
|
85
|
+
var patientsListRef = makeFunctionReference2("patients:list");
|
|
86
|
+
var patientsGetRef = makeFunctionReference2("patients:get");
|
|
87
|
+
var patientsByElationIdRef = makeFunctionReference2("patients:getByElationId");
|
|
88
|
+
var patientsByHintIdRef = makeFunctionReference2("patients:getByHintId");
|
|
89
|
+
var appointmentsListRef = makeFunctionReference2("appointments:list");
|
|
90
|
+
var appointmentsGetRef = makeFunctionReference2("appointments:get");
|
|
91
|
+
var appointmentsByElationIdRef = makeFunctionReference2("appointments:getByElationId");
|
|
35
92
|
function usePatients(options) {
|
|
36
|
-
return
|
|
93
|
+
return useQuery2(patientsListRef, options != null ? options : {});
|
|
37
94
|
}
|
|
38
95
|
function usePatient(id) {
|
|
39
|
-
return
|
|
96
|
+
return useQuery2(patientsGetRef, { id });
|
|
40
97
|
}
|
|
41
98
|
function usePatientByElationId(elationId) {
|
|
42
|
-
return
|
|
99
|
+
return useQuery2(patientsByElationIdRef, {
|
|
43
100
|
elationId
|
|
44
101
|
});
|
|
45
102
|
}
|
|
46
103
|
function usePatientByHintId(hintId) {
|
|
47
|
-
return
|
|
104
|
+
return useQuery2(patientsByHintIdRef, {
|
|
48
105
|
hintId
|
|
49
106
|
});
|
|
50
107
|
}
|
|
51
108
|
function useAppointments(options) {
|
|
52
|
-
return
|
|
109
|
+
return useQuery2(
|
|
53
110
|
appointmentsListRef,
|
|
54
111
|
options != null ? options : {}
|
|
55
112
|
);
|
|
56
113
|
}
|
|
57
114
|
function useAppointment(id) {
|
|
58
|
-
return
|
|
115
|
+
return useQuery2(appointmentsGetRef, { id });
|
|
59
116
|
}
|
|
60
117
|
function useAppointmentByElationId(elationId) {
|
|
61
|
-
return
|
|
118
|
+
return useQuery2(appointmentsByElationIdRef, {
|
|
62
119
|
elationId
|
|
63
120
|
});
|
|
64
121
|
}
|
|
65
|
-
var physiciansGetByElationIdsRef =
|
|
66
|
-
var physiciansGetByElationIdRef =
|
|
122
|
+
var physiciansGetByElationIdsRef = makeFunctionReference2("physicians:getByElationIds");
|
|
123
|
+
var physiciansGetByElationIdRef = makeFunctionReference2("physicians:getByElationId");
|
|
67
124
|
function usePhysiciansByElationIds(ids) {
|
|
68
|
-
return
|
|
125
|
+
return useQuery2(
|
|
69
126
|
physiciansGetByElationIdsRef,
|
|
70
127
|
ids && ids.length > 0 ? { ids } : "skip"
|
|
71
128
|
);
|
|
72
129
|
}
|
|
73
130
|
function usePhysicianByElationId(id) {
|
|
74
|
-
return
|
|
131
|
+
return useQuery2(
|
|
75
132
|
physiciansGetByElationIdRef,
|
|
76
133
|
id !== void 0 ? { id } : "skip"
|
|
77
134
|
);
|
|
78
135
|
}
|
|
79
|
-
var medicationsByPatientRef =
|
|
80
|
-
var problemsByPatientRef =
|
|
81
|
-
var allergiesByPatientRef =
|
|
82
|
-
var appointmentsByPatientRef =
|
|
136
|
+
var medicationsByPatientRef = makeFunctionReference2("medicalRecords:getMedicationsByElationPatient");
|
|
137
|
+
var problemsByPatientRef = makeFunctionReference2("medicalRecords:getProblemsByElationPatient");
|
|
138
|
+
var allergiesByPatientRef = makeFunctionReference2("medicalRecords:getAllergiesByElationPatient");
|
|
139
|
+
var appointmentsByPatientRef = makeFunctionReference2("medicalRecords:getAppointmentsByElationPatient");
|
|
83
140
|
function usePatientMedical(elationId, options) {
|
|
84
|
-
const medications =
|
|
141
|
+
const medications = useQuery2(
|
|
85
142
|
medicationsByPatientRef,
|
|
86
143
|
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
87
144
|
);
|
|
88
|
-
const problems =
|
|
145
|
+
const problems = useQuery2(
|
|
89
146
|
problemsByPatientRef,
|
|
90
147
|
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
91
148
|
);
|
|
92
|
-
const allergies =
|
|
149
|
+
const allergies = useQuery2(
|
|
93
150
|
allergiesByPatientRef,
|
|
94
151
|
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
95
152
|
);
|
|
96
|
-
const appointments =
|
|
153
|
+
const appointments = useQuery2(
|
|
97
154
|
appointmentsByPatientRef,
|
|
98
155
|
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
99
156
|
);
|
|
@@ -121,26 +178,32 @@ function usePatientMedical(elationId, options) {
|
|
|
121
178
|
}, [elationId, options == null ? void 0 : options.apiBaseUrl, options == null ? void 0 : options.apiKey, options == null ? void 0 : options.skipRefresh]);
|
|
122
179
|
return { medications, problems, allergies, appointments };
|
|
123
180
|
}
|
|
124
|
-
var elationPatientByIdRef =
|
|
125
|
-
var hintPatientByIdRef =
|
|
126
|
-
var pharmacyByNcpdpRef =
|
|
127
|
-
var patientPhotoByIdRef =
|
|
181
|
+
var elationPatientByIdRef = makeFunctionReference2("elationPatients:getByElationId");
|
|
182
|
+
var hintPatientByIdRef = makeFunctionReference2("hintPatients:getByHintId");
|
|
183
|
+
var pharmacyByNcpdpRef = makeFunctionReference2("elationPharmacies:getByNcpdpId");
|
|
184
|
+
var patientPhotoByIdRef = makeFunctionReference2("elationPatientPhotos:getByElationPatientId");
|
|
128
185
|
function usePatientBasic(input, options) {
|
|
129
186
|
var _a, _b;
|
|
130
|
-
const elationRow =
|
|
187
|
+
const elationRow = useQuery2(
|
|
131
188
|
elationPatientByIdRef,
|
|
132
189
|
input.elationId !== void 0 ? { elationId: input.elationId } : "skip"
|
|
133
190
|
);
|
|
134
|
-
const hintRow =
|
|
191
|
+
const hintRow = useQuery2(
|
|
135
192
|
hintPatientByIdRef,
|
|
136
193
|
input.hintId !== void 0 ? { hintId: input.hintId } : "skip"
|
|
137
194
|
);
|
|
138
195
|
useEffect(() => {
|
|
139
|
-
if (options == null ? void 0 : options.skipRefresh)
|
|
140
|
-
|
|
196
|
+
if (options == null ? void 0 : options.skipRefresh) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (!input.hintId && input.elationId === void 0) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
141
202
|
const apiBaseUrl = options == null ? void 0 : options.apiBaseUrl;
|
|
142
203
|
const apiKey = options == null ? void 0 : options.apiKey;
|
|
143
|
-
if (!apiBaseUrl || !apiKey)
|
|
204
|
+
if (!apiBaseUrl || !apiKey) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
144
207
|
const controller = new AbortController();
|
|
145
208
|
void fetch(`${apiBaseUrl}/api/patients/basic/refresh`, {
|
|
146
209
|
method: "POST",
|
|
@@ -176,22 +239,28 @@ function usePatientBasic(input, options) {
|
|
|
176
239
|
};
|
|
177
240
|
}
|
|
178
241
|
function usePharmacyByNcpdpId(ncpdpId) {
|
|
179
|
-
return
|
|
242
|
+
return useQuery2(
|
|
180
243
|
pharmacyByNcpdpRef,
|
|
181
244
|
ncpdpId ? { ncpdpId } : "skip"
|
|
182
245
|
);
|
|
183
246
|
}
|
|
184
247
|
function usePatientPhoto(elationId, options) {
|
|
185
|
-
const photo =
|
|
248
|
+
const photo = useQuery2(
|
|
186
249
|
patientPhotoByIdRef,
|
|
187
250
|
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
188
251
|
);
|
|
189
252
|
useEffect(() => {
|
|
190
|
-
if (options == null ? void 0 : options.skipRefresh)
|
|
191
|
-
|
|
253
|
+
if (options == null ? void 0 : options.skipRefresh) {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (elationId === void 0) {
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
192
259
|
const apiBaseUrl = options == null ? void 0 : options.apiBaseUrl;
|
|
193
260
|
const apiKey = options == null ? void 0 : options.apiKey;
|
|
194
|
-
if (!apiBaseUrl || !apiKey)
|
|
261
|
+
if (!apiBaseUrl || !apiKey) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
195
264
|
const controller = new AbortController();
|
|
196
265
|
void fetch(`${apiBaseUrl}/api/patients/photo/refresh`, {
|
|
197
266
|
method: "POST",
|
|
@@ -207,6 +276,406 @@ function usePatientPhoto(elationId, options) {
|
|
|
207
276
|
}, [elationId, options == null ? void 0 : options.apiBaseUrl, options == null ? void 0 : options.apiKey, options == null ? void 0 : options.skipRefresh]);
|
|
208
277
|
return photo;
|
|
209
278
|
}
|
|
279
|
+
var messagesByPhonesRef = makeFunctionReference2("conversationMessages:getByPhones");
|
|
280
|
+
var messagesByConversationIdRef = makeFunctionReference2("conversationMessages:getByConversationId");
|
|
281
|
+
function useConversationMessages(input, options) {
|
|
282
|
+
const hasPair = !!input.phoneA && !!input.phoneB;
|
|
283
|
+
const byPair = useQuery2(
|
|
284
|
+
messagesByPhonesRef,
|
|
285
|
+
hasPair ? {
|
|
286
|
+
phoneA: input.phoneA,
|
|
287
|
+
phoneB: input.phoneB,
|
|
288
|
+
limit: options == null ? void 0 : options.limit
|
|
289
|
+
} : "skip"
|
|
290
|
+
);
|
|
291
|
+
const byConvo = useQuery2(
|
|
292
|
+
messagesByConversationIdRef,
|
|
293
|
+
!hasPair && input.conversationId ? { conversationId: input.conversationId, limit: options == null ? void 0 : options.limit } : "skip"
|
|
294
|
+
);
|
|
295
|
+
return hasPair ? byPair : byConvo;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
// src/react/notifications.ts
|
|
299
|
+
import { useCallback, useEffect as useEffect2, useRef, useState } from "react";
|
|
300
|
+
|
|
301
|
+
// src/web-push.ts
|
|
302
|
+
function isWebPushSupported() {
|
|
303
|
+
return typeof window !== "undefined" && "serviceWorker" in navigator && "PushManager" in window;
|
|
304
|
+
}
|
|
305
|
+
function registerServiceWorker(path = "/truth-sw.js") {
|
|
306
|
+
return __async(this, null, function* () {
|
|
307
|
+
return navigator.serviceWorker.register(path);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
function subscribeToPush(registration, vapidPublicKey) {
|
|
311
|
+
return __async(this, null, function* () {
|
|
312
|
+
const existing = yield registration.pushManager.getSubscription();
|
|
313
|
+
if (existing) {
|
|
314
|
+
return existing;
|
|
315
|
+
}
|
|
316
|
+
return registration.pushManager.subscribe({
|
|
317
|
+
userVisibleOnly: true,
|
|
318
|
+
applicationServerKey: urlBase64ToUint8Array(
|
|
319
|
+
vapidPublicKey
|
|
320
|
+
)
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
function subscriptionToJSON(sub) {
|
|
325
|
+
var _a, _b, _c, _d;
|
|
326
|
+
const json = sub.toJSON();
|
|
327
|
+
return {
|
|
328
|
+
endpoint: sub.endpoint,
|
|
329
|
+
keys: {
|
|
330
|
+
p256dh: (_b = (_a = json.keys) == null ? void 0 : _a.p256dh) != null ? _b : "",
|
|
331
|
+
auth: (_d = (_c = json.keys) == null ? void 0 : _c.auth) != null ? _d : ""
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
function urlBase64ToUint8Array(base64String) {
|
|
336
|
+
const padding = "=".repeat((4 - base64String.length % 4) % 4);
|
|
337
|
+
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
338
|
+
const rawData = atob(base64);
|
|
339
|
+
const outputArray = new Uint8Array(rawData.length);
|
|
340
|
+
for (let i = 0; i < rawData.length; ++i) {
|
|
341
|
+
outputArray[i] = rawData.charCodeAt(i);
|
|
342
|
+
}
|
|
343
|
+
return outputArray;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// src/react/notifications.ts
|
|
347
|
+
function loadExpo() {
|
|
348
|
+
return __async(this, null, function* () {
|
|
349
|
+
try {
|
|
350
|
+
const modName = "expo-notifications";
|
|
351
|
+
return yield import(
|
|
352
|
+
/* @vite-ignore */
|
|
353
|
+
/* webpackIgnore: true */
|
|
354
|
+
modName
|
|
355
|
+
);
|
|
356
|
+
} catch (e) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
function useNotifications(options) {
|
|
362
|
+
var _a;
|
|
363
|
+
const [permissionStatus, setPermissionStatus] = useState("unknown");
|
|
364
|
+
const [devicePushToken, setDevicePushToken] = useState(null);
|
|
365
|
+
const expoRef = useRef(null);
|
|
366
|
+
const isWebRef = useRef(false);
|
|
367
|
+
const vapidKeyRef = useRef((_a = options.vapidPublicKey) != null ? _a : null);
|
|
368
|
+
useEffect2(() => {
|
|
369
|
+
let mounted = true;
|
|
370
|
+
void (() => __async(null, null, function* () {
|
|
371
|
+
var _a2;
|
|
372
|
+
const expo = yield loadExpo();
|
|
373
|
+
if (!mounted) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
expoRef.current = expo;
|
|
377
|
+
if (expo) {
|
|
378
|
+
try {
|
|
379
|
+
const perm = yield expo.getPermissionsAsync();
|
|
380
|
+
if (!mounted) {
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
setPermissionStatus(mapStatus(perm == null ? void 0 : perm.status));
|
|
384
|
+
} catch (e) {
|
|
385
|
+
setPermissionStatus("unknown");
|
|
386
|
+
}
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
if (isWebPushSupported()) {
|
|
390
|
+
isWebRef.current = true;
|
|
391
|
+
if (!vapidKeyRef.current) {
|
|
392
|
+
try {
|
|
393
|
+
const res = yield fetch(
|
|
394
|
+
`${options.apiBaseUrl}/api/notifications/vapid-key`,
|
|
395
|
+
{
|
|
396
|
+
headers: {
|
|
397
|
+
Accept: "application/json",
|
|
398
|
+
"X-API-Key": options.apiKey
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
);
|
|
402
|
+
if (res.ok) {
|
|
403
|
+
const data = yield res.json();
|
|
404
|
+
vapidKeyRef.current = (_a2 = data.vapidPublicKey) != null ? _a2 : null;
|
|
405
|
+
}
|
|
406
|
+
} catch (e) {
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
if (!mounted) {
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
const webPerm = typeof Notification !== "undefined" ? Notification.permission : "default";
|
|
413
|
+
setPermissionStatus(
|
|
414
|
+
webPerm === "granted" ? "granted" : webPerm === "denied" ? "denied" : "undetermined"
|
|
415
|
+
);
|
|
416
|
+
} else {
|
|
417
|
+
setPermissionStatus("unknown");
|
|
418
|
+
}
|
|
419
|
+
}))();
|
|
420
|
+
return () => {
|
|
421
|
+
mounted = false;
|
|
422
|
+
};
|
|
423
|
+
}, [options.apiBaseUrl, options.apiKey]);
|
|
424
|
+
const register = useCallback(() => __async(null, null, function* () {
|
|
425
|
+
var _a2, _b;
|
|
426
|
+
if (!options.userId) {
|
|
427
|
+
return { ok: false, reason: "missing_userId" };
|
|
428
|
+
}
|
|
429
|
+
if (isWebRef.current) {
|
|
430
|
+
const vapidKey = vapidKeyRef.current;
|
|
431
|
+
if (!vapidKey) {
|
|
432
|
+
return { ok: false, reason: "no_vapid_key" };
|
|
433
|
+
}
|
|
434
|
+
const webPerm = yield Notification.requestPermission();
|
|
435
|
+
setPermissionStatus(
|
|
436
|
+
webPerm === "granted" ? "granted" : webPerm === "denied" ? "denied" : "undetermined"
|
|
437
|
+
);
|
|
438
|
+
if (webPerm !== "granted") {
|
|
439
|
+
return { ok: false, reason: "permission_denied" };
|
|
440
|
+
}
|
|
441
|
+
try {
|
|
442
|
+
const swPath = (_a2 = options.serviceWorkerPath) != null ? _a2 : "/truth-sw.js";
|
|
443
|
+
const registration = yield registerServiceWorker(swPath);
|
|
444
|
+
yield navigator.serviceWorker.ready;
|
|
445
|
+
const subscription = yield subscribeToPush(registration, vapidKey);
|
|
446
|
+
const subJSON = subscriptionToJSON(subscription);
|
|
447
|
+
setDevicePushToken(subscription.endpoint);
|
|
448
|
+
const res2 = yield fetch(
|
|
449
|
+
`${options.apiBaseUrl}/api/notifications/devices/register`,
|
|
450
|
+
{
|
|
451
|
+
method: "POST",
|
|
452
|
+
headers: {
|
|
453
|
+
"Content-Type": "application/json",
|
|
454
|
+
"X-API-Key": options.apiKey
|
|
455
|
+
},
|
|
456
|
+
body: JSON.stringify({
|
|
457
|
+
userId: options.userId,
|
|
458
|
+
platform: "web",
|
|
459
|
+
webPushSubscription: subJSON,
|
|
460
|
+
appVersion: options.appVersion,
|
|
461
|
+
locale: navigator.language,
|
|
462
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
463
|
+
})
|
|
464
|
+
}
|
|
465
|
+
);
|
|
466
|
+
if (!res2.ok) {
|
|
467
|
+
const text = yield res2.text().catch(() => "");
|
|
468
|
+
return {
|
|
469
|
+
ok: false,
|
|
470
|
+
reason: `register_failed_${res2.status}: ${text.slice(0, 120)}`
|
|
471
|
+
};
|
|
472
|
+
}
|
|
473
|
+
return { ok: true };
|
|
474
|
+
} catch (err) {
|
|
475
|
+
return {
|
|
476
|
+
ok: false,
|
|
477
|
+
reason: `web_push_error: ${err instanceof Error ? err.message : String(err)}`
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
const expo = (_b = expoRef.current) != null ? _b : yield loadExpo();
|
|
482
|
+
expoRef.current = expo;
|
|
483
|
+
if (!expo) {
|
|
484
|
+
return { ok: false, reason: "expo_notifications_missing" };
|
|
485
|
+
}
|
|
486
|
+
let perm = yield expo.getPermissionsAsync();
|
|
487
|
+
if ((perm == null ? void 0 : perm.status) !== "granted") {
|
|
488
|
+
perm = yield expo.requestPermissionsAsync();
|
|
489
|
+
}
|
|
490
|
+
setPermissionStatus(mapStatus(perm == null ? void 0 : perm.status));
|
|
491
|
+
if ((perm == null ? void 0 : perm.status) !== "granted") {
|
|
492
|
+
return { ok: false, reason: "permission_denied" };
|
|
493
|
+
}
|
|
494
|
+
const tokenResp = yield expo.getDevicePushTokenAsync();
|
|
495
|
+
const nativeToken = tokenResp == null ? void 0 : tokenResp.data;
|
|
496
|
+
const platform = detectPlatform(tokenResp == null ? void 0 : tokenResp.type);
|
|
497
|
+
if (!nativeToken || platform !== "ios" && platform !== "android") {
|
|
498
|
+
return { ok: false, reason: "no_native_token" };
|
|
499
|
+
}
|
|
500
|
+
setDevicePushToken(nativeToken);
|
|
501
|
+
const res = yield fetch(
|
|
502
|
+
`${options.apiBaseUrl}/api/notifications/devices/register`,
|
|
503
|
+
{
|
|
504
|
+
method: "POST",
|
|
505
|
+
headers: {
|
|
506
|
+
"Content-Type": "application/json",
|
|
507
|
+
"X-API-Key": options.apiKey
|
|
508
|
+
},
|
|
509
|
+
body: JSON.stringify({
|
|
510
|
+
userId: options.userId,
|
|
511
|
+
platform,
|
|
512
|
+
nativeToken,
|
|
513
|
+
appVersion: options.appVersion,
|
|
514
|
+
locale: typeof navigator !== "undefined" ? navigator.language : void 0,
|
|
515
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
516
|
+
})
|
|
517
|
+
}
|
|
518
|
+
);
|
|
519
|
+
if (!res.ok) {
|
|
520
|
+
const text = yield res.text().catch(() => "");
|
|
521
|
+
return {
|
|
522
|
+
ok: false,
|
|
523
|
+
reason: `register_failed_${res.status}: ${text.slice(0, 120)}`
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
return { ok: true };
|
|
527
|
+
}), [
|
|
528
|
+
options.apiBaseUrl,
|
|
529
|
+
options.apiKey,
|
|
530
|
+
options.userId,
|
|
531
|
+
options.appVersion,
|
|
532
|
+
options.serviceWorkerPath
|
|
533
|
+
]);
|
|
534
|
+
const unregister = useCallback(() => __async(null, null, function* () {
|
|
535
|
+
if (!devicePushToken) {
|
|
536
|
+
return;
|
|
537
|
+
}
|
|
538
|
+
yield fetch(`${options.apiBaseUrl}/api/notifications/devices/unregister`, {
|
|
539
|
+
method: "POST",
|
|
540
|
+
headers: {
|
|
541
|
+
"Content-Type": "application/json",
|
|
542
|
+
"X-API-Key": options.apiKey
|
|
543
|
+
},
|
|
544
|
+
body: JSON.stringify({ nativeToken: devicePushToken })
|
|
545
|
+
}).catch(() => {
|
|
546
|
+
});
|
|
547
|
+
setDevicePushToken(null);
|
|
548
|
+
}), [options.apiBaseUrl, options.apiKey, devicePushToken]);
|
|
549
|
+
const addReceivedListener = useCallback(
|
|
550
|
+
(listener) => {
|
|
551
|
+
if (isWebRef.current) {
|
|
552
|
+
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
|
|
553
|
+
return () => {
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
const handler = (event) => {
|
|
557
|
+
var _a2;
|
|
558
|
+
if (((_a2 = event.data) == null ? void 0 : _a2.type) === "TRUTH_PUSH_RECEIVED") {
|
|
559
|
+
listener(event.data.payload);
|
|
560
|
+
}
|
|
561
|
+
};
|
|
562
|
+
navigator.serviceWorker.addEventListener("message", handler);
|
|
563
|
+
return () => navigator.serviceWorker.removeEventListener("message", handler);
|
|
564
|
+
}
|
|
565
|
+
const expo = expoRef.current;
|
|
566
|
+
if (!(expo == null ? void 0 : expo.addNotificationReceivedListener)) {
|
|
567
|
+
return () => {
|
|
568
|
+
};
|
|
569
|
+
}
|
|
570
|
+
const sub = expo.addNotificationReceivedListener(listener);
|
|
571
|
+
return () => {
|
|
572
|
+
var _a2;
|
|
573
|
+
return (_a2 = sub.remove) == null ? void 0 : _a2.call(sub);
|
|
574
|
+
};
|
|
575
|
+
},
|
|
576
|
+
[]
|
|
577
|
+
);
|
|
578
|
+
const addResponseListener = useCallback(
|
|
579
|
+
(listener) => {
|
|
580
|
+
if (isWebRef.current) {
|
|
581
|
+
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
|
|
582
|
+
return () => {
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
const handler = (event) => {
|
|
586
|
+
var _a2;
|
|
587
|
+
if (((_a2 = event.data) == null ? void 0 : _a2.type) === "TRUTH_PUSH_TAPPED") {
|
|
588
|
+
listener(event.data.payload);
|
|
589
|
+
}
|
|
590
|
+
};
|
|
591
|
+
navigator.serviceWorker.addEventListener("message", handler);
|
|
592
|
+
return () => navigator.serviceWorker.removeEventListener("message", handler);
|
|
593
|
+
}
|
|
594
|
+
const expo = expoRef.current;
|
|
595
|
+
if (!(expo == null ? void 0 : expo.addNotificationResponseReceivedListener)) {
|
|
596
|
+
return () => {
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
const sub = expo.addNotificationResponseReceivedListener(listener);
|
|
600
|
+
return () => {
|
|
601
|
+
var _a2;
|
|
602
|
+
return (_a2 = sub.remove) == null ? void 0 : _a2.call(sub);
|
|
603
|
+
};
|
|
604
|
+
},
|
|
605
|
+
[]
|
|
606
|
+
);
|
|
607
|
+
const getBadgeCount = useCallback(() => __async(null, null, function* () {
|
|
608
|
+
var _a2;
|
|
609
|
+
const expo = expoRef.current;
|
|
610
|
+
if (!(expo == null ? void 0 : expo.getBadgeCountAsync)) {
|
|
611
|
+
return 0;
|
|
612
|
+
}
|
|
613
|
+
return (_a2 = yield expo.getBadgeCountAsync()) != null ? _a2 : 0;
|
|
614
|
+
}), []);
|
|
615
|
+
const setBadgeCount = useCallback((count) => __async(null, null, function* () {
|
|
616
|
+
const expo = expoRef.current;
|
|
617
|
+
if (!(expo == null ? void 0 : expo.setBadgeCountAsync)) {
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
yield expo.setBadgeCountAsync(count);
|
|
621
|
+
}), []);
|
|
622
|
+
const autoRegister = options.autoRegister !== false;
|
|
623
|
+
useEffect2(() => {
|
|
624
|
+
if (!autoRegister) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
if (permissionStatus !== "granted") {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (devicePushToken) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
if (!options.userId) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
void register();
|
|
637
|
+
}, [
|
|
638
|
+
autoRegister,
|
|
639
|
+
permissionStatus,
|
|
640
|
+
devicePushToken,
|
|
641
|
+
options.userId,
|
|
642
|
+
register
|
|
643
|
+
]);
|
|
644
|
+
return {
|
|
645
|
+
permissionStatus,
|
|
646
|
+
devicePushToken,
|
|
647
|
+
register,
|
|
648
|
+
unregister,
|
|
649
|
+
addReceivedListener,
|
|
650
|
+
addResponseListener,
|
|
651
|
+
getBadgeCount,
|
|
652
|
+
setBadgeCount
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
function mapStatus(status) {
|
|
656
|
+
if (status === "granted") {
|
|
657
|
+
return "granted";
|
|
658
|
+
}
|
|
659
|
+
if (status === "denied") {
|
|
660
|
+
return "denied";
|
|
661
|
+
}
|
|
662
|
+
if (status === "undetermined") {
|
|
663
|
+
return "undetermined";
|
|
664
|
+
}
|
|
665
|
+
return "unknown";
|
|
666
|
+
}
|
|
667
|
+
function detectPlatform(tokenType) {
|
|
668
|
+
if (tokenType === "apns") {
|
|
669
|
+
return "ios";
|
|
670
|
+
}
|
|
671
|
+
if (tokenType === "fcm") {
|
|
672
|
+
return "android";
|
|
673
|
+
}
|
|
674
|
+
if (tokenType === "web") {
|
|
675
|
+
return "web";
|
|
676
|
+
}
|
|
677
|
+
return "unknown";
|
|
678
|
+
}
|
|
210
679
|
|
|
211
680
|
// src/react/provider.ts
|
|
212
681
|
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
@@ -219,13 +688,20 @@ var CONVEX_URLS = {
|
|
|
219
688
|
uat: "https://gallant-gecko-217.convex.cloud",
|
|
220
689
|
production: "https://gallant-gecko-217.convex.cloud"
|
|
221
690
|
};
|
|
691
|
+
function resolveConvexUrl(environment, override) {
|
|
692
|
+
var _a;
|
|
693
|
+
if (override) {
|
|
694
|
+
return override;
|
|
695
|
+
}
|
|
696
|
+
const env = environment != null ? environment : "sandbox";
|
|
697
|
+
return (_a = CONVEX_URLS[env]) != null ? _a : CONVEX_URLS.sandbox;
|
|
698
|
+
}
|
|
222
699
|
function TruthProvider({
|
|
223
700
|
environment = "sandbox",
|
|
224
701
|
convexUrl,
|
|
225
702
|
children
|
|
226
703
|
}) {
|
|
227
|
-
|
|
228
|
-
const url = (_a = convexUrl != null ? convexUrl : CONVEX_URLS[environment]) != null ? _a : CONVEX_URLS.sandbox;
|
|
704
|
+
const url = resolveConvexUrl(environment, convexUrl);
|
|
229
705
|
const client = useMemo(() => new ConvexReactClient(url), [url]);
|
|
230
706
|
return createElement(ConvexProvider, { client }, children);
|
|
231
707
|
}
|
|
@@ -471,6 +947,11 @@ export {
|
|
|
471
947
|
useAppointment,
|
|
472
948
|
useAppointmentByElationId,
|
|
473
949
|
useAppointments,
|
|
950
|
+
useConversationByPhonePair,
|
|
951
|
+
useConversationMessages,
|
|
952
|
+
useConversations,
|
|
953
|
+
useMessages,
|
|
954
|
+
useNotifications,
|
|
474
955
|
usePatient,
|
|
475
956
|
usePatientBasic,
|
|
476
957
|
usePatientByElationId,
|
|
@@ -481,6 +962,7 @@ export {
|
|
|
481
962
|
usePharmacyByNcpdpId,
|
|
482
963
|
usePhysicianByElationId,
|
|
483
964
|
usePhysiciansByElationIds,
|
|
484
|
-
useTruth
|
|
965
|
+
useTruth,
|
|
966
|
+
useUnreadCount
|
|
485
967
|
};
|
|
486
968
|
//# sourceMappingURL=react.mjs.map
|