@wwog/react 1.3.12 → 1.3.13
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/README.md +78 -0
- package/dist/index.d.mts +101 -10
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/algorithm/date/zellersKongruenz.ts +9 -14
- package/src/algorithm/date.ts +2 -2
- package/src/components/Layout/index.ts +2 -2
- package/src/components/ProcessControl/If.tsx +2 -2
- package/src/components/Sundry/Boundary.tsx +67 -0
- package/src/components/Sundry/Portal.tsx +59 -0
- package/src/components/Sundry/Repeat.tsx +34 -0
- package/src/components/Sundry/index.ts +8 -5
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useScreen.ts +54 -65
- package/src/index.ts +5 -5
- package/src/utils/constants.ts +7 -16
- package/src/utils/createExternalState.ts +71 -84
- package/src/utils/index.ts +7 -7
- package/src/utils/promise.ts +18 -18
- package/src/utils/ruleChecker.test.ts +336 -349
- package/src/utils/ruleChecker.ts +98 -181
- package/src/utils/sundry.ts +66 -67
package/src/hooks/useScreen.ts
CHANGED
|
@@ -1,99 +1,88 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
breakpoints,
|
|
4
|
-
DefBreakpointDesc,
|
|
5
|
-
type BreakpointDesc,
|
|
6
|
-
type BreakpointName,
|
|
7
|
-
} from "../utils";
|
|
1
|
+
import {useEffect, useMemo, useRef, useState} from 'react'
|
|
2
|
+
import {type BreakpointDesc, type BreakpointName, DefBreakpointDesc, breakpoints} from '../utils'
|
|
8
3
|
|
|
9
|
-
const reverseBreakpoints = [...breakpoints].reverse()
|
|
4
|
+
const reverseBreakpoints = [...breakpoints].reverse()
|
|
5
|
+
|
|
6
|
+
const isBrowser = typeof window !== 'undefined'
|
|
10
7
|
|
|
11
8
|
export function getCurrentBreakpoint(
|
|
12
9
|
breakpointDesc: BreakpointDesc,
|
|
13
|
-
width: number
|
|
10
|
+
width: number,
|
|
14
11
|
): BreakpointName {
|
|
15
12
|
for (const bp of reverseBreakpoints) {
|
|
16
|
-
const bpValue = breakpointDesc[bp]
|
|
13
|
+
const bpValue = breakpointDesc[bp]
|
|
17
14
|
if (bpValue !== undefined && !Number.isNaN(bpValue) && width >= bpValue) {
|
|
18
|
-
return bp
|
|
15
|
+
return bp
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
return
|
|
18
|
+
return 'base'
|
|
22
19
|
}
|
|
23
20
|
|
|
24
21
|
export function useScreen(breakpointDesc: BreakpointDesc = DefBreakpointDesc) {
|
|
22
|
+
// 用 JSON 序列化稳定化对象引用,避免调用方每次传字面量对象导致 effect 无限重跑
|
|
23
|
+
const stableKey = useMemo(() => JSON.stringify(breakpointDesc), [breakpointDesc])
|
|
24
|
+
const descRef = useRef(breakpointDesc)
|
|
25
|
+
descRef.current = breakpointDesc
|
|
26
|
+
|
|
25
27
|
const [currentBreakpoint, setCurrentBreakpoint] = useState<BreakpointName>(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
// lazy initializer:SSR 环境下 window 不存在,fallback 到 "base"
|
|
29
|
+
() => (isBrowser ? getCurrentBreakpoint(breakpointDesc, window.innerWidth) : 'base'),
|
|
30
|
+
)
|
|
28
31
|
|
|
29
32
|
useEffect(() => {
|
|
30
|
-
|
|
31
|
-
|
|
33
|
+
if (!isBrowser) return
|
|
34
|
+
|
|
35
|
+
let mediaQueries: MediaQueryList[] = []
|
|
36
|
+
let listeners: (() => void)[] = []
|
|
32
37
|
|
|
33
38
|
const updateMediaQueries = () => {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
listeners = [];
|
|
39
|
+
listeners.forEach((removeListener) => removeListener())
|
|
40
|
+
mediaQueries = []
|
|
41
|
+
listeners = []
|
|
38
42
|
|
|
39
|
-
|
|
40
|
-
const currentBp = getCurrentBreakpoint(
|
|
41
|
-
setCurrentBreakpoint(currentBp)
|
|
43
|
+
const desc = descRef.current
|
|
44
|
+
const currentBp = getCurrentBreakpoint(desc, window.innerWidth)
|
|
45
|
+
setCurrentBreakpoint(currentBp)
|
|
42
46
|
|
|
43
|
-
|
|
44
|
-
const currentIndex = breakpoints.indexOf(currentBp);
|
|
47
|
+
const currentIndex = breakpoints.indexOf(currentBp)
|
|
45
48
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const nextMinWidth = breakpointDesc[nextBp];
|
|
49
|
+
const nextBp = breakpoints[currentIndex + 1]
|
|
50
|
+
if (nextBp && desc[nextBp] !== undefined) {
|
|
51
|
+
const nextMinWidth = desc[nextBp]
|
|
50
52
|
if (!Number.isNaN(nextMinWidth)) {
|
|
51
|
-
const mediaQuery = window.matchMedia(
|
|
52
|
-
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
mediaQuery.addEventListener("change", handleMediaChange);
|
|
57
|
-
listeners.push(() =>
|
|
58
|
-
mediaQuery.removeEventListener("change", handleMediaChange)
|
|
59
|
-
);
|
|
53
|
+
const mediaQuery = window.matchMedia(`(min-width: ${nextMinWidth}px)`)
|
|
54
|
+
mediaQueries.push(mediaQuery)
|
|
55
|
+
const handleMediaChange = () => updateMediaQueries()
|
|
56
|
+
mediaQuery.addEventListener('change', handleMediaChange)
|
|
57
|
+
listeners.push(() => mediaQuery.removeEventListener('change', handleMediaChange))
|
|
60
58
|
} else {
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Invalid breakpoint value for ${nextBp}: ${breakpointDesc[nextBp]}`
|
|
63
|
-
);
|
|
59
|
+
throw new Error(`Invalid breakpoint value for ${nextBp}: ${desc[nextBp]}`)
|
|
64
60
|
}
|
|
65
61
|
}
|
|
66
62
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const prevMinWidth = breakpointDesc[prevBp];
|
|
63
|
+
const prevBp = breakpoints[currentIndex - 1]
|
|
64
|
+
if (prevBp && desc[prevBp] !== undefined) {
|
|
65
|
+
const prevMinWidth = desc[prevBp]
|
|
71
66
|
if (!Number.isNaN(prevMinWidth)) {
|
|
72
|
-
const mediaQuery = window.matchMedia(
|
|
73
|
-
|
|
74
|
-
)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
mediaQuery.addEventListener("change", handleMediaChange);
|
|
78
|
-
listeners.push(() =>
|
|
79
|
-
mediaQuery.removeEventListener("change", handleMediaChange)
|
|
80
|
-
);
|
|
67
|
+
const mediaQuery = window.matchMedia(`(max-width: ${prevMinWidth - 1}px)`)
|
|
68
|
+
mediaQueries.push(mediaQuery)
|
|
69
|
+
const handleMediaChange = () => updateMediaQueries()
|
|
70
|
+
mediaQuery.addEventListener('change', handleMediaChange)
|
|
71
|
+
listeners.push(() => mediaQuery.removeEventListener('change', handleMediaChange))
|
|
81
72
|
} else {
|
|
82
|
-
throw new Error(
|
|
83
|
-
`Invalid breakpoint value for ${prevBp}: ${breakpointDesc[prevBp]}`
|
|
84
|
-
);
|
|
73
|
+
throw new Error(`Invalid breakpoint value for ${prevBp}: ${desc[prevBp]}`)
|
|
85
74
|
}
|
|
86
75
|
}
|
|
87
|
-
}
|
|
76
|
+
}
|
|
88
77
|
|
|
89
|
-
|
|
90
|
-
updateMediaQueries();
|
|
78
|
+
updateMediaQueries()
|
|
91
79
|
|
|
92
|
-
// 清理函数
|
|
93
80
|
return () => {
|
|
94
|
-
listeners.forEach((removeListener) => removeListener())
|
|
95
|
-
}
|
|
96
|
-
|
|
81
|
+
listeners.forEach((removeListener) => removeListener())
|
|
82
|
+
}
|
|
83
|
+
// stableKey 作为稳定化的依赖,替代直接依赖 breakpointDesc 对象引用
|
|
84
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: stableKey is the stable proxy for breakpointDesc object identity
|
|
85
|
+
}, [stableKey])
|
|
97
86
|
|
|
98
|
-
return currentBreakpoint
|
|
87
|
+
return currentBreakpoint
|
|
99
88
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
1
|
+
export * from './components/ProcessControl'
|
|
2
|
+
export * from './components/Sundry'
|
|
3
|
+
export * from './components/Struct'
|
|
4
4
|
|
|
5
|
-
export * from
|
|
5
|
+
export * from './hooks'
|
|
6
6
|
|
|
7
|
-
export * from
|
|
7
|
+
export * from './utils'
|
package/src/utils/constants.ts
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
export const breakpoints = [
|
|
2
|
-
"base",
|
|
3
|
-
"xs",
|
|
4
|
-
"sm",
|
|
5
|
-
"md",
|
|
6
|
-
"lg",
|
|
7
|
-
"xl",
|
|
8
|
-
"2xl",
|
|
9
|
-
"3xl",
|
|
10
|
-
] as const;
|
|
1
|
+
export const breakpoints = ['base', 'xs', 'sm', 'md', 'lg', 'xl', '2xl', '3xl'] as const
|
|
11
2
|
|
|
12
3
|
export const DefBreakpointDesc: BreakpointDesc = {
|
|
13
4
|
xs: 475,
|
|
@@ -15,11 +6,11 @@ export const DefBreakpointDesc: BreakpointDesc = {
|
|
|
15
6
|
md: 768,
|
|
16
7
|
lg: 1024,
|
|
17
8
|
xl: 1280,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
export type BreakpointName = (typeof breakpoints)[number]
|
|
9
|
+
'2xl': 1536,
|
|
10
|
+
'3xl': 1920,
|
|
11
|
+
}
|
|
12
|
+
export type BreakpointName = (typeof breakpoints)[number]
|
|
22
13
|
|
|
23
|
-
export type BreakpointDesc = Partial<Record<BreakpointName, number
|
|
14
|
+
export type BreakpointDesc = Partial<Record<BreakpointName, number>>
|
|
24
15
|
|
|
25
|
-
export type Responsive<T> = T | Partial<Record<BreakpointName, T
|
|
16
|
+
export type Responsive<T> = T | Partial<Record<BreakpointName, T>>
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* @en Callback function type for state change listeners
|
|
6
|
-
* @zh 状态变更监听器的回调函数类型
|
|
7
|
-
* @template T The type of the state / 状态的类型
|
|
8
|
-
*/
|
|
9
|
-
export type CreateStateListener<T> = (state: T) => void;
|
|
1
|
+
import {useSyncExternalStore} from 'react'
|
|
2
|
+
import {safePromiseTry} from './promise'
|
|
10
3
|
|
|
11
4
|
/**
|
|
12
5
|
* @zh 如果需要在变更状态时执行副作用,可以传入函数,对于异步函数,会在更改状态后执行,不会阻塞状态更新, 尽可能在外部使用useEffect处理异步副作用
|
|
@@ -15,10 +8,7 @@ export type CreateStateListener<T> = (state: T) => void;
|
|
|
15
8
|
* @param newState The new state value / 新的状态值
|
|
16
9
|
* @param prevState The previous state value / 之前的状态值
|
|
17
10
|
*/
|
|
18
|
-
export type ExternalSideEffect<T> = (
|
|
19
|
-
newState: T,
|
|
20
|
-
prevState: T
|
|
21
|
-
) => any | Promise<any>;
|
|
11
|
+
export type ExternalSideEffect<T> = (newState: T, prevState: T) => any | Promise<any>
|
|
22
12
|
|
|
23
13
|
/**
|
|
24
14
|
* @en Transform functions for getting and setting state
|
|
@@ -31,12 +21,12 @@ export interface Transform<T, U = T> {
|
|
|
31
21
|
* @en Transform function for getting state
|
|
32
22
|
* @zh 获取状态时的转换函数
|
|
33
23
|
*/
|
|
34
|
-
get?: (state: T) => U
|
|
24
|
+
get?: (state: T) => U
|
|
35
25
|
/**
|
|
36
26
|
* @en Transform function for setting state
|
|
37
27
|
* @zh 设置状态时的转换函数
|
|
38
28
|
*/
|
|
39
|
-
set?: (value: U) => T
|
|
29
|
+
set?: (value: U) => T
|
|
40
30
|
}
|
|
41
31
|
|
|
42
32
|
/**
|
|
@@ -50,12 +40,12 @@ export interface ExternalStateOptions<T, U = T> {
|
|
|
50
40
|
* @en Side effect function to run after state changes
|
|
51
41
|
* @zh 状态变更后运行的副作用函数
|
|
52
42
|
*/
|
|
53
|
-
sideEffect?: ExternalSideEffect<T
|
|
43
|
+
sideEffect?: ExternalSideEffect<T>
|
|
54
44
|
/**
|
|
55
45
|
* @en Transform functions for getting and setting state
|
|
56
46
|
* @zh 用于获取和设置状态的转换函数
|
|
57
47
|
*/
|
|
58
|
-
transform?: Transform<T, U
|
|
48
|
+
transform?: Transform<T, U>
|
|
59
49
|
}
|
|
60
50
|
|
|
61
51
|
/**
|
|
@@ -70,31 +60,31 @@ export interface ExternalState<T, U = T> {
|
|
|
70
60
|
* @zh 获取当前状态值
|
|
71
61
|
* @returns The current state value (transformed if transform.get is provided) / 当前状态值(如果提供了 transform.get 则进行转换)
|
|
72
62
|
*/
|
|
73
|
-
get: () => U
|
|
63
|
+
get: () => U
|
|
74
64
|
|
|
75
65
|
/**
|
|
76
66
|
* @en Set a new state value
|
|
77
67
|
* @zh 设置新的状态值
|
|
78
68
|
* @param newState The new state value or a function that returns it / 新的状态值或返回新状态的函数
|
|
79
69
|
*/
|
|
80
|
-
set: (newState: U | ((prevState: U) => U)) => void
|
|
70
|
+
set: (newState: U | ((prevState: U) => U)) => void
|
|
81
71
|
|
|
82
72
|
/**
|
|
83
73
|
* @en React Hook for using external state in components
|
|
84
74
|
* @zh 在组件中使用外部状态的 React Hook
|
|
85
75
|
* @returns Array containing current钣金龙8国际唯一官网 current state and update function, similar to useState / 包含当前状态和更新函数的数组,类似于 useState
|
|
86
76
|
*/
|
|
87
|
-
use: () => [U, (newState: U | ((prevState: U) => U)) => void]
|
|
77
|
+
use: () => [U, (newState: U | ((prevState: U) => U)) => void]
|
|
88
78
|
|
|
89
79
|
/**
|
|
90
80
|
* @zh use的变体,只获取value.
|
|
91
81
|
* @en A variant of use that only gets the value.
|
|
92
82
|
*/
|
|
93
|
-
useGetter: () => U
|
|
83
|
+
useGetter: () => U
|
|
94
84
|
}
|
|
95
85
|
|
|
96
86
|
export interface ExternalWithKernel<T, U = T> extends ExternalState<T, U> {
|
|
97
|
-
__listeners:
|
|
87
|
+
__listeners: (() => void)[]
|
|
98
88
|
}
|
|
99
89
|
|
|
100
90
|
/**
|
|
@@ -130,117 +120,114 @@ export interface ExternalWithKernel<T, U = T> extends ExternalState<T, U> {
|
|
|
130
120
|
*/
|
|
131
121
|
export function createExternalState<T, U = T>(
|
|
132
122
|
initialState: T | (() => T),
|
|
133
|
-
options: ExternalStateOptions<T, U> = {}
|
|
123
|
+
options: ExternalStateOptions<T, U> = {},
|
|
134
124
|
): ExternalState<T, U> {
|
|
135
|
-
let state: T =
|
|
136
|
-
typeof initialState === "function"
|
|
137
|
-
? (initialState as () => T)()
|
|
138
|
-
: initialState;
|
|
125
|
+
let state: T = typeof initialState === 'function' ? (initialState as () => T)() : initialState
|
|
139
126
|
|
|
140
|
-
const
|
|
141
|
-
const {
|
|
127
|
+
const storeListeners: (() => void)[] = []
|
|
128
|
+
const {sideEffect, transform} = options
|
|
142
129
|
|
|
143
130
|
const get = () => {
|
|
144
|
-
const currentState = state
|
|
145
|
-
return transform?.get
|
|
146
|
-
|
|
147
|
-
: (currentState as unknown as U);
|
|
148
|
-
};
|
|
131
|
+
const currentState = state
|
|
132
|
+
return transform?.get ? transform.get(currentState) : (currentState as unknown as U)
|
|
133
|
+
}
|
|
149
134
|
|
|
150
135
|
const set = (newState: U | ((prevState: U) => U)) => {
|
|
151
|
-
const prevState = state
|
|
136
|
+
const prevState = state
|
|
152
137
|
const transformedPrevState = transform?.get
|
|
153
138
|
? transform.get(prevState)
|
|
154
|
-
: (prevState as unknown as U)
|
|
139
|
+
: (prevState as unknown as U)
|
|
155
140
|
state = transform?.set
|
|
156
141
|
? transform.set(
|
|
157
|
-
typeof newState ===
|
|
142
|
+
typeof newState === 'function'
|
|
158
143
|
? (newState as (prev: U) => U)(transformedPrevState)
|
|
159
|
-
: newState
|
|
144
|
+
: newState,
|
|
160
145
|
)
|
|
161
|
-
: ((typeof newState ===
|
|
146
|
+
: ((typeof newState === 'function'
|
|
162
147
|
? (newState as (prev: U) => U)(transformedPrevState)
|
|
163
|
-
: newState) as unknown as T)
|
|
148
|
+
: newState) as unknown as T)
|
|
164
149
|
|
|
165
|
-
|
|
150
|
+
storeListeners.forEach((listener) => listener())
|
|
166
151
|
if (sideEffect) {
|
|
167
152
|
safePromiseTry(sideEffect, state, prevState).catch((error) => {
|
|
168
153
|
console.error(
|
|
169
|
-
|
|
170
|
-
error
|
|
171
|
-
)
|
|
172
|
-
})
|
|
154
|
+
'Error in external state side effect, Please do it within side effects:',
|
|
155
|
+
error,
|
|
156
|
+
)
|
|
157
|
+
})
|
|
173
158
|
}
|
|
174
|
-
}
|
|
159
|
+
}
|
|
175
160
|
|
|
176
161
|
const use = () => {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
162
|
+
const localState = useSyncExternalStore(
|
|
163
|
+
(onStoreChange) => {
|
|
164
|
+
storeListeners.push(onStoreChange)
|
|
165
|
+
return () => {
|
|
166
|
+
const index = storeListeners.indexOf(onStoreChange)
|
|
167
|
+
if (index > -1) {
|
|
168
|
+
storeListeners.splice(index, 1)
|
|
169
|
+
}
|
|
185
170
|
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
171
|
+
},
|
|
172
|
+
() => state,
|
|
173
|
+
() => state,
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
return [transform?.get ? transform.get(localState) : (localState as unknown as U), set] as [
|
|
177
|
+
U,
|
|
178
|
+
(newState: U | ((prevState: U) => U)) => void,
|
|
179
|
+
]
|
|
180
|
+
}
|
|
194
181
|
|
|
195
182
|
const useGetter = () => {
|
|
196
|
-
const [value] = use()
|
|
197
|
-
return value
|
|
198
|
-
}
|
|
183
|
+
const [value] = use()
|
|
184
|
+
return value
|
|
185
|
+
}
|
|
199
186
|
|
|
200
187
|
//@ts-expect-error ignore
|
|
201
|
-
return {
|
|
188
|
+
return {get, set, use, useGetter, __listeners: storeListeners}
|
|
202
189
|
}
|
|
203
190
|
|
|
204
191
|
export interface StorageStateOptions<T, U> {
|
|
205
|
-
sideEffect?: (newState: T) => void
|
|
206
|
-
transform?: Transform<T, U
|
|
207
|
-
storageType:
|
|
192
|
+
sideEffect?: (newState: T) => void
|
|
193
|
+
transform?: Transform<T, U>
|
|
194
|
+
storageType: 'local' | 'session'
|
|
208
195
|
}
|
|
209
196
|
|
|
210
197
|
export function createStorageState<T, U = T>(
|
|
211
198
|
key: string,
|
|
212
199
|
initialState: T,
|
|
213
|
-
options?: StorageStateOptions<T, U
|
|
200
|
+
options?: StorageStateOptions<T, U>,
|
|
214
201
|
) {
|
|
215
|
-
const {
|
|
216
|
-
let _initState: T = initialState
|
|
217
|
-
|
|
202
|
+
const {storageType = 'local', sideEffect, transform} = options ?? {}
|
|
203
|
+
let _initState: T = initialState
|
|
204
|
+
|
|
218
205
|
// 只在客户端环境中读取存储
|
|
219
206
|
if (typeof window !== 'undefined') {
|
|
220
|
-
const storage = storageType ===
|
|
221
|
-
const storedValue = storage.getItem(key)
|
|
207
|
+
const storage = storageType === 'local' ? localStorage : sessionStorage
|
|
208
|
+
const storedValue = storage.getItem(key)
|
|
222
209
|
if (storedValue) {
|
|
223
210
|
try {
|
|
224
|
-
_initState = JSON.parse(storedValue)
|
|
211
|
+
_initState = JSON.parse(storedValue)
|
|
225
212
|
} catch (error) {
|
|
226
213
|
console.warn(
|
|
227
214
|
`Failed to parse ${storageType}Storage value for key "${key}", using initial state:`,
|
|
228
|
-
error
|
|
229
|
-
)
|
|
230
|
-
_initState = initialState
|
|
215
|
+
error,
|
|
216
|
+
)
|
|
217
|
+
_initState = initialState
|
|
231
218
|
}
|
|
232
219
|
}
|
|
233
220
|
}
|
|
234
|
-
|
|
221
|
+
|
|
235
222
|
return createExternalState(_initState, {
|
|
236
223
|
sideEffect: (newState) => {
|
|
237
224
|
// 只在客户端环境中写入存储
|
|
238
225
|
if (typeof window !== 'undefined') {
|
|
239
|
-
const storage = storageType ===
|
|
240
|
-
storage.setItem(key, JSON.stringify(newState))
|
|
226
|
+
const storage = storageType === 'local' ? localStorage : sessionStorage
|
|
227
|
+
storage.setItem(key, JSON.stringify(newState))
|
|
241
228
|
}
|
|
242
|
-
sideEffect?.(newState)
|
|
229
|
+
sideEffect?.(newState)
|
|
243
230
|
},
|
|
244
231
|
transform,
|
|
245
|
-
})
|
|
232
|
+
})
|
|
246
233
|
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
7
|
-
export * from
|
|
1
|
+
export * from './createExternalState'
|
|
2
|
+
export * from './cx'
|
|
3
|
+
export * from './reactUtils'
|
|
4
|
+
export * from './sundry'
|
|
5
|
+
export * from './promise'
|
|
6
|
+
export * from './constants'
|
|
7
|
+
export * from './ruleChecker'
|
package/src/utils/promise.ts
CHANGED
|
@@ -16,37 +16,37 @@ function promiseTry<T, U extends unknown[]>(
|
|
|
16
16
|
...args: U
|
|
17
17
|
): Promise<Awaited<T>> {
|
|
18
18
|
try {
|
|
19
|
-
const result = callbackFn(...args)
|
|
19
|
+
const result = callbackFn(...args) // Call the callback function
|
|
20
20
|
// Check if the result is a PromiseLike (Promise)
|
|
21
21
|
if (result instanceof Promise) {
|
|
22
|
-
return result
|
|
22
|
+
return result // If it's a promise, return it directly
|
|
23
23
|
}
|
|
24
24
|
// If the result is not a promise, resolve it with Promise.resolve
|
|
25
|
-
return Promise.resolve(result as Awaited<T>)
|
|
25
|
+
return Promise.resolve(result as Awaited<T>)
|
|
26
26
|
} catch (error) {
|
|
27
27
|
// If the callback throws an error, reject the promise
|
|
28
|
-
return Promise.reject(error)
|
|
28
|
+
return Promise.reject(error)
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
32
|
export const safePromiseTry = (() => {
|
|
33
|
-
if (typeof Promise.try ===
|
|
34
|
-
return Promise.try.bind(Promise)
|
|
33
|
+
if (typeof Promise.try === 'function') {
|
|
34
|
+
return Promise.try.bind(Promise)
|
|
35
35
|
}
|
|
36
|
-
return promiseTry
|
|
37
|
-
})()
|
|
36
|
+
return promiseTry
|
|
37
|
+
})()
|
|
38
38
|
|
|
39
39
|
export const safePromiseWithResolvers = (() => {
|
|
40
|
-
if (typeof Promise.withResolvers ===
|
|
41
|
-
return Promise.withResolvers.bind(Promise)
|
|
40
|
+
if (typeof Promise.withResolvers === 'function') {
|
|
41
|
+
return Promise.withResolvers.bind(Promise)
|
|
42
42
|
}
|
|
43
43
|
return <T>() => {
|
|
44
|
-
let resolve!: (value: T) => void
|
|
45
|
-
let reject!: (reason?: any) => void
|
|
44
|
+
let resolve!: (value: T) => void
|
|
45
|
+
let reject!: (reason?: any) => void
|
|
46
46
|
const promise = new Promise((res, rej) => {
|
|
47
|
-
resolve = res
|
|
48
|
-
reject = rej
|
|
49
|
-
})
|
|
50
|
-
return {
|
|
51
|
-
}
|
|
52
|
-
})()
|
|
47
|
+
resolve = res
|
|
48
|
+
reject = rej
|
|
49
|
+
})
|
|
50
|
+
return {promise, resolve, reject}
|
|
51
|
+
}
|
|
52
|
+
})()
|