Commit Graph
19463 Commits
Author SHA1 Message Date
Lauren Tan 5cdfa7cdc4 [feedback] Don't skip copying dist 2023-11-01 13:45:50 -04:00
Lauren Tan c289d098d7 [babel] Rename useMemoCacheSource to enableUseMemoCachePolyfill 2023-11-01 13:28:18 -04:00
Lauren Tan 139336b87c [feedback] Specify react dep for react-forget-runtime 2023-11-01 13:12:09 -04:00
Lauren Tan 7042983f69 [feedback] Add changelog to build 2023-10-31 18:31:09 -04:00
Lauren Tan 8860faa65c [feedback] Add script to copy forget-feedback to new repo 2023-10-31 17:14:19 -04:00
Lauren Tan 776f2148b4 [feedback] More efficient userspace impl for uMC 2023-10-31 13:17:40 -04:00
Lauren Tan a0de8e6d2d [babel] Disable ts declaration maps
This was unnecessary, switching it back to disabled
2023-10-31 13:06:19 -04:00
Lauren Tan e4acd448f6 [feedback] Add script to bundle for oss 2023-10-31 12:42:39 -04:00
Lauren Tan 0a7bb7ac7a [babel] Clean up import logic a bit
Addressing feedback from #2218
2023-10-31 12:16:34 -04:00
Lauren Tan 847a6f0a09 [feedback] Make babel/types a dep not a peerDep 2023-10-31 12:16:33 -04:00
Lauren Tan 5ebc9fe388 [feedback] Add github action to run e2e test 2023-10-31 12:16:33 -04:00
Lauren Tan 3246dc641f [feedback] Add testapp with e2e test
Adds a toy next.js app which doesn't do anything interesting. It has a single 
e2e test which can be run via `npm run test:e2e`, which checks if a `$` variable 
was injected by the compiler, as a sanity check whenever we commit a new version 
of the compiler to the external repo.
2023-10-31 12:16:32 -04:00
Lauren Tan ac170f4f0d [babel] Allow userspace useMemoCache
Not every consumer of Forget will be able to run an experimental version of 
React. In the meantime before useMemoCache is stable, provide a way for OSS to 
pass in a userspace impl.
2023-10-31 12:16:31 -04:00
Mofei Zhang c7c57ec531 [playground] QoL use webpack to bundle monaco-editor's loader
--- 

This lets us load playground locally, entirely offline (e.g. on an airplane, 
when a cdn is down, at ReactAdvanced, etc) 

Before: 

See external script link 

<img width="691" alt="image" 
src="https://github.com/facebook/react-forget/assets/34200447/85500e86-c1a5-4dff-bdcd-58db0d6fd453"> 

Now: 

No external script 

<img width="476" alt="image" 
src="https://github.com/facebook/react-forget/assets/34200447/fdcbea09-0b5f-42e3-9310-35d8d1d726b7">
2023-10-30 14:53:00 -04:00
Mofei Zhang 16bef168c1 [playground] Move Editor/index for next PR (dynamic import) 2023-10-30 14:53:00 -04:00
Lauren Tan 0841caab8e [rollup] Include typescript definitions in build
Emit our TypeScript definitions as well in the build so things like options have 
typechecking
2023-10-30 13:58:03 -04:00
Lauren Tan 52afd8a566 [ext-preview] Inline @babel/generator
Turns out we were only using this in PrintHIR and in the logger, so it should be 
safe to inline and makes installing the plugin for external collaborators a 
little easier. 

I'm assuming inlining this is ok because we only need to defer to the host's 
Babel version(s) when it affects parsing or the final codegen output, hence why 
we continue to no-inline @babel/types – as it is responsible for creating AST 
nodes during codegen
2023-10-30 13:58:02 -04:00
Mofei Zhang e2836eec5b [bugfix] do not hoist computed memberpaths in lambdas 2023-10-30 12:56:50 -04:00
Mofei Zhang 3e812df89c [repro] Test case for more variable naming collision bugs
--- 

bug repro from @JacksonGL 

