@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
@@ -4,59 +4,41 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.useDhis2ConnectionStatus = exports.getLastConnectedKey = exports.Dhis2ConnectionStatusProvider = void 0;
7
-
8
7
  var _appServiceConfig = require("@dhis2/app-service-config");
9
-
10
8
  var _lodash = require("lodash");
11
-
12
9
  var _propTypes = _interopRequireDefault(require("prop-types"));
13
-
14
10
  var _react = _interopRequireWildcard(require("react"));
15
-
16
11
  var _offlineInterface = require("../offline-interface");
17
-
18
12
  var _devDebugLog = require("./dev-debug-log");
19
-
20
13
  var _isPingAvailable = require("./is-ping-available");
21
-
22
14
  var _smartInterval = _interopRequireDefault(require("./smart-interval"));
23
-
24
15
  var _usePingQuery = require("./use-ping-query");
25
-
26
- function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
27
-
28
- 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; }
29
-
30
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
31
-
16
+ 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); }
17
+ 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; }
18
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
32
19
  // Utils for saving 'last connected' datetime in local storage
33
20
  const lastConnectedKey = 'dhis2.lastConnected';
34
-
35
21
  const getLastConnectedKey = appName => appName ? `${lastConnectedKey}.${appName}` : lastConnectedKey;
36
-
37
22
  exports.getLastConnectedKey = getLastConnectedKey;
38
-
39
23
  const updateLastConnected = appName => {
40
24
  // use Date.now() because it's easier to mock for easier unit testing
41
25
  const now = new Date(Date.now());
42
26
  localStorage.setItem(getLastConnectedKey(appName), now.toUTCString());
43
27
  return now;
44
28
  };
45
-
46
29
  const getLastConnected = appName => {
47
30
  const lastConnected = localStorage.getItem(getLastConnectedKey(appName));
48
31
  return lastConnected ? new Date(lastConnected) : null;
49
32
  };
50
-
51
33
  const clearLastConnected = appName => {
52
34
  localStorage.removeItem(getLastConnectedKey(appName));
53
35
  };
54
-
55
36
  const Dhis2ConnectionStatusContext = /*#__PURE__*/_react.default.createContext({
56
37
  isConnected: true,
57
38
  isDisconnected: false,
58
39
  lastConnected: null
59
40
  });
41
+
60
42
  /**
61
43
  * Provides a boolean indicating client's connection to the DHIS2 server,
62
44
  * which is different from connection to the internet.
@@ -66,9 +48,7 @@ const Dhis2ConnectionStatusContext = /*#__PURE__*/_react.default.createContext({
66
48
  * and then will initiate periodic pings if there are no incidental requests in
67
49
  * order to check the connection consistently
68
50
  */
69
-
70
-
71
- const Dhis2ConnectionStatusProvider = (_ref) => {
51
+ const Dhis2ConnectionStatusProvider = _ref => {
72
52
  let {
73
53
  children
74
54
  } = _ref;
@@ -76,21 +56,21 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
76
56
  const {
77
57
  appName,
78
58
  serverVersion
79
- } = (0, _appServiceConfig.useConfig)(); // The offline interface persists the latest update from the SW so that
59
+ } = (0, _appServiceConfig.useConfig)();
60
+ // The offline interface persists the latest update from the SW so that
80
61
  // this hook can initialize to an accurate value. The App Adapter in the
81
62
  // platform waits for this value to be populated before rendering the
82
63
  // the App Runtime provider (including this), but if that is not done,
83
64
  // `latestIsConnected` may be `null` depending on the outcome of race
84
65
  // conditions between the SW and the React component tree.
85
-
86
66
  const [isConnected, setIsConnected] = (0, _react.useState)(offlineInterface.latestIsConnected);
87
67
  const ping = (0, _usePingQuery.usePingQuery)();
88
68
  const smartIntervalRef = (0, _react.useRef)(null);
69
+
89
70
  /**
90
71
  * Update state, reset ping backoff if changed, and update
91
72
  * the lastConnected value in localStorage
92
73
  */
93
-
94
74
  const updateConnectedState = (0, _react.useCallback)(newIsConnected => {
95
75
  // use 'set' with a function as param to get latest isConnected
96
76
  // without needing it as a dependency for useCallback
@@ -99,13 +79,10 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
99
79
  prevIsConnected,
100
80
  newIsConnected
101
81
  });
102
-
103
82
  if (newIsConnected !== prevIsConnected) {
104
83
  var _smartIntervalRef$cur;
105
-
106
84
  // if value changed, reset ping interval to initial delay
107
85
  (_smartIntervalRef$cur = smartIntervalRef.current) === null || _smartIntervalRef$cur === void 0 ? void 0 : _smartIntervalRef$cur.reset();
108
-
109
86
  if (newIsConnected) {
110
87
  // Need to clear this here so it doesn't affect another
111
88
  // session that starts while offline
@@ -114,15 +91,15 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
114
91
  updateLastConnected(appName);
115
92
  }
116
93
  }
117
-
118
94
  return newIsConnected;
119
95
  });
120
- }, [appName]); // Note that the SW is configured to not cache ping requests and won't
96
+ }, [appName]);
97
+
98
+ // Note that the SW is configured to not cache ping requests and won't
121
99
  // trigger `handleChange` below to avoid redundant signals. This also
