This reverts commit faa1e127f1ba755da846bc6ce299cdefaf97721f.
* Support nesting of startTransition and flushSync
* Unset transition before entering any special execution contexts
Co-authored-by: Andrew Clark <git@andrewclark.io>
Typically we don't need to restore the context here because we assume that
we'll terminate the rest of the subtree so we don't need the correct
context since we're not rendering any siblings.
However, after a nested suspense boundary we need to restore the context.
The boundary could do this but since we're already doing this in the
suspense branch of renderNode, we might as well do it in the error case
which isn't very perf sensitive anyway.
The outermost `batchedUpdates` call flushes pending sync updates at the
end. This was intended for legacy sync mode, but it also happens to
flush discrete updates in concurrent mode.
Instead, we should only flush sync updates at the end of
`batchedUpdates` for legacy roots. Discrete sync updates can wait to
flush in the microtask.
`discreteUpdates` has the same issue, which is how I originally noticed
this, but I'll change that one in a separate commit since it requires
updating a few (no longer relevant) internal tests.
We don't need this anymore because we flush in a microtask.
This should allow us to remove the logic in the event system that
tracks nested event dispatches.
I added a test to confirm that nested event dispatches don't triggger
a synchronous flush, like they would if we wrapped them `flushSync`. It
already passed; I added it to prevent a regression.
This may not be the first root element if the root is a fragment and the
second one unsuspends first. But this tag doesn't work well for root
fragments anyway.
* Fix reentrancy bug
* Fix another reentrancy bug
There's also an issue if we try to schedule something to be client
rendered if its fallback hasn't rendered yet. So we don't do it
in that case.
* Add NewContext module
This implements a reverse linked list tree containing the previous
contexts.
* Implement recursive algorithm
This algorithm pops the contexts back to a shared ancestor on the way down
the stack and then pushes new contexts in reverse order up the stack.
* Move isPrimaryRenderer to ServerFormatConfig
This is primarily intended to be used to support renderToString with a
separate build than the main one. This allows them to be nested.
* Wire up more element type matchers
* Wire up Context Provider type
* Wire up Context Consumer
* Test
* Implement reader in class
* Update error codez
* Remove redundant initial of isArray (#21163)
* Reapply prettier
* Type the isArray function with refinement support
This ensures that an argument gets refined just like it does if isArray is
used directly.
I'm not sure how to express with just a direct reference so I added a
function wrapper and confirmed that this does get inlined properly by
closure compiler.
* A few more
* Rename unit test to internal
This is not testing a bundle.
Co-authored-by: Behnam Mohammadi <itten@live.com>
* Implement DOM format config structure
* Styles
* Input warnings
* Textarea special cases
* Select special cases
* Option special cases
We read the currently selected value from the FormatContext.
* Warning for non-lower case HTML
We don't change to lower case at runtime anymore but keep the warning.
* Pre tags innerHTML needs to be prefixed
This is because if you do the equivalent on the client using innerHTML,
this is the effect you'd get.
* Extract errors
* Support nesting of startTransition and flushSync
* Unset transition before entering any special execution contexts
Co-authored-by: Andrew Clark <git@andrewclark.io>
The sync task queue is React-specific and doesn't really have anything
to do with Scheduler. We'd keep using it even once `postTask` exists.
By separating that part out, `SchedulerWithReactIntegration` is now
just a module that re-exports the Scheduler API. So I unforked it.
When we switch to ES Modules, we can remove this re-exporting module.
* Bump version number
* Remove Scheduler indirection
I originally kept the React PriorityLevel and Scheduler PriorityLevel
types separate in case there was a versioning mismatch between the two
modules. However, it looks like we're going to keep the Scheduler module
private in the short to medium term, and longer term the public
interface will match postTask. So, I've removed the extra indirection
(the switch statements that convert between the two types).
* Encode tables as a special insertion mode
The table modes are special in that its children can't be created outside
a table context so we need the segment container to be wrapped in a table.
* Move formatContext from Task to Segment
It works the same otherwise. It's just that this context needs to outlive
the task so that I can use it when writing the segment.
* Use template tag for placeholders and inserted dummy nodes with IDs
These can be used in any parent. At least outside IE11. Not sure yet what
happens in IE11 to these.
Not sure if these are bad for perf since they're special nodes.
* Add special wrappers around inserted segments depending on their insertion mode
* Allow the root namespace to be configured
This allows us to insert the correct wrappers when streaming into an
existing non-HTML tree.
* Add comment
This flag was meant to avoid flushing discrete updates unnecessarily,
if multiple discrete events were dispatched in response to the same
platform event.
But since we now flush all discrete events at the end of the task, in
a microtask, it no longer has any effect.
* Add format context
* Let the Work node hold all working state for the recursive loop
Stacks are nice and all but there's a cost to maintaining each frame
both in terms of stack size usage and writing to it.
* Move current format context into work
* Synchronously render children of a Suspense boundary
We don't have to spawn work and snapshot the context. Instead we can try
to render the boundary immediately in case it works.
* Lazily create the fallback work
Instead of eagerly create the fallback work and then immediately abort it.
We can just avoid creating it if we finish synchronously.
Instead of LanePriority. Internally, EventPriority is just a lane, so
this skips an extra conversion. Since EventPriority is a "public" (to
the host config) type, I was also able to remove some deep imports
of the Lane module.
This gets us most of the way to deleting the LanePriority entirely.