@ovok/core 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +35 -0
- package/dist/client/ovok-client.d.ts +2 -1
- package/dist/client/ovok-client.js +5 -2
- package/dist/client/signals/errors.d.ts +19 -0
- package/dist/client/signals/errors.js +184 -0
- package/dist/client/signals/index.d.ts +3 -0
- package/dist/client/signals/index.js +19 -0
- package/dist/client/signals/methods.d.ts +11 -0
- package/dist/client/signals/methods.js +64 -0
- package/dist/client/signals/types.d.ts +54 -0
- package/dist/client/signals/types.js +2 -0
- package/dist/conformance/capability-requirements.js +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +10 -1
- package/dist/hooks/signals-hooks.d.ts +34 -0
- package/dist/hooks/signals-hooks.js +152 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Core TypeScript SDK for healthcare applications. Provides authentication, AI-FHI
|
|
|
17
17
|
- 🧭 Runtime discovery of the backend FHIR and public API capabilities
|
|
18
18
|
- 🧩 Typed accounts, projects, localization, and patient-observation APIs
|
|
19
19
|
- 🏥 Typed CareHub patient, device, telemetry, notification, and monitoring APIs
|
|
20
|
+
- 🚨 Typed Signals thresholds, alerts, and project settings APIs
|
|
20
21
|
|
|
21
22
|
## Installation
|
|
22
23
|
|
|
@@ -151,6 +152,40 @@ const slots = await client.listPatientSlots({
|
|
|
151
152
|
});
|
|
152
153
|
```
|
|
153
154
|
|
|
155
|
+
## Signals APIs
|
|
156
|
+
|
|
157
|
+
The Signals client methods and hooks cover resident thresholds, the project's alert feed, and
|
|
158
|
+
Signals tenant settings. Ovok forwards observations for enabled residents to Signals on the
|
|
159
|
+
backend; continue saving readings through the existing Observation APIs and do not submit the
|
|
160
|
+
same readings to Signals separately.
|
|
161
|
+
|
|
162
|
+
```ts
|
|
163
|
+
const thresholds = await client.getSignalsThresholds(patientId);
|
|
164
|
+
const updated = await client.setSignalsThreshold(patientId, "8867-4", {
|
|
165
|
+
low: 50,
|
|
166
|
+
high: 120,
|
|
167
|
+
reason: "Updated after review",
|
|
168
|
+
});
|
|
169
|
+
const alerts = await client.listSignalsAlerts({
|
|
170
|
+
status: "OPEN",
|
|
171
|
+
codes: ["8867-4"],
|
|
172
|
+
limit: 25,
|
|
173
|
+
});
|
|
174
|
+
await client.acknowledgeSignalsAlert(alerts.items[0].id);
|
|
175
|
+
const settings = await client.getSignalsSettings();
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Use `editable` and `source` from threshold rows to present the available controls, but let the
|
|
179
|
+
backend enforce permissions. When lowering alert sensitivity or removing a bound, provide a
|
|
180
|
+
non-empty `reason`; the backend decides whether the caller has the required capability. A
|
|
181
|
+
`shared` settings tenant is read-only. Signal errors are exposed as `SignalsError` values and can
|
|
182
|
+
be checked with `isSignalsError`.
|
|
183
|
+
|
|
184
|
+
`useSignalsAlerts` accumulates pages through `loadMore`. Check `hasMore` rather than the current
|
|
185
|
+
item count: access filtering can produce a short or empty page with another cursor. Query changes
|
|
186
|
+
and `reload` start again at the first page. The hook exposes `reload` so a screen can refresh its
|
|
187
|
+
alert list after `useAcknowledgeSignalsAlert` succeeds.
|
|
188
|
+
|
|
154
189
|
## CareHub APIs
|
|
155
190
|
|
|
156
191
|
CareHub methods cover the verified `/v1/slim/*` and `/v2/slim/*` application routes for
|
|
@@ -14,6 +14,7 @@ import * as patientMethods from "./patient/methods";
|
|
|
14
14
|
import * as patientSharingMethods from "./patient-sharing/methods";
|
|
15
15
|
import * as platformMethods from "./platform/methods";
|
|
16
16
|
import * as questionnaireResponseMethods from "./questionnaire-response/methods";
|
|
17
|
+
import * as signalsMethods from "./signals/methods";
|
|
17
18
|
export declare const MAX_CONDITIONAL_OBSERVATION_ENTRIES = 8;
|
|
18
19
|
export { MAX_OBSERVATION_BUNDLE_BYTES } from "./observation/observation-bundle-utils";
|
|
19
20
|
export type SaveObservationsResult = {
|
|
@@ -59,7 +60,7 @@ export declare class OvokClient extends MedplumClient {
|
|
|
59
60
|
*/
|
|
60
61
|
getSubscriptionManager(): SubscriptionManager;
|
|
61
62
|
}
|
|
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;
|
|
63
|
+
type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof carehubMethods & typeof platformMethods & typeof experienceMethods & typeof patientMethods & typeof patientSharingMethods & typeof signalsMethods;
|
|
63
64
|
type Omitted<T> = Omit<T, "executeBot">;
|
|
64
65
|
declare module "./ovok-client" {
|
|
65
66
|
interface OvokClient extends Omitted<Methods> {
|
|
@@ -51,6 +51,8 @@ const patientMethods = __importStar(require("./patient/methods"));
|
|
|
51
51
|
const patientSharingMethods = __importStar(require("./patient-sharing/methods"));
|
|
52
52
|
const platformMethods = __importStar(require("./platform/methods"));
|
|
53
53
|
const questionnaireResponseMethods = __importStar(require("./questionnaire-response/methods"));
|
|
54
|
+
const errors_1 = require("./signals/errors");
|
|
55
|
+
const signalsMethods = __importStar(require("./signals/methods"));
|
|
54
56
|
exports.MAX_CONDITIONAL_OBSERVATION_ENTRIES = 8;
|
|
55
57
|
var observation_bundle_utils_2 = require("./observation/observation-bundle-utils");
|
|
56
58
|
Object.defineProperty(exports, "MAX_OBSERVATION_BUNDLE_BYTES", { enumerable: true, get: function () { return observation_bundle_utils_2.MAX_OBSERVATION_BUNDLE_BYTES; } });
|
|
@@ -75,6 +77,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
75
77
|
this.bindMethods(experienceMethods);
|
|
76
78
|
this.bindMethods(patientMethods);
|
|
77
79
|
this.bindMethods(patientSharingMethods);
|
|
80
|
+
this.bindMethods(signalsMethods, (error) => (0, errors_1.mapSignalsError)((0, rate_limit_error_1.mapRateLimitError)(error), { signalsRequest: true }));
|
|
78
81
|
this.clientStorage = config.storage;
|
|
79
82
|
this.offlineQueueOptions = (_b = config.offlineQueue) !== null && _b !== void 0 ? _b : {};
|
|
80
83
|
}
|
|
@@ -141,7 +144,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
141
144
|
async executeObservationBundle(bundle) {
|
|
142
145
|
return (0, observation_bundle_utils_1.executeObservationBundle)(bundle, (request) => this.executeBatch(request));
|
|
143
146
|
}
|
|
144
|
-
bindMethods(methods) {
|
|
147
|
+
bindMethods(methods, mapError = rate_limit_error_1.mapRateLimitError) {
|
|
145
148
|
for (const [name, method] of Object.entries(methods)) {
|
|
146
149
|
const boundMethod = method.bind(this);
|
|
147
150
|
this[name] = async (...args) => {
|
|
@@ -149,7 +152,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
149
152
|
return await boundMethod(...args);
|
|
150
153
|
}
|
|
151
154
|
catch (error) {
|
|
152
|
-
throw (
|
|
155
|
+
throw mapError(error);
|
|
153
156
|
}
|
|
154
157
|
};
|
|
155
158
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SignalsErrorCode, SignalsFieldError } from "./types";
|
|
2
|
+
type SignalsErrorOptions = {
|
|
3
|
+
cause?: unknown;
|
|
4
|
+
fieldErrors?: SignalsFieldError[];
|
|
5
|
+
};
|
|
6
|
+
/** A typed error returned by an Ovok Signals API route. */
|
|
7
|
+
export declare class SignalsError extends Error {
|
|
8
|
+
readonly code: SignalsErrorCode;
|
|
9
|
+
readonly status: number;
|
|
10
|
+
readonly fieldErrors: SignalsFieldError[];
|
|
11
|
+
readonly cause: unknown;
|
|
12
|
+
constructor(code: SignalsErrorCode, status: number, message: string, options?: SignalsErrorOptions);
|
|
13
|
+
}
|
|
14
|
+
export declare function isSignalsError(error: unknown): error is SignalsError;
|
|
15
|
+
/** Converts the Signals error envelope while leaving unrelated errors untouched. */
|
|
16
|
+
export declare function mapSignalsError(error: unknown, options?: {
|
|
17
|
+
signalsRequest?: boolean;
|
|
18
|
+
}): unknown;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SignalsError = void 0;
|
|
4
|
+
exports.isSignalsError = isSignalsError;
|
|
5
|
+
exports.mapSignalsError = mapSignalsError;
|
|
6
|
+
const ovok_error_1 = require("../errors/ovok-error");
|
|
7
|
+
const SIGNALS_ERROR_STATUSES = {
|
|
8
|
+
signals_threshold_not_editable: 409,
|
|
9
|
+
signals_patient_not_enrolled: 409,
|
|
10
|
+
signals_conflict: 409,
|
|
11
|
+
signals_code_not_medical: 422,
|
|
12
|
+
signals_reason_required: 422,
|
|
13
|
+
signals_episodes_disabled: 409,
|
|
14
|
+
signals_bad_request: 422,
|
|
15
|
+
signals_shared_tenant: 409,
|
|
16
|
+
signals_audit_failed: 503,
|
|
17
|
+
signals_write_mismatch: 503,
|
|
18
|
+
signals_unavailable: 503,
|
|
19
|
+
signals_undo_failed: 503,
|
|
20
|
+
signals_forbidden: 403,
|
|
21
|
+
signals_not_found: 404,
|
|
22
|
+
validation_error: 422,
|
|
23
|
+
};
|
|
24
|
+
const SIGNALS_ERROR_CODES = new Set(Object.keys(SIGNALS_ERROR_STATUSES));
|
|
25
|
+
/** A typed error returned by an Ovok Signals API route. */
|
|
26
|
+
class SignalsError extends Error {
|
|
27
|
+
constructor(code, status, message, options = {}) {
|
|
28
|
+
var _a;
|
|
29
|
+
super(message);
|
|
30
|
+
this.name = "SignalsError";
|
|
31
|
+
this.code = code;
|
|
32
|
+
this.status = status;
|
|
33
|
+
this.fieldErrors = (_a = options.fieldErrors) !== null && _a !== void 0 ? _a : [];
|
|
34
|
+
if (options.cause !== undefined) {
|
|
35
|
+
Object.defineProperty(this, "cause", {
|
|
36
|
+
configurable: true,
|
|
37
|
+
enumerable: false,
|
|
38
|
+
value: options.cause,
|
|
39
|
+
writable: false,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.SignalsError = SignalsError;
|
|
45
|
+
function isSignalsError(error) {
|
|
46
|
+
return error instanceof SignalsError;
|
|
47
|
+
}
|
|
48
|
+
/** Converts the Signals error envelope while leaving unrelated errors untouched. */
|
|
49
|
+
function mapSignalsError(error, options = {}) {
|
|
50
|
+
if (isSignalsError(error)) {
|
|
51
|
+
return error;
|
|
52
|
+
}
|
|
53
|
+
const payload = responsePayload(error);
|
|
54
|
+
const code = responseCode(payload);
|
|
55
|
+
const parsed = (0, ovok_error_1.parseOvokError)(payload !== null && payload !== void 0 ? payload : error);
|
|
56
|
+
const message = (parsed.message === "[object Object]" || parsed.message === "undefined") &&
|
|
57
|
+
error instanceof Error
|
|
58
|
+
? error.message
|
|
59
|
+
: parsed.message;
|
|
60
|
+
const status = responseStatus(error, payload);
|
|
61
|
+
if (code && SIGNALS_ERROR_CODES.has(code)) {
|
|
62
|
+
const knownCode = code;
|
|
63
|
+
const resolvedStatus = status !== null && status !== void 0 ? status : SIGNALS_ERROR_STATUSES[knownCode];
|
|
64
|
+
if (resolvedStatus !== undefined) {
|
|
65
|
+
return new SignalsError(knownCode, resolvedStatus, message, {
|
|
66
|
+
cause: error,
|
|
67
|
+
fieldErrors: parsed.fieldErrors,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (status === 409 && options.signalsRequest && !code) {
|
|
72
|
+
return new SignalsError("signals_conflict", status, message, { cause: error });
|
|
73
|
+
}
|
|
74
|
+
if (status === 403 && !code) {
|
|
75
|
+
return new SignalsError("signals_forbidden", status, message, { cause: error });
|
|
76
|
+
}
|
|
77
|
+
if (status === 404 && !code) {
|
|
78
|
+
return new SignalsError("signals_not_found", status, message, { cause: error });
|
|
79
|
+
}
|
|
80
|
+
if (status === 422 && !code) {
|
|
81
|
+
const validationCode = /reason.*(required|missing|provide|must)|(?:required|missing).{0,20}reason/i.test(message)
|
|
82
|
+
? "signals_reason_required"
|
|
83
|
+
: "validation_error";
|
|
84
|
+
return new SignalsError(validationCode, status, message, {
|
|
85
|
+
cause: error,
|
|
86
|
+
fieldErrors: parsed.fieldErrors,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return error;
|
|
90
|
+
}
|
|
91
|
+
function responsePayload(error) {
|
|
92
|
+
var _a, _b;
|
|
93
|
+
const root = asRecord(error);
|
|
94
|
+
const candidates = [
|
|
95
|
+
root === null || root === void 0 ? void 0 : root.body,
|
|
96
|
+
root === null || root === void 0 ? void 0 : root.data,
|
|
97
|
+
(_a = asRecord(root === null || root === void 0 ? void 0 : root.response)) === null || _a === void 0 ? void 0 : _a.data,
|
|
98
|
+
(_b = asRecord(root === null || root === void 0 ? void 0 : root.response)) === null || _b === void 0 ? void 0 : _b.body,
|
|
99
|
+
root === null || root === void 0 ? void 0 : root.outcome,
|
|
100
|
+
];
|
|
101
|
+
for (const candidate of candidates) {
|
|
102
|
+
const parsed = parseJson(candidate);
|
|
103
|
+
if (parsed !== undefined) {
|
|
104
|
+
return parsed;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (error instanceof Error) {
|
|
108
|
+
const parsed = parseJson(error.message);
|
|
109
|
+
if (parsed !== undefined) {
|
|
110
|
+
return parsed;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return error;
|
|
114
|
+
}
|
|
115
|
+
function responseCode(payload) {
|
|
116
|
+
var _a, _b, _c, _d, _e, _f;
|
|
117
|
+
const root = asRecord(payload);
|
|
118
|
+
const error = asRecord(root === null || root === void 0 ? void 0 : root.error);
|
|
119
|
+
const directCode = (_b = (_a = (typeof (root === null || root === void 0 ? void 0 : root.error) === "string" ? root.error : undefined)) !== null && _a !== void 0 ? _a : (typeof (root === null || root === void 0 ? void 0 : root.code) === "string" ? root.code : undefined)) !== null && _b !== void 0 ? _b : (typeof (error === null || error === void 0 ? void 0 : error.code) === "string" ? error.code : undefined);
|
|
120
|
+
if (directCode) {
|
|
121
|
+
return directCode;
|
|
122
|
+
}
|
|
123
|
+
const outcome = (_d = (_c = asRecord(root === null || root === void 0 ? void 0 : root.outcome)) !== null && _c !== void 0 ? _c : root) !== null && _d !== void 0 ? _d : {};
|
|
124
|
+
const issues = Array.isArray(outcome.issue) ? outcome.issue : [];
|
|
125
|
+
for (const issue of issues) {
|
|
126
|
+
const issueRecord = asRecord(issue);
|
|
127
|
+
const details = asRecord(issueRecord === null || issueRecord === void 0 ? void 0 : issueRecord.details);
|
|
128
|
+
const coding = Array.isArray(details === null || details === void 0 ? void 0 : details.coding) ? details.coding : [];
|
|
129
|
+
for (const entry of coding) {
|
|
130
|
+
const entryCode = (_e = asRecord(entry)) === null || _e === void 0 ? void 0 : _e.code;
|
|
131
|
+
if (typeof entryCode === "string" && entryCode.startsWith("signals_")) {
|
|
132
|
+
return entryCode;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const diagnostic = parseJson(issueRecord === null || issueRecord === void 0 ? void 0 : issueRecord.diagnostics);
|
|
136
|
+
const diagnosticRecord = asRecord(diagnostic);
|
|
137
|
+
const diagnosticCode = (_f = diagnosticRecord === null || diagnosticRecord === void 0 ? void 0 : diagnosticRecord.error) !== null && _f !== void 0 ? _f : diagnosticRecord === null || diagnosticRecord === void 0 ? void 0 : diagnosticRecord.code;
|
|
138
|
+
if (typeof diagnosticCode === "string") {
|
|
139
|
+
return diagnosticCode;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return undefined;
|
|
143
|
+
}
|
|
144
|
+
function responseStatus(error, payload) {
|
|
145
|
+
var _a, _b, _c, _d, _e, _f;
|
|
146
|
+
const root = asRecord(error);
|
|
147
|
+
const response = asRecord(root === null || root === void 0 ? void 0 : root.response);
|
|
148
|
+
const body = asRecord(payload);
|
|
149
|
+
const status = (_d = (_c = (_b = (_a = root === null || root === void 0 ? void 0 : root.status) !== null && _a !== void 0 ? _a : root === null || root === void 0 ? void 0 : root.statusCode) !== null && _b !== void 0 ? _b : response === null || response === void 0 ? void 0 : response.status) !== null && _c !== void 0 ? _c : body === null || body === void 0 ? void 0 : body.status) !== null && _d !== void 0 ? _d : body === null || body === void 0 ? void 0 : body.statusCode;
|
|
150
|
+
if (typeof status === "number") {
|
|
151
|
+
return status;
|
|
152
|
+
}
|
|
153
|
+
const outcome = (_e = asRecord(body === null || body === void 0 ? void 0 : body.outcome)) !== null && _e !== void 0 ? _e : body;
|
|
154
|
+
const issues = Array.isArray(outcome === null || outcome === void 0 ? void 0 : outcome.issue) ? outcome.issue : [];
|
|
155
|
+
for (const issue of issues) {
|
|
156
|
+
const issueCode = (_f = asRecord(issue)) === null || _f === void 0 ? void 0 : _f.code;
|
|
157
|
+
if (issueCode === "conflict") {
|
|
158
|
+
return 409;
|
|
159
|
+
}
|
|
160
|
+
if (issueCode === "forbidden") {
|
|
161
|
+
return 403;
|
|
162
|
+
}
|
|
163
|
+
if (issueCode === "not-found") {
|
|
164
|
+
return 404;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return undefined;
|
|
168
|
+
}
|
|
169
|
+
function parseJson(value) {
|
|
170
|
+
if (typeof value !== "string") {
|
|
171
|
+
return value;
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
return JSON.parse(value);
|
|
175
|
+
}
|
|
176
|
+
catch (_a) {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function asRecord(value) {
|
|
181
|
+
return value && typeof value === "object"
|
|
182
|
+
? value
|
|
183
|
+
: undefined;
|
|
184
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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("./errors"), exports);
|
|
18
|
+
__exportStar(require("./methods"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OvokClient } from "../ovok-client";
|
|
2
|
+
import { SetSignalsThresholdBody, SignalsAlert, SignalsAlertsPage, SignalsAlertsQuery, SignalsSettingsPatch, SignalsSettingsResponse, SignalsThreshold, SignalsThresholds } from "./types";
|
|
3
|
+
export declare function getSignalsThresholds(this: OvokClient, patientId: string): Promise<SignalsThresholds>;
|
|
4
|
+
export declare function setSignalsThreshold(this: OvokClient, patientId: string, code: string, body: SetSignalsThresholdBody): Promise<SignalsThreshold>;
|
|
5
|
+
export declare function removeSignalsThreshold(this: OvokClient, patientId: string, code: string, reason: string): Promise<void>;
|
|
6
|
+
export declare function serializeSignalsAlertsQuery(query?: SignalsAlertsQuery): string;
|
|
7
|
+
export declare function listSignalsAlerts(this: OvokClient, query?: SignalsAlertsQuery): Promise<SignalsAlertsPage>;
|
|
8
|
+
export declare function getSignalsAlert(this: OvokClient, episodeId: string): Promise<SignalsAlert>;
|
|
9
|
+
export declare function acknowledgeSignalsAlert(this: OvokClient, episodeId: string): Promise<SignalsAlert>;
|
|
10
|
+
export declare function getSignalsSettings(this: OvokClient): Promise<SignalsSettingsResponse>;
|
|
11
|
+
export declare function updateSignalsSettings(this: OvokClient, patch: SignalsSettingsPatch, reason?: string | null): Promise<SignalsSettingsResponse>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getSignalsThresholds = getSignalsThresholds;
|
|
4
|
+
exports.setSignalsThreshold = setSignalsThreshold;
|
|
5
|
+
exports.removeSignalsThreshold = removeSignalsThreshold;
|
|
6
|
+
exports.serializeSignalsAlertsQuery = serializeSignalsAlertsQuery;
|
|
7
|
+
exports.listSignalsAlerts = listSignalsAlerts;
|
|
8
|
+
exports.getSignalsAlert = getSignalsAlert;
|
|
9
|
+
exports.acknowledgeSignalsAlert = acknowledgeSignalsAlert;
|
|
10
|
+
exports.getSignalsSettings = getSignalsSettings;
|
|
11
|
+
exports.updateSignalsSettings = updateSignalsSettings;
|
|
12
|
+
const segment = (value) => encodeURIComponent(value);
|
|
13
|
+
function getSignalsThresholds(patientId) {
|
|
14
|
+
return this.get(`/v1/signals/patients/${segment(patientId)}/thresholds`);
|
|
15
|
+
}
|
|
16
|
+
function setSignalsThreshold(patientId, code, body) {
|
|
17
|
+
return this.put(`/v1/signals/patients/${segment(patientId)}/thresholds/${segment(code)}`, body);
|
|
18
|
+
}
|
|
19
|
+
function removeSignalsThreshold(patientId, code, reason) {
|
|
20
|
+
return this.delete(`/v1/signals/patients/${segment(patientId)}/thresholds/${segment(code)}?reason=${segment(reason)}`);
|
|
21
|
+
}
|
|
22
|
+
function serializeSignalsAlertsQuery(query = {}) {
|
|
23
|
+
const params = [];
|
|
24
|
+
if (query.status !== undefined) {
|
|
25
|
+
params.push(["status", query.status]);
|
|
26
|
+
}
|
|
27
|
+
if (query.since !== undefined) {
|
|
28
|
+
params.push(["since", query.since]);
|
|
29
|
+
}
|
|
30
|
+
if (query.acknowledged !== undefined) {
|
|
31
|
+
params.push(["acknowledged", String(query.acknowledged)]);
|
|
32
|
+
}
|
|
33
|
+
if (query.codes !== undefined) {
|
|
34
|
+
params.push(["codes", query.codes.join(",")]);
|
|
35
|
+
}
|
|
36
|
+
if (query.limit !== undefined) {
|
|
37
|
+
params.push(["limit", String(query.limit)]);
|
|
38
|
+
}
|
|
39
|
+
if (query.cursor !== undefined) {
|
|
40
|
+
params.push(["cursor", query.cursor]);
|
|
41
|
+
}
|
|
42
|
+
return params
|
|
43
|
+
.map(([key, value]) => `${segment(key)}=${segment(value)}`)
|
|
44
|
+
.join("&");
|
|
45
|
+
}
|
|
46
|
+
function listSignalsAlerts(query = {}) {
|
|
47
|
+
const serialized = serializeSignalsAlertsQuery(query);
|
|
48
|
+
return this.get(`/v1/signals/alerts${serialized ? `?${serialized}` : ""}`);
|
|
49
|
+
}
|
|
50
|
+
function getSignalsAlert(episodeId) {
|
|
51
|
+
return this.get(`/v1/signals/alerts/${segment(episodeId)}`);
|
|
52
|
+
}
|
|
53
|
+
function acknowledgeSignalsAlert(episodeId) {
|
|
54
|
+
return this.post(`/v1/signals/alerts/${segment(episodeId)}/ack`);
|
|
55
|
+
}
|
|
56
|
+
function getSignalsSettings() {
|
|
57
|
+
return this.get("/v1/signals/settings");
|
|
58
|
+
}
|
|
59
|
+
function updateSignalsSettings(patch, reason) {
|
|
60
|
+
return this.patch("/v1/signals/settings", {
|
|
61
|
+
...patch,
|
|
62
|
+
...(reason !== undefined ? { reason } : {}),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { ValidationError } from "../../types/ValidationError";
|
|
2
|
+
export type SignalsThresholdSource = "organization" | "individual" | "auto" | "unknown";
|
|
3
|
+
export type SignalsThreshold = {
|
|
4
|
+
code: string;
|
|
5
|
+
low: number | null;
|
|
6
|
+
high: number | null;
|
|
7
|
+
editable: boolean;
|
|
8
|
+
version: number;
|
|
9
|
+
updatedAt: string;
|
|
10
|
+
source: SignalsThresholdSource;
|
|
11
|
+
};
|
|
12
|
+
export type SignalsThresholds = {
|
|
13
|
+
patientId: string;
|
|
14
|
+
thresholds: SignalsThreshold[];
|
|
15
|
+
};
|
|
16
|
+
export type SetSignalsThresholdBody = {
|
|
17
|
+
low: number | null;
|
|
18
|
+
high: number | null;
|
|
19
|
+
reason?: string | null;
|
|
20
|
+
};
|
|
21
|
+
export type SignalsAlertStatus = "OPEN" | "CLOSED";
|
|
22
|
+
export type SignalsAlert = {
|
|
23
|
+
id: string;
|
|
24
|
+
patientId: string;
|
|
25
|
+
signalsPatientId: string;
|
|
26
|
+
code: string;
|
|
27
|
+
status: SignalsAlertStatus;
|
|
28
|
+
[key: string]: unknown;
|
|
29
|
+
};
|
|
30
|
+
export type SignalsAlertsQuery = {
|
|
31
|
+
status?: SignalsAlertStatus;
|
|
32
|
+
since?: string;
|
|
33
|
+
acknowledged?: boolean;
|
|
34
|
+
codes?: readonly string[];
|
|
35
|
+
limit?: number;
|
|
36
|
+
cursor?: string;
|
|
37
|
+
};
|
|
38
|
+
export type SignalsAlertsPage = {
|
|
39
|
+
items: SignalsAlert[];
|
|
40
|
+
nextCursor: string | null;
|
|
41
|
+
};
|
|
42
|
+
export type SignalsSettings = {
|
|
43
|
+
episodicAlerts: boolean;
|
|
44
|
+
synchronousMode: boolean;
|
|
45
|
+
throttleLimit: number | null;
|
|
46
|
+
};
|
|
47
|
+
export type SignalsTenantKind = "project" | "shared";
|
|
48
|
+
export type SignalsSettingsResponse = {
|
|
49
|
+
tenant: SignalsTenantKind;
|
|
50
|
+
settings: SignalsSettings;
|
|
51
|
+
};
|
|
52
|
+
export type SignalsSettingsPatch = Partial<SignalsSettings>;
|
|
53
|
+
export type SignalsErrorCode = "signals_threshold_not_editable" | "signals_patient_not_enrolled" | "signals_conflict" | "signals_code_not_medical" | "signals_reason_required" | "signals_episodes_disabled" | "signals_bad_request" | "signals_shared_tenant" | "signals_audit_failed" | "signals_write_mismatch" | "signals_unavailable" | "signals_undo_failed" | "signals_forbidden" | "signals_not_found" | "validation_error";
|
|
54
|
+
export type SignalsFieldError = ValidationError;
|
|
@@ -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.4.
|
|
51
|
+
version: "0.4.2",
|
|
52
52
|
},
|
|
53
53
|
fhirVersion: "4.0.1",
|
|
54
54
|
format: ["json"],
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -11,3 +11,4 @@ export { useConsentSignature, useContent, useCreateVideoCallAppointment, useCrea
|
|
|
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
13
|
export { useCreatePatientSharingInvite, usePatientSharing, usePatientSharingSettings, useRedeemPatientSharingInvite, useRevokePatientSharing, useUpdatePatientSharingSettings, } from "./patient-sharing-hooks";
|
|
14
|
+
export { useAcknowledgeSignalsAlert, useRemoveSignalsThreshold, useSetSignalsThreshold, useSignalsAlert, useSignalsAlerts, useSignalsSettings, useSignalsThresholds, useUpdateSignalsSettings, } from "./signals-hooks";
|
package/dist/hooks/index.js
CHANGED
|
@@ -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.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;
|
|
38
|
+
exports.useUpdateSignalsSettings = exports.useSignalsThresholds = exports.useSignalsSettings = exports.useSignalsAlerts = exports.useSignalsAlert = exports.useSetSignalsThreshold = exports.useRemoveSignalsThreshold = exports.useAcknowledgeSignalsAlert = 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
|
*
|
|
@@ -130,3 +130,12 @@ Object.defineProperty(exports, "usePatientSharingSettings", { enumerable: true,
|
|
|
130
130
|
Object.defineProperty(exports, "useRedeemPatientSharingInvite", { enumerable: true, get: function () { return patient_sharing_hooks_1.useRedeemPatientSharingInvite; } });
|
|
131
131
|
Object.defineProperty(exports, "useRevokePatientSharing", { enumerable: true, get: function () { return patient_sharing_hooks_1.useRevokePatientSharing; } });
|
|
132
132
|
Object.defineProperty(exports, "useUpdatePatientSharingSettings", { enumerable: true, get: function () { return patient_sharing_hooks_1.useUpdatePatientSharingSettings; } });
|
|
133
|
+
var signals_hooks_1 = require("./signals-hooks");
|
|
134
|
+
Object.defineProperty(exports, "useAcknowledgeSignalsAlert", { enumerable: true, get: function () { return signals_hooks_1.useAcknowledgeSignalsAlert; } });
|
|
135
|
+
Object.defineProperty(exports, "useRemoveSignalsThreshold", { enumerable: true, get: function () { return signals_hooks_1.useRemoveSignalsThreshold; } });
|
|
136
|
+
Object.defineProperty(exports, "useSetSignalsThreshold", { enumerable: true, get: function () { return signals_hooks_1.useSetSignalsThreshold; } });
|
|
137
|
+
Object.defineProperty(exports, "useSignalsAlert", { enumerable: true, get: function () { return signals_hooks_1.useSignalsAlert; } });
|
|
138
|
+
Object.defineProperty(exports, "useSignalsAlerts", { enumerable: true, get: function () { return signals_hooks_1.useSignalsAlerts; } });
|
|
139
|
+
Object.defineProperty(exports, "useSignalsSettings", { enumerable: true, get: function () { return signals_hooks_1.useSignalsSettings; } });
|
|
140
|
+
Object.defineProperty(exports, "useSignalsThresholds", { enumerable: true, get: function () { return signals_hooks_1.useSignalsThresholds; } });
|
|
141
|
+
Object.defineProperty(exports, "useUpdateSignalsSettings", { enumerable: true, get: function () { return signals_hooks_1.useUpdateSignalsSettings; } });
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { SetSignalsThresholdBody, SignalsAlert, SignalsAlertsQuery, SignalsSettingsPatch, SignalsSettingsResponse, SignalsThreshold, SignalsThresholds } from "../client/signals";
|
|
2
|
+
import { OvokMutationState, OvokRequestState } from "./api-hooks";
|
|
3
|
+
type SetSignalsThresholdParams = {
|
|
4
|
+
patientId: string;
|
|
5
|
+
code: string;
|
|
6
|
+
body: SetSignalsThresholdBody;
|
|
7
|
+
};
|
|
8
|
+
type RemoveSignalsThresholdParams = {
|
|
9
|
+
patientId: string;
|
|
10
|
+
code: string;
|
|
11
|
+
reason: string;
|
|
12
|
+
};
|
|
13
|
+
type UpdateSignalsSettingsParams = {
|
|
14
|
+
patch: SignalsSettingsPatch;
|
|
15
|
+
reason?: string | null;
|
|
16
|
+
};
|
|
17
|
+
type SignalsAlertsHookQuery = Omit<SignalsAlertsQuery, "cursor">;
|
|
18
|
+
export type SignalsAlertsHookState = {
|
|
19
|
+
items: SignalsAlert[];
|
|
20
|
+
loading: boolean;
|
|
21
|
+
error: Error | undefined;
|
|
22
|
+
reload: () => void;
|
|
23
|
+
hasMore: boolean;
|
|
24
|
+
loadMore: () => Promise<void>;
|
|
25
|
+
};
|
|
26
|
+
export declare const useSignalsThresholds: (patientId?: string) => OvokRequestState<SignalsThresholds>;
|
|
27
|
+
export declare const useSetSignalsThreshold: () => OvokMutationState<SetSignalsThresholdParams, SignalsThreshold>;
|
|
28
|
+
export declare const useRemoveSignalsThreshold: () => OvokMutationState<RemoveSignalsThresholdParams, void>;
|
|
29
|
+
export declare const useSignalsAlerts: (query?: SignalsAlertsHookQuery) => SignalsAlertsHookState;
|
|
30
|
+
export declare const useSignalsAlert: (episodeId?: string) => OvokRequestState<SignalsAlert>;
|
|
31
|
+
export declare const useAcknowledgeSignalsAlert: () => OvokMutationState<string, SignalsAlert>;
|
|
32
|
+
export declare const useSignalsSettings: () => OvokRequestState<SignalsSettingsResponse>;
|
|
33
|
+
export declare const useUpdateSignalsSettings: () => OvokMutationState<UpdateSignalsSettingsParams, SignalsSettingsResponse>;
|
|
34
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
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.useUpdateSignalsSettings = exports.useSignalsSettings = exports.useAcknowledgeSignalsAlert = exports.useSignalsAlert = exports.useSignalsAlerts = exports.useRemoveSignalsThreshold = exports.useSetSignalsThreshold = exports.useSignalsThresholds = void 0;
|
|
38
|
+
const React = __importStar(require("react"));
|
|
39
|
+
const api_hooks_1 = require("./api-hooks");
|
|
40
|
+
const index_1 = require("./index");
|
|
41
|
+
const useSignalsThresholds = (patientId) => {
|
|
42
|
+
const client = (0, index_1.useClient)();
|
|
43
|
+
const load = React.useCallback(() => client.getSignalsThresholds(patientId), [client, patientId]);
|
|
44
|
+
return (0, api_hooks_1.useOvokRequest)(load, patientId !== undefined);
|
|
45
|
+
};
|
|
46
|
+
exports.useSignalsThresholds = useSignalsThresholds;
|
|
47
|
+
const useSetSignalsThreshold = () => (0, api_hooks_1.useOvokMutation)((client, params) => client.setSignalsThreshold(params.patientId, params.code, params.body));
|
|
48
|
+
exports.useSetSignalsThreshold = useSetSignalsThreshold;
|
|
49
|
+
const useRemoveSignalsThreshold = () => (0, api_hooks_1.useOvokMutation)((client, params) => client.removeSignalsThreshold(params.patientId, params.code, params.reason));
|
|
50
|
+
exports.useRemoveSignalsThreshold = useRemoveSignalsThreshold;
|
|
51
|
+
const useSignalsAlerts = (query = {}) => {
|
|
52
|
+
const client = (0, index_1.useClient)();
|
|
53
|
+
const queryKey = JSON.stringify(query);
|
|
54
|
+
const querySnapshot = React.useMemo(() => JSON.parse(queryKey), [queryKey]);
|
|
55
|
+
const [items, setItems] = React.useState([]);
|
|
56
|
+
const [nextCursor, setNextCursor] = React.useState(null);
|
|
57
|
+
const [loading, setLoading] = React.useState(true);
|
|
58
|
+
const [error, setError] = React.useState();
|
|
59
|
+
const [revision, setRevision] = React.useState(0);
|
|
60
|
+
const generation = React.useRef(0);
|
|
61
|
+
const loadingRef = React.useRef(false);
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
const requestGeneration = generation.current + 1;
|
|
64
|
+
generation.current = requestGeneration;
|
|
65
|
+
loadingRef.current = true;
|
|
66
|
+
setItems([]);
|
|
67
|
+
setNextCursor(null);
|
|
68
|
+
setError(undefined);
|
|
69
|
+
setLoading(true);
|
|
70
|
+
client
|
|
71
|
+
.listSignalsAlerts(querySnapshot)
|
|
72
|
+
.then((page) => {
|
|
73
|
+
if (generation.current === requestGeneration) {
|
|
74
|
+
setItems(page.items);
|
|
75
|
+
setNextCursor(page.nextCursor);
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
.catch((reason) => {
|
|
79
|
+
if (generation.current === requestGeneration) {
|
|
80
|
+
setError(toError(reason));
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
.finally(() => {
|
|
84
|
+
if (generation.current === requestGeneration) {
|
|
85
|
+
loadingRef.current = false;
|
|
86
|
+
setLoading(false);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
return () => {
|
|
90
|
+
generation.current += 1;
|
|
91
|
+
};
|
|
92
|
+
}, [client, queryKey, querySnapshot, revision]);
|
|
93
|
+
const loadMore = React.useCallback(async () => {
|
|
94
|
+
if (nextCursor === null || loadingRef.current) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const requestGeneration = generation.current;
|
|
98
|
+
loadingRef.current = true;
|
|
99
|
+
setLoading(true);
|
|
100
|
+
setError(undefined);
|
|
101
|
+
try {
|
|
102
|
+
const page = await client.listSignalsAlerts({
|
|
103
|
+
...querySnapshot,
|
|
104
|
+
cursor: nextCursor,
|
|
105
|
+
});
|
|
106
|
+
if (generation.current === requestGeneration) {
|
|
107
|
+
setItems((current) => [...current, ...page.items]);
|
|
108
|
+
setNextCursor(page.nextCursor);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (reason) {
|
|
112
|
+
if (generation.current === requestGeneration) {
|
|
113
|
+
setError(toError(reason));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
if (generation.current === requestGeneration) {
|
|
118
|
+
loadingRef.current = false;
|
|
119
|
+
setLoading(false);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}, [client, nextCursor, querySnapshot]);
|
|
123
|
+
const reload = React.useCallback(() => {
|
|
124
|
+
setRevision((current) => current + 1);
|
|
125
|
+
}, []);
|
|
126
|
+
return {
|
|
127
|
+
items,
|
|
128
|
+
loading,
|
|
129
|
+
error,
|
|
130
|
+
reload,
|
|
131
|
+
hasMore: nextCursor !== null,
|
|
132
|
+
loadMore,
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
exports.useSignalsAlerts = useSignalsAlerts;
|
|
136
|
+
const useSignalsAlert = (episodeId) => {
|
|
137
|
+
const client = (0, index_1.useClient)();
|
|
138
|
+
const load = React.useCallback(() => client.getSignalsAlert(episodeId), [client, episodeId]);
|
|
139
|
+
return (0, api_hooks_1.useOvokRequest)(load, episodeId !== undefined);
|
|
140
|
+
};
|
|
141
|
+
exports.useSignalsAlert = useSignalsAlert;
|
|
142
|
+
const useAcknowledgeSignalsAlert = () => (0, api_hooks_1.useOvokMutation)((client, episodeId) => client.acknowledgeSignalsAlert(episodeId));
|
|
143
|
+
exports.useAcknowledgeSignalsAlert = useAcknowledgeSignalsAlert;
|
|
144
|
+
const useSignalsSettings = () => {
|
|
145
|
+
const client = (0, index_1.useClient)();
|
|
146
|
+
const load = React.useCallback(() => client.getSignalsSettings(), [client]);
|
|
147
|
+
return (0, api_hooks_1.useOvokRequest)(load);
|
|
148
|
+
};
|
|
149
|
+
exports.useSignalsSettings = useSignalsSettings;
|
|
150
|
+
const useUpdateSignalsSettings = () => (0, api_hooks_1.useOvokMutation)((client, params) => client.updateSignalsSettings(params.patch, params.reason));
|
|
151
|
+
exports.useUpdateSignalsSettings = useUpdateSignalsSettings;
|
|
152
|
+
const toError = (error) => error instanceof Error ? error : new Error(String(error));
|
package/dist/index.d.ts
CHANGED
|
@@ -941,6 +941,7 @@ export * from "./client/carehub/types";
|
|
|
941
941
|
export * from "./client/experience/types";
|
|
942
942
|
export * from "./client/patient/types";
|
|
943
943
|
export * from "./client/patient-sharing";
|
|
944
|
+
export { SignalsError, isSignalsError, mapSignalsError } from "./client/signals/errors";
|
|
944
945
|
export * from "./client/storage";
|
|
945
946
|
export * from "./client/questionnaire-response/methods";
|
|
946
947
|
export * from "./client/questionnaire-response/types";
|
package/dist/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
36
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.saveMeasurement = exports.MAX_OBSERVATION_BUNDLE_BYTES = exports.MAX_CONDITIONAL_OBSERVATION_ENTRIES = exports.OvokClient = exports.Medplum = void 0;
|
|
39
|
+
exports.mapSignalsError = exports.isSignalsError = exports.SignalsError = exports.saveMeasurement = exports.MAX_OBSERVATION_BUNDLE_BYTES = exports.MAX_CONDITIONAL_OBSERVATION_ENTRIES = exports.OvokClient = exports.Medplum = void 0;
|
|
40
40
|
const MedplumCore = __importStar(require("@medplum/core"));
|
|
41
41
|
__exportStar(require("./types"), exports);
|
|
42
42
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -64,6 +64,10 @@ __exportStar(require("./client/carehub/types"), exports);
|
|
|
64
64
|
__exportStar(require("./client/experience/types"), exports);
|
|
65
65
|
__exportStar(require("./client/patient/types"), exports);
|
|
66
66
|
__exportStar(require("./client/patient-sharing"), exports);
|
|
67
|
+
var errors_1 = require("./client/signals/errors");
|
|
68
|
+
Object.defineProperty(exports, "SignalsError", { enumerable: true, get: function () { return errors_1.SignalsError; } });
|
|
69
|
+
Object.defineProperty(exports, "isSignalsError", { enumerable: true, get: function () { return errors_1.isSignalsError; } });
|
|
70
|
+
Object.defineProperty(exports, "mapSignalsError", { enumerable: true, get: function () { return errors_1.mapSignalsError; } });
|
|
67
71
|
__exportStar(require("./client/storage"), exports);
|
|
68
72
|
__exportStar(require("./client/questionnaire-response/methods"), exports);
|
|
69
73
|
__exportStar(require("./client/questionnaire-response/types"), exports);
|
package/dist/types/index.d.ts
CHANGED
|
@@ -18,5 +18,6 @@ export * from "../client/chat/ai/types/CreateAiSessionProps";
|
|
|
18
18
|
export * from "../client/chat/ai/types/SessionMessagesResponse";
|
|
19
19
|
export * from "../client/chat/ai/types/CreateAiSessionResponse";
|
|
20
20
|
export * from "../client/ai-fhir/types";
|
|
21
|
+
export * from "../client/signals/types";
|
|
21
22
|
export * from "./ValidationError";
|
|
22
23
|
export * from "@medplum/core";
|
package/dist/types/index.js
CHANGED
|
@@ -38,6 +38,7 @@ __exportStar(require("../client/chat/ai/types/CreateAiSessionProps"), exports);
|
|
|
38
38
|
__exportStar(require("../client/chat/ai/types/SessionMessagesResponse"), exports);
|
|
39
39
|
__exportStar(require("../client/chat/ai/types/CreateAiSessionResponse"), exports);
|
|
40
40
|
__exportStar(require("../client/ai-fhir/types"), exports);
|
|
41
|
+
__exportStar(require("../client/signals/types"), exports);
|
|
41
42
|
// Common types
|
|
42
43
|
__exportStar(require("./ValidationError"), exports);
|
|
43
44
|
__exportStar(require("@medplum/core"), exports);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ovok/core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"@types/jest": "^29.5.14",
|
|
38
38
|
"@types/node": "^20.11.0",
|
|
39
39
|
"@types/react": "^18.3.12",
|
|
40
|
+
"@types/react-test-renderer": "^18.3.1",
|
|
40
41
|
"eslint": "^9.15.0",
|
|
41
42
|
"eslint-plugin-check-file": "^2.8.0",
|
|
42
43
|
"eslint-plugin-import": "^2.31.0",
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"globals": "^15.12.0",
|
|
46
47
|
"jest": "^29.7.0",
|
|
47
48
|
"react": "^18.3.1",
|
|
49
|
+
"react-test-renderer": "^18.3.1",
|
|
48
50
|
"release-it": "^19.0.6",
|
|
49
51
|
"ts-jest": "^29.2.5",
|
|
50
52
|
"ts-node": "^10.9.2",
|