@openmrs/esm-offline 3.2.1-pre.986 → 3.3.1-pre.1173
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/.turbo/turbo-build.log +17 -0
- package/dist/openmrs-esm-offline.js +1 -1
- package/dist/openmrs-esm-offline.js.map +1 -1
- package/jest.config.js +4 -1
- package/package.json +6 -6
- package/src/index.ts +0 -3
- package/src/mode.ts +2 -0
- package/src/offline-patient-data.ts +1 -0
- package/src/public.ts +20 -0
- package/src/service-worker-http-headers.ts +2 -0
- package/src/service-worker-messaging.ts +1 -0
- package/src/sync.test.ts +153 -0
- package/src/sync.ts +27 -4
- package/src/uuid.ts +1 -0
- package/webpack.config.js +1 -1
- package/.babelrc +0 -7
- package/src/events.ts +0 -18
- package/src/patches.ts +0 -7
- package/src/service-worker-events.ts +0 -15
package/jest.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-offline",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1-pre.1173",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "Helper utilities for OpenMRS",
|
|
6
6
|
"browser": "dist/openmrs-esm-offline.js",
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@openmrs/esm-api": "^3.
|
|
40
|
-
"@openmrs/esm-globals": "^3.
|
|
41
|
-
"@openmrs/esm-state": "^3.
|
|
42
|
-
"@openmrs/esm-styleguide": "^3.
|
|
39
|
+
"@openmrs/esm-api": "^3.3.1-pre.1173",
|
|
40
|
+
"@openmrs/esm-globals": "^3.3.1-pre.1173",
|
|
41
|
+
"@openmrs/esm-state": "^3.3.1-pre.1173",
|
|
42
|
+
"@openmrs/esm-styleguide": "^3.3.1-pre.1173",
|
|
43
43
|
"@types/uuid": "^8.3.0",
|
|
44
44
|
"rxjs": "^6.5.3"
|
|
45
45
|
},
|
|
@@ -56,5 +56,5 @@
|
|
|
56
56
|
"uuid": "^8.3.2",
|
|
57
57
|
"workbox-window": "^6.1.5"
|
|
58
58
|
},
|
|
59
|
-
"gitHead": "
|
|
59
|
+
"gitHead": "957c0c36b8f754808127269f6e50b90992a60559"
|
|
60
60
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
export * from "./service-worker";
|
|
2
2
|
export * from "./service-worker-http-headers";
|
|
3
3
|
export * from "./service-worker-messaging";
|
|
4
|
-
export * from "./service-worker-events";
|
|
5
|
-
export * from "./events";
|
|
6
4
|
export * from "./mode";
|
|
7
|
-
export * from "./patches";
|
|
8
5
|
export * from "./sync";
|
|
9
6
|
export * from "./uuid";
|
|
10
7
|
export * from "./offline-patient-data";
|
package/src/mode.ts
CHANGED
package/src/public.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export { OfflineMode, OfflineModeResult, getCurrentOfflineMode } from "./mode";
|
|
2
|
+
export * from "./offline-patient-data";
|
|
3
|
+
export * from "./service-worker-messaging";
|
|
4
|
+
export * from "./service-worker-http-headers";
|
|
5
|
+
export * from "./uuid";
|
|
6
|
+
export {
|
|
7
|
+
QueueItemDescriptor,
|
|
8
|
+
SyncItem,
|
|
9
|
+
SyncProcessOptions,
|
|
10
|
+
queueSynchronizationItem,
|
|
11
|
+
getSynchronizationItem,
|
|
12
|
+
getSynchronizationItems,
|
|
13
|
+
getFullSynchronizationItems,
|
|
14
|
+
getFullSynchronizationItemsFor,
|
|
15
|
+
getOfflineDb,
|
|
16
|
+
canBeginEditSynchronizationItemsOfType,
|
|
17
|
+
beginEditSynchronizationItem,
|
|
18
|
+
deleteSynchronizationItem,
|
|
19
|
+
setupOfflineSync,
|
|
20
|
+
} from "./sync";
|
package/src/sync.test.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import "fake-indexeddb/auto";
|
|
2
|
+
import { getLoggedInUser, LoggedInUser } from "@openmrs/esm-api";
|
|
3
|
+
import {
|
|
4
|
+
getFullSynchronizationItems,
|
|
5
|
+
getFullSynchronizationItemsFor,
|
|
6
|
+
getOfflineDb,
|
|
7
|
+
getSynchronizationItems,
|
|
8
|
+
getSynchronizationItemsFor,
|
|
9
|
+
QueueItemDescriptor,
|
|
10
|
+
queueSynchronizationItem,
|
|
11
|
+
queueSynchronizationItemFor,
|
|
12
|
+
deleteSynchronizationItem,
|
|
13
|
+
getSynchronizationItem,
|
|
14
|
+
} from "./sync";
|
|
15
|
+
|
|
16
|
+
interface MockSyncItem {
|
|
17
|
+
value: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const systemTime = new Date();
|
|
21
|
+
const mockUserId = "00000000-0000-0000-0000-000000000000";
|
|
22
|
+
const mockSyncItemType = "mock-sync-item";
|
|
23
|
+
const defaultMockSyncItem: MockSyncItem = {
|
|
24
|
+
value: 123,
|
|
25
|
+
};
|
|
26
|
+
const defaultMockSyncItemDescriptor: QueueItemDescriptor = {
|
|
27
|
+
dependencies: [],
|
|
28
|
+
id: "123",
|
|
29
|
+
displayName: "Mock Sync Item",
|
|
30
|
+
patientUuid: "00000000-0000-0000-0000-000000000001",
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
jest.mock("@openmrs/esm-api", () => ({
|
|
34
|
+
getLoggedInUser: jest.fn(async () => ({ uuid: mockUserId })),
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
afterEach(async () => {
|
|
38
|
+
// We want each test case to start fresh with a clean sync queue.
|
|
39
|
+
await getOfflineDb().syncQueue.clear();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("Sync Queue", () => {
|
|
43
|
+
beforeAll(() => {
|
|
44
|
+
// We want to control the timers to ensure that we can test the `createdOn` attribute
|
|
45
|
+
// of the sync item (which is created using `new Date()`).
|
|
46
|
+
jest.useFakeTimers("modern");
|
|
47
|
+
jest.setSystemTime(systemTime);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
afterAll(() => {
|
|
51
|
+
jest.useRealTimers();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("enqueues sync item with expected attributes", async () => {
|
|
55
|
+
const id = await queueSynchronizationItemFor(
|
|
56
|
+
mockUserId,
|
|
57
|
+
mockSyncItemType,
|
|
58
|
+
defaultMockSyncItem,
|
|
59
|
+
defaultMockSyncItemDescriptor
|
|
60
|
+
);
|
|
61
|
+
const queuedItems = await getFullSynchronizationItemsFor<MockSyncItem>(
|
|
62
|
+
mockUserId,
|
|
63
|
+
mockSyncItemType
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
expect(queuedItems).toHaveLength(1);
|
|
67
|
+
expect(queuedItems[0].id).toBe(id);
|
|
68
|
+
expect(queuedItems[0].type).toBe(mockSyncItemType);
|
|
69
|
+
expect(queuedItems[0].userId).toBe(mockUserId);
|
|
70
|
+
expect(queuedItems[0].createdOn).toStrictEqual(systemTime);
|
|
71
|
+
expect(queuedItems[0].content).toStrictEqual(defaultMockSyncItem);
|
|
72
|
+
expect(queuedItems[0].descriptor).toStrictEqual(
|
|
73
|
+
defaultMockSyncItemDescriptor
|
|
74
|
+
);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("Logged-in user specific functions", () => {
|
|
79
|
+
it("enqueue and return sync items of currently logged-in user", async () => {
|
|
80
|
+
const loggedInUserId = (await getLoggedInUser()).uuid;
|
|
81
|
+
await queueSynchronizationItem(mockSyncItemType, defaultMockSyncItem);
|
|
82
|
+
const queuedItems = await getFullSynchronizationItems(mockSyncItemType);
|
|
83
|
+
|
|
84
|
+
expect(queuedItems).toHaveLength(1);
|
|
85
|
+
expect(queuedItems[0].userId).toBe(loggedInUserId);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
describe("getSynchronizationItems", () => {
|
|
90
|
+
it("returns `content` of corresponding `getFullSynchronizationItems` call", async () => {
|
|
91
|
+
await queueSynchronizationItem(mockSyncItemType, defaultMockSyncItem);
|
|
92
|
+
const items = await getSynchronizationItems(mockSyncItemType);
|
|
93
|
+
const fullItems = await getFullSynchronizationItems(mockSyncItemType);
|
|
94
|
+
expect(items).toHaveLength(1);
|
|
95
|
+
expect(fullItems).toHaveLength(1);
|
|
96
|
+
expect(items[0]).toStrictEqual(fullItems[0].content);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe("getSynchronizationItemsFor", () => {
|
|
101
|
+
it("returns `content` of corresponding `getFullSynchronizationItemsFor` call", async () => {
|
|
102
|
+
await queueSynchronizationItemFor(
|
|
103
|
+
mockUserId,
|
|
104
|
+
mockSyncItemType,
|
|
105
|
+
defaultMockSyncItem
|
|
106
|
+
);
|
|
107
|
+
const items = await getSynchronizationItemsFor(
|
|
108
|
+
mockUserId,
|
|
109
|
+
mockSyncItemType
|
|
110
|
+
);
|
|
111
|
+
const fullItems = await getFullSynchronizationItemsFor(
|
|
112
|
+
mockUserId,
|
|
113
|
+
mockSyncItemType
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
expect(items).toHaveLength(1);
|
|
117
|
+
expect(fullItems).toHaveLength(1);
|
|
118
|
+
expect(items[0]).toStrictEqual(fullItems[0].content);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe("getSynchronizationItem", () => {
|
|
123
|
+
it("returns the specific sync item with given ID", async () => {
|
|
124
|
+
const id = await queueSynchronizationItem(
|
|
125
|
+
mockSyncItemType,
|
|
126
|
+
defaultMockSyncItem
|
|
127
|
+
);
|
|
128
|
+
const items = await getFullSynchronizationItems(mockSyncItemType);
|
|
129
|
+
const item = await getSynchronizationItem(id);
|
|
130
|
+
expect(item).toStrictEqual(items[0]);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("returns undefined when no item with given ID exists", async () => {
|
|
134
|
+
const item = await getSynchronizationItem(404);
|
|
135
|
+
expect(item).toBeUndefined();
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
describe("deleteSynchronizationItem", () => {
|
|
140
|
+
it("deletes sync item with given ID", async () => {
|
|
141
|
+
const id = await queueSynchronizationItem(
|
|
142
|
+
mockSyncItemType,
|
|
143
|
+
defaultMockSyncItem
|
|
144
|
+
);
|
|
145
|
+
await deleteSynchronizationItem(id);
|
|
146
|
+
const items = await getSynchronizationItems(mockSyncItemType);
|
|
147
|
+
expect(items).toHaveLength(0);
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("does not throw when no item with given ID exists", async () => {
|
|
151
|
+
await deleteSynchronizationItem(404);
|
|
152
|
+
});
|
|
153
|
+
});
|
package/src/sync.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/** @module @category Offline */
|
|
1
2
|
import Dexie, { Table } from "dexie";
|
|
2
3
|
import { getLoggedInUser } from "@openmrs/esm-api";
|
|
3
4
|
import { createGlobalStore } from "@openmrs/esm-state";
|
|
@@ -299,26 +300,39 @@ export async function queueSynchronizationItem<T>(
|
|
|
299
300
|
}
|
|
300
301
|
|
|
301
302
|
/**
|
|
302
|
-
* Returns all currently queued up sync items of a given user.
|
|
303
|
+
* Returns the content of all currently queued up sync items of a given user.
|
|
303
304
|
* @param userId The ID of the user whose synchronization items should be returned.
|
|
304
305
|
* @param type The identifying type of the synchronization items to be returned..
|
|
305
306
|
*/
|
|
306
307
|
export async function getSynchronizationItemsFor<T>(
|
|
307
308
|
userId: string,
|
|
308
309
|
type: string
|
|
310
|
+
) {
|
|
311
|
+
const fullItems = await getFullSynchronizationItemsFor<T>(userId, type);
|
|
312
|
+
return fullItems.map((item) => item.content);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Returns all currently queued up sync items of a given user.
|
|
317
|
+
* @param userId The ID of the user whose synchronization items should be returned.
|
|
318
|
+
* @param type The identifying type of the synchronization items to be returned..
|
|
319
|
+
*/
|
|
320
|
+
export async function getFullSynchronizationItemsFor<T>(
|
|
321
|
+
userId: string,
|
|
322
|
+
type: string
|
|
309
323
|
) {
|
|
310
324
|
const table = db.syncQueue;
|
|
311
|
-
const items: Array<T
|
|
325
|
+
const items: Array<SyncItem<T>> = [];
|
|
312
326
|
|
|
313
327
|
await table.where({ type, userId }).each((item) => {
|
|
314
|
-
items.push(item
|
|
328
|
+
items.push(item);
|
|
315
329
|
});
|
|
316
330
|
|
|
317
331
|
return items;
|
|
318
332
|
}
|
|
319
333
|
|
|
320
334
|
/**
|
|
321
|
-
* Returns all currently queued up sync items of the currently signed in user.
|
|
335
|
+
* Returns the content of all currently queued up sync items of the currently signed in user.
|
|
322
336
|
* @param type The identifying type of the synchronization items to be returned.
|
|
323
337
|
*/
|
|
324
338
|
export async function getSynchronizationItems<T>(type: string) {
|
|
@@ -326,6 +340,15 @@ export async function getSynchronizationItems<T>(type: string) {
|
|
|
326
340
|
return await getSynchronizationItemsFor<T>(userId, type);
|
|
327
341
|
}
|
|
328
342
|
|
|
343
|
+
/**
|
|
344
|
+
* Returns all currently queued up sync items of the currently signed in user.
|
|
345
|
+
* @param type The identifying type of the synchronization items to be returned.
|
|
346
|
+
*/
|
|
347
|
+
export async function getFullSynchronizationItems<T>(type: string) {
|
|
348
|
+
const userId = await getUserId();
|
|
349
|
+
return await getFullSynchronizationItemsFor<T>(userId, type);
|
|
350
|
+
}
|
|
351
|
+
|
|
329
352
|
/**
|
|
330
353
|
* Returns a queued sync item with the given ID or `undefined` if no such item exists.
|
|
331
354
|
* @param id The ID of the requested sync item.
|
package/src/uuid.ts
CHANGED
package/webpack.config.js
CHANGED
package/.babelrc
DELETED
package/src/events.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { NetworkRequestFailedEvent } from "./service-worker-events";
|
|
2
|
-
|
|
3
|
-
const networkRequestFailedEventName = "openmrs:network-request-failed";
|
|
4
|
-
|
|
5
|
-
export function dispatchNetworkRequestFailed(data: NetworkRequestFailedEvent) {
|
|
6
|
-
window.dispatchEvent(
|
|
7
|
-
new CustomEvent(networkRequestFailedEventName, { detail: data })
|
|
8
|
-
);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function subscribeNetworkRequestFailed(
|
|
12
|
-
cb: (data: NetworkRequestFailedEvent) => void
|
|
13
|
-
) {
|
|
14
|
-
const handler = (ev: CustomEvent) => cb(ev.detail);
|
|
15
|
-
window.addEventListener(networkRequestFailedEventName, handler);
|
|
16
|
-
return () =>
|
|
17
|
-
window.removeEventListener(networkRequestFailedEventName, handler);
|
|
18
|
-
}
|
package/src/patches.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export interface OmrsServiceWorkerEvent<TypeIdentifier extends string> {
|
|
2
|
-
type: TypeIdentifier;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export interface NetworkRequestFailedEvent
|
|
6
|
-
extends OmrsServiceWorkerEvent<"networkRequestFailed"> {
|
|
7
|
-
request: {
|
|
8
|
-
url: string;
|
|
9
|
-
method: string;
|
|
10
|
-
headers: Record<string, string>;
|
|
11
|
-
body: string;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export type KnownOmrsServiceWorkerEvents = NetworkRequestFailedEvent;
|