Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(react-v19): Properly support react v19 #3

Merged
merged 1 commit into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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