Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
65 changes: 57 additions & 8 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ type Response = {
_stringDecoder: StringDecoder,
_closed: boolean,
_closedReason: mixed,
_allowPartialStream: boolean,
_tempRefs: void | TemporaryReferenceSet, // the set temporary references can be resolved from
_timeOrigin: number, // Profiling-only
_pendingInitialRender: null | TimeoutID, // Profiling-only,
Expand Down Expand Up @@ -1456,9 +1457,19 @@ function getChunk(response: Response, id: number): SomeChunk<any> {
let chunk = chunks.get(id);
if (!chunk) {
if (response._closed) {
// We have already errored the response and we're not going to get
// anything more streaming in so this will immediately error.
chunk = createErrorChunk(response, response._closedReason);
if (response._allowPartialStream) {
// For partial streams, chunks accessed after close should be HALTED
// (never resolve).
chunk = createPendingChunk(response);
const haltedChunk: HaltedChunk<any> = (chunk: any);
haltedChunk.status = HALTED;
haltedChunk.value = null;
haltedChunk.reason = null;
} else {
// We have already errored the response and we're not going to get
// anything more streaming in so this will immediately error.
chunk = createErrorChunk(response, response._closedReason);
}
} else {
chunk = createPendingChunk(response);
}
Expand Down Expand Up @@ -2655,6 +2666,7 @@ function ResponseInstance(
encodeFormAction: void | EncodeFormActionCallback,
nonce: void | string,
temporaryReferences: void | TemporaryReferenceSet,
allowPartialStream: boolean,
findSourceMapURL: void | FindSourceMapURLCallback, // DEV-only
replayConsole: boolean, // DEV-only
environmentName: void | string, // DEV-only
Expand All @@ -2674,6 +2686,7 @@ function ResponseInstance(
this._fromJSON = (null: any);
this._closed = false;
this._closedReason = null;
this._allowPartialStream = allowPartialStream;
this._tempRefs = temporaryReferences;
if (enableProfilerTimer && enableComponentPerformanceTrack) {
this._timeOrigin = 0;
Expand Down Expand Up @@ -2767,6 +2780,7 @@ export function createResponse(
encodeFormAction: void | EncodeFormActionCallback,
nonce: void | string,
temporaryReferences: void | TemporaryReferenceSet,
allowPartialStream: boolean,
findSourceMapURL: void | FindSourceMapURLCallback, // DEV-only
replayConsole: boolean, // DEV-only
environmentName: void | string, // DEV-only
Expand All @@ -2792,6 +2806,7 @@ export function createResponse(
encodeFormAction,
nonce,
temporaryReferences,
allowPartialStream,
findSourceMapURL,
replayConsole,
environmentName,
Expand Down Expand Up @@ -5243,11 +5258,45 @@ function createFromJSONCallback(response: Response) {
}

export function close(weakResponse: WeakResponse): void {
// In case there are any remaining unresolved chunks, they won't
// be resolved now. So we need to issue an error to those.
// Ideally we should be able to early bail out if we kept a
// ref count of pending chunks.
reportGlobalError(weakResponse, new Error('Connection closed.'));
// In case there are any remaining unresolved chunks, they won't be resolved
// now. So we either error or halt them depending on whether partial streams
// are allowed.
// TODO: Ideally we should be able to bail out early if we kept a ref count of
// pending chunks.
if (hasGCedResponse(weakResponse)) {
return;
}
const response = unwrapWeakResponse(weakResponse);
if (response._allowPartialStream) {
// For partial streams, we halt pending chunks instead of erroring them.
response._closed = true;
response._chunks.forEach(chunk => {
if (chunk.status === PENDING) {
// Clear listeners to release closures and transition to HALTED.
// Future .then() calls on HALTED chunks are no-ops.
releasePendingChunk(response, chunk);
const haltedChunk: HaltedChunk<any> = (chunk: any);
haltedChunk.status = HALTED;
haltedChunk.value = null;
haltedChunk.reason = null;
} else if (chunk.status === INITIALIZED && chunk.reason !== null) {
// Stream chunk - close gracefully instead of erroring.
chunk.reason.close('"$undefined"');
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be an alternative API: pass a special reason exported by React

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or similarly, React exports a special AbortController subclass that does this internally

}
});
if (__DEV__) {
const debugChannel = response._debugChannel;
if (debugChannel !== undefined) {
closeDebugChannel(debugChannel);
response._debugChannel = undefined;
if (debugChannelRegistry !== null) {
debugChannelRegistry.unregister(response);
}
}
}
} else {
reportGlobalError(weakResponse, new Error('Connection closed.'));
}
}

function getCurrentOwnerInDEV(): null | ReactComponentInfo {
Expand Down
1 change: 1 addition & 0 deletions packages/react-markup/src/ReactMarkupServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export function experimental_renderToHTML(
noServerCallOrFormAction,
undefined,
undefined,
false,
undefined,
false,
undefined,
Expand Down
1 change: 1 addition & 0 deletions packages/react-noop-renderer/src/ReactNoopFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function read<T>(source: Source, options: ReadOptions): Thenable<T> {
undefined,
undefined,
undefined,
false,
options !== undefined ? options.findSourceMapURL : undefined,
true,
undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export type Options = {
callServer?: CallServerCallback,
debugChannel?: {writable?: WritableStream, readable?: ReadableStream, ...},
temporaryReferences?: TemporaryReferenceSet,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -98,6 +99,9 @@ function createResponseFromOptions(options: void | Options) {
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type EncodeFormActionCallback = <A>(
export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -104,6 +105,9 @@ function createFromNodeStream<T>(
options ? options.encodeFormAction : undefined,
options && typeof options.nonce === 'string' ? options.nonce : undefined,
undefined, // TODO: If encodeReply is supported, this should support temporaryReferences
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ function createResponseFromOptions(options: void | Options) {
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ ? findSourceMapURL : undefined,
__DEV__ ? (options ? options.replayConsoleLogs !== false : true) : false, // defaults to true
__DEV__ && options && options.environmentName
Expand Down Expand Up @@ -207,6 +210,7 @@ function startReadingFromStream(
export type Options = {
debugChannel?: {writable?: WritableStream, readable?: ReadableStream, ...},
temporaryReferences?: TemporaryReferenceSet,
unstable_allowPartialStream?: boolean,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
temporaryReferences?: TemporaryReferenceSet,
unstable_allowPartialStream?: boolean,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
Expand Down Expand Up @@ -104,6 +105,9 @@ function createResponseFromOptions(options?: Options) {
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ ? findSourceMapURL : undefined,
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
__DEV__ && options && options.environmentName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ type EncodeFormActionCallback = <A>(
export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
unstable_allowPartialStream?: boolean,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
Expand Down Expand Up @@ -97,6 +98,9 @@ export function createFromNodeStream<T>(
options ? options.encodeFormAction : undefined,
options && typeof options.nonce === 'string' ? options.nonce : undefined,
undefined, // TODO: If encodeReply is supported, this should support temporaryReferences
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ ? findSourceMapURL : undefined,
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
__DEV__ && options && options.environmentName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export type Options = {
callServer?: CallServerCallback,
debugChannel?: {writable?: WritableStream, readable?: ReadableStream, ...},
temporaryReferences?: TemporaryReferenceSet,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -97,6 +98,9 @@ function createResponseFromOptions(options: void | Options) {
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
temporaryReferences?: TemporaryReferenceSet,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -104,6 +105,9 @@ function createResponseFromOptions(options: Options) {
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type EncodeFormActionCallback = <A>(
export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -106,6 +107,9 @@ function createFromNodeStream<T>(
options ? options.encodeFormAction : undefined,
options && typeof options.nonce === 'string' ? options.nonce : undefined,
undefined, // TODO: If encodeReply is supported, this should support temporaryReferences
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
temporaryReferences?: TemporaryReferenceSet,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -104,6 +105,9 @@ function createResponseFromOptions(options: Options) {
options && options.temporaryReferences
? options.temporaryReferences
: undefined,
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ type EncodeFormActionCallback = <A>(
export type Options = {
nonce?: string,
encodeFormAction?: EncodeFormActionCallback,
unstable_allowPartialStream?: boolean,
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
Expand Down Expand Up @@ -106,6 +107,9 @@ function createFromNodeStream<T>(
options ? options.encodeFormAction : undefined,
options && typeof options.nonce === 'string' ? options.nonce : undefined,
undefined, // TODO: If encodeReply is supported, this should support temporaryReferences
options && options.unstable_allowPartialStream
? options.unstable_allowPartialStream
: false,
__DEV__ && options && options.findSourceMapURL
? options.findSourceMapURL
: undefined,
Expand Down
Loading
Loading