@hipnation-truth/sdk 0.7.3 → 0.7.5
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 +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.ts +11 -0
- package/dist/react.js +18 -4
- package/dist/react.js.map +1 -1
- package/package.json +2 -3
- package/dist/react.d.mts +0 -898
- package/dist/react.mjs +0 -969
- package/dist/react.mjs.map +0 -1
package/dist/react.mjs
DELETED
|
@@ -1,969 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
var __pow = Math.pow;
|
|
3
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
4
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
5
|
-
}) : x)(function(x) {
|
|
6
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
7
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
8
|
-
});
|
|
9
|
-
var __async = (__this, __arguments, generator) => {
|
|
10
|
-
return new Promise((resolve, reject) => {
|
|
11
|
-
var fulfilled = (value) => {
|
|
12
|
-
try {
|
|
13
|
-
step(generator.next(value));
|
|
14
|
-
} catch (e) {
|
|
15
|
-
reject(e);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
var rejected = (value) => {
|
|
19
|
-
try {
|
|
20
|
-
step(generator.throw(value));
|
|
21
|
-
} catch (e) {
|
|
22
|
-
reject(e);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
26
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
// src/react/conversations.ts
|
|
31
|
-
import { useQuery } from "convex/react";
|
|
32
|
-
import { makeFunctionReference } from "convex/server";
|
|
33
|
-
var conversationsListForUserRef = makeFunctionReference("conversations:listForUser");
|
|
34
|
-
var conversationsGetUnreadTotalForUserRef = makeFunctionReference("conversations:getUnreadTotalForUser");
|
|
35
|
-
var conversationsGetByPhonePairRef = makeFunctionReference("conversations:getByPhonePair");
|
|
36
|
-
var conversationMessagesGetByConversationIdRef = makeFunctionReference("conversationMessages:getByConversationId");
|
|
37
|
-
var SKIP = "skip";
|
|
38
|
-
function toResult(value, skipped) {
|
|
39
|
-
if (skipped) {
|
|
40
|
-
return { data: void 0, loading: false, error: void 0 };
|
|
41
|
-
}
|
|
42
|
-
return {
|
|
43
|
-
data: value,
|
|
44
|
-
loading: value === void 0,
|
|
45
|
-
error: void 0
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
function useConversations(filters) {
|
|
49
|
-
const skipped = !filters.userId;
|
|
50
|
-
const result = useQuery(
|
|
51
|
-
conversationsListForUserRef,
|
|
52
|
-
skipped ? SKIP : {
|
|
53
|
-
userId: filters.userId,
|
|
54
|
-
limit: filters.limit
|
|
55
|
-
}
|
|
56
|
-
);
|
|
57
|
-
return toResult(result, skipped);
|
|
58
|
-
}
|
|
59
|
-
function useConversationByPhonePair(phonePair) {
|
|
60
|
-
const skipped = !phonePair;
|
|
61
|
-
const result = useQuery(
|
|
62
|
-
conversationsGetByPhonePairRef,
|
|
63
|
-
skipped ? SKIP : { phonePair }
|
|
64
|
-
);
|
|
65
|
-
return toResult(result, skipped);
|
|
66
|
-
}
|
|
67
|
-
function useMessages(conversationId, options) {
|
|
68
|
-
const skipped = !conversationId;
|
|
69
|
-
const result = useQuery(
|
|
70
|
-
conversationMessagesGetByConversationIdRef,
|
|
71
|
-
skipped ? SKIP : {
|
|
72
|
-
conversationId,
|
|
73
|
-
limit: options == null ? void 0 : options.limit
|
|
74
|
-
}
|
|
75
|
-
);
|
|
76
|
-
return toResult(result, skipped);
|
|
77
|
-
}
|
|
78
|
-
function useUnreadCount(userId) {
|
|
79
|
-
const skipped = !userId;
|
|
80
|
-
const result = useQuery(
|
|
81
|
-
conversationsGetUnreadTotalForUserRef,
|
|
82
|
-
skipped ? SKIP : { userId }
|
|
83
|
-
);
|
|
84
|
-
return toResult(result, skipped);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// src/react/hooks.ts
|
|
88
|
-
import { useQuery as useQuery2 } from "convex/react";
|
|
89
|
-
import { useEffect } from "react";
|
|
90
|
-
import { makeFunctionReference as makeFunctionReference2 } from "convex/server";
|
|
91
|
-
var patientsListRef = makeFunctionReference2("patients:list");
|
|
92
|
-
var patientsGetRef = makeFunctionReference2("patients:get");
|
|
93
|
-
var patientsByElationIdRef = makeFunctionReference2("patients:getByElationId");
|
|
94
|
-
var patientsByHintIdRef = makeFunctionReference2("patients:getByHintId");
|
|
95
|
-
var appointmentsListRef = makeFunctionReference2("appointments:list");
|
|
96
|
-
var appointmentsGetRef = makeFunctionReference2("appointments:get");
|
|
97
|
-
var appointmentsByElationIdRef = makeFunctionReference2("appointments:getByElationId");
|
|
98
|
-
function usePatients(options) {
|
|
99
|
-
return useQuery2(patientsListRef, options != null ? options : {});
|
|
100
|
-
}
|
|
101
|
-
function usePatient(id) {
|
|
102
|
-
return useQuery2(patientsGetRef, { id });
|
|
103
|
-
}
|
|
104
|
-
function usePatientByElationId(elationId) {
|
|
105
|
-
return useQuery2(patientsByElationIdRef, {
|
|
106
|
-
elationId
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
function usePatientByHintId(hintId) {
|
|
110
|
-
return useQuery2(patientsByHintIdRef, {
|
|
111
|
-
hintId
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
function useAppointments(options) {
|
|
115
|
-
return useQuery2(
|
|
116
|
-
appointmentsListRef,
|
|
117
|
-
options != null ? options : {}
|
|
118
|
-
);
|
|
119
|
-
}
|
|
120
|
-
function useAppointment(id) {
|
|
121
|
-
return useQuery2(appointmentsGetRef, { id });
|
|
122
|
-
}
|
|
123
|
-
function useAppointmentByElationId(elationId) {
|
|
124
|
-
return useQuery2(appointmentsByElationIdRef, {
|
|
125
|
-
elationId
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
var physiciansGetByElationIdsRef = makeFunctionReference2("physicians:getByElationIds");
|
|
129
|
-
var physiciansGetByElationIdRef = makeFunctionReference2("physicians:getByElationId");
|
|
130
|
-
function usePhysiciansByElationIds(ids) {
|
|
131
|
-
return useQuery2(
|
|
132
|
-
physiciansGetByElationIdsRef,
|
|
133
|
-
ids && ids.length > 0 ? { ids } : "skip"
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
function usePhysicianByElationId(id) {
|
|
137
|
-
return useQuery2(
|
|
138
|
-
physiciansGetByElationIdRef,
|
|
139
|
-
id !== void 0 ? { id } : "skip"
|
|
140
|
-
);
|
|
141
|
-
}
|
|
142
|
-
var medicationsByPatientRef = makeFunctionReference2("medicalRecords:getMedicationsByElationPatient");
|
|
143
|
-
var problemsByPatientRef = makeFunctionReference2("medicalRecords:getProblemsByElationPatient");
|
|
144
|
-
var allergiesByPatientRef = makeFunctionReference2("medicalRecords:getAllergiesByElationPatient");
|
|
145
|
-
var appointmentsByPatientRef = makeFunctionReference2("medicalRecords:getAppointmentsByElationPatient");
|
|
146
|
-
function usePatientMedical(elationId, options) {
|
|
147
|
-
const medications = useQuery2(
|
|
148
|
-
medicationsByPatientRef,
|
|
149
|
-
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
150
|
-
);
|
|
151
|
-
const problems = useQuery2(
|
|
152
|
-
problemsByPatientRef,
|
|
153
|
-
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
154
|
-
);
|
|
155
|
-
const allergies = useQuery2(
|
|
156
|
-
allergiesByPatientRef,
|
|
157
|
-
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
158
|
-
);
|
|
159
|
-
const appointments = useQuery2(
|
|
160
|
-
appointmentsByPatientRef,
|
|
161
|
-
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
162
|
-
);
|
|
163
|
-
useEffect(() => {
|
|
164
|
-
if (elationId === void 0 || (options == null ? void 0 : options.skipRefresh)) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
|
-
const apiBaseUrl = options == null ? void 0 : options.apiBaseUrl;
|
|
168
|
-
const apiKey = options == null ? void 0 : options.apiKey;
|
|
169
|
-
if (!apiBaseUrl || !apiKey) {
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
const controller = new AbortController();
|
|
173
|
-
void fetch(`${apiBaseUrl}/api/patients/medical/refresh`, {
|
|
174
|
-
method: "POST",
|
|
175
|
-
headers: {
|
|
176
|
-
"Content-Type": "application/json",
|
|
177
|
-
"X-API-Key": apiKey
|
|
178
|
-
},
|
|
179
|
-
body: JSON.stringify({ elationId }),
|
|
180
|
-
signal: controller.signal
|
|
181
|
-
}).catch(() => {
|
|
182
|
-
});
|
|
183
|
-
return () => controller.abort();
|
|
184
|
-
}, [elationId, options == null ? void 0 : options.apiBaseUrl, options == null ? void 0 : options.apiKey, options == null ? void 0 : options.skipRefresh]);
|
|
185
|
-
return { medications, problems, allergies, appointments };
|
|
186
|
-
}
|
|
187
|
-
var elationPatientByIdRef = makeFunctionReference2("elationPatients:getByElationId");
|
|
188
|
-
var hintPatientByIdRef = makeFunctionReference2("hintPatients:getByHintId");
|
|
189
|
-
var pharmacyByNcpdpRef = makeFunctionReference2("elationPharmacies:getByNcpdpId");
|
|
190
|
-
var patientPhotoByIdRef = makeFunctionReference2("elationPatientPhotos:getByElationPatientId");
|
|
191
|
-
function usePatientBasic(input, options) {
|
|
192
|
-
var _a, _b;
|
|
193
|
-
const elationRow = useQuery2(
|
|
194
|
-
elationPatientByIdRef,
|
|
195
|
-
input.elationId !== void 0 ? { elationId: input.elationId } : "skip"
|
|
196
|
-
);
|
|
197
|
-
const hintRow = useQuery2(
|
|
198
|
-
hintPatientByIdRef,
|
|
199
|
-
input.hintId !== void 0 ? { hintId: input.hintId } : "skip"
|
|
200
|
-
);
|
|
201
|
-
useEffect(() => {
|
|
202
|
-
if (options == null ? void 0 : options.skipRefresh) {
|
|
203
|
-
return;
|
|
204
|
-
}
|
|
205
|
-
if (!input.hintId && input.elationId === void 0) {
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
const apiBaseUrl = options == null ? void 0 : options.apiBaseUrl;
|
|
209
|
-
const apiKey = options == null ? void 0 : options.apiKey;
|
|
210
|
-
if (!apiBaseUrl || !apiKey) {
|
|
211
|
-
return;
|
|
212
|
-
}
|
|
213
|
-
const controller = new AbortController();
|
|
214
|
-
void fetch(`${apiBaseUrl}/api/patients/basic/refresh`, {
|
|
215
|
-
method: "POST",
|
|
216
|
-
headers: {
|
|
217
|
-
"Content-Type": "application/json",
|
|
218
|
-
"X-API-Key": apiKey
|
|
219
|
-
},
|
|
220
|
-
body: JSON.stringify({
|
|
221
|
-
hintId: input.hintId,
|
|
222
|
-
elationId: input.elationId
|
|
223
|
-
}),
|
|
224
|
-
signal: controller.signal
|
|
225
|
-
}).catch(() => {
|
|
226
|
-
});
|
|
227
|
-
return () => controller.abort();
|
|
228
|
-
}, [
|
|
229
|
-
input.hintId,
|
|
230
|
-
input.elationId,
|
|
231
|
-
options == null ? void 0 : options.apiBaseUrl,
|
|
232
|
-
options == null ? void 0 : options.apiKey,
|
|
233
|
-
options == null ? void 0 : options.skipRefresh
|
|
234
|
-
]);
|
|
235
|
-
const elationPatient = elationRow === void 0 ? void 0 : elationRow === null ? null : (_a = elationRow.raw) != null ? _a : null;
|
|
236
|
-
const hintPatient = hintRow === void 0 ? void 0 : hintRow === null ? null : (_b = hintRow.raw) != null ? _b : null;
|
|
237
|
-
const elationLoading = input.elationId !== void 0 && elationRow === void 0;
|
|
238
|
-
const hintLoading = input.hintId !== void 0 && hintRow === void 0;
|
|
239
|
-
return {
|
|
240
|
-
elationPatient,
|
|
241
|
-
hintPatient,
|
|
242
|
-
elationRow,
|
|
243
|
-
hintRow,
|
|
244
|
-
loading: elationLoading || hintLoading
|
|
245
|
-
};
|
|
246
|
-
}
|
|
247
|
-
function usePharmacyByNcpdpId(ncpdpId) {
|
|
248
|
-
return useQuery2(
|
|
249
|
-
pharmacyByNcpdpRef,
|
|
250
|
-
ncpdpId ? { ncpdpId } : "skip"
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
function usePatientPhoto(elationId, options) {
|
|
254
|
-
const photo = useQuery2(
|
|
255
|
-
patientPhotoByIdRef,
|
|
256
|
-
elationId !== void 0 ? { elationPatientId: elationId } : "skip"
|
|
257
|
-
);
|
|
258
|
-
useEffect(() => {
|
|
259
|
-
if (options == null ? void 0 : options.skipRefresh) {
|
|
260
|
-
return;
|
|
261
|
-
}
|
|
262
|
-
if (elationId === void 0) {
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
const apiBaseUrl = options == null ? void 0 : options.apiBaseUrl;
|
|
266
|
-
const apiKey = options == null ? void 0 : options.apiKey;
|
|
267
|
-
if (!apiBaseUrl || !apiKey) {
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
const controller = new AbortController();
|
|
271
|
-
void fetch(`${apiBaseUrl}/api/patients/photo/refresh`, {
|
|
272
|
-
method: "POST",
|
|
273
|
-
headers: {
|
|
274
|
-
"Content-Type": "application/json",
|
|
275
|
-
"X-API-Key": apiKey
|
|
276
|
-
},
|
|
277
|
-
body: JSON.stringify({ elationId }),
|
|
278
|
-
signal: controller.signal
|
|
279
|
-
}).catch(() => {
|
|
280
|
-
});
|
|
281
|
-
return () => controller.abort();
|
|
282
|
-
}, [elationId, options == null ? void 0 : options.apiBaseUrl, options == null ? void 0 : options.apiKey, options == null ? void 0 : options.skipRefresh]);
|
|
283
|
-
return photo;
|
|
284
|
-
}
|
|
285
|
-
var messagesByPhonesRef = makeFunctionReference2("conversationMessages:getByPhones");
|
|
286
|
-
var messagesByConversationIdRef = makeFunctionReference2("conversationMessages:getByConversationId");
|
|
287
|
-
function useConversationMessages(input, options) {
|
|
288
|
-
const hasPair = !!input.phoneA && !!input.phoneB;
|
|
289
|
-
const byPair = useQuery2(
|
|
290
|
-
messagesByPhonesRef,
|
|
291
|
-
hasPair ? {
|
|
292
|
-
phoneA: input.phoneA,
|
|
293
|
-
phoneB: input.phoneB,
|
|
294
|
-
limit: options == null ? void 0 : options.limit
|
|
295
|
-
} : "skip"
|
|
296
|
-
);
|
|
297
|
-
const byConvo = useQuery2(
|
|
298
|
-
messagesByConversationIdRef,
|
|
299
|
-
!hasPair && input.conversationId ? { conversationId: input.conversationId, limit: options == null ? void 0 : options.limit } : "skip"
|
|
300
|
-
);
|
|
301
|
-
return hasPair ? byPair : byConvo;
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// src/react/notifications.ts
|
|
305
|
-
import { useCallback, useEffect as useEffect2, useRef, useState } from "react";
|
|
306
|
-
|
|
307
|
-
// src/web-push.ts
|
|
308
|
-
function isWebPushSupported() {
|
|
309
|
-
return typeof window !== "undefined" && "serviceWorker" in navigator && "PushManager" in window;
|
|
310
|
-
}
|
|
311
|
-
function registerServiceWorker(path = "/truth-sw.js") {
|
|
312
|
-
return __async(this, null, function* () {
|
|
313
|
-
return navigator.serviceWorker.register(path);
|
|
314
|
-
});
|
|
315
|
-
}
|
|
316
|
-
function subscribeToPush(registration, vapidPublicKey) {
|
|
317
|
-
return __async(this, null, function* () {
|
|
318
|
-
const existing = yield registration.pushManager.getSubscription();
|
|
319
|
-
if (existing) {
|
|
320
|
-
return existing;
|
|
321
|
-
}
|
|
322
|
-
return registration.pushManager.subscribe({
|
|
323
|
-
userVisibleOnly: true,
|
|
324
|
-
applicationServerKey: urlBase64ToUint8Array(
|
|
325
|
-
vapidPublicKey
|
|
326
|
-
)
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
}
|
|
330
|
-
function subscriptionToJSON(sub) {
|
|
331
|
-
var _a, _b, _c, _d;
|
|
332
|
-
const json = sub.toJSON();
|
|
333
|
-
return {
|
|
334
|
-
endpoint: sub.endpoint,
|
|
335
|
-
keys: {
|
|
336
|
-
p256dh: (_b = (_a = json.keys) == null ? void 0 : _a.p256dh) != null ? _b : "",
|
|
337
|
-
auth: (_d = (_c = json.keys) == null ? void 0 : _c.auth) != null ? _d : ""
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
}
|
|
341
|
-
function urlBase64ToUint8Array(base64String) {
|
|
342
|
-
const padding = "=".repeat((4 - base64String.length % 4) % 4);
|
|
343
|
-
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
344
|
-
const rawData = atob(base64);
|
|
345
|
-
const outputArray = new Uint8Array(rawData.length);
|
|
346
|
-
for (let i = 0; i < rawData.length; ++i) {
|
|
347
|
-
outputArray[i] = rawData.charCodeAt(i);
|
|
348
|
-
}
|
|
349
|
-
return outputArray;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// src/react/notifications.ts
|
|
353
|
-
function loadExpo() {
|
|
354
|
-
return __async(this, null, function* () {
|
|
355
|
-
try {
|
|
356
|
-
return __require("expo-notifications");
|
|
357
|
-
} catch (e) {
|
|
358
|
-
return null;
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
function useNotifications(options) {
|
|
363
|
-
var _a;
|
|
364
|
-
const [permissionStatus, setPermissionStatus] = useState("unknown");
|
|
365
|
-
const [devicePushToken, setDevicePushToken] = useState(null);
|
|
366
|
-
const expoRef = useRef(null);
|
|
367
|
-
const isWebRef = useRef(false);
|
|
368
|
-
const vapidKeyRef = useRef((_a = options.vapidPublicKey) != null ? _a : null);
|
|
369
|
-
useEffect2(() => {
|
|
370
|
-
let mounted = true;
|
|
371
|
-
void (() => __async(null, null, function* () {
|
|
372
|
-
var _a2;
|
|
373
|
-
const expo = yield loadExpo();
|
|
374
|
-
if (!mounted) {
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
expoRef.current = expo;
|
|
378
|
-
if (expo) {
|
|
379
|
-
try {
|
|
380
|
-
const perm = yield expo.getPermissionsAsync();
|
|
381
|
-
if (!mounted) {
|
|
382
|
-
return;
|
|
383
|
-
}
|
|
384
|
-
setPermissionStatus(mapStatus(perm == null ? void 0 : perm.status));
|
|
385
|
-
} catch (e) {
|
|
386
|
-
setPermissionStatus("unknown");
|
|
387
|
-
}
|
|
388
|
-
return;
|
|
389
|
-
}
|
|
390
|
-
if (isWebPushSupported()) {
|
|
391
|
-
isWebRef.current = true;
|
|
392
|
-
if (!vapidKeyRef.current) {
|
|
393
|
-
try {
|
|
394
|
-
const res = yield fetch(
|
|
395
|
-
`${options.apiBaseUrl}/api/notifications/vapid-key`,
|
|
396
|
-
{
|
|
397
|
-
headers: {
|
|
398
|
-
Accept: "application/json",
|
|
399
|
-
"X-API-Key": options.apiKey
|
|
400
|
-
}
|
|
401
|
-
}
|
|
402
|
-
);
|
|
403
|
-
if (res.ok) {
|
|
404
|
-
const data = yield res.json();
|
|
405
|
-
vapidKeyRef.current = (_a2 = data.vapidPublicKey) != null ? _a2 : null;
|
|
406
|
-
}
|
|
407
|
-
} catch (e) {
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
if (!mounted) {
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
|
-
const webPerm = typeof Notification !== "undefined" ? Notification.permission : "default";
|
|
414
|
-
setPermissionStatus(
|
|
415
|
-
webPerm === "granted" ? "granted" : webPerm === "denied" ? "denied" : "undetermined"
|
|
416
|
-
);
|
|
417
|
-
} else {
|
|
418
|
-
setPermissionStatus("unknown");
|
|
419
|
-
}
|
|
420
|
-
}))();
|
|
421
|
-
return () => {
|
|
422
|
-
mounted = false;
|
|
423
|
-
};
|
|
424
|
-
}, [options.apiBaseUrl, options.apiKey]);
|
|
425
|
-
const register = useCallback(() => __async(null, null, function* () {
|
|
426
|
-
var _a2, _b;
|
|
427
|
-
if (!options.userId) {
|
|
428
|
-
return { ok: false, reason: "missing_userId" };
|
|
429
|
-
}
|
|
430
|
-
if (isWebRef.current) {
|
|
431
|
-
const vapidKey = vapidKeyRef.current;
|
|
432
|
-
if (!vapidKey) {
|
|
433
|
-
return { ok: false, reason: "no_vapid_key" };
|
|
434
|
-
}
|
|
435
|
-
const webPerm = yield Notification.requestPermission();
|
|
436
|
-
setPermissionStatus(
|
|
437
|
-
webPerm === "granted" ? "granted" : webPerm === "denied" ? "denied" : "undetermined"
|
|
438
|
-
);
|
|
439
|
-
if (webPerm !== "granted") {
|
|
440
|
-
return { ok: false, reason: "permission_denied" };
|
|
441
|
-
}
|
|
442
|
-
try {
|
|
443
|
-
const swPath = (_a2 = options.serviceWorkerPath) != null ? _a2 : "/truth-sw.js";
|
|
444
|
-
const registration = yield registerServiceWorker(swPath);
|
|
445
|
-
yield navigator.serviceWorker.ready;
|
|
446
|
-
const subscription = yield subscribeToPush(registration, vapidKey);
|
|
447
|
-
const subJSON = subscriptionToJSON(subscription);
|
|
448
|
-
setDevicePushToken(subscription.endpoint);
|
|
449
|
-
const res2 = yield fetch(
|
|
450
|
-
`${options.apiBaseUrl}/api/notifications/devices/register`,
|
|
451
|
-
{
|
|
452
|
-
method: "POST",
|
|
453
|
-
headers: {
|
|
454
|
-
"Content-Type": "application/json",
|
|
455
|
-
"X-API-Key": options.apiKey
|
|
456
|
-
},
|
|
457
|
-
body: JSON.stringify({
|
|
458
|
-
userId: options.userId,
|
|
459
|
-
platform: "web",
|
|
460
|
-
webPushSubscription: subJSON,
|
|
461
|
-
appVersion: options.appVersion,
|
|
462
|
-
locale: navigator.language,
|
|
463
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
464
|
-
})
|
|
465
|
-
}
|
|
466
|
-
);
|
|
467
|
-
if (!res2.ok) {
|
|
468
|
-
const text = yield res2.text().catch(() => "");
|
|
469
|
-
return {
|
|
470
|
-
ok: false,
|
|
471
|
-
reason: `register_failed_${res2.status}: ${text.slice(0, 120)}`
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
|
-
return { ok: true };
|
|
475
|
-
} catch (err) {
|
|
476
|
-
return {
|
|
477
|
-
ok: false,
|
|
478
|
-
reason: `web_push_error: ${err instanceof Error ? err.message : String(err)}`
|
|
479
|
-
};
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
const expo = (_b = expoRef.current) != null ? _b : yield loadExpo();
|
|
483
|
-
expoRef.current = expo;
|
|
484
|
-
if (!expo) {
|
|
485
|
-
return { ok: false, reason: "expo_notifications_missing" };
|
|
486
|
-
}
|
|
487
|
-
let perm = yield expo.getPermissionsAsync();
|
|
488
|
-
if ((perm == null ? void 0 : perm.status) !== "granted") {
|
|
489
|
-
perm = yield expo.requestPermissionsAsync();
|
|
490
|
-
}
|
|
491
|
-
setPermissionStatus(mapStatus(perm == null ? void 0 : perm.status));
|
|
492
|
-
if ((perm == null ? void 0 : perm.status) !== "granted") {
|
|
493
|
-
return { ok: false, reason: "permission_denied" };
|
|
494
|
-
}
|
|
495
|
-
const tokenResp = yield expo.getDevicePushTokenAsync();
|
|
496
|
-
const nativeToken = tokenResp == null ? void 0 : tokenResp.data;
|
|
497
|
-
const platform = detectPlatform(tokenResp == null ? void 0 : tokenResp.type);
|
|
498
|
-
if (!nativeToken || platform !== "ios" && platform !== "android") {
|
|
499
|
-
return { ok: false, reason: "no_native_token" };
|
|
500
|
-
}
|
|
501
|
-
setDevicePushToken(nativeToken);
|
|
502
|
-
const res = yield fetch(
|
|
503
|
-
`${options.apiBaseUrl}/api/notifications/devices/register`,
|
|
504
|
-
{
|
|
505
|
-
method: "POST",
|
|
506
|
-
headers: {
|
|
507
|
-
"Content-Type": "application/json",
|
|
508
|
-
"X-API-Key": options.apiKey
|
|
509
|
-
},
|
|
510
|
-
body: JSON.stringify({
|
|
511
|
-
userId: options.userId,
|
|
512
|
-
platform,
|
|
513
|
-
nativeToken,
|
|
514
|
-
appVersion: options.appVersion,
|
|
515
|
-
locale: typeof navigator !== "undefined" ? navigator.language : void 0,
|
|
516
|
-
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
517
|
-
})
|
|
518
|
-
}
|
|
519
|
-
);
|
|
520
|
-
if (!res.ok) {
|
|
521
|
-
const text = yield res.text().catch(() => "");
|
|
522
|
-
return {
|
|
523
|
-
ok: false,
|
|
524
|
-
reason: `register_failed_${res.status}: ${text.slice(0, 120)}`
|
|
525
|
-
};
|
|
526
|
-
}
|
|
527
|
-
return { ok: true };
|
|
528
|
-
}), [
|
|
529
|
-
options.apiBaseUrl,
|
|
530
|
-
options.apiKey,
|
|
531
|
-
options.userId,
|
|
532
|
-
options.appVersion,
|
|
533
|
-
options.serviceWorkerPath
|
|
534
|
-
]);
|
|
535
|
-
const unregister = useCallback(() => __async(null, null, function* () {
|
|
536
|
-
if (!devicePushToken) {
|
|
537
|
-
return;
|
|
538
|
-
}
|
|
539
|
-
yield fetch(`${options.apiBaseUrl}/api/notifications/devices/unregister`, {
|
|
540
|
-
method: "POST",
|
|
541
|
-
headers: {
|
|
542
|
-
"Content-Type": "application/json",
|
|
543
|
-
"X-API-Key": options.apiKey
|
|
544
|
-
},
|
|
545
|
-
body: JSON.stringify({ nativeToken: devicePushToken })
|
|
546
|
-
}).catch(() => {
|
|
547
|
-
});
|
|
548
|
-
setDevicePushToken(null);
|
|
549
|
-
}), [options.apiBaseUrl, options.apiKey, devicePushToken]);
|
|
550
|
-
const addReceivedListener = useCallback(
|
|
551
|
-
(listener) => {
|
|
552
|
-
if (isWebRef.current) {
|
|
553
|
-
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
|
|
554
|
-
return () => {
|
|
555
|
-
};
|
|
556
|
-
}
|
|
557
|
-
const handler = (event) => {
|
|
558
|
-
var _a2;
|
|
559
|
-
if (((_a2 = event.data) == null ? void 0 : _a2.type) === "TRUTH_PUSH_RECEIVED") {
|
|
560
|
-
listener(event.data.payload);
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
navigator.serviceWorker.addEventListener("message", handler);
|
|
564
|
-
return () => navigator.serviceWorker.removeEventListener("message", handler);
|
|
565
|
-
}
|
|
566
|
-
const expo = expoRef.current;
|
|
567
|
-
if (!(expo == null ? void 0 : expo.addNotificationReceivedListener)) {
|
|
568
|
-
return () => {
|
|
569
|
-
};
|
|
570
|
-
}
|
|
571
|
-
const sub = expo.addNotificationReceivedListener(listener);
|
|
572
|
-
return () => {
|
|
573
|
-
var _a2;
|
|
574
|
-
return (_a2 = sub.remove) == null ? void 0 : _a2.call(sub);
|
|
575
|
-
};
|
|
576
|
-
},
|
|
577
|
-
[]
|
|
578
|
-
);
|
|
579
|
-
const addResponseListener = useCallback(
|
|
580
|
-
(listener) => {
|
|
581
|
-
if (isWebRef.current) {
|
|
582
|
-
if (typeof navigator === "undefined" || !("serviceWorker" in navigator)) {
|
|
583
|
-
return () => {
|
|
584
|
-
};
|
|
585
|
-
}
|
|
586
|
-
const handler = (event) => {
|
|
587
|
-
var _a2;
|
|
588
|
-
if (((_a2 = event.data) == null ? void 0 : _a2.type) === "TRUTH_PUSH_TAPPED") {
|
|
589
|
-
listener(event.data.payload);
|
|
590
|
-
}
|
|
591
|
-
};
|
|
592
|
-
navigator.serviceWorker.addEventListener("message", handler);
|
|
593
|
-
return () => navigator.serviceWorker.removeEventListener("message", handler);
|
|
594
|
-
}
|
|
595
|
-
const expo = expoRef.current;
|
|
596
|
-
if (!(expo == null ? void 0 : expo.addNotificationResponseReceivedListener)) {
|
|
597
|
-
return () => {
|
|
598
|
-
};
|
|
599
|
-
}
|
|
600
|
-
const sub = expo.addNotificationResponseReceivedListener(listener);
|
|
601
|
-
return () => {
|
|
602
|
-
var _a2;
|
|
603
|
-
return (_a2 = sub.remove) == null ? void 0 : _a2.call(sub);
|
|
604
|
-
};
|
|
605
|
-
},
|
|
606
|
-
[]
|
|
607
|
-
);
|
|
608
|
-
const getBadgeCount = useCallback(() => __async(null, null, function* () {
|
|
609
|
-
var _a2;
|
|
610
|
-
const expo = expoRef.current;
|
|
611
|
-
if (!(expo == null ? void 0 : expo.getBadgeCountAsync)) {
|
|
612
|
-
return 0;
|
|
613
|
-
}
|
|
614
|
-
return (_a2 = yield expo.getBadgeCountAsync()) != null ? _a2 : 0;
|
|
615
|
-
}), []);
|
|
616
|
-
const setBadgeCount = useCallback((count) => __async(null, null, function* () {
|
|
617
|
-
const expo = expoRef.current;
|
|
618
|
-
if (!(expo == null ? void 0 : expo.setBadgeCountAsync)) {
|
|
619
|
-
return;
|
|
620
|
-
}
|
|
621
|
-
yield expo.setBadgeCountAsync(count);
|
|
622
|
-
}), []);
|
|
623
|
-
const autoRegister = options.autoRegister !== false;
|
|
624
|
-
useEffect2(() => {
|
|
625
|
-
if (!autoRegister) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
if (permissionStatus !== "granted") {
|
|
629
|
-
return;
|
|
630
|
-
}
|
|
631
|
-
if (devicePushToken) {
|
|
632
|
-
return;
|
|
633
|
-
}
|
|
634
|
-
if (!options.userId) {
|
|
635
|
-
return;
|
|
636
|
-
}
|
|
637
|
-
void register();
|
|
638
|
-
}, [
|
|
639
|
-
autoRegister,
|
|
640
|
-
permissionStatus,
|
|
641
|
-
devicePushToken,
|
|
642
|
-
options.userId,
|
|
643
|
-
register
|
|
644
|
-
]);
|
|
645
|
-
return {
|
|
646
|
-
permissionStatus,
|
|
647
|
-
devicePushToken,
|
|
648
|
-
register,
|
|
649
|
-
unregister,
|
|
650
|
-
addReceivedListener,
|
|
651
|
-
addResponseListener,
|
|
652
|
-
getBadgeCount,
|
|
653
|
-
setBadgeCount
|
|
654
|
-
};
|
|
655
|
-
}
|
|
656
|
-
function mapStatus(status) {
|
|
657
|
-
if (status === "granted") {
|
|
658
|
-
return "granted";
|
|
659
|
-
}
|
|
660
|
-
if (status === "denied") {
|
|
661
|
-
return "denied";
|
|
662
|
-
}
|
|
663
|
-
if (status === "undetermined") {
|
|
664
|
-
return "undetermined";
|
|
665
|
-
}
|
|
666
|
-
return "unknown";
|
|
667
|
-
}
|
|
668
|
-
function detectPlatform(tokenType) {
|
|
669
|
-
if (tokenType === "apns") {
|
|
670
|
-
return "ios";
|
|
671
|
-
}
|
|
672
|
-
if (tokenType === "fcm") {
|
|
673
|
-
return "android";
|
|
674
|
-
}
|
|
675
|
-
if (tokenType === "web") {
|
|
676
|
-
return "web";
|
|
677
|
-
}
|
|
678
|
-
return "unknown";
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
// src/react/provider.ts
|
|
682
|
-
import { ConvexProvider, ConvexReactClient } from "convex/react";
|
|
683
|
-
import { createElement, useMemo } from "react";
|
|
684
|
-
var CONVEX_URLS = {
|
|
685
|
-
local: "https://courteous-duck-623.convex.cloud",
|
|
686
|
-
staging: "https://courteous-duck-623.convex.cloud",
|
|
687
|
-
stg: "https://courteous-duck-623.convex.cloud",
|
|
688
|
-
sandbox: "https://courteous-duck-623.convex.cloud",
|
|
689
|
-
uat: "https://gallant-gecko-217.convex.cloud",
|
|
690
|
-
production: "https://gallant-gecko-217.convex.cloud"
|
|
691
|
-
};
|
|
692
|
-
function resolveConvexUrl(environment, override) {
|
|
693
|
-
var _a;
|
|
694
|
-
if (override) {
|
|
695
|
-
return override;
|
|
696
|
-
}
|
|
697
|
-
const env = environment != null ? environment : "sandbox";
|
|
698
|
-
return (_a = CONVEX_URLS[env]) != null ? _a : CONVEX_URLS.sandbox;
|
|
699
|
-
}
|
|
700
|
-
function TruthProvider({
|
|
701
|
-
environment = "sandbox",
|
|
702
|
-
convexUrl,
|
|
703
|
-
children
|
|
704
|
-
}) {
|
|
705
|
-
const url = resolveConvexUrl(environment, convexUrl);
|
|
706
|
-
const client = useMemo(() => new ConvexReactClient(url), [url]);
|
|
707
|
-
return createElement(ConvexProvider, { client }, children);
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
// src/react/tracking.ts
|
|
711
|
-
import { createContext, createElement as createElement2, useContext, useMemo as useMemo2 } from "react";
|
|
712
|
-
|
|
713
|
-
// src/tracking/tracker.ts
|
|
714
|
-
function generateUuidV7() {
|
|
715
|
-
const now = Date.now();
|
|
716
|
-
const timeBytes = new Uint8Array(6);
|
|
717
|
-
let ts = now;
|
|
718
|
-
for (let i = 5; i >= 0; i--) {
|
|
719
|
-
timeBytes[i] = ts & 255;
|
|
720
|
-
ts = Math.floor(ts / 256);
|
|
721
|
-
}
|
|
722
|
-
const randomBytes = new Uint8Array(10);
|
|
723
|
-
if (typeof globalThis.crypto !== "undefined" && globalThis.crypto.getRandomValues) {
|
|
724
|
-
globalThis.crypto.getRandomValues(randomBytes);
|
|
725
|
-
} else {
|
|
726
|
-
for (let i = 0; i < 10; i++) {
|
|
727
|
-
randomBytes[i] = Math.floor(Math.random() * 256);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
|
-
const bytes = new Uint8Array(16);
|
|
731
|
-
bytes.set(timeBytes, 0);
|
|
732
|
-
bytes.set(randomBytes, 6);
|
|
733
|
-
bytes[6] = bytes[6] & 15 | 112;
|
|
734
|
-
bytes[8] = bytes[8] & 63 | 128;
|
|
735
|
-
const hex = Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
736
|
-
return [
|
|
737
|
-
hex.slice(0, 8),
|
|
738
|
-
hex.slice(8, 12),
|
|
739
|
-
hex.slice(12, 16),
|
|
740
|
-
hex.slice(16, 20),
|
|
741
|
-
hex.slice(20, 32)
|
|
742
|
-
].join("-");
|
|
743
|
-
}
|
|
744
|
-
var API_URLS = {
|
|
745
|
-
local: "http://localhost:3000",
|
|
746
|
-
staging: "https://app.sandbox.communication-hub.com",
|
|
747
|
-
stg: "https://app.sandbox.communication-hub.com",
|
|
748
|
-
sandbox: "https://app.sandbox.communication-hub.com",
|
|
749
|
-
uat: "https://app.truth.communication-hub.com",
|
|
750
|
-
production: "https://app.truth.communication-hub.com"
|
|
751
|
-
};
|
|
752
|
-
var MAX_RETRIES = 3;
|
|
753
|
-
var BASE_RETRY_DELAY_MS = 500;
|
|
754
|
-
var Tracker = class {
|
|
755
|
-
constructor(config) {
|
|
756
|
-
this.queue = [];
|
|
757
|
-
this.flushTimer = null;
|
|
758
|
-
this.isFlushing = false;
|
|
759
|
-
this.isShutdown = false;
|
|
760
|
-
var _a, _b;
|
|
761
|
-
this.config = config;
|
|
762
|
-
this.apiUrl = (_b = (_a = config.apiBaseUrl) != null ? _a : API_URLS[config.environment]) != null ? _b : API_URLS.local;
|
|
763
|
-
this.startFlushInterval();
|
|
764
|
-
this.registerShutdownHooks();
|
|
765
|
-
}
|
|
766
|
-
/**
|
|
767
|
-
* Set the default actor context for subsequent events.
|
|
768
|
-
*/
|
|
769
|
-
setActor(actor) {
|
|
770
|
-
this.defaultActor = actor;
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Enqueue a typed event for delivery. This is fire-and-forget from
|
|
774
|
-
* the caller's perspective -- events are buffered and flushed in batches.
|
|
775
|
-
*/
|
|
776
|
-
track(eventType, payload, options) {
|
|
777
|
-
var _a, _b, _c;
|
|
778
|
-
if (this.isShutdown) {
|
|
779
|
-
return;
|
|
780
|
-
}
|
|
781
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
782
|
-
const envelope = {
|
|
783
|
-
event_id: generateUuidV7(),
|
|
784
|
-
event_type: eventType,
|
|
785
|
-
schema_version: 1,
|
|
786
|
-
occurred_at: (_a = options == null ? void 0 : options.occurredAt) != null ? _a : now,
|
|
787
|
-
received_at: now,
|
|
788
|
-
source: this.config.source,
|
|
789
|
-
source_version: this.config.sourceVersion,
|
|
790
|
-
tenant_id: (_b = options == null ? void 0 : options.tenantId) != null ? _b : this.config.tenantId,
|
|
791
|
-
actor: (_c = options == null ? void 0 : options.actor) != null ? _c : this.defaultActor ? {
|
|
792
|
-
actor_id: this.defaultActor.actorId,
|
|
793
|
-
actor_type: this.defaultActor.actorType
|
|
794
|
-
} : void 0,
|
|
795
|
-
subject: options == null ? void 0 : options.subject,
|
|
796
|
-
compliance: options == null ? void 0 : options.compliance,
|
|
797
|
-
payload
|
|
798
|
-
};
|
|
799
|
-
this.queue.push(envelope);
|
|
800
|
-
if (this.queue.length >= this.config.batchSize) {
|
|
801
|
-
void this.flush();
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
/**
|
|
805
|
-
* Force an immediate flush of all buffered events.
|
|
806
|
-
* Returns a promise that resolves when the flush completes.
|
|
807
|
-
*/
|
|
808
|
-
flush() {
|
|
809
|
-
return __async(this, null, function* () {
|
|
810
|
-
if (this.queue.length === 0 || this.isFlushing) {
|
|
811
|
-
return;
|
|
812
|
-
}
|
|
813
|
-
this.isFlushing = true;
|
|
814
|
-
const batch = this.queue.splice(0, this.config.batchSize);
|
|
815
|
-
try {
|
|
816
|
-
yield this.sendBatch(batch);
|
|
817
|
-
} catch (e) {
|
|
818
|
-
this.queue.unshift(...batch);
|
|
819
|
-
} finally {
|
|
820
|
-
this.isFlushing = false;
|
|
821
|
-
}
|
|
822
|
-
if (this.queue.length >= this.config.batchSize) {
|
|
823
|
-
yield this.flush();
|
|
824
|
-
}
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
/**
|
|
828
|
-
* Gracefully shut down the tracker. Flushes remaining events and
|
|
829
|
-
* clears the flush interval.
|
|
830
|
-
*/
|
|
831
|
-
shutdown() {
|
|
832
|
-
return __async(this, null, function* () {
|
|
833
|
-
this.isShutdown = true;
|
|
834
|
-
this.stopFlushInterval();
|
|
835
|
-
yield this.flush();
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
/**
|
|
839
|
-
* Send a batch of events to the Truth API with exponential backoff retry.
|
|
840
|
-
*/
|
|
841
|
-
sendBatch(batch) {
|
|
842
|
-
return __async(this, null, function* () {
|
|
843
|
-
let lastError;
|
|
844
|
-
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
845
|
-
try {
|
|
846
|
-
const response = yield fetch(`${this.apiUrl}/api/events/ingest`, {
|
|
847
|
-
method: "POST",
|
|
848
|
-
headers: {
|
|
849
|
-
"Content-Type": "application/json",
|
|
850
|
-
"X-API-Key": this.config.apiKey
|
|
851
|
-
},
|
|
852
|
-
body: JSON.stringify({ events: batch })
|
|
853
|
-
});
|
|
854
|
-
if (response.ok) {
|
|
855
|
-
return;
|
|
856
|
-
}
|
|
857
|
-
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
858
|
-
return;
|
|
859
|
-
}
|
|
860
|
-
lastError = new Error(
|
|
861
|
-
`HTTP ${response.status}: ${response.statusText}`
|
|
862
|
-
);
|
|
863
|
-
} catch (error) {
|
|
864
|
-
lastError = error;
|
|
865
|
-
}
|
|
866
|
-
if (attempt < MAX_RETRIES) {
|
|
867
|
-
const delay = BASE_RETRY_DELAY_MS * __pow(2, attempt);
|
|
868
|
-
const jitter = Math.random() * delay * 0.5;
|
|
869
|
-
yield sleep(delay + jitter);
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
throw lastError;
|
|
873
|
-
});
|
|
874
|
-
}
|
|
875
|
-
startFlushInterval() {
|
|
876
|
-
if (this.config.flushIntervalMs > 0) {
|
|
877
|
-
this.flushTimer = setInterval(() => {
|
|
878
|
-
void this.flush();
|
|
879
|
-
}, this.config.flushIntervalMs);
|
|
880
|
-
if (typeof this.flushTimer === "object" && "unref" in this.flushTimer) {
|
|
881
|
-
this.flushTimer.unref();
|
|
882
|
-
}
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
stopFlushInterval() {
|
|
886
|
-
if (this.flushTimer !== null) {
|
|
887
|
-
clearInterval(this.flushTimer);
|
|
888
|
-
this.flushTimer = null;
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
registerShutdownHooks() {
|
|
892
|
-
if (typeof globalThis.process !== "undefined" && globalThis.process.on) {
|
|
893
|
-
const shutdownHandler = () => {
|
|
894
|
-
void this.shutdown();
|
|
895
|
-
};
|
|
896
|
-
globalThis.process.on("beforeExit", shutdownHandler);
|
|
897
|
-
globalThis.process.on("SIGTERM", shutdownHandler);
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
};
|
|
901
|
-
function sleep(ms) {
|
|
902
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
903
|
-
}
|
|
904
|
-
|
|
905
|
-
// src/react/tracking.ts
|
|
906
|
-
var TruthTrackingContext = createContext(
|
|
907
|
-
null
|
|
908
|
-
);
|
|
909
|
-
function TruthTrackingProvider({
|
|
910
|
-
environment = "sandbox",
|
|
911
|
-
source = "communication-hub.frontend",
|
|
912
|
-
sourceVersion = "unknown",
|
|
913
|
-
tenantId = "hipnation",
|
|
914
|
-
apiKey = "",
|
|
915
|
-
children
|
|
916
|
-
}) {
|
|
917
|
-
const value = useMemo2(() => {
|
|
918
|
-
const tracker = new Tracker({
|
|
919
|
-
apiKey,
|
|
920
|
-
environment,
|
|
921
|
-
source,
|
|
922
|
-
sourceVersion,
|
|
923
|
-
tenantId,
|
|
924
|
-
batchSize: 10,
|
|
925
|
-
flushIntervalMs: 5e3
|
|
926
|
-
});
|
|
927
|
-
return {
|
|
928
|
-
track: (eventType, payload, options) => {
|
|
929
|
-
tracker.track(eventType, payload, options);
|
|
930
|
-
},
|
|
931
|
-
identify: (actorId, actorType) => {
|
|
932
|
-
tracker.setActor({ actorId, actorType });
|
|
933
|
-
}
|
|
934
|
-
};
|
|
935
|
-
}, [apiKey, environment, source, sourceVersion, tenantId]);
|
|
936
|
-
return createElement2(TruthTrackingContext.Provider, { value }, children);
|
|
937
|
-
}
|
|
938
|
-
function useTruth() {
|
|
939
|
-
const ctx = useContext(TruthTrackingContext);
|
|
940
|
-
if (!ctx) {
|
|
941
|
-
throw new Error("useTruth must be used within a TruthTrackingProvider");
|
|
942
|
-
}
|
|
943
|
-
return ctx;
|
|
944
|
-
}
|
|
945
|
-
export {
|
|
946
|
-
TruthProvider,
|
|
947
|
-
TruthTrackingProvider,
|
|
948
|
-
useAppointment,
|
|
949
|
-
useAppointmentByElationId,
|
|
950
|
-
useAppointments,
|
|
951
|
-
useConversationByPhonePair,
|
|
952
|
-
useConversationMessages,
|
|
953
|
-
useConversations,
|
|
954
|
-
useMessages,
|
|
955
|
-
useNotifications,
|
|
956
|
-
usePatient,
|
|
957
|
-
usePatientBasic,
|
|
958
|
-
usePatientByElationId,
|
|
959
|
-
usePatientByHintId,
|
|
960
|
-
usePatientMedical,
|
|
961
|
-
usePatientPhoto,
|
|
962
|
-
usePatients,
|
|
963
|
-
usePharmacyByNcpdpId,
|
|
964
|
-
usePhysicianByElationId,
|
|
965
|
-
usePhysiciansByElationIds,
|
|
966
|
-
useTruth,
|
|
967
|
-
useUnreadCount
|
|
968
|
-
};
|
|
969
|
-
//# sourceMappingURL=react.mjs.map
|