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 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 escapedPatientName = escapeHL7(requestData.patientName || "Unknown Patient");
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||${requestData.patientId || ""}||${escapedPatientName}^||${timestamp}|U||||||||||${requestData.userId || ""}|||||||||||||||`
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.patientId ? [
1594
+ identifier: requestData.patientDetails?.id ? [
1526
1595
  {
1527
1596
  system: "http://nuxera.ai/patient-id",
1528
- value: requestData.patientId.toString()
1597
+ value: requestData.patientDetails.id.toString()
1529
1598
  }
1530
1599
  ] : [],
1531
1600
  name: [
1532
1601
  {
1533
- family: requestData.patientName || "Unknown",
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
- patientName: patientName || "",
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 (patientId) formData.append("patientId", patientId.toString());
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
- patientId,
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);