@dhis2/app-service-offline 3.16.0 → 3.17.0-beta.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.
Files changed (47) hide show
  1. package/build/cjs/__tests__/integration.test.js +19 -29
  2. package/build/cjs/lib/__tests__/cacheable-section-state.test.js +5 -8
  3. package/build/cjs/lib/__tests__/clear-sensitive-caches.test.js +1 -4
  4. package/build/cjs/lib/__tests__/network-status.test.js +13 -34
  5. package/build/cjs/lib/__tests__/offline-provider.test.js +2 -5
  6. package/build/cjs/lib/__tests__/use-cacheable-section.test.js +38 -65
  7. package/build/cjs/lib/__tests__/use-online-status-message.test.js +5 -8
  8. package/build/cjs/lib/cacheable-section-state.js +11 -15
  9. package/build/cjs/lib/cacheable-section.js +11 -13
  10. package/build/cjs/lib/clear-sensitive-caches.js +4 -8
  11. package/build/cjs/lib/dhis2-connection-status/dev-debug-log.js +2 -2
  12. package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.js +9 -11
  13. package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.test.js +83 -107
  14. package/build/cjs/lib/dhis2-connection-status/smart-interval.js +7 -8
  15. package/build/cjs/lib/global-state-service.js +10 -15
  16. package/build/cjs/lib/network-status.js +4 -6
  17. package/build/cjs/lib/offline-interface.js +4 -5
  18. package/build/cjs/lib/offline-provider.js +4 -5
  19. package/build/cjs/lib/online-status-message.js +3 -4
  20. package/build/cjs/utils/render-counter.js +4 -5
  21. package/build/cjs/utils/test-mocks.js +8 -10
  22. package/build/es/__tests__/integration.test.js +19 -29
  23. package/build/es/lib/__tests__/cacheable-section-state.test.js +5 -8
  24. package/build/es/lib/__tests__/clear-sensitive-caches.test.js +1 -4
  25. package/build/es/lib/__tests__/network-status.test.js +13 -34
  26. package/build/es/lib/__tests__/offline-provider.test.js +2 -5
  27. package/build/es/lib/__tests__/use-cacheable-section.test.js +38 -65
  28. package/build/es/lib/__tests__/use-online-status-message.test.js +5 -8
  29. package/build/es/lib/cacheable-section-state.js +11 -15
  30. package/build/es/lib/cacheable-section.js +11 -13
  31. package/build/es/lib/clear-sensitive-caches.js +4 -8
  32. package/build/es/lib/dhis2-connection-status/dev-debug-log.js +2 -2
  33. package/build/es/lib/dhis2-connection-status/dhis2-connection-status.js +9 -11
  34. package/build/es/lib/dhis2-connection-status/dhis2-connection-status.test.js +83 -107
  35. package/build/es/lib/dhis2-connection-status/smart-interval.js +7 -8
  36. package/build/es/lib/global-state-service.js +10 -15
  37. package/build/es/lib/network-status.js +4 -6
  38. package/build/es/lib/offline-interface.js +4 -5
  39. package/build/es/lib/offline-provider.js +4 -5
  40. package/build/es/lib/online-status-message.js +3 -4
  41. package/build/es/utils/render-counter.js +4 -5
  42. package/build/es/utils/test-mocks.js +8 -10
  43. package/package.json +3 -3
  44. package/build/cjs/locales/en/translations.json +0 -4
  45. package/build/cjs/locales/index.js +0 -21
  46. package/build/es/locales/en/translations.json +0 -4
  47. package/build/es/locales/index.js +0 -13
