med-scribe-alliance-ts-sdk 2.0.37 → 2.0.39

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/README.md CHANGED
@@ -395,8 +395,8 @@ interface RecordingOptions {
395
395
 
396
396
  | Method | Returns | Description |
397
397
  |---|---|---|
398
- | `createSession(request)` | `SDKResult<CreateSessionResponse>` | Create a session without starting a recording. |
399
- | `getSessionStatus(sessionId?, options?)` | `SDKResult<GetSessionStatusResponse>` | Get status. Supports `poll` and `templateId` options. |
398
+ | `createSession(request, version?)` | `SDKResult<CreateSessionResponse>` | Create a session without starting a recording. Optional `version` is sent as a `version` query param. |
399
+ | `getSessionStatus(sessionId?, options?)` | `SDKResult<GetSessionStatusResponse>` | Get status. Supports `poll`, `templateId`, and `version` options (`version` sent as a query param). |
400
400
  | `getCurrentSession()` | `CreateSessionResponse \| null` | Get the active session if any. |
401
401
  | `updateSession(request, sessionId?)` | `SDKResult<PatchSessionResponse>` | Patch session (patient details, status, etc.). |
402
402
  | `processTemplate(templateId, sessionId?)` | `SDKResult<ProcessTemplateResponse>` | Trigger processing for a specific template. |
package/dist/index.d.ts CHANGED
@@ -425,6 +425,7 @@ export interface GetSessionStatusResponse {
425
425
  };
426
426
  patient_details?: PatientDetails;
427
427
  message?: string;
428
+ upload_url?: SessionUploadInfo;
428
429
  }
