-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutility.ts
85 lines (75 loc) · 1.84 KB
/
utility.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import {
ReadonlySignal,
Signal,
effect,
signal,
useComputed,
useSignal,
} from "@preact-signals/unified-signals";
import { Context, useContext, useEffect, useRef } from "react";
import {
AnyReactive,
GetValue,
ReducerSignal,
reducerSignal,
untracked,
unwrapReactive,
} from "../utils";
import { EMPTY_ARRAY } from "../constants";
/**
* Allows to create signal function which is called only once, without dependencies tracking
*/
export const useInitSignal = <T>(init: () => T) => {
const signalRef = useRef<null | Signal<T>>(null);
if (signalRef.current === null) {
signalRef.current = signal(untracked(init));
}
return signalRef.current!;
};
/**
* Creates computed which will subscribe tp reactive value
*/
export const useSignalOfReactive = <T extends AnyReactive>(
reactive: T
): ReadonlySignal<GetValue<T>> =>
useComputed(() => /** __PURE__ */ unwrapReactive(reactive));
/**
*
* Creates signal which state is always equal to state passed to hook
*/
export const useSignalOfState = <T>(state: T): ReadonlySignal<T> => {
const s = useSignal(state);
if (s.peek() !== state) {
s.value = state;
}
return s;
};
/**
*
* @param context
* @returns signal of context value
*/
export const useSignalContext = <T>(context: Context<T>) =>
useSignalOfState(useContext(context));
export type Dispose = () => void;
/**
*
* Creates effect with with first provided function
*/
export const useSignalEffectOnce = (_effect: () => void | Dispose) => {
useEffect(() => effect(_effect), EMPTY_ARRAY);
};
/**
*
* Hook wrapper for {@link reducerSignal}
*/
export const useReducerSignal: typeof reducerSignal = (
initialValue,
reducer
) => {
const ref = useRef<null | ReducerSignal<any, any>>(null);
if (ref.current === null) {
ref.current = reducerSignal(initialValue, reducer);
}
return ref.current;
};