122
100
  // helps to detect the connectivity status when the SW is not available
123
101
  // for some reason (maybe private browsing, first installation, or
124
102
  // insecure browser context)
125
-
126
103
  const pingAndHandleStatus = (0, _react.useCallback)(() => {
127
104
  return ping().then(() => {
128
105
  // Ping is successful; set 'connected'
@@ -132,16 +109,16 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
132
109
  updateConnectedState(false);
133
110
  });
134
111
  }, [ping, updateConnectedState]);
135
- /** Called when SW reports updates from incidental network traffic */
136
112
 
137
- const onUpdate = (0, _react.useCallback)((_ref2) => {
113
+ /** Called when SW reports updates from incidental network traffic */
114
+ const onUpdate = (0, _react.useCallback)(_ref2 => {
138
115
  var _smartIntervalRef$cur2;
139
-
140
116
  let {
141
117
  isConnected: newIsConnected
142
118
  } = _ref2;
143
- (0, _devDebugLog.devDebugLog)('[D2CS] handling update from sw'); // Snooze ping timer to reduce pings since we know state from SW
119
+ (0, _devDebugLog.devDebugLog)('[D2CS] handling update from sw');
144
120
 
121
+ // Snooze ping timer to reduce pings since we know state from SW
145
122
  (_smartIntervalRef$cur2 = smartIntervalRef.current) === null || _smartIntervalRef$cur2 === void 0 ? void 0 : _smartIntervalRef$cur2.snooze();
146
123
  updateConnectedState(newIsConnected);
147
124
  }, [updateConnectedState]);
@@ -150,26 +127,22 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
150
127
  // pinging with the smart interval. Just use the service worker
151
128
  if (!serverVersion || !(0, _isPingAvailable.isPingAvailable)(serverVersion)) {
152
129
  return;
153
- } // Only create the smart interval once
154
-
130
+ }
155
131
 
132
+ // Only create the smart interval once
156
133
  const smartInterval = (0, _smartInterval.default)({
157
134
  // don't ping if window isn't focused or visible
158
135
  initialPauseValue: !document.hasFocus() || document.visibilityState !== 'visible',
159
136
  callback: pingAndHandleStatus
160
137
  });
161
138
  smartIntervalRef.current = smartInterval;
162
-
163
139
  const handleBlur = () => smartInterval.pause();
164
-
165
- const handleFocus = () => smartInterval.resume(); // Pinging when going offline should be low/no-cost in both online and
140
+ const handleFocus = () => smartInterval.resume();
141
+ // Pinging when going offline should be low/no-cost in both online and
166
142
  // local servers
167
-
168
-
169
- const handleOffline = () => smartInterval.invokeCallbackImmediately(); // Pinging when going online has a cost but improves responsiveness of
143
+ const handleOffline = () => smartInterval.invokeCallbackImmediately();
144
+ // Pinging when going online has a cost but improves responsiveness of
170
145
  // the connection status -- only do it once every 15 seconds at most
171
-
172
-
173
146
  const handleOnline = (0, _lodash.throttle)(() => smartInterval.invokeCallbackImmediately(), 15000);
174
147
  window.addEventListener('blur', handleBlur);
175
148
  window.addEventListener('focus', handleFocus);
@@ -179,8 +152,9 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
179
152
  window.removeEventListener('blur', handleBlur);
180
153
  window.removeEventListener('focus', handleFocus);
181
154
  window.removeEventListener('offline', handleOffline);
182
- window.removeEventListener('online', handleOnline); // clean up smart interval and throttled function
155
+ window.removeEventListener('online', handleOnline);
183
156
 
157
+ // clean up smart interval and throttled function
184
158
  smartInterval.clear();
185
159
  handleOnline.cancel();
186
160
  };
