diff --git a/package.json b/package.json index 90ee3304af4fa..97e1343213eb0 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "@babel/preset-flow": "^7.10.4", "@babel/preset-react": "^7.10.4", "@babel/traverse": "^7.11.0", - "abort-controller": "^3.0.0", "art": "0.10.1", "babel-plugin-syntax-trailing-function-commas": "^6.5.0", "chalk": "^3.0.0", diff --git a/packages/jest-mock-scheduler/README.md b/packages/jest-mock-scheduler/README.md deleted file mode 100644 index 387f015246617..0000000000000 --- a/packages/jest-mock-scheduler/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# `jest-mock-scheduler` - -Jest matchers and utilities for testing the `scheduler` package. - -This package is experimental. APIs may change between releases. \ No newline at end of file diff --git a/packages/jest-mock-scheduler/npm/index.js b/packages/jest-mock-scheduler/npm/index.js deleted file mode 100644 index 9a1d6ca4d1495..0000000000000 --- a/packages/jest-mock-scheduler/npm/index.js +++ /dev/null @@ -1,3 +0,0 @@ -'use strict'; - -module.exports = require('scheduler/unstable_mock'); diff --git a/packages/jest-mock-scheduler/package.json b/packages/jest-mock-scheduler/package.json deleted file mode 100644 index 16761b19d3750..0000000000000 --- a/packages/jest-mock-scheduler/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "jest-mock-scheduler", - "private": true, - "version": "0.1.0", - "description": "Jest matchers and utilities for testing the scheduler package.", - "main": "index.js", - "repository": { - "type" : "git", - "url" : "https://github.com/facebook/react.git", - "directory": "packages/jest-mock-scheduler" - }, - "keywords": [ - "jest", - "scheduler" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/facebook/react/issues" - }, - "homepage": "https://reactjs.org/", - "peerDependencies": { - "jest": "^23.0.1 || ^24.0.0 || ^25.1.0", - "scheduler": "^0.20.0" - }, - "files": [ - "LICENSE", - "README.md", - "index.js", - "cjs/" - ] -} diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 86455c3dfe6ad..2dd135ad656a9 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -201,14 +201,6 @@ function createErrorChunk( return new Chunk(ERRORED, null, error, response); } -function createInitializedChunk( - response: Response, - value: T, -): InitializedChunk { - // $FlowFixMe Flow doesn't support functions as constructors - return new Chunk(INITIALIZED, value, null, response); -} - function wakeChunk(listeners: Array<(T) => mixed>, value: T): void { for (let i = 0; i < listeners.length; i++) { const listener = listeners[i]; @@ -483,14 +475,32 @@ export function parseModelString( key: string, value: string, ): any { - switch (value[0]) { - case '$': { - if (value === '$') { - return REACT_ELEMENT_TYPE; - } else if (value[1] === '$' || value[1] === '@') { + if (value[0] === '$') { + if (value === '$') { + // A very common symbol. + return REACT_ELEMENT_TYPE; + } + switch (value[1]) { + case '$': { // This was an escaped string value. return value.substring(1); - } else { + } + case 'L': { + // Lazy node + const id = parseInt(value.substring(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 'S': { + return Symbol.for(value.substring(2)); + } + case 'P': { + return getOrCreateServerContext(value.substring(2)).Provider; + } + default: { + // We assume that anything else is a reference ID. const id = parseInt(value.substring(1), 16); const chunk = getChunk(response, id); switch (chunk.status) { @@ -518,13 +528,6 @@ export function parseModelString( } } } - case '@': { - const id = parseInt(value.substring(1), 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); - } } return value; } @@ -566,21 +569,6 @@ export function resolveModel( } } -export function resolveProvider( - response: Response, - id: number, - contextName: string, -): void { - const chunks = response._chunks; - chunks.set( - id, - createInitializedChunk( - response, - getOrCreateServerContext(contextName).Provider, - ), - ); -} - export function resolveModule( response: Response, id: number, @@ -626,17 +614,6 @@ export function resolveModule( } } -export function resolveSymbol( - response: Response, - id: number, - name: string, -): void { - const chunks = response._chunks; - // We assume that we'll always emit the symbol before anything references it - // to save a few bytes. - chunks.set(id, createInitializedChunk(response, Symbol.for(name))); -} - type ErrorWithDigest = Error & {digest?: string}; export function resolveErrorProd( response: Response, diff --git a/packages/react-client/src/ReactFlightClientStream.js b/packages/react-client/src/ReactFlightClientStream.js index bcdcda4375a8f..57887e48d4550 100644 --- a/packages/react-client/src/ReactFlightClientStream.js +++ b/packages/react-client/src/ReactFlightClientStream.js @@ -14,8 +14,6 @@ import type {BundlerConfig} from './ReactFlightClientHostConfig'; import { resolveModule, resolveModel, - resolveProvider, - resolveSymbol, resolveErrorProd, resolveErrorDev, createResponse as createResponseBase, @@ -36,33 +34,20 @@ function processFullRow(response: Response, row: string): void { if (row === '') { return; } - const tag = row[0]; + const colon = row.indexOf(':', 0); + const id = parseInt(row.substring(0, colon), 16); + const tag = row[colon + 1]; // When tags that are not text are added, check them here before // parsing the row as text. // switch (tag) { // } - const colon = row.indexOf(':', 1); - const id = parseInt(row.substring(1, colon), 16); - const text = row.substring(colon + 1); switch (tag) { - case 'J': { - resolveModel(response, id, text); - return; - } - case 'M': { - resolveModule(response, id, text); - return; - } - case 'P': { - resolveProvider(response, id, text); - return; - } - case 'S': { - resolveSymbol(response, id, JSON.parse(text)); + case 'I': { + resolveModule(response, id, row.substring(colon + 2)); return; } case 'E': { - const errorInfo = JSON.parse(text); + const errorInfo = JSON.parse(row.substring(colon + 2)); if (__DEV__) { resolveErrorDev( response, @@ -77,9 +62,9 @@ function processFullRow(response: Response, row: string): void { return; } default: { - throw new Error( - "Error parsing the data. It's probably an error code or network corruption.", - ); + // We assume anything else is JSON. + resolveModel(response, id, row.substring(colon + 1)); + return; } } } diff --git a/packages/react-server-dom-relay/src/ReactFlightDOMRelayClient.js b/packages/react-server-dom-relay/src/ReactFlightDOMRelayClient.js index 5e344c1398c53..5bf775bfb5f26 100644 --- a/packages/react-server-dom-relay/src/ReactFlightDOMRelayClient.js +++ b/packages/react-server-dom-relay/src/ReactFlightDOMRelayClient.js @@ -15,7 +15,6 @@ import { createResponse, resolveModel, resolveModule, - resolveSymbol, resolveErrorDev, resolveErrorProd, close, @@ -25,15 +24,12 @@ import { export {createResponse, close, getRoot}; export function resolveRow(response: Response, chunk: RowEncoding): void { - if (chunk[0] === 'J') { + if (chunk[0] === 'O') { // $FlowFixMe unable to refine on array indices resolveModel(response, chunk[1], chunk[2]); - } else if (chunk[0] === 'M') { + } else if (chunk[0] === 'I') { // $FlowFixMe unable to refine on array indices resolveModule(response, chunk[1], chunk[2]); - } else if (chunk[0] === 'S') { - // $FlowFixMe: Flow doesn't support disjoint unions on tuples. - resolveSymbol(response, chunk[1], chunk[2]); } else { if (__DEV__) { resolveErrorDev( diff --git a/packages/react-server-dom-relay/src/ReactFlightDOMRelayProtocol.js b/packages/react-server-dom-relay/src/ReactFlightDOMRelayProtocol.js index 3b3425abeca06..f770432dce1e2 100644 --- a/packages/react-server-dom-relay/src/ReactFlightDOMRelayProtocol.js +++ b/packages/react-server-dom-relay/src/ReactFlightDOMRelayProtocol.js @@ -18,8 +18,8 @@ export type JSONValue = | $ReadOnlyArray; export type RowEncoding = - | ['J', number, JSONValue] - | ['M', number, ModuleMetaData] + | ['O', number, JSONValue] + | ['I', number, ModuleMetaData] | ['P', number, string] | ['S', number, string] | [ diff --git a/packages/react-server-dom-relay/src/ReactFlightDOMRelayServerHostConfig.js b/packages/react-server-dom-relay/src/ReactFlightDOMRelayServerHostConfig.js index 7efc6c911e44c..bf6572110d4d1 100644 --- a/packages/react-server-dom-relay/src/ReactFlightDOMRelayServerHostConfig.js +++ b/packages/react-server-dom-relay/src/ReactFlightDOMRelayServerHostConfig.js @@ -151,7 +151,7 @@ export function processModelChunk( ): Chunk { // $FlowFixMe no good way to define an empty exact object const json = convertModelToJSON(request, {}, '', model); - return ['J', id, json]; + return ['O', id, json]; } export function processReferenceChunk( @@ -159,7 +159,7 @@ export function processReferenceChunk( id: number, reference: string, ): Chunk { - return ['J', id, reference]; + return ['O', id, reference]; } export function processModuleChunk( @@ -168,23 +168,7 @@ export function processModuleChunk( moduleMetaData: ModuleMetaData, ): Chunk { // The moduleMetaData is already a JSON serializable value. - return ['M', id, moduleMetaData]; -} - -export function processProviderChunk( - request: Request, - id: number, - contextName: string, -): Chunk { - return ['P', id, contextName]; -} - -export function processSymbolChunk( - request: Request, - id: number, - name: string, -): Chunk { - return ['S', id, name]; + return ['I', id, moduleMetaData]; } export function scheduleWork(callback: () => void) { diff --git a/packages/react-server-native-relay/src/ReactFlightNativeRelayClient.js b/packages/react-server-native-relay/src/ReactFlightNativeRelayClient.js index 94f287971441f..b9a398cc9328b 100644 --- a/packages/react-server-native-relay/src/ReactFlightNativeRelayClient.js +++ b/packages/react-server-native-relay/src/ReactFlightNativeRelayClient.js @@ -15,7 +15,6 @@ import { createResponse, resolveModel, resolveModule, - resolveSymbol, resolveErrorDev, resolveErrorProd, close, @@ -25,15 +24,12 @@ import { export {createResponse, close, getRoot}; export function resolveRow(response: Response, chunk: RowEncoding): void { - if (chunk[0] === 'J') { + if (chunk[0] === 'O') { // $FlowFixMe `Chunk` doesn't flow into `JSONValue` because of the `E` row type. resolveModel(response, chunk[1], chunk[2]); - } else if (chunk[0] === 'M') { + } else if (chunk[0] === 'I') { // $FlowFixMe `Chunk` doesn't flow into `JSONValue` because of the `E` row type. resolveModule(response, chunk[1], chunk[2]); - } else if (chunk[0] === 'S') { - // $FlowFixMe: Flow doesn't support disjoint unions on tuples. - resolveSymbol(response, chunk[1], chunk[2]); } else { if (__DEV__) { resolveErrorDev( diff --git a/packages/react-server-native-relay/src/ReactFlightNativeRelayProtocol.js b/packages/react-server-native-relay/src/ReactFlightNativeRelayProtocol.js index a69b14407aec1..788fd14293ca3 100644 --- a/packages/react-server-native-relay/src/ReactFlightNativeRelayProtocol.js +++ b/packages/react-server-native-relay/src/ReactFlightNativeRelayProtocol.js @@ -18,8 +18,8 @@ export type JSONValue = | Array; export type RowEncoding = - | ['J', number, JSONValue] - | ['M', number, ModuleMetaData] + | ['O', number, JSONValue] + | ['I', number, ModuleMetaData] | ['P', number, string] | ['S', number, string] | [ diff --git a/packages/react-server-native-relay/src/ReactFlightNativeRelayServerHostConfig.js b/packages/react-server-native-relay/src/ReactFlightNativeRelayServerHostConfig.js index 9684fbd3a17f8..a58bf22f0c2a9 100644 --- a/packages/react-server-native-relay/src/ReactFlightNativeRelayServerHostConfig.js +++ b/packages/react-server-native-relay/src/ReactFlightNativeRelayServerHostConfig.js @@ -146,7 +146,7 @@ export function processModelChunk( ): Chunk { // $FlowFixMe no good way to define an empty exact object const json = convertModelToJSON(request, {}, '', model); - return ['J', id, json]; + return ['O', id, json]; } export function processReferenceChunk( @@ -154,7 +154,7 @@ export function processReferenceChunk( id: number, reference: string, ): Chunk { - return ['J', id, reference]; + return ['O', id, reference]; } export function processModuleChunk( @@ -163,23 +163,7 @@ export function processModuleChunk( moduleMetaData: ModuleMetaData, ): Chunk { // The moduleMetaData is already a JSON serializable value. - return ['M', id, moduleMetaData]; -} - -export function processProviderChunk( - request: Request, - id: number, - contextName: string, -): Chunk { - return ['P', id, contextName]; -} - -export function processSymbolChunk( - request: Request, - id: number, - name: string, -): Chunk { - return ['S', id, name]; + return ['I', id, moduleMetaData]; } export function scheduleWork(callback: () => void) { diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 660dc8d5a894f..3d4bd59756cd9 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -38,8 +38,6 @@ import { closeWithError, processModelChunk, processModuleChunk, - processProviderChunk, - processSymbolChunk, processErrorChunkProd, processErrorChunkDev, processReferenceChunk, @@ -417,7 +415,15 @@ function serializeByValueID(id: number): string { } function serializeByRefID(id: number): string { - return '@' + id.toString(16); + return '$L' + id.toString(16); +} + +function serializeSymbolReference(name: string): string { + return '$S' + name; +} + +function serializeProviderReference(name: string): string { + return '$P' + name; } function serializeClientReference( @@ -473,7 +479,7 @@ function serializeClientReference( } function escapeStringValue(value: string): string { - if (value[0] === '$' || value[0] === '@') { + if (value[0] === '$') { // We need to escape $ or @ prefixed strings since we use those to encode // references to IDs and as special symbol values. return '$' + value; @@ -1110,7 +1116,8 @@ function emitModuleChunk( } function emitSymbolChunk(request: Request, id: number, name: string): void { - const processedChunk = processSymbolChunk(request, id, name); + const symbolReference = serializeSymbolReference(name); + const processedChunk = processReferenceChunk(request, id, symbolReference); request.completedModuleChunks.push(processedChunk); } @@ -1119,7 +1126,8 @@ function emitProviderChunk( id: number, contextName: string, ): void { - const processedChunk = processProviderChunk(request, id, contextName); + const contextReference = serializeProviderReference(contextName); + const processedChunk = processReferenceChunk(request, id, contextReference); request.completedJSONChunks.push(processedChunk); } diff --git a/packages/react-server/src/ReactFlightServerConfigStream.js b/packages/react-server/src/ReactFlightServerConfigStream.js index d5e4ec6f6371a..7364ab86dbfb7 100644 --- a/packages/react-server/src/ReactFlightServerConfigStream.js +++ b/packages/react-server/src/ReactFlightServerConfigStream.js @@ -80,7 +80,7 @@ export { const stringify = JSON.stringify; function serializeRowHeader(tag: string, id: number) { - return tag + id.toString(16) + ':'; + return id.toString(16) + ':' + tag; } export function processErrorChunkProd( @@ -127,7 +127,7 @@ export function processModelChunk( model: ReactModel, ): Chunk { const json: string = stringify(model, request.toJSON); - const row = serializeRowHeader('J', id) + json + '\n'; + const row = id.toString(16) + ':' + json + '\n'; return stringToChunk(row); } @@ -137,7 +137,7 @@ export function processReferenceChunk( reference: string, ): Chunk { const json = stringify(reference); - const row = serializeRowHeader('J', id) + json + '\n'; + const row = id.toString(16) + ':' + json + '\n'; return stringToChunk(row); } @@ -147,26 +147,7 @@ export function processModuleChunk( moduleMetaData: ReactModel, ): Chunk { const json: string = stringify(moduleMetaData); - const row = serializeRowHeader('M', id) + json + '\n'; - return stringToChunk(row); -} - -export function processProviderChunk( - request: Request, - id: number, - contextName: string, -): Chunk { - const row = serializeRowHeader('P', id) + contextName + '\n'; - return stringToChunk(row); -} - -export function processSymbolChunk( - request: Request, - id: number, - name: string, -): Chunk { - const json = stringify(name); - const row = serializeRowHeader('S', id) + json + '\n'; + const row = serializeRowHeader('I', id) + json + '\n'; return stringToChunk(row); } diff --git a/yarn.lock b/yarn.lock index bea16f8fbe308..820fa8a937c3e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3274,13 +3274,6 @@ abab@^2.0.5: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -7268,11 +7261,6 @@ etag@~1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - event-to-promise@0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/event-to-promise/-/event-to-promise-0.8.0.tgz#4b84f11772b6f25f7752fc74d971531ac6f5b626"