@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,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.isPingAvailable = isPingAvailable;
|
|
7
|
-
|
|
8
7
|
/**
|
|
9
8
|
* Checks the server version to see if the /api/ping endpoint is available for
|
|
10
9
|
* this version.
|
|
@@ -21,22 +20,17 @@ function isPingAvailable(serverVersion) {
|
|
|
21
20
|
if (!serverVersion) {
|
|
22
21
|
return false;
|
|
23
22
|
}
|
|
24
|
-
|
|
25
23
|
const {
|
|
26
24
|
minor,
|
|
27
25
|
patch
|
|
28
26
|
} = serverVersion;
|
|
29
|
-
|
|
30
27
|
switch (minor) {
|
|
31
28
|
case 39:
|
|
32
29
|
return patch === undefined || patch >= 2;
|
|
33
|
-
|
|
34
30
|
case 38:
|
|
35
31
|
return patch === undefined || patch >= 4;
|
|
36
|
-
|
|
37
32
|
case 37:
|
|
38
33
|
return patch === undefined || patch >= 10;
|
|
39
|
-
|
|
40
34
|
default:
|
|
41
35
|
return minor >= 40;
|
|
42
36
|
}
|
|
@@ -5,23 +5,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.DEFAULT_MAX_DELAY_MS = exports.DEFAULT_INITIAL_DELAY_MS = exports.DEFAULT_INCREMENT_FACTOR = void 0;
|
|
7
7
|
exports.default = createSmartInterval;
|
|
8
|
-
|
|
9
8
|
var _devDebugLog = require("./dev-debug-log");
|
|
10
|
-
|
|
11
9
|
// Exported for tests
|
|
12
|
-
const DEFAULT_INITIAL_DELAY_MS = 1000 * 30; // 30 sec
|
|
13
|
-
|
|
14
|
-
exports.
|
|
15
|
-
const DEFAULT_MAX_DELAY_MS = 1000 * 60 * 5; // 5 min
|
|
16
|
-
|
|
17
|
-
exports.DEFAULT_MAX_DELAY_MS = DEFAULT_MAX_DELAY_MS;
|
|
18
|
-
const DEFAULT_INCREMENT_FACTOR = 1.5;
|
|
19
|
-
exports.DEFAULT_INCREMENT_FACTOR = DEFAULT_INCREMENT_FACTOR;
|
|
20
|
-
|
|
10
|
+
const DEFAULT_INITIAL_DELAY_MS = exports.DEFAULT_INITIAL_DELAY_MS = 1000 * 30; // 30 sec
|
|
11
|
+
const DEFAULT_MAX_DELAY_MS = exports.DEFAULT_MAX_DELAY_MS = 1000 * 60 * 5; // 5 min
|
|
12
|
+
const DEFAULT_INCREMENT_FACTOR = exports.DEFAULT_INCREMENT_FACTOR = 1.5;
|
|
21
13
|
const throwErrorIfNoCallbackIsProvided = () => {
|
|
22
14
|
throw new Error('Provide a callback');
|
|
23
15
|
};
|
|
24
|
-
|
|
25
16
|
function createSmartInterval() {
|
|
26
17
|
let {
|
|
27
18
|
initialDelay = DEFAULT_INITIAL_DELAY_MS,
|
|
@@ -40,8 +31,8 @@ function createSmartInterval() {
|
|
|
40
31
|
}, 0),
|
|
41
32
|
standbyCallback: null
|
|
42
33
|
};
|
|
43
|
-
/** Increment delay by the increment factor, up to a max value */
|
|
44
34
|
|
|
35
|
+
/** Increment delay by the increment factor, up to a max value */
|
|
45
36
|
function incrementDelay() {
|
|
46
37
|
const newDelay = Math.min(state.delay * delayIncrementFactor, maxDelay);
|
|
47
38
|
(0, _devDebugLog.devDebugLog)('[SI] incrementing delay', {
|
|
@@ -50,51 +41,51 @@ function createSmartInterval() {
|
|
|
50
41
|
});
|
|
51
42
|
state.delay = newDelay;
|
|
52
43
|
}
|
|
53
|
-
|
|
54
44
|
function invokeCallbackAndHandleDelay() {
|
|
55
45
|
// Increment delay before calling callback, so callback can potentially
|
|
56
46
|
// reset the delay to initial before starting the next timeout
|
|
57
47
|
incrementDelay();
|
|
58
48
|
callback();
|
|
59
49
|
}
|
|
60
|
-
|
|
61
50
|
function clearTimeoutAndStart() {
|
|
62
51
|
(0, _devDebugLog.devDebugLog)('[SI] clearing and starting timeout', {
|
|
63
52
|
delay: state.delay
|
|
64
|
-
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Prevent parallel timeouts from occuring
|
|
65
56
|
// (weird note: `if (this.timeout) { clearTimeout(this.timeout) }`
|
|
66
57
|
// does NOT work for some reason)
|
|
58
|
+
clearTimeout(state.timeout);
|
|
67
59
|
|
|
68
|
-
|
|
60
|
+
// A timeout is used instead of an interval for handling slow execution
|
|
69
61
|
// https://developer.mozilla.org/en-US/docs/Web/API/setInterval#ensure_that_execution_duration_is_shorter_than_interval_frequency
|
|
70
|
-
|
|
71
62
|
state.timeout = setTimeout(function callbackAndRestart() {
|
|
72
63
|
if (state.paused) {
|
|
73
|
-
(0, _devDebugLog.devDebugLog)('[SI] entering regular standby');
|
|
64
|
+
(0, _devDebugLog.devDebugLog)('[SI] entering regular standby');
|
|
65
|
+
|
|
66
|
+
// If paused, prepare a 'standby callback' to be invoked when
|
|
74
67
|
// `resume()` is called (see its definition below).
|
|
75
68
|
// The timer will not be started again until the standbyCallback
|
|
76
69
|
// is invoked.
|
|
77
|
-
|
|
78
70
|
state.standbyCallback = () => {
|
|
79
71
|
invokeCallbackAndHandleDelay();
|
|
80
72
|
clearTimeoutAndStart();
|
|
81
73
|
};
|
|
82
|
-
|
|
83
74
|
return;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
invokeCallbackAndHandleDelay(); // and start process over again
|
|
75
|
+
}
|
|
88
76
|
|
|
77
|
+
// Otherwise, invoke callback
|
|
78
|
+
invokeCallbackAndHandleDelay();
|
|
79
|
+
// and start process over again
|
|
89
80
|
clearTimeoutAndStart();
|
|
90
81
|
}, state.delay);
|
|
91
82
|
}
|
|
92
|
-
/** Stop the interval. Used for cleaning up */
|
|
93
|
-
|
|
94
83
|
|
|
84
|
+
/** Stop the interval. Used for cleaning up */
|
|
95
85
|
function clear() {
|
|
96
86
|
clearTimeout(state.timeout);
|
|
97
87
|
}
|
|
88
|
+
|
|
98
89
|
/**
|
|
99
90
|
* Invoke the provided callback immediately and start the timer over.
|
|
100
91
|
* The timeout to the next invocation will not be increased
|
|
@@ -106,8 +97,6 @@ function createSmartInterval() {
|
|
|
106
97
|
* elapses while paused, the regular standby is entered, overwriting this
|
|
107
98
|
* partial standby.
|
|
108
99
|
*/
|
|
109
|
-
|
|
110
|
-
|
|
111
100
|
function invokeCallbackImmediately() {
|
|
112
101
|
if (state.paused) {
|
|
113
102
|
if (state.standbyCallback === null) {
|
|
@@ -119,22 +108,22 @@ function createSmartInterval() {
|
|
|
119
108
|
// overwrite this callback if the timer elapses, so that the
|
|
120
109
|
// timeout delay gets incremented appropriately.
|
|
121
110
|
(0, _devDebugLog.devDebugLog)('[SI] entering standby without timer increment');
|
|
122
|
-
|
|
123
111
|
state.standbyCallback = () => {
|
|
124
112
|
// Invoke callback and start timer without incrementing
|
|
125
113
|
callback();
|
|
126
114
|
clearTimeoutAndStart();
|
|
127
115
|
};
|
|
128
|
-
}
|
|
129
|
-
|
|
116
|
+
}
|
|
130
117
|
|
|
118
|
+
// Skip rest of execution while paused
|
|
131
119
|
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
120
|
+
}
|
|
134
121
|
|
|
122
|
+
// Invoke callback and start timer without incrementing
|
|
135
123
|
callback();
|
|
136
124
|
clearTimeoutAndStart();
|
|
137
125
|
}
|
|
126
|
+
|
|
138
127
|
/**
|
|
139
128
|
* Sets a 'paused' flag (doesn't yet stop the timer):
|
|
140
129
|
*
|
|
@@ -145,35 +134,35 @@ function createSmartInterval() {
|
|
|
145
134
|
*
|
|
146
135
|
* This decreases execution activity while 'paused'
|
|
147
136
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
137
|
function pause() {
|
|
151
138
|
(0, _devDebugLog.devDebugLog)('[SI] pausing');
|
|
152
139
|
state.paused = true;
|
|
153
140
|
}
|
|
141
|
+
|
|
154
142
|
/**
|
|
155
143
|
* Removes 'paused' state
|
|
156
144
|
*
|
|
157
145
|
* If the interval is in 'standby', trigger the saved 'standbyCallback',
|
|
158
146
|
* which should start the interval timer again
|
|
159
147
|
*/
|
|
160
|
-
|
|
161
|
-
|
|
162
148
|
function resume() {
|
|
163
149
|
(0, _devDebugLog.devDebugLog)('[SI] resuming', {
|
|
164
150
|
standbyCb: state.standbyCallback
|
|
165
|
-
});
|
|
151
|
+
});
|
|
166
152
|
|
|
167
|
-
|
|
153
|
+
// Clear paused state
|
|
154
|
+
state.paused = false;
|
|
155
|
+
|
|
156
|
+
// If in standby, invoke the saved callback
|
|
168
157
|
// (invokeCallbackImmediately and clearTimeoutAndStart can set a
|
|
169
158
|
// standby callback)
|
|
170
|
-
|
|
171
159
|
if (state.standbyCallback !== null) {
|
|
172
|
-
state.standbyCallback();
|
|
173
|
-
|
|
160
|
+
state.standbyCallback();
|
|
161
|
+
// Remove existing standbyCallback
|
|
174
162
|
state.standbyCallback = null;
|
|
175
163
|
}
|
|
176
164
|
}
|
|
165
|
+
|
|
177
166
|
/**
|
|
178
167
|
* Restart the timer to the next callback invocation, using the current
|
|
179
168
|
* delay
|
|
@@ -181,24 +170,21 @@ function createSmartInterval() {
|
|
|
181
170
|
* Expected to be called to delay a ping in response to incidental network
|
|
182
171
|
* traffic, for example
|
|
183
172
|
*/
|
|
184
|
-
|
|
185
|
-
|
|
186
173
|
function snooze() {
|
|
187
174
|
(0, _devDebugLog.devDebugLog)('[SI] snoozing timeout');
|
|
188
175
|
clearTimeoutAndStart();
|
|
189
176
|
}
|
|
177
|
+
|
|
190
178
|
/**
|
|
191
179
|
* Cancels the current timeout and starts a new one with the initial delay
|
|
192
180
|
*/
|
|
193
|
-
|
|
194
|
-
|
|
195
181
|
function reset() {
|
|
196
182
|
(0, _devDebugLog.devDebugLog)('[SI] resetting interval from beginning');
|
|
197
183
|
state.delay = initialDelay;
|
|
198
184
|
clearTimeoutAndStart();
|
|
199
|
-
}
|
|
200
|
-
|
|
185
|
+
}
|
|
201
186
|
|
|
187
|
+
// Start the timer!
|
|
202
188
|
clearTimeoutAndStart();
|
|
203
189
|
return {
|
|
204
190
|
clear,
|
|
@@ -4,18 +4,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.usePingQuery = usePingQuery;
|
|
7
|
-
|
|
8
7
|
var _appServiceConfig = require("@dhis2/app-service-config");
|
|
9
|
-
|
|
10
8
|
var _react = require("react");
|
|
11
|
-
|
|
12
9
|
// This function has a separate file for easier mocking
|
|
10
|
+
|
|
13
11
|
function usePingQuery() {
|
|
14
12
|
const {
|
|
15
13
|
baseUrl
|
|
16
|
-
} = (0, _appServiceConfig.useConfig)();
|
|
17
|
-
// public. It doesn't extend the user session. See DHIS2-14531
|
|
14
|
+
} = (0, _appServiceConfig.useConfig)();
|
|
18
15
|
|
|
16
|
+
// This endpoint doesn't need any extra headers or handling since it's
|
|
17
|
+
// public. It doesn't extend the user session. See DHIS2-14531
|
|
19
18
|
const ping = (0, _react.useCallback)(() => fetch(baseUrl + '/api/ping'), [baseUrl]);
|
|
20
19
|
return ping;
|
|
21
20
|
}
|
|
@@ -5,24 +5,17 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.useGlobalState = exports.createStore = exports.GlobalStateProvider = void 0;
|
|
7
7
|
exports.useGlobalStateMutation = useGlobalStateMutation;
|
|
8
|
-
|
|
9
8
|
var _isEqual = _interopRequireDefault(require("lodash/isEqual"));
|
|
10
|
-
|
|
11
9
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
12
|
-
|
|
13
10
|
var _react = _interopRequireWildcard(require("react"));
|
|
14
|
-
|
|
15
|
-
function
|
|
16
|
-
|
|
17
|
-
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; }
|
|
18
|
-
|
|
19
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
20
|
-
|
|
11
|
+
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); }
|
|
12
|
+
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; }
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
21
14
|
// This file creates a redux-like state management service using React context
|
|
22
15
|
// that minimizes unnecessary rerenders that consume the context.
|
|
23
16
|
// See more at https://github.com/amcgee/state-service-poc
|
|
24
|
-
const identity = state => state;
|
|
25
17
|
|
|
18
|
+
const identity = state => state;
|
|
26
19
|
const createStore = function () {
|
|
27
20
|
let initialState = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
28
21
|
const subscriptions = new Set();
|
|
@@ -37,21 +30,16 @@ const createStore = function () {
|
|
|
37
30
|
},
|
|
38
31
|
mutate: mutation => {
|
|
39
32
|
state = mutation(state);
|
|
40
|
-
|
|
41
33
|
for (const callback of subscriptions) {
|
|
42
34
|
callback(state);
|
|
43
35
|
}
|
|
44
36
|
}
|
|
45
37
|
};
|
|
46
38
|
};
|
|
47
|
-
|
|
48
39
|
exports.createStore = createStore;
|
|
49
|
-
|
|
50
40
|
const GlobalStateContext = /*#__PURE__*/_react.default.createContext(createStore());
|
|
51
|
-
|
|
52
41
|
const useGlobalStateStore = () => (0, _react.useContext)(GlobalStateContext);
|
|
53
|
-
|
|
54
|
-
const GlobalStateProvider = (_ref) => {
|
|
42
|
+
const GlobalStateProvider = _ref => {
|
|
55
43
|
let {
|
|
56
44
|
store,
|
|
57
45
|
children
|
|
@@ -60,13 +48,11 @@ const GlobalStateProvider = (_ref) => {
|
|
|
60
48
|
value: store
|
|
61
49
|
}, children);
|
|
62
50
|
};
|
|
63
|
-
|
|
64
51
|
exports.GlobalStateProvider = GlobalStateProvider;
|
|
65
52
|
GlobalStateProvider.propTypes = {
|
|
66
53
|
children: _propTypes.default.node,
|
|
67
54
|
store: _propTypes.default.shape({})
|
|
68
55
|
};
|
|
69
|
-
|
|
70
56
|
const useGlobalState = function () {
|
|
71
57
|
let selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : identity;
|
|
72
58
|
const store = useGlobalStateStore();
|
|
@@ -74,29 +60,25 @@ const useGlobalState = function () {
|
|
|
74
60
|
(0, _react.useEffect)(() => {
|
|
75
61
|
// NEW: deep equality check before updating
|
|
76
62
|
const callback = state => {
|
|
77
|
-
const newSelectedState = selector(state);
|
|
78
|
-
|
|
63
|
+
const newSelectedState = selector(state);
|
|
64
|
+
// Use this form to avoid having `selectedState` as a dep in here
|
|
79
65
|
setSelectedState(currentSelectedState => {
|
|
80
66
|
// Second condition handles case where a selected object gets
|
|
81
67
|
// deleted, but state does not update
|
|
82
68
|
if (!(0, _isEqual.default)(currentSelectedState, newSelectedState) || currentSelectedState === undefined) {
|
|
83
69
|
return newSelectedState;
|
|
84
70
|
}
|
|
85
|
-
|
|
86
71
|
return currentSelectedState;
|
|
87
72
|
});
|
|
88
73
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
74
|
+
store.subscribe(callback);
|
|
75
|
+
// Make sure to update state when selector changes
|
|
92
76
|
callback(store.getState());
|
|
93
77
|
return () => store.unsubscribe(callback);
|
|
94
78
|
}, [store, selector]);
|
|
95
79
|
return (0, _react.useMemo)(() => [selectedState, store.mutate], [selectedState, store.mutate]);
|
|
96
80
|
};
|
|
97
|
-
|
|
98
81
|
exports.useGlobalState = useGlobalState;
|
|
99
|
-
|
|
100
82
|
function useGlobalStateMutation(mutationCreator) {
|
|
101
83
|
const store = useGlobalStateStore();
|
|
102
84
|
return (0, _react.useCallback)(function () {
|
|
@@ -4,14 +4,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.useNetworkStatus = useNetworkStatus;
|
|
7
|
-
|
|
8
7
|
var _debounce = _interopRequireDefault(require("lodash/debounce"));
|
|
9
|
-
|
|
10
8
|
var _react = require("react");
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
const lastOnlineKey = 'dhis2.lastOnline';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const lastOnlineKey = 'dhis2.lastOnline'; // TODO: Add option to periodically ping server to check online status.
|
|
12
|
+
// TODO: Add option to periodically ping server to check online status.
|
|
15
13
|
// TODO: Add logic to return a variable indicating unstable connection.
|
|
16
14
|
|
|
17
15
|
/**
|
|
@@ -28,30 +26,28 @@ const lastOnlineKey = 'dhis2.lastOnline'; // TODO: Add option to periodically pi
|
|
|
28
26
|
* @param {Number} [options.debounceDelay] - Timeout delay to debounce updates, in ms
|
|
29
27
|
* @returns {Object} `{ online: boolean, offline: boolean, lastOnline: Date | null }`
|
|
30
28
|
*/
|
|
31
|
-
|
|
32
29
|
function useNetworkStatus() {
|
|
33
30
|
var _options$debounceDela;
|
|
34
|
-
|
|
35
31
|
let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
|
|
36
32
|
// initialize state to `navigator.onLine` value
|
|
37
|
-
const [online, setOnline] = (0, _react.useState)(navigator.onLine);
|
|
33
|
+
const [online, setOnline] = (0, _react.useState)(navigator.onLine);
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
36
|
+
const updateState = (0, _react.useCallback)((0, _debounce.default)(_ref => {
|
|
40
37
|
let {
|
|
41
38
|
type
|
|
42
39
|
} = _ref;
|
|
43
|
-
|
|
44
40
|
if (type === 'online') {
|
|
45
41
|
setOnline(true);
|
|
46
42
|
} else if (type === 'offline') {
|
|
47
43
|
if (online || !localStorage.getItem(lastOnlineKey)) {
|
|
48
44
|
localStorage.setItem(lastOnlineKey, new Date(Date.now()).toUTCString());
|
|
49
45
|
}
|
|
50
|
-
|
|
51
46
|
setOnline(false);
|
|
52
47
|
}
|
|
53
|
-
}, (_options$debounceDela = options.debounceDelay) !== null && _options$debounceDela !== void 0 ? _options$debounceDela : 1000), [options.debounceDelay]);
|
|
48
|
+
}, (_options$debounceDela = options.debounceDelay) !== null && _options$debounceDela !== void 0 ? _options$debounceDela : 1000), [options.debounceDelay]);
|
|
54
49
|
|
|
50
|
+
// on 'online' or 'offline' events, set state
|
|
55
51
|
(0, _react.useEffect)(() => {
|
|
56
52
|
window.addEventListener('online', updateState);
|
|
57
53
|
window.addEventListener('offline', updateState);
|
|
@@ -60,8 +56,9 @@ function useNetworkStatus() {
|
|
|
60
56
|
window.removeEventListener('online', updateState);
|
|
61
57
|
window.removeEventListener('offline', updateState);
|
|
62
58
|
};
|
|
63
|
-
}, [updateState]);
|
|
59
|
+
}, [updateState]);
|
|
64
60
|
|
|
61
|
+
// Only fetch if `online === false` as local storage is synchronous and disk-based
|
|
65
62
|
const lastOnline = (0, _react.useMemo)(() => !online && localStorage.getItem(lastOnlineKey), [online]);
|
|
66
63
|
return {
|
|
67
64
|
online,
|
|
@@ -5,17 +5,11 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.OfflineInterfaceProvider = OfflineInterfaceProvider;
|
|
7
7
|
exports.useOfflineInterface = useOfflineInterface;
|
|
8
|
-
|
|
9
8
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
10
|
-
|
|
11
9
|
var _react = _interopRequireWildcard(require("react"));
|
|
12
|
-
|
|
13
|
-
function
|
|
14
|
-
|
|
15
|
-
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; }
|
|
16
|
-
|
|
17
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
18
|
-
|
|
10
|
+
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); }
|
|
11
|
+
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; }
|
|
12
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
19
13
|
// This is to prevent 'offlineInterface could be null' type-checking errors
|
|
20
14
|
const noopOfflineInterface = {
|
|
21
15
|
pwaEnabled: false,
|
|
@@ -26,7 +20,6 @@ const noopOfflineInterface = {
|
|
|
26
20
|
removeSection: async () => false
|
|
27
21
|
};
|
|
28
22
|
const OfflineInterfaceContext = /*#__PURE__*/(0, _react.createContext)(noopOfflineInterface);
|
|
29
|
-
|
|
30
23
|
/**
|
|
31
24
|
* Receives an OfflineInterface instance as a prop (presumably from the app
|
|
32
25
|
* adapter) and provides it as context for other offline tools.
|
|
@@ -44,20 +37,16 @@ function OfflineInterfaceProvider(_ref) {
|
|
|
44
37
|
value: offlineInterface
|
|
45
38
|
}, children);
|
|
46
39
|
}
|
|
47
|
-
|
|
48
40
|
OfflineInterfaceProvider.propTypes = {
|
|
49
41
|
children: _propTypes.default.node,
|
|
50
42
|
offlineInterface: _propTypes.default.shape({
|
|
51
43
|
init: _propTypes.default.func
|
|
52
44
|
})
|
|
53
45
|
};
|
|
54
|
-
|
|
55
46
|
function useOfflineInterface() {
|
|
56
47
|
const offlineInterface = (0, _react.useContext)(OfflineInterfaceContext);
|
|
57
|
-
|
|
58
48
|
if (offlineInterface === undefined) {
|
|
59
49
|
throw new Error('Offline interface context not found. If this app is using the app platform, make sure `pwa: { enabled: true }` is in d2.config.js. If this is not a platform app, make sure your app is wrapped with an app-runtime <Provider> or an <OfflineProvider> from app-service-offline.');
|
|
60
50
|
}
|
|
61
|
-
|
|
62
51
|
return offlineInterface;
|
|
63
52
|
}
|
|
@@ -4,39 +4,28 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.OfflineProvider = OfflineProvider;
|
|
7
|
-
|
|
8
7
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
-
|
|
10
8
|
var _react = _interopRequireDefault(require("react"));
|
|
11
|
-
|
|
12
9
|
var _cacheableSectionState = require("./cacheable-section-state");
|
|
13
|
-
|
|
14
10
|
var _dhis2ConnectionStatus = require("./dhis2-connection-status");
|
|
15
|
-
|
|
16
11
|
var _offlineInterface = require("./offline-interface");
|
|
17
|
-
|
|
18
12
|
var _onlineStatusMessage = require("./online-status-message");
|
|
19
|
-
|
|
20
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
21
|
-
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
22
14
|
/** A context provider for all the relevant offline contexts */
|
|
23
15
|
function OfflineProvider(_ref) {
|
|
24
16
|
let {
|
|
25
17
|
offlineInterface,
|
|
26
18
|
children
|
|
27
19
|
} = _ref;
|
|
28
|
-
|
|
29
20
|
// If an offline interface is not provided, or if one is provided and PWA
|
|
30
21
|
// is not enabled, skip adding context providers
|
|
31
22
|
if (!offlineInterface || !offlineInterface.pwaEnabled) {
|
|
32
23
|
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, children);
|
|
33
24
|
}
|
|
34
|
-
|
|
35
25
|
return /*#__PURE__*/_react.default.createElement(_offlineInterface.OfflineInterfaceProvider, {
|
|
36
26
|
offlineInterface: offlineInterface
|
|
37
27
|
}, /*#__PURE__*/_react.default.createElement(_dhis2ConnectionStatus.Dhis2ConnectionStatusProvider, null, /*#__PURE__*/_react.default.createElement(_cacheableSectionState.CacheableSectionProvider, null, /*#__PURE__*/_react.default.createElement(_onlineStatusMessage.OnlineStatusMessageProvider, null, children))));
|
|
38
28
|
}
|
|
39
|
-
|
|
40
29
|
OfflineProvider.propTypes = {
|
|
41
30
|
children: _propTypes.default.node,
|
|
42
31
|
offlineInterface: _propTypes.default.shape({
|
|
@@ -4,20 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.useSetOnlineStatusMessage = exports.useOnlineStatusMessageValue = exports.useOnlineStatusMessage = exports.OnlineStatusMessageProvider = void 0;
|
|
7
|
-
|
|
8
7
|
var _react = _interopRequireWildcard(require("react"));
|
|
9
|
-
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
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; }
|
|
13
|
-
|
|
8
|
+
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); }
|
|
9
|
+
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; }
|
|
14
10
|
// 'get' and 'set' contexts are separated so 'setter' consumers that don't
|
|
15
11
|
// actually need the value don't have to rerender when the value changes:
|
|
16
12
|
const OnlineStatusMessageValueContext = /*#__PURE__*/_react.default.createContext(undefined);
|
|
17
|
-
|
|
18
13
|
const SetOnlineStatusMessageContext = /*#__PURE__*/_react.default.createContext(() => undefined);
|
|
19
|
-
|
|
20
|
-
const OnlineStatusMessageProvider = (_ref) => {
|
|
14
|
+
const OnlineStatusMessageProvider = _ref => {
|
|
21
15
|
let {
|
|
22
16
|
children
|
|
23
17
|
} = _ref;
|
|
@@ -29,22 +23,17 @@ const OnlineStatusMessageProvider = (_ref) => {
|
|
|
29
23
|
value: setOnlineStatusMessage
|
|
30
24
|
}, children));
|
|
31
25
|
};
|
|
32
|
-
|
|
33
26
|
exports.OnlineStatusMessageProvider = OnlineStatusMessageProvider;
|
|
34
|
-
|
|
35
27
|
const useOnlineStatusMessageValue = () => {
|
|
36
28
|
return (0, _react.useContext)(OnlineStatusMessageValueContext);
|
|
37
29
|
};
|
|
38
|
-
|
|
39
30
|
exports.useOnlineStatusMessageValue = useOnlineStatusMessageValue;
|
|
40
|
-
|
|
41
31
|
const useSetOnlineStatusMessage = () => {
|
|
42
32
|
return (0, _react.useContext)(SetOnlineStatusMessageContext);
|
|
43
|
-
};
|
|
44
|
-
|
|
33
|
+
};
|
|
45
34
|
|
|
35
|
+
// combination of both getter and setter (also provides backward compatability)
|
|
46
36
|
exports.useSetOnlineStatusMessage = useSetOnlineStatusMessage;
|
|
47
|
-
|
|
48
37
|
const useOnlineStatusMessage = () => {
|
|
49
38
|
const onlineStatusMessage = useOnlineStatusMessageValue();
|
|
50
39
|
const setOnlineStatusMessage = useSetOnlineStatusMessage();
|
|
@@ -53,5 +42,4 @@ const useOnlineStatusMessage = () => {
|
|
|
53
42
|
setOnlineStatusMessage
|
|
54
43
|
};
|
|
55
44
|
};
|
|
56
|
-
|
|
57
45
|
exports.useOnlineStatusMessage = useOnlineStatusMessage;
|
package/build/cjs/setupRTL.js
CHANGED
|
@@ -4,22 +4,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.Rerenderer = void 0;
|
|
7
|
-
|
|
8
7
|
var _react = require("@testing-library/react");
|
|
9
|
-
|
|
10
8
|
var _react2 = _interopRequireDefault(require("react"));
|
|
11
|
-
|
|
12
9
|
var _renderCounter = require("../render-counter");
|
|
13
|
-
|
|
14
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
15
|
-
|
|
10
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
11
|
const renderCounts = {};
|
|
17
|
-
|
|
18
12
|
const Rerenderer = () => {
|
|
19
13
|
const [, setState] = _react2.default.useState(true);
|
|
20
|
-
|
|
21
14
|
const toggleState = () => setState(prevState => !prevState);
|
|
22
|
-
|
|
23
15
|
return /*#__PURE__*/_react2.default.createElement(_react2.default.Fragment, null, /*#__PURE__*/_react2.default.createElement("button", {
|
|
24
16
|
onClick: toggleState,
|
|
25
17
|
role: "button"
|
|
@@ -28,13 +20,12 @@ const Rerenderer = () => {
|
|
|
28
20
|
countsObj: renderCounts
|
|
29
21
|
}));
|
|
30
22
|
};
|
|
31
|
-
|
|
32
23
|
exports.Rerenderer = Rerenderer;
|
|
33
24
|
afterEach(() => {
|
|
34
25
|
(0, _renderCounter.resetRenderCounts)(renderCounts);
|
|
35
26
|
});
|
|
36
27
|
it('increments the counter when rerendered', () => {
|
|
37
|
-
(0, _react.render)(
|
|
28
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(Rerenderer, null));
|
|
38
29
|
const {
|
|
39
30
|
getByTestId,
|
|
40
31
|
getByRole
|
|
@@ -50,6 +41,6 @@ it('increments the counter when rerendered', () => {
|
|
|
50
41
|
expect(getByTestId('rc1')).toHaveTextContent('3');
|
|
51
42
|
});
|
|
52
43
|
it('resets the render counter successfully', () => {
|
|
53
|
-
(0, _react.render)(
|
|
44
|
+
(0, _react.render)(/*#__PURE__*/_react2.default.createElement(Rerenderer, null));
|
|
54
45
|
expect(_react.screen.getByTestId('rc1')).toHaveTextContent('1');
|
|
55
46
|
});
|