@medplum/react-hooks 5.1.39 → 5.1.40

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.
@@ -9,6 +9,8 @@ import type { Identifier } from '@medplum/fhirtypes';
9
9
  import type { JSX } from 'react';
10
10
  import type { Medication } from '@medplum/fhirtypes';
11
11
  import type { MedicationCartClearRequest } from '@medplum/core';
12
+ import type { MedicationCartContentsRequest } from '@medplum/core';
13
+ import type { MedicationCartContentsResponse } from '@medplum/core';
12
14
  import type { MedicationCartManageResponse } from '@medplum/core';
13
15
  import type { MedicationCartRemoveRequest } from '@medplum/core';
14
16
  import type { MedicationCheckoutRequest } from '@medplum/core';
@@ -340,8 +342,9 @@ export declare const useCachedBinaryUrl: (binaryUrl: string | undefined) => stri
340
342
  /**
341
343
  * Vendor-neutral hook for the full **medication cart** lifecycle: add a draft
342
344
  * line (`createResource`), check out a set of drafts into the vendor's batch
343
- * approval queue (`$checkout-medications`), and remove/clear cart lines
344
- * (`$remove-cart-medication` / `$clear-cart`).
345
+ * approval queue (`$checkout-medications`), remove/clear cart lines
346
+ * (`$remove-cart-medication` / `$clear-cart`), and read the vendor's own view of
347
+ * the cart (`$get-cart`).
345
348
  *
346
349
  * Cart checkout / remove / clear hit project-scoped **FHIR custom operations**
347
350
  * whose backing Bot is chosen at deploy time via an `OperationDefinition`
@@ -360,7 +363,7 @@ export declare const useCachedBinaryUrl: (binaryUrl: string | undefined) => stri
360
363
  * decoded by the matching `@medplum/core` helpers. Per-line outcomes arrive in
361
364
  * `response.items`.
362
365
  *
363
- * @returns Cart add / checkout / remove / clear callbacks plus `adding` state.
366
+ * @returns Cart add / checkout / remove / clear / read callbacks plus `adding` state.
364
367
  */
365
368
  export declare function useMedicationCart(): UseMedicationCartReturn;
366
369
 
@@ -382,6 +385,12 @@ export declare interface UseMedicationCartReturn {
382
385
  removeFromCart: (input: MedicationCartRemoveRequest) => Promise<MedicationCartManageResponse>;
383
386
  /** Remove every item from the patient's vendor cart. */
384
387
  clearCart: (input: MedicationCartClearRequest) => Promise<MedicationCartManageResponse>;
388
+ /**
389
+ * Read the patient's cart as the **vendor** holds it, reconciled against the
390
+ * local draft lines. Use this rather than counting drafts whenever the number
391
+ * is shown to a prescriber: drafts alone are a lower bound.
392
+ */
393
+ getCart: (input: MedicationCartContentsRequest) => Promise<MedicationCartContentsResponse>;
385
394
  }
386
395
 
387
396
  /**
@@ -9,6 +9,8 @@ import type { Identifier } from '@medplum/fhirtypes';
9
9
  import type { JSX } from 'react';
10
10
  import type { Medication } from '@medplum/fhirtypes';
11
11
  import type { MedicationCartClearRequest } from '@medplum/core';
12
+ import type { MedicationCartContentsRequest } from '@medplum/core';
13
+ import type { MedicationCartContentsResponse } from '@medplum/core';
12
14
  import type { MedicationCartManageResponse } from '@medplum/core';
13
15
  import type { MedicationCartRemoveRequest } from '@medplum/core';
14
16
  import type { MedicationCheckoutRequest } from '@medplum/core';
@@ -340,8 +342,9 @@ export declare const useCachedBinaryUrl: (binaryUrl: string | undefined) => stri
340
342
  /**
341
343
  * Vendor-neutral hook for the full **medication cart** lifecycle: add a draft
342
344
  * line (`createResource`), check out a set of drafts into the vendor's batch
343
- * approval queue (`$checkout-medications`), and remove/clear cart lines
344
- * (`$remove-cart-medication` / `$clear-cart`).
345
+ * approval queue (`$checkout-medications`), remove/clear cart lines
346
+ * (`$remove-cart-medication` / `$clear-cart`), and read the vendor's own view of
347
+ * the cart (`$get-cart`).
345
348
  *
346
349
  * Cart checkout / remove / clear hit project-scoped **FHIR custom operations**
347
350
  * whose backing Bot is chosen at deploy time via an `OperationDefinition`
@@ -360,7 +363,7 @@ export declare const useCachedBinaryUrl: (binaryUrl: string | undefined) => stri
360
363
  * decoded by the matching `@medplum/core` helpers. Per-line outcomes arrive in
361
364
  * `response.items`.
362
365
  *
363
- * @returns Cart add / checkout / remove / clear callbacks plus `adding` state.
366
+ * @returns Cart add / checkout / remove / clear / read callbacks plus `adding` state.
364
367
  */
365
368
  export declare function useMedicationCart(): UseMedicationCartReturn;
366
369
 
@@ -382,6 +385,12 @@ export declare interface UseMedicationCartReturn {
382
385
  removeFromCart: (input: MedicationCartRemoveRequest) => Promise<MedicationCartManageResponse>;
383
386
  /** Remove every item from the patient's vendor cart. */
384
387
  clearCart: (input: MedicationCartClearRequest) => Promise<MedicationCartManageResponse>;
388
+ /**
389
+ * Read the patient's cart as the **vendor** holds it, reconciled against the
390
+ * local draft lines. Use this rather than counting drafts whenever the number
391
+ * is shown to a prescriber: drafts alone are a lower bound.
392
+ */
393
+ getCart: (input: MedicationCartContentsRequest) => Promise<MedicationCartContentsResponse>;
385
394
  }
386
395
 