@@ -38,9 +38,7 @@ describe('state changes in response to browser "online" and "offline" events', (
38
38
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
39
39
  const {
40
40
  result
41
- } = renderHook(function () {
42
- return useOnlineStatus(...arguments);
43
- }, {
41
+ } = renderHook((...args) => useOnlineStatus(...args), {
44
42
  initialProps: {
45
43
  debounceDelay: 50
46
44
  }
@@ -62,9 +60,7 @@ describe('state changes in response to browser "online" and "offline" events', (
62
60
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
63
61
  const {
64
62
  result
65
- } = renderHook(function () {
66
- return useOnlineStatus(...arguments);
67
- }, {
63
+ } = renderHook((...args) => useOnlineStatus(...args), {
68
64
  initialProps: {
69
65
  debounceDelay: 50
70
66
  }
@@ -111,9 +107,7 @@ describe('debouncing state changes', () => {
111
107
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
112
108
  const {
113
109
  result
114
- } = renderHook(function () {
115
- return useOnlineStatus(...arguments);
116
- }, {
110
+ } = renderHook((...args) => useOnlineStatus(...args), {
117
111
  initialProps: {
118
112
  debounceDelay: 50
119
113
  }
@@ -139,9 +133,7 @@ describe('debouncing state changes', () => {
139
133
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
140
134
  const {
141
135
  result
142
- } = renderHook(function () {
143
- return useOnlineStatus(...arguments);
144
- }, {
136
+ } = renderHook((...args) => useOnlineStatus(...args), {
145
137
  initialProps: {
146
138
  debounceDelay: 0
147
139
  }
@@ -167,9 +159,7 @@ describe('debouncing state changes', () => {
167
159
  const {
168
160
  result,
169
161
  rerender
170
- } = renderHook(function () {
171
- return useOnlineStatus(...arguments);
172
- }, {
162
+ } = renderHook((...args) => useOnlineStatus(...args), {
173
163
  initialProps: {
174
164
  debounceDelay: 150
175
165
  }
@@ -247,10 +237,9 @@ describe('debouncing state changes', () => {
247
237
  jest.spyOn(navigator, 'onLine', 'get').mockReturnValueOnce(true);
248
238
  const events = {};
249
239
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
250
- const TestComponent = _ref => {
251
- let {
252
- options
253
- } = _ref;
240
+ const TestComponent = ({
241
+ options
242
+ }) => {
254
243
  const {
255
244
  online
256
245
  } = useOnlineStatus(options);
@@ -349,9 +338,7 @@ describe('it updates the lastOnline value in local storage', () => {
349
338
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
350
339
  const {
351
340
  result
352
- } = renderHook(function () {
353
- return useOnlineStatus(...arguments);
354
- }, {
341
+ } = renderHook((...args) => useOnlineStatus(...args), {
355
342
  initialProps: {
356
343
  debounceDelay: 0
357
344
  }
@@ -385,9 +372,7 @@ describe('it updates the lastOnline value in local storage', () => {
385
372
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
386
373
  const {
387
374
  result
388
- } = renderHook(function () {
389
- return useOnlineStatus(...arguments);
390
- }, {
375
+ } = renderHook((...args) => useOnlineStatus(...args), {
391
376
  initialProps: {
392
377
  debounceDelay: 0
393
378
  }
@@ -405,9 +390,7 @@ describe('it updates the lastOnline value in local storage', () => {
405
390
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
406
391
  const {
407
392
  result
408
- } = renderHook(function () {
409
- return useOnlineStatus(...arguments);
410
- }, {
393
+ } = renderHook((...args) => useOnlineStatus(...args), {
411
394
  initialProps: {
412
395
  debounceDelay: 0
413
396
  }
@@ -431,9 +414,7 @@ describe('it updates the lastOnline value in local storage', () => {
431
414
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
432
415
  const {
433
416
  result
434
- } = renderHook(function () {
435
- return useOnlineStatus(...arguments);
436
- }, {
417
+ } = renderHook((...args) => useOnlineStatus(...args), {
437
418
  initialProps: {
438
419
  debounceDelay: 0
439
420
  }
@@ -459,9 +440,7 @@ describe('it updates the lastOnline value in local storage', () => {
459
440
  window.addEventListener = jest.fn((event, cb) => events[event] = cb);
460
441
  const {
461
442
  result
462
- } = renderHook(function () {
463
- return useOnlineStatus(...arguments);
464
- }, {
443
+ } = renderHook((...args) => useOnlineStatus(...args), {
465
444
  initialProps: {
466
445
  debounceDelay: 0
467
446
  }
@@ -8,11 +8,8 @@ import { OfflineProvider } from '../offline-provider';
8
8
  // Suppress 'act' warning for these tests
9
9
  const originalError = console.error;
10
10
  beforeEach(() => {
11
- jest.spyOn(console, 'error').mockImplementation(function () {
11
+ jest.spyOn(console, 'error').mockImplementation((...args) => {
12
12
  const pattern = /Warning: An update to .* inside a test was not wrapped in act/;
13
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
14
- args[_key] = arguments[_key];
15
- }
16
13
  if (typeof args[0] === 'string' && pattern.test(args[0])) {
17
14
  return;
18
15
  }
@@ -22,7 +19,7 @@ beforeEach(() => {
22
19
  afterEach(() => {
23
20
  jest.clearAllMocks()
24
21
  // syntax needed to appease typescript
25
- ;
22
+ ;
26
23
  console.error.mockRestore();
27
24
  });
28
25
  describe('Testing offline provider', () => {
@@ -7,11 +7,8 @@ import { OfflineProvider } from '../offline-provider';
7
7
  // Suppress 'act' warning for these tests
8
8
  const originalError = console.error;
9
9
  beforeEach(() => {
10
- jest.spyOn(console, 'error').mockImplementation(function () {
10
+ jest.spyOn(console, 'error').mockImplementation((...args) => {
11
11
  const pattern = /Warning: An update to .* inside a test was not wrapped in act/;
12
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
13
- args[_key] = arguments[_key];
14
- }
15
12
  if (typeof args[0] === 'string' && pattern.test(args[0])) {
16
13
  return;
17
14
  }
@@ -21,18 +18,15 @@ beforeEach(() => {
21
18
  afterEach(() => {
22
19
  jest.clearAllMocks()
23
20
  // This syntax appeases typescript:
24
- ;
21
+ ;
25
22
  console.error.mockRestore();
26
23
  });
27
24
  it('renders in the default state initially', () => {
28
- const wrapper = _ref => {
29
- let {
30
- children
31
- } = _ref;
32
- return /*#__PURE__*/React.createElement(OfflineProvider, {
33
- offlineInterface: mockOfflineInterface
34
- }, children);
35
- };
25
+ const wrapper = ({
26
+ children
27
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
28
+ offlineInterface: mockOfflineInterface
29
+ }, children);
36
30
  const {
37
31
  result
38
32
  } = renderHook(() => useCacheableSection('one'), {
@@ -43,14 +37,11 @@ it('renders in the default state initially', () => {
43
37
  expect(result.current.lastUpdated).toBeUndefined();
44
38
  });
45
39
  it('has stable references', () => {
46
- const wrapper = _ref2 => {
47
- let {
48
- children
49
- } = _ref2;
50
- return /*#__PURE__*/React.createElement(OfflineProvider, {
51
- offlineInterface: mockOfflineInterface
52
- }, children);
53
- };
40
+ const wrapper = ({
41
+ children
42
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
43
+ offlineInterface: mockOfflineInterface
44
+ }, children);
54
45
  const {
55
46
  result,
56
47
  rerender
@@ -78,14 +69,11 @@ it('handles a successful recording', async done => {
78
69
  lastUpdated: new Date()
79
70
  }])
80
71
  };
81
- const wrapper = _ref3 => {
82
- let {
83
- children
84
- } = _ref3;
85
- return /*#__PURE__*/React.createElement(OfflineProvider, {
86
- offlineInterface: recordingSuccessOfflineInterface
87
- }, children);
88
- };
72
+ const wrapper = ({
73
+ children
74
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
75
+ offlineInterface: recordingSuccessOfflineInterface
76
+ }, children);
89
77
  const {
90
78
  result
91
79
  } = renderHook(() => useCacheableSection(sectionId), {
@@ -136,12 +124,9 @@ it('handles a successful recording', async done => {
136
124
  });
137
125
  it('handles a recording that encounters an error', async done => {
138
126
  // Suppress the expected error from console (in addition to 'act' warning)
139
- jest.spyOn(console, 'error').mockImplementation(function () {
127
+ jest.spyOn(console, 'error').mockImplementation((...args) => {
140
128
  const actPattern = /Warning: An update to .* inside a test was not wrapped in act/;
141
129
  const errPattern = /Error during recording/;
142
- for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
143
- args[_key2] = arguments[_key2];
144
- }
145
130
  const matchesPattern = actPattern.test(args[0]) || errPattern.test(args[0]);
146
131
  if (typeof args[0] === 'string' && matchesPattern) {
147
132
  return;
@@ -152,14 +137,11 @@ it('handles a recording that encounters an error', async done => {
152
137
  ...mockOfflineInterface,
153
138
  startRecording: errorRecordingMock
154
139
  };
155
- const wrapper = _ref4 => {
156
- let {
157
- children
158
- } = _ref4;
159
- return /*#__PURE__*/React.createElement(OfflineProvider, {
160
- offlineInterface: recordingErrorOfflineInterface
161
- }, children);
162
- };
140
+ const wrapper = ({
141
+ children
142
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
143
+ offlineInterface: recordingErrorOfflineInterface
144
+ }, children);
163
145
  const {
164
146
  result
165
147
  } = renderHook(() => useCacheableSection('one'), {
@@ -197,14 +179,11 @@ it('handles an error starting the recording', async () => {
197
179
  ...mockOfflineInterface,
198
180
  startRecording: failedMessageRecordingMock
199
181
  };
200
- const wrapper = _ref5 => {
201
- let {
202
- children
203
- } = _ref5;
204
- return /*#__PURE__*/React.createElement(OfflineProvider, {
205
- offlineInterface: messageErrorOfflineInterface
206
- }, children);
207
- };
182
+ const wrapper = ({
183
+ children
184
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
185
+ offlineInterface: messageErrorOfflineInterface
186
+ }, children);
208
187
  const {
209
188
  result
210
189
  } = renderHook(() => useCacheableSection('err'), {
@@ -222,14 +201,11 @@ it('handles remove and updates sections', async () => {
222
201
  lastUpdated: new Date()
223
202
  }]).mockResolvedValueOnce([])
224
203
  };
225
- const wrapper = _ref6 => {
226
- let {
227
- children
228
- } = _ref6;
229
- return /*#__PURE__*/React.createElement(OfflineProvider, {
230
- offlineInterface: sectionOpsOfflineInterface
231
- }, children);
232
- };
204
+ const wrapper = ({
205
+ children
206
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
207
+ offlineInterface: sectionOpsOfflineInterface
208
+ }, children);
233
209
  const {
234
210
  result
235
211
  } = renderHook(() => useCacheableSection(sectionId), {
@@ -257,14 +233,11 @@ it('handles a change in ID', async () => {
257
233
  lastUpdated: new Date()
258
234
  }])
259
235
  };
260
- const wrapper = _ref7 => {
261
- let {
262
- children
263
- } = _ref7;
264
- return /*#__PURE__*/React.createElement(OfflineProvider, {
265
- offlineInterface: idChangeOfflineInterface
266
- }, children);
267
- };
236
+ const wrapper = ({
237
+ children
238
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
239
+ offlineInterface: idChangeOfflineInterface
240
+ }, children);
268
241
  const {
269
242
  result,
270
243
  rerender
@@ -5,14 +5,11 @@ import { OfflineProvider } from '../offline-provider';
5
5
  import { useOnlineStatusMessage } from '../online-status-message';
6
6
  describe('useOnlineStatusMessage', () => {
7
7
  it('should allow the online status to be updated ', () => {
8
- const wrapper = _ref => {
9
- let {
10
- children
11
- } = _ref;
12
- return /*#__PURE__*/React.createElement(OfflineProvider, {
13
- offlineInterface: mockOfflineInterface
14
- }, children);
15
- };
8
+ const wrapper = ({
9
+ children
10
+ }) => /*#__PURE__*/React.createElement(OfflineProvider, {
11
+ offlineInterface: mockOfflineInterface
12
+ }, children);
16
13
  const {
17
14
  result
18
15
  } = renderHook(() => useOnlineStatusMessage(), {
@@ -14,18 +14,15 @@ import { useOfflineInterface } from './offline-interface';
14
14
  * @returns {Object} An object of sections, keyed by ID
15
15
  */
16
16
  function getSectionsById(sectionsArray) {
17
- return sectionsArray.reduce((result, _ref) => {
18
- let {
19
- sectionId,
17
+ return sectionsArray.reduce((result, {
18
+ sectionId,
19
+ lastUpdated
20
+ }) => ({
21
+ ...result,
22
+ [sectionId]: {
20
23
  lastUpdated
21
- } = _ref;
22
- return {
23
- ...result,
24
- [sectionId]: {
25
- lastUpdated
26
- }
27
- };
28
- }, {});
24
+ }
25
+ }), {});
29
26
  }
30
27
 
31
28
  /**
@@ -59,10 +56,9 @@ function useConst(factory) {
59
56
  * determine how that component will render. The provider will be a part of
60
57
  * the OfflineProvider.
61
58
  */
62
- export function CacheableSectionProvider(_ref2) {
63
- let {
64
- children
65
- } = _ref2;
59
+ export function CacheableSectionProvider({
60
+ children
61
+ }) {
66
62
  const offlineInterface = useOfflineInterface();
67
63
  const store = useConst(createCacheableSectionStore);
68
64
 
@@ -55,13 +55,12 @@ export function useCacheableSection(id) {
55
55
  console.error('Error during recording:', error);
56
56
  setRecordingState(recordingStates.error);
57
57
  }, [setRecordingState]);
58
- const startRecording = useCallback(function () {
59
- let {
60
- recordingTimeoutDelay = 1000,
61
- onStarted,
62
- onCompleted,
63
- onError
64
- } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
58
+ const startRecording = useCallback(({
59
+ recordingTimeoutDelay = 1000,
60
+ onStarted,
61
+ onCompleted,
62
+ onError
63
+ } = {}) => {
65
64
  // This promise resolving means that the message to the service worker
66
65
  // to start recording was successful. Waiting for resolution prevents
67
66
  // unnecessarily rerendering the whole component in case of an error
@@ -112,12 +111,11 @@ export function useCacheableSection(id) {
112
111
  * intended to prevent other interaction with the app that might interfere
113
112
  * with the recording process.
114
113
  */
115
- export function CacheableSection(_ref) {
116
- let {
117
- id,
118
- loadingMask,
119
- children
120
- } = _ref;
114
+ export function CacheableSection({
115
+ id,
116
+ loadingMask,
117
+ children
118
+ }) {
121
119
  // Accesses recording state that useCacheableSection controls
122
120
  const {
123
121
  recordingState
@@ -20,12 +20,9 @@ const clearDB = async dbName => {
20
20
  return;
21
21
  }
22
22
  const dbs = await window.indexedDB.databases();
23
- if (!dbs.some(_ref => {
24
- let {
25
- name
26
- } = _ref;
27
- return name === dbName;
28
- })) {
23
+ if (!dbs.some(({
24
+ name
25
+ }) => name === dbName)) {
29
26
  // Sections-db is not created; nothing to do here
30
27
  return;
31
28
  }
@@ -53,8 +50,7 @@ const clearDB = async dbName => {
53
50
  * different user logs in to prevent someone from accessing a different user's
54
51
  * caches. Should be able to be used in a non-PWA app.
55
52
  */
56
- export async function clearSensitiveCaches() {
57
- let dbName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SECTIONS_DB;
53
+ export async function clearSensitiveCaches(dbName = SECTIONS_DB) {
58
54
  console.debug('Clearing sensitive caches');
59
55
  let cacheKeys;
60
56
 
@@ -11,8 +11,8 @@ if (shouldLog) {
11
11
  * The behavior of the connection status can be quite hard to inspect without
12
12
  * logs, but the logs are quite chatty and should be omitted normally.
13
13
  */
14
- export function devDebugLog() {
14
+ export function devDebugLog(...args) {
15
15
  if (shouldLog) {
16
- console.log(...arguments);
16
+ console.log(...args);
17
17
  }
18
18
  }
@@ -39,10 +39,9 @@ const Dhis2ConnectionStatusContext = /*#__PURE__*/React.createContext({
39
39
  * and then will initiate periodic pings if there are no incidental requests in
40
40
  * order to check the connection consistently
41
41
  */
42
- export const Dhis2ConnectionStatusProvider = _ref => {
43
- let {
44
- children
45
- } = _ref;
42
+ export const Dhis2ConnectionStatusProvider = ({
43
+ children
44
+ }) => {
46
45
  const offlineInterface = useOfflineInterface();
47
46
  const {
48
47
  appName,
@@ -73,7 +72,7 @@ export const Dhis2ConnectionStatusProvider = _ref => {
73
72
  if (newIsConnected !== prevIsConnected) {
74
73
  var _smartIntervalRef$cur;
75
74
  // if value changed, reset ping interval to initial delay
76
- (_smartIntervalRef$cur = smartIntervalRef.current) === null || _smartIntervalRef$cur === void 0 ? void 0 : _smartIntervalRef$cur.reset();
75
+ (_smartIntervalRef$cur = smartIntervalRef.current) === null || _smartIntervalRef$cur === void 0 || _smartIntervalRef$cur.reset();
77
76
  if (newIsConnected) {
78
77
  // Need to clear this here so it doesn't affect another
79
78
  // session that starts while offline
@@ -102,15 +101,14 @@ export const Dhis2ConnectionStatusProvider = _ref => {
102
101
  }, [ping, updateConnectedState]);
103
102
 
104
103
  /** Called when SW reports updates from incidental network traffic */
105
- const onUpdate = useCallback(_ref2 => {
104
+ const onUpdate = useCallback(({
105
+ isConnected: newIsConnected
106
+ }) => {
106
107
  var _smartIntervalRef$cur2;
107
- let {
108
- isConnected: newIsConnected
109
- } = _ref2;
110
108
  devDebugLog('[D2CS] handling update from sw');
111
109
 
112
110
  // Snooze ping timer to reduce pings since we know state from SW
113
- (_smartIntervalRef$cur2 = smartIntervalRef.current) === null || _smartIntervalRef$cur2 === void 0 ? void 0 : _smartIntervalRef$cur2.snooze();
111
+ (_smartIntervalRef$cur2 = smartIntervalRef.current) === null || _smartIntervalRef$cur2 === void 0 || _smartIntervalRef$cur2.snooze();
114
112
  updateConnectedState(newIsConnected);
115
113
  }, [updateConnectedState]);
116
114
  useEffect(() => {
@@ -155,7 +153,7 @@ export const Dhis2ConnectionStatusProvider = _ref => {
155
153
  var _smartIntervalRef$cur3;
156
154
  // Missing this functionality from the offline interface --
157
155
  // use a ping on startup to get the status
158
- (_smartIntervalRef$cur3 = smartIntervalRef.current) === null || _smartIntervalRef$cur3 === void 0 ? void 0 : _smartIntervalRef$cur3.invokeCallbackImmediately();
156
+ (_smartIntervalRef$cur3 = smartIntervalRef.current) === null || _smartIntervalRef$cur3 === void 0 || _smartIntervalRef$cur3.invokeCallbackImmediately();
159
157
  console.warn('Please upgrade to @dhis2/cli-app-scripts@>10.3.8 for full connection status features');
160
158
  return;
161
159
  }