@ovok/core 0.3.18 → 0.3.20

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.
@@ -0,0 +1,7 @@
1
+ import { ValidationError } from "../../types/ValidationError";
2
+ export type ParsedOvokError = {
3
+ message: string;
4
+ fieldErrors: ValidationError[];
5
+ };
6
+ /** Normalizes Ovok's Nest and FHIR error envelopes without exposing transport details. */
7
+ export declare const parseOvokError: (error: unknown) => ParsedOvokError;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseOvokError = void 0;
4
+ const isValidationError = (value) => !!value &&
5
+ typeof value === "object" &&
6
+ typeof value.code === "string" &&
7
+ typeof value.message === "string" &&
8
+ Array.isArray(value.path);
9
+ const asRecord = (value) => value && typeof value === "object" ? value : undefined;
10
+ /** Normalizes Ovok's Nest and FHIR error envelopes without exposing transport details. */
11
+ const parseOvokError = (error) => {
12
+ var _a, _b;
13
+ const parsed = typeof error === "string"
14
+ ? (() => {
15
+ try {
16
+ return JSON.parse(error);
17
+ }
18
+ catch (_a) {
19
+ return undefined;
20
+ }
21
+ })()
22
+ : error;
23
+ const root = (_a = asRecord(parsed)) !== null && _a !== void 0 ? _a : {};
24
+ const nested = (_b = asRecord(root.error)) !== null && _b !== void 0 ? _b : root;
25
+ const rawErrors = nested.errors;
26
+ const fieldErrors = Array.isArray(rawErrors) ? rawErrors.filter(isValidationError) : [];
27
+ return {
28
+ message: (typeof nested.message === "string" && nested.message) ||
29
+ (typeof root.message === "string" && root.message) ||
30
+ (error instanceof Error ? error.message : String(error)),
31
+ fieldErrors,
32
+ };
33
+ };
34
+ exports.parseOvokError = parseOvokError;
@@ -189,10 +189,12 @@ const firstValue = (observations, code) => observations.find((observation) => co
189
189
  : undefined;
190
190
  const baseMeasurement = (measurementTypeKey, observation) => ({
191
191
  measurementTypeKey,
192
+ ...(observation.id ? { id: observation.id } : {}),
193
+ ...(observation.device ? { device: observation.device } : {}),
192
194
  ...(recordedAtOf(observation) ? { recordedAt: recordedAtOf(observation) } : {}),
193
195
  });
194
196
  const inverseGroup = (type, observations) => {
195
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
197
+ var _a, _b, _c, _d, _e, _f, _g;
196
198
  const first = [...observations].sort((left, right) => {
197
199
  var _a, _b, _c, _d;
198
200
  return ((_b = (_a = recordedAtOf(left)) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : Number.MAX_SAFE_INTEGER) -
@@ -278,14 +280,18 @@ const inverseGroup = (type, observations) => {
278
280
  : [];
279
281
  });
280
282
  const diagnosticResult = (_d = (_c = first.interpretation) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d.text;
281
- const duration = (_g = (_f = (_e = first.component) === null || _e === void 0 ? void 0 : _e.find((component) => component.id === "measurement-duration")) === null || _f === void 0 ? void 0 : _f.valueQuantity) === null || _g === void 0 ? void 0 : _g.value;
283
+ const duration = observations.reduce((total, observation) => {
284
+ var _a, _b, _c, _d;
285
+ return total +
286
+ ((_d = (_c = (_b = (_a = observation.component) === null || _a === void 0 ? void 0 : _a.find((component) => component.id === "measurement-duration")) === null || _b === void 0 ? void 0 : _b.valueQuantity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 0);
287
+ }, 0);
282
288
  return {
283
289
  ...measurement,
284
290
  measurementTypeKey: type,
285
291
  diagramPoints: points,
286
- heartRate: (_h = value(types_1.ObservationCode.ECG_HEART_RATE)) !== null && _h !== void 0 ? _h : value(types_1.ObservationCode.HEART_RATE),
292
+ heartRate: (_e = value(types_1.ObservationCode.ECG_HEART_RATE)) !== null && _e !== void 0 ? _e : value(types_1.ObservationCode.HEART_RATE),
287
293
  ...(diagnosticResult ? { diagnosticResult } : {}),
288
- ...(typeof duration === "number" ? { duration } : {}),
294
+ ...(duration > 0 ? { duration } : {}),
289
295
  };
290
296
  }
291
297
  case types_1.MeasurementTypeKey.urineAnalysis:
@@ -298,7 +304,7 @@ const inverseGroup = (type, observations) => {
298
304
  };
299
305
  for (const observation of observations) {
300
306
  const analyteCode = codeOf(observation);
301
- const component = (_k = (_j = first.code) === null || _j === void 0 ? void 0 : _j.coding) === null || _k === void 0 ? void 0 : _k.find((coding) => coding.code === analyteCode);
307
+ const component = (_g = (_f = first.code) === null || _f === void 0 ? void 0 : _f.coding) === null || _g === void 0 ? void 0 : _g.find((coding) => coding.code === analyteCode);
302
308
  const value = valueOf(observation);
303
309
  const key = analyteByCode[analyteCode !== null && analyteCode !== void 0 ? analyteCode : ""];
304
310
  if (key && typeof value === "number") {
@@ -1,4 +1,8 @@
1
+ import { Reference } from "@medplum/fhirtypes";
1
2
  import { MeasurementTypeKey } from "../MeasurementTypeKey";
2
3
  export type Measurement = {
3
4
  measurementTypeKey: MeasurementTypeKey;
5
+ id?: string;
6
+ device?: Reference;
7
+ recordedAt?: Date;
4
8
  };
@@ -1,6 +1,6 @@
1
1
  import { IClientStorage } from "@medplum/core";
2
2
  import { Bundle, BundleEntry, Observation } from "@medplum/fhirtypes";
3
- declare const DEFAULT_STORAGE_KEY = "@ovok/core/offline-measurements";
3
+ declare const DEFAULT_STORAGE_KEY = "ovok.core.offline-measurements";
4
4
  declare const IDENTIFIER_SYSTEM = "https://api.ovok.com/fhir/StructureDefinition/offline-measurement-id";
5
5
  export type OfflineMeasurementQueueOptions = {
6
6
  enabled?: boolean;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.stableMeasurementId = exports.entryForObservation = exports.OFFLINE_MEASUREMENT_IDENTIFIER_SYSTEM = exports.DEFAULT_OFFLINE_MEASUREMENT_QUEUE_KEY = exports.OfflineMeasurementQueue = void 0;
4
- const DEFAULT_STORAGE_KEY = "@ovok/core/offline-measurements";
4
+ const DEFAULT_STORAGE_KEY = "ovok.core.offline-measurements";
5
5
  exports.DEFAULT_OFFLINE_MEASUREMENT_QUEUE_KEY = DEFAULT_STORAGE_KEY;
6
6
  const DEFAULT_MAX_RETRIES = 8;
7
7
  const DEFAULT_RETRY_BACKOFF_MS = 5000;
@@ -121,6 +121,9 @@ class OfflineMeasurementQueue {
121
121
  };
122
122
  this.writeQueue = (queue) => {
123
123
  this.storage.setObject(this.storageKey, queue);
124
+ if (!Array.isArray(this.storage.getObject(this.storageKey))) {
125
+ throw new Error(`Offline measurement queue could not be persisted at storage key "${this.storageKey}".`);
126
+ }
124
127
  };
125
128
  this.flushQueue = async (queue, options = {}) => {
126
129
  const result = {
@@ -11,6 +11,7 @@ import * as observationMethods from "./observation/methods";
11
11
  import { GenerateObservationBodyParams } from "./observation/types/generate-observation-body/GenerateObservationBodyParams";
12
12
  import { OfflineMeasurementFlushOptions, OfflineMeasurementFlushResult, OfflineMeasurementQueueOptions } from "./offline";
13
13
  import * as patientMethods from "./patient/methods";
14
+ import * as patientSharingMethods from "./patient-sharing/methods";
14
15
  import * as platformMethods from "./platform/methods";
15
16
  import * as questionnaireResponseMethods from "./questionnaire-response/methods";
16
17
  export declare const MAX_CONDITIONAL_OBSERVATION_ENTRIES = 8;
@@ -58,7 +59,7 @@ export declare class OvokClient extends MedplumClient {
58
59
  */
59
60
  getSubscriptionManager(): SubscriptionManager;
60
61
  }
61
- type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof carehubMethods & typeof platformMethods & typeof experienceMethods & typeof patientMethods;
62
+ type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof carehubMethods & typeof platformMethods & typeof experienceMethods & typeof patientMethods & typeof patientSharingMethods;
62
63
  type Omitted<T> = Omit<T, "executeBot">;
63
64
  declare module "./ovok-client" {
64
65
  interface OvokClient extends Omitted<Methods> {
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.OvokClient = exports.MAX_OBSERVATION_BUNDLE_BYTES = exports.MAX_CONDITIONAL_OBSERVATION_ENTRIES = void 0;
37
- /* eslint-disable @typescript-eslint/no-unsafe-function-type */ // TODO: fix this whenever find time
37
+ /* eslint-disable @typescript-eslint/no-unsafe-function-type, max-lines */ // TODO: fix this whenever find time
38
38
  const core_1 = require("@medplum/core");
39
39
  const capability_1 = require("../conformance/capability");
40
40
  const aiFhirMethods = __importStar(require("./ai-fhir/methods"));
@@ -48,6 +48,7 @@ const observationMethods = __importStar(require("./observation/methods"));
48
48
  const observation_bundle_utils_1 = require("./observation/observation-bundle-utils");
49
49
  const offline_1 = require("./offline");
50
50
  const patientMethods = __importStar(require("./patient/methods"));
51
+ const patientSharingMethods = __importStar(require("./patient-sharing/methods"));
51
52
  const platformMethods = __importStar(require("./platform/methods"));
52
53
  const questionnaireResponseMethods = __importStar(require("./questionnaire-response/methods"));
53
54
  exports.MAX_CONDITIONAL_OBSERVATION_ENTRIES = 8;
@@ -73,6 +74,7 @@ class OvokClient extends core_1.MedplumClient {
73
74
  this.bindMethods(platformMethods);
74
75
  this.bindMethods(experienceMethods);
75
76
  this.bindMethods(patientMethods);
77
+ this.bindMethods(patientSharingMethods);
76
78
  this.clientStorage = config.storage;
77
79
  this.offlineQueueOptions = (_b = config.offlineQueue) !== null && _b !== void 0 ? _b : {};
78
80
  }
@@ -0,0 +1,2 @@
1
+ export * from "./methods";
2
+ export * from "./types";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./methods"), exports);
18
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,8 @@
1
+ import { OvokClient } from "../ovok-client";
2
+ import { CreatePatientSharingInvite, PatientSharingInvite, PatientSharingSettings, PatientSharingShare, PatientSharingShares, RedeemPatientSharingInvite } from "./types";
3
+ export declare function createPatientSharingInvite(this: OvokClient, body: CreatePatientSharingInvite): Promise<PatientSharingInvite>;
4
+ export declare function redeemPatientSharingInvite(this: OvokClient, body: RedeemPatientSharingInvite): Promise<PatientSharingShare>;
5
+ export declare function listPatientSharing(this: OvokClient): Promise<PatientSharingShares>;
6
+ export declare function revokePatientSharing(this: OvokClient, consentId: string): Promise<void>;
7
+ export declare function getPatientSharingSettings(this: OvokClient): Promise<PatientSharingSettings>;
8
+ export declare function updatePatientSharingSettings(this: OvokClient, settings: PatientSharingSettings): Promise<PatientSharingSettings>;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createPatientSharingInvite = createPatientSharingInvite;
4
+ exports.redeemPatientSharingInvite = redeemPatientSharingInvite;
5
+ exports.listPatientSharing = listPatientSharing;
6
+ exports.revokePatientSharing = revokePatientSharing;
7
+ exports.getPatientSharingSettings = getPatientSharingSettings;
8
+ exports.updatePatientSharingSettings = updatePatientSharingSettings;
9
+ const segment = (value) => encodeURIComponent(value);
10
+ function createPatientSharingInvite(body) {
11
+ return this.post("/v1/patient-sharing/invites", body);
12
+ }
13
+ function redeemPatientSharingInvite(body) {
14
+ return this.post("/v1/patient-sharing/invites/redeem", body);
15
+ }
16
+ function listPatientSharing() {
17
+ return this.get("/v1/patient-sharing/shares");
18
+ }
19
+ async function revokePatientSharing(consentId) {
20
+ await this.delete(`/v1/patient-sharing/shares/${segment(consentId)}`);
21
+ }
22
+ function getPatientSharingSettings() {
23
+ return this.get("/v1/patient-sharing/settings");
24
+ }
25
+ function updatePatientSharingSettings(settings) {
26
+ return this.put("/v1/patient-sharing/settings", settings);
27
+ }
@@ -0,0 +1,22 @@
1
+ export type PatientSharingInvite = {
2
+ inviteId: string;
3
+ code: string;
4
+ expiresAt: string;
5
+ };
6
+ export type PatientSharingShare = {
7
+ consentId: string;
8
+ [key: string]: unknown;
9
+ };
10
+ export type PatientSharingShares = {
11
+ outgoing: PatientSharingShare[];
12
+ incoming: PatientSharingShare[];
13
+ };
14
+ export type CreatePatientSharingInvite = {
15
+ codes: string[];
16
+ endsAt: string;
17
+ };
18
+ export type RedeemPatientSharingInvite = {
19
+ inviteId: string;
20
+ code: string;
21
+ };
22
+ export type PatientSharingSettings = Record<string, unknown>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import { IClientStorage } from "@medplum/core";
2
+ export type AsyncKeyValueStore = {
3
+ getItem(key: string): Promise<string | null>;
4
+ setItem(key: string, value: string): Promise<void>;
5
+ removeItem(key: string): Promise<void>;
6
+ };
7
+ /** Bridges an async keychain-like store to Medplum's synchronous storage contract. */
8
+ export declare const createClientStorage: (store: AsyncKeyValueStore, keys?: readonly string[]) => IClientStorage & {
9
+ reload(): Promise<void>;
10
+ failed?: Error;
11
+ };
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createClientStorage = void 0;
4
+ /** Bridges an async keychain-like store to Medplum's synchronous storage contract. */
5
+ const createClientStorage = (store, keys = []) => {
6
+ const cache = new Map();
7
+ let failed;
8
+ let writes = Promise.resolve();
9
+ const reload = async () => {
10
+ try {
11
+ const values = await Promise.all(keys.map(async (key) => [key, await store.getItem(key)]));
12
+ cache.clear();
13
+ values.forEach(([key, value]) => {
14
+ if (value !== null) {
15
+ cache.set(key, value);
16
+ }
17
+ });
18
+ failed = undefined;
19
+ }
20
+ catch (error) {
21
+ failed = error instanceof Error ? error : new Error(String(error));
22
+ throw failed;
23
+ }
24
+ };
25
+ const persist = (operation) => {
26
+ writes = writes.then(operation, operation).catch((error) => {
27
+ failed = error instanceof Error ? error : new Error(String(error));
28
+ });
29
+ };
30
+ const storage = {
31
+ clear: () => {
32
+ cache.clear();
33
+ keys.forEach((key) => persist(() => store.removeItem(key)));
34
+ },
35
+ getInitPromise: reload,
36
+ reload,
37
+ getString: (key) => cache.get(key),
38
+ setString: (key, value) => {
39
+ if (value === undefined) {
40
+ cache.delete(key);
41
+ persist(() => store.removeItem(key));
42
+ }
43
+ else {
44
+ cache.set(key, value);
45
+ persist(() => store.setItem(key, value));
46
+ }
47
+ },
48
+ getObject: (key) => {
49
+ const value = cache.get(key);
50
+ if (value === undefined) {
51
+ return undefined;
52
+ }
53
+ try {
54
+ return JSON.parse(value);
55
+ }
56
+ catch (_a) {
57
+ return undefined;
58
+ }
59
+ },
60
+ setObject: (key, value) => {
61
+ const serialized = JSON.stringify(value);
62
+ cache.set(key, serialized);
63
+ persist(() => store.setItem(key, serialized));
64
+ },
65
+ makeKey: (key) => key,
66
+ };
67
+ Object.defineProperty(storage, "failed", { get: () => failed, enumerable: true });
68
+ return storage;
69
+ };
70
+ exports.createClientStorage = createClientStorage;
@@ -48,7 +48,7 @@ exports.OVOK_CORE_REQUIREMENTS = {
48
48
  description: "The FHIR surface a server must provide for the @ovok/core client library's own methods to function.",
49
49
  software: {
50
50
  name: "@ovok/core",
51
- version: "0.3.18",
51
+ version: "0.3.20",
52
52
  },
53
53
  fhirVersion: "4.0.1",
54
54
  format: ["json"],
@@ -10,3 +10,4 @@ export { useAdministeredProjects, useCarehubDeviceTelemetry, useCarehubDevices,
10
10
  export { useConsentSignature, useContent, useCreateVideoCallAppointment, useCreateVideoCallUserAccess, useDocuments, useVideoCallAccess, useVideoCallAppointments, } from "./experience-hooks";
11
11
  export { useI18nextDocument, useLocales, useLocalizations, useUpdateI18nextDocument, useUpdateLocalization, } from "./platform-hooks";
12
12
  export { useCurrentPatientProfile, useExtractQuestionnaireObservations, usePatientAppointments, usePatientCarePlans, usePatientDevices, usePatientDeviceTelemetry, usePatientDeviceTelemetryHistory, usePatientMeasurement, usePatientMeasurementHistory, usePatientDashboard, usePatientLatestObservations, usePatientNotifications, usePatientQuestionnaireResponses, usePatientQuestionnaires, usePatientSchedules, usePatientSlots, usePopulateQuestionnaire, useSubmitQuestionnaireResponse, } from "./patient-hooks";
13
+ export { useCreatePatientSharingInvite, usePatientSharing, usePatientSharingSettings, useRedeemPatientSharingInvite, useRevokePatientSharing, useUpdatePatientSharingSettings, } from "./patient-sharing-hooks";
@@ -35,7 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.usePatientMeasurement = exports.usePatientDeviceTelemetryHistory = exports.usePatientDeviceTelemetry = exports.usePatientDevices = exports.usePatientCarePlans = exports.usePatientAppointments = exports.useExtractQuestionnaireObservations = exports.useCurrentPatientProfile = exports.useUpdateLocalization = exports.useUpdateI18nextDocument = exports.useLocalizations = exports.useLocales = exports.useI18nextDocument = exports.useVideoCallAppointments = exports.useVideoCallAccess = exports.useDocuments = exports.useCreateVideoCallUserAccess = exports.useCreateVideoCallAppointment = exports.useContent = exports.useConsentSignature = exports.useRecentCarehubNotifications = exports.usePublicApiEndpoints = exports.useProjectSettings = exports.useProjectFeatures = exports.useOvokRequest = exports.useOvokMutation = exports.useCapabilityStatement = exports.useCarehubPatients = exports.useCarehubNotifications = exports.useCarehubDevices = exports.useCarehubDeviceTelemetry = exports.useAdministeredProjects = exports.useUrineTests = exports.useSaveMeasurement = exports.useObservations = exports.useEcgRecording = exports.observationsToMeasurements = exports.OvokProvider = exports.useClient = exports.useCachedBinaryUrl = exports.reactContext = exports.useSubscription = exports.useSearchResources = exports.useSearchOne = exports.useSearch = exports.useResource = exports.usePrevious = exports.useMedplumProfile = exports.useMedplumNavigate = exports.useMedplumContext = void 0;
38
- exports.useSubmitQuestionnaireResponse = exports.usePopulateQuestionnaire = exports.usePatientSlots = exports.usePatientSchedules = exports.usePatientQuestionnaires = exports.usePatientQuestionnaireResponses = exports.usePatientNotifications = exports.usePatientLatestObservations = exports.usePatientDashboard = exports.usePatientMeasurementHistory = void 0;
38
+ exports.useUpdatePatientSharingSettings = exports.useRevokePatientSharing = exports.useRedeemPatientSharingInvite = exports.usePatientSharingSettings = exports.usePatientSharing = exports.useCreatePatientSharingInvite = exports.useSubmitQuestionnaireResponse = exports.usePopulateQuestionnaire = exports.usePatientSlots = exports.usePatientSchedules = exports.usePatientQuestionnaires = exports.usePatientQuestionnaireResponses = exports.usePatientNotifications = exports.usePatientLatestObservations = exports.usePatientDashboard = exports.usePatientMeasurementHistory = void 0;
39
39
  /*
40
40
  * The only React-dependent module in the package.
41
41
  *
@@ -123,3 +123,10 @@ Object.defineProperty(exports, "usePatientSchedules", { enumerable: true, get: f
123
123
  Object.defineProperty(exports, "usePatientSlots", { enumerable: true, get: function () { return patient_hooks_1.usePatientSlots; } });
124
124
  Object.defineProperty(exports, "usePopulateQuestionnaire", { enumerable: true, get: function () { return patient_hooks_1.usePopulateQuestionnaire; } });
125
125
  Object.defineProperty(exports, "useSubmitQuestionnaireResponse", { enumerable: true, get: function () { return patient_hooks_1.useSubmitQuestionnaireResponse; } });
126
+ var patient_sharing_hooks_1 = require("./patient-sharing-hooks");
127
+ Object.defineProperty(exports, "useCreatePatientSharingInvite", { enumerable: true, get: function () { return patient_sharing_hooks_1.useCreatePatientSharingInvite; } });
128
+ Object.defineProperty(exports, "usePatientSharing", { enumerable: true, get: function () { return patient_sharing_hooks_1.usePatientSharing; } });
129
+ Object.defineProperty(exports, "usePatientSharingSettings", { enumerable: true, get: function () { return patient_sharing_hooks_1.usePatientSharingSettings; } });
130
+ Object.defineProperty(exports, "useRedeemPatientSharingInvite", { enumerable: true, get: function () { return patient_sharing_hooks_1.useRedeemPatientSharingInvite; } });
131
+ Object.defineProperty(exports, "useRevokePatientSharing", { enumerable: true, get: function () { return patient_sharing_hooks_1.useRevokePatientSharing; } });
132
+ Object.defineProperty(exports, "useUpdatePatientSharingSettings", { enumerable: true, get: function () { return patient_sharing_hooks_1.useUpdatePatientSharingSettings; } });
@@ -13,29 +13,36 @@ export interface UseObservationsOptions<T extends readonly SupportedType[]> {
13
13
  types: T;
14
14
  period?: ObservationPeriod;
15
15
  patientId?: string;
16
+ id?: string;
16
17
  groupBy?: ObservationsToMeasurementsOptions["groupBy"];
17
18
  timeToleranceMs?: number;
19
+ count?: number;
20
+ sort?: string;
21
+ elements?: string | readonly string[];
18
22
  }
19
23
  /** Plain inverse mapping for apps that already fetched their Observation resources. */
20
24
  export { observationsToMeasurements };
21
- export declare const useObservations: <T extends readonly SupportedType[]>({ types, period, patientId, groupBy, timeToleranceMs, }: UseObservationsOptions<T>) => {
25
+ export declare const useObservations: <T extends readonly SupportedType[]>({ types, period, patientId, id, groupBy, timeToleranceMs, count, sort, elements, }: UseObservationsOptions<T>) => {
22
26
  measurements: Array<Extract<SupportedMeasurement, {
23
27
  measurementTypeKey: T[number];
24
28
  }>>;
25
29
  loading: boolean;
26
30
  error?: Error;
27
31
  observations: readonly Observation[];
32
+ refetch: () => void;
28
33
  };
29
34
  export declare const useSaveMeasurement: () => ((params: GenerateObservationBodyParams) => Promise<Awaited<ReturnType<OvokClient["saveMeasurement"]>>>);
30
35
  export declare const useEcgRecording: (id?: string) => {
31
36
  recording: import("../types").EcgMeasurement;
32
- measurements: readonly Observation[];
37
+ measurements: import("@medplum/core").WithId<Observation>[];
33
38
  loading: boolean;
34
- error?: Error;
39
+ error: Error | undefined;
40
+ reload: () => void;
35
41
  };
36
42
  export declare const useUrineTests: () => {
37
43
  measurements: never[];
38
44
  loading: boolean;
39
45
  error?: Error;
40
46
  observations: readonly Observation[];
47
+ refetch: () => void;
41
48
  };
@@ -35,20 +35,20 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
37
  exports.useUrineTests = exports.useEcgRecording = exports.useSaveMeasurement = exports.useObservations = exports.observationsToMeasurements = void 0;
38
- const react_hooks_1 = require("@medplum/react-hooks");
39
38
  const React = __importStar(require("react"));
40
39
  const observationsToMeasurements_1 = require("../client/observation/methods/observationsToMeasurements");
41
40
  Object.defineProperty(exports, "observationsToMeasurements", { enumerable: true, get: function () { return observationsToMeasurements_1.observationsToMeasurements; } });
42
41
  const types_1 = require("../types");
42
+ const api_hooks_1 = require("./api-hooks");
43
43
  const index_1 = require("./index");
44
- const useObservations = ({ types, period, patientId, groupBy, timeToleranceMs, }) => {
45
- var _a, _b, _c;
44
+ const useObservations = ({ types, period, patientId, id, groupBy, timeToleranceMs, count, sort, elements, }) => {
46
45
  // A broad search is intentional: one measurement can expand into several
47
46
  // observations, and the inverse mapper performs the type-specific grouping.
48
47
  const codes = React.useMemo(() => (0, observationsToMeasurements_1.observationCodesForTypes)(types), [types]);
49
48
  const query = React.useMemo(() => ({
50
49
  ...(codes ? { code: codes } : {}),
51
50
  ...(patientId ? { subject: `Patient/${patientId}` } : {}),
51
+ ...(id ? { _id: id } : {}),
52
52
  ...((period === null || period === void 0 ? void 0 : period.start) || (period === null || period === void 0 ? void 0 : period.end)
53
53
  ? {
54
54
  date: [
@@ -57,15 +57,20 @@ const useObservations = ({ types, period, patientId, groupBy, timeToleranceMs, }
57
57
  ],
58
58
  }
59
59
  : {}),
60
- }), [codes, patientId, period === null || period === void 0 ? void 0 : period.end, period === null || period === void 0 ? void 0 : period.start]);
61
- const [resources, loading, outcome] = (0, react_hooks_1.useSearchResources)("Observation", query);
62
- const observations = resources !== null && resources !== void 0 ? resources : [];
60
+ ...(count !== undefined ? { _count: count } : {}),
61
+ ...(sort ? { _sort: sort } : {}),
62
+ ...(elements ? { _elements: Array.isArray(elements) ? elements.join(",") : elements } : {}),
63
+ }), [codes, count, elements, id, patientId, period === null || period === void 0 ? void 0 : period.end, period === null || period === void 0 ? void 0 : period.start, sort]);
64
+ const client = (0, index_1.useClient)();
65
+ const load = React.useCallback(() => client.searchResources("Observation", query), [client, query]);
66
+ const { data: observations = [], reload: refetch, loading, error } = (0, api_hooks_1.useOvokRequest)(load);
63
67
  const measurements = React.useMemo(() => (0, observationsToMeasurements_1.observationsToMeasurements)(observations, types, { groupBy, timeToleranceMs }), [groupBy, observations, timeToleranceMs, types]);
64
68
  return {
65
69
  measurements,
66
70
  loading,
67
- error: outcome ? new Error((_c = (_b = (_a = outcome.issue) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.diagnostics) !== null && _c !== void 0 ? _c : "Observation search failed") : undefined,
71
+ error,
68
72
  observations,
73
+ refetch,
69
74
  };
70
75
  };
71
76
  exports.useObservations = useObservations;
@@ -75,13 +80,23 @@ const useSaveMeasurement = () => {
75
80
  };
76
81
  exports.useSaveMeasurement = useSaveMeasurement;
77
82
  const useEcgRecording = (id) => {
78
- const { observations, ...state } = (0, exports.useObservations)({
79
- types: [types_1.MeasurementTypeKey.ecg],
80
- });
81
- const recordingObservations = id
82
- ? observations.filter((observation) => { var _a; return observation.id === id || ((_a = observation.id) === null || _a === void 0 ? void 0 : _a.startsWith(`${id}-`)); })
83
- : observations;
84
- const recording = (0, observationsToMeasurements_1.observationsToMeasurements)(recordingObservations, [types_1.MeasurementTypeKey.ecg])[0];
83
+ const client = (0, index_1.useClient)();
84
+ const load = React.useCallback(async () => {
85
+ const query = {
86
+ code: (0, observationsToMeasurements_1.observationCodesForTypes)([types_1.MeasurementTypeKey.ecg]),
87
+ _elements: "id,effectivePeriod,code,device,component,interpretation,valueSampledData,hasMember",
88
+ };
89
+ if (!id) {
90
+ return client.searchResources("Observation", query);
91
+ }
92
+ const [root, members] = await Promise.all([
93
+ client.searchResources("Observation", { ...query, _id: id }),
94
+ client.searchResources("Observation", { ...query, "has-member": `Observation/${id}` }),
95
+ ]);
96
+ return [...root, ...members];
97
+ }, [client, id]);
98
+ const { data: observations = [], ...state } = (0, api_hooks_1.useOvokRequest)(load);
99
+ const recording = (0, observationsToMeasurements_1.observationsToMeasurements)(observations, [types_1.MeasurementTypeKey.ecg])[0];
85
100
  return { ...state, recording, measurements: observations };
86
101
  };
87
102
  exports.useEcgRecording = useEcgRecording;
@@ -0,0 +1,8 @@
1
+ import { CreatePatientSharingInvite, PatientSharingInvite, PatientSharingSettings, PatientSharingShare, PatientSharingShares, RedeemPatientSharingInvite } from "../client/patient-sharing";
2
+ import { OvokMutationState, OvokRequestState } from "./api-hooks";
3
+ export declare const usePatientSharing: () => OvokRequestState<PatientSharingShares>;
4
+ export declare const useCreatePatientSharingInvite: () => OvokMutationState<CreatePatientSharingInvite, PatientSharingInvite>;
5
+ export declare const useRedeemPatientSharingInvite: () => OvokMutationState<RedeemPatientSharingInvite, PatientSharingShare>;
6
+ export declare const useRevokePatientSharing: () => OvokMutationState<string, void>;
7
+ export declare const usePatientSharingSettings: () => OvokRequestState<PatientSharingSettings>;
8
+ export declare const useUpdatePatientSharingSettings: () => OvokMutationState<PatientSharingSettings, PatientSharingSettings>;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ "use client";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.useUpdatePatientSharingSettings = exports.usePatientSharingSettings = exports.useRevokePatientSharing = exports.useRedeemPatientSharingInvite = exports.useCreatePatientSharingInvite = exports.usePatientSharing = void 0;
38
+ const React = __importStar(require("react"));
39
+ const api_hooks_1 = require("./api-hooks");
40
+ const index_1 = require("./index");
41
+ const usePatientSharing = () => {
42
+ const client = (0, index_1.useClient)();
43
+ const load = React.useCallback(() => client.listPatientSharing(), [client]);
44
+ return (0, api_hooks_1.useOvokRequest)(load);
45
+ };
46
+ exports.usePatientSharing = usePatientSharing;
47
+ const useCreatePatientSharingInvite = () => (0, api_hooks_1.useOvokMutation)((client, params) => client.createPatientSharingInvite(params));
48
+ exports.useCreatePatientSharingInvite = useCreatePatientSharingInvite;
49
+ const useRedeemPatientSharingInvite = () => (0, api_hooks_1.useOvokMutation)((client, params) => client.redeemPatientSharingInvite(params));
50
+ exports.useRedeemPatientSharingInvite = useRedeemPatientSharingInvite;
51
+ const useRevokePatientSharing = () => (0, api_hooks_1.useOvokMutation)((client, consentId) => client.revokePatientSharing(consentId));
52
+ exports.useRevokePatientSharing = useRevokePatientSharing;
53
+ const usePatientSharingSettings = () => {
54
+ const client = (0, index_1.useClient)();
55
+ const load = React.useCallback(() => client.getPatientSharingSettings(), [client]);
56
+ return (0, api_hooks_1.useOvokRequest)(load);
57
+ };
58
+ exports.usePatientSharingSettings = usePatientSharingSettings;
59
+ const useUpdatePatientSharingSettings = () => (0, api_hooks_1.useOvokMutation)((client, settings) => client.updatePatientSharingSettings(settings));
60
+ exports.useUpdatePatientSharingSettings = useUpdatePatientSharingSettings;
package/dist/index.d.ts CHANGED
@@ -924,6 +924,7 @@ declare const Medplum: {
924
924
  export { Medplum };
925
925
  export { OvokClient } from "./client/ovok-client";
926
926
  export * from "./client/errors/rate-limit-error";
927
+ export * from "./client/errors/ovok-error";
927
928
  export { MAX_CONDITIONAL_OBSERVATION_ENTRIES, MAX_OBSERVATION_BUNDLE_BYTES, } from "./client/ovok-client";
928
929
  export type { SaveObservationsResult } from "./client/ovok-client";
929
930
  export * from "./client/offline";
@@ -939,5 +940,7 @@ export * from "./client/platform/types";
939
940
  export * from "./client/carehub/types";
940
941
  export * from "./client/experience/types";
941
942
  export * from "./client/patient/types";
943
+ export * from "./client/patient-sharing";
944
+ export * from "./client/storage";
942
945
  export * from "./client/questionnaire-response/methods";
943
946
  export * from "./client/questionnaire-response/types";
package/dist/index.js CHANGED
@@ -45,6 +45,7 @@ exports.Medplum = Medplum;
45
45
  var ovok_client_1 = require("./client/ovok-client");
46
46
  Object.defineProperty(exports, "OvokClient", { enumerable: true, get: function () { return ovok_client_1.OvokClient; } });
47
47
  __exportStar(require("./client/errors/rate-limit-error"), exports);
48
+ __exportStar(require("./client/errors/ovok-error"), exports);
48
49
  var ovok_client_2 = require("./client/ovok-client");
49
50
  Object.defineProperty(exports, "MAX_CONDITIONAL_OBSERVATION_ENTRIES", { enumerable: true, get: function () { return ovok_client_2.MAX_CONDITIONAL_OBSERVATION_ENTRIES; } });
50
51
  Object.defineProperty(exports, "MAX_OBSERVATION_BUNDLE_BYTES", { enumerable: true, get: function () { return ovok_client_2.MAX_OBSERVATION_BUNDLE_BYTES; } });
@@ -62,5 +63,7 @@ __exportStar(require("./client/platform/types"), exports);
62
63
  __exportStar(require("./client/carehub/types"), exports);
63
64
  __exportStar(require("./client/experience/types"), exports);
64
65
  __exportStar(require("./client/patient/types"), exports);
66
+ __exportStar(require("./client/patient-sharing"), exports);
67
+ __exportStar(require("./client/storage"), exports);
65
68
  __exportStar(require("./client/questionnaire-response/methods"), exports);
66
69
  __exportStar(require("./client/questionnaire-response/types"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ovok/core",
3
- "version": "0.3.18",
3
+ "version": "0.3.20",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",