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