@dxos/react-async 2.28.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +29 -0
  2. package/dist/src/index.d.ts +8 -0
  3. package/dist/src/index.d.ts.map +1 -0
  4. package/dist/src/index.js +23 -0
  5. package/dist/src/index.js.map +1 -0
  6. package/dist/src/useAsyncEffect.d.ts +28 -0
  7. package/dist/src/useAsyncEffect.d.ts.map +1 -0
  8. package/dist/src/useAsyncEffect.js +53 -0
  9. package/dist/src/useAsyncEffect.js.map +1 -0
  10. package/dist/src/useAsyncEffect.test.d.ts +2 -0
  11. package/dist/src/useAsyncEffect.test.d.ts.map +1 -0
  12. package/dist/src/useAsyncEffect.test.js +70 -0
  13. package/dist/src/useAsyncEffect.test.js.map +1 -0
  14. package/dist/src/useControlledState.d.ts +17 -0
  15. package/dist/src/useControlledState.d.ts.map +1 -0
  16. package/dist/src/useControlledState.js +37 -0
  17. package/dist/src/useControlledState.js.map +1 -0
  18. package/dist/src/useDynamicRef.d.ts +17 -0
  19. package/dist/src/useDynamicRef.d.ts.map +1 -0
  20. package/dist/src/useDynamicRef.js +33 -0
  21. package/dist/src/useDynamicRef.js.map +1 -0
  22. package/dist/src/useMounted.d.ts +25 -0
  23. package/dist/src/useMounted.d.ts.map +1 -0
  24. package/dist/src/useMounted.js +42 -0
  25. package/dist/src/useMounted.js.map +1 -0
  26. package/dist/src/useStateUpdater.d.ts +20 -0
  27. package/dist/src/useStateUpdater.d.ts.map +1 -0
  28. package/dist/src/useStateUpdater.js +43 -0
  29. package/dist/src/useStateUpdater.js.map +1 -0
  30. package/dist/src/useStateUpdater.test.d.ts +2 -0
  31. package/dist/src/useStateUpdater.test.d.ts.map +1 -0
  32. package/dist/src/useStateUpdater.test.js +69 -0
  33. package/dist/src/useStateUpdater.test.js.map +1 -0
  34. package/dist/src/useStateWithRef.d.ts +17 -0
  35. package/dist/src/useStateWithRef.d.ts.map +1 -0
  36. package/dist/src/useStateWithRef.js +31 -0
  37. package/dist/src/useStateWithRef.js.map +1 -0
  38. package/dist/src/useTimestamp.d.ts +12 -0
  39. package/dist/src/useTimestamp.d.ts.map +1 -0
  40. package/dist/src/useTimestamp.js +28 -0
  41. package/dist/src/useTimestamp.js.map +1 -0
  42. package/dist/stories/stale-callback.stories.d.ts +6 -0
  43. package/dist/stories/stale-callback.stories.d.ts.map +1 -0
  44. package/dist/stories/stale-callback.stories.js +59 -0
  45. package/dist/stories/stale-callback.stories.js.map +1 -0
  46. package/dist/stories/unmounted.stories.d.ts +6 -0
  47. package/dist/stories/unmounted.stories.d.ts.map +1 -0
  48. package/dist/stories/unmounted.stories.js +60 -0
  49. package/dist/stories/unmounted.stories.js.map +1 -0
  50. package/dist/tsconfig.tsbuildinfo +1 -0
  51. package/package.json +52 -0
  52. package/src/index.ts +11 -0
  53. package/src/useAsyncEffect.test.tsx +57 -0
  54. package/src/useAsyncEffect.ts +61 -0
  55. package/src/useControlledState.ts +39 -0
  56. package/src/useDynamicRef.ts +34 -0
  57. package/src/useMounted.ts +40 -0
  58. package/src/useStateUpdater.test.tsx +58 -0
  59. package/src/useStateUpdater.ts +40 -0
  60. package/src/useStateWithRef.ts +31 -0
  61. package/src/useTimestamp.ts +27 -0
