sera-ai 1.0.27 → 1.0.28
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 +8 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +96 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +96 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
|
|
3
|
+
interface PatientDetails {
|
|
4
|
+
id?: number;
|
|
5
|
+
name?: string;
|
|
6
|
+
gender?: string;
|
|
7
|
+
dateOfBirth?: Date | string;
|
|
8
|
+
age?: number;
|
|
9
|
+
}
|
|
3
10
|
interface AudioRecorderProps {
|
|
4
11
|
speciality: string;
|
|
5
12
|
apiKey: string;
|
|
6
13
|
apiBaseUrl?: string;
|
|
7
|
-
patientId?: number;
|
|
8
|
-
patientName?: string;
|
|
9
14
|
patientHistory?: string;
|
|
15
|
+
patientDetails?: PatientDetails;
|
|
10
16
|
selectedFormat?: "json" | "hl7" | "fhir";
|
|
11
17
|
onTranscriptionUpdate?: (text: string, sessionId: string) => void;
|
|
12
18
|
onTranscriptionComplete?: (text: string, classification: ClassificationInfoResponse, sessionId: string) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import * as React$1 from 'react';
|
|
2
2
|
|
|
3
|
+
interface PatientDetails {
|
|
4
|
+
id?: number;
|
|
5
|
+
name?: string;
|
|
6
|
+
gender?: string;
|
|
7
|
+
dateOfBirth?: Date | string;
|
|
8
|
+
age?: number;
|
|
9
|
+
}
|
|
3
10
|
interface AudioRecorderProps {
|
|
4
11
|
speciality: string;
|
|
5
12
|
apiKey: string;
|
|
6
13
|
apiBaseUrl?: string;
|
|
7
|
-
patientId?: number;
|
|
8
|
-
patientName?: string;
|
|
9
14
|
patientHistory?: string;
|
|
15
|
+
patientDetails?: PatientDetails;
|
|
10
16
|
selectedFormat?: "json" | "hl7" | "fhir";
|
|
11
17
|
onTranscriptionUpdate?: (text: string, sessionId: string) => void;
|
|
12
18
|
onTranscriptionComplete?: (text: string, classification: ClassificationInfoResponse, sessionId: string) => void;
|
package/dist/index.js
CHANGED
|
@@ -1005,6 +1005,65 @@ var useHL7FHIRConverter = () => {
|
|
|
1005
1005
|
const escapeHL7 = React3.useCallback((text) => {
|
|
1006
1006
|
return text.replace(/\\/g, "\\E\\").replace(/\|/g, "\\F\\").replace(/\^/g, "\\S\\").replace(/~/g, "\\R\\").replace(/&/g, "\\T\\").replace(/\n/g, "\\X0A\\").replace(/\r/g, "\\X0D\\");
|
|
1007
1007
|
}, []);
|
|
1008
|
+
const formatHL7Date = (date) => {
|
|
1009
|
+
if (!date) return "";
|
|
1010
|
+
if (date instanceof Date && !isNaN(date.getTime())) {
|
|
1011
|
+
const year = date.getFullYear().toString().padStart(4, "0");
|
|
1012
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
1013
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
1014
|
+
return `${year}${month}${day}`;
|
|
1015
|
+
}
|
|
1016
|
+
if (typeof date === "string") {
|
|
1017
|
+
const trimmed = date.trim();
|
|
1018
|
+
if (/^\\d{8}$/.test(trimmed)) return trimmed;
|
|
1019
|
+
const parsed = new Date(trimmed);
|
|
1020
|
+
if (!isNaN(parsed.getTime())) {
|
|
1021
|
+
const year = parsed.getFullYear().toString().padStart(4, "0");
|
|
1022
|
+
const month = (parsed.getMonth() + 1).toString().padStart(2, "0");
|
|
1023
|
+
const day = parsed.getDate().toString().padStart(2, "0");
|
|
1024
|
+
return `${year}${month}${day}`;
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
return "";
|
|
1028
|
+
};
|
|
1029
|
+
const formatFHIRDate = (date) => {
|
|
1030
|
+
if (!date) return void 0;
|
|
1031
|
+
if (date instanceof Date && !isNaN(date.getTime())) {
|
|
1032
|
+
const year = date.getFullYear().toString().padStart(4, "0");
|
|
1033
|
+
const month = (date.getMonth() + 1).toString().padStart(2, "0");
|
|
1034
|
+
const day = date.getDate().toString().padStart(2, "0");
|
|
1035
|
+
return `${year}-${month}-${day}`;
|
|
1036
|
+
}
|
|
1037
|
+
if (typeof date === "string") {
|
|
1038
|
+
const trimmed = date.trim();
|
|
1039
|
+
if (/^\\d{4}-\\d{2}-\\d{2}$/.test(trimmed)) return trimmed;
|
|
1040
|
+
const parsed = new Date(trimmed);
|
|
1041
|
+
if (!isNaN(parsed.getTime())) {
|
|
1042
|
+
const year = parsed.getFullYear().toString().padStart(4, "0");
|
|
1043
|
+
const month = (parsed.getMonth() + 1).toString().padStart(2, "0");
|
|
1044
|
+
const day = parsed.getDate().toString().padStart(2, "0");
|
|
1045
|
+
return `${year}-${month}-${day}`;
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
return void 0;
|
|
1049
|
+
};
|
|
1050
|
+
const mapHL7Gender = (gender) => {
|
|
1051
|
+
if (!gender) return "U";
|
|
1052
|
+
const normalized = gender.toLowerCase();
|
|
1053
|
+
if (normalized === "male" || normalized === "m") return "M";
|
|
1054
|
+
if (normalized === "female" || normalized === "f") return "F";
|
|
1055
|
+
if (normalized === "other" || normalized === "o") return "O";
|
|
1056
|
+
return "U";
|
|
1057
|
+
};
|
|
1058
|
+
const mapFHIRGender = (gender) => {
|
|
1059
|
+
if (!gender) return void 0;
|
|
1060
|
+
const normalized = gender.toLowerCase();
|
|
1061
|
+
if (normalized === "male" || normalized === "m") return "male";
|
|
1062
|
+
if (normalized === "female" || normalized === "f") return "female";
|
|
1063
|
+
if (normalized === "other" || normalized === "o") return "other";
|
|
1064
|
+
if (normalized === "unknown" || normalized === "u") return "unknown";
|
|
1065
|
+
return "unknown";
|
|
1066
|
+
};
|
|
1008
1067
|
const parseHL7 = React3.useCallback((hl7String) => {
|
|
1009
1068
|
const segments = [];
|
|
1010
1069
|
const lines = hl7String.split(/[\r\n]+/);
|
|
@@ -1406,9 +1465,14 @@ var useHL7FHIRConverter = () => {
|
|
|
1406
1465
|
hl7Lines.push(
|
|
1407
1466
|
`MSH|^~\\&|Nuxera-Client|CLIENT_FACILITY|Nuxera-Transcribe|Nuxera|${timestamp}||ORU^R01^ORU_R01|${messageControlId}|P|2.5`
|
|
1408
1467
|
);
|
|
1409
|
-
const
|
|
1468
|
+
const patientId = requestData.patientDetails?.id?.toString() || "";
|
|
1469
|
+
const escapedPatientName = escapeHL7(
|
|
1470
|
+
requestData.patientDetails?.name || "Unknown Patient"
|
|
1471
|
+
);
|
|
1472
|
+
const patientDob = formatHL7Date(requestData.patientDetails?.dateOfBirth);
|
|
1473
|
+
const patientGender = mapHL7Gender(requestData.patientDetails?.gender);
|
|
1410
1474
|
hl7Lines.push(
|
|
1411
|
-
`PID|1||${
|
|
1475
|
+
`PID|1||${patientId}||${escapedPatientName}^||${patientDob}|${patientGender}||||||||||${requestData.userId || ""}|||||||||||||||`
|
|
1412
1476
|
);
|
|
1413
1477
|
hl7Lines.push(
|
|
1414
1478
|
`OBR|1|${messageControlId}||TRANSCRIPTION^Audio Transcription Request|||${timestamp}||||||||${timestamp}|||F`
|
|
@@ -1421,6 +1485,11 @@ var useHL7FHIRConverter = () => {
|
|
|
1421
1485
|
)}|||||F|||${timestamp}`
|
|
1422
1486
|
);
|
|
1423
1487
|
}
|
|
1488
|
+
if (requestData.patientDetails?.age !== void 0) {
|
|
1489
|
+
hl7Lines.push(
|
|
1490
|
+
`OBX|${obxSequence++}|NM|PATIENT_AGE^Patient Age||${requestData.patientDetails.age}|||||F|||${timestamp}`
|
|
1491
|
+
);
|
|
1492
|
+
}
|
|
1424
1493
|
hl7Lines.push(
|
|
1425
1494
|
`OBX|${obxSequence++}|TX|MODEL^Transcription Model||${escapeHL7(
|
|
1426
1495
|
requestData.model
|
|
@@ -1475,7 +1544,7 @@ var useHL7FHIRConverter = () => {
|
|
|
1475
1544
|
formData.append("audio", audioFile);
|
|
1476
1545
|
return formData;
|
|
1477
1546
|
},
|
|
1478
|
-
[escapeHL7]
|
|
1547
|
+
[escapeHL7, formatHL7Date, mapHL7Gender]
|
|
1479
1548
|
);
|
|
1480
1549
|
const createFHIRTranscriptionRequest = React3.useCallback(
|
|
1481
1550
|
(audioFile, requestData) => {
|
|
@@ -1522,18 +1591,26 @@ var useHL7FHIRConverter = () => {
|
|
|
1522
1591
|
resource: {
|
|
1523
1592
|
resourceType: "Patient",
|
|
1524
1593
|
id: `${requestId}-patient`,
|
|
1525
|
-
identifier: requestData.
|
|
1594
|
+
identifier: requestData.patientDetails?.id ? [
|
|
1526
1595
|
{
|
|
1527
1596
|
system: "http://nuxera.ai/patient-id",
|
|
1528
|
-
value: requestData.
|
|
1597
|
+
value: requestData.patientDetails.id.toString()
|
|
1529
1598
|
}
|
|
1530
1599
|
] : [],
|
|
1531
1600
|
name: [
|
|
1532
1601
|
{
|
|
1533
|
-
family: requestData.
|
|
1602
|
+
family: requestData.patientDetails?.name || "Unknown",
|
|
1534
1603
|
given: ["Patient"]
|
|
1535
1604
|
}
|
|
1536
|
-
]
|
|
1605
|
+
],
|
|
1606
|
+
gender: mapFHIRGender(requestData.patientDetails?.gender),
|
|
1607
|
+
birthDate: formatFHIRDate(requestData.patientDetails?.dateOfBirth),
|
|
1608
|
+
extension: requestData.patientDetails?.age !== void 0 ? [
|
|
1609
|
+
{
|
|
1610
|
+
url: "http://hl7.org/fhir/StructureDefinition/patient-age",
|
|
1611
|
+
valueUnsignedInt: requestData.patientDetails.age
|
|
1612
|
+
}
|
|
1613
|
+
] : void 0
|
|
1537
1614
|
}
|
|
1538
1615
|
},
|
|
1539
1616
|
// Practitioner (Doctor)
|
|
@@ -1736,7 +1813,7 @@ var useHL7FHIRConverter = () => {
|
|
|
1736
1813
|
);
|
|
1737
1814
|
return formData;
|
|
1738
1815
|
},
|
|
1739
|
-
[]
|
|
1816
|
+
[formatFHIRDate, mapFHIRGender]
|
|
1740
1817
|
);
|
|
1741
1818
|
const clearError = React3.useCallback(() => {
|
|
1742
1819
|
setConversionError(null);
|
|
@@ -2849,9 +2926,8 @@ var useAudioRecorder = ({
|
|
|
2849
2926
|
apiKey,
|
|
2850
2927
|
apiBaseUrl = API_BASE_URL,
|
|
2851
2928
|
speciality,
|
|
2852
|
-
patientId,
|
|
2853
|
-
patientName,
|
|
2854
2929
|
patientHistory,
|
|
2930
|
+
patientDetails,
|
|
2855
2931
|
selectedFormat = "json",
|
|
2856
2932
|
skipDiarization = true,
|
|
2857
2933
|
silenceRemoval = true,
|
|
@@ -3203,12 +3279,12 @@ var useAudioRecorder = ({
|
|
|
3203
3279
|
`[WARN] Small audio file (${audioFile.size} bytes) - may contain minimal audio data, sending to server anyway`
|
|
3204
3280
|
);
|
|
3205
3281
|
}
|
|
3282
|
+
const patientDetailsPayload = patientDetails;
|
|
3206
3283
|
const requestData = {
|
|
3207
3284
|
sessionId: retry ? void 0 : sessionIdRef.current || void 0,
|
|
3208
3285
|
model: selectedModelRef.current,
|
|
3209
3286
|
doctorName,
|
|
3210
|
-
|
|
3211
|
-
patientId,
|
|
3287
|
+
patientDetails: patientDetailsPayload,
|
|
3212
3288
|
removeSilence: removeSilenceRef.current,
|
|
3213
3289
|
skipDiarization: skipDiarizationRef.current,
|
|
3214
3290
|
isFinalChunk,
|
|
@@ -3243,9 +3319,10 @@ var useAudioRecorder = ({
|
|
|
3243
3319
|
formData.append("audio", audioFile);
|
|
3244
3320
|
formData.append("model", selectedModelRef.current);
|
|
3245
3321
|
formData.append("doctorName", doctorName);
|
|
3246
|
-
formData.append("patientName", patientName || "");
|
|
3247
3322
|
if (patientHistory) formData.append("patientHistory", patientHistory);
|
|
3248
|
-
if (
|
|
3323
|
+
if (patientDetailsPayload) {
|
|
3324
|
+
formData.append("patientDetails", JSON.stringify(patientDetailsPayload));
|
|
3325
|
+
}
|
|
3249
3326
|
formData.append("removeSilence", removeSilenceRef.current.toString());
|
|
3250
3327
|
formData.append("skipDiarization", skipDiarizationRef.current.toString());
|
|
3251
3328
|
formData.append("isFinalChunk", isFinalChunk.toString());
|
|
@@ -3430,8 +3507,8 @@ var useAudioRecorder = ({
|
|
|
3430
3507
|
silenceRemoval,
|
|
3431
3508
|
skipDiarization,
|
|
3432
3509
|
selectedFormat,
|
|
3433
|
-
patientName,
|
|
3434
3510
|
patientHistory,
|
|
3511
|
+
patientDetails,
|
|
3435
3512
|
onTranscriptionComplete,
|
|
3436
3513
|
speciality,
|
|
3437
3514
|
removeSilence,
|
|
@@ -3530,8 +3607,7 @@ var useAudioRecorder = ({
|
|
|
3530
3607
|
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
|
|
3531
3608
|
if (!isPaused && localSessionIdRef.current) {
|
|
3532
3609
|
await createSession(localSessionIdRef.current, {
|
|
3533
|
-
|
|
3534
|
-
patientName: patientName || void 0,
|
|
3610
|
+
patientDetails: patientDetails || void 0,
|
|
3535
3611
|
patientHistory: patientHistory || void 0,
|
|
3536
3612
|
speciality,
|
|
3537
3613
|
sampleRate: audioContext.sampleRate
|
|
@@ -3615,9 +3691,8 @@ var useAudioRecorder = ({
|
|
|
3615
3691
|
validateMicrophoneAccess,
|
|
3616
3692
|
isPaused,
|
|
3617
3693
|
createSession,
|
|
3618
|
-
patientId,
|
|
3619
|
-
patientName,
|
|
3620
3694
|
patientHistory,
|
|
3695
|
+
patientDetails,
|
|
3621
3696
|
speciality,
|
|
3622
3697
|
currentDeviceId
|
|
3623
3698
|
]);
|
|
@@ -4416,9 +4491,8 @@ var AudioRecorder = ({
|
|
|
4416
4491
|
apiKey,
|
|
4417
4492
|
apiBaseUrl,
|
|
4418
4493
|
speciality,
|
|
4419
|
-
patientId,
|
|
4420
|
-
patientName,
|
|
4421
4494
|
patientHistory,
|
|
4495
|
+
patientDetails,
|
|
4422
4496
|
selectedFormat = "json",
|
|
4423
4497
|
onTranscriptionUpdate,
|
|
4424
4498
|
onTranscriptionComplete,
|
|
@@ -4453,9 +4527,8 @@ var AudioRecorder = ({
|
|
|
4453
4527
|
apiKey,
|
|
4454
4528
|
apiBaseUrl,
|
|
4455
4529
|
speciality,
|
|
4456
|
-
patientName,
|
|
4457
|
-
patientId,
|
|
4458
4530
|
patientHistory,
|
|
4531
|
+
patientDetails,
|
|
4459
4532
|
selectedFormat,
|
|
4460
4533
|
onTranscriptionUpdate: (text, sessionId) => {
|
|
4461
4534
|
console.log("onTranscriptionUpdate called with text:", text, "sessionId:", sessionId);
|