Skip to content

Commit 8cc4a6f

Browse files
committed
fix(react-v19): Properly support react v19
Make prepass backwards compatible with react v19, it was necessary to handle with the following changes in React: - facebook/react#28789 - facebook/react#28813 - facebook/react#28226
1 parent b19a571 commit 8cc4a6f

File tree

5 files changed

+54
-20
lines changed

5 files changed

+54
-20
lines changed

.tool-versions

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
nodejs 14.20.0
1+
nodejs 18.19.0

src/element.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { AbstractContext, AbstractElement } from './types'
66
import {
77
type ReactSymbol,
88
REACT_ELEMENT_TYPE,
9+
REACT_TRANSITIONAL_ELEMENT_TYPE,
910
REACT_PORTAL_TYPE,
1011
REACT_FRAGMENT_TYPE,
1112
REACT_STRICT_MODE_TYPE,
@@ -16,7 +17,8 @@ import {
1617
REACT_FORWARD_REF_TYPE,
1718
REACT_SUSPENSE_TYPE,
1819
REACT_MEMO_TYPE,
19-
REACT_LAZY_TYPE
20+
REACT_LAZY_TYPE,
21+
REACT_CONSUMER_TYPE
2022
} from './symbols'
2123

2224
/** Is a given Component a class component */
@@ -29,6 +31,7 @@ export const typeOf = (x: AbstractElement): ReactSymbol | void => {
2931
case REACT_PORTAL_TYPE:
3032
return REACT_PORTAL_TYPE
3133
case REACT_ELEMENT_TYPE:
34+
case REACT_TRANSITIONAL_ELEMENT_TYPE:
3235
switch (x.type) {
3336
case REACT_CONCURRENT_MODE_TYPE:
3437
return REACT_CONCURRENT_MODE_TYPE
@@ -47,8 +50,9 @@ export const typeOf = (x: AbstractElement): ReactSymbol | void => {
4750
return REACT_LAZY_TYPE
4851
case REACT_MEMO_TYPE:
4952
return REACT_MEMO_TYPE
53+
case REACT_CONSUMER_TYPE:
54+
return REACT_CONSUMER_TYPE
5055
case REACT_CONTEXT_TYPE:
51-
return REACT_CONTEXT_TYPE
5256
case REACT_PROVIDER_TYPE:
5357
return REACT_PROVIDER_TYPE
5458
case REACT_FORWARD_REF_TYPE:

src/symbols.js

+18-5
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
import type { Node } from 'react'
44

5+
/**
6+
* Element is already legacy in NextJS v15 https://github.com/vercel/next.js/pull/65058
7+
* https://github.com/facebook/react/pull/28813
8+
*/
59
let Element = 0xeac7
10+
let TransitionalElement = 0xeac7
611
let Portal = 0xeaca
712
let Fragment = 0xeacb
813
let StrictMode = 0xeacc
914
let Profiler = 0xead2
1015
let ContextProvider = 0xeacd
11-
let ContextConsumer = 0xeace
16+
let ContextConsumer = undefined
17+
let Context = 0xeace
1218
let ConcurrentMode = 0xeacf
1319
let ForwardRef = 0xead0
1420
let Suspense = 0xead1
@@ -19,28 +25,32 @@ let ClientReferenceTag = undefined
1925
if (typeof Symbol === 'function' && Symbol.for) {
2026
const symbolFor = Symbol.for
2127
Element = symbolFor('react.element')
28+
TransitionalElement = symbolFor('react.transitional.element')
2229
Portal = symbolFor('react.portal')
2330
Fragment = symbolFor('react.fragment')
2431
StrictMode = symbolFor('react.strict_mode')
2532
Profiler = symbolFor('react.profiler')
2633
ContextProvider = symbolFor('react.provider')
27-
ContextConsumer = symbolFor('react.context')
28-
ConcurrentMode = Symbol.for('react.concurrent_mode')
34+
ContextConsumer = symbolFor('react.consumer')
35+
Context = symbolFor('react.context')
36+
ConcurrentMode = symbolFor('react.concurrent_mode')
2937
ForwardRef = symbolFor('react.forward_ref')
3038
Suspense = symbolFor('react.suspense')
3139
Memo = symbolFor('react.memo')
3240
Lazy = symbolFor('react.lazy')
33-
ClientReferenceTag = Symbol.for('react.client.reference')
41+
ClientReferenceTag = symbolFor('react.client.reference')
3442
}
3543

3644
/** Literal types representing the ReactSymbol values. These values do not actually match the values from react-is! */
3745
export type ReactSymbol =
3846
| 'react.element' /* 0xeac7 | Symbol(react.element) */
47+
| 'react.transitional.element' /* 0xeac7 | Symbol(react.transitional.element) */
3948
| 'react.portal' /* 0xeaca | Symbol(react.portal) */
4049
| 'react.fragment' /* 0xeacb | Symbol(react.fragment) */
4150
| 'react.strict_mode' /* 0xeacc | Symbol(react.strict_mode) */
4251
| 'react.profiler' /* 0xead2 | Symbol(react.profiler) */
4352
| 'react.provider' /* 0xeacd | Symbol(react.provider) */
53+
| 'react.consumer' /* undefined | Symbol(react.consumer) */
4454
| 'react.context' /* 0xeace | Symbol(react.context) */
4555
| 'react.concurrent_mode' /* 0xeacf | Symbol(react.concurrent_mode) */
4656
| 'react.forward_ref' /* 0xead0 | Symbol(react.forward_ref) */
@@ -49,12 +59,15 @@ export type ReactSymbol =
4959
| 'react.lazy' /* 0xead4 | Symbol(react.lazy) */
5060

5161
export const REACT_ELEMENT_TYPE: 'react.element' = (Element: any)
62+
export const REACT_TRANSITIONAL_ELEMENT_TYPE: 'react.transitional.element' =
63+
(TransitionalElement: any)
5264
export const REACT_PORTAL_TYPE: 'react.portal' = (Portal: any)
5365
export const REACT_FRAGMENT_TYPE: 'react.fragment' = (Fragment: any)
5466
export const REACT_STRICT_MODE_TYPE: 'react.strict_mode' = (StrictMode: any)
5567
export const REACT_PROFILER_TYPE: 'react.profiler' = (Profiler: any)
5668
export const REACT_PROVIDER_TYPE: 'react.provider' = (ContextProvider: any)
57-
export const REACT_CONTEXT_TYPE: 'react.context' = (ContextConsumer: any)
69+
export const REACT_CONSUMER_TYPE: 'react.consumer' = (ContextConsumer: any)
70+
export const REACT_CONTEXT_TYPE: 'react.context' = (Context: any)
5871
export const REACT_CONCURRENT_MODE_TYPE: 'react.concurrent_mode' =
5972
(ConcurrentMode: any)
6073
export const REACT_FORWARD_REF_TYPE: 'react.forward_ref' = (ForwardRef: any)

src/types/element.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import {
1414
REACT_FORWARD_REF_TYPE,
1515
REACT_SUSPENSE_TYPE,
1616
REACT_MEMO_TYPE,
17-
REACT_LAZY_TYPE
17+
REACT_LAZY_TYPE,
18+
REACT_CONSUMER_TYPE
1819
} from '../symbols'
1920

2021
export type AbstractContext = Context<mixed> & {
@@ -41,7 +42,7 @@ export type ConsumerElement = {
4142
type:
4243
| AbstractContext
4344
| {
44-
$$typeof: typeof REACT_CONTEXT_TYPE,
45+
$$typeof: typeof REACT_CONSUMER_TYPE,
4546
_context: AbstractContext
4647
},
4748
props: { children?: (value: mixed) => Node },

src/visitor.js

+26-10
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import {
6666

6767
import {
6868
REACT_ELEMENT_TYPE,
69+
REACT_TRANSITIONAL_ELEMENT_TYPE,
6970
REACT_PORTAL_TYPE,
7071
REACT_FRAGMENT_TYPE,
7172
REACT_STRICT_MODE_TYPE,
@@ -76,7 +77,8 @@ import {
7677
REACT_FORWARD_REF_TYPE,
7778
REACT_SUSPENSE_TYPE,
7879
REACT_MEMO_TYPE,
79-
REACT_LAZY_TYPE
80+
REACT_LAZY_TYPE,
81+
REACT_CONSUMER_TYPE
8082
} from './symbols'
8183

8284
import { isClientReference } from './utils'
@@ -86,7 +88,19 @@ const REACT_INTERNALS =
8688
(React: any).__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE
8789

8890
const ReactCurrentDispatcher =
89-
REACT_INTERNALS && REACT_INTERNALS.ReactCurrentDispatcher
91+
REACT_INTERNALS.ReactCurrentDispatcher || REACT_INTERNALS
92+
93+
const getReactCurrentDispatcher = () => {
94+
return ReactCurrentDispatcher.current || ReactCurrentDispatcher.H
95+
}
96+
97+
const injectReactCurrentDispatcher = (newDispatcher) => {
98+
if (ReactCurrentDispatcher.current) {
99+
ReactCurrentDispatcher.current = newDispatcher
100+
} else {
101+
ReactCurrentDispatcher.H = newDispatcher
102+
}
103+
}
90104

91105
// In the presence of setImmediate, i.e. on Node, we'll enable the
92106
// yielding behavior that gives the event loop a chance to continue
@@ -141,12 +155,14 @@ export const visitElement = (
141155
const providerElement = ((element: any): ProviderElement)
142156
// Add provider's value prop to context
143157
const { value, children } = providerElement.props
144-
setContextValue(providerElement.type._context, value)
158+
const type = (providerElement.type: any)
159+
const context = typeof type._context === 'object' ? type._context : type
160+
setContextValue(context, value)
145161

146162
return getChildrenArray(children)
147163
}
148164

149-
case REACT_CONTEXT_TYPE: {
165+
case REACT_CONSUMER_TYPE: {
150166
const consumerElement = ((element: any): ConsumerElement)
151167
const { children } = consumerElement.props
152168

@@ -221,11 +237,11 @@ const visitLoop = (
221237
visitor: Visitor,
222238
clientRefVisitor: ClientReferenceVisitor
223239
): boolean => {
224-
const prevDispatcher = ReactCurrentDispatcher.current
240+
const prevDispatcher = getReactCurrentDispatcher()
225241
const start = Date.now()
226242

227243
try {
228-
ReactCurrentDispatcher.current = Dispatcher
244+
injectReactCurrentDispatcher(Dispatcher)
229245
while (traversalChildren.length > 0) {
230246
const element = traversalChildren[traversalChildren.length - 1].shift()
231247
if (element !== undefined) {
@@ -254,7 +270,7 @@ const visitLoop = (
254270
queue.unshift(errorFrame)
255271
return false
256272
} finally {
257-
ReactCurrentDispatcher.current = prevDispatcher
273+
injectReactCurrentDispatcher(prevDispatcher)
258274
}
259275
}
260276

@@ -341,10 +357,10 @@ export const update = (
341357
)
342358
}
343359
} else {
344-
const prevDispatcher = ReactCurrentDispatcher.current
360+
const prevDispatcher = getReactCurrentDispatcher()
345361
let children = null
346362

347-
ReactCurrentDispatcher.current = Dispatcher
363+
injectReactCurrentDispatcher(Dispatcher)
348364

349365
try {
350366
if (frame.kind === 'frame.class') {
@@ -363,7 +379,7 @@ export const update = (
363379
queue.unshift(errorFrame)
364380
children = null
365381
} finally {
366-
ReactCurrentDispatcher.current = prevDispatcher
382+
injectReactCurrentDispatcher(prevDispatcher)
367383
}
368384

369385
visit(getChildrenArray(children), queue, visitor, clientRefVisitor)

0 commit comments

Comments
 (0)