(we currently bailout for references to `useMemoCache`, but not other variables 
that may collide with codegenned ones). 

``` 

% yarn sprout --filter 

yarn run v1.22.19 

$ node ../sprout/dist/main.js --filter 

FAIL  todo 

Failures: 

FAIL: todo 

Difference in forget and non-forget results. 

Expected result: { 

"kind": "ok", 

"value": "0", 

"logs": [ 

"'module_$'", 

"'module_t0'", 

"'module_c_0'" 

] 

} 

Found: { 

"kind": "ok", 

"value": "0", 

"logs": [ 

"[ 0, 0 ]", 

"0", 

"true" 

] 

} 

```
2023-10-30 12:01:24 -04:00
Sathya Gunasekaran f648e4ce85 [test/react] Turn on react tests in CI 2023-10-25 12:39:20 +01:00
Sathya Gunasekaran 51baf5807e [test/react] Fix github workflow
The flattening broke the shell script because the directory structure changed. 

Instead of depending on a flaky shell script, this PR encodes the commands as 
part of the github workflow.
2023-10-25 12:36:55 +01:00
Lauren Tan 419310cd15 Bundle babel-plugin-react-forget with rollup
Attempt to bundle the plugin with rollup instead of just tsc. I'm intentionally 
not inlining babel related modules, as we should ideally rely on the host 
environment's version instead
2023-10-27 14:07:56 -04:00
Lauren Tan 473237ba1f Remove prettier from babel-plugin as dependency
We can now fully remove prettier from babel-plugin-react-forget. I moved it to 
devDependencies instead, to make the rollup build simpler and so we can continue 
to prettify our internal source code.
2023-10-27 14:07:56 -04:00
Lauren Tan c72673bd8f [fixtures] Run prettier after babel-plugin
This moves prettier formatting into fixture-test-utils instead, so we can remove 
the dependency on prettier in the babel plugin. I want to do this because I 
don't want to include prettier in the rolledup artifact when we build the babel 
plugin.
2023-10-27 14:07:55 -04:00
Andrew Clark b8e47d988e Bugfix: useFormState queues actions in wrong order (#27570)
I neglected to update the "last" pointer of the action queue. Since the
queue is circular, rather than dropping the update, the effect was to
add the update to the front of the queue instead of the back. I didn't
notice earlier because in my demos/tests, the actions would either
resolve really quickly or the actions weren't order dependent (like
incrementing a counter).
2023-10-23 17:52:15 -04:00
Sebastian Markbåge 05fbd1aab0 [Fizz] Postponing in the shell (#27569)
When we postpone a prerender in the shell, we should just leave an empty
prelude and resume from the root. While preserving any options passed
in.

Since we haven't flushed anything we can't assume we've already emitted
html/body tags or any resources tracked in the resumable state. This
introduces a resetResumableState function to reset anything we didn't
flush.

This is a bit hacky. Ideally, we probably shouldn't have tracked it as
already happened until it flushed or something like that.

Basically, it's like restarting the prerender with the same options and
then immediately aborting. When we add the preload headers, we'd track
those as preload() being emitted after the reset and so they get readded
to the resumable state in that case.
2023-10-23 15:53:59 -04:00
Andrew Clark 779d59374e useDeferredValue has higher priority than partial hydration (#27550)
By default, partial hydration is given the lowest possible priority,
because until a tree is updated, the server-rendered HTML is assumed to
match the final resolved HTML.

However, this isn't completely true because a component may choose to
"upgrade" itself upon hydration. The simplest example is a component
that calls setState in a useEffect to switch to a richer implementation
of the UI. Another example is a component that doesn't have a server-
rendered implementation, so it intentionally suspends to force a client-
only render.

useDeferredValue is an example, too: the server only renders the first
pass (the initialValue) argument, and relies on the client to upgrade to
the final value.

What we should really do in these cases is emit some information into
the Fizz stream so that Fiber knows to prioritize the hydration of
certain trees. We plan to add a mechanism for this in the future.

In the meantime, though, we can at least ensure that the priority of the
upgrade task is correct once it's "discovered" during hydration. In this
case, the priority of the task spawned by useDeferredValue should have
Transition priority, not Offscreen priority.
2023-10-23 13:48:48 -04:00
Sathya Gunasekaran ad1fe50546 [playground] Turn on Forget
Runs Forget on the playground, so we can dogfood Forget and experiment with 
improvements to UX. 

Opts out of compiling the layout page because thats run on the server which 
doesn't seem to have access to useMemoCache.
2023-10-23 15:41:01 +01:00
Sathya Gunasekaran 1138ef00e3 [playground] Force nextjs to use experimental react
These experimental features aren't used by the playground, but turning it on 
forces nextjs to use experimental react which has the useMemoCache hook.
2023-10-23 15:41:00 +01:00
Sathya Gunasekaran 48d465eb22 [playground] Upgrade to latest nextjs 2023-10-23 15:41:00 +01:00
Sathya Gunasekaran 23a226227f Remove use of prettier in babel-plugin-react-forget
This kept throwing warnings in our playground build because prettier uses node 
APIs and is not meant to be bundled and run on the browser. 

There's a separate standalone version that runs on the browser. A follow on PR 
will make the playground use that but this PR is a first step towards using a 
standalone prettier.
2023-10-25 15:40:31 +01:00
Andrew Clark 6db7f4209e Bugfix: useDeferredValue loop during popstate transition (#27559)
During a popstate event, we attempt to render updates synchronously even
if they are transitions, to preserve scroll position if possible. We do
this by entangling the transition lane with the Sync lane.

However, if rendering the transition spawns additional transition
updates (e.g. a setState inside useEffect), there's no reason to render
those synchronously, too. We should use the normal transition behavior.

This fixes an issue where useDeferredValue during a popstate event would
spawn a transition update that was itself also synchronous.
2023-10-21 12:11:25 -04:00
Josh Story 90172d12e8 [Flight] Cleanup turbopack tests (#27552)
Renames turbopack flight test files. removes tests which are primarily
testing internal implemenation behavior of Flight Client itself
2023-10-20 23:21:31 -07:00
Matt Carroll b9244f79ba Add initial canary changelog (#27504) 2023-10-20 19:11:07 -07:00
Jung Yujun 8c85b02996 [Fizz] Optimize end tags chunks (#27522)
Implements `endChunkForTag` to make writing end tags faster
2023-10-20 15:34:21 -07:00
Jan Kassens d803f519ea Upgrade to Flow 0.219.0 (#27542)
This upgrade made the `React$Element` type opaque, which is good for
product code where accessing props of elements is code smell, but React
needs to use that internally. I overrode the type to restore it.
2023-10-20 11:09:44 -04:00
Lauren Tan b049c14bb3 Repro of hoisting bug
Adds a test case reproducing an issue with hoisting. This seems like a case 
where hoisting was incorrectly applied as this example doesn't require it
2023-10-20 11:34:41 +01:00
Josh Story 3a1967b7d5 [Flight] Expose encodeReply from ReactFlightDOMClientEdge (#27551)
Adds encodeReply to ReactFlightDOMClientEdge in webpack and turbopack
bindings
2023-10-19 17:24:47 -07:00
Joe Savona f8cee28f1d Retain minimal variable declarations in DCE
Currently DCE can remove variable declarations that are unused, ie where all 
control-flow paths to usage of the variable are overwritten by a reassignment. 
We then have to reconstruct the original variable declaration at the appropriate 
block scope during LeaveSSA, which is complex and can actually be incorrect in 
some cases. 

This PR updates to ensure that DCE will not remove the original variable 
declaration for any variable that is used (even in the case of always being 
reassigned before use). The main changes are: 

* DCE retains variable declarations, but if a variable declaration is always 
shadowed by reassignments then DCE will rewrite StoreLocal -> DeclareLocal so 
that it can DCE the unused initial value. 

* BuildHIR now has to change its handling for reassignment destructure 
instructions with nesting. Nesting uses a temporary which would appear as a 
declaration of a new variable, which is incompatible with other reassignments. 
See comments in the file. 

* LeaveSSA is quite a bit simpler now, since we never need to reconstruct a 
declaration.
2023-10-19 22:08:15 +01:00
Sebastian Markbåge f172fa7461 [Flight] Detriplicate Objects (#27537)
Now that we no longer support Server Context, we can now deduplicate
objects. It's not completely safe for useId but only in the same way as
it's not safe if you reuse elements on the client, so it's not a new
issue.

This also solves cyclic object references.

The issue is that we prefer to inline objects into a plain JSON format
when an object is not going to get reused. In this case the object
doesn't have an id. We could potentially serialize a reference to an
existing model + a path to it but it bloats the format and complicates
the client.

In a smarter flush phase like we have in Fizz we could choose to inline
or outline depending on what we've discovered so far before a flush. We
can't do that here since we use native stringify. However, even in that
solution you might not know that you're going to discover the same
object later so it's not perfect deduping anyway.

Instead, I use a heuristic where I mark previously seen objects and if I
ever see that object again, then I'll outline it. The idea is that most
objects are just going to be emitted once and if it's more than once
it's fairly likely you have a shared reference to it somewhere and it
might be more than two.

The third object gets deduplicated (or "detriplicated").

It's not a perfect heuristic because when we write the second object we
will have already visited all the nested objects inside of it, which
causes us to outline every nested object too even those weren't
reference more than by that parent. Not sure how to solve for that.

If we for some other reason outline an object such as if it suspends,
then it's truly deduplicated since it already has an id.
2023-10-19 13:41:16 -04:00
Sebastian Markbåge 2eeb9f9226 [Flight Reply] Update error message (#27549)
This is in the reverse direction.
2023-10-19 13:40:24 -04:00
Andrey Lunyov b67ddaa434 [meta-only] Move ReactServerStreamConfigFB to react-server from react-server-dom-fb (#27544)
Code organization PR.

It looks like the `ReactServerStreamConfigFB` is only used in the
`relay-server` package. This PR moves it to `react-server` from
`react-server-dom-fb` (similar to how we have config for bun, for
example). This avoids cross-package imports from `react-server` to
`react-server-dom-fb.`
2023-10-19 12:35:41 -04:00
Josh Story 9617d39eca [Fizz] Add proper assertion for stream fix (#27543)
In https://github.com/facebook/react/pull/27541 I added tests to assert
that the write after close bug was fixed. However the Node
implementation has an abort behavior preventing reproduction of the
original issue and the Browser build does not use AsyncLocalStorage
which also prevents reproduction. This change moves the Browser test to
a Edge runtime where AsyncLocalStorage is polyfilled. In this
implementation the test does correctly fail when the patch is removed.
2023-10-18 12:01:09 -07:00
Josh Story 601e5c3850 [Fizz][Float] Do not write after closing the stream (#27541)
Float methods can hang on to a reference to a Request after the request
is closed due to AsyncLocalStorage. If a Float method is called at this
point we do not want to attempt to flush anything. This change updates
the closing logic to also call `stopFlowing` which will ensure that any
checks against the destination properly reflect that we cannot do any
writes. In addition it updates the enqueueFlush logic to existence check
the destination inside the work function since it can change across the
work scheduling gap if it is async.

fixes: https://github.com/facebook/react/issues/27540
2023-10-18 10:05:18 -07:00
Ruslan Lesiutin 20c91b6534 React DevTools 4.28.4 -> 4.28.5 (#27538)
Changes:
* fix[devtools/useMemoCache]: add stub for useMemoCache in
ReactDebugHook ([hoxyq](https://github.com/hoxyq) in
[#27472](https://github.com/facebook/react/pull/27472))
* useDeferredValue should skip initialValue if it suspends
([acdlite](https://github.com/acdlite) in
[#27509](https://github.com/facebook/react/pull/27509))
* feat[react-devtools-extensions/logging]: initialize session id on the
client for logging ([hoxyq](https://github.com/hoxyq) in
[#27517](https://github.com/facebook/react/pull/27517))
* refactor[react-devtools-extensions]: use globals to eliminate dead
code ([hoxyq](https://github.com/hoxyq) in
[#27516](https://github.com/facebook/react/pull/27516))
* fix[devtools/inspectElement]: dont pause initial inspectElement call
when user switches tabs ([hoxyq](https://github.com/hoxyq) in
[#27488](https://github.com/facebook/react/pull/27488))
2023-10-18 14:08:23 +01:00
Sebastian Markbåge e3748a0bde [Fizz] Pass cancellation reason to abort (#27536)
This was implemented correctly for Flight but not Fizz. Hard to keep
these many wrappers in sync.
2023-10-17 21:43:12 -04:00
Ruslan Lesiutin a419575077 fix[devtools/useMemoCache]: add stub for useMemoCache in ReactDebugHook (#27472)
Currently, we have this error in our logs of the internal version of
React DevTools:
```
TypeError: Cannot read properties of undefined (reading 'memoCache')
    at Proxy.useMemoCache (chrome-extension://dnjnjgbfilfphmojnmhliehogmojhclc/build/react_devtools_backend_compact.js:151:71)
```

Looking at the build files of the extension, it fails here:
https://github.com/facebook/react/blob/dddfe688206dafa5646550d351eb9a8e9c53654a/packages/react-debug-tools/src/ReactDebugHooks.js#L333-L337

Looks like `updateQueue` can be `undefined`, as it is not defined in
hook object here:
https://github.com/facebook/react/blob/dddfe688206dafa5646550d351eb9a8e9c53654a/packages/react-reconciler/src/ReactFiberHooks.js#L180-L186

~~Also, it looks like `useMemoCache` implementation doesn't expect this,
so it should also result into TypeError here, line 1114:~~

https://github.com/facebook/react/blob/dddfe688206dafa5646550d351eb9a8e9c53654a/packages/react-reconciler/src/ReactFiberHooks.js#L1108-L1115

~~Should this also be updated?~~
2023-10-17 18:39:10 +01:00
Andrew Clark 75c1bd7ee7 Prerendering support for useDeferredValue (#27512)
### Based on #27509 

Revealing a prerendered tree (hidden -> visible) is considered the same
as mounting a brand new tree. So, when an initialValue argument is
passed to useDeferredValue, and it's prerendered inside a hidden tree,
we should first prerender the initial value.

After the initial value has been prerendered, we switch to prerendering
the final one. This is the same sequence that we use when mounting new
visible tree. Depending on how much prerendering work has been finished
by the time the tree is revealed, we may or may not be able to skip all
the way to the final value.

This means we get the benefits of both prerendering and preview states:
if we have enough resources to prerender the whole thing, we do that. If
we don't, we have a preview state to show for immediate feedback.
2023-10-17 12:58:48 -04:00
Andrew Clark b2a68a65c8 useDeferredValue should skip initialValue if it suspends (#27509)
### Based on https://github.com/facebook/react/pull/27505

If a parent render spawns a deferred task with useDeferredValue, but the
parent render suspends, we should not wait for the parent render to
complete before attempting to render the final value.

The reason is that the initialValue argument to useDeferredValue is
meant to represent an immediate preview of the final UI. If we can't
render it "immediately", we might as well skip it and go straight to the
"real" value.

This is an improvement over how a userspace implementation of
useDeferredValue would work, because a userspace implementation would
have to wait for the parent task to commit (useEffect) before spawning
the deferred task, creating a waterfall.
2023-10-17 12:48:11 -04:00
Ruslan Lesiutin 9abf6fa31c feat[react-devtools-extensions/logging]: initialize session id on the client for logging (#27517)
This code is executed once React DevTools panels are mounted, basically
when user opens browser's DevTools. Based on this fact, session in this
case is defined by browser's DevTools session, while they are open. A
session can involve debugging multiple React pages. `crypto.randomUUID`
is used to generate random user id.

Corresponding logger config changes -
[D50267871](https://www.internalfb.com/diff/D50267871).
2023-10-17 15:23:53 +01:00