@khanacademy/wonder-blocks-timing 4.0.2 → 5.0.0

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @khanacademy/wonder-blocks-timing
2
2
 
3
+ ## 5.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - f72f7dd4: - **[BREAKING CHANGE]** Policy types are now using enums across all APIs
8
+ - **[BREAKING CHANGE]** `useScheduledTimeout` has been renamed to `useTimeout` and the original `useTimeout` has been removed. To update existing uses of `useTimeout` to the new API: if `active` was `true` just delete that argument or replace it with `{schedulingPolicy: SchedulingPolicy.Immediately}`; if `active` was `false` replace it with `{schedulingPolicy: SchedulingPolicy.OnDemand}`.
9
+ - **[BREAKING CHANGE]** `useScheduledInterval` has been renamed to `useInterval` and the original `useInterval` has been removed. To update existing uses of `useInterval` to the new API: if `active` was `true` just delete that argument or replace it with `{schedulingPolicy: SchedulingPolicy.Immediately}`; if `active` was `false` replace it with `{schedulingPolicy: SchedulingPolicy.OnDemand}`.
10
+ - **[NEW]** `useTimeout` now supports an optional `ActionPolicy` in the options. The default is to not reset the timeout when the `action` callback changes. This can be changed to `ActionPolicy.Reset` to reset the timeout when the `action` callback changes (it is recommended that you use `useCallback` on your `action` callback to avoid resetting the timeout everytime a component renders when using the `Reset` policy).
11
+ - **[NEW]** `useInterval` now supports an optional `ActionPolicy` in the options. The default is to not reset the interval when the `action` callback changes. This can be changed to `ActionPolicy.Reset` to reset the interval when the `action` callback changes (it is recommended that you use `useCallback` on your `action` callback to avoid resetting the interval everytime a component renders when using the `Reset` policy).
12
+ - **[BUGFIX]** `useTimeout` will now correctly reset the timeout when the `set` method is called, as intended.
13
+ - **[BUGFIX]** `useInterval` will now correctly reset the interval when the `set` method is called, as intended.
14
+
3
15
  ## 4.0.2
4
16
 
5
17
  ### Patch Changes
package/dist/es/index.js CHANGED
@@ -1,14 +1,21 @@
1
1
  import * as React from 'react';
2
- import { useRef, useEffect, useState, useCallback } from 'react';
2
+ import { useRef, useEffect, useMemo } from 'react';
3
3
 
4
- const SchedulePolicy = {
5
- Immediately: "schedule-immediately",
6
- OnDemand: "schedule-on-demand"
7
- };
8
- const ClearPolicy = {
9
- Resolve: "resolve-on-clear",
10
- Cancel: "cancel-on-clear"
11
- };
4
+ let SchedulePolicy = function (SchedulePolicy) {
5
+ SchedulePolicy["Immediately"] = "schedule-immediately";
6
+ SchedulePolicy["OnDemand"] = "schedule-on-demand";
7
+ return SchedulePolicy;
8
+ }({});
9
+ let ClearPolicy = function (ClearPolicy) {
10
+ ClearPolicy["Resolve"] = "resolve-on-clear";
11
+ ClearPolicy["Cancel"] = "cancel-on-clear";
12
+ return ClearPolicy;
13
+ }({});
14
+ let ActionPolicy = function (ActionPolicy) {
15
+ ActionPolicy["Reset"] = "reset";
16
+ ActionPolicy["Passive"] = "passive";
17
+ return ActionPolicy;
18
+ }({});
12
19
 
