@medplum/react-hooks 5.1.17 → 5.1.21
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/cjs/index.cjs +7 -7
- package/dist/cjs/index.cjs.map +4 -4
- package/dist/cjs/index.d.ts +44 -0
- package/dist/esm/index.d.ts +44 -0
- package/dist/esm/index.mjs +7 -7
- package/dist/esm/index.mjs.map +4 -4
- package/package.json +8 -8
package/dist/cjs/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ import type { Reference } from '@medplum/fhirtypes';
|
|
|
31
31
|
import type { Resource } from '@medplum/fhirtypes';
|
|
32
32
|
import type { ResourceArray } from '@medplum/core';
|
|
33
33
|
import type { ResourceType } from '@medplum/fhirtypes';
|
|
34
|
+
import type { SearchRequest } from '@medplum/core';
|
|
34
35
|
import type { Signature } from '@medplum/fhirtypes';
|
|
35
36
|
import type { Subscription } from '@medplum/fhirtypes';
|
|
36
37
|
import type { TypedValue } from '@medplum/core';
|
|
@@ -271,6 +272,11 @@ export declare const reactContext: Context<MedplumContext | undefined>;
|
|
|
271
272
|
*/
|
|
272
273
|
export declare function removeDisabledItems(questionnaire: Questionnaire, response: QuestionnaireResponse): QuestionnaireResponse;
|
|
273
274
|
|
|
275
|
+
export declare interface ResourceBoardLoadResult<T extends Resource = Resource> {
|
|
276
|
+
readonly items: WithId<T>[];
|
|
277
|
+
readonly total?: number;
|
|
278
|
+
}
|
|
279
|
+
|
|
274
280
|
export declare type SearchOptions = {
|
|
275
281
|
debounceMs?: number;
|
|
276
282
|
enabled?: boolean;
|
|
@@ -494,6 +500,44 @@ export declare interface UseQuestionnaireFormProps {
|
|
|
494
500
|
*/
|
|
495
501
|
export declare function useResource<T extends Resource>(value: Reference<T> | Partial<T> | undefined, setOutcome?: (outcome: OperationOutcome) => void): WithId<T> | undefined;
|
|
496
502
|
|
|
503
|
+
/**
|
|
504
|
+
* useResourceBoard manages the data layer for the ResourceBoard component:
|
|
505
|
+
* fetching the resource list, resolving the selected resource, and supporting
|
|
506
|
+
* background refresh.
|
|
507
|
+
* @param options - The data options, a subset of the ResourceBoard props.
|
|
508
|
+
* @returns The loaded resources, total, loading state, resolved selection, and refresh helper.
|
|
509
|
+
*/
|
|
510
|
+
export declare function useResourceBoard<T extends Resource = Resource>(options: UseResourceBoardProps<T>): UseResourceBoardResult<T>;
|
|
511
|
+
|
|
512
|
+
export declare interface UseResourceBoardProps<T extends Resource = Resource> {
|
|
513
|
+
readonly search: SearchRequest;
|
|
514
|
+
readonly selectedId?: string;
|
|
515
|
+
readonly loadItems?: (search: SearchRequest, medplum: MedplumClient) => Promise<ResourceBoardLoadResult<T>>;
|
|
516
|
+
readonly resolveSelected?: (id: string, items: WithId<T>[], medplum: MedplumClient) => Promise<WithId<T> | undefined>;
|
|
517
|
+
/**
|
|
518
|
+
* Manual refresh trigger: change this value (e.g. a counter) to re-run the load
|
|
519
|
+
* without changing the search. Reloads in place — no skeleton — like `refresh()`.
|
|
520
|
+
*/
|
|
521
|
+
readonly reloadKey?: unknown;
|
|
522
|
+
readonly onSelectFirst?: (item: WithId<T>) => void;
|
|
523
|
+
readonly onLoad?: (items: WithId<T>[], total: number | undefined) => void;
|
|
524
|
+
readonly onError?: (error: unknown) => void;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export declare interface UseResourceBoardResult<T extends Resource = Resource> {
|
|
528
|
+
readonly items: WithId<T>[];
|
|
529
|
+
readonly total: number | undefined;
|
|
530
|
+
readonly loading: boolean;
|
|
531
|
+
readonly selected: WithId<T> | undefined;
|
|
532
|
+
/**
|
|
533
|
+
* The search currently in effect. Tracks the input `search`, but only updates when it
|
|
534
|
+
* changes by deep equality — so this identity is stable across renders and safe to use
|
|
535
|
+
* in dependency arrays or to derive pagination from.
|
|
536
|
+
*/
|
|
537
|
+
readonly search: SearchRequest;
|
|
538
|
+
readonly refresh: () => Promise<void>;
|
|
539
|
+
}
|
|
540
|
+
|
|
497
541
|
/**
|
|
498
542
|
* React hook for searching FHIR resources.
|
|
499
543
|
*
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -31,6 +31,7 @@ import type { Reference } from '@medplum/fhirtypes';
|
|
|
31
31
|
import type { Resource } from '@medplum/fhirtypes';
|
|
32
32
|
import type { ResourceArray } from '@medplum/core';
|
|
33
33
|
import type { ResourceType } from '@medplum/fhirtypes';
|
|
34
|
+
import type { SearchRequest } from '@medplum/core';
|
|
34
35
|
import type { Signature } from '@medplum/fhirtypes';
|
|
35
36
|
import type { Subscription } from '@medplum/fhirtypes';
|
|
36
37
|
import type { TypedValue } from '@medplum/core';
|
|
@@ -271,6 +272,11 @@ export declare const reactContext: Context<MedplumContext | undefined>;
|
|
|
271
272
|
*/
|
|
272
273
|
export declare function removeDisabledItems(questionnaire: Questionnaire, response: QuestionnaireResponse): QuestionnaireResponse;
|
|
273
274
|
|
|
275
|
+
export declare interface ResourceBoardLoadResult<T extends Resource = Resource> {
|
|
276
|
+
readonly items: WithId<T>[];
|
|
277
|
+
readonly total?: number;
|
|
278
|
+
}
|
|
279
|
+
|
|
274
280
|
export declare type SearchOptions = {
|
|
275
281
|
debounceMs?: number;
|
|
276
282
|
enabled?: boolean;
|
|
@@ -494,6 +500,44 @@ export declare interface UseQuestionnaireFormProps {
|
|
|
494
500
|
*/
|
|
495
501
|
export declare function useResource<T extends Resource>(value: Reference<T> | Partial<T> | undefined, setOutcome?: (outcome: OperationOutcome) => void): WithId<T> | undefined;
|
|
496
502
|
|
|
503
|
+
/**
|
|
504
|
+
* useResourceBoard manages the data layer for the ResourceBoard component:
|
|
505
|
+
* fetching the resource list, resolving the selected resource, and supporting
|
|
506
|
+
* background refresh.
|
|
507
|
+
* @param options - The data options, a subset of the ResourceBoard props.
|
|
508
|
+
* @returns The loaded resources, total, loading state, resolved selection, and refresh helper.
|
|
509
|
+
*/
|
|
510
|
+
export declare function useResourceBoard<T extends Resource = Resource>(options: UseResourceBoardProps<T>): UseResourceBoardResult<T>;
|
|
511
|
+
|
|
512
|
+
export declare interface UseResourceBoardProps<T extends Resource = Resource> {
|
|
513
|
+
readonly search: SearchRequest;
|
|
514
|
+
readonly selectedId?: string;
|
|
515
|
+
readonly loadItems?: (search: SearchRequest, medplum: MedplumClient) => Promise<ResourceBoardLoadResult<T>>;
|
|
516
|
+
readonly resolveSelected?: (id: string, items: WithId<T>[], medplum: MedplumClient) => Promise<WithId<T> | undefined>;
|
|
517
|
+
/**
|
|
518
|
+
* Manual refresh trigger: change this value (e.g. a counter) to re-run the load
|
|
519
|
+
* without changing the search. Reloads in place — no skeleton — like `refresh()`.
|
|
520
|
+
*/
|
|
521
|
+
readonly reloadKey?: unknown;
|
|
522
|
+
readonly onSelectFirst?: (item: WithId<T>) => void;
|
|
523
|
+
readonly onLoad?: (items: WithId<T>[], total: number | undefined) => void;
|
|
524
|
+
readonly onError?: (error: unknown) => void;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export declare interface UseResourceBoardResult<T extends Resource = Resource> {
|
|
528
|
+
readonly items: WithId<T>[];
|
|
529
|
+
readonly total: number | undefined;
|
|
530
|
+
readonly loading: boolean;
|
|
531
|
+
readonly selected: WithId<T> | undefined;
|
|
532
|
+
/**
|
|
533
|
+
* The search currently in effect. Tracks the input `search`, but only updates when it
|
|
534
|
+
* changes by deep equality — so this identity is stable across renders and safe to use
|
|
535
|
+
* in dependency arrays or to derive pagination from.
|
|
536
|
+
*/
|
|
537
|
+
readonly search: SearchRequest;
|
|
538
|
+
readonly refresh: () => Promise<void>;
|
|
539
|
+
}
|
|
540
|
+
|
|
497
541
|
/**
|
|
498
542
|
* React hook for searching FHIR resources.
|
|
499
543
|
*
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{useEffect as ze,useMemo as Je,useState as Ge}from"react";import{createContext as Be,useContext as je}from"react";var K=Be(void 0);function B(){return je(K)}function v(){return B().medplum}function bt(){return B().navigate}function pe(){return B().profile}import{jsx as Xe}from"react/jsx-runtime";var fe=["change","storageInitialized","storageInitFailed","profileRefreshing","profileRefreshed"];function Qt(e){let t=e.medplum,n=e.navigate??He,[o,r]=Ge({profile:t.getProfile(),loading:t.isLoading()});ze(()=>{function s(){r(a=>({...a,profile:t.getProfile(),loading:t.isLoading()}))}for(let a of fe)t.addEventListener(a,s);return()=>{for(let a of fe)t.removeEventListener(a,s)}},[t]);let i=Je(()=>({...o,medplum:t,navigate:n}),[o,t,n]);return Xe(K.Provider,{value:i,children:e.children})}function He(e){window.location.assign(e)}import{useMemo as Ye}from"react";var le=new Map,Mt=e=>Ye(()=>{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 o=n.get("Expires");if(!o||o.length>13)return e;let r=le.get(t);if(r){let s=new URLSearchParams(new URL(r).search).get("Expires");if(s&&Number.parseInt(s,10)*1e3-5e3>Date.now())return r}return le.set(t,e),e},[e]);import{useEffect as me,useRef as j,useState as Ze}from"react";function kt(e,t,n){let o=v(),{patientId:r,onPatientSyncSuccess:i,onIframeSuccess:s,onError:a}=n,[l,S]=Ze(void 0),x=j(i),b=j(s),g=j(a);return me(()=>{x.current=i,b.current=s,g.current=a},[i,s,a]),me(()=>{let h=!1;return(async()=>{try{if(r){if(await o.executeBot(e,{patientId:r}),h)return;x.current?.()}let u=await o.executeBot(t,{patientId:r});if(h)return;u.url&&(S(u.url),b.current?.(u.url))}catch(u){h||g.current?.(u)}})().catch(()=>{}),()=>{h=!0}},[o,e,t,r]),l}import{INVALID_MEDICATION_ORDER_RESPONSE as en,INVALID_MEDICATION_SEARCH_RESPONSE as nn,isResource as z,medicationOrderRequestToParameters as tn,medicationSearchParamsToParameters as rn,parametersToMedicationOrderResponse as on}from"@medplum/core";import{useCallback as he}from"react";function Wt(){let e=v(),t=he(async o=>{let r=e.fhirUrl("Medication","$drug-search"),i=rn(o),s=await e.post(r,i);if(!z(s,"Bundle"))throw new Error(nn);return(s.entry??[]).map(a=>a.resource).filter(a=>z(a,"Medication"))},[e]),n=he(async o=>{let r=e.fhirUrl("MedicationRequest","$order-medication"),i=tn(o),s=await e.post(r,i);if(!z(s,"Parameters"))throw new Error(en);return on(s)},[e]);return{searchMedications:t,orderMedication:n}}import{INVALID_MEDICATION_ORDER_SET_RESPONSE as sn,isResource as an,medicationOrderSetRequestToParameters as un,parametersToMedicationOrderSetResponse as cn}from"@medplum/core";import{useCallback as ye,useEffect as dn,useRef as Re,useState as J}from"react";function Kt(e){let t=v(),{patientId:n,planDefinitionId:o,vendorOrderSetId:r,appId:i}=e,[s,a]=J(void 0),[l,S]=J(!1),[x,b]=J(void 0),g=Re({patientId:n,planDefinitionId:o,vendorOrderSetId:r,appId:i});g.current={patientId:n,planDefinitionId:o,vendorOrderSetId:r,appId:i};let h=()=>{let c=g.current;if(!c.patientId)return;let f=!!c.planDefinitionId,d=c.vendorOrderSetId!==void 0&&c.vendorOrderSetId!==null&&c.vendorOrderSetId!=="";return!f&&!d?void 0:{patientId:c.patientId,planDefinitionId:f?c.planDefinitionId:void 0,vendorOrderSetId:d?c.vendorOrderSetId:void 0,appId:c.appId}},y=ye(async c=>{let f=t.fhirUrl("PlanDefinition","$order-set-url"),d=un(c),R=await t.post(f,d);if(!an(R,"Parameters"))throw new Error(sn);return cn(R).launchUrl},[t]),u=Re(0),p=ye(async()=>{let c=h();if(!c)return;u.current+=1;let f=u.current;S(!0),b(void 0);try{let d=await y(c);return u.current!==f?void 0:(a(d),d)}catch(d){u.current===f&&(b(d),a(void 0));return}finally{u.current===f&&S(!1)}},[y]);return dn(()=>{let c=!1,f=h();if(!f){u.current+=1,a(void 0),S(!1),b(void 0);return}u.current+=1;let d=u.current;return S(!0),b(void 0),y(f).then(R=>{c||u.current!==d||a(R)}).catch(R=>{c||u.current!==d||(b(R),a(void 0))}).finally(()=>{!c&&u.current===d&&S(!1)}),()=>{c=!0}},[y,n,o,r,i]),{url:s,loading:l,error:x,refresh:p}}import{useCallback as fn,useEffect as ln,useState as mn}from"react";import{deepEquals as ge}from"@medplum/core";import{useCallback as q,useEffect as G,useRef as A,useState as Ie}from"react";var pn=3e3;function Se(e,t,n){let o=v(),i=pe()?e:void 0,[s,a]=Ie(),[l,S]=Ie(n?.subscriptionProps),x=A(!1),b=A(void 0),g=A(void 0),h=A(void 0),y=A(t);y.current=t;let u=A(n?.onWebSocketOpen);u.current=n?.onWebSocketOpen;let p=A(n?.onWebSocketClose);p.current=n?.onWebSocketClose;let c=A(n?.onSubscriptionConnect);c.current=n?.onSubscriptionConnect;let f=A(n?.onSubscriptionDisconnect);f.current=n?.onSubscriptionDisconnect;let d=A(n?.onError);d.current=n?.onError,G(()=>{ge(n?.subscriptionProps,l)||S(n?.subscriptionProps)},[l,n]),G(()=>{b.current&&(clearTimeout(b.current),b.current=void 0);let Q=!1;return(g.current!==i||!ge(h.current,l))&&(Q=!0),Q&&g.current&&o.unsubscribeFromCriteria(g.current,h.current),g.current=i,h.current=l,Q&&i?a(o.subscribeToCriteria(i,l)):i||a(void 0),()=>{b.current=setTimeout(()=>{a(void 0),i&&o.unsubscribeFromCriteria(i,l)},pn)}},[o,i,l]);let R=q(Q=>{y.current?.(Q.payload)},[]),E=q(()=>{u.current?.()},[]),P=q(()=>{p.current?.()},[]),m=q(Q=>{c.current?.(Q.payload.subscriptionId)},[]),w=q(Q=>{f.current?.(Q.payload.subscriptionId)},[]),O=q(Q=>{d.current?.(Q.payload)},[]);G(()=>s?(x.current||(s.addEventListener("message",R),s.addEventListener("open",E),s.addEventListener("close",P),s.addEventListener("connect",m),s.addEventListener("disconnect",w),s.addEventListener("error",O),x.current=!0),()=>{x.current=!1,s.removeEventListener("message",R),s.removeEventListener("open",E),s.removeEventListener("close",P),s.removeEventListener("connect",m),s.removeEventListener("disconnect",w),s.removeEventListener("error",O)}):()=>{},[s,R,E,P,m,w,O])}function Zt(e){let t=v(),{resourceType:n,countCriteria:o,subscriptionCriteria:r}=e,[i,s]=mn(0),a=fn(l=>{t.search(n,o,{cache:l}).then(S=>s(S.total)).catch(console.error)},[t,n,o]);return ln(()=>{a("default")},[a]),Se(r,()=>{a("reload")}),i}import{resolveId as hn}from"@medplum/core";import{useEffect as yn,useMemo as xe,useState as H}from"react";function be(e){let t=e.patientParam??"subject",n=e.query,o="";if(n!=null)if(typeof n=="string")o=n;else if(n instanceof URLSearchParams){let r=Array.from(n.entries()).sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));o=JSON.stringify(r)}else if(Array.isArray(n)){let r=[...n].sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));o=JSON.stringify(r)}else{let r=Object.entries(n).filter(([,i])=>i!==void 0).sort(([i],[s])=>i.localeCompare(s));o=JSON.stringify(r)}return`${e.resourceType}:${t}:${o}`}function Rn(e){return e.map(t=>{let n=t.searches?t.searches.map(be).join(","):"";return`${t.key}:[${n}]`}).join("|")}function or(e,t){let n=v(),[o,r]=H([]),[i,s]=H(!0),[a,l]=H(),S=Rn(t),x=xe(()=>t,[S]),b=xe(()=>hn(e),[e]);return yn(()=>{if(!b)return;let g=!1,h=`Patient/${b}`,y={_count:100,_sort:"-_lastUpdated"},u=[],p=new Map,c=[];for(let d of x){let R=[];if(d.searches)for(let E of d.searches){let P=be(E),m=p.get(P);m===void 0&&(m=u.length,p.set(P,m),u.push(E)),R.push({searchIdx:m,resultKey:E.key})}c.push(R)}if(u.length===0){r(x.map(()=>({}))),s(!1);return}let f=u.map(d=>{let R=d.patientParam??"subject",E={[R]:h};if(d.query){if(typeof d.query=="string")return n.searchResources(d.resourceType,`${R}=${h}&${d.query}&_count=100&_sort=-_lastUpdated`);if(d.query instanceof URLSearchParams)d.query.forEach((P,m)=>{E[m]=P});else if(Array.isArray(d.query))for(let[P,m]of d.query)E[P]=m;else for(let[P,m]of Object.entries(d.query))m!==void 0&&(E[P]=m)}return n.searchResources(d.resourceType,{...y,...E})});return s(!0),l(void 0),Promise.allSettled(f).then(d=>{if(g)return;let R=c.map(P=>{let m={};for(let{searchIdx:w,resultKey:O}of P){let Q=d[w];m[O]=Q.status==="fulfilled"?Q.value:[]}return m});r(R),s(!1);let E=d.filter(P=>P.status==="rejected");if(E.length>0){console.error("Some patient summary searches failed:",E.map(m=>m.reason));let P=E[0].reason;l(P instanceof Error?P:new Error(String(P)))}}).catch(d=>{g||(l(d instanceof Error?d:new Error(String(d))),s(!1))}),()=>{g=!0}},[n,b,x]),{sectionData:o,loading:i,error:a}}import{isAddPharmacyResponse as gn,isOrganizationArray as In}from"@medplum/core";import{useCallback as Ee}from"react";function cr(e,t){let n=v(),o=Ee(async i=>{let s=await n.executeBot(e,i);if(!In(s))throw new Error("Invalid response from pharmacy search");return s},[n,e]),r=Ee(async i=>{let s=await n.executeBot(t,{patientId:i.patientId,pharmacy:i.pharmacy,setAsPrimary:i.setAsPrimary});if(!gn(s))throw new Error("Invalid response from add pharmacy bot");return s},[n,t]);return{searchPharmacies:o,addToFavorites:r}}import{useEffect as Sn,useRef as xn}from"react";function fr(e){let t=xn(void 0);return Sn(()=>{t.current=e}),t.current}import{getExtension as Xn}from"@medplum/core";import{useReducer as Yn,useRef as Zn}from"react";import{deepEquals as bn,isReference as ve,isResource as En,normalizeOperationOutcome as Pn}from"@medplum/core";import{useCallback as vn,useEffect as Qn,useState as Tn}from"react";function X(e,t){let n=v(),[o,r]=Tn(()=>Pe(n,e)),i=vn(s=>{bn(s,o)||r(s)},[o]);return Qn(()=>{let s=!0,a=Pe(n,e);return!a&&ve(e)?n.readReference(e).then(l=>{s&&i(l)}).catch(l=>{s&&(i(void 0),t&&t(Pn(l)))}):i(a),(()=>s=!1)},[n,e,i,t]),o}function Pe(e,t){if(t){if(En(t))return t;if(ve(t))return e.getCachedReference(t)}}import{EMPTY as Oe,HTTP_HL7_ORG as U,PropertyType as C,append as Qe,capitalize as Te,deepClone as Cn,evalFhirPathTyped as Z,getExtension as L,getReferenceString as On,getTypedPropertyValueWithoutSchema as V,normalizeErrorString as Mn,splitN as wn,toJsBoolean as An,toTypedValue as Me,typedValueToString as _n}from"@medplum/core";var T={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"},we=`${U}/fhir/StructureDefinition/questionnaire-itemControl`,kn=`${U}/fhir/StructureDefinition/questionnaire-referenceFilter`,Y=`${U}/fhir/StructureDefinition/questionnaire-referenceResource`,Un=`${U}/fhir/StructureDefinition/questionnaire-validationError`,Nn=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression`,qn=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression`,Ir=`${U}/fhir/StructureDefinition/questionnaire-signatureRequired`,$=`${U}/fhir/StructureDefinition/questionnaireresponse-signature`,Ln=`${U}/fhir/StructureDefinition/questionnaire-hidden`;function Sr(e){return e.type==="choice"||e.type==="open-choice"}function ee(e,t){return{...t,item:Ae(e.item,t.item,t)}}function Ae(e,t,n){if(!t)return t;let o=[];for(let r of t){let i=e?.find(s=>s.linkId===r.linkId);i&&!Wn(i,n)||(i?.item&&r.item?o.push({...r,item:Ae(i.item,r.item,n)}):o.push(r))}return o}function Wn(e,t){if(L(e,Ln)?.valueBoolean===!0)return!1;let o=Dn(e,t);return o!==void 0?o:Fn(e,t)}function Dn(e,t){let n=L(e,Nn);if(t&&n){let o=n.valueExpression?.expression;if(o){let r=Me(t),i=Z(o,[r],{"%resource":r});return An(i)}}}function Fn(e,t){if(!e.enableWhen)return!0;let n=e.enableBehavior??"any";for(let o of e.enableWhen){let r=_e(t?.item,o.question);if(o.operator==="exists"&&!o.answerBoolean&&!r?.length){if(n==="any")return!0;continue}let{anyMatch:i,allMatch:s}=zn(o,r,n);if(n==="any"&&i)return!0;if(n==="all"&&!s)return!1}return n!=="any"}function ne(e,t,n=t.item){for(let o of e){let r=n?.find(i=>i.linkId===o.linkId);r&&(Vn(t,o,r),o.item&&r.item&&ne(o.item,t,r.item))}}function Vn(e,t,n){try{let o=Bn(t,e);if(!o)return;let r=Kn(t,o);if(!r)return;n.answer=[r]}catch(o){n.extension=[{url:Un,valueString:`Expression evaluation failed: ${Mn(o)}`}]}}var $n={[T.boolean]:[C.boolean],[T.date]:[C.date],[T.dateTime]:[C.dateTime],[T.time]:[C.time],[T.url]:[C.string,C.uri,C.url],[T.attachment]:[C.Attachment],[T.reference]:[C.Reference],[T.quantity]:[C.Quantity],[T.decimal]:[C.decimal,C.integer],[T.integer]:[C.decimal,C.integer]};function Kn(e,t){if(!e.type)return;if(e.type===T.choice||e.type===T.openChoice)return{[`value${Te(t.type)}`]:t.value};if(e.type===T.string||e.type===T.text)return typeof t.value=="string"?{valueString:t.value}:void 0;if($n[e.type]?.includes(t.type))return{[`value${Te(e.type)}`]:t.value}}function Bn(e,t){if(!t)return;let n=L(e,qn);if(n){let o=n.valueExpression?.expression;if(o){let r=Me(t),i=Z(o,[r],{"%resource":r});return i.length!==0?i[0]:void 0}}}function xr(e,t,n){let o=[];for(let r of e){let i=n.answerOption?.find(s=>_n(Ce(s))===r);if(i){let s=Ce(i);s&&o.push({[t]:s.value})}}return o}function _e(e,t){for(let n of e??Oe){if(n.linkId===t)return n.answer;if(n.item){let o=_e(n.item,t);if(o)return o}}}function jn(e,t,n){if(n==="exists")return!!e===t.value;if(e){let o=n==="="||n==="!="?n?.replace("=","~"):n,[{value:r}]=Z(`%actualAnswer ${o} %expectedAnswer`,[e],{"%actualAnswer":e,"%expectedAnswer":t});return r}else return!1}function zn(e,t,n){let o=t||[],r=Gn(e),i=!1,s=!0;for(let a of o){let l=Hn(a),{operator:S}=e;if(jn(l,r,S)?i=!0:s=!1,n==="any"&&i)break}return{anyMatch:i,allMatch:s}}function br(e){let t=L(e,Y);if(t){if(t.valueCode!==void 0)return[t.valueCode];if(t.valueCodeableConcept)return t.valueCodeableConcept?.coding?.map(n=>n.code)}}function Er(e,t){let n=Cn(e),o=L(n,Y);return!t||t.length===0?(o&&(n.extension=n.extension?.filter(r=>r!==o)),n):(o||(n.extension??=[],o={url:Y},n.extension.push(o)),t.length===1?(o.valueCode=t[0],delete o.valueCodeableConcept):(o.valueCodeableConcept={coding:t.map(r=>({code:r}))},delete o.valueCode),n)}function Pr(e,t,n){let o=L(e,kn);if(!o?.valueString)return;let r=o.valueString;t?.reference&&(r=r.replaceAll("$subj",t.reference)),n?.reference&&(r=r.replaceAll("$encounter",n.reference));let i={},s=r.split("&");for(let a of s){let[l,S]=wn(a,"=",2);i[l]=S}return i}function te(e,t){return{resourceType:"QuestionnaireResponse",questionnaire:e.url??On(e),item:re(e.item,t?.item),status:"in-progress"}}function re(e,t){let n;for(let o of e??Oe){if(o.type===T.display)continue;let r=t?.filter(i=>i.linkId===o.linkId);if(r?.length)for(let i of r)i.id=i.id??ke(),i.text=i.text??o.text,i.item=re(o.item,i.item),i.answer=Ue(o,i),n=Qe(n,i);else n=Qe(n,oe(o))}return n}function oe(e){return{id:ke(),linkId:e.linkId,text:e.text,item:re(e.item,void 0),answer:Ue(e)}}var Jn=1;function ke(){return"id-"+Jn++}function Ue(e,t){if(!(e.type===T.display||e.type===T.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 vr(e){return V({type:"QuestionnaireItemInitial",value:e},"value")}function Ce(e){return V({type:"QuestionnaireItemAnswerOption",value:e},"value")}function Gn(e){return V({type:"QuestionnaireItemEnableWhen",value:e},"answer")}function Hn(e){return V({type:"QuestionnaireResponseItemAnswer",value:e},"value")}function wr(e){let t=X(e.questionnaire),n=X(e.defaultValue),[,o]=Yn(y=>y+1,0),r=Zn({activePage:0});if(!r.current.questionnaire&&t&&(r.current.questionnaire=t,r.current.pages=e.disablePagination?void 0:et(t)),t&&e.defaultValue&&n&&!r.current.questionnaireResponse&&(r.current.questionnaireResponse=te(t,n),h()),t&&!e.defaultValue&&!r.current.questionnaireResponse&&(r.current.questionnaireResponse=te(t),h()),!r.current.questionnaire||!r.current.questionnaireResponse)return{loading:!0};function i(y,u){let p=r.current.questionnaireResponse;for(let c of y)p=p?.item?.find(f=>c.id?f.id===c.id:f.linkId===c.linkId);return u&&(p=p?.item?.find(c=>c.linkId===u.linkId)),p}function s(){r.current.activePage=(r.current.activePage??0)+1,o()}function a(){r.current.activePage=(r.current.activePage??0)-1,o()}function l(y,u){let p=i(y);p&&(p.item??=[],p.item.push(oe(u)),h())}function S(y,u){let p=i(y,u);p&&(p.answer??=[],p.answer.push({}),h())}function x(y,u,p){let c=i(y,u);c&&(c.answer=p,h())}function b(y){let u=r.current.questionnaireResponse;u&&(y?(u.extension=u.extension??[],u.extension=u.extension.filter(p=>p.url!==$),u.extension.push({url:$,valueSignature:y})):u.extension=u.extension?.filter(p=>p.url!==$),h())}function g(){let y=r.current.questionnaire;if(y?.item){let u=r.current.questionnaireResponse;ne(y.item,u)}}function h(){let y=r.current.questionnaireResponse,u=r.current.questionnaire;!y||!u||(g(),o(),e.onChange?.(ee(u,y)))}return{loading:!1,pagination:!!r.current.pages,questionnaire:r.current.questionnaire,questionnaireResponse:ee(r.current.questionnaire,r.current.questionnaireResponse),subject:e.subject,encounter:e.encounter,activePage:r.current.activePage,pages:r.current.pages,items:nt(r.current.questionnaire,r.current.pages,r.current.activePage),responseItems:tt(r.current.questionnaireResponse,r.current.pages,r.current.activePage),onNextPage:s,onPrevPage:a,onAddGroup:l,onAddAnswer:S,onChangeAnswer:x,onChangeSignature:b}}function et(e){if(!(!e?.item||Xn(e?.item?.[0],we)?.valueCodeableConcept?.coding?.[0]?.code!=="page"))return e.item.map((n,o)=>({linkId:n.linkId,title:n.text??`Page ${o+1}`,group:n}))}function nt(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}function tt(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}import{allOk as it,normalizeOperationOutcome as st}from"@medplum/core";import{useEffect as at,useMemo as ut,useState as se}from"react";import{useCallback as rt,useEffect as Ne,useRef as ie,useState as ot}from"react";function qe(e,t,n={leading:!1}){let[o,r]=ot(e),i=ie(!1),s=ie(void 0),a=ie(!1),l=rt(()=>window.clearTimeout(s.current),[]);return Ne(()=>{i.current&&(!a.current&&n.leading?(a.current=!0,r(e),s.current=setTimeout(()=>{a.current=!1},t)):(l(),s.current=setTimeout(()=>{a.current=!1,r(e)},t)))},[e,n.leading,t,l]),Ne(()=>(i.current=!0,l),[l]),[o,l]}var ct=250;function Wr(e,t,n){return ae("search",e,t,n)}function Dr(e,t,n){return ae("searchOne",e,t,n)}function Fr(e,t,n){return ae("searchResources",e,t,n)}function ae(e,t,n,o){let r=v(),[i,s]=se(!1),[a,l]=se(),[S,x]=se(),b=r.fhirSearchUrl(t,n).toString(),g=ut(()=>({resourceType:t,query:n}),[b]),h=o?.enabled??!0,y=o?.debounceMs??ct,[u]=qe(g,y,{leading:!0});return at(()=>{if(!h)return()=>{};s(!0);let p=!0;return r[e](u.resourceType,u.query).then(c=>{p&&(s(!1),l(c),x(it))}).catch(c=>{p&&(s(!1),l(void 0),x(st(c)))}),()=>{p=!1}},[r,e,u,h]),[a,i,S]}import{OperationOutcomeError as dt}from"@medplum/core";import{useCallback as pt}from"react";function jr(){let e=v();return pt(async t=>{try{await e.post(e.fhirUrl("PlanDefinition","$sync-orderset"),{planDefinitionId:t})}catch(n){if(n instanceof dt&&n.outcome.issue?.some(o=>o.code==="not-found"))return;throw n}},[e])}import{getReferenceString as ft}from"@medplum/core";import{useCallback as lt,useEffect as Le,useState as W}from"react";function Xr({query:e,threadId:t}){let n=v(),[o,r]=W(!0),[i,s]=W([]),[a,l]=W(void 0),[S,x]=W(null),[b,g]=W(void 0),h=lt(async()=>{let p=new URLSearchParams(e);p.append("identifier:not","http://medplum.com/ai-message|"),p.append("part-of:missing","true"),p.append("_has:Communication:part-of:_id:not","null");let c=await n.search("Communication",p.toString(),{cache:"no-cache"}),f=c.entry?.map(m=>m.resource).filter(m=>m!==void 0)||[];if(c.total!==void 0&&g(c.total),f.length===0){s([]);return}let R=`
|
|
1
|
+
import{useEffect as He,useMemo as Xe,useState as Ye}from"react";import{createContext as Je,useContext as Ge}from"react";var K=Je(void 0);function j(){return Ge(K)}function P(){return j().medplum}function Ot(){return j().navigate}function me(){return j().profile}import{jsx as en}from"react/jsx-runtime";var he=["change","storageInitialized","storageInitFailed","profileRefreshing","profileRefreshed"];function _t(e){let t=e.medplum,n=e.navigate??Ze,[o,r]=Ye({profile:t.getProfile(),loading:t.isLoading()});He(()=>{function s(){r(a=>({...a,profile:t.getProfile(),loading:t.isLoading()}))}for(let a of he)t.addEventListener(a,s);return()=>{for(let a of he)t.removeEventListener(a,s)}},[t]);let i=Xe(()=>({...o,medplum:t,navigate:n}),[o,t,n]);return en(K.Provider,{value:i,children:e.children})}function Ze(e){window.location.assign(e)}import{useMemo as nn}from"react";var ye=new Map,Nt=e=>nn(()=>{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 o=n.get("Expires");if(!o||o.length>13)return e;let r=ye.get(t);if(r){let s=new URLSearchParams(new URL(r).search).get("Expires");if(s&&Number.parseInt(s,10)*1e3-5e3>Date.now())return r}return ye.set(t,e),e},[e]);import{useEffect as Re,useRef as z,useState as tn}from"react";function Dt(e,t,n){let o=P(),{patientId:r,onPatientSyncSuccess:i,onIframeSuccess:s,onError:a}=n,[f,S]=tn(void 0),E=z(i),T=z(s),g=z(a);return Re(()=>{E.current=i,T.current=s,g.current=a},[i,s,a]),Re(()=>{let h=!1;return(async()=>{try{if(r){if(await o.executeBot(e,{patientId:r}),h)return;E.current?.()}let u=await o.executeBot(t,{patientId:r});if(h)return;u.url&&(S(u.url),T.current?.(u.url))}catch(u){h||g.current?.(u)}})().catch(()=>{}),()=>{h=!0}},[o,e,t,r]),f}import{INVALID_MEDICATION_ORDER_RESPONSE as rn,INVALID_MEDICATION_SEARCH_RESPONSE as on,isResource as J,medicationOrderRequestToParameters as sn,medicationSearchParamsToParameters as an,parametersToMedicationOrderResponse as un}from"@medplum/core";import{useCallback as ge}from"react";function jt(){let e=P(),t=ge(async o=>{let r=e.fhirUrl("Medication","$drug-search"),i=an(o),s=await e.post(r,i);if(!J(s,"Bundle"))throw new Error(on);return(s.entry??[]).map(a=>a.resource).filter(a=>J(a,"Medication"))},[e]),n=ge(async o=>{let r=e.fhirUrl("MedicationRequest","$order-medication"),i=sn(o),s=await e.post(r,i);if(!J(s,"Parameters"))throw new Error(rn);return un(s)},[e]);return{searchMedications:t,orderMedication:n}}import{INVALID_MEDICATION_ORDER_SET_RESPONSE as cn,isResource as dn,medicationOrderSetRequestToParameters as pn,parametersToMedicationOrderSetResponse as fn}from"@medplum/core";import{useCallback as Ie,useEffect as ln,useRef as Se,useState as G}from"react";function Xt(e){let t=P(),{patientId:n,planDefinitionId:o,vendorOrderSetId:r,appId:i}=e,[s,a]=G(void 0),[f,S]=G(!1),[E,T]=G(void 0),g=Se({patientId:n,planDefinitionId:o,vendorOrderSetId:r,appId:i});g.current={patientId:n,planDefinitionId:o,vendorOrderSetId:r,appId:i};let h=()=>{let c=g.current;if(!c.patientId)return;let l=!!c.planDefinitionId,d=c.vendorOrderSetId!==void 0&&c.vendorOrderSetId!==null&&c.vendorOrderSetId!=="";return!l&&!d?void 0:{patientId:c.patientId,planDefinitionId:l?c.planDefinitionId:void 0,vendorOrderSetId:d?c.vendorOrderSetId:void 0,appId:c.appId}},y=Ie(async c=>{let l=t.fhirUrl("PlanDefinition","$order-set-url"),d=pn(c),R=await t.post(l,d);if(!dn(R,"Parameters"))throw new Error(cn);return fn(R).launchUrl},[t]),u=Se(0),p=Ie(async()=>{let c=h();if(!c)return;u.current+=1;let l=u.current;S(!0),T(void 0);try{let d=await y(c);return u.current!==l?void 0:(a(d),d)}catch(d){u.current===l&&(T(d),a(void 0));return}finally{u.current===l&&S(!1)}},[y]);return ln(()=>{let c=!1,l=h();if(!l){u.current+=1,a(void 0),S(!1),T(void 0);return}u.current+=1;let d=u.current;return S(!0),T(void 0),y(l).then(R=>{c||u.current!==d||a(R)}).catch(R=>{c||u.current!==d||(T(R),a(void 0))}).finally(()=>{!c&&u.current===d&&S(!1)}),()=>{c=!0}},[y,n,o,r,i]),{url:s,loading:f,error:E,refresh:p}}import{useCallback as hn,useEffect as yn,useState as Rn}from"react";import{deepEquals as xe}from"@medplum/core";import{useCallback as L,useEffect as H,useRef as A,useState as be}from"react";var mn=3e3;function Ee(e,t,n){let o=P(),i=me()?e:void 0,[s,a]=be(),[f,S]=be(n?.subscriptionProps),E=A(!1),T=A(void 0),g=A(void 0),h=A(void 0),y=A(t);y.current=t;let u=A(n?.onWebSocketOpen);u.current=n?.onWebSocketOpen;let p=A(n?.onWebSocketClose);p.current=n?.onWebSocketClose;let c=A(n?.onSubscriptionConnect);c.current=n?.onSubscriptionConnect;let l=A(n?.onSubscriptionDisconnect);l.current=n?.onSubscriptionDisconnect;let d=A(n?.onError);d.current=n?.onError,H(()=>{xe(n?.subscriptionProps,f)||S(n?.subscriptionProps)},[f,n]),H(()=>{T.current&&(clearTimeout(T.current),T.current=void 0);let v=!1;return(g.current!==i||!xe(h.current,f))&&(v=!0),v&&g.current&&o.unsubscribeFromCriteria(g.current,h.current),g.current=i,h.current=f,v&&i?a(o.subscribeToCriteria(i,f)):i||a(void 0),()=>{T.current=setTimeout(()=>{a(void 0),i&&o.unsubscribeFromCriteria(i,f)},mn)}},[o,i,f]);let R=L(v=>{y.current?.(v.payload)},[]),b=L(()=>{u.current?.()},[]),I=L(()=>{p.current?.()},[]),m=L(v=>{c.current?.(v.payload.subscriptionId)},[]),w=L(v=>{l.current?.(v.payload.subscriptionId)},[]),Q=L(v=>{d.current?.(v.payload)},[]);H(()=>s?(E.current||(s.addEventListener("message",R),s.addEventListener("open",b),s.addEventListener("close",I),s.addEventListener("connect",m),s.addEventListener("disconnect",w),s.addEventListener("error",Q),E.current=!0),()=>{E.current=!1,s.removeEventListener("message",R),s.removeEventListener("open",b),s.removeEventListener("close",I),s.removeEventListener("connect",m),s.removeEventListener("disconnect",w),s.removeEventListener("error",Q)}):()=>{},[s,R,b,I,m,w,Q])}function sr(e){let t=P(),{resourceType:n,countCriteria:o,subscriptionCriteria:r}=e,[i,s]=Rn(0),a=hn(f=>{t.search(n,o,{cache:f}).then(S=>s(S.total)).catch(console.error)},[t,n,o]);return yn(()=>{a("default")},[a]),Ee(r,()=>{a("reload")}),i}import{resolveId as gn}from"@medplum/core";import{useEffect as In,useMemo as Te,useState as X}from"react";function ve(e){let t=e.patientParam??"subject",n=e.query,o="";if(n!=null)if(typeof n=="string")o=n;else if(n instanceof URLSearchParams){let r=Array.from(n.entries()).sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));o=JSON.stringify(r)}else if(Array.isArray(n)){let r=[...n].sort((i,s)=>i[0].localeCompare(s[0])||i[1].localeCompare(s[1]));o=JSON.stringify(r)}else{let r=Object.entries(n).filter(([,i])=>i!==void 0).sort(([i],[s])=>i.localeCompare(s));o=JSON.stringify(r)}return`${e.resourceType}:${t}:${o}`}function Sn(e){return e.map(t=>{let n=t.searches?t.searches.map(ve).join(","):"";return`${t.key}:[${n}]`}).join("|")}function pr(e,t){let n=P(),[o,r]=X([]),[i,s]=X(!0),[a,f]=X(),S=Sn(t),E=Te(()=>t,[S]),T=Te(()=>gn(e),[e]);return In(()=>{if(!T)return;let g=!1,h=`Patient/${T}`,y={_count:100,_sort:"-_lastUpdated"},u=[],p=new Map,c=[];for(let d of E){let R=[];if(d.searches)for(let b of d.searches){let I=ve(b),m=p.get(I);m===void 0&&(m=u.length,p.set(I,m),u.push(b)),R.push({searchIdx:m,resultKey:b.key})}c.push(R)}if(u.length===0){r(E.map(()=>({}))),s(!1);return}let l=u.map(d=>{let R=d.patientParam??"subject",b={[R]:h};if(d.query){if(typeof d.query=="string")return n.searchResources(d.resourceType,`${R}=${h}&${d.query}&_count=100&_sort=-_lastUpdated`);if(d.query instanceof URLSearchParams)d.query.forEach((I,m)=>{b[m]=I});else if(Array.isArray(d.query))for(let[I,m]of d.query)b[I]=m;else for(let[I,m]of Object.entries(d.query))m!==void 0&&(b[I]=m)}return n.searchResources(d.resourceType,{...y,...b})});return s(!0),f(void 0),Promise.allSettled(l).then(d=>{if(g)return;let R=c.map(I=>{let m={};for(let{searchIdx:w,resultKey:Q}of I){let v=d[w];m[Q]=v.status==="fulfilled"?v.value:[]}return m});r(R),s(!1);let b=d.filter(I=>I.status==="rejected");if(b.length>0){console.error("Some patient summary searches failed:",b.map(m=>m.reason));let I=b[0].reason;f(I instanceof Error?I:new Error(String(I)))}}).catch(d=>{g||(f(d instanceof Error?d:new Error(String(d))),s(!1))}),()=>{g=!0}},[n,T,E]),{sectionData:o,loading:i,error:a}}import{isAddPharmacyResponse as xn,isOrganizationArray as bn}from"@medplum/core";import{useCallback as Pe}from"react";function yr(e,t){let n=P(),o=Pe(async i=>{let s=await n.executeBot(e,i);if(!bn(s))throw new Error("Invalid response from pharmacy search");return s},[n,e]),r=Pe(async i=>{let s=await n.executeBot(t,{patientId:i.patientId,pharmacy:i.pharmacy,setAsPrimary:i.setAsPrimary});if(!xn(s))throw new Error("Invalid response from add pharmacy bot");return s},[n,t]);return{searchPharmacies:o,addToFavorites:r}}import{useEffect as En,useRef as Tn}from"react";function Ir(e){let t=Tn(void 0);return En(()=>{t.current=e}),t.current}import{getExtension as et}from"@medplum/core";import{useReducer as nt,useRef as tt}from"react";import{deepEquals as vn,isReference as Ce,isResource as Pn,normalizeOperationOutcome as Qn}from"@medplum/core";import{useCallback as Cn,useEffect as On,useState as Mn}from"react";function Y(e,t){let n=P(),[o,r]=Mn(()=>Qe(n,e)),i=Cn(s=>{vn(s,o)||r(s)},[o]);return On(()=>{let s=!0,a=Qe(n,e);return!a&&Ce(e)?n.readReference(e).then(f=>{s&&i(f)}).catch(f=>{s&&(i(void 0),t&&t(Qn(f)))}):i(a),(()=>s=!1)},[n,e,i,t]),o}function Qe(e,t){if(t){if(Pn(t))return t;if(Ce(t))return e.getCachedReference(t)}}import{EMPTY as Ae,HTTP_HL7_ORG as U,PropertyType as O,append as Oe,capitalize as Me,deepClone as wn,evalFhirPathTyped as ee,getExtension as W,getReferenceString as An,getTypedPropertyValueWithoutSchema as $,normalizeErrorString as _n,splitN as kn,toJsBoolean as Un,toTypedValue as _e,typedValueToString as qn}from"@medplum/core";var C={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"},ke=`${U}/fhir/StructureDefinition/questionnaire-itemControl`,Nn=`${U}/fhir/StructureDefinition/questionnaire-referenceFilter`,Z=`${U}/fhir/StructureDefinition/questionnaire-referenceResource`,Ln=`${U}/fhir/StructureDefinition/questionnaire-validationError`,Wn=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-enableWhenExpression`,Fn=`${U}/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression`,Pr=`${U}/fhir/StructureDefinition/questionnaire-signatureRequired`,B=`${U}/fhir/StructureDefinition/questionnaireresponse-signature`,Dn=`${U}/fhir/StructureDefinition/questionnaire-hidden`;function Qr(e){return e.type==="choice"||e.type==="open-choice"}function ne(e,t){return{...t,item:Ue(e.item,t.item,t)}}function Ue(e,t,n){if(!t)return t;let o=[];for(let r of t){let i=e?.find(s=>s.linkId===r.linkId);i&&!Vn(i,n)||(i?.item&&r.item?o.push({...r,item:Ue(i.item,r.item,n)}):o.push(r))}return o}function Vn(e,t){if(W(e,Dn)?.valueBoolean===!0)return!1;let o=$n(e,t);return o!==void 0?o:Bn(e,t)}function $n(e,t){let n=W(e,Wn);if(t&&n){let o=n.valueExpression?.expression;if(o){let r=_e(t),i=ee(o,[r],{"%resource":r});return Un(i)}}}function Bn(e,t){if(!e.enableWhen)return!0;let n=e.enableBehavior??"any";for(let o of e.enableWhen){let r=qe(t?.item,o.question);if(o.operator==="exists"&&!o.answerBoolean&&!r?.length){if(n==="any")return!0;continue}let{anyMatch:i,allMatch:s}=Hn(o,r,n);if(n==="any"&&i)return!0;if(n==="all"&&!s)return!1}return n!=="any"}function te(e,t,n=t.item){for(let o of e){let r=n?.find(i=>i.linkId===o.linkId);r&&(Kn(t,o,r),o.item&&r.item&&te(o.item,t,r.item))}}function Kn(e,t,n){try{let o=Jn(t,e);if(!o)return;let r=zn(t,o);if(!r)return;n.answer=[r]}catch(o){n.extension=[{url:Ln,valueString:`Expression evaluation failed: ${_n(o)}`}]}}var jn={[C.boolean]:[O.boolean],[C.date]:[O.date],[C.dateTime]:[O.dateTime],[C.time]:[O.time],[C.url]:[O.string,O.uri,O.url],[C.attachment]:[O.Attachment],[C.reference]:[O.Reference],[C.quantity]:[O.Quantity],[C.decimal]:[O.decimal,O.integer],[C.integer]:[O.decimal,O.integer]};function zn(e,t){if(!e.type)return;if(e.type===C.choice||e.type===C.openChoice)return{[`value${Me(t.type)}`]:t.value};if(e.type===C.string||e.type===C.text)return typeof t.value=="string"?{valueString:t.value}:void 0;if(jn[e.type]?.includes(t.type))return{[`value${Me(e.type)}`]:t.value}}function Jn(e,t){if(!t)return;let n=W(e,Fn);if(n){let o=n.valueExpression?.expression;if(o){let r=_e(t),i=ee(o,[r],{"%resource":r});return i.length!==0?i[0]:void 0}}}function Cr(e,t,n){let o=[];for(let r of e){let i=n.answerOption?.find(s=>qn(we(s))===r);if(i){let s=we(i);s&&o.push({[t]:s.value})}}return o}function qe(e,t){for(let n of e??Ae){if(n.linkId===t)return n.answer;if(n.item){let o=qe(n.item,t);if(o)return o}}}function Gn(e,t,n){if(n==="exists")return!!e===t.value;if(e){let o=n==="="||n==="!="?n?.replace("=","~"):n,[{value:r}]=ee(`%actualAnswer ${o} %expectedAnswer`,[e],{"%actualAnswer":e,"%expectedAnswer":t});return r}else return!1}function Hn(e,t,n){let o=t||[],r=Yn(e),i=!1,s=!0;for(let a of o){let f=Zn(a),{operator:S}=e;if(Gn(f,r,S)?i=!0:s=!1,n==="any"&&i)break}return{anyMatch:i,allMatch:s}}function Or(e){let t=W(e,Z);if(t){if(t.valueCode!==void 0)return[t.valueCode];if(t.valueCodeableConcept)return t.valueCodeableConcept?.coding?.map(n=>n.code)}}function Mr(e,t){let n=wn(e),o=W(n,Z);return!t||t.length===0?(o&&(n.extension=n.extension?.filter(r=>r!==o)),n):(o||(n.extension??=[],o={url:Z},n.extension.push(o)),t.length===1?(o.valueCode=t[0],delete o.valueCodeableConcept):(o.valueCodeableConcept={coding:t.map(r=>({code:r}))},delete o.valueCode),n)}function wr(e,t,n){let o=W(e,Nn);if(!o?.valueString)return;let r=o.valueString;t?.reference&&(r=r.replaceAll("$subj",t.reference)),n?.reference&&(r=r.replaceAll("$encounter",n.reference));let i={},s=r.split("&");for(let a of s){let[f,S]=kn(a,"=",2);i[f]=S}return i}function re(e,t){return{resourceType:"QuestionnaireResponse",questionnaire:e.url??An(e),item:oe(e.item,t?.item),status:"in-progress"}}function oe(e,t){let n;for(let o of e??Ae){if(o.type===C.display)continue;let r=t?.filter(i=>i.linkId===o.linkId);if(r?.length)for(let i of r)i.id=i.id??Ne(),i.text=i.text??o.text,i.item=oe(o.item,i.item),i.answer=Le(o,i),n=Oe(n,i);else n=Oe(n,ie(o))}return n}function ie(e){return{id:Ne(),linkId:e.linkId,text:e.text,item:oe(e.item,void 0),answer:Le(e)}}var Xn=1;function Ne(){return"id-"+Xn++}function Le(e,t){if(!(e.type===C.display||e.type===C.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 Ar(e){return $({type:"QuestionnaireItemInitial",value:e},"value")}function we(e){return $({type:"QuestionnaireItemAnswerOption",value:e},"value")}function Yn(e){return $({type:"QuestionnaireItemEnableWhen",value:e},"answer")}function Zn(e){return $({type:"QuestionnaireResponseItemAnswer",value:e},"value")}function Lr(e){let t=Y(e.questionnaire),n=Y(e.defaultValue),[,o]=nt(y=>y+1,0),r=tt({activePage:0});if(!r.current.questionnaire&&t&&(r.current.questionnaire=t,r.current.pages=e.disablePagination?void 0:rt(t)),t&&e.defaultValue&&n&&!r.current.questionnaireResponse&&(r.current.questionnaireResponse=re(t,n),h()),t&&!e.defaultValue&&!r.current.questionnaireResponse&&(r.current.questionnaireResponse=re(t),h()),!r.current.questionnaire||!r.current.questionnaireResponse)return{loading:!0};function i(y,u){let p=r.current.questionnaireResponse;for(let c of y)p=p?.item?.find(l=>c.id?l.id===c.id:l.linkId===c.linkId);return u&&(p=p?.item?.find(c=>c.linkId===u.linkId)),p}function s(){r.current.activePage=(r.current.activePage??0)+1,o()}function a(){r.current.activePage=(r.current.activePage??0)-1,o()}function f(y,u){let p=i(y);p&&(p.item??=[],p.item.push(ie(u)),h())}function S(y,u){let p=i(y,u);p&&(p.answer??=[],p.answer.push({}),h())}function E(y,u,p){let c=i(y,u);c&&(c.answer=p,h())}function T(y){let u=r.current.questionnaireResponse;u&&(y?(u.extension=u.extension??[],u.extension=u.extension.filter(p=>p.url!==B),u.extension.push({url:B,valueSignature:y})):u.extension=u.extension?.filter(p=>p.url!==B),h())}function g(){let y=r.current.questionnaire;if(y?.item){let u=r.current.questionnaireResponse;te(y.item,u)}}function h(){let y=r.current.questionnaireResponse,u=r.current.questionnaire;!y||!u||(g(),o(),e.onChange?.(ne(u,y)))}return{loading:!1,pagination:!!r.current.pages,questionnaire:r.current.questionnaire,questionnaireResponse:ne(r.current.questionnaire,r.current.questionnaireResponse),subject:e.subject,encounter:e.encounter,activePage:r.current.activePage,pages:r.current.pages,items:ot(r.current.questionnaire,r.current.pages,r.current.activePage),responseItems:it(r.current.questionnaireResponse,r.current.pages,r.current.activePage),onNextPage:s,onPrevPage:a,onAddGroup:f,onAddAnswer:S,onChangeAnswer:E,onChangeSignature:T}}function rt(e){if(!(!e?.item||et(e?.item?.[0],ke)?.valueCodeableConcept?.coding?.[0]?.code!=="page"))return e.item.map((n,o)=>({linkId:n.linkId,title:n.text??`Page ${o+1}`,group:n}))}function ot(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}function it(e,t,n=0){return t&&e?.item?.[n]?[e.item[n]]:e.item??[]}import{deepEquals as st,formatSearchQuery as at}from"@medplum/core";import{useCallback as ut,useEffect as se,useRef as ae,useState as F}from"react";async function ct(e,t){let n=await t.search(e.resourceType,at({...e,total:e.total??"accurate"}),{cache:"no-cache"});return{items:n.entry?.map(r=>r.resource).filter(r=>r!==void 0)??[],total:n.total}}function $r(e){let{search:t,selectedId:n,loadItems:o,reloadKey:r}=e,i=P(),[s,a]=F(t),[f,S]=F([]),[E,T]=F(),[g,h]=F(!0),[y,u]=F(),p=ae(e),c=ae(0),l=ae(0),d=s.resourceType,R=n!==void 0&&y?.id===n?y.value:void 0;st(t,s)||(a(t),h(!0));let b=ut(async()=>{let I=++c.current;try{let m=o?await o(s,i):await ct(s,i);if(I!==c.current)return;S(m.items),T(m.total),p.current.onLoad?.(m.items,m.total),p.current.selectedId===void 0&&m.items.length>0&&p.current.onSelectFirst?.(m.items[0])}catch(m){I===c.current&&(p.current.onError??console.error)(m)}finally{I===c.current&&h(!1)}},[s,o,i]);return se(()=>{p.current=e}),se(()=>{b().catch(console.error)},[b,r]),se(()=>{let I=++l.current;if(!n)return;let m=async()=>{let Q=p.current.resolveSelected;if(Q)return Q(n,f,i);let v=f.find(N=>N.id===n);return v!==void 0?v:await i.readResource(d,n)};(async()=>{try{let Q=await m();I===l.current&&u({id:n,value:Q})}catch(Q){I===l.current&&(u({id:n,value:void 0}),(p.current.onError??console.error)(Q))}})().catch(console.error)},[n,f,i,d]),{items:f,total:E,loading:g,selected:R,search:s,refresh:b}}import{allOk as ft,normalizeOperationOutcome as lt}from"@medplum/core";import{useEffect as mt,useMemo as ht,useState as ce}from"react";import{useCallback as dt,useEffect as We,useRef as ue,useState as pt}from"react";function Fe(e,t,n={leading:!1}){let[o,r]=pt(e),i=ue(!1),s=ue(void 0),a=ue(!1),f=dt(()=>window.clearTimeout(s.current),[]);return We(()=>{i.current&&(!a.current&&n.leading?(a.current=!0,r(e),s.current=setTimeout(()=>{a.current=!1},t)):(f(),s.current=setTimeout(()=>{a.current=!1,r(e)},t)))},[e,n.leading,t,f]),We(()=>(i.current=!0,f),[f]),[o,f]}var yt=250;function Xr(e,t,n){return de("search",e,t,n)}function Yr(e,t,n){return de("searchOne",e,t,n)}function Zr(e,t,n){return de("searchResources",e,t,n)}function de(e,t,n,o){let r=P(),[i,s]=ce(!1),[a,f]=ce(),[S,E]=ce(),T=r.fhirSearchUrl(t,n).toString(),g=ht(()=>({resourceType:t,query:n}),[T]),h=o?.enabled??!0,y=o?.debounceMs??yt,[u]=Fe(g,y,{leading:!0});return mt(()=>{if(!h)return()=>{};s(!0);let p=!0;return r[e](u.resourceType,u.query).then(c=>{p&&(s(!1),f(c),E(ft))}).catch(c=>{p&&(s(!1),f(void 0),E(lt(c)))}),()=>{p=!1}},[r,e,u,h]),[a,i,S]}import{OperationOutcomeError as Rt}from"@medplum/core";import{useCallback as gt}from"react";function oo(){let e=P();return gt(async t=>{try{await e.post(e.fhirUrl("PlanDefinition","$sync-orderset"),{planDefinitionId:t})}catch(n){if(n instanceof Rt&&n.outcome.issue?.some(o=>o.code==="not-found"))return;throw n}},[e])}import{getReferenceString as It}from"@medplum/core";import{useCallback as St,useEffect as De,useState as D}from"react";function co({query:e,threadId:t}){let n=P(),[o,r]=D(!0),[i,s]=D([]),[a,f]=D(void 0),[S,E]=D(null),[T,g]=D(void 0),h=St(async()=>{let p=new URLSearchParams(e);p.append("identifier:not","http://medplum.com/ai-message|"),p.append("part-of:missing","true"),p.append("_has:Communication:part-of:_id:not","null");let c=await n.search("Communication",p.toString(),{cache:"no-cache"}),l=c.entry?.map(m=>m.resource).filter(m=>m!==void 0)||[];if(c.total!==void 0&&g(c.total),l.length===0){s([]);return}let R=`
|
|
2
2
|
query {
|
|
3
|
-
${
|
|
4
|
-
${
|
|
5
|
-
part_of: "${
|
|
3
|
+
${l.map(m=>{let Q=`thread_${m.id?.replaceAll("-","")||""}`,v=It(m);return`
|
|
4
|
+
${Q}: CommunicationList(
|
|
5
|
+
part_of: "${v}"
|
|
6
6
|
_sort: "-sent"
|
|
7
7
|
_count: 1
|
|
8
8
|
) {
|
|
@@ -26,7 +26,7 @@ import{useEffect as ze,useMemo as Je,useState as Ge}from"react";import{createCon
|
|
|
26
26
|
`}).join(`
|
|
27
27
|
`)}
|
|
28
28
|
}
|
|
29
|
-
`,
|
|
29
|
+
`,b=await n.graphql(R),I=l.map(m=>{let Q=`thread_${m.id?.replaceAll("-","")||""}`,v=b.data[Q],N=v&&v.length>0?v[0]:void 0;return[m,N]}).filter(m=>m[1]!==void 0);s(I)},[n,e]);return De(()=>{r(!0),h().catch(p=>{E(p)}).finally(()=>{r(!1)})},[h]),De(()=>{(async()=>{if(!t){f(void 0);return}let c=i.find(d=>d[0].id===t);if(c){f(c[0]);return}let l=await n.readResource("Communication",t);if(l.partOf===void 0)f(l);else{let d=l.partOf[0].reference;if(d){let R=await n.readReference({reference:d});f(R)}}})().catch(c=>{E(c)})},[t,i,n]),{loading:o,error:S,threadMessages:i,selectedThread:a,total:T,addThreadMessage:p=>{(async()=>{await h(),s(l=>[[p,void 0],...l])})().catch(l=>E(l))},handleThreadStatusChange:p=>{if(!a)return;(async()=>{let l=await n.updateResource({...a,status:p});f(l),s(d=>d.map(([R,b])=>R.id===l.id?[l,b]:[R,b]))})().catch(l=>E(l))},refreshThreadMessages:h}}import{ReconnectingWebSocket as xt,sleep as bt}from"@medplum/core";import{useCallback as _,useEffect as pe,useRef as q,useState as fe}from"react";var Et=12e4;function ho({language:e="en",model:t="gpt-4o-transcribe",onTranscript:n,idleTimeoutMs:o=Et}){let r=P(),i=q(n);pe(()=>{i.current=n},[n]);let[s,a]=fe("idle"),[f,S]=fe(void 0),[E,T]=fe([]),g=q(void 0),h=q(void 0),y=q(void 0),u=q(void 0),p=q(!1),c=q(!1),l=q(!1),d=_(()=>{l.current=!1,u.current?.disconnect(),u.current=void 0,y.current?.close().catch(()=>{}),y.current=void 0,h.current?.getTracks().forEach(x=>x.stop()),h.current=void 0,a(g.current?"idle":"disconnected")},[]),R=_(()=>{d(),g.current?.close(),g.current=void 0,c.current=!1,a("disconnected")},[d]),b=_(()=>{g.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]),I=_(async()=>{if(!(u.current||p.current)&&!(!h.current||!g.current)){p.current=!0;try{let x=new AudioContext({sampleRate:24e3});await x.audioWorklet.addModule(Qt());let M=h.current,k=g.current;if(!l.current||!M||!k){await x.close().catch(()=>{});return}let Be=x.createMediaStreamSource(M),V=new AudioWorkletNode(x,Ve);V.port.onmessage=Ke=>{if(k.readyState!==WebSocket.OPEN){console.warn("WebSocket is not open. Unable to send audio data.");return}let je=Tt(Ke.data),ze=btoa(String.fromCharCode(...je));k.send(JSON.stringify({type:"input_audio_buffer.append",audio:ze}))},Be.connect(V),V.connect(x.destination),y.current=x,u.current=V,a("listening")}catch(x){S(x),a("error"),d()}finally{p.current=!1}}},[d]),m=_(()=>{l.current&&c.current&&h.current&&(u.current||(g.current?.send(JSON.stringify({type:"input_audio_buffer.clear"})),I().catch(()=>{})))},[I]),w=_(x=>{switch(x.type){case"session.created":b();break;case"session.updated":c.current=!0,m();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 M={text:x.transcript,timestamp:new Date().toISOString()};T(k=>[...k,M]),i.current?.(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),S(x),a("error");break;default:console.debug("[useWhisper] unhandled message",x.type,x);break}},[b,m]),Q=_(async()=>{a("requesting_microphone");let x=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:24e3,channelCount:1,echoCancellation:!0,noiseSuppression:!0}});return h.current=x,x},[]),v=_(()=>{a("connecting");let x=vt(r.getBaseUrl());console.debug("[useWhisper] connecting to",x);let M=new xt(x);return g.current=M,M.onopen=()=>{c.current=!1,l.current?a("connected"):a("idle"),M.send(JSON.stringify({type:"ai-realtime:connect",accessToken:r.getAccessToken()}))},M.onmessage=k=>w(JSON.parse(k.data)),M.onerror=k=>{l.current&&(S(k),R(),a("error"))},M.onclose=()=>{c.current=!1,g.current&&a(l.current?"connecting":"idle")},M},[r,w,R]),N=_(()=>g.current??v(),[v]),$e=_(async()=>{try{S(void 0),l.current=!0,N(),await Q(),m()}catch(x){S(x),a("error"),d()}},[Q,N,d,m]);return pe(()=>{if(s!=="idle"||!g.current||!Number.isFinite(o)||o<=0)return;let x=new AbortController;return bt(o,{signal:x.signal}).then(()=>R()).catch(()=>{}),()=>x.abort()},[s,o,R]),pe(()=>()=>R(),[R]),{status:s,error:f,transcripts:E,start:$e,stop:d,isListening:s==="listening"||s==="speech_started"||s==="speech_stopped"}}function Tt(e){let t=new Int16Array(e.length);for(let n=0;n<e.length;n++){let o=Math.max(-1,Math.min(1,e[n]));t[n]=o*32767}return new Uint8Array(t.buffer)}function vt(e){let t=new URL("ws/ai-realtime",e);return t.protocol=t.protocol==="https:"?"wss:":"ws:",t.toString()}var Ve="medplum-pcm-worklet",Pt=`
|
|
30
30
|
class PcmWorkletProcessor extends AudioWorkletProcessor {
|
|
31
31
|
constructor() {
|
|
32
32
|
super();
|
|
@@ -58,6 +58,6 @@ class PcmWorkletProcessor extends AudioWorkletProcessor {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
registerProcessor('${
|
|
62
|
-
`,
|
|
61
|
+
registerProcessor('${Ve}', PcmWorkletProcessor);
|
|
62
|
+
`,le;function Qt(){if(!le){let e=new Blob([Pt],{type:"application/javascript"});le=URL.createObjectURL(e)}return le}export{_t as MedplumProvider,Fn as QUESTIONNAIRE_CALCULATED_EXPRESSION_URL,Wn as QUESTIONNAIRE_ENABLED_WHEN_EXPRESSION_URL,Dn as QUESTIONNAIRE_HIDDEN_URL,ke as QUESTIONNAIRE_ITEM_CONTROL_URL,Nn as QUESTIONNAIRE_REFERENCE_FILTER_URL,Z as QUESTIONNAIRE_REFERENCE_RESOURCE_URL,Pr as QUESTIONNAIRE_SIGNATURE_REQUIRED_URL,B as QUESTIONNAIRE_SIGNATURE_RESPONSE_URL,Ln as QUESTIONNAIRE_VALIDATION_ERROR_URL,C as QuestionnaireItemType,re as buildInitialResponse,ie as buildInitialResponseItem,Tt as convertToPCM16,te as evaluateCalculatedExpressionsInQuestionnaire,we as getItemAnswerOptionValue,Yn as getItemEnableWhenValueAnswer,Ar as getItemInitialValue,Cr as getNewMultiSelectValues,wr as getQuestionnaireItemReferenceFilter,Or as getQuestionnaireItemReferenceTargetTypes,Zn as getResponseItemAnswerValue,Qr as isChoiceQuestion,Vn as isQuestionEnabled,K as reactContext,ne as removeDisabledItems,Mr as setQuestionnaireItemReferenceTargetTypes,zn as typedValueToResponseItem,Nt as useCachedBinaryUrl,Dt as useMedicationIFrame,jt as useMedicationOrder,Xt as useMedicationOrderSet,P as useMedplum,j as useMedplumContext,Ot as useMedplumNavigate,me as useMedplumProfile,sr as useNotificationCount,pr as usePatientSummaryData,yr as usePharmacySearch,Ir as usePrevious,Lr as useQuestionnaireForm,Y as useResource,$r as useResourceBoard,Xr as useSearch,Yr as useSearchOne,Zr as useSearchResources,Ee as useSubscription,oo as useSyncOrderSet,co as useThreadInbox,ho as useWhisper};
|
|
63
63
|
//# sourceMappingURL=index.mjs.map
|