Skip to content

syncing with main #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
d8089f2
[Flight Reply] Encode FormData (#26663)
sebmarkbage Apr 18, 2023
96fd2fb
(patch)[DevTools] bug fix: backend injection logic not working for un…
mondaychen Apr 19, 2023
c6db19f
[Flight] Serialize Date (#26622)
sophiebits Apr 19, 2023
a227bcd
chore[devtools/release-scripts]: update messages / fixed npm view com…
hoxyq Apr 19, 2023
b90e8eb
cleanup[devtools]: remove named hooks & profiler changed hook indices…
hoxyq Apr 19, 2023
1f248bd
Switching checked to null should leave the current value (#26667)
sebmarkbage Apr 19, 2023
6d394e3
[actions] commit from special branches iff they exist (#26673)
kassens Apr 19, 2023
cd2b79d
Initial (client-only) async actions support (#26621)
acdlite Apr 19, 2023
c826dc5
Add (Client) Functions as Form Actions (#26674)
sebmarkbage Apr 19, 2023
767f522
Use .slice() for all substring-ing (#26677)
sophiebits Apr 19, 2023
22d5942
Add two event system cleanup TODOs (#26678)
sophiebits Apr 20, 2023
7f8c501
React DevTools 4.27.5 -> 4.27.6 (#26684)
hoxyq Apr 20, 2023
d73d7d5
Add `alwaysThrottleRetries` flag (#26685)
acdlite Apr 20, 2023
e5708b3
[Tests][Fizz] Better HTML parsing behavior for Fizz tests (#26570)
gnoff Apr 20, 2023
fdad813
[Float][Fiber] Enable Float methods to be called outside of render (#…
gnoff Apr 20, 2023
cc93a85
[Fiber] InvokeGuardedCallback without metaprogramming (#26569)
gnoff Apr 20, 2023
c836952
update broken icon link (circleCi status) (#26688)
itaim18 Apr 21, 2023
c57a0f6
Remove react-is download hack (#26692)
kassens Apr 21, 2023
fd3fb8e
Rethrow errors from form actions (#26689)
acdlite Apr 21, 2023
5d7ebb4
Allow Node.js 20 to build (#26693)
kassens Apr 21, 2023
967d46c
Add error boundary to Flight fixture (#26695)
acdlite Apr 21, 2023
8f42196
Change DOM HostContext to number instead of string (#26698)
acdlite Apr 22, 2023
36e4cbe
[Float][Flight] Flight support for Float (#26502)
gnoff Apr 22, 2023
a21d147
[Flight] Fix File Upload in Node.js (#26700)
sebmarkbage Apr 22, 2023
7ce765e
Clean up enableUseHook flag (#26707)
acdlite Apr 23, 2023
2fa6323
Restore server controlled form fields to whatever they should be (#26…
sebmarkbage Apr 23, 2023
9ee7964
Fix escaping in ReactDOMInput code (#26630)
sophiebits Apr 24, 2023
9c58a0b
Update Flight fixture to use use() instead of Promise as a child (#26…
sebmarkbage Apr 24, 2023
5e5342b
Insert temporary input node to polyfill submitter argument in FormDat…
sebmarkbage Apr 24, 2023
9ece58e
Go through the toString path for booleanish strings and .name propert…
sebmarkbage Apr 24, 2023
919620b
Add stub for experimental_useFormStatus (#26719)
acdlite Apr 25, 2023
64d6be7
Use require() to implement script src in tests (#26717)
sebmarkbage Apr 25, 2023
bf449ee
Replay Client Actions After Hydration (#26716)
sebmarkbage Apr 25, 2023
ed545ae
Turn off enableFormActions in Meta build (#26721)
acdlite Apr 25, 2023
25b99ef
[DevTools] Add support for useMemoCache (#26696)
poteto Apr 25, 2023
f87e97a
Handle line endings correctly on Windows in build script for RN (#26727)
rubennorte Apr 25, 2023
ec5e9c2
Fix double preload (#26729)
gnoff Apr 25, 2023
6eadbe0
Fix: Resolve entangled actions independently (#26726)
acdlite Apr 26, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,14 @@ module.exports = {
'no-inner-declarations': [ERROR, 'functions'],
'no-multi-spaces': ERROR,
'no-restricted-globals': [ERROR].concat(restrictedGlobals),
'no-restricted-syntax': [ERROR, 'WithStatement'],
'no-restricted-syntax': [
ERROR,
'WithStatement',
{
selector: 'MemberExpression[property.name=/^(?:substring|substr)$/]',
message: 'Prefer string.slice() over .substring() and .substr().',
},
],
'no-shadow': ERROR,
'no-unused-vars': [ERROR, {args: 'none'}],
'no-use-before-define': OFF,
Expand Down
15 changes: 13 additions & 2 deletions .github/workflows/commit_artifacts.yml
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
name: Commit Artifacts for Facebook WWW and fbsource
name: Commit Artifacts for Meta WWW and fbsource

on:
push:
branches: [main]
branches: [main, meta-www, meta-fbsource]

jobs:
download_artifacts:
runs-on: ubuntu-latest
outputs:
www_branch_count: ${{ steps.check_branches.outputs.www_branch_count }}
fbsource_branch_count: ${{ steps.check_branches.outputs.fbsource_branch_count }}
steps:
- uses: actions/checkout@v3
- name: "Check branches"
id: check_branches
run: |
echo "www_branch_count=$(git ls-remote --heads origin "refs/heads/meta-www" | wc -l)" >> "$GITHUB_OUTPUT"
echo "fbsource_branch_count=$(git ls-remote --heads origin "refs/heads/meta-fbsource" | wc -l)" >> "$GITHUB_OUTPUT"
- name: Download and unzip artifacts
uses: actions/github-script@v6
env:
Expand Down Expand Up @@ -168,6 +177,7 @@ jobs:

commit_www_artifacts:
needs: download_artifacts
if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.www_branch_count == '0') || github.ref == 'refs/heads/meta-www' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
Expand Down Expand Up @@ -204,6 +214,7 @@ jobs:
commit_fbsource_artifacts:
needs: download_artifacts
runs-on: ubuntu-latest
if: ${{ (github.ref == 'refs/heads/main' && needs.download_artifacts.outputs.fbsource_branch_count == '0') || github.ref == 'refs/heads/meta-fbsource' }}
steps:
- uses: actions/checkout@v3
with:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# [React](https://reactjs.org/) · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/facebook/react/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/react.svg?style=flat)](https://www.npmjs.com/package/react) [![CircleCI Status](https://circleci.com/gh/facebook/react.svg?style=shield&circle-token=:circle-token)](https://circleci.com/gh/facebook/react) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)
# [React](https://reactjs.org/) · [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/facebook/react/blob/main/LICENSE) [![npm version](https://img.shields.io/npm/v/react.svg?style=flat)](https://www.npmjs.com/package/react) [![CircleCI Status](https://circleci.com/gh/facebook/react.svg?style=shield)](https://circleci.com/gh/facebook/react) [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://reactjs.org/docs/how-to-contribute.html#your-first-pull-request)

React is a JavaScript library for building user interfaces.

Expand Down
2 changes: 1 addition & 1 deletion fixtures/concurrent/time-slicing/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class App extends PureComponent {
}
const multiplier = input.length !== 0 ? input.length : 1;
const complexity =
(parseInt(window.location.search.substring(1), 10) / 100) * 25 || 25;
(parseInt(window.location.search.slice(1), 10) / 100) * 25 || 25;
const data = _.range(5).map(t =>
_.range(complexity * multiplier).map((j, i) => {
return {
Expand Down
2 changes: 1 addition & 1 deletion fixtures/dom/src/react-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import semver from 'semver';

function parseQuery(qstr) {
var query = {};
var a = qstr.substr(1).split('&');
var a = qstr.slice(1).split('&');

for (var i = 0; i < a.length; i++) {
var b = a[i].split('=');
Expand Down
4 changes: 3 additions & 1 deletion fixtures/flight/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ import {Counter as Counter2} from './Counter2.js';

import ShowMore from './ShowMore.js';
import Button from './Button.js';
import Form from './Form.js';

import {like} from './actions.js';
import {like, greet} from './actions.js';

export default async function App() {
const res = await fetch('http://localhost:3001/todos');
Expand All @@ -33,6 +34,7 @@ export default async function App() {
<ShowMore>
<p>Lorem ipsum</p>
</ShowMore>
<Form action={greet} />
<div>
<Button action={like}>Like</Button>
</div>
Expand Down
35 changes: 20 additions & 15 deletions fixtures/flight/src/Button.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
'use client';

import * as React from 'react';
import {flushSync} from 'react-dom';
import ErrorBoundary from './ErrorBoundary.js';

export default function Button({action, children}) {
const [isPending, setIsPending] = React.useState(false);

return (
<button
disabled={isPending}
onClick={async () => {
setIsPending(true);
try {
const result = await action();
console.log(result);
} catch (error) {
console.error(error);
} finally {
setIsPending(false);
}
}}>
{children}
</button>
<ErrorBoundary>
<form>
<button
disabled={isPending}
formAction={async () => {
// TODO: Migrate to useFormPending once that exists
flushSync(() => setIsPending(true));
try {
const result = await action();
console.log(result);
} finally {
React.startTransition(() => setIsPending(false));
}
}}>
{children}
</button>
</form>
</ErrorBoundary>
);
}
16 changes: 16 additions & 0 deletions fixtures/flight/src/ErrorBoundary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
'use client';

import * as React from 'react';

export default class ErrorBoundary extends React.Component {
state = {error: null};
static getDerivedStateFromError(error) {
return {error};
}
render() {
if (this.state.error) {
return <div>Caught an error: {this.state.error.message}</div>;
}
return this.props.children;
}
}
34 changes: 34 additions & 0 deletions fixtures/flight/src/Form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use client';

import * as React from 'react';
import {flushSync} from 'react-dom';
import ErrorBoundary from './ErrorBoundary.js';

export default function Form({action, children}) {
const [isPending, setIsPending] = React.useState(false);

return (
<ErrorBoundary>
<form
action={async formData => {
// TODO: Migrate to useFormPending once that exists
flushSync(() => setIsPending(true));
try {
const result = await action(formData);
alert(result);
} finally {
React.startTransition(() => setIsPending(false));
}
}}>
<label>
Name: <input name="name" />
</label>
<label>
File: <input type="file" name="file" />
</label>
<button>Say Hi</button>
{isPending ? 'Saving...' : null}
</form>
</ErrorBoundary>
);
}
11 changes: 11 additions & 0 deletions fixtures/flight/src/actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,14 @@
export async function like() {
return new Promise((resolve, reject) => resolve('Liked'));
}

export async function greet(formData) {
const name = formData.get('name') || 'you';
const file = formData.get('file');
if (file) {
return `Ok, ${name}, here is ${file.name}:
${(await file.text()).toUpperCase()}
`;
}
return 'Hi ' + name + '!';
}
11 changes: 6 additions & 5 deletions fixtures/flight/src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import {Suspense} from 'react';
import {use, Suspense} from 'react';
import ReactDOM from 'react-dom/client';
import {createFromFetch, encodeReply} from 'react-server-dom-webpack/client';

Expand Down Expand Up @@ -27,7 +27,8 @@ let data = createFromFetch(
}
);

// TODO: This transition shouldn't really be necessary but it is for now.
React.startTransition(() => {
ReactDOM.hydrateRoot(document, data);
});
function Shell({data}) {
return use(data);
}

ReactDOM.hydrateRoot(document, <Shell data={data} />);
5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@
"minimist": "^1.2.3",
"mkdirp": "^0.5.1",
"ncp": "^2.0.0",
"pacote": "^10.3.0",
"prettier": "2.8.3",
"pretty-format": "^29.4.1",
"prop-types": "^15.6.2",
Expand All @@ -103,7 +102,7 @@
"yargs": "^15.3.1"
},
"devEngines": {
"node": "16.x || 18.x || 19.x"
"node": "16.x || 18.x || 19.x || 20.x"
},
"jest": {
"testRegex": "/scripts/jest/dont-run-jest-directly\\.js$"
Expand All @@ -118,7 +117,7 @@
"lint": "node ./scripts/tasks/eslint.js",
"lint-build": "node ./scripts/rollup/validate/index.js",
"extract-errors": "node scripts/error-codes/extract-errors.js",
"postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js && node ./scripts/yarn/downloadReactIsForPrettyFormat.js",
"postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js",
"debug-test": "yarn test --deprecated 'yarn test --debug'",
"test": "node ./scripts/jest/jest-cli.js",
"test-stable": "node ./scripts/jest/jest-cli.js --release-channel=stable",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const ReactHooksESLintRule = ReactHooksESLintPlugin.rules['exhaustive-deps'];
function normalizeIndent(strings) {
const codeLines = strings[0].split('\n');
const leftPadding = codeLines[1].match(/\s+/)[0];
return codeLines.map(line => line.substr(leftPadding.length)).join('\n');
return codeLines.map(line => line.slice(leftPadding.length)).join('\n');
}

// ***************************************************
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ ESLintTester.setDefaultConfig({
function normalizeIndent(strings) {
const codeLines = strings[0].split('\n');
const leftPadding = codeLines[1].match(/\s+/)[0];
return codeLines.map(line => line.substr(leftPadding.length)).join('\n');
return codeLines.map(line => line.slice(leftPadding.length)).join('\n');
}

// ***************************************************
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-react-hooks/src/ExhaustiveDeps.js
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ export default {
extraWarning =
` You can also do a functional update '${
setStateRecommendation.setter
}(${setStateRecommendation.missingDep.substring(
}(${setStateRecommendation.missingDep.slice(
0,
1,
)} => ...)' if you only need '${
Expand Down
8 changes: 0 additions & 8 deletions packages/react-art/src/ReactFiberConfigART.js
Original file line number Diff line number Diff line change
Expand Up @@ -479,11 +479,3 @@ export function suspendInstance(type, props) {}
export function waitForCommitToBeReady() {
return null;
}
// eslint-disable-next-line no-undef
export function prepareRendererToRender(container: Container): void {
// noop
}

export function resetRendererAfterRender(): void {
// noop
}
32 changes: 24 additions & 8 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ import type {
SSRManifest,
} from './ReactFlightClientConfig';

import type {HintModel} from 'react-server/src/ReactFlightServerConfig';

import {
resolveClientReference,
preloadModule,
requireModule,
parseModel,
dispatchHint,
} from './ReactFlightClientConfig';

import {knownServerReferences} from './ReactFlightServerReferenceRegistry';
Expand Down Expand Up @@ -515,33 +518,33 @@ export function parseModelString(
switch (value[1]) {
case '$': {
// This was an escaped string value.
return value.substring(1);
return value.slice(1);
}
case 'L': {
// Lazy node
const id = parseInt(value.substring(2), 16);
const id = parseInt(value.slice(2), 16);
const chunk = getChunk(response, id);
// We create a React.lazy wrapper around any lazy values.
// When passed into React, we'll know how to suspend on this.
return createLazyChunkWrapper(chunk);
}
case '@': {
// Promise
const id = parseInt(value.substring(2), 16);
const id = parseInt(value.slice(2), 16);
const chunk = getChunk(response, id);
return chunk;
}
case 'S': {
// Symbol
return Symbol.for(value.substring(2));
return Symbol.for(value.slice(2));
}
case 'P': {
// Server Context Provider
return getOrCreateServerContext(value.substring(2)).Provider;
return getOrCreateServerContext(value.slice(2)).Provider;
}
case 'F': {
// Server Reference
const id = parseInt(value.substring(2), 16);
const id = parseInt(value.slice(2), 16);
const chunk = getChunk(response, id);
switch (chunk.status) {
case RESOLVED_MODEL:
Expand Down Expand Up @@ -580,13 +583,17 @@ export function parseModelString(
// Special encoding for `undefined` which can't be serialized as JSON otherwise.
return undefined;
}
case 'D': {
// Date
return new Date(Date.parse(value.slice(2)));
}
case 'n': {
// BigInt
return BigInt(value.substring(2));
return BigInt(value.slice(2));
}
default: {
// We assume that anything else is a reference ID.
const id = parseInt(value.substring(1), 16);
const id = parseInt(value.slice(1), 16);
const chunk = getChunk(response, id);
switch (chunk.status) {
case RESOLVED_MODEL:
Expand Down Expand Up @@ -774,6 +781,15 @@ export function resolveErrorDev(
}
}

export function resolveHint(
response: Response,
code: string,
model: UninitializedModel,
): void {
const hintModel = parseModel<HintModel>(response, model);
dispatchHint(code, hintModel);
}

export function close(response: Response): void {
// In case there are any remaining unresolved chunks, they won't
// be resolved now. So we need to issue an error to those.
Expand Down
Loading