387
396
  /**
@@ -1,6 +1,6 @@
1
- import{useEffect as dn,useMemo as ln,useState as pn}from"react";import{createContext as un,useContext as cn}from"react";var Y=un(void 0);function Z(){return cn(Y)}function v(){return Z().medplum}function pr(){return Z().navigate}function xe(){return Z().profile}import{jsx as mn}from"react/jsx-runtime";var be=["change","storageInitialized","storageInitFailed","profileRefreshing","profileRefreshed"];function hr(e){let t=e.medplum,n=e.navigate??fn,[r,o]=pn({profile:t.getProfile(),loading:t.isLoading()});dn(()=>{function s(){o(a=>({...a,profile:t.getProfile(),loading:t.isLoading()}))}for(let a of be)t.addEventListener(a,s);return()=>{for(let a of be)t.removeEventListener(a,s)}},[t]);let i=ln(()=>({...r,medplum:t,navigate:n}),[r,t,n]);return mn(Y.Provider,{value:i,children:e.children})}function fn(e){window.location.assign(e)}import{useMemo as Rn}from"react";var Ee=new Map,Sr=e=>Rn(()=>{if(!e)return;let t=e.split("?")[0];if(!t)return e;let n;try{n=new URLSearchParams(new URL(e).search)}catch{return e}if(!n.has("Key-Pair-Id")||!n.has("Signature"))return e;let r=n.get("Expires");if(!r||r.length>13)return e;let o=Ee.get(t);if(o){let s=new URLSearchParams(new URL(o).search).get("Expires");if(s&&Number.parseInt(s,10)*1e3-5e3>Date.now())return o}return Ee.set(t,e),e},[e]);import{INVALID_MEDICATION_CART_RESPONSE as ve,INVALID_MEDICATION_CHECKOUT_RESPONSE as hn,isResource as ee,medicationCartClearRequestToParameters as yn,medicationCartRemoveRequestToParameters as gn,medicationCheckoutRequestToParameters as In,parametersToMedicationCartManageResponse as Te,parametersToMedicationCheckoutResponse as Sn}from"@medplum/core";import{useCallback as j,useRef as xn,useState as bn}from"react";var En="Cannot checkout while a medication is still being added to the cart";function Tr(){let e=v(),[t,n]=bn(!1),r=xn(0),o=j(async u=>{r.current+=1,n(!0);try{return await e.createResource(u)}finally{r.current-=1,r.current<=0&&(r.current=0,n(!1))}},[e]),i=j(async u=>{if(r.current>0)throw new Error(En);let p=e.fhirUrl("MedicationRequest","$checkout-medications"),f=In(u),T=await e.post(p,f);if(!ee(T,"Parameters"))throw new Error(hn);return Sn(T)},[e]),s=j(async u=>{let p=e.fhirUrl("MedicationRequest","$remove-cart-medication"),f=await e.post(p,gn(u));if(!ee(f,"Parameters"))throw new Error(ve);return Te(f)},[e]),a=j(async u=>{let p=e.fhirUrl("MedicationRequest","$clear-cart"),f=await e.post(p,yn(u));if(!ee(f,"Parameters"))throw new Error(ve);return Te(f)},[e]);return{addToCart:o,adding:t,checkout:i,removeFromCart:s,clearCart:a}}import{resolveId as Cn}from"@medplum/core";import{useEffect as Mn,useState as Qn}from"react";import{useCallback as vn,useInsertionEffect as Tn,useRef as Pn}from"react";function A(e){let t=Pn(e);return Tn(()=>{t.current=e},[e]),vn((...n)=>t.current?.(...n),[])}function kr(e,t,n){let r=v(),{patientId:o,organization:i}=n,s=Cn(i),[a,u]=Qn(void 0),p=A(n.onPatientSyncSuccess),f=A(n.onIframeSuccess),T=A(n.onError);return Mn(()=>{let y=!1;return(async()=>{try{if(o){if(await r.executeBot(e,{patientId:o,organizationId:s}),y)return;p()}let R=await r.executeBot(t,{patientId:o,organizationId:s});if(y)return;R.url&&(u(R.url),f(R.url))}catch(R){y||T(R)}})().catch(()=>{}),()=>{y=!0}},[r,e,t,o,s,p,f,T]),a}import{INVALID_MEDICATION_ORDER_RESPONSE as On,INVALID_MEDICATION_SEARCH_RESPONSE as wn,isResource as ne,medicationOrderRequestToParameters as An,medicationSearchParamsToParameters as kn,parametersToMedicationOrderResponse as _n}from"@medplum/core";import{useCallback as Pe}from"react";function Lr(){let e=v(),t=Pe(async r=>{let o=e.fhirUrl("Medication","$drug-search"),i=kn(r),s=await e.post(o,i);if(!ne(s,"Bundle"))throw new Error(wn);return(s.entry??[]).map(a=>a.resource).filter(a=>ne(a,"Medication"))},[e]),n=Pe(async r=>{let o=e.fhirUrl("MedicationRequest","$order-medication"),i=An(r),s=await e.post(o,i);if(!ne(s,"Parameters"))throw new Error(On);return _n(s)},[e]);return{searchMedications:t,orderMedication:n}}import{INVALID_MEDICATION_ORDER_SET_RESPONSE as qn,isResource as Un,medicationOrderSetRequestToParameters as Nn,parametersToMedicationOrderSetResponse as Ln}from"@medplum/core";import{useCallback as Ce,useEffect as Wn,useRef as Me,useState as te}from"react";function zr(e){let t=v(),{patientId:n,planDefinitionId:r,vendorOrderSetId:o,appId:i,organization:s}=e,[a,u]=te(void 0),[p,f]=te(!1),[T,y]=te(void 0),b=Me({patientId:n,planDefinitionId:r,vendorOrderSetId:o,appId:i,organization:s});b.current={patientId:n,planDefinitionId:r,vendorOrderSetId:o,appId:i,organization:s};let R=()=>{let g=b.current;if(!g.patientId)return;let l=!!g.planDefinitionId,I=g.vendorOrderSetId!==void 0&&g.vendorOrderSetId!==null&&g.vendorOrderSetId!=="";return!l&&!I?void 0:{patientId:g.patientId,planDefinitionId:l?g.planDefinitionId:void 0,vendorOrderSetId:I?g.vendorOrderSetId:void 0,appId:g.appId,organization:g.organization}},d=Ce(async g=>{let l=t.fhirUrl("PlanDefinition","$order-set-url"),I=Nn(g),m=await t.post(l,I);if(!Un(m,"Parameters"))throw new Error(qn);return Ln(m).launchUrl},[t]),c=Me(0),E=Ce(async()=>{let g=R();if(!g)return;c.current+=1;let l=c.current;f(!0),y(void 0);try{let I=await d(g);return c.current!==l?void 0:(u(I),I)}catch(I){c.current===l&&(y(I),u(void 0));return}finally{c.current===l&&f(!1)}},[d]);return Wn(()=>{let g=!1,l=R();if(!l){c.current+=1,u(void 0),f(!1),y(void 0);return}c.current+=1;let I=c.current;return f(!0),y(void 0),d(l).then(m=>{g||c.current!==I||u(m)}).catch(m=>{g||c.current!==I||(y(m),u(void 0))}).finally(()=>{!g&&c.current===I&&f(!1)}),()=>{g=!0}},[d,n,r,o,i,s]),{url:a,loading:p,error:T,refresh:E}}import{useCallback as Fn,useEffect as Vn,useState as zn}from"react";import{deepEquals as Qe}from"@medplum/core";import{useCallback as V,useEffect as re,useRef as J,useState as Oe}from"react";var Dn=3e3;function we(e,t,n){let r=v(),o=r.getProject(),a=xe()&&o?.features?.includes("websocket-subscriptions")?e:void 0,[u,p]=Oe(),[f,T]=Oe(n?.subscriptionProps),y=J(!1),b=J(void 0),R=J(void 0),d=J(void 0);re(()=>{Qe(n?.subscriptionProps,f)||T(n?.subscriptionProps)},[f,n]),re(()=>{b.current&&(clearTimeout(b.current),b.current=void 0);let M=!1;return(R.current!==a||!Qe(d.current,f))&&(M=!0),M&&R.current&&r.unsubscribeFromCriteria(R.current,d.current),R.current=a,d.current=f,M&&a?p(r.subscribeToCriteria(a,f)):a||p(void 0),()=>{b.current=setTimeout(()=>{a&&r.unsubscribeFromCriteria(a,f)},Dn)}},[r,a,f]);let c=A(t),E=A(n?.onWebSocketOpen),g=A(n?.onWebSocketClose),l=A(n?.onSubscriptionConnect),I=A(n?.onSubscriptionDisconnect),m=A(n?.onError),S=V(M=>c(M.payload),[c]),h=V(M=>E(),[E]),C=V(M=>g(),[g]),Q=V(M=>l(M.payload.subscriptionId),[l]),k=V(M=>I(M.payload.subscriptionId),[I]),P=V(M=>m(M.payload),[m]);re(()=>u?(y.current||(u.addEventListener("message",S),u.addEventListener("open",h),u.addEventListener("close",C),u.addEventListener("connect",Q),u.addEventListener("disconnect",k),u.addEventListener("error",P),y.current=!0),()=>{y.current=!1,u.removeEventListener("message",S),u.removeEventListener("open",h),u.removeEventListener("close",C),u.removeEventListener("connect",Q),u.removeEventListener("disconnect",k),u.removeEventListener("error",P)}):()=>{},[u,S,h,C,Q,k,P])}function Zr(e){let t=v(),{resourceType:n,countCriteria:r,subscriptionCriteria:o}=e,[i,s]=zn(0),a=Fn(u=>{t.search(n,r,{cache:u}).then(p=>s(p.total)).catch(console.error)},[t,n,r]);return Vn(()=>{a("default")},[a]),we(o,()=>{a("reload")}),i}import{resolveId as Kn}from"@medplum/core";import{useEffect as $n,useMemo as Ae,useState as oe}from"react";function ke(e){let t=e.patientParam??"subject",n=e.query,r="";if(n!=null)if(typeof n=="string")r=n;else if(n instanceof URLSearchParams){let o=Array.from(n.entries()).sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));r=JSON.stringify(o)}else if(Array.isArray(n)){let o=[...n].sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));r=JSON.stringify(o)}else{let o=Object.entries(n).filter(([,i])=>i!==void 0).sort(([i],[s])=>i.localeCompare(s));r=JSON.stringify(o)}return`${e.resourceType}:${t}:${r}`}function Bn(e){return e.map(t=>{let n=t.searches?t.searches.map(ke).join(","):"";return`${t.key}:[${n}]`}).join("|")}function oo(e,t){let n=v(),[r,o]=oe([]),[i,s]=oe(!0),[a,u]=oe(),p=Bn(t),f=Ae(()=>t,[p]),T=Ae(()=>Kn(e),[e]);return $n(()=>{if(!T)return;let y=!1,b=`Patient/${T}`,R={_count:100,_sort:"-_lastUpdated"},d=[],c=new Map,E=[];for(let l of f){let I=[];if(l.searches)for(let m of l.searches){let S=ke(m),h=c.get(S);h===void 0&&(h=d.length,c.set(S,h),d.push(m)),I.push({searchIdx:h,resultKey:m.key})}E.push(I)}if(d.length===0){o(f.map(()=>({}))),s(!1);return}let g=d.map(l=>{let I=l.patientParam??"subject",m={[I]:b};if(l.query){if(typeof l.query=="string")return n.searchResources(l.resourceType,`${I}=${b}&${l.query}&_count=100&_sort=-_lastUpdated`);if(l.query instanceof URLSearchParams)l.query.forEach((S,h)=>{m[h]=S});else if(Array.isArray(l.query))for(let[S,h]of l.query)m[S]=h;else for(let[S,h]of Object.entries(l.query))h!==void 0&&(m[S]=h)}return n.searchResources(l.resourceType,{...R,...m})});return s(!0),u(void 0),Promise.allSettled(g).then(l=>{if(y)return;let I=E.map(S=>{let h={};for(let{searchIdx:C,resultKey:Q}of S){let k=l[C];h[Q]=k.status==="fulfilled"?k.value:[]}return h});o(I),s(!1);let m=l.filter(S=>S.status==="rejected");if(m.length>0){console.error("Some patient summary searches failed:",m.map(h=>h.reason));let S=m[0].reason;u(S instanceof Error?S:new Error(String(S)))}}).catch(l=>{y||(u(l instanceof Error?l:new Error(String(l))),s(!1))}),()=>{y=!0}},[n,T,f]),{sectionData:r,loading:i,error:a}}import{isAddPharmacyResponse as jn,isOrganizationArray as Jn,resolveId as _e}from"@medplum/core";import{useCallback as qe}from"react";function co(e,t){let n=v(),r=qe(async i=>{let{organization:s,...a}=i,u=_e(s),p=await n.executeBot(e,u?{...a,organizationId:u}:a);if(!Jn(p))throw new Error("Invalid response from pharmacy search");return p},[n,e]),o=qe(async i=>{let s=await n.executeBot(t,{patientId:i.patientId,pharmacy:i.pharmacy,setAsPrimary:i.setAsPrimary,organizationId:_e(i.organization)});if(!jn(s))throw new Error("Invalid response from add pharmacy bot");return s},[n,t]);return{searchPharmacies:r,addToFavorites:o}}import{useEffect as Gn,useRef as Hn}from"react";function fo(e){let t=Hn(void 0);return Gn(()=>{t.current=e}),t.current}import{getExtension as Pt}from"@medplum/core";import{useReducer as Ct,useRef as Mt}from"react";import{deepEquals as Xn,isReference as Ne,isResource as Yn,normalizeOperationOutcome as Zn}from"@medplum/core";import{useCallback as et,useEffect as nt,useState as tt}from"react";function ie(e,t){let n=v(),[r,o]=tt(()=>Ue(n,e)),i=et(s=>{Xn(s,r)||o(s)},[r]);return nt(()=>{let s=!0,a=Ue(n,e);return!a&&Ne(e)?n.readReference(e).then(u=>{s&&i(u)}).catch(u=>{s&&(i(void 0),t&&t(Zn(u)))}):i(a),(()=>s=!1)},[n,e,i,t]),r}function Ue(e,t){if(t){if(Yn(t))return t;if(Ne(t))return e.getCachedReference(t)}}import{EMPTY as ue,HTTP_HL7_ORG as U,PropertyType as _,append as Le,capitalize as We,deepClone as rt,deepEquals as De,evalFhirPathTyped as ce,getExtension as D,getReferenceString as ot,getTypedPropertyValueWithoutSchema as G,normalizeErrorString as it,splitN as st,toJsBoolean as at,toTypedValue as Fe,typedValueToString as ut}from"@medplum/core";var O={group:"group",display:"display",question:"question",boolean:"boolean",decimal:"decimal",integer:"integer",date:"date",dateTime:"dateTime",time:"time",string:"string",text:"text",url:"url",choice:"choice",openChoice:"open-choice",attachment:"attachment",reference:"reference",quantity:"quantity"},Ve=`${U}/fhir/StructureDefinition/questionnaire-itemControl`,ct=`${U}/fhir/StructureDefinition/questionnaire-referenceFilter`,se=`${U}/fhir/StructureDefinition/questionnaire-referenceResource`,dt=`${U}/fhir/StructureDefinition/questionnaire-validationError`,lt=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression`,pt=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression`,So=`${U}/fhir/StructureDefinition/questionnaire-signatureRequired`,H=`${U}/fhir/StructureDefinition/questionnaireresponse-signature`,ft=`${U}/fhir/StructureDefinition/questionnaire-hidden`,mt=`${U}/fhir/StructureDefinition/questionnaire-optionExclusive`;function xo(e){return e.type==="choice"||e.type==="open-choice"}function de(e,t){return{...t,item:ze(e.item,t.item,t)}}function ze(e,t,n){if(!t)return t;let r=[];for(let o of t){let i=e?.find(s=>s.linkId===o.linkId);i&&!Rt(i,n)||(i?.item&&o.item?r.push({...o,item:ze(i.item,o.item,n)}):r.push(o))}return r}function Rt(e,t){if(D(e,ft)?.valueBoolean===!0)return!1;let r=ht(e,t);return r!==void 0?r:yt(e,t)}function ht(e,t){let n=D(e,lt);if(t&&n){let r=n.valueExpression?.expression;if(r){let o=Fe(t),i=ce(r,[o],{"%resource":o});return at(i)}}}function yt(e,t){if(!e.enableWhen)return!0;let n=e.enableBehavior??"any";for(let r of e.enableWhen){let o=$e(t?.item,r.question);if(r.operator==="exists"&&!r.answerBoolean&&!o?.length){if(n==="any")return!0;continue}let{anyMatch:i,allMatch:s}=Et(r,o,n);if(n==="any"&&i)return!0;if(n==="all"&&!s)return!1}return n!=="any"}function le(e,t,n=t.item){for(let r of e){let o=n?.find(i=>i.linkId===r.linkId);o&&(gt(t,r,o),r.item&&o.item&&le(r.item,t,o.item))}}function gt(e,t,n){try{let r=xt(t,e);if(!r)return;let o=St(t,r);if(!o)return;n.answer=[o]}catch(r){n.extension=[{url:dt,valueString:`Expression evaluation failed: ${it(r)}`}]}}var It={[O.boolean]:[_.boolean],[O.date]:[_.date],[O.dateTime]:[_.dateTime],[O.time]:[_.time],[O.url]:[_.string,_.uri,_.url],[O.attachment]:[_.Attachment],[O.reference]:[_.Reference],[O.quantity]:[_.Quantity],[O.decimal]:[_.decimal,_.integer],[O.integer]:[_.decimal,_.integer]};function St(e,t){if(!e.type)return;if(e.type===O.choice||e.type===O.openChoice)return{[`value${We(t.type)}`]:t.value};if(e.type===O.string||e.type===O.text)return typeof t.value=="string"?{valueString:t.value}:void 0;if(It[e.type]?.includes(t.type))return{[`value${We(e.type)}`]:t.value}}function xt(e,t){if(!t)return;let n=D(e,pt);if(n){let r=n.valueExpression?.expression;if(r){let o=Fe(t),i=ce(r,[o],{"%resource":o});return i.length!==0?i[0]:void 0}}}function bo(e,t,n){let r=[];for(let o of e){let i=n.answerOption?.find(s=>ut(ae(s))===o);if(i){let s=ae(i);s&&r.push({[t]:s.value})}}return r}function Ke(e,t,n){let r=[];for(let a of e.answerOption??ue)if(D(a,mt)?.valueBoolean===!0){let u=ae(a);u?.value!==void 0&&r.push(u)}if(r.length===0)return n;let o=a=>{let u=Je(a);return!!u&&r.some(p=>De(p,u))},i=n.filter(a=>!t?.some(u=>De(u,a))),s=i.find(o);return s?[s]:i.some(a=>!o(a))?n.filter(a=>!o(a)):n}function $e(e,t){for(let n of e??ue){if(n.linkId===t)return n.answer;if(n.item){let r=$e(n.item,t);if(r)return r}}}function bt(e,t,n){if(n==="exists")return!!e===t.value;if(e){let r=n==="="||n==="!="?n?.replace("=","~"):n,[{value:o}]=ce(`%actualAnswer ${r} %expectedAnswer`,[e],{"%actualAnswer":e,"%expectedAnswer":t});return o}else return!1}function Et(e,t,n){let r=t||[],o=Tt(e),i=!1,s=!0;for(let a of r){let u=Je(a),{operator:p}=e;if(bt(u,o,p)?i=!0:s=!1,n==="any"&&i)break}return{anyMatch:i,allMatch:s}}function Eo(e){let t=D(e,se);if(t){if(t.valueCode!==void 0)return[t.valueCode];if(t.valueCodeableConcept)return t.valueCodeableConcept?.coding?.map(n=>n.code)}}function vo(e,t){let n=rt(e),r=D(n,se);return!t||t.length===0?(r&&(n.extension=n.extension?.filter(o=>o!==r)),n):(r||(n.extension??=[],r={url:se},n.extension.push(r)),t.length===1?(r.valueCode=t[0],delete r.valueCodeableConcept):(r.valueCodeableConcept={coding:t.map(o=>({code:o}))},delete r.valueCode),n)}function To(e,t,n){let r=D(e,ct);if(!r?.valueString)return;let o=r.valueString;t?.reference&&(o=o.replaceAll("$subj",t.reference)),n?.reference&&(o=o.replaceAll("$encounter",n.reference));let i={},s=o.split("&");for(let a of s){let[u,p]=st(a,"=",2);i[u]=p}return i}function pe(e,t){return{resourceType:"QuestionnaireResponse",questionnaire:e.url??ot(e),item:fe(e.item,t?.item),status:"in-progress"}}function fe(e,t){let n;for(let r of e??ue){if(r.type===O.display)continue;let o=t?.filter(i=>i.linkId===r.linkId);if(o?.length)for(let i of o)i.id=i.id??Be(),i.text=i.text??r.text,i.item=fe(r.item,i.item),i.answer=je(r,i),n=Le(n,i);else n=Le(n,me(r))}return n}function me(e){return{id:Be(),linkId:e.linkId,text:e.text,item:fe(e.item,void 0),answer:je(e)}}var vt=1;function Be(){return"id-"+vt++}function je(e,t){if(!(e.type===O.display||e.type===O.group)){if(t?.answer&&t.answer.length>0)return t.answer;if(e.initial&&e.initial.length>0)return e.initial.map(n=>({...n}));if(e.answerOption)return e.answerOption.filter(n=>n.initialSelected).map(n=>({...n,initialSelected:void 0}))}}function Po(e){return G({type:"QuestionnaireItemInitial",value:e},"value")}function ae(e){return G({type:"QuestionnaireItemAnswerOption",value:e},"value")}function Tt(e){return G({type:"QuestionnaireItemEnableWhen",value:e},"answer")}function Je(e){return G({type:"QuestionnaireResponseItemAnswer",value:e},"value")}function Ao(e){let t=ie(e.questionnaire),n=ie(e.defaultValue),[,r]=Ct(R=>R+1,0),o=Mt({activePage:0});if(!o.current.questionnaire&&t&&(o.current.questionnaire=t,o.current.pages=e.disablePagination?void 0:Qt(t)),t&&e.defaultValue&&n&&!o.current.questionnaireResponse&&(o.current.questionnaireResponse=pe(t,n),b()),t&&!e.defaultValue&&!o.current.questionnaireResponse&&(o.current.questionnaireResponse=pe(t),b()),!o.current.questionnaire||!o.current.questionnaireResponse)return{loading:!0};function i(R,d){let c=o.current.questionnaireResponse;for(let E of R)c=c?.item?.find(g=>E.id?g.id===E.id:g.linkId===E.linkId);return d&&(c=c?.item?.find(E=>E.linkId===d.linkId)),c}function s(){o.current.activePage=(o.current.activePage??0)+1,r()}function a(){o.current.activePage=(o.current.activePage??0)-1,r()}function u(R,d){let c=i(R);c&&(c.item??=[],c.item.push(me(d)),b())}function p(R,d){let c=i(R,d);c&&(c.answer??=[],c.answer.push({}),b())}function f(R,d,c){let E=i(R,d);E&&(E.answer=Ke(d,E.answer,c),b())}function T(R){let d=o.current.questionnaireResponse;d&&(R?(d.extension=d.extension??[],d.extension=d.extension.filter(c=>c.url!==H),d.extension.push({url:H,valueSignature:R})):d.extension=d.extension?.filter(c=>c.url!==H),b())}function y(){let R=o.current.questionnaire;if(R?.item){let d=o.current.questionnaireResponse;le(R.item,d)}}function b(){let R=o.current.questionnaireResponse,d=o.current.questionnaire;!R||!d||(y(),r(),e.onChange?.(de(d,R)))}return{loading:!1,pagination:!!o.current.pages,questionnaire:o.current.questionnaire,questionnaireResponse:de(o.current.questionnaire,o.current.questionnaireResponse),subject:e.subject,encounter:e.encounter,activePage:o.current.activePage,pages:o.current.pages,items:Ot(o.current.questionnaire,o.current.pages,o.current.activePage),responseItems:wt(o.current.questionnaireResponse,o.current.pages,o.current.activePage),onNextPage:s,onPrevPage:a,onAddGroup:u,onAddAnswer:p,onChangeAnswer:f,onChangeSignature:T}}function Qt(e){if(!(!e?.item||Pt(e?.item?.[0],Ve)?.valueCodeableConcept?.coding?.[0]?.code!=="page"))return e.item.map((n,r)=>({linkId:n.linkId,title:n.text??`Page ${r+1}`,group:n}))}function Ot(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}function wt(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}import{deepEquals as At,formatSearchQuery as kt}from"@medplum/core";import{useCallback as _t,useEffect as Re,useRef as he,useState as K}from"react";async function qt(e,t){let n=await t.search(e.resourceType,kt({...e,total:e.total??"accurate"}),{cache:"no-cache"});return{items:n.entry?.map(o=>o.resource).filter(o=>o!==void 0)??[],total:n.total}}function No(e){let{search:t,selectedId:n,loadItems:r,reloadKey:o}=e,i=v(),[s,a]=K(t),[u,p]=K([]),[f,T]=K(),[y,b]=K(!0),[R,d]=K(),c=he(e),E=he(0),g=he(0),l=s.resourceType,I=n!==void 0&&R?.id===n?R.value:void 0;At(t,s)||(a(t),b(!0));let m=_t(async()=>{let S=++E.current;try{let h=r?await r(s,i):await qt(s,i);if(S!==E.current)return;p(h.items),T(h.total),c.current.onLoad?.(h.items,h.total)}catch(h){S===E.current&&(c.current.onError??console.error)(h)}finally{S===E.current&&b(!1)}},[s,r,i]);return Re(()=>{c.current=e}),Re(()=>{m().catch(console.error)},[m,o]),Re(()=>{let S=++g.current;if(!n)return;let h=async()=>{let Q=c.current.resolveSelected;if(Q)return Q(n,u,i);let k=u.find(P=>P.id===n);return k!==void 0?k:await i.readResource(l,n)};(async()=>{try{let Q=await h();S===g.current&&d({id:n,value:Q})}catch(Q){S===g.current&&(d({id:n,value:void 0}),(c.current.onError??console.error)(Q))}})().catch(console.error)},[n,u,i,l]),{items:u,total:f,loading:y,selected:I,search:s,refresh:m}}import{useEffect as Ut}from"react";function Vo(e,t){let n=v(),r=A(t),o=Array.isArray(e)?e.join(","):e;Ut(()=>{let i=new Set(o.split(",")),s=a=>{i.has(a.payload.resourceType)&&r(a.payload)};return n.addEventListener("resourceModified",s),()=>n.removeEventListener("resourceModified",s)},[n,o,r])}import{allOk as Wt,normalizeOperationOutcome as Dt}from"@medplum/core";import{useEffect as Ft,useMemo as Vt,useState as ge}from"react";import{useCallback as Nt,useEffect as Ge,useRef as ye,useState as Lt}from"react";function He(e,t,n={leading:!1}){let[r,o]=Lt(e),i=ye(!1),s=ye(void 0),a=ye(!1),u=Nt(()=>window.clearTimeout(s.current),[]);return Ge(()=>{i.current&&(!a.current&&n.leading?(a.current=!0,o(e),s.current=setTimeout(()=>{a.current=!1},t)):(u(),s.current=setTimeout(()=>{a.current=!1,o(e)},t)))},[e,n.leading,t,u]),Ge(()=>(i.current=!0,u),[u]),[r,u]}var zt=250;function Ho(e,t,n){return Ie("search",e,t,n)}function Xo(e,t,n){return Ie("searchOne",e,t,n)}function Yo(e,t,n){return Ie("searchResources",e,t,n)}function Ie(e,t,n,r){let o=v(),[i,s]=ge(!1),[a,u]=ge(),[p,f]=ge(),T=o.fhirSearchUrl(t,n).toString(),y=Vt(()=>({resourceType:t,query:n}),[T]),b=r?.enabled??!0,R=r?.debounceMs??zt,[d]=He(y,R,{leading:!0});return Ft(()=>{if(!b)return()=>{};s(!0);let c=!0;return o[e](d.resourceType,d.query).then(E=>{c&&(s(!1),u(E),f(Wt))}).catch(E=>{c&&(s(!1),u(void 0),f(Dt(E)))}),()=>{c=!1}},[o,e,d,b]),[a,i,p]}import{OperationOutcomeError as Kt,isResource as $t,parametersToOrderSetSyncResponse as Bt,resolveId as jt}from"@medplum/core";import{useCallback as Jt}from"react";function ri(){let e=v();return Jt(async(t,n)=>{try{let r=await e.post(e.fhirUrl("PlanDefinition","$sync-orderset"),{planDefinitionId:t,organizationId:jt(n)});return $t(r,"Parameters")?Bt(r):void 0}catch(r){if(r instanceof Kt&&r.outcome.issue?.some(o=>o.code==="not-found"))return;throw r}},[e])}import{getReferenceString as Gt}from"@medplum/core";import{useCallback as Ht,useEffect as Xe,useRef as Xt,useState as z}from"react";function ui({query:e,threadId:t}){let n=v(),[r,o]=z(!0),[i,s]=z(e),[a,u]=z([]),[p,f]=z(void 0),[T,y]=z(null),[b,R]=z(void 0),d=Xt(0);e!==i&&(s(e),o(!0));let c=Ht(async()=>{let l=++d.current;try{let I=new URLSearchParams(i);I.append("identifier:not","http://medplum.com/ai-message|"),I.append("part-of:missing","true"),I.append("_has:Communication:part-of:_id:not","null");let m=await n.search("Communication",I.toString(),{cache:"no-cache"});if(l!==d.current)return;let S=m.entry?.map(P=>P.resource).filter(P=>P!==void 0)||[];if(m.total!==void 0&&R(m.total),S.length===0){u([]);return}let C=`
1
+ import{useEffect as dn,useMemo as ln,useState as pn}from"react";import{createContext as un,useContext as cn}from"react";var Z=un(void 0);function ee(){return cn(Z)}function C(){return ee().medplum}function Rr(){return ee().navigate}function xe(){return ee().profile}import{jsx as mn}from"react/jsx-runtime";var be=["change","storageInitialized","storageInitFailed","profileRefreshing","profileRefreshed"];function Ir(e){let t=e.medplum,n=e.navigate??fn,[r,o]=pn({profile:t.getProfile(),loading:t.isLoading()});dn(()=>{function s(){o(a=>({...a,profile:t.getProfile(),loading:t.isLoading()}))}for(let a of be)t.addEventListener(a,s);return()=>{for(let a of be)t.removeEventListener(a,s)}},[t]);let i=ln(()=>({...r,medplum:t,navigate:n}),[r,t,n]);return mn(Z.Provider,{value:i,children:e.children})}function fn(e){window.location.assign(e)}import{useMemo as Rn}from"react";var Ee=new Map,Er=e=>Rn(()=>{if(!e)return;let t=e.split("?")[0];if(!t)return e;let n;try{n=new URLSearchParams(new URL(e).search)}catch{return e}if(!n.has("Key-Pair-Id")||!n.has("Signature"))return e;let r=n.get("Expires");if(!r||r.length>13)return e;let o=Ee.get(t);if(o){let s=new URLSearchParams(new URL(o).search).get("Expires");if(s&&Number.parseInt(s,10)*1e3-5e3>Date.now())return o}return Ee.set(t,e),e},[e]);import{INVALID_MEDICATION_CART_CONTENTS_RESPONSE as hn,INVALID_MEDICATION_CART_RESPONSE as Ce,INVALID_MEDICATION_CHECKOUT_RESPONSE as yn,isResource as J,medicationCartClearRequestToParameters as gn,medicationCartContentsRequestToParameters as In,medicationCartRemoveRequestToParameters as Sn,medicationCheckoutRequestToParameters as xn,parametersToMedicationCartContentsResponse as bn,parametersToMedicationCartManageResponse as ve,parametersToMedicationCheckoutResponse as En}from"@medplum/core";import{useCallback as $,useRef as Cn,useState as vn}from"react";var Tn="Cannot checkout while a medication is still being added to the cart";function Mr(){let e=C(),[t,n]=vn(!1),r=Cn(0),o=$(async l=>{r.current+=1,n(!0);try{return await e.createResource(l)}finally{r.current-=1,r.current<=0&&(r.current=0,n(!1))}},[e]),i=$(async l=>{if(r.current>0)throw new Error(Tn);let f=e.fhirUrl("MedicationRequest","$checkout-medications"),v=xn(l),h=await e.post(f,v);if(!J(h,"Parameters"))throw new Error(yn);return En(h)},[e]),s=$(async l=>{let f=e.fhirUrl("MedicationRequest","$remove-cart-medication"),v=await e.post(f,Sn(l));if(!J(v,"Parameters"))throw new Error(Ce);return ve(v)},[e]),a=$(async l=>{let f=e.fhirUrl("MedicationRequest","$clear-cart"),v=await e.post(f,gn(l));if(!J(v,"Parameters"))throw new Error(Ce);return ve(v)},[e]),u=$(async l=>{let f=e.fhirUrl("MedicationRequest","$get-cart"),v=await e.post(f,In(l));if(!J(v,"Parameters"))throw new Error(hn);return bn(v)},[e]);return{addToCart:o,adding:t,checkout:i,removeFromCart:s,clearCart:a,getCart:u}}import{resolveId as On}from"@medplum/core";import{useEffect as wn,useState as An}from"react";import{useCallback as Pn,useInsertionEffect as Mn,useRef as Qn}from"react";function A(e){let t=Qn(e);return Mn(()=>{t.current=e},[e]),Pn((...n)=>t.current?.(...n),[])}function Ur(e,t,n){let r=C(),{patientId:o,organization:i}=n,s=On(i),[a,u]=An(void 0),l=A(n.onPatientSyncSuccess),f=A(n.onIframeSuccess),v=A(n.onError);return wn(()=>{let h=!1;return(async()=>{try{if(o){if(await r.executeBot(e,{patientId:o,organizationId:s}),h)return;l()}let R=await r.executeBot(t,{patientId:o,organizationId:s});if(h)return;R.url&&(u(R.url),f(R.url))}catch(R){h||v(R)}})().catch(()=>{}),()=>{h=!0}},[r,e,t,o,s,l,f,v]),a}import{INVALID_MEDICATION_ORDER_RESPONSE as _n,INVALID_MEDICATION_SEARCH_RESPONSE as kn,isResource as ne,medicationOrderRequestToParameters as qn,medicationSearchParamsToParameters as Un,parametersToMedicationOrderResponse as Nn}from"@medplum/core";import{useCallback as Te}from"react";function Fr(){let e=C(),t=Te(async r=>{let o=e.fhirUrl("Medication","$drug-search"),i=Un(r),s=await e.post(o,i);if(!ne(s,"Bundle"))throw new Error(kn);return(s.entry??[]).map(a=>a.resource).filter(a=>ne(a,"Medication"))},[e]),n=Te(async r=>{let o=e.fhirUrl("MedicationRequest","$order-medication"),i=qn(r),s=await e.post(o,i);if(!ne(s,"Parameters"))throw new Error(_n);return Nn(s)},[e]);return{searchMedications:t,orderMedication:n}}import{INVALID_MEDICATION_ORDER_SET_RESPONSE as Ln,isResource as Wn,medicationOrderSetRequestToParameters as Dn,parametersToMedicationOrderSetResponse as Fn}from"@medplum/core";import{useCallback as Pe,useEffect as Vn,useRef as Me,useState as te}from"react";function Br(e){let t=C(),{patientId:n,planDefinitionId:r,vendorOrderSetId:o,appId:i,organization:s}=e,[a,u]=te(void 0),[l,f]=te(!1),[v,h]=te(void 0),b=Me({patientId:n,planDefinitionId:r,vendorOrderSetId:o,appId:i,organization:s});b.current={patientId:n,planDefinitionId:r,vendorOrderSetId:o,appId:i,organization:s};let R=()=>{let g=b.current;if(!g.patientId)return;let p=!!g.planDefinitionId,I=g.vendorOrderSetId!==void 0&&g.vendorOrderSetId!==null&&g.vendorOrderSetId!=="";return!p&&!I?void 0:{patientId:g.patientId,planDefinitionId:p?g.planDefinitionId:void 0,vendorOrderSetId:I?g.vendorOrderSetId:void 0,appId:g.appId,organization:g.organization}},d=Pe(async g=>{let p=t.fhirUrl("PlanDefinition","$order-set-url"),I=Dn(g),m=await t.post(p,I);if(!Wn(m,"Parameters"))throw new Error(Ln);return Fn(m).launchUrl},[t]),c=Me(0),E=Pe(async()=>{let g=R();if(!g)return;c.current+=1;let p=c.current;f(!0),h(void 0);try{let I=await d(g);return c.current!==p?void 0:(u(I),I)}catch(I){c.current===p&&(h(I),u(void 0));return}finally{c.current===p&&f(!1)}},[d]);return Vn(()=>{let g=!1,p=R();if(!p){c.current+=1,u(void 0),f(!1),h(void 0);return}c.current+=1;let I=c.current;return f(!0),h(void 0),d(p).then(m=>{g||c.current!==I||u(m)}).catch(m=>{g||c.current!==I||(h(m),u(void 0))}).finally(()=>{!g&&c.current===I&&f(!1)}),()=>{g=!0}},[d,n,r,o,i,s]),{url:a,loading:l,error:v,refresh:E}}import{useCallback as $n,useEffect as Kn,useState as Bn}from"react";import{deepEquals as Qe}from"@medplum/core";import{useCallback as V,useEffect as re,useRef as G,useState as Oe}from"react";var zn=3e3;function we(e,t,n){let r=C(),o=r.getProject(),a=xe()&&o?.features?.includes("websocket-subscriptions")?e:void 0,[u,l]=Oe(),[f,v]=Oe(n?.subscriptionProps),h=G(!1),b=G(void 0),R=G(void 0),d=G(void 0);re(()=>{Qe(n?.subscriptionProps,f)||v(n?.subscriptionProps)},[f,n]),re(()=>{b.current&&(clearTimeout(b.current),b.current=void 0);let M=!1;return(R.current!==a||!Qe(d.current,f))&&(M=!0),M&&R.current&&r.unsubscribeFromCriteria(R.current,d.current),R.current=a,d.current=f,M&&a?l(r.subscribeToCriteria(a,f)):a||l(void 0),()=>{b.current=setTimeout(()=>{a&&r.unsubscribeFromCriteria(a,f)},zn)}},[r,a,f]);let c=A(t),E=A(n?.onWebSocketOpen),g=A(n?.onWebSocketClose),p=A(n?.onSubscriptionConnect),I=A(n?.onSubscriptionDisconnect),m=A(n?.onError),S=V(M=>c(M.payload),[c]),y=V(M=>E(),[E]),P=V(M=>g(),[g]),Q=V(M=>p(M.payload.subscriptionId),[p]),_=V(M=>I(M.payload.subscriptionId),[I]),T=V(M=>m(M.payload),[m]);re(()=>u?(h.current||(u.addEventListener("message",S),u.addEventListener("open",y),u.addEventListener("close",P),u.addEventListener("connect",Q),u.addEventListener("disconnect",_),u.addEventListener("error",T),h.current=!0),()=>{h.current=!1,u.removeEventListener("message",S),u.removeEventListener("open",y),u.removeEventListener("close",P),u.removeEventListener("connect",Q),u.removeEventListener("disconnect",_),u.removeEventListener("error",T)}):()=>{},[u,S,y,P,Q,_,T])}function to(e){let t=C(),{resourceType:n,countCriteria:r,subscriptionCriteria:o}=e,[i,s]=Bn(0),a=$n(u=>{t.search(n,r,{cache:u}).then(l=>s(l.total)).catch(console.error)},[t,n,r]);return Kn(()=>{a("default")},[a]),we(o,()=>{a("reload")}),i}import{resolveId as jn}from"@medplum/core";import{useEffect as Jn,useMemo as Ae,useState as oe}from"react";function _e(e){let t=e.patientParam??"subject",n=e.query,r="";if(n!=null)if(typeof n=="string")r=n;else if(n instanceof URLSearchParams){let o=Array.from(n.entries()).sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));r=JSON.stringify(o)}else if(Array.isArray(n)){let o=[...n].sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));r=JSON.stringify(o)}else{let o=Object.entries(n).filter(([,i])=>i!==void 0).sort(([i],[s])=>i.localeCompare(s));r=JSON.stringify(o)}return`${e.resourceType}:${t}:${r}`}function Gn(e){return e.map(t=>{let n=t.searches?t.searches.map(_e).join(","):"";return`${t.key}:[${n}]`}).join("|")}function ao(e,t){let n=C(),[r,o]=oe([]),[i,s]=oe(!0),[a,u]=oe(),l=Gn(t),f=Ae(()=>t,[l]),v=Ae(()=>jn(e),[e]);return Jn(()=>{if(!v)return;let h=!1,b=`Patient/${v}`,R={_count:100,_sort:"-_lastUpdated"},d=[],c=new Map,E=[];for(let p of f){let I=[];if(p.searches)for(let m of p.searches){let S=_e(m),y=c.get(S);y===void 0&&(y=d.length,c.set(S,y),d.push(m)),I.push({searchIdx:y,resultKey:m.key})}E.push(I)}if(d.length===0){o(f.map(()=>({}))),s(!1);return}let g=d.map(p=>{let I=p.patientParam??"subject",m={[I]:b};if(p.query){if(typeof p.query=="string")return n.searchResources(p.resourceType,`${I}=${b}&${p.query}&_count=100&_sort=-_lastUpdated`);if(p.query instanceof URLSearchParams)p.query.forEach((S,y)=>{m[y]=S});else if(Array.isArray(p.query))for(let[S,y]of p.query)m[S]=y;else for(let[S,y]of Object.entries(p.query))y!==void 0&&(m[S]=y)}return n.searchResources(p.resourceType,{...R,...m})});return s(!0),u(void 0),Promise.allSettled(g).then(p=>{if(h)return;let I=E.map(S=>{let y={};for(let{searchIdx:P,resultKey:Q}of S){let _=p[P];y[Q]=_.status==="fulfilled"?_.value:[]}return y});o(I),s(!1);let m=p.filter(S=>S.status==="rejected");if(m.length>0){console.error("Some patient summary searches failed:",m.map(y=>y.reason));let S=m[0].reason;u(S instanceof Error?S:new Error(String(S)))}}).catch(p=>{h||(u(p instanceof Error?p:new Error(String(p))),s(!1))}),()=>{h=!0}},[n,v,f]),{sectionData:r,loading:i,error:a}}import{isAddPharmacyResponse as Hn,isOrganizationArray as Xn,resolveId as ke}from"@medplum/core";import{useCallback as qe}from"react";function fo(e,t){let n=C(),r=qe(async i=>{let{organization:s,...a}=i,u=ke(s),l=await n.executeBot(e,u?{...a,organizationId:u}:a);if(!Xn(l))throw new Error("Invalid response from pharmacy search");return l},[n,e]),o=qe(async i=>{let s=await n.executeBot(t,{patientId:i.patientId,pharmacy:i.pharmacy,setAsPrimary:i.setAsPrimary,organizationId:ke(i.organization)});if(!Hn(s))throw new Error("Invalid response from add pharmacy bot");return s},[n,t]);return{searchPharmacies:r,addToFavorites:o}}import{useEffect as Yn,useRef as Zn}from"react";function ho(e){let t=Zn(void 0);return Yn(()=>{t.current=e}),t.current}import{getExtension as Qt}from"@medplum/core";import{useReducer as Ot,useRef as wt}from"react";import{deepEquals as et,isReference as Ne,isResource as nt,normalizeOperationOutcome as tt}from"@medplum/core";import{useCallback as rt,useEffect as ot,useState as it}from"react";function ie(e,t){let n=C(),[r,o]=it(()=>Ue(n,e)),i=rt(s=>{et(s,r)||o(s)},[r]);return ot(()=>{let s=!0,a=Ue(n,e);return!a&&Ne(e)?n.readReference(e).then(u=>{s&&i(u)}).catch(u=>{s&&(i(void 0),t&&t(tt(u)))}):i(a),(()=>s=!1)},[n,e,i,t]),r}function Ue(e,t){if(t){if(nt(t))return t;if(Ne(t))return e.getCachedReference(t)}}import{EMPTY as ue,HTTP_HL7_ORG as U,PropertyType as k,append as Le,capitalize as We,deepClone as st,deepEquals as De,evalFhirPathTyped as ce,getExtension as D,getReferenceString as at,getTypedPropertyValueWithoutSchema as H,normalizeErrorString as ut,splitN as ct,toJsBoolean as dt,toTypedValue as Fe,typedValueToString as lt}from"@medplum/core";var O={group:"group",display:"display",question:"question",boolean:"boolean",decimal:"decimal",integer:"integer",date:"date",dateTime:"dateTime",time:"time",string:"string",text:"text",url:"url",choice:"choice",openChoice:"open-choice",attachment:"attachment",reference:"reference",quantity:"quantity"},Ve=`${U}/fhir/StructureDefinition/questionnaire-itemControl`,pt=`${U}/fhir/StructureDefinition/questionnaire-referenceFilter`,se=`${U}/fhir/StructureDefinition/questionnaire-referenceResource`,ft=`${U}/fhir/StructureDefinition/questionnaire-validationError`,mt=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression`,Rt=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression`,Eo=`${U}/fhir/StructureDefinition/questionnaire-signatureRequired`,X=`${U}/fhir/StructureDefinition/questionnaireresponse-signature`,ht=`${U}/fhir/StructureDefinition/questionnaire-hidden`,yt=`${U}/fhir/StructureDefinition/questionnaire-optionExclusive`;function Co(e){return e.type==="choice"||e.type==="open-choice"}function de(e,t){return{...t,item:ze(e.item,t.item,t)}}function ze(e,t,n){if(!t)return t;let r=[];for(let o of t){let i=e?.find(s=>s.linkId===o.linkId);i&&!gt(i,n)||(i?.item&&o.item?r.push({...o,item:ze(i.item,o.item,n)}):r.push(o))}return r}function gt(e,t){if(D(e,ht)?.valueBoolean===!0)return!1;let r=It(e,t);return r!==void 0?r:St(e,t)}function It(e,t){let n=D(e,mt);if(t&&n){let r=n.valueExpression?.expression;if(r){let o=Fe(t),i=ce(r,[o],{"%resource":o});return dt(i)}}}function St(e,t){if(!e.enableWhen)return!0;let n=e.enableBehavior??"any";for(let r of e.enableWhen){let o=Ke(t?.item,r.question);if(r.operator==="exists"&&!r.answerBoolean&&!o?.length){if(n==="any")return!0;continue}let{anyMatch:i,allMatch:s}=Tt(r,o,n);if(n==="any"&&i)return!0;if(n==="all"&&!s)return!1}return n!=="any"}function le(e,t,n=t.item){for(let r of e){let o=n?.find(i=>i.linkId===r.linkId);o&&(xt(t,r,o),r.item&&o.item&&le(r.item,t,o.item))}}function xt(e,t,n){try{let r=Ct(t,e);if(!r)return;let o=Et(t,r);if(!o)return;n.answer=[o]}catch(r){n.extension=[{url:ft,valueString:`Expression evaluation failed: ${ut(r)}`}]}}var bt={[O.boolean]:[k.boolean],[O.date]:[k.date],[O.dateTime]:[k.dateTime],[O.time]:[k.time],[O.url]:[k.string,k.uri,k.url],[O.attachment]:[k.Attachment],[O.reference]:[k.Reference],[O.quantity]:[k.Quantity],[O.decimal]:[k.decimal,k.integer],[O.integer]:[k.decimal,k.integer]};function Et(e,t){if(!e.type)return;if(e.type===O.choice||e.type===O.openChoice)return{[`value${We(t.type)}`]:t.value};if(e.type===O.string||e.type===O.text)return typeof t.value=="string"?{valueString:t.value}:void 0;if(bt[e.type]?.includes(t.type))return{[`value${We(e.type)}`]:t.value}}function Ct(e,t){if(!t)return;let n=D(e,Rt);if(n){let r=n.valueExpression?.expression;if(r){let o=Fe(t),i=ce(r,[o],{"%resource":o});return i.length!==0?i[0]:void 0}}}function vo(e,t,n){let r=[];for(let o of e){let i=n.answerOption?.find(s=>lt(ae(s))===o);if(i){let s=ae(i);s&&r.push({[t]:s.value})}}return r}function $e(e,t,n){let r=[];for(let a of e.answerOption??ue)if(D(a,yt)?.valueBoolean===!0){let u=ae(a);u?.value!==void 0&&r.push(u)}if(r.length===0)return n;let o=a=>{let u=Je(a);return!!u&&r.some(l=>De(l,u))},i=n.filter(a=>!t?.some(u=>De(u,a))),s=i.find(o);return s?[s]:i.some(a=>!o(a))?n.filter(a=>!o(a)):n}function Ke(e,t){for(let n of e??ue){if(n.linkId===t)return n.answer;if(n.item){let r=Ke(n.item,t);if(r)return r}}}function vt(e,t,n){if(n==="exists")return!!e===t.value;if(e){let r=n==="="||n==="!="?n?.replace("=","~"):n,[{value:o}]=ce(`%actualAnswer ${r} %expectedAnswer`,[e],{"%actualAnswer":e,"%expectedAnswer":t});return o}else return!1}function Tt(e,t,n){let r=t||[],o=Mt(e),i=!1,s=!0;for(let a of r){let u=Je(a),{operator:l}=e;if(vt(u,o,l)?i=!0:s=!1,n==="any"&&i)break}return{anyMatch:i,allMatch:s}}function To(e){let t=D(e,se);if(t){if(t.valueCode!==void 0)return[t.valueCode];if(t.valueCodeableConcept)return t.valueCodeableConcept?.coding?.map(n=>n.code)}}function Po(e,t){let n=st(e),r=D(n,se);return!t||t.length===0?(r&&(n.extension=n.extension?.filter(o=>o!==r)),n):(r||(n.extension??=[],r={url:se},n.extension.push(r)),t.length===1?(r.valueCode=t[0],delete r.valueCodeableConcept):(r.valueCodeableConcept={coding:t.map(o=>({code:o}))},delete r.valueCode),n)}function Mo(e,t,n){let r=D(e,pt);if(!r?.valueString)return;let o=r.valueString;t?.reference&&(o=o.replaceAll("$subj",t.reference)),n?.reference&&(o=o.replaceAll("$encounter",n.reference));let i={},s=o.split("&");for(let a of s){let[u,l]=ct(a,"=",2);i[u]=l}return i}function pe(e,t){return{resourceType:"QuestionnaireResponse",questionnaire:e.url??at(e),item:fe(e.item,t?.item),status:"in-progress"}}function fe(e,t){let n;for(let r of e??ue){if(r.type===O.display)continue;let o=t?.filter(i=>i.linkId===r.linkId);if(o?.length)for(let i of o)i.id=i.id??Be(),i.text=i.text??r.text,i.item=fe(r.item,i.item),i.answer=je(r,i),n=Le(n,i);else n=Le(n,me(r))}return n}function me(e){return{id:Be(),linkId:e.linkId,text:e.text,item:fe(e.item,void 0),answer:je(e)}}var Pt=1;function Be(){return"id-"+Pt++}function je(e,t){if(!(e.type===O.display||e.type===O.group)){if(t?.answer&&t.answer.length>0)return t.answer;if(e.initial&&e.initial.length>0)return e.initial.map(n=>({...n}));if(e.answerOption)return e.answerOption.filter(n=>n.initialSelected).map(n=>({...n,initialSelected:void 0}))}}function Qo(e){return H({type:"QuestionnaireItemInitial",value:e},"value")}function ae(e){return H({type:"QuestionnaireItemAnswerOption",value:e},"value")}function Mt(e){return H({type:"QuestionnaireItemEnableWhen",value:e},"answer")}function Je(e){return H({type:"QuestionnaireResponseItemAnswer",value:e},"value")}function qo(e){let t=ie(e.questionnaire),n=ie(e.defaultValue),[,r]=Ot(R=>R+1,0),o=wt({activePage:0});if(!o.current.questionnaire&&t&&(o.current.questionnaire=t,o.current.pages=e.disablePagination?void 0:At(t)),t&&e.defaultValue&&n&&!o.current.questionnaireResponse&&(o.current.questionnaireResponse=pe(t,n),b()),t&&!e.defaultValue&&!o.current.questionnaireResponse&&(o.current.questionnaireResponse=pe(t),b()),!o.current.questionnaire||!o.current.questionnaireResponse)return{loading:!0};function i(R,d){let c=o.current.questionnaireResponse;for(let E of R)c=c?.item?.find(g=>E.id?g.id===E.id:g.linkId===E.linkId);return d&&(c=c?.item?.find(E=>E.linkId===d.linkId)),c}function s(){o.current.activePage=(o.current.activePage??0)+1,r()}function a(){o.current.activePage=(o.current.activePage??0)-1,r()}function u(R,d){let c=i(R);c&&(c.item??=[],c.item.push(me(d)),b())}function l(R,d){let c=i(R,d);c&&(c.answer??=[],c.answer.push({}),b())}function f(R,d,c){let E=i(R,d);E&&(E.answer=$e(d,E.answer,c),b())}function v(R){let d=o.current.questionnaireResponse;d&&(R?(d.extension=d.extension??[],d.extension=d.extension.filter(c=>c.url!==X),d.extension.push({url:X,valueSignature:R})):d.extension=d.extension?.filter(c=>c.url!==X),b())}function h(){let R=o.current.questionnaire;if(R?.item){let d=o.current.questionnaireResponse;le(R.item,d)}}function b(){let R=o.current.questionnaireResponse,d=o.current.questionnaire;!R||!d||(h(),r(),e.onChange?.(de(d,R)))}return{loading:!1,pagination:!!o.current.pages,questionnaire:o.current.questionnaire,questionnaireResponse:de(o.current.questionnaire,o.current.questionnaireResponse),subject:e.subject,encounter:e.encounter,activePage:o.current.activePage,pages:o.current.pages,items:_t(o.current.questionnaire,o.current.pages,o.current.activePage),responseItems:kt(o.current.questionnaireResponse,o.current.pages,o.current.activePage),onNextPage:s,onPrevPage:a,onAddGroup:u,onAddAnswer:l,onChangeAnswer:f,onChangeSignature:v}}function At(e){if(!(!e?.item||Qt(e?.item?.[0],Ve)?.valueCodeableConcept?.coding?.[0]?.code!=="page"))return e.item.map((n,r)=>({linkId:n.linkId,title:n.text??`Page ${r+1}`,group:n}))}function _t(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}function kt(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}import{deepEquals as qt,formatSearchQuery as Ut}from"@medplum/core";import{useCallback as Nt,useEffect as Re,useRef as he,useState as K}from"react";async function Lt(e,t){let n=await t.search(e.resourceType,Ut({...e,total:e.total??"accurate"}),{cache:"no-cache"});return{items:n.entry?.map(o=>o.resource).filter(o=>o!==void 0)??[],total:n.total}}function Do(e){let{search:t,selectedId:n,loadItems:r,reloadKey:o}=e,i=C(),[s,a]=K(t),[u,l]=K([]),[f,v]=K(),[h,b]=K(!0),[R,d]=K(),c=he(e),E=he(0),g=he(0),p=s.resourceType,I=n!==void 0&&R?.id===n?R.value:void 0;qt(t,s)||(a(t),b(!0));let m=Nt(async()=>{let S=++E.current;try{let y=r?await r(s,i):await Lt(s,i);if(S!==E.current)return;l(y.items),v(y.total),c.current.onLoad?.(y.items,y.total)}catch(y){S===E.current&&(c.current.onError??console.error)(y)}finally{S===E.current&&b(!1)}},[s,r,i]);return Re(()=>{c.current=e}),Re(()=>{m().catch(console.error)},[m,o]),Re(()=>{let S=++g.current;if(!n)return;let y=async()=>{let Q=c.current.resolveSelected;if(Q)return Q(n,u,i);let _=u.find(T=>T.id===n);return _!==void 0?_:await i.readResource(p,n)};(async()=>{try{let Q=await y();S===g.current&&d({id:n,value:Q})}catch(Q){S===g.current&&(d({id:n,value:void 0}),(c.current.onError??console.error)(Q))}})().catch(console.error)},[n,u,i,p]),{items:u,total:f,loading:h,selected:I,search:s,refresh:m}}import{useEffect as Wt}from"react";function Ko(e,t){let n=C(),r=A(t),o=Array.isArray(e)?e.join(","):e;Wt(()=>{let i=new Set(o.split(",")),s=a=>{i.has(a.payload.resourceType)&&r(a.payload)};return n.addEventListener("resourceModified",s),()=>n.removeEventListener("resourceModified",s)},[n,o,r])}import{allOk as Vt,normalizeOperationOutcome as zt}from"@medplum/core";import{useEffect as $t,useMemo as Kt,useState as ge}from"react";import{useCallback as Dt,useEffect as Ge,useRef as ye,useState as Ft}from"react";function He(e,t,n={leading:!1}){let[r,o]=Ft(e),i=ye(!1),s=ye(void 0),a=ye(!1),u=Dt(()=>window.clearTimeout(s.current),[]);return Ge(()=>{i.current&&(!a.current&&n.leading?(a.current=!0,o(e),s.current=setTimeout(()=>{a.current=!1},t)):(u(),s.current=setTimeout(()=>{a.current=!1,o(e)},t)))},[e,n.leading,t,u]),Ge(()=>(i.current=!0,u),[u]),[r,u]}var Bt=250;function Zo(e,t,n){return Ie("search",e,t,n)}function ei(e,t,n){return Ie("searchOne",e,t,n)}function ni(e,t,n){return Ie("searchResources",e,t,n)}function Ie(e,t,n,r){let o=C(),[i,s]=ge(!1),[a,u]=ge(),[l,f]=ge(),v=o.fhirSearchUrl(t,n).toString(),h=Kt(()=>({resourceType:t,query:n}),[v]),b=r?.enabled??!0,R=r?.debounceMs??Bt,[d]=He(h,R,{leading:!0});return $t(()=>{if(!b)return()=>{};s(!0);let c=!0;return o[e](d.resourceType,d.query).then(E=>{c&&(s(!1),u(E),f(Vt))}).catch(E=>{c&&(s(!1),u(void 0),f(zt(E)))}),()=>{c=!1}},[o,e,d,b]),[a,i,l]}import{OperationOutcomeError as jt,isResource as Jt,parametersToOrderSetSyncResponse as Gt,resolveId as Ht}from"@medplum/core";import{useCallback as Xt}from"react";function si(){let e=C();return Xt(async(t,n)=>{try{let r=await e.post(e.fhirUrl("PlanDefinition","$sync-orderset"),{planDefinitionId:t,organizationId:Ht(n)});return Jt(r,"Parameters")?Gt(r):void 0}catch(r){if(r instanceof jt&&r.outcome.issue?.some(o=>o.code==="not-found"))return;throw r}},[e])}import{getReferenceString as Yt}from"@medplum/core";import{useCallback as Zt,useEffect as Xe,useRef as er,useState as z}from"react";function li({query:e,threadId:t}){let n=C(),[r,o]=z(!0),[i,s]=z(e),[a,u]=z([]),[l,f]=z(void 0),[v,h]=z(null),[b,R]=z(void 0),d=er(0);e!==i&&(s(e),o(!0));let c=Zt(async()=>{let p=++d.current;try{let I=new URLSearchParams(i);I.append("identifier:not","http://medplum.com/ai-message|"),I.append("part-of:missing","true"),I.append("_has:Communication:part-of:_id:not","null");let m=await n.search("Communication",I.toString(),{cache:"no-cache"});if(p!==d.current)return;let S=m.entry?.map(T=>T.resource).filter(T=>T!==void 0)||[];if(m.total!==void 0&&R(m.total),S.length===0){u([]);return}let P=`
2
2
  query {
3
- ${S.map(P=>{let F=`thread_${P.id?.replaceAll("-","")||""}`,L=Gt(P);return`
3
+ ${S.map(T=>{let F=`thread_${T.id?.replaceAll("-","")||""}`,L=Yt(T);return`
4
4
  ${F}: CommunicationList(
5
5
  part_of: "${L}"
6
6
  _sort: "-sent"
@@ -26,9 +26,9 @@ import{useEffect as dn,useMemo as ln,useState as pn}from"react";import{createCon
26
26
  `}).join(`
27
27
  `)}
28
28
  }
29
- `,Q=await n.graphql(C);if(l!==d.current)return;let k=S.map(P=>{let F=`thread_${P.id?.replaceAll("-","")||""}`,L=Q.data[F],$=L&&L.length>0?L[0]:void 0;return[P,$]}).filter(P=>P[1]!==void 0);u(k)}finally{l===d.current&&o(!1)}},[n,i]);return Xe(()=>{c().catch(l=>{y(l)})},[c]),Xe(()=>{(async()=>{if(!t){f(void 0);return}let I=a.find(S=>S[0].id===t);if(I){f(I[0]);return}let m=await n.readResource("Communication",t);if(m.partOf===void 0)f(m);else{let S=m.partOf[0].reference;if(S){let h=await n.readReference({reference:S});f(h)}}})().catch(I=>{y(I)})},[t,a,n]),{loading:r,error:T,threadMessages:a,selectedThread:p,total:b,addThreadMessage:l=>{(async()=>{await c(),u(m=>[[l,void 0],...m])})().catch(m=>y(m))},handleThreadStatusChange:l=>{if(!p)return;(async()=>{let m=await n.updateResource({...p,status:l});f(m),u(S=>S.map(([h,C])=>h.id===m.id?[m,C]:[h,C]))})().catch(m=>y(m))},refreshThreadMessages:c}}import{getStatus as Yt,OperationOutcomeError as Zt}from"@medplum/core";import{useEffect as er,useMemo as Ye,useState as nr}from"react";function tr(e){if(e instanceof Zt){let t=Yt(e.outcome);return t===400||t===404}return!1}var Ze=[];function rr(e){let t=v(),n=Array.from(new Set(e.filter(s=>!!s))).sort((s,a)=>s.localeCompare(a)).join(`
29
+ `,Q=await n.graphql(P);if(p!==d.current)return;let _=S.map(T=>{let F=`thread_${T.id?.replaceAll("-","")||""}`,L=Q.data[F],B=L&&L.length>0?L[0]:void 0;return[T,B]}).filter(T=>T[1]!==void 0);u(_)}finally{p===d.current&&o(!1)}},[n,i]);return Xe(()=>{c().catch(p=>{h(p)})},[c]),Xe(()=>{(async()=>{if(!t){f(void 0);return}let I=a.find(S=>S[0].id===t);if(I){f(I[0]);return}let m=await n.readResource("Communication",t);if(m.partOf===void 0)f(m);else{let S=m.partOf[0].reference;if(S){let y=await n.readReference({reference:S});f(y)}}})().catch(I=>{h(I)})},[t,a,n]),{loading:r,error:v,threadMessages:a,selectedThread:l,total:b,addThreadMessage:p=>{(async()=>{await c(),u(m=>[[p,void 0],...m])})().catch(m=>h(m))},handleThreadStatusChange:p=>{if(!l)return;(async()=>{let m=await n.updateResource({...l,status:p});f(m),u(S=>S.map(([y,P])=>y.id===m.id?[m,P]:[y,P]))})().catch(m=>h(m))},refreshThreadMessages:c}}import{getStatus as nr,OperationOutcomeError as tr}from"@medplum/core";import{useEffect as rr,useMemo as Ye,useState as or}from"react";function ir(e){if(e instanceof tr){let t=nr(e.outcome);return t===400||t===404}return!1}var Ze=[];function sr(e){let t=C(),n=Array.from(new Set(e.filter(s=>!!s))).sort((s,a)=>s.localeCompare(a)).join(`
30
30
  `),r=Ye(()=>n===""?Ze:n.split(`
31
- `),[n]),[o,i]=nr({});return er(()=>{if(r.length===0)return;let s=!1,a=new AbortController;for(let u of r)t.valueSetExpand({url:u,count:1},{signal:a.signal}).then(()=>{s||i(p=>({...p,[u]:!0}))}).catch(p=>{s||i(f=>({...f,[u]:!tr(p)}))});return()=>{s=!0,a.abort()}},[t,r]),Ye(()=>{let s=[],a=[],u=!1;for(let p of r){let f=o[p];f===void 0?u=!0:f?s.push(p):a.push(p)}return{loading:u,available:s,unavailable:a}},[r,o])}function fi(e){let{loading:t,unavailable:n}=rr(e?[e]:Ze);if(!e)return!0;if(!t)return!n.includes(e)}import{ReconnectingWebSocket as or,sleep as ir}from"@medplum/core";import{useCallback as q,useEffect as en,useRef as W,useState as X}from"react";var sr=12e4;function Ii({language:e="en",model:t="gpt-4o-transcribe",onTranscript:n,idleTimeoutMs:r=sr}){let o=v(),i=A(n),[s,a]=X("idle"),[u,p]=X(void 0),[f,T]=X([]),y=W(void 0),b=W(void 0),R=W(void 0),d=W(void 0),c=W(!1),E=W(!1),g=W(!1),[l,I]=X(!1),m=W(!1),S=q(x=>{m.current=x,I(x),b.current?.getAudioTracks().forEach(w=>{w.enabled=!x})},[]),h=q(()=>{g.current=!1,d.current?.disconnect(),d.current=void 0,R.current?.close().catch(()=>{}),R.current=void 0,b.current?.getTracks().forEach(x=>x.stop()),b.current=void 0,m.current=!1,I(!1),a(y.current?"idle":"disconnected")},[]),C=q(()=>{h(),y.current?.close(),y.current=void 0,E.current=!1,a("disconnected")},[h]),Q=q(()=>{y.current?.send(JSON.stringify({type:"session.update",session:{type:"transcription",audio:{input:{format:{type:"audio/pcm",rate:24e3},transcription:{model:t,language:e},turn_detection:{type:"server_vad",threshold:.5,prefix_padding_ms:300,silence_duration_ms:200},noise_reduction:{type:"near_field"}}}}}))},[e,t]),k=q(async()=>{if(!(d.current||c.current)&&!(!b.current||!y.current)){c.current=!0;try{let x=new AudioContext({sampleRate:24e3});await x.audioWorklet.addModule(dr());let w=b.current,N=y.current;if(!g.current||!w||!N){await x.close().catch(()=>{});return}let rn=x.createMediaStreamSource(w),B=new AudioWorkletNode(x,nn);B.port.onmessage=on=>{if(N.readyState!==WebSocket.OPEN){console.warn("WebSocket is not open. Unable to send audio data.");return}let sn=ar(on.data),an=btoa(String.fromCharCode(...sn));N.send(JSON.stringify({type:"input_audio_buffer.append",audio:an}))},rn.connect(B),B.connect(x.destination),R.current=x,d.current=B,a("listening")}catch(x){p(x),a("error"),h()}finally{c.current=!1}}},[h]),P=q(()=>{g.current&&E.current&&b.current&&(d.current||(y.current?.send(JSON.stringify({type:"input_audio_buffer.clear"})),k().catch(()=>{})))},[k]),M=q(x=>{switch(x.type){case"session.created":Q();break;case"session.updated":E.current=!0,P();break;case"input_audio_buffer.speech_started":a("speech_started");break;case"input_audio_buffer.speech_stopped":a("speech_stopped");break;case"conversation.item.input_audio_transcription.completed":case"input_audio_transcription.completed":if(x.transcript){let w={text:x.transcript,timestamp:new Date().toISOString()};T(N=>[...N,w]),i(x.transcript)}break;case"ai-realtime:connected":console.debug("[useWhisper] upstream connected");break;case"ai-realtime:error":case"error":console.error("[useWhisper] error event",x),p(x),a("error");break;default:console.debug("[useWhisper] unhandled message",x.type,x);break}},[Q,P,i]),F=q(async()=>{a("requesting_microphone");let x=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:24e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0}});return x.getAudioTracks().forEach(w=>{w.enabled=!m.current}),b.current=x,x},[]),L=q(()=>{a("connecting");let x=ur(o.getBaseUrl());console.debug("[useWhisper] connecting to",x);let w=new or(x);return y.current=w,w.onopen=()=>{E.current=!1,g.current?a("connected"):a("idle"),w.send(JSON.stringify({type:"ai-realtime:connect",accessToken:o.getAccessToken()}))},w.onmessage=N=>M(JSON.parse(N.data)),w.onerror=N=>{g.current&&(p(N),C(),a("error"))},w.onclose=()=>{E.current=!1,y.current&&a(g.current?"connecting":"idle")},w},[o,M,C]),$=q(()=>y.current??L(),[L]),tn=q(async()=>{try{p(void 0),g.current=!0,$(),await F(),P()}catch(x){p(x),a("error"),h()}},[F,$,h,P]);return en(()=>{if(s!=="idle"||!y.current||!Number.isFinite(r)||r<=0)return;let x=new AbortController;return ir(r,{signal:x.signal}).then(()=>C()).catch(()=>{}),()=>x.abort()},[s,r,C]),en(()=>()=>C(),[C]),{status:s,error:u,transcripts:f,start:tn,stop:h,isListening:s==="listening"||s==="speech_started"||s==="speech_stopped",muted:l,setMuted:S}}function ar(e){let t=new Int16Array(e.length);for(let n=0;n<e.length;n++){let r=Math.max(-1,Math.min(1,e[n]));t[n]=r*32767}return new Uint8Array(t.buffer)}function ur(e){let t=new URL("ws/ai-realtime",e);return t.protocol=t.protocol==="https:"?"wss:":"ws:",t.toString()}var nn="medplum-pcm-worklet",cr=`
31
+ `),[n]),[o,i]=or({});return rr(()=>{if(r.length===0)return;let s=!1,a=new AbortController;for(let u of r)t.valueSetExpand({url:u,count:1},{signal:a.signal}).then(()=>{s||i(l=>({...l,[u]:!0}))}).catch(l=>{s||i(f=>({...f,[u]:!ir(l)}))});return()=>{s=!0,a.abort()}},[t,r]),Ye(()=>{let s=[],a=[],u=!1;for(let l of r){let f=o[l];f===void 0?u=!0:f?s.push(l):a.push(l)}return{loading:u,available:s,unavailable:a}},[r,o])}function hi(e){let{loading:t,unavailable:n}=sr(e?[e]:Ze);if(!e)return!0;if(!t)return!n.includes(e)}import{ReconnectingWebSocket as ar,sleep as ur}from"@medplum/core";import{useCallback as q,useEffect as en,useRef as W,useState as Y}from"react";var cr=12e4;function bi({language:e="en",model:t="gpt-4o-transcribe",onTranscript:n,idleTimeoutMs:r=cr}){let o=C(),i=A(n),[s,a]=Y("idle"),[u,l]=Y(void 0),[f,v]=Y([]),h=W(void 0),b=W(void 0),R=W(void 0),d=W(void 0),c=W(!1),E=W(!1),g=W(!1),[p,I]=Y(!1),m=W(!1),S=q(x=>{m.current=x,I(x),b.current?.getAudioTracks().forEach(w=>{w.enabled=!x})},[]),y=q(()=>{g.current=!1,d.current?.disconnect(),d.current=void 0,R.current?.close().catch(()=>{}),R.current=void 0,b.current?.getTracks().forEach(x=>x.stop()),b.current=void 0,m.current=!1,I(!1),a(h.current?"idle":"disconnected")},[]),P=q(()=>{y(),h.current?.close(),h.current=void 0,E.current=!1,a("disconnected")},[y]),Q=q(()=>{h.current?.send(JSON.stringify({type:"session.update",session:{type:"transcription",audio:{input:{format:{type:"audio/pcm",rate:24e3},transcription:{model:t,language:e},turn_detection:{type:"server_vad",threshold:.5,prefix_padding_ms:300,silence_duration_ms:200},noise_reduction:{type:"near_field"}}}}}))},[e,t]),_=q(async()=>{if(!(d.current||c.current)&&!(!b.current||!h.current)){c.current=!0;try{let x=new AudioContext({sampleRate:24e3});await x.audioWorklet.addModule(fr());let w=b.current,N=h.current;if(!g.current||!w||!N){await x.close().catch(()=>{});return}let rn=x.createMediaStreamSource(w),j=new AudioWorkletNode(x,nn);j.port.onmessage=on=>{if(N.readyState!==WebSocket.OPEN){console.warn("WebSocket is not open. Unable to send audio data.");return}let sn=dr(on.data),an=btoa(String.fromCharCode(...sn));N.send(JSON.stringify({type:"input_audio_buffer.append",audio:an}))},rn.connect(j),j.connect(x.destination),R.current=x,d.current=j,a("listening")}catch(x){l(x),a("error"),y()}finally{c.current=!1}}},[y]),T=q(()=>{g.current&&E.current&&b.current&&(d.current||(h.current?.send(JSON.stringify({type:"input_audio_buffer.clear"})),_().catch(()=>{})))},[_]),M=q(x=>{switch(x.type){case"session.created":Q();break;case"session.updated":E.current=!0,T();break;case"input_audio_buffer.speech_started":a("speech_started");break;case"input_audio_buffer.speech_stopped":a("speech_stopped");break;case"conversation.item.input_audio_transcription.completed":case"input_audio_transcription.completed":if(x.transcript){let w={text:x.transcript,timestamp:new Date().toISOString()};v(N=>[...N,w]),i(x.transcript)}break;case"ai-realtime:connected":console.debug("[useWhisper] upstream connected");break;case"ai-realtime:error":case"error":console.error("[useWhisper] error event",x),l(x),a("error");break;default:console.debug("[useWhisper] unhandled message",x.type,x);break}},[Q,T,i]),F=q(async()=>{a("requesting_microphone");let x=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:24e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0}});return x.getAudioTracks().forEach(w=>{w.enabled=!m.current}),b.current=x,x},[]),L=q(()=>{a("connecting");let x=lr(o.getBaseUrl());console.debug("[useWhisper] connecting to",x);let w=new ar(x);return h.current=w,w.onopen=()=>{E.current=!1,g.current?a("connected"):a("idle"),w.send(JSON.stringify({type:"ai-realtime:connect",accessToken:o.getAccessToken()}))},w.onmessage=N=>M(JSON.parse(N.data)),w.onerror=N=>{g.current&&(l(N),P(),a("error"))},w.onclose=()=>{E.current=!1,h.current&&a(g.current?"connecting":"idle")},w},[o,M,P]),B=q(()=>h.current??L(),[L]),tn=q(async()=>{try{l(void 0),g.current=!0,B(),await F(),T()}catch(x){l(x),a("error"),y()}},[F,B,y,T]);return en(()=>{if(s!=="idle"||!h.current||!Number.isFinite(r)||r<=0)return;let x=new AbortController;return ur(r,{signal:x.signal}).then(()=>P()).catch(()=>{}),()=>x.abort()},[s,r,P]),en(()=>()=>P(),[P]),{status:s,error:u,transcripts:f,start:tn,stop:y,isListening:s==="listening"||s==="speech_started"||s==="speech_stopped",muted:p,setMuted:S}}function dr(e){let t=new Int16Array(e.length);for(let n=0;n<e.length;n++){let r=Math.max(-1,Math.min(1,e[n]));t[n]=r*32767}return new Uint8Array(t.buffer)}function lr(e){let t=new URL("ws/ai-realtime",e);return t.protocol=t.protocol==="https:"?"wss:":"ws:",t.toString()}var nn="medplum-pcm-worklet",pr=`
32
32
  class PcmWorkletProcessor extends AudioWorkletProcessor {
33
33
  constructor() {
34
34
  super();
@@ -61,5 +61,5 @@ class PcmWorkletProcessor extends AudioWorkletProcessor {
61
61
  }
62
62
 
63
63
  registerProcessor('${nn}', PcmWorkletProcessor);
64
- `,Se;function dr(){if(!Se){let e=new Blob([cr],{type:"application/javascript"});Se=URL.createObjectURL(e)}return Se}export{En as MEDICATION_CART_ADD_IN_PROGRESS,hr as MedplumProvider,pt as QUESTIONNAIRE_CALCULATED_EXPRESSION_URL,lt as QUESTIONNAIRE_ENABLED_WHEN_EXPRESSION_URL,ft as QUESTIONNAIRE_HIDDEN_URL,Ve as QUESTIONNAIRE_ITEM_CONTROL_URL,mt as QUESTIONNAIRE_OPTION_EXCLUSIVE_URL,ct as QUESTIONNAIRE_REFERENCE_FILTER_URL,se as QUESTIONNAIRE_REFERENCE_RESOURCE_URL,So as QUESTIONNAIRE_SIGNATURE_REQUIRED_URL,H as QUESTIONNAIRE_SIGNATURE_RESPONSE_URL,dt as QUESTIONNAIRE_VALIDATION_ERROR_URL,O as QuestionnaireItemType,Ke as applyOptionExclusive,pe as buildInitialResponse,me as buildInitialResponseItem,ar as convertToPCM16,le as evaluateCalculatedExpressionsInQuestionnaire,ae as getItemAnswerOptionValue,Tt as getItemEnableWhenValueAnswer,Po as getItemInitialValue,bo as getNewMultiSelectValues,To as getQuestionnaireItemReferenceFilter,Eo as getQuestionnaireItemReferenceTargetTypes,Je as getResponseItemAnswerValue,xo as isChoiceQuestion,Rt as isQuestionEnabled,tr as isValueSetUnavailableError,Y as reactContext,de as removeDisabledItems,vo as setQuestionnaireItemReferenceTargetTypes,St as typedValueToResponseItem,Sr as useCachedBinaryUrl,Tr as useMedicationCart,kr as useMedicationIFrame,Lr as useMedicationOrder,zr as useMedicationOrderSet,v as useMedplum,Z as useMedplumContext,pr as useMedplumNavigate,xe as useMedplumProfile,Zr as useNotificationCount,oo as usePatientSummaryData,co as usePharmacySearch,fo as usePrevious,Ao as useQuestionnaireForm,ie as useResource,No as useResourceBoard,Vo as useResourceModified,Ho as useSearch,Xo as useSearchOne,Yo as useSearchResources,A as useStabilizedCallback,we as useSubscription,ri as useSyncOrderSet,ui as useThreadInbox,rr as useValueSetAvailabilities,fi as useValueSetAvailability,Ii as useWhisper};
64
+ `,Se;function fr(){if(!Se){let e=new Blob([pr],{type:"application/javascript"});Se=URL.createObjectURL(e)}return Se}export{Tn as MEDICATION_CART_ADD_IN_PROGRESS,Ir as MedplumProvider,Rt as QUESTIONNAIRE_CALCULATED_EXPRESSION_URL,mt as QUESTIONNAIRE_ENABLED_WHEN_EXPRESSION_URL,ht as QUESTIONNAIRE_HIDDEN_URL,Ve as QUESTIONNAIRE_ITEM_CONTROL_URL,yt as QUESTIONNAIRE_OPTION_EXCLUSIVE_URL,pt as QUESTIONNAIRE_REFERENCE_FILTER_URL,se as QUESTIONNAIRE_REFERENCE_RESOURCE_URL,Eo as QUESTIONNAIRE_SIGNATURE_REQUIRED_URL,X as QUESTIONNAIRE_SIGNATURE_RESPONSE_URL,ft as QUESTIONNAIRE_VALIDATION_ERROR_URL,O as QuestionnaireItemType,$e as applyOptionExclusive,pe as buildInitialResponse,me as buildInitialResponseItem,dr as convertToPCM16,le as evaluateCalculatedExpressionsInQuestionnaire,ae as getItemAnswerOptionValue,Mt as getItemEnableWhenValueAnswer,Qo as getItemInitialValue,vo as getNewMultiSelectValues,Mo as getQuestionnaireItemReferenceFilter,To as getQuestionnaireItemReferenceTargetTypes,Je as getResponseItemAnswerValue,Co as isChoiceQuestion,gt as isQuestionEnabled,ir as isValueSetUnavailableError,Z as reactContext,de as removeDisabledItems,Po as setQuestionnaireItemReferenceTargetTypes,Et as typedValueToResponseItem,Er as useCachedBinaryUrl,Mr as useMedicationCart,Ur as useMedicationIFrame,Fr as useMedicationOrder,Br as useMedicationOrderSet,C as useMedplum,ee as useMedplumContext,Rr as useMedplumNavigate,xe as useMedplumProfile,to as useNotificationCount,ao as usePatientSummaryData,fo as usePharmacySearch,ho as usePrevious,qo as useQuestionnaireForm,ie as useResource,Do as useResourceBoard,Ko as useResourceModified,Zo as useSearch,ei as useSearchOne,ni as useSearchResources,A as useStabilizedCallback,we as useSubscription,si as useSyncOrderSet,li as useThreadInbox,sr as useValueSetAvailabilities,hi as useValueSetAvailability,bi as useWhisper};
65
65
  //# sourceMappingURL=index.mjs.map