* Lazily initialize models as they're read intead of eagerly when received
This ensures that we don't spend CPU cycles processing models that we're
not going to end up rendering.
This model will also allow us to suspend during this initialization if
data is not yet available to satisfy the model.
* Refactoring carefully to ensure bundles still compile to something optimal
* Remove generic from Response
The root model needs to be cast at one point or another same as othe
chunks. So we can parameterize the read instead of the whole Response.
* Read roots from the 0 key of the map
The special case to read the root isn't worth the field and code.
* Store response on each Chunk
Instead of storing it on the data tuple which is kind of dynamic, we store
it on each Chunk. This uses more memory. Especially compared to just making
initializeBlock a closure, but overall is simpler.
* Rename private fields to underscores
Response objects are exposed.
* Encode server components as delayed references
This allows us to stream in server components one after another over the
wire. It also allows parallelizing their fetches and resuming only the
server component instead of the whole parent block.
This doesn't yet allow us to suspend deeper while waiting on this content
because we don't have "lazy elements".
* Eject CRA from Flight
We need to eject because we're going to add a custom Webpack Plugin.
We can undo this once the plugin has upstreamed into CRA.
* Add Webpack plugin build
I call this entry point "webpack-plugin" instead of "plugin" even though
this is a webpack specific package. That's because there will also be a
Node.js plugin to do the server transform.
* Add Flight Webpack plugin to fixture
* Rm UMD builds
* Transform classes
* Rename webpack-plugin to plugin
This avoids the double webpack name. We're going to reuse this for both
server and client.
* Enable prefer-const rule
Stylistically I don't like this but Closure Compiler takes advantage of
this information.
* Auto-fix lints
* Manually fix the remaining callsites
This is equivalent to the jsx-runtime in that this is what the compiled
output on the server is supposed to target.
It's really just the same code for all the different Flights, but they
have different types in their arguments so each one gets their own entry
point. We might use this to add runtime warnings per entry point.
Unlike the client-side React.block call this doesn't provide the factory
function that curries the load function. The compiler is expected to wrap
this call in the currying factory.
* Formalize the Wakeable and Thenable types
We use two subsets of Promises throughout React APIs. This introduces
the smallest subset - Wakeable. It's the thing that you can throw to
suspend. It's something that can ping.
I also use a shared type for Thenable in the cases where we expect a value
so we can be a bit more rigid with our us of them.
* Make Chunks into Wakeables instead of using native Promises
This value is just going from here to React so we can keep it a lighter
abstraction throughout.
* Renamed thenable to wakeable in variable names
Originally the idea was to hide all suspending behind getters or proxies.
However, this has some issues with perf on hot code like React elements.
It also makes it too easy to accidentally access it the first time in an
effect or callback where things aren't allowed to suspend. Making it
an explicit method call avoids this issue.
All other suspending has moved to explicit lazy blocks (and soon elements).
The only thing remaining is the root. We could require the root to be an
element or block but that creates an unfortunate indirection unnecessarily.
Instead, I expose a readRoot method on the response. Typically we try to
avoid virtual dispatch but in this case, it's meant that you build
abstractions on top of a Flight response so passing it a round is useful.
* Resolve Server-side Blocks instead of Components
React elements should no longer be used to extract arbitrary data but only
for prerendering trees.
Blocks are used to create asynchronous behavior.
* Resolve Blocks in the Client
* Tests
* Bug fix relay JSON traversal
It's supposed to pass the original object and not the new one.
* Lint
* Move Noop Module Test Helpers to top level entry points
This module has shared state. It needs to be external from builds.
This lets us test the built versions of the Noop renderer.
Follow ups from https://github.com/facebook/react/pull/18334
I also introduced the concept of a module reference on the client too.
We don't need this for webpack so that gets compiled out but we need it
for www. Similarly I also need a difference between preload and load.
This replaces the HTML renderer with instead resolving host elements into
arrays tagged with the react.element symbol. These turn into proper
React Elements on the client.
The symbol is encoded as the magical value "$". This has security implications
so this special value needs to remain escaped for other strings.
We could just encode the element as {$$typeof: "$", key: key props: props}
but that's a lot more bytes. So instead I encode it as:
["$", key, props] and then convert it back.
It would be nicer if React's reconciler could just accept these tuples.
* Add ReactFlightServerConfig intermediate
This just forwards to the stream version of Flight which is itself forked
between Node and W3C streams.
The dom-relay goes directly to the Relay config though which allows it to
avoid the stream part of Flight.
* Separate streaming protocol into the Stream config
* Split streaming parts into the ReactFlightServerConfigStream
This decouples it so that the Relay implementation doesn't have to encode
the JSON to strings. Instead it can be fed the values as JSON objects and
do its own encoding.
* Split FlightClient into a basic part and a stream part
Same split as the server.
* Expose lower level async hooks to Relay
This requires an external helper file that we'll wire up internally.
* Rename to clarify that it's client-only
* Rename FizzStreamer to FizzServer for consistency
* Rename react-flight to react-client/flight
For consistency with react-server. Currently this just includes flight
but it could be expanded to include the whole reconciler.
* Add Relay Flight Build
* Rename ReactServerHostConfig to ReactServerStreamConfig
This will be the config specifically for streaming purposes.
There will be other configs for other purposes.
* Require deep for reconcilers
* Delete inline* files
* Delete react-reconciler/persistent
This no longer makes any sense because it react-reconciler takes
supportsMutation or supportsPersistence as options. It's no longer based
on feature flags.
* Fix jest mocking
* Fix Flow strategy
We now explicitly list which paths we want to be checked by a renderer.
For every other renderer config we ignore those paths.
Nothing is "any" typed. So if some transitive dependency isn't reachable
it won't be accidentally "any" that leaks.
* Move remaining things to named exports
The interesting case here is the noop renderers. The wrappers around the
reconciler now changed to use a local export that gets mutated.
ReactNoop and ReactNoopPersistent now have to destructure the object to
list out the names it's going to export. We should probably refactor
ReactNoop away from createReactNoop. Especially since it's also not Flow
typed.
* Switch interactions to star exports
This will have esModule compatibility flag on them. They should ideally
export default instead.
* Move Flight DOM to Webpack Specific Packagee
We'll have Webpack specific coupling so we need to ensure that it can be
versioned separately from various Webpack versions. We'll also have builds
for other bundlers in the future.
* Move to peerDep
* Move DOM Flight Tests
* Merge ReactFlightIntegration into ReactFlightDOM
This was an integration test. We can add to it.
* Fix fixture paths