@@ -188,22 +162,21 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
188
162
  (0, _react.useEffect)(() => {
189
163
  if (!offlineInterface.subscribeToDhis2ConnectionStatus) {
190
164
  var _smartIntervalRef$cur3;
191
-
192
165
  // Missing this functionality from the offline interface --
193
166
  // use a ping on startup to get the status
194
167
  (_smartIntervalRef$cur3 = smartIntervalRef.current) === null || _smartIntervalRef$cur3 === void 0 ? void 0 : _smartIntervalRef$cur3.invokeCallbackImmediately();
195
168
  console.warn('Please upgrade to @dhis2/cli-app-scripts@>10.3.8 for full connection status features');
196
169
  return;
197
170
  }
198
-
199
171
  const unsubscribe = offlineInterface.subscribeToDhis2ConnectionStatus({
200
172
  onUpdate
201
173
  });
202
174
  return () => {
203
175
  unsubscribe();
204
176
  };
205
- }, [offlineInterface, onUpdate]); // Memoize this value to prevent unnecessary rerenders of context provider
177
+ }, [offlineInterface, onUpdate]);
206
178
 
179
+ // Memoize this value to prevent unnecessary rerenders of context provider
207
180
  const contextValue = (0, _react.useMemo)(() => {
208
181
  // in the unlikely circumstance that offlineInterface.latestIsConnected
209
182
  // is `null` or `undefined` when this initializes, fail safe by defaulting to
@@ -212,7 +185,8 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
212
185
  return {
213
186
  isConnected: validatedIsConnected,
214
187
  isDisconnected: !validatedIsConnected,
215
- lastConnected: validatedIsConnected ? null : // Only evaluate if disconnected, since local storage
188
+ lastConnected: validatedIsConnected ? null :
189
+ // Only evaluate if disconnected, since local storage
216
190
  // is synchronous and disk-based.
217
191
  // If lastConnected is not set in localStorage though, set it.
218
192
  // (relevant on startup)
@@ -223,20 +197,15 @@ const Dhis2ConnectionStatusProvider = (_ref) => {
223
197
  value: contextValue
224
198
  }, children);
225
199
  };
226
-
227
200
  exports.Dhis2ConnectionStatusProvider = Dhis2ConnectionStatusProvider;
228
201
  Dhis2ConnectionStatusProvider.propTypes = {
229
202
  children: _propTypes.default.node
230
203
  };
231
-
232
204
  const useDhis2ConnectionStatus = () => {
233
205
  const context = (0, _react.useContext)(Dhis2ConnectionStatusContext);
234
-
235
206
  if (!context) {
236
207
  throw new Error('useDhis2ConnectionStatus must be used within a Dhis2ConnectionStatus provider');
237
208
  }
238
-
239
209
  return context;
240
210
  };
241
-
242
211
  exports.useDhis2ConnectionStatus = useDhis2ConnectionStatus;