* BUG: ReactPartialRenderer / New Context polutes mutable global state
The new context API stores the provided values on the shared context instance. When used in a synchronous context, this is not an issue. However when used in an concurrent context this can cause a "push provider" from one react render to have an effect on an unrelated concurrent react render.
I've encountered this bug in production when using renderToNodeStream, which asks ReactPartialRenderer for bytes up to a high water mark before yielding. If two Node Streams are created and read from in parallel, the state of one can polute the other.
I wrote a failing test to illustrate the conditions under which this happens.
I'm also concerned that the experimental concurrent/async React rendering on the client could suffer from the same issue.
* Use unique thread ID for each partial render to access Context
This first adds an allocator that keeps track of a unique ThreadID index
for each currently executing partial renderer. IDs are not just growing
but are reused as streams are destroyed.
This ensures that IDs are kept nice and compact.
This lets us use an "array" for each Context object to store the current
values. The look up for these are fast because they're just looking up
an offset in a tightly packed "array".
I don't use an actual Array object to store the values. Instead, I rely
on that VMs (notably V8) treat storage of numeric index property access
as a separate "elements" allocation.
This lets us avoid an extra indirection.
However, we must ensure that these arrays are not holey to preserve this
feature.
To do that I store the _threadCount on each context (effectively it takes
the place of the .length property on an array).
This lets us first validate that the context has enough slots before we
access the slot. If not, we fill in the slots with the default value.
* Parse build script type and package names
This ensures that `yarn build core dom` includes DOM.
It also ensures that spaces like `yarn build "core, dom"` doesn't build EVERYTHING.
* Get rid of label in bundles config
Instead we just use the name from entry using fuzzy search.
There is one special case. If you put in `/index` or `/index.js`.
That allows to build things like `react/index` to only build isomorphic
where as `react` would build everything. Or `react-dom/index` to exclude
the server renderers.
* Instead of matching `/index.js` just append it to the search string
That way things like `yarn build react/` works too.
* Add debug tools package
* Add basic implementation
* Implement inspection of the current state of hooks using the fiber tree
* Support useContext hooks inspection by backtracking from the Fiber
I'm not sure this is safe because the return fibers may not be current
but close enough and it's fast.
We use this to set up the current values of the providers.
* rm copypasta
* Use lastIndexOf
Just in case. I don't know of any scenario where this can happen.
* Support ForwardRef
* Add test for memo and custom hooks
* Support defaultProps resolution
* [react-cache] Remove `cache` as argument to `read`
Updated is API is `Resource.read(key)` instead of
`Resource.read(cache, key)`.
The cache is read from context using `readContext`.
This also removes cache invalidation entirely (other than the default
LRU mechanism), as well as the ability to have multiple caches. We'll
add it back once `Context.write` lands and we can implement it the
right way.
Since there's now only a single cache (the global one), we don't
actually need to use context yet, but I've added a dummy context
anyway so the user gets an error if they attempt to read outside the
render phase.
* nits
* Add test for thenables that resolve multiple times
* Jest + test renderer helpers for concurrent mode
Most of our concurrent React tests use the noop renderer. But most
of those tests don't test the renderer API, and could instead be
written with the test renderer. We should switch to using the test
renderer whenever possible, because that's what we expect product devs
and library authors to do. If test renderer is sufficient for writing
most React core tests, it should be sufficient for others, too. (The
converse isn't true but we should aim to dogfood test renderer as much
as possible.)
This PR adds a new package, jest-react (thanks @cpojer). I've moved
our existing Jest matchers into that package and added some new ones.
I'm not expecting to figure out the final API in this PR. My goal is
to land something good enough that we can start dogfooding in www.
TODO: Continue migrating Suspense tests, decide on better API names
* Add additional invariants to prevent common errors
- Errors if user attempts to flush when log of yields is not empty
- Throws if argument passed to toClearYields is not ReactTestRenderer
* Better method names
- toFlushAll -> toFlushAndYield
- toFlushAndYieldThrough ->
- toClearYields -> toHaveYielded
Also added toFlushWithoutYielding
* Fix jest-react exports
* Tweak README
* Added UMD_PROFILING type to react-dom and scheduling package. Added UMD shim to schedule package.
* Added new schedule umd prod+prof bundle to API test
* 🔥 Stop syncing the value attribute on inputs
* Eliminate some additional checks
* Remove initialValue and initialWrapper from wrapperState flow type
* Update tests with new sync logic, reduce some operations
* Update tests, add some caveats for SSR mismatches
* Revert newline change
* Remove unused type
* Call toString to safely type string values
* Add disableInputAttributeSyncing feature flag
Reverts tests to original state, adds attribute sync feature flag,
then moves all affected tests to ReactFire-test.js.
* Revert position of types in toStringValues
* Invert flag on number input blur
* Add clarification why double blur is necessary
* Update ReactFire number cases to be more explicite about blur
* Move comments to reduce diff size
* Add comments to clarify behavior in each branch
* There is no need to assign a different checked behavior in Fire
* Use checked reference
* Format
* Avoid precomputing stringable values
* Revert getToStringValue comment
* Revert placement of undefined in getToStringValue
* Do not eagerly stringify value
* Unify Fire test cases with normal ones
* Revert toString change. Only assign unsynced values when not nully
* Remove injectComponentTree from unstable-native-dependencies, add
EventPluginHub
injectComponentTree was exposed for react-native-web, but wasn't
actually being used by the project. They were using EventPluginHub
through ReactDOM's secret internals, but that was removed in https://github.com/facebook/react/pull/13539
This removes the unused injectComponentTree export, refactors the
ResponderEventPlugin test so it doesn't depend on it, and also adds
EventPluginHub to the exports to unbreak react-native-web
* Re-export injectEventPluginsByName from ReactDOM internals