@dhis2/app-service-offline 3.11.3 → 3.12.0-alpha.1

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 (60) hide show
  1. package/build/cjs/__tests__/integration.test.js +51 -82
  2. package/build/cjs/index.js +0 -7
  3. package/build/cjs/lib/__tests__/cacheable-section-state.test.js +7 -14
  4. package/build/cjs/lib/__tests__/clear-sensitive-caches.test.js +17 -20
  5. package/build/cjs/lib/__tests__/network-status.test.js +135 -148
  6. package/build/cjs/lib/__tests__/offline-provider.test.js +12 -22
  7. package/build/cjs/lib/__tests__/use-cacheable-section.test.js +87 -98
  8. package/build/cjs/lib/__tests__/use-online-status-message.test.js +7 -14
  9. package/build/cjs/lib/cacheable-section-state.js +27 -38
  10. package/build/cjs/lib/cacheable-section.js +26 -27
  11. package/build/cjs/lib/clear-sensitive-caches.js +14 -24
  12. package/build/cjs/lib/dhis2-connection-status/dev-debug-log.js +1 -3
  13. package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.js +27 -58
  14. package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.test.js +287 -230
  15. package/build/cjs/lib/dhis2-connection-status/index.js +0 -1
  16. package/build/cjs/lib/dhis2-connection-status/is-ping-available.js +0 -6
  17. package/build/cjs/lib/dhis2-connection-status/is-ping-available.test.js +0 -1
  18. package/build/cjs/lib/dhis2-connection-status/smart-interval.js +35 -49
  19. package/build/cjs/lib/dhis2-connection-status/use-ping-query.js +4 -5
  20. package/build/cjs/lib/global-state-service.js +9 -27
  21. package/build/cjs/lib/network-status.js +10 -13
  22. package/build/cjs/lib/offline-interface.js +3 -14
  23. package/build/cjs/lib/offline-provider.js +1 -12
  24. package/build/cjs/lib/online-status-message.js +5 -17
  25. package/build/cjs/setupRTL.js +1 -1
  26. package/build/cjs/utils/__tests__/render-counter.test.js +3 -12
  27. package/build/cjs/utils/render-counter.js +2 -10
  28. package/build/cjs/utils/test-mocks.js +13 -18
  29. package/build/es/__tests__/integration.test.js +51 -74
  30. package/build/es/index.js +2 -2
  31. package/build/es/lib/__tests__/cacheable-section-state.test.js +2 -4
  32. package/build/es/lib/__tests__/clear-sensitive-caches.test.js +19 -16
  33. package/build/es/lib/__tests__/network-status.test.js +105 -114
  34. package/build/es/lib/__tests__/offline-provider.test.js +13 -15
  35. package/build/es/lib/__tests__/use-cacheable-section.test.js +69 -73
  36. package/build/es/lib/__tests__/use-online-status-message.test.js +2 -3
  37. package/build/es/lib/cacheable-section-state.js +25 -26
  38. package/build/es/lib/cacheable-section.js +23 -15
  39. package/build/es/lib/clear-sensitive-caches.js +13 -21
  40. package/build/es/lib/dhis2-connection-status/dev-debug-log.js +1 -3
  41. package/build/es/lib/dhis2-connection-status/dhis2-connection-status.js +26 -37
  42. package/build/es/lib/dhis2-connection-status/dhis2-connection-status.test.js +223 -159
  43. package/build/es/lib/dhis2-connection-status/is-ping-available.js +0 -5
  44. package/build/es/lib/dhis2-connection-status/smart-interval.js +34 -42
  45. package/build/es/lib/dhis2-connection-status/use-ping-query.js +6 -3
  46. package/build/es/lib/global-state-service.js +6 -12
  47. package/build/es/lib/network-status.js +10 -9
  48. package/build/es/lib/offline-interface.js +0 -3
  49. package/build/es/lib/offline-provider.js +0 -3
  50. package/build/es/lib/online-status-message.js +3 -2
  51. package/build/es/setupRTL.js +1 -1
  52. package/build/es/utils/__tests__/render-counter.test.js +2 -4
  53. package/build/es/utils/render-counter.js +1 -3
  54. package/build/es/utils/test-mocks.js +8 -9
  55. package/build/types/lib/cacheable-section.d.ts +1 -1
  56. package/build/types/lib/dhis2-connection-status/dhis2-connection-status.d.ts +1 -1
  57. package/build/types/lib/network-status.d.ts +1 -1
  58. package/build/types/lib/online-status-message.d.ts +1 -1
  59. package/build/types/types.d.ts +1 -1
  60. package/package.json +4 -4
