@khanacademy/wonder-blocks-timing 2.0.3 → 2.1.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/CHANGELOG.md +18 -0
- package/dist/es/index.js +107 -230
- package/dist/index.js +260 -547
- package/dist/index.js.flow +1 -1
- package/package.json +3 -4
- package/src/__docs__/_overview_.stories.mdx +17 -0
- package/src/components/__docs__/migration.stories.mdx +112 -0
- package/{docs.md → src/components/__docs__/types.ischedule-actions.stories.mdx} +11 -260
- package/src/components/__docs__/with-action-scheduler-examples.js +80 -0
- package/src/components/__docs__/with-action-scheduler.stories.mdx +218 -0
- package/src/components/__tests__/action-scheduler-provider.test.js +7 -7
- package/src/components/__tests__/with-action-scheduler.test.js +6 -6
- package/src/components/action-scheduler-provider.js +2 -2
- package/src/components/with-action-scheduler.js +2 -2
- package/src/hooks/__docs__/use-interval.stories.mdx +80 -0
- package/src/hooks/__docs__/use-scheduled-interval.stories.mdx +147 -0
- package/src/hooks/{use-timeout.stories.mdx → __docs__/use-scheduled-timeout.stories.mdx} +13 -17
- package/src/hooks/__docs__/use-timeout.stories.mdx +80 -0
- package/src/hooks/__tests__/use-interval.test.js +124 -0
- package/src/hooks/__tests__/use-scheduled-interval.test.js +461 -0
- package/src/hooks/__tests__/use-scheduled-timeout.test.js +479 -0
- package/src/hooks/__tests__/use-timeout.test.js +94 -294
- package/src/hooks/internal/use-updating-ref.js +20 -0
- package/src/hooks/use-interval.js +37 -0
- package/src/hooks/use-scheduled-interval.js +73 -0
- package/src/hooks/use-scheduled-timeout.js +80 -0
- package/src/hooks/use-timeout.js +22 -55
- package/src/index.js +7 -4
- package/src/util/__tests__/action-scheduler.test.js +9 -9
- package/src/util/__tests__/animation-frame.test.js +2 -2
- package/src/util/__tests__/interval.test.js +2 -2
- package/src/util/__tests__/timeout.test.js +2 -2
- package/src/util/action-scheduler.js +4 -4
- package/src/util/animation-frame.js +2 -2
- package/src/util/interval.js +2 -2
- package/src/util/timeout.js +2 -2
- package/src/util/types.flowtest.js +2 -2
- package/LICENSE +0 -21
- package/src/__tests__/__snapshots__/generated-snapshot.test.js.snap +0 -353
- package/src/__tests__/generated-snapshot.test.js +0 -156
- package/src/components/with-action-scheduler.md +0 -18
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @khanacademy/wonder-blocks-timing
|
|
2
|
+
|
|
3
|
+
## 2.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 91cb727c: Remove file extensions from imports
|
|
8
|
+
|
|
9
|
+
## 2.1.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 029b4810: Adds `useInterval()` hook that mimics the behavior of `ActionScheduler`'s
|
|
14
|
+
`interval()` method.
|
|
15
|
+
- c57cd770: Rename `useInterval` and `useTimeout` to `useScheduledInterval`
|
|
16
|
+
and `useScheduledTimeout` respectively.
|
|
17
|
+
- 29766c8e: Add `useInterval` and `useTimeout` hooks to provide an API for
|
|
18
|
+
using intervals and timeouts.
|
package/dist/es/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _extends from '@babel/runtime/helpers/extends';
|
|
2
|
-
import
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { useRef, useEffect, useState, useCallback } from 'react';
|
|
3
4
|
|
|
4
5
|
const SchedulePolicy = {
|
|
5
6
|
Immediately: "schedule-immediately",
|
|
@@ -10,29 +11,7 @@ const ClearPolicy = {
|
|
|
10
11
|
Cancel: "cancel-on-clear"
|
|
11
12
|
};
|
|
12
13
|
|
|
13
|
-
/**
|
|
14
|
-
* Encapsulates everything associated with calling setTimeout/clearTimeout, and
|
|
15
|
-
* managing the lifecycle of that timer, including the ability to resolve or
|
|
16
|
-
* cancel a pending timeout action.
|
|
17
|
-
*
|
|
18
|
-
* @export
|
|
19
|
-
* @class Timeout
|
|
20
|
-
* @implements {ITimeout}
|
|
21
|
-
*/
|
|
22
14
|
class Timeout {
|
|
23
|
-
/**
|
|
24
|
-
* Creates a timeout that will invoke the given action after
|
|
25
|
-
* the given period. The timeout does not start until set is called.
|
|
26
|
-
*
|
|
27
|
-
* @param {() => mixed} action The action to be invoked when the timeout
|
|
28
|
-
* period has passed.
|
|
29
|
-
* @param {number} timeoutMs The timeout period.
|
|
30
|
-
* @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
|
|
31
|
-
* the timer is set immediately on instantiation; otherwise, `set` must be
|
|
32
|
-
* called to set the timeout.
|
|
33
|
-
* Defaults to `SchedulePolicy.Immediately`.
|
|
34
|
-
* @memberof Timeout
|
|
35
|
-
*/
|
|
36
15
|
constructor(action, timeoutMs, schedulePolicy = SchedulePolicy.Immediately) {
|
|
37
16
|
if (typeof action !== "function") {
|
|
38
17
|
throw new Error("Action must be a function");
|
|
@@ -49,28 +28,10 @@ class Timeout {
|
|
|
49
28
|
this.set();
|
|
50
29
|
}
|
|
51
30
|
}
|
|
52
|
-
/**
|
|
53
|
-
* Determine if the timeout is set or not.
|
|
54
|
-
*
|
|
55
|
-
* @returns {boolean} true if the timeout is set (aka pending), otherwise
|
|
56
|
-
* false.
|
|
57
|
-
* @memberof Timeout
|
|
58
|
-
*/
|
|
59
|
-
|
|
60
31
|
|
|
61
32
|
get isSet() {
|
|
62
33
|
return this._timeoutId != null;
|
|
63
34
|
}
|
|
64
|
-
/**
|
|
65
|
-
* Set the timeout.
|
|
66
|
-
*
|
|
67
|
-
* If the timeout is pending, this cancels that pending timeout and
|
|
68
|
-
* sets the timeout afresh. If the timeout is not pending, this
|
|
69
|
-
* sets a new timeout.
|
|
70
|
-
*
|
|
71
|
-
* @memberof Timeout
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
35
|
|
|
75
36
|
set() {
|
|
76
37
|
if (this.isSet) {
|
|
@@ -79,21 +40,6 @@ class Timeout {
|
|
|
79
40
|
|
|
80
41
|
this._timeoutId = setTimeout(() => this.clear(ClearPolicy.Resolve), this._timeoutMs);
|
|
81
42
|
}
|
|
82
|
-
/**
|
|
83
|
-
* Clear the set timeout.
|
|
84
|
-
*
|
|
85
|
-
* If the timeout is pending, this cancels that pending timeout without
|
|
86
|
-
* invoking the action. If no timeout is pending, this does nothing.
|
|
87
|
-
*
|
|
88
|
-
* @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
|
|
89
|
-
* was set when called, the request action is invoked after cancelling
|
|
90
|
-
* the request; otherwise, the pending action is cancelled.
|
|
91
|
-
* Defaults to `ClearPolicy.Cancel`.
|
|
92
|
-
*
|
|
93
|
-
* @returns {void}
|
|
94
|
-
* @memberof Timeout
|
|
95
|
-
*/
|
|
96
|
-
|
|
97
43
|
|
|
98
44
|
clear(policy = ClearPolicy.Cancel) {
|
|
99
45
|
const timeoutId = this._timeoutId;
|
|
@@ -112,29 +58,7 @@ class Timeout {
|
|
|
112
58
|
|
|
113
59
|
}
|
|
114
60
|
|
|
115
|
-
/**
|
|
116
|
-
* Encapsulates everything associated with calling setInterval/clearInterval,
|
|
117
|
-
* and managing the lifecycle of that interval. This includes the ability to
|
|
118
|
-
* cancel the interval, and knowing if the interval is active.
|
|
119
|
-
*
|
|
120
|
-
* @export
|
|
121
|
-
* @class Interval
|
|
122
|
-
* @implements {IInterval}
|
|
123
|
-
*/
|
|
124
61
|
class Interval {
|
|
125
|
-
/**
|
|
126
|
-
* Creates an interval that will invoke the given action after
|
|
127
|
-
* the given period. The interval does not start until set is called.
|
|
128
|
-
*
|
|
129
|
-
* @param {() => mixed} action The action to be invoked each time the
|
|
130
|
-
* interval period has passed.
|
|
131
|
-
* @param {number} intervalMs The interval period.
|
|
132
|
-
* @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
|
|
133
|
-
* the interval is set immediately on instantiation; otherwise, `set` must be
|
|
134
|
-
* called to set the interval.
|
|
135
|
-
* Defaults to `SchedulePolicy.Immediately`.
|
|
136
|
-
* @memberof Interval
|
|
137
|
-
*/
|
|
138
62
|
constructor(action, intervalMs, schedulePolicy = SchedulePolicy.Immediately) {
|
|
139
63
|
if (typeof action !== "function") {
|
|
140
64
|
throw new Error("Action must be a function");
|
|
@@ -151,26 +75,10 @@ class Interval {
|
|
|
151
75
|
this.set();
|
|
152
76
|
}
|
|
153
77
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Determine if the interval is active or not.
|
|
156
|
-
*
|
|
157
|
-
* @returns {boolean} true if the interval is active, otherwise false.
|
|
158
|
-
* @memberof Interval
|
|
159
|
-
*/
|
|
160
|
-
|
|
161
78
|
|
|
162
79
|
get isSet() {
|
|
163
80
|
return this._intervalId != null;
|
|
164
81
|
}
|
|
165
|
-
/**
|
|
166
|
-
* Activate the interval.
|
|
167
|
-
*
|
|
168
|
-
* If the interval is active, this cancels that interval and starts the
|
|
169
|
-
* interval afresh. If the interval is not active, this starts it.
|
|
170
|
-
*
|
|
171
|
-
* @memberof Interval
|
|
172
|
-
*/
|
|
173
|
-
|
|
174
82
|
|
|
175
83
|
set() {
|
|
176
84
|
if (this.isSet) {
|
|
@@ -179,21 +87,6 @@ class Interval {
|
|
|
179
87
|
|
|
180
88
|
this._intervalId = setInterval(() => this._action(), this._intervalMs);
|
|
181
89
|
}
|
|
182
|
-
/**
|
|
183
|
-
* Clear the active interval.
|
|
184
|
-
*
|
|
185
|
-
* If the interval is active, this cancels that interval. If no interval is
|
|
186
|
-
* pending, this does nothing.
|
|
187
|
-
*
|
|
188
|
-
* @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
|
|
189
|
-
* was set when called, the request action is invoked after cancelling
|
|
190
|
-
* the request; otherwise, the pending action is cancelled.
|
|
191
|
-
* Defaults to `ClearPolicy.Cancel`.
|
|
192
|
-
*
|
|
193
|
-
* @returns {void}
|
|
194
|
-
* @memberof Interval
|
|
195
|
-
*/
|
|
196
|
-
|
|
197
90
|
|
|
198
91
|
clear(policy = ClearPolicy.Cancel) {
|
|
199
92
|
const intervalId = this._intervalId;
|
|
@@ -212,27 +105,7 @@ class Interval {
|
|
|
212
105
|
|
|
213
106
|
}
|
|
214
107
|
|
|
215
|
-
/**
|
|
216
|
-
* Encapsulates everything associated with calling requestAnimationFrame/
|
|
217
|
-
* cancelAnimationFrame, and managing the lifecycle of that request, including
|
|
218
|
-
* the ability to resolve or cancel a pending request action.
|
|
219
|
-
*
|
|
220
|
-
* @export
|
|
221
|
-
* @class AnimationFrame
|
|
222
|
-
* @implements {IAnimationFrame}
|
|
223
|
-
*/
|
|
224
108
|
class AnimationFrame {
|
|
225
|
-
/**
|
|
226
|
-
* Creates an animation frame request that will invoke the given action.
|
|
227
|
-
* The request is not made until set is called.
|
|
228
|
-
*
|
|
229
|
-
* @param {DOMHighResTimeStamp => mixed} action The action to be invoked.
|
|
230
|
-
* @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
|
|
231
|
-
* the interval is set immediately on instantiation; otherwise, `set` must be
|
|
232
|
-
* called to set the interval.
|
|
233
|
-
* Defaults to `SchedulePolicy.Immediately`.
|
|
234
|
-
* @memberof AnimationFrame
|
|
235
|
-
*/
|
|
236
109
|
constructor(action, schedulePolicy = SchedulePolicy.Immediately) {
|
|
237
110
|
if (typeof action !== "function") {
|
|
238
111
|
throw new Error("Action must be a function");
|
|
@@ -244,28 +117,10 @@ class AnimationFrame {
|
|
|
244
117
|
this.set();
|
|
245
118
|
}
|
|
246
119
|
}
|
|
247
|
-
/**
|
|
248
|
-
* Determine if the request is pending or not.
|
|
249
|
-
*
|
|
250
|
-
* @returns {boolean} true if the request is pending, otherwise
|
|
251
|
-
* false.
|
|
252
|
-
* @memberof AnimationFrame
|
|
253
|
-
*/
|
|
254
|
-
|
|
255
120
|
|
|
256
121
|
get isSet() {
|
|
257
122
|
return this._animationFrameId != null;
|
|
258
123
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Make the animation frame request.
|
|
261
|
-
*
|
|
262
|
-
* If the request is pending, this cancels that pending request and
|
|
263
|
-
* makes the request afresh. If the request is not pending, this
|
|
264
|
-
* makes a new request.
|
|
265
|
-
*
|
|
266
|
-
* @memberof AnimationFrame
|
|
267
|
-
*/
|
|
268
|
-
|
|
269
124
|
|
|
270
125
|
set() {
|
|
271
126
|
if (this.isSet) {
|
|
@@ -274,24 +129,6 @@ class AnimationFrame {
|
|
|
274
129
|
|
|
275
130
|
this._animationFrameId = requestAnimationFrame(time => this.clear(ClearPolicy.Resolve, time));
|
|
276
131
|
}
|
|
277
|
-
/**
|
|
278
|
-
* Clear the pending request.
|
|
279
|
-
*
|
|
280
|
-
* If the request is pending, this cancels that pending request without
|
|
281
|
-
* invoking the action. If no request is pending, this does nothing.
|
|
282
|
-
*
|
|
283
|
-
* @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
|
|
284
|
-
* was set when called, the request action is invoked after cancelling
|
|
285
|
-
* the request; otherwise, the pending action is cancelled.
|
|
286
|
-
* Defaults to `ClearPolicy.Cancel`.
|
|
287
|
-
* @param {DOMHighResTimeStamp} [time] Timestamp to pass to the action when
|
|
288
|
-
* ClearPolicy.Resolve is specified. Ignored when ClearPolicy.Cancel is
|
|
289
|
-
* specified.
|
|
290
|
-
*
|
|
291
|
-
* @returns {void}
|
|
292
|
-
* @memberof AnimationFrame
|
|
293
|
-
*/
|
|
294
|
-
|
|
295
132
|
|
|
296
133
|
clear(policy = ClearPolicy.Cancel, time) {
|
|
297
134
|
const animationFrameId = this._animationFrameId;
|
|
@@ -310,12 +147,6 @@ class AnimationFrame {
|
|
|
310
147
|
|
|
311
148
|
}
|
|
312
149
|
|
|
313
|
-
/**
|
|
314
|
-
* Implements the `IScheduleActions` API to provide timeout, interval, and
|
|
315
|
-
* animation frame support. This is not intended for direct use, but instead
|
|
316
|
-
* is to be used solely by the `ActionSchedulerProvider` to provide an
|
|
317
|
-
* `IScheduleActions` instance.
|
|
318
|
-
*/
|
|
319
150
|
class ActionScheduler {
|
|
320
151
|
constructor() {
|
|
321
152
|
this._disabled = false;
|
|
@@ -363,11 +194,6 @@ class ActionScheduler {
|
|
|
363
194
|
this._registeredActions = [];
|
|
364
195
|
registered.forEach(clearFn => clearFn());
|
|
365
196
|
}
|
|
366
|
-
/**
|
|
367
|
-
* Prevents this scheduler from creating any additional actions.
|
|
368
|
-
* This also clears any pending actions.
|
|
369
|
-
*/
|
|
370
|
-
|
|
371
197
|
|
|
372
198
|
disable() {
|
|
373
199
|
this._disabled = true;
|
|
@@ -385,17 +211,7 @@ ActionScheduler.NoopAction = {
|
|
|
385
211
|
clear: () => {}
|
|
386
212
|
};
|
|
387
213
|
|
|
388
|
-
|
|
389
|
-
* A provider component that passes our action scheduling API to its children
|
|
390
|
-
* and ensures that all scheduled actions are cleared on unmount.
|
|
391
|
-
*
|
|
392
|
-
* ```jsx
|
|
393
|
-
* <ActionSchedulerProvider>
|
|
394
|
-
* {schedule => this.renderThingThatNeedsTimers(schedule)}
|
|
395
|
-
* </ActionSchedulerProvider>
|
|
396
|
-
* ```
|
|
397
|
-
*/
|
|
398
|
-
class ActionSchedulerProvider extends Component {
|
|
214
|
+
class ActionSchedulerProvider extends React.Component {
|
|
399
215
|
constructor(...args) {
|
|
400
216
|
super(...args);
|
|
401
217
|
this._actionScheduler = new ActionScheduler();
|
|
@@ -414,69 +230,130 @@ class ActionSchedulerProvider extends Component {
|
|
|
414
230
|
|
|
415
231
|
}
|
|
416
232
|
|
|
417
|
-
/**
|
|
418
|
-
* A higher order component that attaches the given component to an
|
|
419
|
-
* `IScheduleActions` instance. Any actions scheduled will automatically be
|
|
420
|
-
* cleared on unmount.
|
|
421
|
-
*
|
|
422
|
-
* @template TOwnProps The own props of the component being rendered, without
|
|
423
|
-
* the additional action scheduler prop. To attach the additional prop to
|
|
424
|
-
* these props use the `WithActionScheduler` type.
|
|
425
|
-
*/
|
|
426
233
|
function withActionScheduler(WrappedComponent) {
|
|
427
|
-
return
|
|
234
|
+
return React.forwardRef((props, ref) => React.createElement(ActionSchedulerProvider, null, schedule => React.createElement(WrappedComponent, _extends({}, props, {
|
|
428
235
|
ref: ref,
|
|
429
236
|
schedule: schedule
|
|
430
237
|
}))));
|
|
431
238
|
}
|
|
432
239
|
|
|
433
|
-
|
|
240
|
+
const useUpdatingRef = value => {
|
|
241
|
+
const ref = useRef(value);
|
|
242
|
+
useEffect(() => {
|
|
243
|
+
ref.current = value;
|
|
244
|
+
}, [value]);
|
|
245
|
+
return ref;
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
function useInterval(action, intervalMs, active) {
|
|
249
|
+
const actionRef = useUpdatingRef(action);
|
|
250
|
+
useEffect(() => {
|
|
251
|
+
if (active) {
|
|
252
|
+
const intervalId = setInterval(() => {
|
|
253
|
+
actionRef.current();
|
|
254
|
+
}, intervalMs);
|
|
255
|
+
return () => {
|
|
256
|
+
clearInterval(intervalId);
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
}, [intervalMs, active, actionRef]);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function useTimeout(action, timeoutMs, active) {
|
|
263
|
+
const actionRef = useUpdatingRef(action);
|
|
264
|
+
useEffect(() => {
|
|
265
|
+
if (active) {
|
|
266
|
+
const timeoutId = setTimeout(() => {
|
|
267
|
+
actionRef.current();
|
|
268
|
+
}, timeoutMs);
|
|
269
|
+
return () => {
|
|
270
|
+
clearTimeout(timeoutId);
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}, [timeoutMs, active, actionRef]);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function useScheduledInterval(action, intervalMs, options) {
|
|
434
277
|
var _options$schedulePoli;
|
|
435
278
|
|
|
279
|
+
if (typeof action !== "function") {
|
|
280
|
+
throw new Error("Action must be a function");
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (intervalMs < 1) {
|
|
284
|
+
throw new Error("Interval period must be >= 1");
|
|
285
|
+
}
|
|
286
|
+
|
|
436
287
|
const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : SchedulePolicy.Immediately;
|
|
437
288
|
const [isSet, setIsSet] = useState(schedulePolicy === SchedulePolicy.Immediately);
|
|
438
|
-
const
|
|
439
|
-
const
|
|
289
|
+
const set = useCallback(() => setIsSet(true), []);
|
|
290
|
+
const actionRef = useUpdatingRef(action);
|
|
291
|
+
const clear = useCallback(policy => {
|
|
292
|
+
var _policy;
|
|
293
|
+
|
|
294
|
+
policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
|
|
295
|
+
|
|
296
|
+
if (isSet && policy === ClearPolicy.Resolve) {
|
|
297
|
+
actionRef.current();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
setIsSet(false);
|
|
301
|
+
}, [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
|
|
302
|
+
const runOnUnmountRef = useUpdatingRef(isSet && (options == null ? void 0 : options.clearPolicy) === ClearPolicy.Resolve);
|
|
440
303
|
useEffect(() => {
|
|
441
|
-
mountedRef.current = true;
|
|
442
304
|
return () => {
|
|
443
|
-
|
|
305
|
+
if (runOnUnmountRef.current) {
|
|
306
|
+
actionRef.current();
|
|
307
|
+
}
|
|
444
308
|
};
|
|
445
309
|
}, []);
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
310
|
+
useInterval(action, intervalMs, isSet);
|
|
311
|
+
return {
|
|
312
|
+
isSet,
|
|
313
|
+
set,
|
|
314
|
+
clear
|
|
315
|
+
};
|
|
316
|
+
}
|
|
453
317
|
|
|
318
|
+
function useScheduledTimeout(action, timeoutMs, options) {
|
|
319
|
+
var _options$schedulePoli;
|
|
320
|
+
|
|
321
|
+
if (typeof action !== "function") {
|
|
322
|
+
throw new Error("Action must be a function");
|
|
323
|
+
}
|
|
454
324
|
|
|
325
|
+
if (timeoutMs < 0) {
|
|
326
|
+
throw new Error("Timeout period must be >= 0");
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : SchedulePolicy.Immediately;
|
|
330
|
+
const [isSet, setIsSet] = useState(schedulePolicy === SchedulePolicy.Immediately);
|
|
331
|
+
const set = useCallback(() => setIsSet(true), []);
|
|
332
|
+
const wrappedAction = useCallback(() => {
|
|
455
333
|
setIsSet(false);
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
334
|
+
action();
|
|
335
|
+
}, [action]);
|
|
336
|
+
const actionRef = useUpdatingRef(wrappedAction);
|
|
337
|
+
const clear = useCallback(policy => {
|
|
338
|
+
var _policy;
|
|
461
339
|
|
|
340
|
+
policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
|
|
462
341
|
|
|
463
|
-
|
|
464
|
-
|
|
342
|
+
if (isSet && policy === ClearPolicy.Resolve) {
|
|
343
|
+
actionRef.current();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
setIsSet(false);
|
|
347
|
+
}, [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
|
|
348
|
+
const runOnUnmountRef = useUpdatingRef(isSet && (options == null ? void 0 : options.clearPolicy) === ClearPolicy.Resolve);
|
|
465
349
|
useEffect(() => {
|
|
466
|
-
|
|
467
|
-
|
|
350
|
+
return () => {
|
|
351
|
+
if (runOnUnmountRef.current) {
|
|
468
352
|
actionRef.current();
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
if (!mountedRef.current) {
|
|
475
|
-
clear();
|
|
476
|
-
}
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
|
-
}, [clear, isSet, timeoutMs]);
|
|
353
|
+
}
|
|
354
|
+
};
|
|
355
|
+
}, []);
|
|
356
|
+
useTimeout(wrappedAction, timeoutMs, isSet);
|
|
480
357
|
return {
|
|
481
358
|
isSet,
|
|
482
359
|
set,
|
|
@@ -484,4 +361,4 @@ function useTimeout(action, timeoutMs, options) {
|
|
|
484
361
|
};
|
|
485
362
|
}
|
|
486
363
|
|
|
487
|
-
export { ClearPolicy, SchedulePolicy, useTimeout, withActionScheduler };
|
|
364
|
+
export { ClearPolicy, SchedulePolicy, useInterval, useScheduledInterval, useScheduledTimeout, useTimeout, withActionScheduler };
|