@depup/react-redux 9.3.0-depup.53
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/LICENSE.md +21 -0
- package/README.md +32 -0
- package/changes.json +14 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/react-redux.development.cjs +1119 -0
- package/dist/cjs/react-redux.development.cjs.map +1 -0
- package/dist/cjs/react-redux.production.min.cjs +6 -0
- package/dist/cjs/react-redux.production.min.cjs.map +1 -0
- package/dist/react-redux.browser.mjs +6 -0
- package/dist/react-redux.browser.mjs.map +1 -0
- package/dist/react-redux.d.ts +587 -0
- package/dist/react-redux.legacy-esm.js +1105 -0
- package/dist/react-redux.legacy-esm.js.map +1 -0
- package/dist/react-redux.mjs +1071 -0
- package/dist/react-redux.mjs.map +1 -0
- package/dist/rsc.mjs +46 -0
- package/dist/rsc.mjs.map +1 -0
- package/package.json +124 -0
- package/src/components/Context.ts +50 -0
- package/src/components/Provider.tsx +105 -0
- package/src/components/connect.tsx +845 -0
- package/src/connect/invalidArgFactory.ts +14 -0
- package/src/connect/mapDispatchToProps.ts +25 -0
- package/src/connect/mapStateToProps.ts +14 -0
- package/src/connect/mergeProps.ts +78 -0
- package/src/connect/selectorFactory.ts +242 -0
- package/src/connect/verifySubselectors.ts +26 -0
- package/src/connect/wrapMapToProps.ts +110 -0
- package/src/exports.ts +51 -0
- package/src/hooks/useDispatch.ts +104 -0
- package/src/hooks/useReduxContext.ts +42 -0
- package/src/hooks/useSelector.ts +286 -0
- package/src/hooks/useStore.ts +123 -0
- package/src/index-rsc.ts +35 -0
- package/src/index.ts +1 -0
- package/src/types.ts +180 -0
- package/src/utils/Subscription.ts +183 -0
- package/src/utils/batch.ts +4 -0
- package/src/utils/bindActionCreators.ts +16 -0
- package/src/utils/hoistStatics.ts +139 -0
- package/src/utils/isPlainObject.ts +17 -0
- package/src/utils/react-is.ts +97 -0
- package/src/utils/react.ts +3 -0
- package/src/utils/shallowEqual.ts +36 -0
- package/src/utils/useIsomorphicLayoutEffect.ts +40 -0
- package/src/utils/useSyncExternalStore.ts +9 -0
- package/src/utils/verifyPlainObject.ts +14 -0
- package/src/utils/warning.ts +21 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { defaultNoopBatch as batch } from './batch'
|
|
2
|
+
|
|
3
|
+
// encapsulates the subscription logic for connecting a component to the redux store, as
|
|
4
|
+
// well as nesting subscriptions of descendant components, so that we can ensure the
|
|
5
|
+
// ancestor components re-render before descendants
|
|
6
|
+
|
|
7
|
+
type VoidFunc = () => void
|
|
8
|
+
|
|
9
|
+
type Listener = {
|
|
10
|
+
callback: VoidFunc
|
|
11
|
+
next: Listener | null
|
|
12
|
+
prev: Listener | null
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function createListenerCollection() {
|
|
16
|
+
let first: Listener | null = null
|
|
17
|
+
let last: Listener | null = null
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
clear() {
|
|
21
|
+
first = null
|
|
22
|
+
last = null
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
notify() {
|
|
26
|
+
batch(() => {
|
|
27
|
+
let listener = first
|
|
28
|
+
while (listener) {
|
|
29
|
+
listener.callback()
|
|
30
|
+
listener = listener.next
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
get() {
|
|
36
|
+
const listeners: Listener[] = []
|
|
37
|
+
let listener = first
|
|
38
|
+
while (listener) {
|
|
39
|
+
listeners.push(listener)
|
|
40
|
+
listener = listener.next
|
|
41
|
+
}
|
|
42
|
+
return listeners
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
subscribe(callback: () => void) {
|
|
46
|
+
let isSubscribed = true
|
|
47
|
+
|
|
48
|
+
const listener: Listener = (last = {
|
|
49
|
+
callback,
|
|
50
|
+
next: null,
|
|
51
|
+
prev: last,
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
if (listener.prev) {
|
|
55
|
+
listener.prev.next = listener
|
|
56
|
+
} else {
|
|
57
|
+
first = listener
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return function unsubscribe() {
|
|
61
|
+
if (!isSubscribed || first === null) return
|
|
62
|
+
isSubscribed = false
|
|
63
|
+
|
|
64
|
+
if (listener.next) {
|
|
65
|
+
listener.next.prev = listener.prev
|
|
66
|
+
} else {
|
|
67
|
+
last = listener.prev
|
|
68
|
+
}
|
|
69
|
+
if (listener.prev) {
|
|
70
|
+
listener.prev.next = listener.next
|
|
71
|
+
} else {
|
|
72
|
+
first = listener.next
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
type ListenerCollection = ReturnType<typeof createListenerCollection>
|
|
80
|
+
|
|
81
|
+
export interface Subscription {
|
|
82
|
+
addNestedSub: (listener: VoidFunc) => VoidFunc
|
|
83
|
+
notifyNestedSubs: VoidFunc
|
|
84
|
+
handleChangeWrapper: VoidFunc
|
|
85
|
+
isSubscribed: () => boolean
|
|
86
|
+
onStateChange?: VoidFunc | null
|
|
87
|
+
trySubscribe: VoidFunc
|
|
88
|
+
tryUnsubscribe: VoidFunc
|
|
89
|
+
getListeners: () => ListenerCollection
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
const nullListeners = {
|
|
93
|
+
notify() {},
|
|
94
|
+
get: () => [],
|
|
95
|
+
} as unknown as ListenerCollection
|
|
96
|
+
|
|
97
|
+
export function createSubscription(store: any, parentSub?: Subscription) {
|
|
98
|
+
let unsubscribe: VoidFunc | undefined
|
|
99
|
+
let listeners: ListenerCollection = nullListeners
|
|
100
|
+
|
|
101
|
+
// Reasons to keep the subscription active
|
|
102
|
+
let subscriptionsAmount = 0
|
|
103
|
+
|
|
104
|
+
// Is this specific subscription subscribed (or only nested ones?)
|
|
105
|
+
let selfSubscribed = false
|
|
106
|
+
|
|
107
|
+
function addNestedSub(listener: () => void) {
|
|
108
|
+
trySubscribe()
|
|
109
|
+
|
|
110
|
+
const cleanupListener = listeners.subscribe(listener)
|
|
111
|
+
|
|
112
|
+
// cleanup nested sub
|
|
113
|
+
let removed = false
|
|
114
|
+
return () => {
|
|
115
|
+
if (!removed) {
|
|
116
|
+
removed = true
|
|
117
|
+
cleanupListener()
|
|
118
|
+
tryUnsubscribe()
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function notifyNestedSubs() {
|
|
124
|
+
listeners.notify()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function handleChangeWrapper() {
|
|
128
|
+
if (subscription.onStateChange) {
|
|
129
|
+
subscription.onStateChange()
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function isSubscribed() {
|
|
134
|
+
return selfSubscribed
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function trySubscribe() {
|
|
138
|
+
subscriptionsAmount++
|
|
139
|
+
if (!unsubscribe) {
|
|
140
|
+
unsubscribe = parentSub
|
|
141
|
+
? parentSub.addNestedSub(handleChangeWrapper)
|
|
142
|
+
: store.subscribe(handleChangeWrapper)
|
|
143
|
+
|
|
144
|
+
listeners = createListenerCollection()
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function tryUnsubscribe() {
|
|
149
|
+
subscriptionsAmount--
|
|
150
|
+
if (unsubscribe && subscriptionsAmount === 0) {
|
|
151
|
+
unsubscribe()
|
|
152
|
+
unsubscribe = undefined
|
|
153
|
+
listeners.clear()
|
|
154
|
+
listeners = nullListeners
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function trySubscribeSelf() {
|
|
159
|
+
if (!selfSubscribed) {
|
|
160
|
+
selfSubscribed = true
|
|
161
|
+
trySubscribe()
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function tryUnsubscribeSelf() {
|
|
166
|
+
if (selfSubscribed) {
|
|
167
|
+
selfSubscribed = false
|
|
168
|
+
tryUnsubscribe()
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const subscription: Subscription = {
|
|
173
|
+
addNestedSub,
|
|
174
|
+
notifyNestedSubs,
|
|
175
|
+
handleChangeWrapper,
|
|
176
|
+
isSubscribed,
|
|
177
|
+
trySubscribe: trySubscribeSelf,
|
|
178
|
+
tryUnsubscribe: tryUnsubscribeSelf,
|
|
179
|
+
getListeners: () => listeners,
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return subscription
|
|
183
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ActionCreatorsMapObject, Dispatch } from 'redux'
|
|
2
|
+
|
|
3
|
+
export default function bindActionCreators(
|
|
4
|
+
actionCreators: ActionCreatorsMapObject,
|
|
5
|
+
dispatch: Dispatch,
|
|
6
|
+
): ActionCreatorsMapObject {
|
|
7
|
+
const boundActionCreators: ActionCreatorsMapObject = {}
|
|
8
|
+
|
|
9
|
+
for (const key in actionCreators) {
|
|
10
|
+
const actionCreator = actionCreators[key]
|
|
11
|
+
if (typeof actionCreator === 'function') {
|
|
12
|
+
boundActionCreators[key] = (...args) => dispatch(actionCreator(...args))
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
return boundActionCreators
|
|
16
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Copied directly from:
|
|
2
|
+
// https://github.com/mridgway/hoist-non-react-statics/blob/main/src/index.js
|
|
3
|
+
// https://unpkg.com/browse/@types/hoist-non-react-statics@3.3.6/index.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Copyright 2015, Yahoo! Inc.
|
|
7
|
+
* Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
|
|
8
|
+
*/
|
|
9
|
+
import type { ForwardRefExoticComponent, MemoExoticComponent } from 'react'
|
|
10
|
+
import { ForwardRef, Memo, isMemo } from '../utils/react-is'
|
|
11
|
+
|
|
12
|
+
const REACT_STATICS = {
|
|
13
|
+
childContextTypes: true,
|
|
14
|
+
contextType: true,
|
|
15
|
+
contextTypes: true,
|
|
16
|
+
defaultProps: true,
|
|
17
|
+
displayName: true,
|
|
18
|
+
getDefaultProps: true,
|
|
19
|
+
getDerivedStateFromError: true,
|
|
20
|
+
getDerivedStateFromProps: true,
|
|
21
|
+
mixins: true,
|
|
22
|
+
propTypes: true,
|
|
23
|
+
type: true,
|
|
24
|
+
} as const
|
|
25
|
+
|
|
26
|
+
const KNOWN_STATICS = {
|
|
27
|
+
name: true,
|
|
28
|
+
length: true,
|
|
29
|
+
prototype: true,
|
|
30
|
+
caller: true,
|
|
31
|
+
callee: true,
|
|
32
|
+
arguments: true,
|
|
33
|
+
arity: true,
|
|
34
|
+
} as const
|
|
35
|
+
|
|
36
|
+
const FORWARD_REF_STATICS = {
|
|
37
|
+
$$typeof: true,
|
|
38
|
+
render: true,
|
|
39
|
+
defaultProps: true,
|
|
40
|
+
displayName: true,
|
|
41
|
+
propTypes: true,
|
|
42
|
+
} as const
|
|
43
|
+
|
|
44
|
+
const MEMO_STATICS = {
|
|
45
|
+
$$typeof: true,
|
|
46
|
+
compare: true,
|
|
47
|
+
defaultProps: true,
|
|
48
|
+
displayName: true,
|
|
49
|
+
propTypes: true,
|
|
50
|
+
type: true,
|
|
51
|
+
} as const
|
|
52
|
+
|
|
53
|
+
const TYPE_STATICS = {
|
|
54
|
+
[ForwardRef]: FORWARD_REF_STATICS,
|
|
55
|
+
[Memo]: MEMO_STATICS,
|
|
56
|
+
} as const
|
|
57
|
+
|
|
58
|
+
function getStatics(component: any) {
|
|
59
|
+
// React v16.11 and below
|
|
60
|
+
if (isMemo(component)) {
|
|
61
|
+
return MEMO_STATICS
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// React v16.12 and above
|
|
65
|
+
return TYPE_STATICS[component['$$typeof']] || REACT_STATICS
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export type NonReactStatics<
|
|
69
|
+
Source,
|
|
70
|
+
C extends {
|
|
71
|
+
[key: string]: true
|
|
72
|
+
} = {},
|
|
73
|
+
> = {
|
|
74
|
+
[key in Exclude<
|
|
75
|
+
keyof Source,
|
|
76
|
+
Source extends MemoExoticComponent<any>
|
|
77
|
+
? keyof typeof MEMO_STATICS | keyof C
|
|
78
|
+
: Source extends ForwardRefExoticComponent<any>
|
|
79
|
+
? keyof typeof FORWARD_REF_STATICS | keyof C
|
|
80
|
+
: keyof typeof REACT_STATICS | keyof typeof KNOWN_STATICS | keyof C
|
|
81
|
+
>]: Source[key]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const defineProperty = Object.defineProperty
|
|
85
|
+
const getOwnPropertyNames = Object.getOwnPropertyNames
|
|
86
|
+
const getOwnPropertySymbols = Object.getOwnPropertySymbols
|
|
87
|
+
const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor
|
|
88
|
+
const getPrototypeOf = Object.getPrototypeOf
|
|
89
|
+
const objectPrototype = Object.prototype
|
|
90
|
+
|
|
91
|
+
export default function hoistNonReactStatics<
|
|
92
|
+
Target,
|
|
93
|
+
Source,
|
|
94
|
+
CustomStatic extends {
|
|
95
|
+
[key: string]: true
|
|
96
|
+
} = {},
|
|
97
|
+
>(
|
|
98
|
+
targetComponent: Target,
|
|
99
|
+
sourceComponent: Source,
|
|
100
|
+
): Target & NonReactStatics<Source, CustomStatic> {
|
|
101
|
+
if (typeof sourceComponent !== 'string') {
|
|
102
|
+
// don't hoist over string (html) components
|
|
103
|
+
|
|
104
|
+
if (objectPrototype) {
|
|
105
|
+
const inheritedComponent = getPrototypeOf(sourceComponent)
|
|
106
|
+
if (inheritedComponent && inheritedComponent !== objectPrototype) {
|
|
107
|
+
hoistNonReactStatics(targetComponent, inheritedComponent)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
let keys: (string | symbol)[] = getOwnPropertyNames(sourceComponent)
|
|
112
|
+
|
|
113
|
+
if (getOwnPropertySymbols) {
|
|
114
|
+
keys = keys.concat(getOwnPropertySymbols(sourceComponent))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const targetStatics = getStatics(targetComponent)
|
|
118
|
+
const sourceStatics = getStatics(sourceComponent)
|
|
119
|
+
|
|
120
|
+
for (let i = 0; i < keys.length; ++i) {
|
|
121
|
+
const key = keys[i]
|
|
122
|
+
if (
|
|
123
|
+
!KNOWN_STATICS[key as keyof typeof KNOWN_STATICS] &&
|
|
124
|
+
!(sourceStatics && sourceStatics[key as keyof typeof sourceStatics]) &&
|
|
125
|
+
!(targetStatics && targetStatics[key as keyof typeof targetStatics])
|
|
126
|
+
) {
|
|
127
|
+
const descriptor = getOwnPropertyDescriptor(sourceComponent, key)
|
|
128
|
+
try {
|
|
129
|
+
// Avoid failures from read-only properties
|
|
130
|
+
defineProperty(targetComponent, key, descriptor!)
|
|
131
|
+
} catch (e) {
|
|
132
|
+
// ignore
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return targetComponent as any
|
|
139
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {any} obj The object to inspect.
|
|
3
|
+
* @returns {boolean} True if the argument appears to be a plain object.
|
|
4
|
+
*/
|
|
5
|
+
export default function isPlainObject(obj: unknown) {
|
|
6
|
+
if (typeof obj !== 'object' || obj === null) return false
|
|
7
|
+
|
|
8
|
+
const proto = Object.getPrototypeOf(obj)
|
|
9
|
+
if (proto === null) return true
|
|
10
|
+
|
|
11
|
+
let baseProto = proto
|
|
12
|
+
while (Object.getPrototypeOf(baseProto) !== null) {
|
|
13
|
+
baseProto = Object.getPrototypeOf(baseProto)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return proto === baseProto
|
|
17
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { ElementType, MemoExoticComponent, ReactElement } from 'react'
|
|
2
|
+
import { React } from './react'
|
|
3
|
+
|
|
4
|
+
// Directly ported from:
|
|
5
|
+
// https://unpkg.com/browse/react-is@19.0.0/cjs/react-is.production.js
|
|
6
|
+
// It's very possible this could change in the future, but given that
|
|
7
|
+
// we only use these in `connect`, this is a low priority.
|
|
8
|
+
|
|
9
|
+
export const IS_REACT_19 = /* @__PURE__ */ React.version.startsWith('19')
|
|
10
|
+
|
|
11
|
+
const REACT_ELEMENT_TYPE = /* @__PURE__ */ Symbol.for(
|
|
12
|
+
IS_REACT_19 ? 'react.transitional.element' : 'react.element',
|
|
13
|
+
)
|
|
14
|
+
const REACT_PORTAL_TYPE = /* @__PURE__ */ Symbol.for('react.portal')
|
|
15
|
+
const REACT_FRAGMENT_TYPE = /* @__PURE__ */ Symbol.for('react.fragment')
|
|
16
|
+
const REACT_STRICT_MODE_TYPE = /* @__PURE__ */ Symbol.for('react.strict_mode')
|
|
17
|
+
const REACT_PROFILER_TYPE = /* @__PURE__ */ Symbol.for('react.profiler')
|
|
18
|
+
const REACT_CONSUMER_TYPE = /* @__PURE__ */ Symbol.for('react.consumer')
|
|
19
|
+
const REACT_CONTEXT_TYPE = /* @__PURE__ */ Symbol.for('react.context')
|
|
20
|
+
const REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for('react.forward_ref')
|
|
21
|
+
const REACT_SUSPENSE_TYPE = /* @__PURE__ */ Symbol.for('react.suspense')
|
|
22
|
+
const REACT_SUSPENSE_LIST_TYPE = /* @__PURE__ */ Symbol.for(
|
|
23
|
+
'react.suspense_list',
|
|
24
|
+
)
|
|
25
|
+
const REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for('react.memo')
|
|
26
|
+
const REACT_LAZY_TYPE = /* @__PURE__ */ Symbol.for('react.lazy')
|
|
27
|
+
const REACT_OFFSCREEN_TYPE = /* @__PURE__ */ Symbol.for('react.offscreen')
|
|
28
|
+
const REACT_CLIENT_REFERENCE = /* @__PURE__ */ Symbol.for(
|
|
29
|
+
'react.client.reference',
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
export const ForwardRef = REACT_FORWARD_REF_TYPE
|
|
33
|
+
export const Memo = REACT_MEMO_TYPE
|
|
34
|
+
|
|
35
|
+
export function isValidElementType(type: any): type is ElementType {
|
|
36
|
+
return typeof type === 'string' ||
|
|
37
|
+
typeof type === 'function' ||
|
|
38
|
+
type === REACT_FRAGMENT_TYPE ||
|
|
39
|
+
type === REACT_PROFILER_TYPE ||
|
|
40
|
+
type === REACT_STRICT_MODE_TYPE ||
|
|
41
|
+
type === REACT_SUSPENSE_TYPE ||
|
|
42
|
+
type === REACT_SUSPENSE_LIST_TYPE ||
|
|
43
|
+
type === REACT_OFFSCREEN_TYPE ||
|
|
44
|
+
(typeof type === 'object' &&
|
|
45
|
+
type !== null &&
|
|
46
|
+
(type.$$typeof === REACT_LAZY_TYPE ||
|
|
47
|
+
type.$$typeof === REACT_MEMO_TYPE ||
|
|
48
|
+
type.$$typeof === REACT_CONTEXT_TYPE ||
|
|
49
|
+
type.$$typeof === REACT_CONSUMER_TYPE ||
|
|
50
|
+
type.$$typeof === REACT_FORWARD_REF_TYPE ||
|
|
51
|
+
type.$$typeof === REACT_CLIENT_REFERENCE ||
|
|
52
|
+
type.getModuleId !== undefined))
|
|
53
|
+
? !0
|
|
54
|
+
: !1
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function typeOf(object: any): symbol | undefined {
|
|
58
|
+
if (typeof object === 'object' && object !== null) {
|
|
59
|
+
const { $$typeof } = object
|
|
60
|
+
|
|
61
|
+
switch ($$typeof) {
|
|
62
|
+
case REACT_ELEMENT_TYPE:
|
|
63
|
+
switch (((object = object.type), object)) {
|
|
64
|
+
case REACT_FRAGMENT_TYPE:
|
|
65
|
+
case REACT_PROFILER_TYPE:
|
|
66
|
+
case REACT_STRICT_MODE_TYPE:
|
|
67
|
+
case REACT_SUSPENSE_TYPE:
|
|
68
|
+
case REACT_SUSPENSE_LIST_TYPE:
|
|
69
|
+
return object
|
|
70
|
+
default:
|
|
71
|
+
switch (((object = object && object.$$typeof), object)) {
|
|
72
|
+
case REACT_CONTEXT_TYPE:
|
|
73
|
+
case REACT_FORWARD_REF_TYPE:
|
|
74
|
+
case REACT_LAZY_TYPE:
|
|
75
|
+
case REACT_MEMO_TYPE:
|
|
76
|
+
return object
|
|
77
|
+
case REACT_CONSUMER_TYPE:
|
|
78
|
+
return object
|
|
79
|
+
default:
|
|
80
|
+
return $$typeof
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
case REACT_PORTAL_TYPE:
|
|
84
|
+
return $$typeof
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function isContextConsumer(object: any): object is ReactElement {
|
|
90
|
+
return IS_REACT_19
|
|
91
|
+
? typeOf(object) === REACT_CONSUMER_TYPE
|
|
92
|
+
: typeOf(object) === REACT_CONTEXT_TYPE
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function isMemo(object: any): object is MemoExoticComponent<any> {
|
|
96
|
+
return typeOf(object) === REACT_MEMO_TYPE
|
|
97
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
function is(x: unknown, y: unknown) {
|
|
2
|
+
if (x === y) {
|
|
3
|
+
return x !== 0 || y !== 0 || 1 / x === 1 / y
|
|
4
|
+
} else {
|
|
5
|
+
return x !== x && y !== y
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function shallowEqual(objA: any, objB: any) {
|
|
10
|
+
if (is(objA, objB)) return true
|
|
11
|
+
|
|
12
|
+
if (
|
|
13
|
+
typeof objA !== 'object' ||
|
|
14
|
+
objA === null ||
|
|
15
|
+
typeof objB !== 'object' ||
|
|
16
|
+
objB === null
|
|
17
|
+
) {
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const keysA = Object.keys(objA)
|
|
22
|
+
const keysB = Object.keys(objB)
|
|
23
|
+
|
|
24
|
+
if (keysA.length !== keysB.length) return false
|
|
25
|
+
|
|
26
|
+
for (let i = 0; i < keysA.length; i++) {
|
|
27
|
+
if (
|
|
28
|
+
!Object.prototype.hasOwnProperty.call(objB, keysA[i]) ||
|
|
29
|
+
!is(objA[keysA[i]], objB[keysA[i]])
|
|
30
|
+
) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { React } from '../utils/react'
|
|
2
|
+
|
|
3
|
+
// React currently throws a warning when using useLayoutEffect on the server.
|
|
4
|
+
// To get around it, we can conditionally useEffect on the server (no-op) and
|
|
5
|
+
// useLayoutEffect in the browser. We need useLayoutEffect to ensure the store
|
|
6
|
+
// subscription callback always has the selector from the latest render commit
|
|
7
|
+
// available, otherwise a store update may happen between render and the effect,
|
|
8
|
+
// which may cause missed updates; we also must ensure the store subscription
|
|
9
|
+
// is created synchronously, otherwise a store update may occur before the
|
|
10
|
+
// subscription is created and an inconsistent state may be observed
|
|
11
|
+
|
|
12
|
+
// Matches logic in React's `shared/ExecutionEnvironment` file
|
|
13
|
+
const canUseDOM = () =>
|
|
14
|
+
!!(
|
|
15
|
+
typeof window !== 'undefined' &&
|
|
16
|
+
typeof window.document !== 'undefined' &&
|
|
17
|
+
typeof window.document.createElement !== 'undefined'
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
const isDOM = /* @__PURE__ */ canUseDOM()
|
|
21
|
+
|
|
22
|
+
// Under React Native, we know that we always want to use useLayoutEffect
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Checks if the code is running in a React Native environment.
|
|
26
|
+
*
|
|
27
|
+
* @returns Whether the code is running in a React Native environment.
|
|
28
|
+
*
|
|
29
|
+
* @see {@link https://github.com/facebook/react-native/issues/1331 Reference}
|
|
30
|
+
*/
|
|
31
|
+
const isRunningInReactNative = () =>
|
|
32
|
+
typeof navigator !== 'undefined' && navigator.product === 'ReactNative'
|
|
33
|
+
|
|
34
|
+
const isReactNative = /* @__PURE__ */ isRunningInReactNative()
|
|
35
|
+
|
|
36
|
+
const getUseIsomorphicLayoutEffect = () =>
|
|
37
|
+
isDOM || isReactNative ? React.useLayoutEffect : React.useEffect
|
|
38
|
+
|
|
39
|
+
export const useIsomorphicLayoutEffect =
|
|
40
|
+
/* @__PURE__ */ getUseIsomorphicLayoutEffect()
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { useSyncExternalStore } from 'use-sync-external-store'
|
|
2
|
+
import type { useSyncExternalStoreWithSelector } from 'use-sync-external-store/with-selector'
|
|
3
|
+
|
|
4
|
+
export const notInitialized = () => {
|
|
5
|
+
throw new Error('uSES not initialized!')
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export type uSES = typeof useSyncExternalStore
|
|
9
|
+
export type uSESWS = typeof useSyncExternalStoreWithSelector
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import isPlainObject from './isPlainObject'
|
|
2
|
+
import warning from './warning'
|
|
3
|
+
|
|
4
|
+
export default function verifyPlainObject(
|
|
5
|
+
value: unknown,
|
|
6
|
+
displayName: string,
|
|
7
|
+
methodName: string,
|
|
8
|
+
) {
|
|
9
|
+
if (!isPlainObject(value)) {
|
|
10
|
+
warning(
|
|
11
|
+
`${methodName}() in ${displayName} must return a plain object. Instead received ${value}.`,
|
|
12
|
+
)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prints a warning in the console if it exists.
|
|
3
|
+
*
|
|
4
|
+
* @param {String} message The warning message.
|
|
5
|
+
* @returns {void}
|
|
6
|
+
*/
|
|
7
|
+
export default function warning(message: string) {
|
|
8
|
+
/* eslint-disable no-console */
|
|
9
|
+
if (typeof console !== 'undefined' && typeof console.error === 'function') {
|
|
10
|
+
console.error(message)
|
|
11
|
+
}
|
|
12
|
+
/* eslint-enable no-console */
|
|
13
|
+
try {
|
|
14
|
+
// This error was thrown as a convenience so that if you enable
|
|
15
|
+
// "break on all exceptions" in your console,
|
|
16
|
+
// it would pause the execution at this line.
|
|
17
|
+
throw new Error(message)
|
|
18
|
+
/* eslint-disable no-empty */
|
|
19
|
+
} catch (e) {}
|
|
20
|
+
/* eslint-enable no-empty */
|
|
21
|
+
}
|