429
430
  export interface TemplateEntry {
430
431
  [templateId: string]: TemplateEntryData;
@@ -533,8 +534,8 @@ export type AudioChunkInfo = {
533
534
  response?: string;
534
535
  } & ({
535
536
  status: "pending";
536
- audioFrames: Float32Array;
537
- fileBlob?: undefined;
537
+ audioFrames?: Float32Array;
538
+ fileBlob?: Blob;
538
539
  } | {
539
540
  status: "success";
540
541
  audioFrames?: undefined;
@@ -806,7 +807,7 @@ export declare class ScribeClient {
806
807
  /**
807
808
  * Create a session directly (without starting a recording).
808
809
  */
809
- createSession(sessionRequest: CreateSessionRequest): Promise<SDKResult<CreateSessionResponse>>;
810
+ createSession(sessionRequest: CreateSessionRequest, version?: string): Promise<SDKResult<CreateSessionResponse>>;
810
811
  /**
811
812
  * End a session directly.
812
813
  */
@@ -819,10 +820,12 @@ export declare class ScribeClient {
819
820
  * terminal state (completed, partial, failed, expired) or times out.
820
821
  *
821
822
  * Pass `templateId` to filter status for a specific template.
823
+ * Pass `version` to target a specific API version (attached as a query param).
822
824
  */
823
825
  getSessionStatus(sessionId?: string, options?: {
824
826
  poll?: PollOptions;
825
827
  templateId?: string;
828
+ version?: string;
826
829
  }): Promise<SDKResult<GetSessionStatusResponse>>;
827
830
  /**
828
831
  * Get the current active session, if any.
@@ -1057,7 +1060,7 @@ export declare class SessionManager {
1057
1060
  * Create a new scribe session.
1058
1061
  * Validates the request structure, sends to server, validates response.
1059
1062
  */
1060
- createSession(baseUrl: string, request: CreateSessionRequest): Promise<ApiCallResult<CreateSessionResponse>>;
1063
+ createSession(baseUrl: string, request: CreateSessionRequest, version?: string): Promise<ApiCallResult<CreateSessionResponse>>;
1061
1064
  /**
1062
1065
  * End an active session.
1063
1066
  * If no sessionId is provided, ends the current session.
@@ -1068,7 +1071,7 @@ export declare class SessionManager {
1068
1071
  * If no sessionId is provided, queries the current session.
1069
1072
  * Pass templateId to filter status for a specific template.
1070
1073
  */
1071
- getSessionStatus(baseUrl: string, sessionId?: string, templateId?: string): Promise<ApiCallResult<GetSessionStatusResponse>>;
1074
+ getSessionStatus(baseUrl: string, sessionId?: string, templateId?: string, version?: string): Promise<ApiCallResult<GetSessionStatusResponse>>;
1072
1075
  /**
1073
1076
  * Patch an existing session (e.g., update user_status or processing_status).
1074
1077
  */
@@ -1083,7 +1086,7 @@ export declare class SessionManager {
1083
1086
  * (completed, partial, or failed) or the max attempts are exhausted.
1084
1087
  * Pass templateId to filter the returned status for a specific template.
1085
1088
  */
1086
- pollForCompletion(baseUrl: string, sessionId?: string, options?: PollOptions, templateId?: string): Promise<ApiCallResult<GetSessionStatusResponse>>;
1089
+ pollForCompletion(baseUrl: string, sessionId?: string, options?: PollOptions, templateId?: string, version?: string): Promise<ApiCallResult<GetSessionStatusResponse>>;
1087
1090
  /**
1088
1091
  * Get the current active session, if any.
1089
1092
  */
package/dist/index.mjs CHANGED
@@ -748,19 +748,19 @@ var z = class {
748
748
  constructor(e, t, n = !1) {
749
749
  this.currentSession = null, this.transport = e, this.validator = t, this.debug = n;
750
750
  }
751
- async createSession(e, t) {
751
+ async createSession(e, t, n) {
752
752
  try {
753
753
  this.validator.validateCreateSessionRequest(t);
754
- let n = `${e}/sessions`;
755
- this.debug && console.log("[ScribeSDK] Creating session:", n);
756
- let r = await this.transport.request({
754
+ let r = `${e}/sessions`;
755
+ n && (r += `?version=${encodeURIComponent(n)}`), this.debug && console.log("[ScribeSDK] Creating session:", r);
756
+ let i = await this.transport.request({
757
757
  method: "POST",
758
- url: n,
758
+ url: r,
759
759
  body: t
760
760
  });
761
- return this.validator.validateCreateSessionResponse(r.data), this.currentSession = r.data, this.debug && console.log("[ScribeSDK] Session created:", r.data.session_id), {
762
- data: r.data,
763
- httpStatus: r.status
761
+ return this.validator.validateCreateSessionResponse(i.data), this.currentSession = i.data, this.debug && console.log("[ScribeSDK] Session created:", i.data.session_id), {
762
+ data: i.data,
763
+ httpStatus: i.status
764
764
  };
765
765
  } catch (e) {
766
766
  throw e instanceof v ? e : new v(`Failed to create session: ${e instanceof Error ? e.message : "Unknown error"}`);
@@ -786,21 +786,23 @@ var z = class {
786
786
  throw e instanceof v ? e : new v(`Failed to end session: ${e instanceof Error ? e.message : "Unknown error"}`);
787
787
  }
788
788
  }
789
- async getSessionStatus(e, t, n) {
789
+ async getSessionStatus(e, t, n, r) {
790
790
  try {
791
- let r = t ?? this.currentSession?.session_id;
792
- if (!r) throw new v("No active session. Provide a sessionId or start a session first.");
793
- this.validator.validateSessionId(r);
794
- let i = `${e}/sessions/${r}`;
795
- n && (i += `?template_id=${encodeURIComponent(n)}`), this.debug && console.log("[ScribeSDK] Getting session status:", r);
796
- let a = await this.transport.request({
791
+ let i = t ?? this.currentSession?.session_id;
792
+ if (!i) throw new v("No active session. Provide a sessionId or start a session first.");
793
+ this.validator.validateSessionId(i);
794
+ let a = new URLSearchParams();
795
+ n && a.set("template_id", n), r && a.set("version", r);
796
+ let o = a.toString(), s = o ? `${e}/sessions/${i}?${o}` : `${e}/sessions/${i}`;
797
+ this.debug && console.log("[ScribeSDK] Getting session status:", i);
798
+ let c = await this.transport.request({
797
799
  method: "GET",
798
- url: i,
800
+ url: s,
799
801
  acceptStatuses: [410]
800
802
  });
801
- return this.validator.validateGetSessionStatusResponse(a.data), this.debug && console.log("[ScribeSDK] Session status:", r, a.data.status), {
802
- data: a.data,
803
- httpStatus: a.status
803
+ return this.validator.validateGetSessionStatusResponse(c.data), this.debug && console.log("[ScribeSDK] Session status:", i, c.data.status), {
804
+ data: c.data,
805
+ httpStatus: c.status
804
806
  };
805
807
  } catch (e) {
806
808
  throw e instanceof v ? e : new v(`Failed to get session status: ${e instanceof Error ? e.message : "Unknown error"}`);
@@ -845,42 +847,42 @@ var z = class {
845
847
  throw e instanceof v ? e : new v(`Failed to process template: ${e instanceof Error ? e.message : "Unknown error"}`);
846
848
  }
847
849
  }
848
- async pollForCompletion(e, t, n, r) {
850
+ async pollForCompletion(e, t, n, r, i) {
849
851
  try {
850
- let i = t ?? this.currentSession?.session_id;
851
- if (!i) throw new v("No active session. Provide a sessionId or start a session first.");
852
- let a = n?.maxAttempts ?? 60, o = n?.intervalMs ?? 2e3, s = n?.timeoutMs, c = s !== void 0 && s > 0 ? Date.now() + s : void 0;
853
- this.debug && console.log("[ScribeSDK] Polling for completion:", i, {
854
- maxAttempts: a,
855
- intervalMs: o,
856
- timeoutMs: s
852
+ let a = t ?? this.currentSession?.session_id;
853
+ if (!a) throw new v("No active session. Provide a sessionId or start a session first.");
854
+ let o = n?.maxAttempts ?? 60, s = n?.intervalMs ?? 2e3, c = n?.timeoutMs, l = c !== void 0 && c > 0 ? Date.now() + c : void 0;
855
+ this.debug && console.log("[ScribeSDK] Polling for completion:", a, {
856
+ maxAttempts: o,
857
+ intervalMs: s,
858
+ timeoutMs: c
857
859
  });
858
- for (let t = 1; t <= a; t++) {
859
- if (n?.signal?.aborted) throw new v("Polling was aborted", "polling_aborted", void 0, { session_id: i });
860
- if (c !== void 0 && Date.now() >= c) throw new v(`Polling timed out after ${s}ms for session '${i}'`, "polling_timeout", void 0, {
861
- session_id: i,
862
- timeout_ms: s
860
+ for (let t = 1; t <= o; t++) {
861
+ if (n?.signal?.aborted) throw new v("Polling was aborted", "polling_aborted", void 0, { session_id: a });
862
+ if (l !== void 0 && Date.now() >= l) throw new v(`Polling timed out after ${c}ms for session '${a}'`, "polling_timeout", void 0, {
863
+ session_id: a,
864
+ timeout_ms: c
863
865
  });
864
- let l = await this.getSessionStatus(e, i, r), u = l.data;
866
+ let u = await this.getSessionStatus(e, a, r, i), d = u.data;
865
867
  if (n?.onProgress) try {
866
- n.onProgress(u);
868
+ n.onProgress(d);
867
869
  } catch (e) {
868
870
  console.error("[ScribeSDK] Error in poll onProgress callback:", e);
869
871
  }
870
- if (this.isTerminalStatus(u.status)) return this.debug && console.log("[ScribeSDK] Poll complete:", i, u.status, `(attempt ${t})`), l;
871
- if (t < a) {
872
- let e = o;
873
- if (c !== void 0) {
874
- let t = c - Date.now();
872
+ if (this.isTerminalStatus(d.status)) return this.debug && console.log("[ScribeSDK] Poll complete:", a, d.status, `(attempt ${t})`), u;
873
+ if (t < o) {
874
+ let e = s;
875
+ if (l !== void 0) {
876
+ let t = l - Date.now();
875
877
  if (t <= 0) continue;
876
- e = Math.min(o, t);
878
+ e = Math.min(s, t);
877
879
  }
878
880
  await this.sleepWithAbort(e, n?.signal);
879
881
  }
880
882
  }
881
- throw new v(`Polling timed out after ${a} attempts for session '${i}'`, "polling_timeout", void 0, {
882
- session_id: i,
883
- max_attempts: a
883
+ throw new v(`Polling timed out after ${o} attempts for session '${a}'`, "polling_timeout", void 0, {
884
+ session_id: a,
885
+ max_attempts: o
884
886
  });
885
887
  } catch (e) {
886
888
  throw e instanceof v ? e : new v(`Failed to poll session: ${e instanceof Error ? e.message : "Unknown error"}`);
@@ -1177,13 +1179,18 @@ var pe = {
1177
1179
  });
1178
1180
  }), e;
1179
1181
  }
1182
+ storeEncodedBlob(e, t) {
1183
+ if (e < 0 || e >= this.chunks.length) return;
1184
+ let n = this.chunks[e];
1185
+ n.status === "pending" && (n.fileBlob = t, n.audioFrames = void 0);
1186
+ }
1180
1187
  markPendingAsFailed() {
1181
1188
  for (let e = 0; e < this.chunks.length; e++) this.chunks[e].status === "pending" && (this.chunks[e] = {
1182
1189
  fileName: this.chunks[e].fileName,
1183
1190
  timestamp: this.chunks[e].timestamp,
1184
1191
  response: "Upload did not complete (timed out or worker unresponsive)",
1185
1192
  status: "failure",
1186
- fileBlob: new Blob()
1193
+ fileBlob: this.chunks[e].fileBlob ?? new Blob()
1187
1194
  });
1188
1195
  }
1189
1196
  resetInstance() {
@@ -1308,8 +1315,8 @@ var Se = class {
1308
1315
  waitForAllUploads() {
1309
1316
  return this.useWorker && this.port ? new Promise((e) => {
1310
1317
  this.allUploadsResolver = e, this.postToWorker({ type: "wait_for_all_uploads" }), setTimeout(() => {
1311
- this.allUploadsResolver &&= (console.warn("[ScribeSDK] waitForAllUploads timed out after 15s"), this.allUploadsResolver(), null);
1312
- }, 15e3);
1318
+ this.allUploadsResolver &&= (console.warn("[ScribeSDK] waitForAllUploads timed out after 30s"), this.allUploadsResolver(), null);
1319
+ }, 3e4);
1313
1320
  }) : Promise.all(this.pendingUploads).then(() => {});
1314
1321
  }
1315
1322
  updateAuthToken(e) {
@@ -1354,6 +1361,10 @@ var Se = class {
1354
1361
  switch (e.type) {
1355
1362
  case "chunk_encoded": {
1356
1363
  let t = this.findChunkIndex(e.fileName);
1364
+ if (t >= 0 && e.chunkData && e.chunkData.length > 0) {
1365
+ let n = new Blob(e.chunkData, { type: "audio/mp3" });
1366
+ this.fileManager.storeEncodedBlob(t, n);
1367
+ }
1357
1368
  this.callbackRegistry.dispatch("onAudioEvent", {
1358
1369
  type: d.CHUNK_READY,
1359
1370
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -1373,7 +1384,7 @@ var Se = class {
1373
1384
  case "upload_failed": {
1374
1385
  let t = this.findChunkIndex(e.fileName);
1375
1386
  if (t >= 0) {
1376
- let n = e.chunkData && e.chunkData.length > 0 ? new Blob(e.chunkData, { type: "audio/mp3" }) : new Blob();
1387
+ let n = e.chunkData && e.chunkData.length > 0 ? new Blob(e.chunkData, { type: "audio/mp3" }) : this.fileManager.getChunks()[t]?.fileBlob ?? new Blob();
1377
1388
  this.fileManager.markFailure(t, n, e.error);
1378
1389
  }
1379
1390
  this.callbackRegistry.dispatch("onUploadEvent", {
@@ -1986,25 +1997,34 @@ var Se = class {
1986
1997
  },
1987
1998
  httpStatus: void 0
1988
1999
  };
1989
- let { upload: e, storageProvider: t, failedChunks: n } = this.retryContext, r = n.length, i = [], a = 0;
1990
- this.config.debug && console.log(`[ScribeSDK] Retrying ${r} failed uploads`);
1991
- for (let o of n) try {
2000
+ let { storageProvider: e, failedChunks: t } = this.retryContext, n = t.length, r = [], i = 0, a = this.retryContext.upload;
2001
+ try {
2002
+ let e = this.activeSession?.session_id;
2003
+ if (e) {
2004
+ let t = await this.sessionManager.getSessionStatus(this.activeBaseUrl, e);
2005
+ t.data.upload_url && (a = t.data.upload_url, this.retryContext.upload = a);
2006
+ }
2007
+ } catch (e) {
2008
+ this.config.debug && console.log("[ScribeSDK] Failed to refresh upload_url, using existing:", e);
2009
+ }
2010
+ this.config.debug && console.log(`[ScribeSDK] Retrying ${n} failed uploads`);
2011
+ for (let o of t) try {
1992
2012
  await Y(this.transport, {
1993
2013
  fileName: o.fileName,
1994
2014
  blob: o.blob,
1995
- upload: e,
1996
- storageProvider: t,
2015
+ upload: a,
2016
+ storageProvider: e,
1997
2017
  maxRetries: 0
1998
- }), a++, this.callbackRegistry.dispatch("onUploadEvent", {
2018
+ }), i++, this.callbackRegistry.dispatch("onUploadEvent", {
1999
2019
  type: f.PROGRESS,
2000
2020
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2001
2021
  data: {
2002
- successCount: a,
2003
- totalCount: r
2022
+ successCount: i,
2023
+ totalCount: n
2004
2024
  }
2005
2025
  }), this.config.debug && console.log(`[ScribeSDK] Retry succeeded: ${o.fileName}`);
2006
2026
  } catch (e) {
2007
- i.push(o.fileName), this.callbackRegistry.dispatch("onUploadEvent", {
2027
+ r.push(o.fileName), this.callbackRegistry.dispatch("onUploadEvent", {
2008
2028
  type: f.FAILED,
2009
2029
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2010
2030
  data: {
@@ -2013,11 +2033,11 @@ var Se = class {
2013
2033
  }
2014
2034
  }), this.config.debug && console.log(`[ScribeSDK] Retry failed: ${o.fileName}`, e);
2015
2035
  }
2016
- return i.length === 0 ? this.retryContext = null : this.retryContext.failedChunks = n.filter((e) => i.includes(e.fileName)), this.config.debug && console.log(`[ScribeSDK] Retry complete: ${a}/${r} succeeded`), {
2036
+ return r.length === 0 ? this.retryContext = null : this.retryContext.failedChunks = t.filter((e) => r.includes(e.fileName)), this.config.debug && console.log(`[ScribeSDK] Retry complete: ${i}/${n} succeeded`), {
2017
2037
  data: {
2018
- retried: r,
2019
- succeeded: a,
2020
- stillFailed: i
2038
+ retried: n,
2039
+ succeeded: i,
2040
+ stillFailed: r
2021
2041
  },
2022
2042
  httpStatus: void 0
2023
2043
  };
@@ -2175,9 +2195,9 @@ var Se = class {
2175
2195
  };
2176
2196
  });
2177
2197
  }
2178
- async createSession(e) {
2179
- let t = this.getEffectiveBaseUrl();
2180
- return this.wrapResult(() => this.sessionManager.createSession(t, e));
2198
+ async createSession(e, t) {
2199
+ let n = this.getEffectiveBaseUrl();
2200
+ return this.wrapResult(() => this.sessionManager.createSession(n, e, t));
2181
2201
  }
2182
2202
  async endSession(e, t) {
2183
2203
  let n = this.getEffectiveBaseUrl();
@@ -2192,7 +2212,7 @@ var Se = class {
2192
2212
  }
2193
2213
  async getSessionStatus(e, t) {
2194
2214
  let n = this.getEffectiveBaseUrl();
2195
- return t?.poll ? this.wrapResult(() => this.sessionManager.pollForCompletion(n, e, t.poll, t.templateId)) : this.wrapResult(() => this.sessionManager.getSessionStatus(n, e, t?.templateId));
2215
+ return t?.poll ? this.wrapResult(() => this.sessionManager.pollForCompletion(n, e, t.poll, t.templateId, t.version)) : this.wrapResult(() => this.sessionManager.getSessionStatus(n, e, t?.templateId, t?.version));
2196
2216
  }
2197
2217
  getCurrentSession() {
2198
2218
  return this.recordingManager.getActiveSession() ?? this.sessionManager.getCurrentSession();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "med-scribe-alliance-ts-sdk",
3
- "version": "2.0.37",
3
+ "version": "2.0.39",
4
4
  "description": "TypeScript SDK for the MedScribe Alliance Protocol",
5
5
  "main": "dist/index.mjs",
6
6
  "module": "dist/index.mjs",