@dxos/react-hooks 0.6.12 → 0.6.13-main.548ca8d

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 (33) hide show
  1. package/dist/lib/browser/index.mjs +28 -26
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/lib/node/index.cjs +26 -24
  5. package/dist/lib/node/index.cjs.map +4 -4
  6. package/dist/lib/node/meta.json +1 -1
  7. package/dist/lib/node-esm/index.mjs +328 -0
  8. package/dist/lib/node-esm/index.mjs.map +7 -0
  9. package/dist/lib/node-esm/meta.json +1 -0
  10. package/dist/types/src/index.d.ts +1 -1
  11. package/dist/types/src/index.d.ts.map +1 -1
  12. package/dist/types/src/useAsyncEffect.test.d.ts +1 -1
  13. package/dist/types/src/useAsyncEffect.test.d.ts.map +1 -1
  14. package/dist/types/src/useAsyncState.d.ts +6 -0
  15. package/dist/types/src/useAsyncState.d.ts.map +1 -0
  16. package/dist/types/src/useControlledValue.d.ts +1 -1
  17. package/dist/types/src/useControlledValue.d.ts.map +1 -1
  18. package/dist/types/src/useDefaultValue.d.ts +1 -1
  19. package/dist/types/src/useDefaultValue.d.ts.map +1 -1
  20. package/dist/types/src/useMulticastObservable.test.d.ts +2 -0
  21. package/dist/types/src/useMulticastObservable.test.d.ts.map +1 -0
  22. package/dist/types/src/useTransitions.d.ts +1 -1
  23. package/dist/types/src/useTransitions.d.ts.map +1 -1
  24. package/package.json +8 -6
  25. package/src/index.ts +1 -1
  26. package/src/useAsyncEffect.test.tsx +3 -9
  27. package/src/{useAsyncCallback.ts → useAsyncState.ts} +7 -4
  28. package/src/useControlledValue.ts +5 -2
  29. package/src/useDefaultValue.ts +2 -2
  30. package/src/useMulticastObservable.test.tsx +23 -0
  31. package/src/useTransitions.ts +4 -7
  32. package/dist/types/src/useAsyncCallback.d.ts +0 -5
  33. package/dist/types/src/useAsyncCallback.d.ts.map +0 -1
@@ -2,14 +2,10 @@
2
2
  // Copyright 2022 DXOS.org
3
3
  //
4
4
 
5
- import expect from 'expect';
6
- import 'raf/polyfill';
7
5
  import React, { useState } from 'react';
8
6
  import { createRoot } from 'react-dom/client';
9
7
  import { act } from 'react-dom/test-utils';
10
- import waitForExpect from 'wait-for-expect';
11
-
12
- import { afterEach, beforeEach, describe, test } from '@dxos/test';
8
+ import { afterEach, beforeEach, describe, expect, test } from 'vitest';
13
9
 
14
10
  import { useAsyncEffect } from './useAsyncEffect';
15
11
 
@@ -45,13 +41,11 @@ describe('useAsyncEffect', () => {
45
41
  });
46
42
 
47
43
  test('gets async value.', async () => {
48
- void act(() => {
44
+ await act(() => {
49
45
  createRoot(rootContainer).render(<Test />);
50
46
  });
51
47
 
52
48
  const h1 = rootContainer.querySelector('h1');
53
- await waitForExpect(() => {
54
- expect(h1?.textContent).toEqual('DXOS');
55
- });
49
+ expect(h1?.textContent).toEqual('DXOS');
56
50
  });
57
51
  });
@@ -2,12 +2,15 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { useEffect, useState } from 'react';
5
+ import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
6
6
 
7
7
  /**
8
8
  * NOTE: Use with care and when necessary to be able to cancel an async operation when unmounting.
9
9
  */
10
- export const useAsyncCallback = <T>(cb: () => Promise<T>): T | undefined => {
10
+ export const useAsyncState = <T>(
11
+ cb: () => Promise<T | undefined>,
12
+ deps: any[] = [],
13
+ ): [T | undefined, Dispatch<SetStateAction<T | undefined>>] => {
11
14
  const [value, setValue] = useState<T | undefined>();
12
15
  useEffect(() => {
13
16
  const t = setTimeout(async () => {
@@ -16,7 +19,7 @@ export const useAsyncCallback = <T>(cb: () => Promise<T>): T | undefined => {
16
19
  });
17
20
 
18
21
  return () => clearTimeout(t);
19
- }, []);
22
+ }, deps);
20
23
 
21
- return value;
24
+ return [value, setValue];
22
25
  };
@@ -7,13 +7,16 @@ import { type Dispatch, type SetStateAction, useEffect, useState } from 'react';
7
7
  /**
8
8
  * A stateful hook with a controlled value.
9
9
  */