13
20
  class Timeout {
14
21
  constructor(action, timeoutMs, schedulePolicy = SchedulePolicy.Immediately) {
@@ -209,116 +216,94 @@ function withActionScheduler(WrappedComponent) {
209
216
  return C;
210
217
  }
211
218
 
212
- const useUpdatingRef = value => {
213
- const ref = useRef(value);
214
- useEffect(() => {
215
- ref.current = value;
216
- }, [value]);
217
- return ref;
218
- };
219
-
220
- function useInterval(action, intervalMs, active) {
221
- const actionRef = useUpdatingRef(action);
222
- useEffect(() => {
223
- if (active) {
224
- const intervalId = setInterval(() => {
225
- actionRef.current();
226
- }, intervalMs);
227
- return () => {
228
- clearInterval(intervalId);
229
- };
230
- }
231
- }, [intervalMs, active, actionRef]);
232
- }
233
-
234
- function useTimeout(action, timeoutMs, active) {
235
- const actionRef = useUpdatingRef(action);
236
- useEffect(() => {
237
- if (active) {
238
- const timeoutId = setTimeout(() => {
239
- actionRef.current();
240
- }, timeoutMs);
241
- return () => {
242
- clearTimeout(timeoutId);
243
- };
244
- }
245
- }, [timeoutMs, active, actionRef]);
246
- }
247
-
248
- function useScheduledInterval(action, intervalMs, options) {
249
- var _options$schedulePoli;
219
+ function useInterval(action, intervalMs, options = {}) {
220
+ const {
221
+ actionPolicy,
222
+ clearPolicy,
223
+ schedulePolicy
224
+ } = options;
225
+ const actionProxyRef = useRef(action);
226
+ const intervalRef = useRef(null);
250
227
  if (typeof action !== "function") {
251
228
  throw new Error("Action must be a function");
252
229
  }
253
- if (intervalMs < 1) {
254
- throw new Error("Interval period must be >= 1");
255
- }
256
- const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : SchedulePolicy.Immediately;
257
- const [isSet, setIsSet] = useState(schedulePolicy === SchedulePolicy.Immediately);
258
- const set = useCallback(() => setIsSet(true), []);
259
- const actionRef = useUpdatingRef(action);
260
- const clear = useCallback(policy => {
261
- var _policy;
262
- policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
263
- if (isSet && policy === ClearPolicy.Resolve) {
264
- actionRef.current();
230
+ if (action !== actionProxyRef.current) {
231
+ actionProxyRef.current = action;
232
+ if (actionPolicy === ActionPolicy.Reset) {
233
+ var _intervalRef$current;
234
+ (_intervalRef$current = intervalRef.current) == null ? void 0 : _intervalRef$current.set();
265
235
  }
266
- setIsSet(false);
267
- }, [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
268
- const runOnUnmountRef = useUpdatingRef(isSet && (options == null ? void 0 : options.clearPolicy) === ClearPolicy.Resolve);
236
+ }
269
237
  useEffect(() => {
238
+ intervalRef.current = new Interval(() => {
239
+ actionProxyRef.current == null ? void 0 : actionProxyRef.current();
240
+ }, intervalMs, schedulePolicy);
270
241
  return () => {
271
- if (runOnUnmountRef.current) {
272
- actionRef.current();
273
- }
242
+ var _intervalRef$current2;
243
+ (_intervalRef$current2 = intervalRef.current) == null ? void 0 : _intervalRef$current2.clear(clearPolicy);
244
+ intervalRef.current = null;
274
245
  };
275
- }, []);
276
- useInterval(action, intervalMs, isSet);
277
- return {
278
- isSet,
279
- set,
280
- clear
281
- };
246
+ }, [intervalMs, clearPolicy, schedulePolicy]);
247
+ const externalApi = useMemo(() => ({
248
+ set: () => {
249
+ var _intervalRef$current3;
250
+ (_intervalRef$current3 = intervalRef.current) == null ? void 0 : _intervalRef$current3.set();
251
+ },
252
+ clear: policy => {
253
+ var _intervalRef$current4;
254
+ (_intervalRef$current4 = intervalRef.current) == null ? void 0 : _intervalRef$current4.clear(policy);
255
+ },
256
+ get isSet() {
257
+ var _intervalRef$current$, _intervalRef$current5;
258
+ return (_intervalRef$current$ = (_intervalRef$current5 = intervalRef.current) == null ? void 0 : _intervalRef$current5.isSet) != null ? _intervalRef$current$ : false;
259
+ }
260
+ }), []);
261
+ return externalApi;
282
262
  }
283
263
 
284
- function useScheduledTimeout(action, timeoutMs, options) {
285
- var _options$schedulePoli;
264
+ function useTimeout(action, timeoutMs, options = {}) {
265
+ const {
266
+ actionPolicy,
267
+ clearPolicy,
268
+ schedulePolicy
269
+ } = options;
270
+ const actionProxyRef = useRef(action);
271
+ const timeoutRef = useRef(null);
286
272
  if (typeof action !== "function") {
287
273
  throw new Error("Action must be a function");
288
274
  }
289
- if (timeoutMs < 0) {
290
- throw new Error("Timeout period must be >= 0");
291
- }
292
- const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : SchedulePolicy.Immediately;
293
- const [isSet, setIsSet] = useState(schedulePolicy === SchedulePolicy.Immediately);
294
- const set = useCallback(() => setIsSet(true), []);
295
- const wrappedAction = useCallback(() => {
296
- setIsSet(false);
297
- action();
298
- }, [action]);
299
- const actionRef = useUpdatingRef(wrappedAction);
300
- const clear = useCallback(policy => {
301
- var _policy;
302
- policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
303
- if (isSet && policy === ClearPolicy.Resolve) {
304
- actionRef.current();
275
+ if (action !== actionProxyRef.current) {
276
+ actionProxyRef.current = action;
277
+ if (actionPolicy === ActionPolicy.Reset) {
278
+ var _timeoutRef$current;
279
+ (_timeoutRef$current = timeoutRef.current) == null ? void 0 : _timeoutRef$current.set();
305
280
  }
306
- setIsSet(false);
307
- }, [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
308
- const runOnUnmountRef = useUpdatingRef(isSet && (options == null ? void 0 : options.clearPolicy) === ClearPolicy.Resolve);
281
+ }
309
282
  useEffect(() => {
283
+ timeoutRef.current = new Timeout(() => {
284
+ actionProxyRef.current == null ? void 0 : actionProxyRef.current();
285
+ }, timeoutMs, schedulePolicy);
310
286
  return () => {
311
- if (runOnUnmountRef.current) {
312
- actionRef.current();
313
- }
287
+ var _timeoutRef$current2;
288
+ (_timeoutRef$current2 = timeoutRef.current) == null ? void 0 : _timeoutRef$current2.clear(clearPolicy);
289
+ timeoutRef.current = null;
314
290
  };
315
- }, []);
316
- useTimeout(wrappedAction, timeoutMs, isSet);
317
- return {
318
- isSet,
319
- set,
320
- clear
321
- };
291
+ }, [timeoutMs, clearPolicy, schedulePolicy]);
292
+ const externalApi = useMemo(() => ({
293
+ set: () => {
294
+ var _timeoutRef$current3;
295
+ (_timeoutRef$current3 = timeoutRef.current) == null ? void 0 : _timeoutRef$current3.set();
296
+ },
297
+ clear: policy => {
298
+ var _timeoutRef$current4;
299
+ (_timeoutRef$current4 = timeoutRef.current) == null ? void 0 : _timeoutRef$current4.clear(policy);
300
+ },
301
+ get isSet() {
302
+ var _timeoutRef$current$i, _timeoutRef$current5;
303
+ return (_timeoutRef$current$i = (_timeoutRef$current5 = timeoutRef.current) == null ? void 0 : _timeoutRef$current5.isSet) != null ? _timeoutRef$current$i : false;
304
+ }
305
+ }), []);
306
+ return externalApi;
322
307
  }
323
308
 
324
- export { ActionSchedulerProvider, ClearPolicy, SchedulePolicy, useInterval, useScheduledInterval, useScheduledTimeout, useTimeout, withActionScheduler };
309
+ export { ActionPolicy, ActionSchedulerProvider, ClearPolicy, SchedulePolicy, useInterval, useTimeout, withActionScheduler };
@@ -1,8 +1,30 @@
1
+ import type { IInterval, HookOptions } from "../util/types";
1
2
  /**
2
- * A simple hook for using `setInterval`.
3
+ * Hook providing access to a scheduled interval.
3
4
  *
4
- * @param action called every `intervalMs` when `active` is true
5
- * @param intervalMs the duration between calls to `action`
6
- * @param active whether or not the interval is active
5
+ * @param action The action to be invoked each time the interval period has
6
+ * passed. By default, this will not cause the interval to restart if it
7
+ * changes. This makes it easier to use with inline lambda functions rather than
8
+ * requiring consumers to wrap their action in a `useCallback`. To change this
9
+ * behavior, see the `actionPolicy` option.
10
+ * @param intervalMs The interval period. If this changes, the interval will
11
+ * be reset per the `schedulePolicy` option.
12
+ * @param options Options for the hook.
13
+ * @param options.actionPolicy Determines how the action is handled when it
14
+ * changes. By default, the action is replaced but the interval is not reset,
15
+ * and the updated action will be invoked when the interval next fires.
16
+ * If you want to reset the interval when the action changes, use
17
+ * `ActionPolicy.Reset`.
18
+ * @param options.clearPolicy Determines how the interval is cleared when the
19
+ * component is unmounted or the interval is recreated. By default, the
20
+ * interval is cleared immediately. If you want to let the interval run to
21
+ * completion, use `ClearPolicy.Resolve`. This is NOT applied if the interval
22
+ * is cleared manually via the `clear()` method on the returned API.
23
+ * @param options.schedulePolicy Determines when the interval is scheduled.
24
+ * By default, the interval is scheduled immediately. If you want to delay
25
+ * scheduling the interval, use `SchedulePolicy.OnDemand`.
26
+ * @returns An `IInterval` API for interacting with the given interval. This
27
+ * API is a no-op if called when not mounted. This means that any calls prior
28
+ * to mounting or after unmounting will not have any effect.
7
29
  */
8
- export declare function useInterval(action: () => unknown, intervalMs: number, active: boolean): void;
30
+ export declare function useInterval(action: () => unknown, intervalMs: number, options?: HookOptions): IInterval;
@@ -1,8 +1,30 @@
1
+ import type { ITimeout, HookOptions } from "../util/types";
1
2
  /**
2
- * A simple hook for using `setTimeout`.
3
+ * Hook providing access to a scheduled timeout.
3
4
  *
4
- * @param action called after `timeoutMs` when `active` is true
5
- * @param timeoutMs the duration after which `action` is called
6
- * @param active whether or not the interval is active
5
+ * @param action The action to be invoked when the timeout period has
6
+ * passed. By default, this will not cause the timeout to restart if it changes.
7
+ * This makes it easier to use with inline lambda functions rather than
8
+ * requiring consumers to wrap their action in a `useCallback`. To change
9
+ * this behavior, see the `actionPolicy` option.
10
+ * @param timeoutMs The timeout period. If this changes, the timeout will
11
+ * be reset per the `schedulePolicy` option.
12
+ * @param options Options for the hook.
13
+ * @param options.actionPolicy Determines how the action is handled when it
14
+ * changes. By default, the action is replaced but the timeout is not reset,
15
+ * and the updated action will be invoked when the timeout next fires.
16
+ * If you want to reset the timeout when the action changes, use
17
+ * `ActionPolicy.Reset`.
18
+ * @param options.clearPolicy Determines how the timeout is cleared when the
19
+ * component is unmounted or the timeout is recreated. By default, the
20
+ * timeout is cleared immediately. If you want to let the timeout run to
21
+ * completion, use `ClearPolicy.Resolve`. This is NOT applied if the timeout
22
+ * is cleared manually via the `clear()` method on the returned API.
23
+ * @param options.schedulePolicy Determines when the timeout is scheduled.
24
+ * By default, the timeout is scheduled immediately. If you want to delay
25
+ * scheduling the timeout, use `SchedulePolicy.OnDemand`.
26
+ * @returns An `ITimeout` API for interacting with the given timeout. This
27
+ * API is a no-op if called when not mounted. This means that any calls prior
28
+ * to mounting or after unmounting will not have any effect.
7
29
  */
8
- export declare function useTimeout(action: () => unknown, timeoutMs: number, active: boolean): void;
30
+ export declare function useTimeout(action: () => unknown, timeoutMs: number, options?: HookOptions): ITimeout;
package/dist/index.d.ts CHANGED
@@ -1,9 +1,6 @@
1
- import type { IAnimationFrame, IInterval, IScheduleActions, ITimeout, WithActionScheduler, WithActionSchedulerProps, WithoutActionScheduler } from "./util/types";
2
- export type { IAnimationFrame, IInterval, IScheduleActions, ITimeout, WithActionScheduler, WithActionSchedulerProps, WithoutActionScheduler, };
3
- export { SchedulePolicy, ClearPolicy } from "./util/policies";
1
+ export type { IAnimationFrame, IInterval, IScheduleActions, ITimeout, WithActionScheduler, WithActionSchedulerProps, WithoutActionScheduler, HookOptions, Options, } from "./util/types";
2
+ export { SchedulePolicy, ClearPolicy, ActionPolicy } from "./util/policies";
4
3
  export { default as ActionSchedulerProvider } from "./components/action-scheduler-provider";
5
4
  export { default as withActionScheduler } from "./components/with-action-scheduler";
6
5
  export { useInterval } from "./hooks/use-interval";
7
6
  export { useTimeout } from "./hooks/use-timeout";
8
- export { useScheduledInterval } from "./hooks/use-scheduled-interval";
9
- export { useScheduledTimeout } from "./hooks/use-scheduled-timeout";
package/dist/index.js CHANGED
@@ -24,14 +24,21 @@ function _interopNamespace(e) {
24
24
 
25
25
  var React__namespace = /*#__PURE__*/_interopNamespace(React);
26
26
 
27
- const SchedulePolicy = {
28
- Immediately: "schedule-immediately",
29
- OnDemand: "schedule-on-demand"
30
- };
31
- const ClearPolicy = {
32
- Resolve: "resolve-on-clear",
33
- Cancel: "cancel-on-clear"
34
- };
27
+ let SchedulePolicy = function (SchedulePolicy) {
28
+ SchedulePolicy["Immediately"] = "schedule-immediately";
29
+ SchedulePolicy["OnDemand"] = "schedule-on-demand";
30
+ return SchedulePolicy;
31
+ }({});
32
+ let ClearPolicy = function (ClearPolicy) {
33
+ ClearPolicy["Resolve"] = "resolve-on-clear";
34
+ ClearPolicy["Cancel"] = "cancel-on-clear";
35
+ return ClearPolicy;
36
+ }({});
37
+ let ActionPolicy = function (ActionPolicy) {
38
+ ActionPolicy["Reset"] = "reset";
39
+ ActionPolicy["Passive"] = "passive";
40
+ return ActionPolicy;
41
+ }({});
35
42
 
36
43
  class Timeout {
37
44
  constructor(action, timeoutMs, schedulePolicy = SchedulePolicy.Immediately) {
@@ -232,123 +239,100 @@ function withActionScheduler(WrappedComponent) {
232
239
  return C;
233
240
  }
234
241
 
235
- const useUpdatingRef = value => {
236
- const ref = React.useRef(value);
237
- React.useEffect(() => {
238
- ref.current = value;
239
- }, [value]);
240
- return ref;
241
- };
242
-
243
- function useInterval(action, intervalMs, active) {
244
- const actionRef = useUpdatingRef(action);
245
- React.useEffect(() => {
246
- if (active) {
247
- const intervalId = setInterval(() => {
248
- actionRef.current();
249
- }, intervalMs);
250
- return () => {
251
- clearInterval(intervalId);
252
- };
253
- }
254
- }, [intervalMs, active, actionRef]);
255
- }
256
-
257
- function useTimeout(action, timeoutMs, active) {
258
- const actionRef = useUpdatingRef(action);
259
- React.useEffect(() => {
260
- if (active) {
261
- const timeoutId = setTimeout(() => {
262
- actionRef.current();
263
- }, timeoutMs);
264
- return () => {
265
- clearTimeout(timeoutId);
266
- };
267
- }
268
- }, [timeoutMs, active, actionRef]);
269
- }
270
-
271
- function useScheduledInterval(action, intervalMs, options) {
272
- var _options$schedulePoli;
242
+ function useInterval(action, intervalMs, options = {}) {
243
+ const {
244
+ actionPolicy,
245
+ clearPolicy,
246
+ schedulePolicy
247
+ } = options;
248
+ const actionProxyRef = React.useRef(action);
249
+ const intervalRef = React.useRef(null);
273
250
  if (typeof action !== "function") {
274
251
  throw new Error("Action must be a function");
275
252
  }
276
- if (intervalMs < 1) {
277
- throw new Error("Interval period must be >= 1");
278
- }
279
- const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : SchedulePolicy.Immediately;
280
- const [isSet, setIsSet] = React.useState(schedulePolicy === SchedulePolicy.Immediately);
281
- const set = React.useCallback(() => setIsSet(true), []);
282
- const actionRef = useUpdatingRef(action);
283
- const clear = React.useCallback(policy => {
284
- var _policy;
285
- policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
286
- if (isSet && policy === ClearPolicy.Resolve) {
287
- actionRef.current();
253
+ if (action !== actionProxyRef.current) {
254
+ actionProxyRef.current = action;
255
+ if (actionPolicy === ActionPolicy.Reset) {
256
+ var _intervalRef$current;
257
+ (_intervalRef$current = intervalRef.current) == null ? void 0 : _intervalRef$current.set();
288
258
  }
289
- setIsSet(false);
290
- }, [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
291
- const runOnUnmountRef = useUpdatingRef(isSet && (options == null ? void 0 : options.clearPolicy) === ClearPolicy.Resolve);
259
+ }
292
260
  React.useEffect(() => {
261
+ intervalRef.current = new Interval(() => {
262
+ actionProxyRef.current == null ? void 0 : actionProxyRef.current();
263
+ }, intervalMs, schedulePolicy);
293
264
  return () => {
294
- if (runOnUnmountRef.current) {
295
- actionRef.current();
296
- }
265
+ var _intervalRef$current2;
266
+ (_intervalRef$current2 = intervalRef.current) == null ? void 0 : _intervalRef$current2.clear(clearPolicy);
267
+ intervalRef.current = null;
297
268
  };
298
- }, []);
299
- useInterval(action, intervalMs, isSet);
300
- return {
301
- isSet,
302
- set,
303
- clear
304
- };
269
+ }, [intervalMs, clearPolicy, schedulePolicy]);
270
+ const externalApi = React.useMemo(() => ({
271
+ set: () => {
272
+ var _intervalRef$current3;
273
+ (_intervalRef$current3 = intervalRef.current) == null ? void 0 : _intervalRef$current3.set();
274
+ },
275
+ clear: policy => {
276
+ var _intervalRef$current4;
277
+ (_intervalRef$current4 = intervalRef.current) == null ? void 0 : _intervalRef$current4.clear(policy);
278
+ },
279
+ get isSet() {
280
+ var _intervalRef$current$, _intervalRef$current5;
281
+ return (_intervalRef$current$ = (_intervalRef$current5 = intervalRef.current) == null ? void 0 : _intervalRef$current5.isSet) != null ? _intervalRef$current$ : false;
282
+ }
283
+ }), []);
284
+ return externalApi;
305
285
  }
306
286
 
307
- function useScheduledTimeout(action, timeoutMs, options) {
308
- var _options$schedulePoli;
287
+ function useTimeout(action, timeoutMs, options = {}) {
288
+ const {
289
+ actionPolicy,
290
+ clearPolicy,
291
+ schedulePolicy
292
+ } = options;
293
+ const actionProxyRef = React.useRef(action);
294
+ const timeoutRef = React.useRef(null);
309
295
  if (typeof action !== "function") {
310
296
  throw new Error("Action must be a function");
311
297
  }
312
- if (timeoutMs < 0) {
313
- throw new Error("Timeout period must be >= 0");
314
- }
315
- const schedulePolicy = (_options$schedulePoli = options == null ? void 0 : options.schedulePolicy) != null ? _options$schedulePoli : SchedulePolicy.Immediately;
316
- const [isSet, setIsSet] = React.useState(schedulePolicy === SchedulePolicy.Immediately);
317
- const set = React.useCallback(() => setIsSet(true), []);
318
- const wrappedAction = React.useCallback(() => {
319
- setIsSet(false);
320
- action();
321
- }, [action]);
322
- const actionRef = useUpdatingRef(wrappedAction);
323
- const clear = React.useCallback(policy => {
324
- var _policy;
325
- policy = (_policy = policy) != null ? _policy : options == null ? void 0 : options.clearPolicy;
326
- if (isSet && policy === ClearPolicy.Resolve) {
327
- actionRef.current();
298
+ if (action !== actionProxyRef.current) {
299
+ actionProxyRef.current = action;
300
+ if (actionPolicy === ActionPolicy.Reset) {
301
+ var _timeoutRef$current;
302
+ (_timeoutRef$current = timeoutRef.current) == null ? void 0 : _timeoutRef$current.set();
328
303
  }
329
- setIsSet(false);
330
- }, [actionRef, isSet, options == null ? void 0 : options.clearPolicy]);
331
- const runOnUnmountRef = useUpdatingRef(isSet && (options == null ? void 0 : options.clearPolicy) === ClearPolicy.Resolve);
304
+ }
332
305
  React.useEffect(() => {
306
+ timeoutRef.current = new Timeout(() => {
307
+ actionProxyRef.current == null ? void 0 : actionProxyRef.current();
308
+ }, timeoutMs, schedulePolicy);
333
309
  return () => {
334
- if (runOnUnmountRef.current) {
335
- actionRef.current();
336
- }
310
+ var _timeoutRef$current2;
311
+ (_timeoutRef$current2 = timeoutRef.current) == null ? void 0 : _timeoutRef$current2.clear(clearPolicy);
312
+ timeoutRef.current = null;
337
313
  };
338
- }, []);
339
- useTimeout(wrappedAction, timeoutMs, isSet);
340
- return {
341
- isSet,
342
- set,
343
- clear
344
- };
314
+ }, [timeoutMs, clearPolicy, schedulePolicy]);
315
+ const externalApi = React.useMemo(() => ({
316
+ set: () => {
317
+ var _timeoutRef$current3;
318
+ (_timeoutRef$current3 = timeoutRef.current) == null ? void 0 : _timeoutRef$current3.set();
319
+ },
320
+ clear: policy => {
321
+ var _timeoutRef$current4;
322
+ (_timeoutRef$current4 = timeoutRef.current) == null ? void 0 : _timeoutRef$current4.clear(policy);
323
+ },
324
+ get isSet() {
325
+ var _timeoutRef$current$i, _timeoutRef$current5;
326
+ return (_timeoutRef$current$i = (_timeoutRef$current5 = timeoutRef.current) == null ? void 0 : _timeoutRef$current5.isSet) != null ? _timeoutRef$current$i : false;
327
+ }
328
+ }), []);
329
+ return externalApi;
345
330
  }
346
331
 
332
+ exports.ActionPolicy = ActionPolicy;
347
333
  exports.ActionSchedulerProvider = ActionSchedulerProvider;
348
334
  exports.ClearPolicy = ClearPolicy;
349
335
  exports.SchedulePolicy = SchedulePolicy;
350
336
  exports.useInterval = useInterval;
351
- exports.useScheduledInterval = useScheduledInterval;
352
- exports.useScheduledTimeout = useScheduledTimeout;
353
337
  exports.useTimeout = useTimeout;
354
338
  exports.withActionScheduler = withActionScheduler;
@@ -1,4 +1,5 @@
1
- import type { IAnimationFrame, SchedulePolicy, ClearPolicy } from "./types";
1
+ import { SchedulePolicy, ClearPolicy } from "./policies";
2
+ import type { IAnimationFrame } from "./types";
2
3
  /**
3
4
  * Encapsulates everything associated with calling requestAnimationFrame/
4
5
  * cancelAnimationFrame, and managing the lifecycle of that request, including
@@ -15,8 +16,8 @@ export default class AnimationFrame implements IAnimationFrame {
15
16
  * Creates an animation frame request that will invoke the given action.
16
17
  * The request is not made until set is called.
17
18
  *
18
- * @param {(time: DOMHighResTimeStamp) => mixed} action The action to be invoked.
19
- * @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
19
+ * @param action The action to be invoked.
20
+ * @param [schedulePolicy] When SchedulePolicy.Immediately,
20
21
  * the interval is set immediately on instantiation; otherwise, `set` must be
21
22
  * called to set the interval.
22
23
  * Defaults to `SchedulePolicy.Immediately`.
@@ -47,15 +48,14 @@ export default class AnimationFrame implements IAnimationFrame {
47
48
  * If the request is pending, this cancels that pending request without
48
49
  * invoking the action. If no request is pending, this does nothing.
49
50
  *
50
- * @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
51
+ * @param [policy] When ClearPolicy.Resolve, if the request
51
52
  * was set when called, the request action is invoked after cancelling
52
53
  * the request; otherwise, the pending action is cancelled.
53
54
  * Defaults to `ClearPolicy.Cancel`.
54
- * @param {DOMHighResTimeStamp} [time] Timestamp to pass to the action when
55
+ * @param [time] Timestamp to pass to the action when
55
56
  * ClearPolicy.Resolve is specified. Ignored when ClearPolicy.Cancel is
56
57
  * specified.
57
58
  *
58
- * @returns {void}
59
59
  * @memberof AnimationFrame
60
60
  */
61
61
  clear(policy?: ClearPolicy, time?: DOMHighResTimeStamp): void;
@@ -1,4 +1,5 @@
1
- import type { IInterval, SchedulePolicy, ClearPolicy } from "./types";
1
+ import { SchedulePolicy, ClearPolicy } from "./policies";
2
+ import type { IInterval } from "./types";
2
3
  /**
3
4
  * Encapsulates everything associated with calling setInterval/clearInterval,
4
5
  * and managing the lifecycle of that interval. This includes the ability to
@@ -16,10 +17,10 @@ export default class Interval implements IInterval {
16
17
  * Creates an interval that will invoke the given action after
17
18
  * the given period. The interval does not start until set is called.
18
19
  *
19
- * @param {() => mixed} action The action to be invoked each time the
20
+ * @param action The action to be invoked each time the
20
21
  * interval period has passed.
21
- * @param {number} intervalMs The interval period.
22
- * @param {SchedulePolicy} [schedulePolicy] When SchedulePolicy.Immediately,
22
+ * @param intervalMs The interval period.
23
+ * @param [schedulePolicy] When SchedulePolicy.Immediately,
23
24
  * the interval is set immediately on instantiation; otherwise, `set` must be
24
25
  * called to set the interval.
25
26
  * Defaults to `SchedulePolicy.Immediately`.
@@ -29,7 +30,7 @@ export default class Interval implements IInterval {
29
30
  /**
30
31
  * Determine if the interval is active or not.
31
32
  *
32
- * @returns {boolean} true if the interval is active, otherwise false.
33
+ * @returns true if the interval is active, otherwise false.
33
34
  * @memberof Interval
34
35
  */
35
36
  get isSet(): boolean;
@@ -48,12 +49,11 @@ export default class Interval implements IInterval {
48
49
  * If the interval is active, this cancels that interval. If no interval is
49
50
  * pending, this does nothing.
50
51
  *
51
- * @param {ClearPolicy} [policy] When ClearPolicy.Resolve, if the request
52
+ * @param [policy] When ClearPolicy.Resolve, if the request
52
53
  * was set when called, the request action is invoked after cancelling
53
54
  * the request; otherwise, the pending action is cancelled.
54
55
  * Defaults to `ClearPolicy.Cancel`.
55
56
  *
56
- * @returns {void}
57
57
  * @memberof Interval
58
58
  */
59
59
  clear(policy?: ClearPolicy): void;
@@ -1,8 +1,12 @@
1
- export declare const SchedulePolicy: {
2
- readonly Immediately: "schedule-immediately";
3
- readonly OnDemand: "schedule-on-demand";
4
- };
5
- export declare const ClearPolicy: {
6
- readonly Resolve: "resolve-on-clear";
7
- readonly Cancel: "cancel-on-clear";
8
- };
1
+ export declare enum SchedulePolicy {
2
+ Immediately = "schedule-immediately",
3
+ OnDemand = "schedule-on-demand"
4
+ }
5
+ export declare enum ClearPolicy {
6
+ Resolve = "resolve-on-clear",
7
+ Cancel = "cancel-on-clear"
8
+ }
9
+ export declare enum ActionPolicy {
10
+ Reset = "reset",
11
+ Passive = "passive"
12
+ }