* 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
* Merged interaction-tracking package into react-scheduler
* Add tracking API to FB+www builds
* Added Rollup plugin to strip no-side-effect imports from Rollup bundles
* Re-bundle tracking and scheduling APIs on SECRET_INTERNALS object for UMD build (and provide lazy forwarding methods)
* Added some additional tests and fixtures
* Fixed broken UMD fixture in master (#13512)
* Updated suspense fixture to use new interaction-tracking API
* Integrated Profiler API with interaction-tracking API (and added tests)
* Pass interaction Set (rather than Array) to Profiler onRender callback
* Removed some :any casts for enableInteractionTracking fields in FiberRoot type
* Refactored threadID calculation into a helper method
* Errors thrown by interaction tracking hooks use unhandledError to rethrow more safely.
Reverted try/finally change to ReactTestRendererScheduling
* Added a $FlowFixMe above the FiberRoot :any cast
* Reduce overhead from calling work-started hook
* Remove interaction-tracking wrap() references from unwind work in favor of managing suspense/interaction continuations in the scheduler
* Moved the logic for calling work-started hook from performWorkOnRoot() to renderRoot()
* Add interaction-tracking to bundle externals. Set feature flag to __PROFILE__
* Renamed the freezeInteractionCount flag and replaced one use-case with a method param
* let -> const
* Updated suspense fixture to handle recent API changes
* Removed enableInteractionTrackingObserver as a separate flag; only enableInteractionTracking is used now
* Added interaction-tracking/subscriptions bundle and split tests
* Added multi-subscriber support
* Moved subscriptions behind feature flag
* Fixed bug with wrap() parameters and added test
* Replaced wrap arrow function
* Use local references to global things inside 'scheduler'
**what is the change?:**
See title
**why make this change?:**
We want to avoid initially calling one version of an API and then later
accessing a polyfilled version.
**test plan:**
Run existing tests.
* Shim ReactScheduler for www
**what is the change?:**
In 'www' we want to reference the separate build of ReactScheduler,
which allows treating it as a separate module internally.
**why make this change?:**
We need to require the ReactScheduler before our rAF polyfill activates,
in order to customize which custom behaviors we want.
This is also a step towards being able to experiment with using it
outside of React.
**test plan:**
Ran tests, ran the build, and ran `test-build`.
* Generate a bundle for fb-www
**what is the change?:**
See title
**why make this change?:**
Splitting out the 'schedule' module allows us to load it before
polyfills kick in for rAF and other APIs.
And long term we want to split this into a separate module anyway, this
is a step towards that.
**test plan:**
I'll run the sync next week and verify that this all works. :)
* ran prettier
* fix rebase issues
* Change names of variables used for holding globals
* Extract base Jest config
This makes it easier to change the source config without affecting the build test config.
* Statically import the host config
This changes react-reconciler to import HostConfig instead of getting it through a function argument.
Rather than start with packages like ReactDOM that want to inline it, I started with React Noop and ensured that *custom* renderers using react-reconciler package still work. To do this, I'm making HostConfig module in the reconciler look at a global variable by default (which, in case of the react-reconciler npm package, ends up being the host config argument in the top-level scope).
This is still very broken.
* Add scaffolding for importing an inlined renderer
* Fix the build
* ES exports for renderer methods
* ES modules for host configs
* Remove closures from the reconciler
* Check each renderer's config with Flow
* Fix uncovered Flow issue
We know nextHydratableInstance doesn't get mutated inside this function, but Flow doesn't so it thinks it may be null.
Help Flow.
* Prettier
* Get rid of enable*Reconciler flags
They are not as useful anymore because for almost all cases (except third party renderers) we *know* whether it supports mutation or persistence.
This refactoring means react-reconciler and react-reconciler/persistent third-party packages now ship the same thing.
Not ideal, but this seems worth how simpler the code becomes. We can later look into addressing it by having a single toggle instead.
* Prettier again
* Fix Flow config creation issue
* Fix imprecise Flow typing
* Revert accidental changes
This is the first step - pulling the ReactDOMFrameScheduling module out
into a separate package.
Co-authored-by: Brandon Dail <aweary@users.noreply.github.com>
* Added new "native-fb" and "native-fabric-fb" bundles.
* Split RN_DEV and RN_PROD bundle types into RN_OSS_DEV, RN_OSS_PROD, RN_FB_DEV, and RN_FB_PROD. (This is a bit redundant but it seemed the least intrusive way of supporting a forked feature flags file for these bundles.)
* Renamed FB_DEV and FB_PROD bundle types to be more explicitly for www (FB_WWW_DEV and FB_WWW_PROD)
* Removed Haste @providesModule headers from the RB-specific RN renderer bundles to avoid a duplicate name conflicts.
* Remove dynamic values from OSS RN feature flags. (Leave them in FB RN feature flags.)
* Updated the sync script(s) to account for new renderer type.
* Move ReactFeatureFlags.js shim to FB bundle only (since OSS bundle no longer needs dynamic values).
* Move view config registry to shims
This ensures that both Fabric and RN renderers share the same view config
registry since it is stateful.
I had to duplicate in the mocks for testing.
* Move createReactNativeComponentClass to shims and delete internal usage
Since createReactNativeComponentClass is just an alias for the register
there's no need to bundle it. This file should probably just move back
to RN too.
* [experimental] simple-cache-provider
Pushing an early version of this for testing and demonstration purposes.
* Change invariant to DEV-only warning
* Use function overloading for createResource type
Expresses that primitive keys do not require a hash function, but
non-primitive keys do.
* More tests
* Use export *
* Make Record type a disjoint union
* Pass miss argument separate from key to avoid a closure
* Unify the way we fork modules
* Replace rollup-plugin-alias with our own plugin
This does exactly what we need and doesn't suffer from https://github.com/rollup/rollup-plugin-alias/issues/34.
* Move the new plugin to its own file
* Rename variable for consistency
I settled on calling them "forks" since we already have a different concept of "shims".
* Move fork config into its own file
* Move ReactFiberTreeReflection to react-reconciler/reflection #11659
* Use * for react-reconciler
We don't know the latest local version, and release script currently doesn't bump deps automatically.
* Remove unused field
* Use CommonJS in entry point for consistency
* Undo the CommonJS change
I didn't realize it would break the build.
* Record sizes
* Remove reconciler fixtures
They're unnecessary now that we run real tests on reconciler bundles.
* Extract Jest config into a separate file
* Refactor Jest scripts directory structure
Introduces a more consistent naming scheme.
* Add yarn test-bundles and yarn test-prod-bundles
Only files ending with -test.public.js are opted in (so far we don't have any).
* Fix error decoding for production bundles
GCC seems to remove `new` from `new Error()` which broke our proxy.
* Build production version of react-noop-renderer
This lets us test more bundles.
* Switch to blacklist (exclude .private.js tests)
* Rename tests that are currently broken against bundles to *-test.internal.js
Some of these are using private APIs. Some have other issues.
* Add bundle tests to CI
* Split private and public ReactJSXElementValidator tests
* Remove internal deps from ReactServerRendering-test and make it public
* Only run tests directly in __tests__
This lets us share code between test files by placing them in __tests__/utils.
* Remove ExecutionEnvironment dependency from DOMServerIntegrationTest
It's not necessary since Stack.
* Split up ReactDOMServerIntegration into test suite and utilities
This enables us to further split it down. Good both for parallelization and extracting public parts.
* Split Fragment tests from other DOMServerIntegration tests
This enables them to opt other DOMServerIntegration tests into bundle testing.
* Split ReactDOMServerIntegration into different test files
It was way too slow to run all these in sequence.
* Don't reset the cache twice in DOMServerIntegration tests
We used to do this to simulate testing separate bundles.
But now we actually *do* test bundles. So there is no need for this, as it makes tests slower.
* Rename test-bundles* commands to test-build*
Also add test-prod-build as alias for test-build-prod because I keep messing them up.
* Use regenerator polyfill for react-noop
This fixes other issues and finally lets us run ReactNoop tests against a prod bundle.
* Run most Incremental tests against bundles
Now that GCC generator issue is fixed, we can do this.
I split ErrorLogging test separately because it does mocking. Other error handling tests don't need it.
* Update sizes
* Fix ReactMount test
* Enable ReactDOMComponent test
* Fix a warning issue uncovered by flat bundle testing
With flat bundles, we couldn't produce a good warning for <div onclick={}> on SSR
because it doesn't use the event system. However the issue was not visible in normal
Jest runs because the event plugins have been injected by the time the test ran.
To solve this, I am explicitly passing whether event system is available as an argument
to the hook. This makes the behavior consistent between source and bundle tests. Then
I change the tests to document the actual logic and _attempt_ to show a nice message
(e.g. we know for sure `onclick` is a bad event but we don't know the right name for it
on the server so we just say a generic message about camelCase naming convention).
* Forked ReactFeatureFlags for React Native to enable debugRenderPhaseSideEffects GK
* Changed debugRenderPhaseSideEffects in www feature flags to be runtime as well
* Implement CS first take
This is using a pure JS API. This should probably switch to native hooks
at some later point but I'll start ironing out issues at this level first.
* Use async scheduling by default
The scheduled callback gets called immediately in render with infinite
time for now. Later this will be per root and abortable.
* Fix up the type signature of the ReactNativeCSType export
* Add escape hatch for special cased children
Working around the fact that we can't map arbitrary children slots. Just
the "children" prop.
* Readd providesModule for ReactNativeCSTypes
* Fix lint
* Fix ReactNativeTypes providesModule and CI check
* Special case a parent instance that doesn't have a props object
CSCustom can be anything here. Ugly but whatevs.
* Don't forget to store stateUpdater so that we can trigger updates
* Fix test
* Update Jest
* Remove hacks for Jest + Workspace integration
They were fixed by https://github.com/facebook/jest/pull/4761.
* Use relative requires in tests relying on private APIs
I changed them to absolute to work around a Jest bug.
The bug has been fixed so I can revert my past changes now.
* Use relative paths in packages/react
* Use relative paths in packages/react-art
* Use relative paths in packages/react-cs
* Use relative paths in other packages
* Fix as many issues as I can
This uncovered an interesting problem where ./b from package/src/a would resolve to a different instantiation of package/src/b in Jest.
Either this is a showstopper or we can solve it by completely fobbidding remaining /src/.
* Fix all tests
It seems we can't use relative requires in tests anymore. Otherwise Jest becomes confused between real file and symlink.
https://github.com/facebook/jest/issues/3830
This seems bad... Except that we already *don't* want people to create tests that import individual source files.
All existing cases of us doing so are actually TODOs waiting to be fixed.
So perhaps this requirement isn't too bad because it makes bad code looks bad.
Of course, if we go with this, we'll have to lint against relative requires in tests.
It also makes moving things more painful.
* Prettier
* Remove @providesModule
* Fix remaining Haste imports I missed earlier
* Fix up paths to reflect new flat structure
* Fix Flow
* Fix CJS and UMD builds
* Fix FB bundles
* Fix RN bundles
* Prettier
* Fix lint
* Fix warning printing and error codes
* Fix buggy return
* Fix lint and Flow
* Use Yarn on CI
* Unbreak Jest
* Fix lint
* Fix aliased originals getting included in DEV
Shouldn't affect correctness (they were ignored) but fixes DEV size regression.
* Record sizes
* Fix weird version in package.json
* Tweak bundle labels
* Get rid of output option by introducing react-dom/server.node
* Reconciler should depend on prop-types
* Update sizes last time
* react-dom/src/syntheticEvents => events, and put plugins into it
* Flatten react-dom/src/shared
* Split react-dom/src/client/utils into event/ and root client folder
Makes it clearer what is used by what.
* Strictly separate modules that can be imported by client and server
* Move files and tests to more meaningful places
* Fix the build
Now that we import reconciler via react-reconciler, I needed to make a few tweaks.
* Update sizes
* Move @preventMunge directive to FB header
* Revert unintentional change
* Fix Flow coverage
I forgot to @flow-ify those files. This uncovered some issues.
* Prettier, I love you but you're bringing me down
Prettier, I love you but you're bringing me down
Like a rat in a cage
Pulling minimum wage
Prettier, I love you but you're bringing me down
Prettier, you're safer and you're wasting my time
Our records all show you were filthy but fine
But they shuttered your stores
When you opened the doors
To the cops who were bored once they'd run out of crime
Prettier, you're perfect, oh, please don't change a thing
Your mild billionaire mayor's now convinced he's a king
So the boring collect
I mean all disrespect
In the neighborhood bars I'd once dreamt I would drink
Prettier, I love you but you're freaking me out
There's a ton of the twist but we're fresh out of shout
Like a death in the hall
That you hear through your wall
Prettier, I love you but you're freaking me out
Prettier, I love you but you're bringing me down
Prettier, I love you but you're bringing me down
Like a death of the heart
Jesus, where do I start?
But you're still the one pool where I'd happily drown
And oh! Take me off your mailing list
For kids who think it still exists
Yes, for those who think it still exists
Maybe I'm wrong and maybe you're right
Maybe I'm wrong and maybe you're right
Maybe you're right, maybe I'm wrong
And just maybe you're right
And oh! Maybe mother told you true
And there'll always be somebody there for you
And you'll never be alone
But maybe she's wrong and maybe I'm right
And just maybe she's wrong
Maybe she's wrong and maybe I'm right
And if so, here's this song!
* Include component stack in more places, including SSR
* Forbid including reconciler code into the server bundle
* Tighten up the Flow annotation
* Fix lint
* Gosh Prettier
* Only renderers should depend on reconciler code
* Remove react-art dependency on react-dom modules
They share ReactDOMFrameScheduling so I moved it to shared.
* Update build size
* [CS] Clone container instead of new root concept
The extra "root" concept is kind of unnecessary. Instead of having a
mutable container even in the persistent mode, I'll instead make the
container be immutable too and be cloned. Then the "commit" just becomes
swapping the previous container for the new one.
* Change the signature or persistence again
We may need to clone without any updates, e.g. when the children are changed.
Passing in the previous node is not enough to recycle since it won't have the
up-to-date props and children. It's really only useful to for allocation pooling.
* Implement persistent updates
This forks the update path for host fibers. For mutation mode we mark
them as having an effect. For persistence mode, we clone the stateNode with
new props/children.
Next I'll do HostRoot and HostPortal.
* Refine protocol into a complete and commit phase
finalizeContainerChildren will get called at the complete phase.
replaceContainer will get called at commit.
Also, drop the keepChildren flag. We'll never keep children as we'll never
update a container if none of the children has changed.
* Implement persistent updates of roots and portals
These are both "containers". Normally we rely on placement/deletion effects
to deal with insertions into the containers. In the persistent mode we need
to clone the container and append all the changed children to it.
I needed somewhere to store these new containers before they're committed
so I added another field.
* Commit persistent work at the end by swapping out the container
* Unify cloneOrRecycle
Originally I tried to make the recyclable instance nullable but Flow didn't
like that and it's kind of sketchy since the instance type might not be
nullable.
However, the real difference which one we call is depending on whether they
are equal. We can just offload that to the renderer. Most of them won't
need to know about this at all since they'll always clone or just create
new.
The ones that do know now have to be careful to compare them so they don't
reuse an existing instance but that's probably fine to simplify the
implementation and API.
* Add persistent noop renderer for testing
* Add basic persistent tree test
* Test bail out
This adds a test for bailouts. This revealed a subtle bug. We don't set the
return pointer when stepping into newly created fibers because there
can only be one. However, since I'm reusing this mechanism for persistent
updates, I'll need to set the return pointer because a bailed out tree
won't have the right return pointer.
* Test persistent text nodes
Found another bug.
* Add persistent portal test
This creates a bit of an unfortunate feature testing in the unmount
branch.
That's because we want to trigger nested host deletions in portals in the
mutation mode.
* Don't consider container when determining portal identity
Basically, we can't use the container to determine if we should keep
identity and update an existing portal instead of recreate it. Because
for persistent containers, there is no permanent identity.
This makes it kind of strange to even use portals in this mode. It's
probably more ideal to have another concept that has permanent identity
rather than trying to swap out containers.
* Clear portals when the portal is deleted
When a portal gets deleted we need to create a new empty container and
replace the current one with the empty one.
* Add renderer mode flags for dead code elimination
* Simplify ReactNoop fix
* Add new type to the host config for persistent configs
We need container to stay as the persistent identity of the root atom.
So that we can refer to portals over time.
Instead, I'll introduce a new type just to temporarily hold the children
of a container until they're ready to be committed into the permanent
container. Essentially, this is just a fancy array that is not an array
so that the host can choose data structure/allocation for it.
* Implement new hooks
Now containers are singletons and instead their children swap. That way
portals can use the container as part of their identity again.
* Update build size and error codes
* Address comment
* Move new files to new location
* Enable Yarn workspaces for packages/*
* Move src/isomorphic/* into packages/react/src/*
* Create index.js stubs for all packages in packages/*
This makes the test pass again, but breaks the build because npm/ folders aren't used yet.
I'm not sure if we'll keep this structure--I'll just keep working and fix the build after it settles down.
* Put FB entry point for react-dom into packages/*
* Move src/renderers/testing/* into packages/react-test-renderer/src/*
Note that this is currently broken because Jest ignores node_modules,
and so Yarn linking makes Jest skip React source when transforming.
* Remove src/node_modules
It is now unnecessary. Some tests fail though.
* Add a hacky workaround for Jest/Workspaces issue
Jest sees node_modules and thinks it's third party code.
This is a hacky way to teach Jest to still transform anything in node_modules/react*
if it resolves outside of node_modules (such as to our packages/*) folder.
I'm not very happy with this and we should revisit.
* Add a fake react-native package
* Move src/renderers/art/* into packages/react-art/src/*
* Move src/renderers/noop/* into packages/react-noop-renderer/src/*
* Move src/renderers/dom/* into packages/react-dom/src/*
* Move src/renderers/shared/fiber/* into packages/react-reconciler/src/*
* Move DOM/reconciler tests I previously forgot to move
* Move src/renderers/native-*/* into packages/react-native-*/src/*
* Move shared code into packages/shared
It's not super clear how to organize this properly yet.
* Add back files that somehow got lost
* Fix the build
* Prettier
* Add missing license headers
* Fix an issue that caused mocks to get included into build
* Update other references to src/
* Re-run Prettier
* Fix lint
* Fix weird Flow violation
I didn't change this file but Flow started complaining.
Caleb said this annotation was unnecessarily using $Abstract though so I removed it.
* Update sizes
* Fix stats script
* Fix packaging fixtures
Use file: instead of NODE_PATH since NODE_PATH.
NODE_PATH trick only worked because we had no react/react-dom in root node_modules, but now we do.
file: dependency only works as I expect in Yarn, so I moved the packaging fixtures to use Yarn and committed lockfiles.
Verified that the page shows up.
* Fix art fixture
* Fix reconciler fixture
* Fix SSR fixture
* Rename native packages