@@ -8,20 +8,15 @@ exports.createCacheableSectionStore = createCacheableSectionStore;
8
8
  exports.useCachedSection = useCachedSection;
9
9
  exports.useCachedSections = useCachedSections;
10
10
  exports.useRecordingState = useRecordingState;
11
-
12
11
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
-
14
12
  var _react = _interopRequireWildcard(require("react"));
15
-
16
13
  var _globalStateService = require("./global-state-service");
17
-
18
14
  var _offlineInterface = require("./offline-interface");
19
-
20
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
21
-
22
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
23
-
24
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
16
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
17
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
18
+ // Functions in here use the global state service to manage cacheable section
19
+ // state in a performant way
25
20
 
26
21
  /**
27
22
  * Helper that transforms an array of cached section objects from the IndexedDB
@@ -36,19 +31,19 @@ function getSectionsById(sectionsArray) {
36
31
  sectionId,
37
32
  lastUpdated
38
33
  } = _ref;
39
- return { ...result,
34
+ return {
35
+ ...result,
40
36
  [sectionId]: {
41
37
  lastUpdated
42
38
  }
43
39
  };
44
40
  }, {});
45
41
  }
42
+
46
43
  /**
47
44
  * Create a store for Cacheable Section state.
48
45
  * Expected to be used in app adapter
49
46
  */
