@ovok/core 0.4.42 → 0.4.43
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 +27 -3
- package/dist/client/auth/session-fetch.js +10 -2
- package/dist/client/auth/session-http.d.ts +4 -2
- package/dist/client/auth/session-http.js +22 -13
- package/dist/client/change-history/methods.js +4 -3
- package/dist/client/change-history/types.d.ts +26 -13
- package/dist/client/errors/ovok-error.js +2 -2
- package/dist/client/notifications/types.d.ts +3 -1
- package/dist/client/ovok-client.d.ts +1 -0
- package/dist/client/ovok-client.js +31 -13
- package/dist/client/slim/methods.d.ts +17 -1
- package/dist/client/slim/methods.js +25 -8
- package/dist/client/slim/types.d.ts +8 -5
- package/dist/conformance/api-requirements.js +0 -1
- package/dist/conformance/capability-requirements.js +1 -1
- package/dist/hooks/notification-hooks.d.ts +1 -0
- package/dist/hooks/notification-hooks.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -330,6 +330,28 @@ validation errors or 424 when the baseline has not been collected. Hooks never r
|
|
|
330
330
|
a stale body; transient 503 transport retries do not clear the session.
|
|
331
331
|
The unconfirmed-limit list and repush routes require project-admin access; a 403 remains an error.
|
|
332
332
|
|
|
333
|
+
Resident deletion returns 409 while the resident has a device; unassign the device with
|
|
334
|
+
`updateSlimPatient()` before deleting. Resident, room, and device writes can also return 422 when
|
|
335
|
+
their device, room, and zone assignments disagree; show the server message and reload before
|
|
336
|
+
retrying. Device serial conflicts return 409 when another customer holds the serial and 422 when
|
|
337
|
+
another device in the project already uses it. Renaming a device moves its serial: old-serial
|
|
338
|
+
readings stop reaching it, and live values return after a reading arrives under the new serial.
|
|
339
|
+
Resident updates replace the editable fields; omitting `locationId` unassigns its devices, and names
|
|
340
|
+
are trimmed by the server.
|
|
341
|
+
|
|
342
|
+
A resident threshold save can return 409 while another save is running; nothing changed, so wait
|
|
343
|
+
briefly and send it again. A home threshold save can return 502 when Signals did not take every
|
|
344
|
+
resident's limits; nothing was written. A home with no saved limits reads as the default template
|
|
345
|
+
with heart rate 40–110 and respiratory rate 8–25 enabled, and `id: null`.
|
|
346
|
+
|
|
347
|
+
Notification feeds and episode reads can wait 5 seconds for Signals before returning 503
|
|
348
|
+
`signals_unavailable`; realtime trends can wait 12 seconds. Realtime trends may also be shed
|
|
349
|
+
immediately under load. Wait for `retryAfterMs` before trying again. The paged medical feed returns
|
|
350
|
+
503 during an outage, while recent medical notifications may return the last good page, up to 10
|
|
351
|
+
minutes old, without a marker. Episode `values` contains only readings the episode counted, not
|
|
352
|
+
valueless or history readings. Acknowledgements can take about 12 seconds and are safe to repeat.
|
|
353
|
+
Realtime trends allow 20 calls per minute per caller; load once per view instead of polling.
|
|
354
|
+
|
|
333
355
|
`getLegalConsent()` returns the signed-in practitioner's own terms status. If
|
|
334
356
|
`needsLegalConsentReacceptance(response.legal)` is true, show the current terms before continuing.
|
|
335
357
|
|
|
@@ -483,9 +505,11 @@ create a second copy of the same observation. The queue is opt-in and requires d
|
|
|
483
505
|
|
|
484
506
|
## Rate limits
|
|
485
507
|
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
508
|
+
Ovok-defined methods, including measurement saves, reject with `RateLimitError` when the server
|
|
509
|
+
returns 429. A 429 or 503 with a retry delay is returned without an automatic retry; wait for
|
|
510
|
+
`retryAfterMs` before trying again. Use `isRateLimitError(error)` and `retryAfterMs` to show a
|
|
511
|
+
translated wait message without parsing backend text. Inherited Medplum FHIR methods keep their
|
|
512
|
+
`OperationOutcomeError`; use `readOvokError(error)` to read their status and delay.
|
|
489
513
|
|
|
490
514
|
## Session management
|
|
491
515
|
|
|
@@ -28,6 +28,14 @@ function createSessionFetch({ config, storage, fetchImplementation, normalizedBa
|
|
|
28
28
|
};
|
|
29
29
|
const fetchOnce = async (url, options) => {
|
|
30
30
|
const response = await (0, session_http_1.fetchWithTimeout)(fetchImplementation, url, options, config.requestTimeoutMs);
|
|
31
|
+
const retry = !response.ok && !isTokenRefresh(url, options)
|
|
32
|
+
? { milliseconds: await (0, session_http_1.retryAfterMs)(response) }
|
|
33
|
+
: undefined;
|
|
34
|
+
if ((retry === null || retry === void 0 ? void 0 : retry.milliseconds) !== undefined &&
|
|
35
|
+
(response.status === 429 || response.status === 503) &&
|
|
36
|
+
options) {
|
|
37
|
+
options.maxRetryTime = 0;
|
|
38
|
+
}
|
|
31
39
|
const requestUrl = new URL(url, normalizedBaseUrl);
|
|
32
40
|
if (isTokenRefresh(url, options)) {
|
|
33
41
|
if (response.status === 400) {
|
|
@@ -68,7 +76,7 @@ function createSessionFetch({ config, storage, fetchImplementation, normalizedBa
|
|
|
68
76
|
}
|
|
69
77
|
return isTokenRefresh(url, options)
|
|
70
78
|
? response
|
|
71
|
-
: (0, session_http_1.withHttpErrorMetadata)(response);
|
|
79
|
+
: (0, session_http_1.withHttpErrorMetadata)(response, retry);
|
|
72
80
|
};
|
|
73
81
|
const fetchWithRefreshRetry = async (url, options) => {
|
|
74
82
|
var _a, _b, _c, _d, _e;
|
|
@@ -150,7 +158,7 @@ function createSessionFetch({ config, storage, fetchImplementation, normalizedBa
|
|
|
150
158
|
break;
|
|
151
159
|
}
|
|
152
160
|
const backoffMs = (0, session_http_1.refreshBackoffMs)(attempt);
|
|
153
|
-
const waitMs = Math.min(Math.max((_b = (0, session_http_1.retryAfterMs)(lastResponse)) !== null && _b !== void 0 ? _b : 0, backoffMs), remainingMs);
|
|
161
|
+
const waitMs = Math.min(Math.max((_b = (await (0, session_http_1.retryAfterMs)(lastResponse))) !== null && _b !== void 0 ? _b : 0, backoffMs), remainingMs);
|
|
154
162
|
if (waitMs >= remainingMs) {
|
|
155
163
|
await (0, session_http_1.waitForRetry)(remainingMs, signal);
|
|
156
164
|
break;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export declare const retryAfterMs: (response: Response) => number | undefined
|
|
2
|
-
export declare const withHttpErrorMetadata: (response: Response
|
|
1
|
+
export declare const retryAfterMs: (response: Response) => Promise<number | undefined>;
|
|
2
|
+
export declare const withHttpErrorMetadata: (response: Response, retry?: {
|
|
3
|
+
milliseconds: number | undefined;
|
|
4
|
+
}) => Promise<Response>;
|
|
3
5
|
export declare const waitForRetry: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
|
|
4
6
|
export declare const isTemporaryRefreshFailure: (status: number) => boolean;
|
|
5
7
|
export declare const refreshUnavailableError: (response?: Response) => Error;
|
|
@@ -2,23 +2,31 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.refreshBackoffMs = exports.fetchWithTimeout = exports.isNetworkError = exports.refreshResponseError = exports.refreshUnavailableError = exports.isTemporaryRefreshFailure = exports.waitForRetry = exports.withHttpErrorMetadata = exports.retryAfterMs = void 0;
|
|
4
4
|
const ovok_error_utils_1 = require("../errors/ovok-error-utils");
|
|
5
|
-
const retryAfterMs = (response) => {
|
|
5
|
+
const retryAfterMs = async (response) => {
|
|
6
6
|
var _a, _b;
|
|
7
7
|
const value = (_b = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, "Retry-After");
|
|
8
|
-
if (
|
|
9
|
-
|
|
8
|
+
if (value) {
|
|
9
|
+
const seconds = Number(value);
|
|
10
|
+
if (Number.isFinite(seconds)) {
|
|
11
|
+
return Math.max(0, seconds * 1000);
|
|
12
|
+
}
|
|
13
|
+
const date = Date.parse(value);
|
|
14
|
+
if (Number.isFinite(date)) {
|
|
15
|
+
return Math.max(0, date - Date.now());
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const body = await response.clone().json();
|
|
20
|
+
return typeof body.retryAfterSec === "number" ? Math.max(0, body.retryAfterSec * 1000) : undefined;
|
|
10
21
|
}
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return Math.max(0, seconds * 1000);
|
|
22
|
+
catch (_c) {
|
|
23
|
+
return undefined;
|
|
14
24
|
}
|
|
15
|
-
const date = Date.parse(value);
|
|
16
|
-
return Number.isFinite(date) ? Math.max(0, date - Date.now()) : undefined;
|
|
17
25
|
};
|
|
18
26
|
exports.retryAfterMs = retryAfterMs;
|
|
19
27
|
const timeoutError = () => (0, ovok_error_utils_1.namedError)("TimeoutError", "The request timed out.");
|
|
20
|
-
const withHttpErrorMetadata = async (response) => {
|
|
21
|
-
var _a
|
|
28
|
+
const withHttpErrorMetadata = async (response, retry) => {
|
|
29
|
+
var _a;
|
|
22
30
|
if (response.ok || typeof response.clone !== "function") {
|
|
23
31
|
return response;
|
|
24
32
|
}
|
|
@@ -28,7 +36,7 @@ const withHttpErrorMetadata = async (response) => {
|
|
|
28
36
|
bodyText = await response.clone().text();
|
|
29
37
|
body = JSON.parse(bodyText);
|
|
30
38
|
}
|
|
31
|
-
catch (
|
|
39
|
+
catch (_b) {
|
|
32
40
|
body = undefined;
|
|
33
41
|
}
|
|
34
42
|
const outcome = body && typeof body === "object" && body.resourceType === "OperationOutcome"
|
|
@@ -42,8 +50,8 @@ const withHttpErrorMetadata = async (response) => {
|
|
|
42
50
|
? Object.fromEntries(Object.entries(envelope).filter(([key]) => ["code", "error", "message", "requestId", "retryAfterSec", "status", "statusCode", "errors", "missing"].includes(key)))
|
|
43
51
|
: { message: typeof body === "string" ? body : response.statusText };
|
|
44
52
|
const status = response.status;
|
|
45
|
-
const retryAfter =
|
|
46
|
-
const requestId = (
|
|
53
|
+
const retryAfter = retry ? retry.milliseconds : await (0, exports.retryAfterMs)(response);
|
|
54
|
+
const requestId = (_a = response.headers.get("x-request-id")) !== null && _a !== void 0 ? _a : (typeof (envelope === null || envelope === void 0 ? void 0 : envelope.requestId) === "string" ? envelope.requestId : undefined);
|
|
47
55
|
const message = typeof (envelope === null || envelope === void 0 ? void 0 : envelope.message) === "string"
|
|
48
56
|
? envelope.message
|
|
49
57
|
: typeof (nestedError === null || nestedError === void 0 ? void 0 : nestedError.message) === "string"
|
|
@@ -79,6 +87,7 @@ const withHttpErrorMetadata = async (response) => {
|
|
|
79
87
|
];
|
|
80
88
|
const headers = new Headers(response.headers);
|
|
81
89
|
headers.delete("content-length");
|
|
90
|
+
headers.delete("content-encoding");
|
|
82
91
|
headers.set("content-type", "application/fhir+json");
|
|
83
92
|
return new Response(JSON.stringify(enrichedOutcome), {
|
|
84
93
|
status,
|
|
@@ -9,9 +9,10 @@ function serializeChangeHistoryQuery(params = {}) {
|
|
|
9
9
|
if (value === undefined) {
|
|
10
10
|
continue;
|
|
11
11
|
}
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
if (Array.isArray(value)) {
|
|
13
|
+
const name = key === "types" ? "types[]" : key;
|
|
14
|
+
for (const item of value) {
|
|
15
|
+
search.append(name, item);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
else {
|
|
@@ -1,28 +1,41 @@
|
|
|
1
|
-
export type ChangeHistoryKey = "deviceCreated" | "deviceDeleted" | "deviceProjectChanged" | "deviceLocationChanged" | "deviceZoneChanged" | "deviceRenamed" | "locationCreated" | "locationDeleted" | "locationRenamed" | "locationZoneChanged" | "locationFloorChanged" | "locationRoomChanged" | "locationBedChanged" | "zoneCreated" | "zoneDeleted" | "zoneRenamed";
|
|
1
|
+
export type ChangeHistoryKey = "residentDeleted" | "residentMaidenNameChanged" | "orgThresholdRangeChanged" | "patientSignalsThresholdSet" | "patientSignalsThresholdRemoved" | "orgSignalsSettingsChanged" | "userInvited" | "userRenamed" | "userRoleChanged" | "userRemoved" | "roleCreated" | "roleDeleted" | "rolePermissionsChanged" | "residentAssignedToDeviceAndLocation" | "residentUnassignedFromDevicesAndLocation" | "residentUnassignedFromDevicesAndLocationWithZone" | "residentUnassignedFromDeviceAndLocation" | "residentDeviceAssigned" | "residentDeviceUnassigned" | "residentMovedToLocation" | "residentRemovedFromLocation" | "residentMovedToZone" | "residentRemovedFromZone" | "patientThresholdMetricSetToIndividual" | "patientThresholdMetricSetToGlobal" | "patientTimeOutOfBedMetricSetToIndividual" | "patientTimeOutOfBedMetricSetToGlobal" | "orgTimeOutOfBedMetricUpdated" | "residentDischarged" | "residentReactivated" | "residentArchived" | "residentNameChanged" | "orgThresholdMetricUpdated" | "patientThresholdMetricUpdated" | "deviceCreated" | "deviceDeleted" | "deviceProjectChanged" | "deviceLocationChanged" | "deviceZoneChanged" | "deviceRenamed" | "locationCreated" | "locationDeleted" | "locationRenamed" | "locationZoneChanged" | "locationFloorChanged" | "locationRoomChanged" | "locationBedChanged" | "zoneCreated" | "zoneDeleted" | "zoneRenamed";
|
|
2
|
+
export type ChangeHistoryType = "Threshold" | "Location" | "Zone" | "Device" | "Resident" | "Access";
|
|
3
|
+
export type ChangeHistoryScope = "all" | "global";
|
|
4
|
+
export type ChangeHistorySort = "asc" | "desc";
|
|
5
|
+
export type ChangeHistoryAction = "created" | "deleted" | "renamed" | "moved" | "assigned" | "unassigned" | "discharged" | "reactivated" | "thresholdChanged";
|
|
6
|
+
export type ChangeHistoryResident = {
|
|
7
|
+
patientId: string;
|
|
8
|
+
residentId: string | null;
|
|
9
|
+
};
|
|
10
|
+
export type ChangeHistoryReference = `Patient/${string}` | `Device/${string}` | `Location/${string}` | `Organization/${string}` | `Practitioner/${string}` | `AccessPolicy/${string}`;
|
|
2
11
|
export type ChangeHistoryRow = {
|
|
3
12
|
id: string;
|
|
4
|
-
type:
|
|
5
|
-
user:
|
|
6
|
-
residentId: string
|
|
7
|
-
deviceId: string
|
|
13
|
+
type: ChangeHistoryType;
|
|
14
|
+
user: string;
|
|
15
|
+
residentId: string;
|
|
16
|
+
deviceId: string;
|
|
17
|
+
resident: ChangeHistoryResident | null;
|
|
8
18
|
locationId?: string | null;
|
|
9
19
|
zoneId?: string | null;
|
|
10
20
|
time: string;
|
|
11
21
|
details: {
|
|
12
22
|
key: ChangeHistoryKey | (string & {});
|
|
13
|
-
values: Record<string,
|
|
23
|
+
values: Record<string, string | number | null>;
|
|
14
24
|
};
|
|
15
25
|
};
|
|
16
26
|
export type ChangeHistoryQuery = {
|
|
17
27
|
page?: number;
|
|
18
28
|
count?: number;
|
|
19
|
-
types?: readonly
|
|
20
|
-
scope?:
|
|
21
|
-
userId?: string;
|
|
22
|
-
residentId?: string;
|
|
23
|
-
deviceId?: string;
|
|
24
|
-
locationId?: string;
|
|
25
|
-
zoneId?: string;
|
|
29
|
+
types?: readonly ChangeHistoryType[];
|
|
30
|
+
scope?: ChangeHistoryScope;
|
|
31
|
+
userId?: string | readonly string[];
|
|
32
|
+
residentId?: string | readonly string[];
|
|
33
|
+
deviceId?: string | readonly string[];
|
|
34
|
+
locationId?: string | readonly string[];
|
|
35
|
+
zoneId?: string | readonly string[];
|
|
36
|
+
relatedTo?: ChangeHistoryReference | readonly ChangeHistoryReference[];
|
|
37
|
+
actions?: ChangeHistoryAction | readonly ChangeHistoryAction[];
|
|
38
|
+
sort?: ChangeHistorySort;
|
|
26
39
|
startDate?: string;
|
|
27
40
|
endDate?: string;
|
|
28
41
|
};
|
|
@@ -103,8 +103,8 @@ function mapOvokApiError(error, options = {}) {
|
|
|
103
103
|
}
|
|
104
104
|
const details = (0, exports.readOvokError)(error);
|
|
105
105
|
const typedStatuses = options.includeAccessErrors
|
|
106
|
-
? [403, 404, 409, 422, 424, 503]
|
|
107
|
-
: [409, 422, 424, 503];
|
|
106
|
+
? [403, 404, 409, 410, 422, 424, 503]
|
|
107
|
+
: [409, 410, 422, 424, 503];
|
|
108
108
|
return typedStatuses.includes((_a = details.status) !== null && _a !== void 0 ? _a : 0)
|
|
109
109
|
? new OvokApiError(details, error)
|
|
110
110
|
: error;
|
|
@@ -128,6 +128,8 @@ export type SlimMedicalEpisodeValue = {
|
|
|
128
128
|
observedAt: string | null;
|
|
129
129
|
recordedAt: string;
|
|
130
130
|
};
|
|
131
|
+
/** STALE closes an out-of-bed episode that stayed open for 48 hours. */
|
|
132
|
+
export type SlimEpisodeCloseReason = "RECOVERED" | "TIMEOUT" | "ACKNOWLEDGED" | "CROSSED" | "THRESHOLD_CHANGED" | "AWAY" | "STALE" | "MANUAL";
|
|
131
133
|
export type SlimMedicalEpisodeCore = {
|
|
132
134
|
id: string;
|
|
133
135
|
patientId: string;
|
|
@@ -137,7 +139,7 @@ export type SlimMedicalEpisodeCore = {
|
|
|
137
139
|
status: string;
|
|
138
140
|
openedAt: string;
|
|
139
141
|
closedAt: string | null;
|
|
140
|
-
closeReason: string | null;
|
|
142
|
+
closeReason: SlimEpisodeCloseReason | (string & {}) | null;
|
|
141
143
|
lastSampleAt: string | null;
|
|
142
144
|
durationMs: number | null;
|
|
143
145
|
observationCount: number | null;
|
|
@@ -136,6 +136,7 @@ export declare class OvokClient extends MedplumClient {
|
|
|
136
136
|
* account differs from `account`: the rest of a reading is never written under someone else's sign-in.
|
|
137
137
|
*/
|
|
138
138
|
private executeObservationBundle;
|
|
139
|
+
private mapError;
|
|
139
140
|
private bindMethods;
|
|
140
141
|
/**
|
|
141
142
|
* Gets the `SubscriptionManager` for WebSocket subscriptions.
|
|
@@ -261,7 +261,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
261
261
|
((_b = previousLogin.profile) === null || _b === void 0 ? void 0 : _b.reference) !== accountId) {
|
|
262
262
|
await this.restoreActiveLogin(previousLogin);
|
|
263
263
|
}
|
|
264
|
-
throw error;
|
|
264
|
+
throw this.mapError(error);
|
|
265
265
|
}
|
|
266
266
|
}
|
|
267
267
|
/**
|
|
@@ -284,7 +284,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
284
284
|
}
|
|
285
285
|
catch (error) {
|
|
286
286
|
if (!sessionClient.getSavedAccounts().some((account) => account.id === accountId && account.expired)) {
|
|
287
|
-
throw error;
|
|
287
|
+
throw this.mapError(error);
|
|
288
288
|
}
|
|
289
289
|
}
|
|
290
290
|
this.removeSavedAccount(accountId);
|
|
@@ -326,11 +326,21 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
326
326
|
}
|
|
327
327
|
/** Reads Ovok's composed FHIR and public-route capability statement. */
|
|
328
328
|
async getCapabilityStatement(version = "R4", requestOptions) {
|
|
329
|
-
|
|
329
|
+
try {
|
|
330
|
+
return await this.get(`/fhir/${version}/metadata`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
331
|
+
}
|
|
332
|
+
catch (error) {
|
|
333
|
+
throw this.mapError(error);
|
|
334
|
+
}
|
|
330
335
|
}
|
|
331
336
|
/** Returns the non-FHIR public routes published by the backend statement. */
|
|
332
337
|
async getPublicApiEndpoints(version = "R4", requestOptions) {
|
|
333
|
-
|
|
338
|
+
try {
|
|
339
|
+
return (0, capability_1.getOvokPublicApiEndpoints)(await this.getCapabilityStatement(version, ...(0, request_options_1.optionalArg)(requestOptions)));
|
|
340
|
+
}
|
|
341
|
+
catch (error) {
|
|
342
|
+
throw this.mapError(error);
|
|
343
|
+
}
|
|
334
344
|
}
|
|
335
345
|
/**
|
|
336
346
|
* Saves one reading's observations, main first, with conditional creates so a retry cannot create a duplicate.
|
|
@@ -518,16 +528,24 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
518
528
|
* account differs from `account`: the rest of a reading is never written under someone else's sign-in.
|
|
519
529
|
*/
|
|
520
530
|
async executeObservationBundle(bundle, requestOptions, account = this.accountKey()) {
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
531
|
+
try {
|
|
532
|
+
const response = await (0, observation_bundle_utils_1.executeObservationBundle)(bundle, (request) => {
|
|
533
|
+
if (this.accountKey() !== account) {
|
|
534
|
+
throw new Error("The signed-in account changed during the save; the rest of it was not sent.");
|
|
535
|
+
}
|
|
536
|
+
return this.executeBatch(request, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
537
|
+
});
|
|
538
|
+
this.invalidateSearches("Observation");
|
|
539
|
+
return response;
|
|
540
|
+
}
|
|
541
|
+
catch (error) {
|
|
542
|
+
throw this.mapError(error);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
mapError(error) {
|
|
546
|
+
return (0, ovok_error_1.mapOvokApiError)((0, rate_limit_error_1.mapRateLimitError)(error));
|
|
529
547
|
}
|
|
530
|
-
bindMethods(methods, mapError = (error) =>
|
|
548
|
+
bindMethods(methods, mapError = (error) => this.mapError(error)) {
|
|
531
549
|
for (const [name, method] of Object.entries(methods)) {
|
|
532
550
|
const boundMethod = method.bind(this);
|
|
533
551
|
this[name] = async (...args) => {
|
|
@@ -7,18 +7,22 @@ export declare function listSlimPatients(this: OvokClient, params?: SlimPatientL
|
|
|
7
7
|
export declare function getSlimPatient(this: OvokClient, patientId: string, requestOptions?: MedplumRequestOptions): Promise<SlimPatient>;
|
|
8
8
|
export declare function getSlimPatientEverything(this: OvokClient, patientId: string, requestOptions?: MedplumRequestOptions): Promise<Bundle<Resource>>;
|
|
9
9
|
export declare function getSlimPatientCurrentVitals(this: OvokClient, patientId: string, requestOptions?: MedplumRequestOptions): Promise<Record<string, unknown>>;
|
|
10
|
+
/** 422 when organizationId has no locationId or deviceId, or the assigned devices span zones. */
|
|
10
11
|
export declare function createSlimPatient(this: OvokClient, body: SlimCreatePatient, requestOptions?: MedplumRequestOptions): Promise<SlimPatient>;
|
|
12
|
+
/** Replaces editable fields; omitting locationId unassigns devices; 422 for null, empty, or [] deviceId with a location or devices across zones. Names are trimmed. */
|
|
11
13
|
export declare function updateSlimPatient(this: OvokClient, patientId: string, body: SlimUpdatePatient, requestOptions?: MedplumRequestOptions): Promise<SlimPatient>;
|
|
14
|
+
/** 409 while the resident has a device; unassign it first with updateSlimPatient and no locationId. */
|
|
12
15
|
export declare function deleteSlimPatient(this: OvokClient, patientId: string, requestOptions?: MedplumRequestOptions): Promise<void>;
|
|
13
16
|
export declare function listSlimDevices(this: OvokClient, params?: SlimDeviceListQuery, requestOptions?: MedplumRequestOptions): Promise<SlimPage<SlimDeviceListItem>>;
|
|
14
17
|
export declare function getSlimDevice(this: OvokClient, deviceId: string, requestOptions?: MedplumRequestOptions): Promise<SlimDevice>;
|
|
18
|
+
/** 409 when another customer holds the serial; 422 when this project already uses it or its organization differs from the room's zone. */
|
|
15
19
|
export declare function createSlimDevice(this: OvokClient, body: SlimCreateDevice, requestOptions?: MedplumRequestOptions): Promise<SlimDevice>;
|
|
20
|
+
/** 409 when another customer holds the serial; 422 when this project already uses it or its organization differs from the room's zone. Renaming moves the serial, so old-serial readings stop and live values return after a reading under the new serial. */
|
|
16
21
|
export declare function updateSlimDevice(this: OvokClient, deviceId: string, body: SlimUpdateDevice, requestOptions?: MedplumRequestOptions): Promise<SlimDevice>;
|
|
17
22
|
export declare function deleteSlimDevice(this: OvokClient, deviceId: string, requestOptions?: MedplumRequestOptions): Promise<void>;
|
|
18
23
|
export declare function assignSlimDeviceToProject(this: OvokClient, body: SlimAssignDevice, requestOptions?: MedplumRequestOptions): Promise<SlimDevice>;
|
|
19
24
|
export declare function listSlimLiveDevices(this: OvokClient, params?: SlimLiveQuery, requestOptions?: MedplumRequestOptions): Promise<SlimPage<Record<string, unknown>>>;
|
|
20
25
|
export declare function listSlimLiveTelemetry(this: OvokClient, params?: SlimLiveQuery, requestOptions?: MedplumRequestOptions): Promise<SlimLiveTelemetry>;
|
|
21
|
-
export declare function getSlimDeviceSleepStatus(this: OvokClient, deviceId: string, requestOptions?: MedplumRequestOptions): Promise<Record<string, unknown>>;
|
|
22
26
|
export declare function getSlimDeviceTelemetry(this: OvokClient, deviceId: string, requestOptions?: MedplumRequestOptions): Promise<SlimDeviceTelemetry>;
|
|
23
27
|
export declare function listSlimEffectiveObservationIds(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<Record<string, SlimObservationIds>>;
|
|
24
28
|
export declare function listSlimLastObservationIds(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<Record<string, SlimObservationIds>>;
|
|
@@ -28,6 +32,7 @@ export declare function getSlimDeviceLastObservationIds(this: OvokClient, device
|
|
|
28
32
|
export declare function listSlimNotifications(this: OvokClient, params?: SlimNotificationsQuery, requestOptions?: MedplumRequestOptions): Promise<SlimNotificationsResponse>;
|
|
29
33
|
export declare function getRecentSlimNotifications(this: OvokClient, count?: number, requestOptions?: MedplumRequestOptions): Promise<SlimRecentNotificationsResponse>;
|
|
30
34
|
export declare function listSlimAlarms(this: OvokClient, params?: SlimAlarmQuery, requestOptions?: MedplumRequestOptions): Promise<SlimAlarmsPage>;
|
|
35
|
+
/** Can take about 12 s; a 503 signals_unavailable means it was not confirmed, so repeat after retryAfterMs (safe to repeat). */
|
|
31
36
|
export declare function acknowledgeSlimAlarm(this: OvokClient, notificationId: string, requestOptions?: MedplumRequestOptions): Promise<SlimNotification>;
|
|
32
37
|
export declare function getRecentSlimAlarms(this: OvokClient, count?: number, requestOptions?: MedplumRequestOptions): Promise<SlimRecentAlarms>;
|
|
33
38
|
/** Same as `getRecentSlimAlarms`. */
|
|
@@ -35,24 +40,33 @@ export declare function getRecentAlarms(this: OvokClient, count?: number, reques
|
|
|
35
40
|
export declare function getRecentSlimOutOfBed(this: OvokClient, count?: number, requestOptions?: MedplumRequestOptions): Promise<SlimRecentOutOfBed>;
|
|
36
41
|
/** Same as `getRecentSlimOutOfBed`. */
|
|
37
42
|
export declare function getRecentOutOfBed(this: OvokClient, count?: number, requestOptions?: MedplumRequestOptions): Promise<SlimRecentOutOfBed>;
|
|
43
|
+
/** Omitting status lists new and reviewed rows; active is new, completed reviewed, and revoked hand-closed. */
|
|
38
44
|
export declare function listSlimOutOfBedNotifications(this: OvokClient, params?: Omit<SlimNotificationsQuery, "type">, requestOptions?: MedplumRequestOptions): Promise<SlimNotificationsResponse>;
|
|
39
45
|
export declare function listSlimMedicalNotifications(this: OvokClient, params?: SlimMedicalNotificationsQuery, requestOptions?: MedplumRequestOptions): Promise<SlimMedicalNotificationsPage>;
|
|
46
|
+
/** During a Signals outage, this may return the last good page from up to 10 minutes ago, without a marker. */
|
|
40
47
|
export declare function getRecentSlimMedicalNotifications(this: OvokClient, count?: number, requestOptions?: MedplumRequestOptions): Promise<SlimRecentNotificationsResponse>;
|
|
41
48
|
export declare function getSlimMedicalNotification(this: OvokClient, episodeId: string, requestOptions?: MedplumRequestOptions): Promise<SlimMedicalNotificationDetail>;
|
|
49
|
+
/** Can take about 12 s; a 503 signals_unavailable means it was not confirmed, so repeat after retryAfterMs (safe to repeat). */
|
|
42
50
|
export declare function acknowledgeSlimMedicalNotification(this: OvokClient, episodeId: string, requestOptions?: MedplumRequestOptions): Promise<SlimMedicalNotificationRow>;
|
|
43
51
|
/** Same as `acknowledgeSlimAlarm`. */
|
|
44
52
|
export declare function acknowledgeSlimNotification(this: OvokClient, notificationId: string, requestOptions?: MedplumRequestOptions): Promise<SlimNotification>;
|
|
53
|
+
/** A home with no stored limits reads as the default template, not as unset. */
|
|
45
54
|
export declare function getSlimThreshold(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<SlimThreshold>;
|
|
55
|
+
/** A 502 means Signals did not take every resident's limits and nothing was written. */
|
|
46
56
|
export declare function updateSlimThreshold(this: OvokClient, body: {
|
|
47
57
|
settings: SlimThresholdSettingsUpdateV1;
|
|
48
58
|
}, requestOptions?: MedplumRequestOptions): Promise<SlimThreshold>;
|
|
49
59
|
export declare function getSlimPatientThreshold(this: OvokClient, patientId: string, requestOptions?: MedplumRequestOptions): Promise<Record<string, unknown>>;
|
|
60
|
+
/** 409 means another save for this resident is running and nothing changed; wait briefly, then send again. */
|
|
50
61
|
export declare function updateSlimPatientThreshold(this: OvokClient, patientId: string, body: {
|
|
51
62
|
settings: SlimThresholdSettingsUpdateV1;
|
|
52
63
|
}, requestOptions?: MedplumRequestOptions): Promise<Record<string, unknown>>;
|
|
64
|
+
/** A home with no stored limits reads as the default template, not as unset. */
|
|
53
65
|
export declare function getSlimThresholdV2(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<SlimThresholdV2>;
|
|
66
|
+
/** A 502 means Signals did not take every resident's limits and nothing was written. */
|
|
54
67
|
export declare function updateSlimThresholdV2(this: OvokClient, body: SlimThresholdV2Update, requestOptions?: MedplumRequestOptions): Promise<SlimThresholdV2>;
|
|
55
68
|
export declare function getSlimPatientThresholdV2(this: OvokClient, patientId: string, requestOptions?: MedplumRequestOptions): Promise<SlimPatientThresholdV2>;
|
|
69
|
+
/** 409 means another save for this resident is running and nothing changed; wait briefly, then send again. */
|
|
56
70
|
export declare function updateSlimPatientThresholdV2(this: OvokClient, patientId: string, body: SlimThresholdV2Update, requestOptions?: MedplumRequestOptions): Promise<SlimPatientThresholdV2>;
|
|
57
71
|
export declare function getSlimTrends(this: OvokClient, params: {
|
|
58
72
|
patientId: string;
|
|
@@ -60,6 +74,7 @@ export declare function getSlimTrends(this: OvokClient, params: {
|
|
|
60
74
|
endDate: string;
|
|
61
75
|
graphType: SlimHistoricalGraphType | readonly SlimHistoricalGraphType[];
|
|
62
76
|
}, requestOptions?: MedplumRequestOptions): Promise<SlimTrends>;
|
|
77
|
+
/** At most 20 calls per minute per caller; load once per view and wait retryAfterMs after 503. */
|
|
63
78
|
export declare function getSlimRealtimeTrends(this: OvokClient, params: {
|
|
64
79
|
patientId: string;
|
|
65
80
|
startTime: string;
|
|
@@ -74,6 +89,7 @@ export declare function getSlimSleepStatistics(this: OvokClient, params: {
|
|
|
74
89
|
export declare function listSlimLocations(this: OvokClient, params?: SlimLocationQuery, requestOptions?: MedplumRequestOptions): Promise<SlimPage<SlimLocation>>;
|
|
75
90
|
export declare function getSlimLocation(this: OvokClient, locationId: string, requestOptions?: MedplumRequestOptions): Promise<SlimLocation>;
|
|
76
91
|
export declare function createSlimLocation(this: OvokClient, body: SlimCreateLocation, requestOptions?: MedplumRequestOptions): Promise<SlimLocation>;
|
|
92
|
+
/** 422 Device not found means the requested device is unreadable; nothing was saved. */
|
|
77
93
|
export declare function updateSlimLocation(this: OvokClient, locationId: string, body: SlimUpdateLocation, requestOptions?: MedplumRequestOptions): Promise<SlimLocation>;
|
|
78
94
|
export declare function deleteSlimLocation(this: OvokClient, locationId: string, requestOptions?: MedplumRequestOptions): Promise<void>;
|
|
79
95
|
export declare function listSlimZones(this: OvokClient, params?: {
|
|
@@ -15,7 +15,6 @@ exports.deleteSlimDevice = deleteSlimDevice;
|
|
|
15
15
|
exports.assignSlimDeviceToProject = assignSlimDeviceToProject;
|
|
16
16
|
exports.listSlimLiveDevices = listSlimLiveDevices;
|
|
17
17
|
exports.listSlimLiveTelemetry = listSlimLiveTelemetry;
|
|
18
|
-
exports.getSlimDeviceSleepStatus = getSlimDeviceSleepStatus;
|
|
19
18
|
exports.getSlimDeviceTelemetry = getSlimDeviceTelemetry;
|
|
20
19
|
exports.listSlimEffectiveObservationIds = listSlimEffectiveObservationIds;
|
|
21
20
|
exports.listSlimLastObservationIds = listSlimLastObservationIds;
|
|
@@ -97,12 +96,15 @@ async function getSlimPatientEverything(patientId, requestOptions) {
|
|
|
97
96
|
async function getSlimPatientCurrentVitals(patientId, requestOptions) {
|
|
98
97
|
return this.get(`/v1/slim/patient/${encodeURIComponent(patientId)}/current-vitals`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
99
98
|
}
|
|
99
|
+
/** 422 when organizationId has no locationId or deviceId, or the assigned devices span zones. */
|
|
100
100
|
async function createSlimPatient(body, requestOptions) {
|
|
101
101
|
return this.post("/v1/slim/patient", body, undefined, requestOptions);
|
|
102
102
|
}
|
|
103
|
+
/** Replaces editable fields; omitting locationId unassigns devices; 422 for null, empty, or [] deviceId with a location or devices across zones. Names are trimmed. */
|
|
103
104
|
async function updateSlimPatient(patientId, body, requestOptions) {
|
|
104
105
|
return (await this.put(`/v1/slim/patient/${encodeURIComponent(patientId)}`, body, undefined, requestOptions));
|
|
105
106
|
}
|
|
107
|
+
/** 409 while the resident has a device; unassign it first with updateSlimPatient and no locationId. */
|
|
106
108
|
async function deleteSlimPatient(patientId, requestOptions) {
|
|
107
109
|
await this.delete(`/v1/slim/patient/${encodeURIComponent(patientId)}`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
108
110
|
}
|
|
@@ -112,9 +114,11 @@ async function listSlimDevices(params = {}, requestOptions) {
|
|
|
112
114
|
async function getSlimDevice(deviceId, requestOptions) {
|
|
113
115
|
return this.get(`/v1/slim/device/${encodeURIComponent(deviceId)}`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
114
116
|
}
|
|
117
|
+
/** 409 when another customer holds the serial; 422 when this project already uses it or its organization differs from the room's zone. */
|
|
115
118
|
async function createSlimDevice(body, requestOptions) {
|
|
116
119
|
return this.post("/v1/slim/device", body, undefined, requestOptions);
|
|
117
120
|
}
|
|
121
|
+
/** 409 when another customer holds the serial; 422 when this project already uses it or its organization differs from the room's zone. Renaming moves the serial, so old-serial readings stop and live values return after a reading under the new serial. */
|
|
118
122
|
async function updateSlimDevice(deviceId, body, requestOptions) {
|
|
119
123
|
return (await this.put(`/v1/slim/device/${encodeURIComponent(deviceId)}`, body, undefined, requestOptions));
|
|
120
124
|
}
|
|
@@ -132,9 +136,6 @@ async function listSlimLiveTelemetry(params = {}, requestOptions) {
|
|
|
132
136
|
validateLiveCount(params);
|
|
133
137
|
return (0, live_read_1.liveGet)(this, `/v1/slim/device/live/telemetry${(0, query_string_1.toQueryString)(params)}`, requestOptions);
|
|
134
138
|
}
|
|
135
|
-
async function getSlimDeviceSleepStatus(deviceId, requestOptions) {
|
|
136
|
-
return (0, live_read_1.liveGet)(this, `/v1/slim/device/live/cloudwatch/${encodeURIComponent(deviceId)}`, requestOptions);
|
|
137
|
-
}
|
|
138
139
|
async function getSlimDeviceTelemetry(deviceId, requestOptions) {
|
|
139
140
|
return (0, live_read_1.liveGet)(this, `/v1/slim/telemetry/${encodeURIComponent(deviceId)}`, requestOptions);
|
|
140
141
|
}
|
|
@@ -160,6 +161,7 @@ async function getRecentSlimNotifications(count, requestOptions) {
|
|
|
160
161
|
async function listSlimAlarms(params = {}, requestOptions) {
|
|
161
162
|
return this.get(`/v1/slim/notifications/alarms${(0, query_string_1.toQueryString)(params)}`, { cache: "reload", ...requestOptions });
|
|
162
163
|
}
|
|
164
|
+
/** Can take about 12 s; a 503 signals_unavailable means it was not confirmed, so repeat after retryAfterMs (safe to repeat). */
|
|
163
165
|
async function acknowledgeSlimAlarm(notificationId, requestOptions) {
|
|
164
166
|
return (await this.patch(`/v1/slim/notifications/${encodeURIComponent(notificationId)}/ack`, [], ...(0, request_options_1.optionalArg)(requestOptions)));
|
|
165
167
|
}
|
|
@@ -177,6 +179,7 @@ async function getRecentSlimOutOfBed(count, requestOptions) {
|
|
|
177
179
|
function getRecentOutOfBed(count, requestOptions) {
|
|
178
180
|
return getRecentSlimOutOfBed.call(this, count, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
179
181
|
}
|
|
182
|
+
/** Omitting status lists new and reviewed rows; active is new, completed reviewed, and revoked hand-closed. */
|
|
180
183
|
async function listSlimOutOfBedNotifications(params = {}, requestOptions) {
|
|
181
184
|
return this.get(`/v1/slim/notifications/oob${(0, query_string_1.toQueryString)(params)}`, { cache: "reload", ...requestOptions });
|
|
182
185
|
}
|
|
@@ -191,12 +194,14 @@ function validateMedicalCodes(codes) {
|
|
|
191
194
|
throw new TypeError("codes must contain at most 32 valid LOINC codes or PI.");
|
|
192
195
|
}
|
|
193
196
|
}
|
|
197
|
+
/** During a Signals outage, this may return the last good page from up to 10 minutes ago, without a marker. */
|
|
194
198
|
async function getRecentSlimMedicalNotifications(count, requestOptions) {
|
|
195
199
|
return this.get(`/v1/slim/notifications/recent/medical${(0, query_string_1.toQueryString)({ count })}`, { cache: "reload", ...requestOptions });
|
|
196
200
|
}
|
|
197
201
|
async function getSlimMedicalNotification(episodeId, requestOptions) {
|
|
198
202
|
return this.get(`/v1/slim/notifications/medical/${encodeURIComponent(episodeId)}`, { cache: "reload", ...requestOptions });
|
|
199
203
|
}
|
|
204
|
+
/** Can take about 12 s; a 503 signals_unavailable means it was not confirmed, so repeat after retryAfterMs (safe to repeat). */
|
|
200
205
|
async function acknowledgeSlimMedicalNotification(episodeId, requestOptions) {
|
|
201
206
|
return this.post(`/v1/slim/notifications/medical/${encodeURIComponent(episodeId)}/ack`, undefined, undefined, requestOptions);
|
|
202
207
|
}
|
|
@@ -204,33 +209,44 @@ async function acknowledgeSlimMedicalNotification(episodeId, requestOptions) {
|
|
|
204
209
|
function acknowledgeSlimNotification(notificationId, requestOptions) {
|
|
205
210
|
return acknowledgeSlimAlarm.call(this, notificationId, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
206
211
|
}
|
|
212
|
+
/** A home with no stored limits reads as the default template, not as unset. */
|
|
207
213
|
async function getSlimThreshold(requestOptions) {
|
|
208
214
|
return this.get("/v1/slim/threshold", ...(0, request_options_1.optionalArg)(requestOptions));
|
|
209
215
|
}
|
|
216
|
+
/** A 502 means Signals did not take every resident's limits and nothing was written. */
|
|
210
217
|
async function updateSlimThreshold(body, requestOptions) {
|
|
211
|
-
return (await this.put("/v1/slim/threshold", body, undefined,
|
|
218
|
+
return (await this.put("/v1/slim/threshold", body, undefined, {
|
|
219
|
+
...requestOptions, maxRetries: 0, maxRetryTime: 0,
|
|
220
|
+
}));
|
|
212
221
|
}
|
|
213
222
|
async function getSlimPatientThreshold(patientId, requestOptions) {
|
|
214
223
|
return this.get(`/v1/slim/threshold/patient/${encodeURIComponent(patientId)}`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
215
224
|
}
|
|
225
|
+
/** 409 means another save for this resident is running and nothing changed; wait briefly, then send again. */
|
|
216
226
|
async function updateSlimPatientThreshold(patientId, body, requestOptions) {
|
|
217
|
-
return (await this.put(`/v1/slim/threshold/patient/${encodeURIComponent(patientId)}`, body, undefined, requestOptions));
|
|
227
|
+
return (await this.put(`/v1/slim/threshold/patient/${encodeURIComponent(patientId)}`, body, undefined, { ...requestOptions, maxRetries: 0, maxRetryTime: 0 }));
|
|
218
228
|
}
|
|
229
|
+
/** A home with no stored limits reads as the default template, not as unset. */
|
|
219
230
|
async function getSlimThresholdV2(requestOptions) {
|
|
220
231
|
return this.get("/v2/slim/threshold", ...(0, request_options_1.optionalArg)(requestOptions));
|
|
221
232
|
}
|
|
233
|
+
/** A 502 means Signals did not take every resident's limits and nothing was written. */
|
|
222
234
|
async function updateSlimThresholdV2(body, requestOptions) {
|
|
223
|
-
return (await this.put("/v2/slim/threshold", body, undefined,
|
|
235
|
+
return (await this.put("/v2/slim/threshold", body, undefined, {
|
|
236
|
+
...requestOptions, maxRetries: 0, maxRetryTime: 0,
|
|
237
|
+
}));
|
|
224
238
|
}
|
|
225
239
|
async function getSlimPatientThresholdV2(patientId, requestOptions) {
|
|
226
240
|
return this.get(`/v2/slim/threshold/patient/${encodeURIComponent(patientId)}`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
227
241
|
}
|
|
242
|
+
/** 409 means another save for this resident is running and nothing changed; wait briefly, then send again. */
|
|
228
243
|
async function updateSlimPatientThresholdV2(patientId, body, requestOptions) {
|
|
229
|
-
return (await this.put(`/v2/slim/threshold/patient/${encodeURIComponent(patientId)}`, body, undefined, requestOptions));
|
|
244
|
+
return (await this.put(`/v2/slim/threshold/patient/${encodeURIComponent(patientId)}`, body, undefined, { ...requestOptions, maxRetries: 0, maxRetryTime: 0 }));
|
|
230
245
|
}
|
|
231
246
|
async function getSlimTrends(params, requestOptions) {
|
|
232
247
|
return this.get(`/v1/slim/trends/graphs${(0, query_string_1.toQueryString)(params)}`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
233
248
|
}
|
|
249
|
+
/** At most 20 calls per minute per caller; load once per view and wait retryAfterMs after 503. */
|
|
234
250
|
async function getSlimRealtimeTrends(params, requestOptions) {
|
|
235
251
|
return this.get(`/v1/slim/trends/realtime${(0, query_string_1.toQueryString)(params)}`, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
236
252
|
}
|
|
@@ -246,6 +262,7 @@ async function getSlimLocation(locationId, requestOptions) {
|
|
|
246
262
|
async function createSlimLocation(body, requestOptions) {
|
|
247
263
|
return this.post("/v1/slim/location", body, undefined, requestOptions);
|
|
248
264
|
}
|
|
265
|
+
/** 422 Device not found means the requested device is unreadable; nothing was saved. */
|
|
249
266
|
async function updateSlimLocation(locationId, body, requestOptions) {
|
|
250
267
|
return (await this.put(`/v1/slim/location/${encodeURIComponent(locationId)}`, body, undefined, requestOptions));
|
|
251
268
|
}
|
|
@@ -38,9 +38,10 @@ export type SlimPatientListItem = {
|
|
|
38
38
|
locationName: string | null;
|
|
39
39
|
deviceId: string | null;
|
|
40
40
|
deviceName: string | null;
|
|
41
|
-
medicalSettings:
|
|
42
|
-
bedActivitySettings:
|
|
41
|
+
medicalSettings: SlimSettingsScope | null;
|
|
42
|
+
bedActivitySettings: SlimSettingsScope | null;
|
|
43
43
|
};
|
|
44
|
+
export type SlimSettingsScope = "inactive" | "global" | "individual";
|
|
44
45
|
export type SlimPatientListQuery = {
|
|
45
46
|
page?: number;
|
|
46
47
|
count?: number;
|
|
@@ -51,8 +52,8 @@ export type SlimPatientListQuery = {
|
|
|
51
52
|
includeDischargedRecent?: boolean;
|
|
52
53
|
organizationId?: string;
|
|
53
54
|
hasDevice?: boolean;
|
|
54
|
-
medicalSettings?:
|
|
55
|
-
bedActivitySettings?:
|
|
55
|
+
medicalSettings?: SlimSettingsScope;
|
|
56
|
+
bedActivitySettings?: SlimSettingsScope;
|
|
56
57
|
};
|
|
57
58
|
export type SlimCreatePatient = {
|
|
58
59
|
name: SlimHumanName[];
|
|
@@ -63,6 +64,7 @@ export type SlimCreatePatient = {
|
|
|
63
64
|
locationId?: string;
|
|
64
65
|
admissionDate?: string;
|
|
65
66
|
};
|
|
67
|
+
/** Replaces the editable fields; omitting locationId unassigns the resident's devices. */
|
|
66
68
|
export type SlimUpdatePatient = Partial<SlimCreatePatient> & {
|
|
67
69
|
residentState?: SlimResidentState;
|
|
68
70
|
dischargeDate?: string;
|
|
@@ -222,6 +224,7 @@ export type SlimThresholdSettingsUpdateV1 = Record<string, SlimThresholdSettingU
|
|
|
222
224
|
export type SlimThresholdV2Setting = {
|
|
223
225
|
mode: string;
|
|
224
226
|
deviationPercent: number | null;
|
|
227
|
+
/** Null when the bed window is 23 hours 59 minutes or longer. */
|
|
225
228
|
baselineAverage: number | null;
|
|
226
229
|
effectiveBand: {
|
|
227
230
|
min: number;
|
|
@@ -239,7 +242,7 @@ export type SignalsSyncStatus = {
|
|
|
239
242
|
reason: string;
|
|
240
243
|
} | null;
|
|
241
244
|
export type SlimThresholdV2 = {
|
|
242
|
-
id
|
|
245
|
+
id: string | null;
|
|
243
246
|
projectId?: string;
|
|
244
247
|
status?: "active" | "retired";
|
|
245
248
|
date?: string;
|
|
@@ -122,7 +122,6 @@ exports.OVOK_CORE_API_REQUIREMENTS = {
|
|
|
122
122
|
{ method: "PUT", path: "/v1/slim/device/assign/project", group: "Slim/Device" },
|
|
123
123
|
{ method: "GET", path: "/v1/slim/device/live", group: "Slim/Device" },
|
|
124
124
|
{ method: "GET", path: "/v1/slim/device/live/telemetry", group: "Slim/Device" },
|
|
125
|
-
{ method: "GET", path: "/v1/slim/device/live/cloudwatch/:deviceId", group: "Slim/Device" },
|
|
126
125
|
{ method: "GET", path: "/v1/slim/telemetry/:deviceId", group: "Slim/Telemetry" },
|
|
127
126
|
{ method: "GET", path: "/v1/slim/telemetry/effectiveIds", group: "Slim/Telemetry" },
|
|
128
127
|
{ method: "GET", path: "/v1/slim/telemetry/lastIds", group: "Slim/Telemetry" },
|
|
@@ -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.43",
|
|
52
52
|
},
|
|
53
53
|
fhirVersion: "4.0.1",
|
|
54
54
|
format: ["json"],
|
|
@@ -7,6 +7,7 @@ export declare const useRecentSlimNotifications: (count?: number) => OvokRequest
|
|
|
7
7
|
export declare const useSlimAlarms: (params?: SlimAlarmQuery) => OvokRequestState<SlimAlarmsPage>;
|
|
8
8
|
export declare const useRecentAlarms: (count?: number) => OvokRequestState<SlimRecentAlarms>;
|
|
9
9
|
export declare const useRecentOutOfBed: (count?: number) => OvokRequestState<SlimRecentOutOfBed>;
|
|
10
|
+
/** Without status, loads new and reviewed rows together; active is new, completed reviewed, and revoked hand-closed. */
|
|
10
11
|
export declare const useSlimOutOfBedNotifications: (params?: Omit<SlimNotificationsQuery, "type">) => OvokRequestState<SlimNotificationsResponse>;
|
|
11
12
|
/** Fetches every cursor page; a short page is not treated as the end of the feed. */
|
|
12
13
|
export declare const useSlimMedicalNotifications: (params?: Omit<SlimMedicalNotificationsQuery, "cursor">, options?: {
|
|
@@ -73,6 +73,7 @@ const useRecentAlarms = (count) => useSlimNotificationFeed((client, signal) => c
|
|
|
73
73
|
exports.useRecentAlarms = useRecentAlarms;
|
|
74
74
|
const useRecentOutOfBed = (count) => useSlimNotificationFeed((client, signal) => client.getRecentOutOfBed(count, { signal }), count, "recent");
|
|
75
75
|
exports.useRecentOutOfBed = useRecentOutOfBed;
|
|
76
|
+
/** Without status, loads new and reviewed rows together; active is new, completed reviewed, and revoked hand-closed. */
|
|
76
77
|
const useSlimOutOfBedNotifications = (params = {}) => useSlimNotificationFeed((client, signal) => client.listSlimOutOfBedNotifications(params, { signal }), params, "resources");
|
|
77
78
|
exports.useSlimOutOfBedNotifications = useSlimOutOfBedNotifications;
|
|
78
79
|
/** Fetches every cursor page; a short page is not treated as the end of the feed. */
|