Skip to content

Commit

Permalink
fix(react-v19): Properly support react v19
Browse files Browse the repository at this point in the history
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
  • Loading branch information
FMota0 committed Nov 27, 2024
1 parent b19a571 commit 35495d6
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1 +1 @@
nodejs 14.20.0
nodejs 18.19.0
8 changes: 6 additions & 2 deletions src/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { AbstractContext, AbstractElement } from './types'
import {
type ReactSymbol,
REACT_ELEMENT_TYPE,
REACT_TRANSITIONAL_ELEMENT_TYPE,
REACT_PORTAL_TYPE,
REACT_FRAGMENT_TYPE,
REACT_STRICT_MODE_TYPE,
Expand All @@ -16,7 +17,8 @@ import {
REACT_FORWARD_REF_TYPE,
REACT_SUSPENSE_TYPE,
REACT_MEMO_TYPE,
REACT_LAZY_TYPE
REACT_LAZY_TYPE,
REACT_CONSUMER_TYPE
} from './symbols'

/** Is a given Component a class component */
Expand All @@ -29,6 +31,7 @@ export const typeOf = (x: AbstractElement): ReactSymbol | void => {
case REACT_PORTAL_TYPE:
return REACT_PORTAL_TYPE
case REACT_ELEMENT_TYPE:
case REACT_TRANSITIONAL_ELEMENT_TYPE:
switch (x.type) {
case REACT_CONCURRENT_MODE_TYPE:
return REACT_CONCURRENT_MODE_TYPE
Expand All @@ -47,8 +50,9 @@ export const typeOf = (x: AbstractElement): ReactSymbol | void => {
return REACT_LAZY_TYPE
case REACT_MEMO_TYPE:
return REACT_MEMO_TYPE
case REACT_CONSUMER_TYPE:
return REACT_CONSUMER_TYPE
case REACT_CONTEXT_TYPE:
return REACT_CONTEXT_TYPE
case REACT_PROVIDER_TYPE:
return REACT_PROVIDER_TYPE
case REACT_FORWARD_REF_TYPE:
Expand Down
23 changes: 18 additions & 5 deletions src/symbols.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import type { Node } from 'react'

/**
* Element is already legacy in NextJS v15 https://github.com/vercel/next.js/pull/65058
* https://github.com/facebook/react/pull/28813
*/
let Element = 0xeac7
let TransitionalElement = 0xeac7
let Portal = 0xeaca
let Fragment = 0xeacb
let StrictMode = 0xeacc
let Profiler = 0xead2
let ContextProvider = 0xeacd
let ContextConsumer = 0xeace
let ContextConsumer = undefined
let Context = 0xeace
let ConcurrentMode = 0xeacf
let ForwardRef = 0xead0
let Suspense = 0xead1
Expand All @@ -19,28 +25,32 @@ let ClientReferenceTag = undefined
if (typeof Symbol === 'function' && Symbol.for) {
const symbolFor = Symbol.for
Element = symbolFor('react.element')
TransitionalElement = symbolFor('react.transitional.element')
Portal = symbolFor('react.portal')
Fragment = symbolFor('react.fragment')
StrictMode = symbolFor('react.strict_mode')
Profiler = symbolFor('react.profiler')
ContextProvider = symbolFor('react.provider')
ContextConsumer = symbolFor('react.context')
ConcurrentMode = Symbol.for('react.concurrent_mode')
ContextConsumer = symbolFor('react.consumer')
Context = symbolFor('react.context')
ConcurrentMode = symbolFor('react.concurrent_mode')
ForwardRef = symbolFor('react.forward_ref')
Suspense = symbolFor('react.suspense')
Memo = symbolFor('react.memo')
Lazy = symbolFor('react.lazy')
ClientReferenceTag = Symbol.for('react.client.reference')
ClientReferenceTag = symbolFor('react.client.reference')
}

/** Literal types representing the ReactSymbol values. These values do not actually match the values from react-is! */
export type ReactSymbol =
| 'react.element' /* 0xeac7 | Symbol(react.element) */
| 'react.transitional.element' /* 0xeac7 | Symbol(react.transitional.element) */
| 'react.portal' /* 0xeaca | Symbol(react.portal) */
| 'react.fragment' /* 0xeacb | Symbol(react.fragment) */
| 'react.strict_mode' /* 0xeacc | Symbol(react.strict_mode) */
| 'react.profiler' /* 0xead2 | Symbol(react.profiler) */
| 'react.provider' /* 0xeacd | Symbol(react.provider) */
| 'react.consumer' /* undefined | Symbol(react.consumer) */
| 'react.context' /* 0xeace | Symbol(react.context) */
| 'react.concurrent_mode' /* 0xeacf | Symbol(react.concurrent_mode) */
| 'react.forward_ref' /* 0xead0 | Symbol(react.forward_ref) */
Expand All @@ -49,12 +59,15 @@ export type ReactSymbol =
| 'react.lazy' /* 0xead4 | Symbol(react.lazy) */

export const REACT_ELEMENT_TYPE: 'react.element' = (Element: any)
export const REACT_TRANSITIONAL_ELEMENT_TYPE: 'react.transitional.element' =
(TransitionalElement: any)
export const REACT_PORTAL_TYPE: 'react.portal' = (Portal: any)
export const REACT_FRAGMENT_TYPE: 'react.fragment' = (Fragment: any)
export const REACT_STRICT_MODE_TYPE: 'react.strict_mode' = (StrictMode: any)
export const REACT_PROFILER_TYPE: 'react.profiler' = (Profiler: any)
export const REACT_PROVIDER_TYPE: 'react.provider' = (ContextProvider: any)
export const REACT_CONTEXT_TYPE: 'react.context' = (ContextConsumer: any)
export const REACT_CONSUMER_TYPE: 'react.consumer' = (ContextConsumer: any)
export const REACT_CONTEXT_TYPE: 'react.context' = (Context: any)
export const REACT_CONCURRENT_MODE_TYPE: 'react.concurrent_mode' =
(ConcurrentMode: any)
export const REACT_FORWARD_REF_TYPE: 'react.forward_ref' = (ForwardRef: any)
Expand Down
5 changes: 3 additions & 2 deletions src/types/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import {
REACT_FORWARD_REF_TYPE,
REACT_SUSPENSE_TYPE,
REACT_MEMO_TYPE,
REACT_LAZY_TYPE
REACT_LAZY_TYPE,
REACT_CONSUMER_TYPE
} from '../symbols'

export type AbstractContext = Context<mixed> & {
Expand All @@ -41,7 +42,7 @@ export type ConsumerElement = {
type:
| AbstractContext
| {
$$typeof: typeof REACT_CONTEXT_TYPE,
$$typeof: typeof REACT_CONSUMER_TYPE,
_context: AbstractContext
},
props: { children?: (value: mixed) => Node },
Expand Down
36 changes: 26 additions & 10 deletions src/visitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ import {

import {
REACT_ELEMENT_TYPE,
REACT_TRANSITIONAL_ELEMENT_TYPE,
REACT_PORTAL_TYPE,
REACT_FRAGMENT_TYPE,
REACT_STRICT_MODE_TYPE,
Expand All @@ -76,7 +77,8 @@ import {
REACT_FORWARD_REF_TYPE,
REACT_SUSPENSE_TYPE,
REACT_MEMO_TYPE,
REACT_LAZY_TYPE
REACT_LAZY_TYPE,
REACT_CONSUMER_TYPE
} from './symbols'

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

const ReactCurrentDispatcher =
REACT_INTERNALS && REACT_INTERNALS.ReactCurrentDispatcher
REACT_INTERNALS.ReactCurrentDispatcher || REACT_INTERNALS

const getReactCurrentDispatcher = () => {
return ReactCurrentDispatcher.current || ReactCurrentDispatcher.H
}

const injectReactCurrentDispatcher = (newDispatcher) => {
if (ReactCurrentDispatcher.current) {
ReactCurrentDispatcher.current = newDispatcher
} else {
ReactCurrentDispatcher.H = newDispatcher
}
}

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

return getChildrenArray(children)
}

case REACT_CONTEXT_TYPE: {
case REACT_CONSUMER_TYPE: {
const consumerElement = ((element: any): ConsumerElement)
const { children } = consumerElement.props

Expand Down Expand Up @@ -221,11 +237,11 @@ const visitLoop = (
visitor: Visitor,
clientRefVisitor: ClientReferenceVisitor
): boolean => {
const prevDispatcher = ReactCurrentDispatcher.current
const prevDispatcher = getReactCurrentDispatcher()
const start = Date.now()

try {
ReactCurrentDispatcher.current = Dispatcher
injectReactCurrentDispatcher(Dispatcher)
while (traversalChildren.length > 0) {
const element = traversalChildren[traversalChildren.length - 1].shift()
if (element !== undefined) {
Expand Down Expand Up @@ -254,7 +270,7 @@ const visitLoop = (
queue.unshift(errorFrame)
return false
} finally {
ReactCurrentDispatcher.current = prevDispatcher
injectReactCurrentDispatcher(prevDispatcher)
}
}

Expand Down Expand Up @@ -341,10 +357,10 @@ export const update = (
)
}
} else {
const prevDispatcher = ReactCurrentDispatcher.current
const prevDispatcher = getReactCurrentDispatcher()
let children = null

ReactCurrentDispatcher.current = Dispatcher
injectReactCurrentDispatcher(Dispatcher)

try {
if (frame.kind === 'frame.class') {
Expand All @@ -363,7 +379,7 @@ export const update = (
queue.unshift(errorFrame)
children = null
} finally {
ReactCurrentDispatcher.current = prevDispatcher
injectReactCurrentDispatcher(prevDispatcher)
}

visit(getChildrenArray(children), queue, visitor, clientRefVisitor)
Expand Down

0 comments on commit 35495d6

Please sign in to comment.