50
-
51
-
52
47
  function createCacheableSectionStore() {
53
48
  const initialState = {
54
49
  recordingStates: {},
@@ -56,41 +51,39 @@ function createCacheableSectionStore() {
56
51
  };
57
52
  return (0, _globalStateService.createStore)(initialState);
58
53
  }
54
+
59
55
  /**
60
56
  * Helper hook that returns a value that will persist between renders but makes
61
57
  * sure to only set its initial state once.
62
58
  * See https://gist.github.com/amcgee/42bb2fa6d5f79e607f00e6dccc733482
63
59
  */
64
-
65
-
66
60
  function useConst(factory) {
67
61
  const ref = _react.default.useRef(null);
68
-
69
62
  if (ref.current === null) {
70
63
  ref.current = factory();
71
64
  }
72
-
73
65
  return ref.current;
74
66
  }
67
+
75
68
  /**
76
69
  * Provides context for a global state context which will track cached
77
70
  * sections' status and cacheable sections' recording states, which will
78
71
  * determine how that component will render. The provider will be a part of
79
72
  * the OfflineProvider.
80
73
  */
81
-
82
-
83
74
  function CacheableSectionProvider(_ref2) {
84
75
  let {
85
76
  children
86
77
  } = _ref2;
87
78
  const offlineInterface = (0, _offlineInterface.useOfflineInterface)();
88
- const store = useConst(createCacheableSectionStore); // On load, get sections and add to store
79
+ const store = useConst(createCacheableSectionStore);
89
80
 
81
+ // On load, get sections and add to store
90
82
  (0, _react.useEffect)(() => {
91
83
  if (offlineInterface) {
92
84
  offlineInterface.getCachedSections().then(sections => {
93
- store.mutate(state => ({ ...state,
85
+ store.mutate(state => ({
86
+ ...state,
94
87
  cachedSections: getSectionsById(sections)
95
88
  }));
96
89
  });
@@ -100,11 +93,9 @@ function CacheableSectionProvider(_ref2) {
100
93
  store: store
101
94
  }, children);
102
95
  }
103
-
104
96
  CacheableSectionProvider.propTypes = {
105
97
  children: _propTypes.default.node
106
98
  };
107
-
108
99
  /**
109
100
  * Uses an optimized global state to manage 'recording state' values without
110
101
  * unnecessarily rerendering all consuming components
@@ -115,17 +106,21 @@ CacheableSectionProvider.propTypes = {
115
106
  function useRecordingState(id) {
116
107
  const recordingStateSelector = (0, _react.useCallback)(state => state.recordingStates[id], [id]);
117
108
  const [recordingState] = (0, _globalStateService.useGlobalState)(recordingStateSelector);
118
- const setRecordingStateMutationCreator = (0, _react.useCallback)(newState => state => ({ ...state,
119
- recordingStates: { ...state.recordingStates,
109
+ const setRecordingStateMutationCreator = (0, _react.useCallback)(newState => state => ({
110
+ ...state,
111
+ recordingStates: {
112
+ ...state.recordingStates,
120
113
  [id]: newState
121
114
  }
122
115
  }), [id]);
123
116
  const setRecordingState = (0, _globalStateService.useGlobalStateMutation)(setRecordingStateMutationCreator);
124
117
  const removeRecordingStateMutationCreator = (0, _react.useCallback)(() => state => {
125
- const recordingStates = { ...state.recordingStates
118
+ const recordingStates = {
119
+ ...state.recordingStates
126
120
  };
127
121
  delete recordingStates[id];
128
- return { ...state,
122
+ return {
123
+ ...state,
129
124
  recordingStates
130
125
  };
131
126
  }, [id]);
@@ -136,17 +131,17 @@ function useRecordingState(id) {
136
131
  removeRecordingState
137
132
  }), [recordingState, setRecordingState, removeRecordingState]);
138
133
  }
134
+
139
135
  /**
140
136
  * Returns a function that syncs cached sections in the global state
141
137
  * with IndexedDB, so that IndexedDB is the single source of truth
142
138
  *
143
139
  * @returns {Function} syncCachedSections
144
140
  */
145
-
146
-
147
141
  function useSyncCachedSections() {
148
142
  const offlineInterface = (0, _offlineInterface.useOfflineInterface)();
149
- const setCachedSectionsMutationCreator = (0, _react.useCallback)(cachedSections => state => ({ ...state,
143
+ const setCachedSectionsMutationCreator = (0, _react.useCallback)(cachedSections => state => ({
144
+ ...state,
150
145
  cachedSections
151
146
  }), []);
152
147
  const setCachedSections = (0, _globalStateService.useGlobalStateMutation)(setCachedSectionsMutationCreator);
@@ -155,7 +150,6 @@ function useSyncCachedSections() {
155
150
  setCachedSections(getSectionsById(sections));
156
151
  }, [offlineInterface, setCachedSections]);
157
152
  }
158
-
159
153
  /**
160
154
  * Uses global state to manage an object of cached sections' statuses
161
155
  *
@@ -165,6 +159,7 @@ function useCachedSections() {
165
159
  const [cachedSections] = (0, _globalStateService.useGlobalState)(state => state.cachedSections);
166
160
  const syncCachedSections = useSyncCachedSections();
167
161
  const offlineInterface = (0, _offlineInterface.useOfflineInterface)();
162
+
168
163
  /**
169
164
  * Uses offline interface to remove a section from IndexedDB and Cache
170
165
  * Storage.
@@ -172,14 +167,11 @@ function useCachedSections() {
172
167
  * Returns a promise that resolves to `true` if a section is found and
173
168
  * deleted, or `false` if asection with the specified ID does not exist.
174
169
  */
175
-
176
170
  const removeById = (0, _react.useCallback)(async id => {
177
171
  const success = await offlineInterface.removeSection(id);
178
-
179
172
  if (success) {
180
173
  await syncCachedSections();
181
174
  }
182
-
183
175
  return success;
184
176
  }, [offlineInterface, syncCachedSections]);
185
177
  return (0, _react.useMemo)(() => ({
@@ -188,7 +180,6 @@ function useCachedSections() {
188
180
  syncCachedSections
189
181
  }), [cachedSections, removeById, syncCachedSections]);
190
182
  }
191
-
192
183
  /**
193
184
  * Uses global state to manage the cached status of just one section, which
194
185
  * prevents unnecessary rerenders of consuming components
@@ -201,6 +192,7 @@ function useCachedSection(id) {
201
192
  const syncCachedSections = useSyncCachedSections();
202
193
  const offlineInterface = (0, _offlineInterface.useOfflineInterface)();
203
194
  const lastUpdated = status && status.lastUpdated;
195
+
204
196
  /**
205
197
  * Uses offline interface to remove a section from IndexedDB and Cache
206
198
  * Storage.
@@ -208,14 +200,11 @@ function useCachedSection(id) {
208
200
  * Returns `true` if a section is found and deleted, or `false` if a
209
201
  * section with the specified ID does not exist.
210
202
  */
211
-
212
203
  const remove = (0, _react.useCallback)(async () => {
213
204
  const success = await offlineInterface.removeSection(id);
214
-
215
205
  if (success) {
216
206
  await syncCachedSections();
217
207
  }
218
-
219
208
  return success;
220
209
  }, [offlineInterface, id, syncCachedSections]);
221
210
  return (0, _react.useMemo)(() => ({
@@ -5,28 +5,20 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.CacheableSection = CacheableSection;
7
7
  exports.useCacheableSection = useCacheableSection;
8
-
9
8
  var _propTypes = _interopRequireDefault(require("prop-types"));
10
-
11
9
  var _react = _interopRequireWildcard(require("react"));
12
-
10
+ var _reactDom = require("react-dom");
13
11
  var _cacheableSectionState = require("./cacheable-section-state");
14
-
15
12
  var _offlineInterface = require("./offline-interface");
16
-
17
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
18
-
19
- function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
20
-
21
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
-
13
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
14
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
23
16
  const recordingStates = {
24
17
  default: 'default',
25
18
  pending: 'pending',
26
19
  recording: 'recording',
27
20
  error: 'error'
28
21
  };
29
-
30
22
  /**
31
23
  * Returns the main controls for a cacheable section and manages recording
32
24
  * state, which affects the render state of the CacheableSection component.
@@ -53,9 +45,8 @@ function useCacheableSection(id) {
53
45
  // On mount, add recording state for this ID to context if needed
54
46
  if (!recordingState) {
55
47
  setRecordingState(recordingStates.default);
56
- } // On unnmount, remove recording state if not recording
57
-
58
-
48
+ }
49
+ // On unnmount, remove recording state if not recording
59
50
  return () => {
60
51
  if (recordingState && recordingState !== recordingStates.recording && recordingState !== recordingStates.pending) {
61
52
  removeRecordingState();
@@ -88,21 +79,30 @@ function useCacheableSection(id) {
88
79
  sectionId: id,
89
80
  recordingTimeoutDelay,
90
81
  onStarted: () => {
91
- onRecordingStarted();
82
+ // Flush this state update synchronously so that the
83
+ // right recordingState is set before any other callbacks
84
+ (0, _reactDom.flushSync)(() => {
85
+ onRecordingStarted();
86
+ });
92
87
  onStarted && onStarted();
93
88
  },
94
89
  onCompleted: () => {
95
- onRecordingCompleted();
90
+ (0, _reactDom.flushSync)(() => {
91
+ onRecordingCompleted();
92
+ });
96
93
  onCompleted && onCompleted();
97
94
  },
98
95
  onError: error => {
99
- onRecordingError(error);
96
+ (0, _reactDom.flushSync)(() => {
97
+ onRecordingError(error);
98
+ });
100
99
  onError && onError(error);
101
100
  }
102
101
  }).then(() => setRecordingState(recordingStates.pending));
103
- }, [id, offlineInterface, onRecordingCompleted, onRecordingError, onRecordingStarted, setRecordingState]); // isCached, lastUpdated, remove: _could_ be accessed by useCachedSection,
104
- // but provided through this hook for convenience
102
+ }, [id, offlineInterface, onRecordingCompleted, onRecordingError, onRecordingStarted, setRecordingState]);
105
103
 
104
+ // isCached, lastUpdated, remove: _could_ be accessed by useCachedSection,
105
+ // but provided through this hook for convenience
106
106
  return (0, _react.useMemo)(() => ({
107
107
  recordingState,
108
108
  startRecording,
@@ -111,7 +111,6 @@ function useCacheableSection(id) {
111
111
  remove
112
112
  }), [recordingState, startRecording, lastUpdated, isCached, remove]);
113
113
  }
114
-
115
114
  /**
116
115
  * Used to wrap the relevant component to be recorded and saved offline.
117
116
  * Depending on the recording state of the section, this wrapper will
@@ -132,21 +131,21 @@ function CacheableSection(_ref) {
132
131
  // Accesses recording state that useCacheableSection controls
133
132
  const {
134
133
  recordingState
135
- } = (0, _cacheableSectionState.useRecordingState)(id); // The following causes the component to reload in the event of a recording
134
+ } = (0, _cacheableSectionState.useRecordingState)(id);
135
+
136
+ // The following causes the component to reload in the event of a recording
136
137
  // error; the state will be cleared next time recording moves to pending.
137
138
  // It fixes a component getting stuck while rendered without data after
138
139
  // failing a recording while offline.
139
140
  // Errors can be handled in the `onError` callback to `startRecording`.
140
-
141
141
  if (recordingState === recordingStates.error) {
142
142
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
143
- } // Handling rendering with the following conditions prevents an unncessary
144
- // rerender after successful recording
145
-
143
+ }
146
144
 
145
+ // Handling rendering with the following conditions prevents an unncessary
146
+ // rerender after successful recording
147
147
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, recordingState === recordingStates.recording && loadingMask, recordingState !== recordingStates.pending && children);
148
148
  }
149
-
150
149
  CacheableSection.propTypes = {
151
150
  id: _propTypes.default.string.isRequired,
152
151
  children: _propTypes.default.node,
@@ -6,14 +6,12 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.SECTIONS_STORE = exports.SECTIONS_DB = void 0;
7
7
  exports.clearSensitiveCaches = clearSensitiveCaches;
8
8
  // IndexedDB names; should be the same as in @dhis2/pwa
9
- const SECTIONS_DB = 'sections-db';
10
- exports.SECTIONS_DB = SECTIONS_DB;
11
- const SECTIONS_STORE = 'sections-store'; // Non-sensitive caches that can be kept:
9
+ const SECTIONS_DB = exports.SECTIONS_DB = 'sections-db';
10
+ const SECTIONS_STORE = exports.SECTIONS_STORE = 'sections-store';
12
11
 
13
- exports.SECTIONS_STORE = SECTIONS_STORE;
12
+ // Non-sensitive caches that can be kept:
14
13
  const KEEPABLE_CACHES = [/^workbox-precache/ // precached static assets
15
14
  ];
16
-
17
15
  /*
18
16
  * Clears the 'sections-db' IndexedDB if it exists. Designed to avoid opening
19
17
  * a new DB if it doesn't exist yet. Firefox can't check if 'sections-db'
@@ -28,10 +26,8 @@ const clearDB = async dbName => {
28
26
  // and offline interface will handle discrepancies in PWA apps.
29
27
  return;
30
28
  }
31
-
32
29
  const dbs = await window.indexedDB.databases();
33
-
34
- if (!dbs.some((_ref) => {
30
+ if (!dbs.some(_ref => {
35
31
  let {
36
32
  name
37
33
  } = _ref;
@@ -40,57 +36,51 @@ const clearDB = async dbName => {
40
36
  // Sections-db is not created; nothing to do here
41
37
  return;
42
38
  }
43
-
44
39
  return new Promise((resolve, reject) => {
45
40
  // IndexedDB fun:
46
41
  const openDBRequest = indexedDB.open(dbName);
47
-
48
42
  openDBRequest.onsuccess = e => {
49
43
  const db = e.target.result;
50
- const tx = db.transaction(SECTIONS_STORE, 'readwrite'); // When the transaction completes is when the operation is done:
51
-
44
+ const tx = db.transaction(SECTIONS_STORE, 'readwrite');
45
+ // When the transaction completes is when the operation is done:
52
46
  tx.oncomplete = () => resolve();
53
-
54
47
  tx.onerror = e => reject(e.target.error);
55
-
56
48
  const os = tx.objectStore(SECTIONS_STORE);
57
49
  const clearReq = os.clear();
58
-
59
50
  clearReq.onerror = e => reject(e.target.error);
60
51
  };
61
-
62
52
  openDBRequest.onerror = e => {
63
53
  reject(e.target.error);
64
54
  };
65
55
  });
66
56
  };
57
+
67
58
  /**
68
59
  * Used to clear caches and 'sections-db' IndexedDB when a user logs out or a
69
60
  * different user logs in to prevent someone from accessing a different user's
70
61
  * caches. Should be able to be used in a non-PWA app.
71
62
  */
72
-
73
-
74
63
  async function clearSensitiveCaches() {
75
64
  let dbName = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : SECTIONS_DB;
76
65
  console.debug('Clearing sensitive caches');
77
- let cacheKeys; // caches.keys can fail in insecure contexts, see:
78
- // https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage
66
+ let cacheKeys;
79
67
 
68
+ // caches.keys can fail in insecure contexts, see:
69
+ // https://developer.mozilla.org/en-US/docs/Web/API/CacheStorage
80
70
  try {
81
71
  cacheKeys = await caches.keys();
82
72
  } catch (e) {
83
73
  // Return false since no caches have been cleared
84
74
  return false;
85
75
  }
86
-
87
- return Promise.all([// (Resolves to 'false' because this can't detect if anything was deleted):
88
- clearDB(dbName).then(() => false), // Remove caches if not in keepable list
76
+ return Promise.all([
77
+ // (Resolves to 'false' because this can't detect if anything was deleted):
78
+ clearDB(dbName).then(() => false),
79
+ // Remove caches if not in keepable list
89
80
  ...cacheKeys.map(key => {
90
81
  if (!KEEPABLE_CACHES.some(pattern => pattern.test(key))) {
91
82
  return caches.delete(key);
92
83
  }
93
-
94
84
  return false;
95
85
  })]).then(responses => {
96
86
  // Return true if any caches have been cleared
@@ -5,10 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.devDebugLog = devDebugLog;
7
7
  const shouldLog = localStorage.getItem('dhis2.debugConnectionStatus');
8
-
9
8
  if (shouldLog) {
10
9
  console.log('Logging for dhis2ConnectionStatus is enabled. Remove the `dhis2.debugConnectionStatus` item in localStorage to disable logging.');
11
10
  }
11
+
12
12
  /**
13
13
  * This can be used to log info if the `dhis2.debugConnectionStatus` value
14
14
  * in localStorage is set to a truthy value during development.
@@ -17,8 +17,6 @@ if (shouldLog) {
17
17
  * The behavior of the connection status can be quite hard to inspect without
18
18
  * logs, but the logs are quite chatty and should be omitted normally.
19
19
  */
20
-
21
-
22
20
  function devDebugLog() {
23
21
  if (shouldLog) {
24
22
  console.log(...arguments);