@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.
- package/build/cjs/__tests__/integration.test.js +51 -82
- package/build/cjs/index.js +0 -7
- package/build/cjs/lib/__tests__/cacheable-section-state.test.js +7 -14
- package/build/cjs/lib/__tests__/clear-sensitive-caches.test.js +17 -20
- package/build/cjs/lib/__tests__/network-status.test.js +135 -148
- package/build/cjs/lib/__tests__/offline-provider.test.js +12 -22
- package/build/cjs/lib/__tests__/use-cacheable-section.test.js +87 -98
- package/build/cjs/lib/__tests__/use-online-status-message.test.js +7 -14
- package/build/cjs/lib/cacheable-section-state.js +27 -38
- package/build/cjs/lib/cacheable-section.js +26 -27
- package/build/cjs/lib/clear-sensitive-caches.js +14 -24
- package/build/cjs/lib/dhis2-connection-status/dev-debug-log.js +1 -3
- package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.js +27 -58
- package/build/cjs/lib/dhis2-connection-status/dhis2-connection-status.test.js +287 -230
- package/build/cjs/lib/dhis2-connection-status/index.js +0 -1
- package/build/cjs/lib/dhis2-connection-status/is-ping-available.js +0 -6
- package/build/cjs/lib/dhis2-connection-status/is-ping-available.test.js +0 -1
- package/build/cjs/lib/dhis2-connection-status/smart-interval.js +35 -49
- package/build/cjs/lib/dhis2-connection-status/use-ping-query.js +4 -5
- package/build/cjs/lib/global-state-service.js +9 -27
- package/build/cjs/lib/network-status.js +10 -13
- package/build/cjs/lib/offline-interface.js +3 -14
- package/build/cjs/lib/offline-provider.js +1 -12
- package/build/cjs/lib/online-status-message.js +5 -17
- package/build/cjs/setupRTL.js +1 -1
- package/build/cjs/utils/__tests__/render-counter.test.js +3 -12
- package/build/cjs/utils/render-counter.js +2 -10
- package/build/cjs/utils/test-mocks.js +13 -18
- package/build/es/__tests__/integration.test.js +51 -74
- package/build/es/index.js +2 -2
- package/build/es/lib/__tests__/cacheable-section-state.test.js +2 -4
- package/build/es/lib/__tests__/clear-sensitive-caches.test.js +19 -16
- package/build/es/lib/__tests__/network-status.test.js +105 -114
- package/build/es/lib/__tests__/offline-provider.test.js +13 -15
- package/build/es/lib/__tests__/use-cacheable-section.test.js +69 -73
- package/build/es/lib/__tests__/use-online-status-message.test.js +2 -3
- package/build/es/lib/cacheable-section-state.js +25 -26
- package/build/es/lib/cacheable-section.js +23 -15
- package/build/es/lib/clear-sensitive-caches.js +13 -21
- package/build/es/lib/dhis2-connection-status/dev-debug-log.js +1 -3
- package/build/es/lib/dhis2-connection-status/dhis2-connection-status.js +26 -37
- package/build/es/lib/dhis2-connection-status/dhis2-connection-status.test.js +223 -159
- package/build/es/lib/dhis2-connection-status/is-ping-available.js +0 -5
- package/build/es/lib/dhis2-connection-status/smart-interval.js +34 -42
- package/build/es/lib/dhis2-connection-status/use-ping-query.js +6 -3
- package/build/es/lib/global-state-service.js +6 -12
- package/build/es/lib/network-status.js +10 -9
- package/build/es/lib/offline-interface.js +0 -3
- package/build/es/lib/offline-provider.js +0 -3
- package/build/es/lib/online-status-message.js +3 -2
- package/build/es/setupRTL.js +1 -1
- package/build/es/utils/__tests__/render-counter.test.js +2 -4
- package/build/es/utils/render-counter.js +1 -3
- package/build/es/utils/test-mocks.js +8 -9
- package/build/types/lib/cacheable-section.d.ts +1 -1
- package/build/types/lib/dhis2-connection-status/dhis2-connection-status.d.ts +1 -1
- package/build/types/lib/network-status.d.ts +1 -1
- package/build/types/lib/online-status-message.d.ts +1 -1
- package/build/types/types.d.ts +1 -1
- 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
|
|
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)();
|
|
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]);
|
|
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
|
-
|
|
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');
|
|
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
|
-
}
|
|
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
|
-
|
|
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);
|
|
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]);
|
|
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 :
|
|
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;
|