mirror of
https://github.com/hanzoai/react.git
synced 2026-09-24 17:02:27 +00:00
This adds support in Flight for serializing four kinds of streams: - `ReadableStream` with objects as a model. This is a single shot iterator so you can read it only once. It can contain any value including Server Components. Chunks are encoded as is so if you send in 10 typed arrays, you get the same typed arrays out on the other side. - Binary `ReadableStream` with `type: 'bytes'` option. This supports the BYOB protocol. In this mode, the receiving side just gets `Uint8Array`s and they can be split across any single byte boundary into arbitrary chunks. - `AsyncIterable` where the `AsyncIterator` function is different than the `AsyncIterable` itself. In this case we assume that this might be a multi-shot iterable and so we buffer its value and you can iterate it multiple times on the other side. We support the `return` value as a value in the single completion slot, but you can't pass values in `next()`. If you want single-shot, return the AsyncIterator instead. - `AsyncIterator`. These gets serialized as a single-shot as it's just an iterator. `AsyncIterable`/`AsyncIterator` yield Promises that are instrumented with our `.status`/`.value` convention so that they can be synchronously looped over if available. They are also lazily parsed upon read. We can't do this with `ReadableStream` because we use the native implementation of `ReadableStream` which owns the promises. The format is a leading row that indicates which type of stream it is. Then a new row with the same ID is emitted for every chunk. Followed by either an error or close row. `AsyncIterable`s can also be returned as children of Server Components and then they're conceptually the same as fragment arrays/iterables. They can't actually be used as children in Fizz/Fiber but there's a separate plan for that. Only `AsyncIterable` not `AsyncIterator` will be valid as children - just like sync `Iterable` is already supported but single-shot `Iterator` is not. Notably, neither of these streams represent updates over time to a value. They represent multiple values in a list. When the server stream is aborted we also close the underlying stream. However, closing a stream on the client, doesn't close the underlying stream. A couple of possible follow ups I'm not planning on doing right now: - [ ] Free memory by releasing the buffer if an Iterator has been exhausted. Single shots could be optimized further to release individual items as you go. - [ ] We could clean up the underlying stream if the only pending data that's still flowing is from streams and all the streams have cleaned up. It's not very reliable though. It's better to do cancellation for the whole stream - e.g. at the framework level. - [ ] Implement smarter Binary Stream chunk handling. Currently we wait until we've received a whole row for binary chunks and copy them into consecutive memory. We need this to preserve semantics when passing typed arrays. However, for binary streams we don't need that. We can just send whatever pieces we have so far.
113 lines
5.3 KiB
JavaScript
113 lines
5.3 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
*/
|
|
|
|
import typeof * as FeatureFlagsType from 'shared/ReactFeatureFlags';
|
|
import typeof * as ExportsType from './ReactFeatureFlags.native-oss';
|
|
|
|
// TODO: Align these flags with canary and delete this file once RN ships from Canary.
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// TODO for next React Native major.
|
|
//
|
|
// Alias __TODO_NEXT_RN_MAJOR__ to false for easier skimming.
|
|
// -----------------------------------------------------------------------------
|
|
const __TODO_NEXT_RN_MAJOR__ = false;
|
|
export const enableRefAsProp = __TODO_NEXT_RN_MAJOR__;
|
|
export const disableStringRefs = __TODO_NEXT_RN_MAJOR__;
|
|
export const disableLegacyMode = __TODO_NEXT_RN_MAJOR__;
|
|
export const disableDOMTestUtils = __TODO_NEXT_RN_MAJOR__;
|
|
export const useModernStrictMode = __TODO_NEXT_RN_MAJOR__;
|
|
export const enableReactTestRendererWarning = __TODO_NEXT_RN_MAJOR__;
|
|
export const enableAsyncActions = __TODO_NEXT_RN_MAJOR__;
|
|
export const consoleManagedByDevToolsDuringStrictMode = __TODO_NEXT_RN_MAJOR__;
|
|
export const enableDeferRootSchedulingToMicrotask = __TODO_NEXT_RN_MAJOR__;
|
|
export const alwaysThrottleRetries = __TODO_NEXT_RN_MAJOR__;
|
|
export const enableInfiniteRenderLoopDetection = __TODO_NEXT_RN_MAJOR__;
|
|
export const enableComponentStackLocations = __TODO_NEXT_RN_MAJOR__;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// These are ready to flip after the next React npm release (or RN switches to
|
|
// Canary, but can't flip before then because of react/renderer mismatches.
|
|
// -----------------------------------------------------------------------------
|
|
export const enableCache = __TODO_NEXT_RN_MAJOR__;
|
|
export const enableRenderableContext = __TODO_NEXT_RN_MAJOR__;
|
|
export const disableDefaultPropsExceptForClasses = __TODO_NEXT_RN_MAJOR__;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// Already enabled for next React Native major.
|
|
// Hardcode these to true after the next RN major.
|
|
//
|
|
// Alias __NEXT_RN_MAJOR__ to true for easier skimming.
|
|
// -----------------------------------------------------------------------------
|
|
const __NEXT_RN_MAJOR__ = true;
|
|
export const disableClientCache = __NEXT_RN_MAJOR__;
|
|
export const disableLegacyContext = __NEXT_RN_MAJOR__;
|
|
export const enableTaint = __NEXT_RN_MAJOR__;
|
|
export const enableUnifiedSyncLane = __NEXT_RN_MAJOR__;
|
|
export const enableFizzExternalRuntime = __NEXT_RN_MAJOR__; // DOM-only
|
|
export const enableBinaryFlight = __NEXT_RN_MAJOR__; // DOM-only
|
|
export const enableFlightReadableStream = __NEXT_RN_MAJOR__; // DOM-only
|
|
export const enableServerComponentKeys = __NEXT_RN_MAJOR__;
|
|
export const enableServerComponentLogs = __NEXT_RN_MAJOR__;
|
|
|
|
// DEV-only but enabled in the next RN Major.
|
|
// Not supported by flag script to avoid the special case.
|
|
export const debugRenderPhaseSideEffectsForStrictMode = __DEV__;
|
|
|
|
// TODO: decide on React 19
|
|
export const enableUseMemoCacheHook = false;
|
|
export const enableUseDeferredValueInitialArg = __EXPERIMENTAL__;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// All other flags
|
|
// -----------------------------------------------------------------------------
|
|
export const enableCPUSuspense = false;
|
|
export const enableDebugTracing = false;
|
|
export const enableAsyncDebugInfo = false;
|
|
export const enableSchedulingProfiler = __PROFILE__;
|
|
export const enableLegacyCache = false;
|
|
export const enableFetchInstrumentation = false;
|
|
export const enablePostpone = false;
|
|
export const disableCommentsAsDOMContainers = true;
|
|
export const disableInputAttributeSyncing = false;
|
|
export const disableIEWorkarounds = true;
|
|
export const enableScopeAPI = false;
|
|
export const enableCreateEventHandleAPI = false;
|
|
export const enableSuspenseCallback = false;
|
|
export const enableTrustedTypesIntegration = false;
|
|
export const disableTextareaChildren = false;
|
|
export const enableSuspenseAvoidThisFallback = false;
|
|
export const enableSuspenseAvoidThisFallbackFizz = false;
|
|
export const enableUseEffectEventHook = false;
|
|
export const favorSafetyOverHydrationPerf = true;
|
|
export const enableLegacyFBSupport = false;
|
|
export const enableFilterEmptyStringAttributesDOM = true;
|
|
export const enableGetInspectorDataForInstanceInProduction = false;
|
|
export const enableRetryLaneExpiration = false;
|
|
export const retryLaneExpirationMs = 5000;
|
|
export const syncLaneExpirationMs = 250;
|
|
export const transitionLaneExpirationMs = 5000;
|
|
export const disableSchedulerTimeoutInWorkLoop = false;
|
|
export const enableLazyContextPropagation = false;
|
|
export const enableLegacyHidden = false;
|
|
export const forceConcurrentByDefaultForTesting = false;
|
|
export const allowConcurrentByDefault = false;
|
|
export const enableTransitionTracing = false;
|
|
export const enableDO_NOT_USE_disableStrictPassiveEffect = false;
|
|
export const passChildrenWhenCloningPersistedNodes = false;
|
|
|
|
// Profiling Only
|
|
export const enableProfilerTimer = __PROFILE__;
|
|
export const enableProfilerCommitHooks = __PROFILE__;
|
|
export const enableProfilerNestedUpdatePhase = __PROFILE__;
|
|
export const enableUpdaterTracking = __PROFILE__;
|
|
|
|
// Flow magic to verify the exports of this file match the original version.
|
|
((((null: any): ExportsType): FeatureFlagsType): ExportsType);
|