10
- export const useControlledValue = <TValue>(controlledValue: TValue): [TValue, Dispatch<SetStateAction<TValue>>] => {
10
+ export const useControlledValue = <TValue>(
11
+ controlledValue: TValue,
12
+ ...deps: any[]
13
+ ): [TValue, Dispatch<SetStateAction<TValue>>] => {
11
14
  const [value, setValue] = useState<TValue>(controlledValue);
12
15
  useEffect(() => {
13
16
  if (controlledValue !== undefined) {
14
17
  setValue(controlledValue);
15
18
  }
16
- }, [controlledValue]);
19
+ }, [controlledValue, ...deps]);
17
20
 
18
21
  return [value, setValue];
19
22
  };
@@ -15,11 +15,11 @@ import { useEffect, useState, useMemo } from 'react';
15
15
  * @param defaultValue - The initial value used when the reactiveValue is undefined. This value is not reactive.
16
16
  * @returns - The reactiveValue if it's defined, otherwise the defaultValue.
17
17
  */
18
- export const useDefaultValue = <T>(reactiveValue: T | undefined | null, defaultValue: T): T => {
18
+ export const useDefaultValue = <T>(reactiveValue: T | undefined | null, getDefaultValue: () => T): T => {
19
19
  // Memoize defaultValue with an empty dependency array.
20
20
  // This ensures that the defaultValue instance remains stable across all re-renders,
21
21
  // regardless of whether the defaultValue changes.
22
- const stableDefaultValue = useMemo(() => defaultValue, []);
22
+ const stableDefaultValue = useMemo(getDefaultValue, []);
23
23
  const [value, setValue] = useState(reactiveValue ?? stableDefaultValue);
24
24
 
25
25
  useEffect(() => {
@@ -0,0 +1,23 @@
1
+ //
2
+ // Copyright 2022 DXOS.org
3
+ //
4
+
5
+ import { act, renderHook } from '@testing-library/react';
6
+ import { describe, expect, test } from 'vitest';
7
+
8
+ import { Event, MulticastObservable } from '@dxos/async';
9
+
10
+ import { useMulticastObservable } from './useMulticastObservable';
11
+
12
+ describe('useMulticastObservable', () => {
13
+ test('observes value', async () => {
14
+ const event = new Event<number>();
15
+ const observable = MulticastObservable.from(event, 0);
16
+ const { result } = renderHook(() => useMulticastObservable(observable));
17
+ expect(result.current).toEqual(0);
18
+
19
+ await act(() => event.emit(1));
20
+
21
+ await expect.poll(() => result.current).toEqual(1);
22
+ });
23
+ });
@@ -28,21 +28,18 @@ export const useDidTransition = <T>(
28
28
 
29
29
  useEffect(() => {
30
30
  const toValueValid = isFunction<T>(toValue) ? toValue(currentValue) : toValue === currentValue;
31
-
32
31
  const fromValueValid = isFunction<T>(fromValue)
33
32
  ? fromValue(previousValue.current)
34
33
  : fromValue === previousValue.current;
35
34
 
36
- const transitioned = fromValueValid && toValueValid;
37
-
38
- if (transitioned) {
35
+ if (fromValueValid && toValueValid && !hasTransitioned) {
39
36
  setHasTransitioned(true);
40
- } else {
37
+ } else if ((!fromValueValid || !toValueValid) && hasTransitioned) {
41
38
  setHasTransitioned(false);
42
39
  }
43
40
 
44
41
  previousValue.current = currentValue;
45
- }, [currentValue, fromValue, toValue, setHasTransitioned, previousValue]);
42
+ }, [currentValue, fromValue, toValue, hasTransitioned]);
46
43
 
47
44
  return hasTransitioned;
48
45
  };
@@ -55,7 +52,7 @@ export const useDidTransition = <T>(
55
52
  export const useOnTransition = <T>(
56
53
  currentValue: T,
57
54
  fromValue: T | ((value: T) => boolean),
58
- toValue: ((value: T) => boolean) | T,
55
+ toValue: T | ((value: T) => boolean),
59
56
  callback: () => void,
60
57
  ) => {
61
58
  const dirty = useRef(false);
@@ -1,5 +0,0 @@
1
- /**
2
- * NOTE: Use with care and when necessary to be able to cancel an async operation when unmounting.
3
- */
4
- export declare const useAsyncCallback: <T>(cb: () => Promise<T>) => T | undefined;
5
- //# sourceMappingURL=useAsyncCallback.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useAsyncCallback.d.ts","sourceRoot":"","sources":["../../../src/useAsyncCallback.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,MAAM,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,CAAC,GAAG,SAY9D,CAAC"}