@@ -0,0 +1,58 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import expect from 'expect';
6
+ import 'raf/polyfill';
7
+ import React, { useEffect } from 'react';
8
+ import ReactDOM from 'react-dom';
9
+ import { act } from 'react-dom/test-utils';
10
+ import waitForExpect from 'wait-for-expect';
11
+
12
+ import { useStateUpdater } from './useStateUpdater';
13
+
14
+ // Don't copy this.
15
+ const complex = {
16
+
17
+ };
18
+
19
+ const Test = () => {
20
+ const [value,, updateValue] = useStateUpdater({ complex, items: [] });
21
+ useEffect(() => {
22
+ updateValue({
23
+ items: {
24
+ $push: [1, 2, 3]
25
+ }
26
+ });
27
+ }, []);
28
+
29
+ return (
30
+ <pre>{JSON.stringify(value)}</pre>
31
+ );
32
+ };
33
+
34
+ let rootContainer: any;
35
+
36
+ beforeEach(() => {
37
+ rootContainer = document.createElement('div');
38
+ document.body.appendChild(rootContainer);
39
+ });
40
+
41
+ afterEach(() => {
42
+ document.body.removeChild(rootContainer);
43
+ rootContainer = null;
44
+ });
45
+
46
+ describe('useStateMutator', () => {
47
+ it('udpates the value.', async () => {
48
+ act(() => {
49
+ ReactDOM.render(<Test />, rootContainer);
50
+ });
51
+
52
+ const pre = rootContainer.querySelector('pre');
53
+ await waitForExpect(() => {
54
+ const data = JSON.parse(pre.textContent);
55
+ expect(data).toEqual({ complex, items: [1, 2, 3] });
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import update from 'immutability-helper';
6
+ import { Dispatch, SetStateAction, useState } from 'react';
7
+
8
+ /**
9
+ * Partially updates state without copying complex (expensive) objects.
10
+ * https://github.com/kolodny/immutability-helper
11
+ *
12
+ * ```tsx
13
+ * const [value,, updateValue] = useStateMutator({ items: [], ... });
14
+ * useEffect(() => {
15
+ * updateValue({
16
+ * items: {
17
+ * $push: [1, 2, 3] // Only update the items property.
18
+ * }
19
+ * })
20
+ * }, []);
21
+ * ```
22
+ *
23
+ * @param initialValue
24
+ */
25
+ export const useStateUpdater = <T> (
26
+ initialValue: T
27
+ ): [T, Dispatch<SetStateAction<T>>, (spec: any) => T] => {
28
+ const [value, setValue] = useState<T>(initialValue);
29
+ const handleUpdate = (spec: any) => {
30
+ const newValue = update(value, spec);
31
+ setValue(newValue);
32
+ return newValue;
33
+ };
34
+
35
+ return [
36
+ value,
37
+ setValue,
38
+ handleUpdate
39
+ ];
40
+ };
@@ -0,0 +1,31 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { Dispatch, RefObject, SetStateAction, useEffect, useRef, useState } from 'react';
6
+
7
+ /**
8
+ * Extension of useState to return an up-to-date reference.
9
+ * E.g., to use in callbacks where the state value is stale.
10
+ * https://css-tricks.com/dealing-with-stale-props-and-states-in-reacts-functional-components
11
+ *
12
+ * ```tsx
13
+ * const [value, setValue, valueRef] = useStateWithRef<string>();
14
+ * const handleAction = () => {
15
+ * console.log(valueRef.current);
16
+ * }
17
+ * ```
18
+ *
19
+ * @param initialValue
20
+ */
21
+ export const useStateWithRef = <V>(
22
+ initialValue?: V | (() => V)
23
+ ): [V | undefined, Dispatch<SetStateAction<V | undefined>>, RefObject<V | undefined>] => {
24
+ const [value, setValue] = useState<V | undefined>(initialValue);
25
+ const ref = useRef<V>();
26
+ useEffect(() => {
27
+ ref.current = value;
28
+ }, [initialValue, value]);
29
+
30
+ return [value, setValue, ref];
31
+ };
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { useEffect, useState } from 'react';
6
+
7
+ /**
8
+ * Provides a timestamp that can be used to force re-rendering based on deps.
9
+ *
10
+ * ```tsx
11
+ * const [, update] = useTimestamp();
12
+ * const handleRefresh = () => update();
13
+ * ```
14
+ *
15
+ * @param deps
16
+ */
17
+ export const useTimestamp = (deps?: any[]): [number, () => void, number | undefined] => {
18
+ const [{ timestamp, previous }, setTimestamp] = useState<{ timestamp: number, previous?: number }>({
19
+ timestamp: Date.now()
20
+ });
21
+
22
+ useEffect(() => {
23
+ setTimestamp({ timestamp: Date.now(), previous: timestamp });
24
+ }, deps || []);
25
+
26
+ return [timestamp, () => setTimestamp({ timestamp: Date.now(), previous: timestamp }), previous];
27
+ };