From c04b18070145b82111e1162729f4776f4d2c6112 Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Wed, 22 Feb 2023 15:32:09 -0500 Subject: [PATCH 001/103] Remove eventTime field from class Update type (#26219) `eventTime` is a vestigial field that can be cleaned up. It was originally used as part of the starvation mechanism but it's since been replaced by a per-lane field on the root. This is a part of a series of smaller refactors I'm doing to simplify/speed up the `setState` path, related to the Sync Unification project that @tyao1 has been working on. --- .../react-reconciler/src/ReactFiberClassComponent.js | 12 ++++++------ .../src/ReactFiberClassUpdateQueue.js | 12 +----------- packages/react-reconciler/src/ReactFiberHooks.js | 4 ++-- .../react-reconciler/src/ReactFiberNewContext.js | 3 +-- .../react-reconciler/src/ReactFiberReconciler.js | 8 ++++---- packages/react-reconciler/src/ReactFiberThrow.js | 7 +++---- 6 files changed, 17 insertions(+), 29 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberClassComponent.js b/packages/react-reconciler/src/ReactFiberClassComponent.js index 2b640bd4801db..7fe8a87e0abe6 100644 --- a/packages/react-reconciler/src/ReactFiberClassComponent.js +++ b/packages/react-reconciler/src/ReactFiberClassComponent.js @@ -198,10 +198,9 @@ const classComponentUpdater = { // $FlowFixMe[missing-local-annot] enqueueSetState(inst: any, payload: any, callback) { const fiber = getInstance(inst); - const eventTime = requestEventTime(); const lane = requestUpdateLane(fiber); - const update = createUpdate(eventTime, lane); + const update = createUpdate(lane); update.payload = payload; if (callback !== undefined && callback !== null) { if (__DEV__) { @@ -212,6 +211,7 @@ const classComponentUpdater = { const root = enqueueUpdate(fiber, update, lane); if (root !== null) { + const eventTime = requestEventTime(); scheduleUpdateOnFiber(root, fiber, lane, eventTime); entangleTransitions(root, fiber, lane); } @@ -231,10 +231,9 @@ const classComponentUpdater = { }, enqueueReplaceState(inst: any, payload: any, callback: null) { const fiber = getInstance(inst); - const eventTime = requestEventTime(); const lane = requestUpdateLane(fiber); - const update = createUpdate(eventTime, lane); + const update = createUpdate(lane); update.tag = ReplaceState; update.payload = payload; @@ -247,6 +246,7 @@ const classComponentUpdater = { const root = enqueueUpdate(fiber, update, lane); if (root !== null) { + const eventTime = requestEventTime(); scheduleUpdateOnFiber(root, fiber, lane, eventTime); entangleTransitions(root, fiber, lane); } @@ -267,10 +267,9 @@ const classComponentUpdater = { // $FlowFixMe[missing-local-annot] enqueueForceUpdate(inst: any, callback) { const fiber = getInstance(inst); - const eventTime = requestEventTime(); const lane = requestUpdateLane(fiber); - const update = createUpdate(eventTime, lane); + const update = createUpdate(lane); update.tag = ForceUpdate; if (callback !== undefined && callback !== null) { @@ -282,6 +281,7 @@ const classComponentUpdater = { const root = enqueueUpdate(fiber, update, lane); if (root !== null) { + const eventTime = requestEventTime(); scheduleUpdateOnFiber(root, fiber, lane, eventTime); entangleTransitions(root, fiber, lane); } diff --git a/packages/react-reconciler/src/ReactFiberClassUpdateQueue.js b/packages/react-reconciler/src/ReactFiberClassUpdateQueue.js index 12b250a8d9a2c..a6148e0184198 100644 --- a/packages/react-reconciler/src/ReactFiberClassUpdateQueue.js +++ b/packages/react-reconciler/src/ReactFiberClassUpdateQueue.js @@ -127,9 +127,6 @@ import {setIsStrictModeForDevtools} from './ReactFiberDevToolsHook'; import assign from 'shared/assign'; export type Update = { - // TODO: Temporary field. Will remove this by storing a map of - // transition -> event time on the root. - eventTime: number, lane: Lane, tag: 0 | 1 | 2 | 3, @@ -208,9 +205,8 @@ export function cloneUpdateQueue( } } -export function createUpdate(eventTime: number, lane: Lane): Update { +export function createUpdate(lane: Lane): Update { const update: Update = { - eventTime, lane, tag: UpdateState, @@ -331,7 +327,6 @@ export function enqueueCapturedUpdate( let update: Update = firstBaseUpdate; do { const clone: Update = { - eventTime: update.eventTime, lane: update.lane, tag: update.tag, @@ -540,9 +535,6 @@ export function processUpdateQueue( let update: Update = firstBaseUpdate; do { - // TODO: Don't need this field anymore - const updateEventTime = update.eventTime; - // An extra OffscreenLane bit is added to updates that were made to // a hidden tree, so that we can distinguish them from updates that were // already there when the tree was hidden. @@ -561,7 +553,6 @@ export function processUpdateQueue( // skipped update, the previous update/state is the new base // update/state. const clone: Update = { - eventTime: updateEventTime, lane: updateLane, tag: update.tag, @@ -583,7 +574,6 @@ export function processUpdateQueue( if (newLastBaseUpdate !== null) { const clone: Update = { - eventTime: updateEventTime, // This update is going to be committed so we never want uncommit // it. Using NoLane works because 0 is a subset of all bitmasks, so // this will never be skipped by the check above. diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index eb74663bf6814..22089c78d4bbe 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -2525,10 +2525,10 @@ function refreshCache(fiber: Fiber, seedKey: ?() => T, seedValue: T): void { case HostRoot: { // Schedule an update on the cache boundary to trigger a refresh. const lane = requestUpdateLane(provider); - const eventTime = requestEventTime(); - const refreshUpdate = createLegacyQueueUpdate(eventTime, lane); + const refreshUpdate = createLegacyQueueUpdate(lane); const root = enqueueLegacyQueueUpdate(provider, refreshUpdate, lane); if (root !== null) { + const eventTime = requestEventTime(); scheduleUpdateOnFiber(root, provider, lane, eventTime); entangleLegacyQueueTransitions(root, provider, lane); } diff --git a/packages/react-reconciler/src/ReactFiberNewContext.js b/packages/react-reconciler/src/ReactFiberNewContext.js index 9e9abfb620798..80bade220d1e1 100644 --- a/packages/react-reconciler/src/ReactFiberNewContext.js +++ b/packages/react-reconciler/src/ReactFiberNewContext.js @@ -26,7 +26,6 @@ import { } from './ReactWorkTags'; import { NoLanes, - NoTimestamp, isSubsetOfLanes, includesSomeLane, mergeLanes, @@ -271,7 +270,7 @@ function propagateContextChange_eager( if (fiber.tag === ClassComponent) { // Schedule a force update on the work-in-progress. const lane = pickArbitraryLane(renderLanes); - const update = createUpdate(NoTimestamp, lane); + const update = createUpdate(lane); update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the // update to the current fiber, too, which means it will persist even if diff --git a/packages/react-reconciler/src/ReactFiberReconciler.js b/packages/react-reconciler/src/ReactFiberReconciler.js index fd80f0933b4c8..adf3316fa49ad 100644 --- a/packages/react-reconciler/src/ReactFiberReconciler.js +++ b/packages/react-reconciler/src/ReactFiberReconciler.js @@ -308,11 +308,11 @@ export function createHydrationContainer( // the update to schedule work on the root fiber (and, for legacy roots, to // enqueue the callback if one is provided). const current = root.current; - const eventTime = requestEventTime(); const lane = requestUpdateLane(current); - const update = createUpdate(eventTime, lane); + const update = createUpdate(lane); update.callback = callback !== undefined && callback !== null ? callback : null; + const eventTime = requestEventTime(); enqueueUpdate(current, update, lane); scheduleInitialHydrationOnRoot(root, lane, eventTime); @@ -329,7 +329,6 @@ export function updateContainer( onScheduleRoot(container, element); } const current = container.current; - const eventTime = requestEventTime(); const lane = requestUpdateLane(current); if (enableSchedulingProfiler) { @@ -360,7 +359,7 @@ export function updateContainer( } } - const update = createUpdate(eventTime, lane); + const update = createUpdate(lane); // Caution: React DevTools currently depends on this property // being called "element". update.payload = {element}; @@ -381,6 +380,7 @@ export function updateContainer( const root = enqueueUpdate(current, update, lane); if (root !== null) { + const eventTime = requestEventTime(); scheduleUpdateOnFiber(root, current, lane, eventTime); entangleTransitions(root, current, lane); } diff --git a/packages/react-reconciler/src/ReactFiberThrow.js b/packages/react-reconciler/src/ReactFiberThrow.js index f1067ba9382b2..5d82b8dbe7e97 100644 --- a/packages/react-reconciler/src/ReactFiberThrow.js +++ b/packages/react-reconciler/src/ReactFiberThrow.js @@ -69,7 +69,6 @@ import {logComponentSuspended} from './DebugTracing'; import {isDevToolsPresent} from './ReactFiberDevToolsHook'; import { SyncLane, - NoTimestamp, includesSomeLane, mergeLanes, pickArbitraryLane, @@ -86,7 +85,7 @@ function createRootErrorUpdate( errorInfo: CapturedValue, lane: Lane, ): Update { - const update = createUpdate(NoTimestamp, lane); + const update = createUpdate(lane); // Unmount the root by rendering null. update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property @@ -105,7 +104,7 @@ function createClassErrorUpdate( errorInfo: CapturedValue, lane: Lane, ): Update { - const update = createUpdate(NoTimestamp, lane); + const update = createUpdate(lane); update.tag = CaptureUpdate; const getDerivedStateFromError = fiber.type.getDerivedStateFromError; if (typeof getDerivedStateFromError === 'function') { @@ -253,7 +252,7 @@ function markSuspenseBoundaryShouldCapture( // When we try rendering again, we should not reuse the current fiber, // since it's known to be in an inconsistent state. Use a force update to // prevent a bail out. - const update = createUpdate(NoTimestamp, SyncLane); + const update = createUpdate(SyncLane); update.tag = ForceUpdate; enqueueUpdate(sourceFiber, update, SyncLane); } From bfb9cbd8ca2d042677056110887cc62d438f665f Mon Sep 17 00:00:00 2001 From: lauren Date: Thu, 23 Feb 2023 10:59:22 -0500 Subject: [PATCH 002/103] [difftrain] Make github sha clickable for easier debugging (#26225) --- .github/workflows/commit_artifacts.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/commit_artifacts.yml b/.github/workflows/commit_artifacts.yml index 4d5e2853ac86b..2c32bef7cb3a0 100644 --- a/.github/workflows/commit_artifacts.yml +++ b/.github/workflows/commit_artifacts.yml @@ -152,7 +152,7 @@ jobs: commit_message: | ${{ github.event.head_commit.message }} - DiffTrain build for commit ${{ github.sha }}. + DiffTrain build for [${{ github.sha }}](https://github.com/facebook/react/commit/${{ github.sha }}) branch: builds/facebook-www commit_user_name: ${{ github.actor }} commit_user_email: ${{ github.actor }}@users.noreply.github.com From ca2cf319fdfcf6e5f048e082f5169bc1b849c129 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Thu, 23 Feb 2023 16:53:11 -0500 Subject: [PATCH 003/103] [DevTools] permanently polyfill for rAF in devtools_page (#26193) ## Summary We had this as a temporary fix for #24626. Now that Chrome team decides to turn the flag on again (with good reasons explained in https://bugs.chromium.org/p/chromium/issues/detail?id=1241986#c31), we will turn it into a long term solution. In the future, we want to explore whether we can render React elements on panel.html instead, as `requestAnimationFrame` produces higher quality animation. ## How did you test this change? Tested on local build with "Throttle non-visible cross-origin iframes" flag enabled. --- .../react-devtools-extensions/src/main.js | 37 +++++++------------ 1 file changed, 14 insertions(+), 23 deletions(-) diff --git a/packages/react-devtools-extensions/src/main.js b/packages/react-devtools-extensions/src/main.js index 1e1fd25ad0d08..eccea0177b26e 100644 --- a/packages/react-devtools-extensions/src/main.js +++ b/packages/react-devtools-extensions/src/main.js @@ -30,29 +30,20 @@ const LOCAL_STORAGE_SUPPORTS_PROFILING_KEY = const isChrome = getBrowserName() === 'Chrome'; const isEdge = getBrowserName() === 'Edge'; -// since Chromium v102, requestAnimationFrame no longer fires in devtools_page (i.e. this file) -// mock requestAnimationFrame with setTimeout as a temporary workaround -// https://github.com/facebook/react/issues/24626 -if (isChrome || isEdge) { - const timeoutID = setTimeout(() => { - // if requestAnimationFrame is not working, polyfill it - // The polyfill is based on https://gist.github.com/jalbam/5fe05443270fa6d8136238ec72accbc0 - const FRAME_TIME = 16; - let lastTime = 0; - window.requestAnimationFrame = function (callback, element) { - const now = window.performance.now(); - const nextTime = Math.max(lastTime + FRAME_TIME, now); - return setTimeout(function () { - callback((lastTime = nextTime)); - }, nextTime - now); - }; - window.cancelAnimationFrame = clearTimeout; - }, 400); - - requestAnimationFrame(() => { - clearTimeout(timeoutID); - }); -} +// rAF never fires on devtools_page (because it's in the background) +// https://bugs.chromium.org/p/chromium/issues/detail?id=1241986#c31 +// Since we render React elements here, we need to polyfill it with setTimeout +// The polyfill is based on https://gist.github.com/jalbam/5fe05443270fa6d8136238ec72accbc0 +const FRAME_TIME = 16; +let lastTime = 0; +window.requestAnimationFrame = function (callback, element) { + const now = window.performance.now(); + const nextTime = Math.max(lastTime + FRAME_TIME, now); + return setTimeout(function () { + callback((lastTime = nextTime)); + }, nextTime - now); +}; +window.cancelAnimationFrame = clearTimeout; let panelCreated = false; From 96cdeaf89bfde7551b4ffe4d685da169b780f2f7 Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Fri, 24 Feb 2023 11:33:54 -0800 Subject: [PATCH 004/103] [Fizz Node] Fix null bytes written at text chunk boundaries (#26228) We encode strings 2048 UTF-8 bytes at a time. If the string we are encoding crosses to the next chunk but the current chunk doesn't fit an integral number of characters, we need to make sure not to send the whole buffer, only the bytes that are actually meaningful. Fixes #24985. I was able to verify that this fixes the repro shared in the issue (be careful when testing because the null bytes do not show when printed to my terminal, at least). However, I don't see a clear way to add a test for this that will be resilient to small changes in how we encode the markup (since it depends on where specific multibyte characters fall against the 2048-byte boundaries). --- .../src/__tests__/ReactDOMFizzServerNode-test.js | 13 +++++++++++++ .../react-server/src/ReactServerStreamConfigNode.js | 8 +++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js index 2f0d5bb98ce00..11c7043e2b9de 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFizzServerNode-test.js @@ -635,4 +635,17 @@ describe('ReactDOMFizzServerNode', () => { expect(rendered).toBe(false); expect(isComplete).toBe(true); }); + + it('should encode multibyte characters correctly without nulls (#24985)', () => { + const {writable, output} = getTestWritable(); + const {pipe} = ReactDOMFizzServer.renderToPipeableStream( +
{Array(700).fill('ののの')}
, + ); + pipe(writable); + jest.runAllTimers(); + expect(output.result.indexOf('\u0000')).toBe(-1); + expect(output.result).toEqual( + '
' + Array(700).fill('ののの').join('') + '
', + ); + }); }); diff --git a/packages/react-server/src/ReactServerStreamConfigNode.js b/packages/react-server/src/ReactServerStreamConfigNode.js index 807dafe5edf6e..16a773314d679 100644 --- a/packages/react-server/src/ReactServerStreamConfigNode.js +++ b/packages/react-server/src/ReactServerStreamConfigNode.js @@ -75,12 +75,14 @@ function writeStringChunk(destination: Destination, stringChunk: string) { writtenBytes += written; if (read < stringChunk.length) { - writeToDestination(destination, (currentView: any)); + writeToDestination( + destination, + (currentView: any).subarray(0, writtenBytes), + ); currentView = new Uint8Array(VIEW_SIZE); writtenBytes = textEncoder.encodeInto( stringChunk.slice(read), - // $FlowFixMe[incompatible-call] found when upgrading Flow - currentView, + (currentView: any), ).written; } From a8f971b7a669a9a6321b9f3cea820f68b2e4ac6e Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Fri, 24 Feb 2023 12:06:27 -0800 Subject: [PATCH 005/103] Switch to mount dispatcher after use() when needed (#26232) When resuming a suspended render, there may be more Hooks to be called that weren't seen the previous time through. Make sure to switch to the mount dispatcher when calling use() if the next Hook call should be treated as a mount. Fixes #25964. --- .../react-reconciler/src/ReactFiberHooks.js | 70 +++++---- .../src/__tests__/ReactHooks-test.internal.js | 2 +- .../src/__tests__/ReactThenable-test.js | 146 +++++++++++++++++- scripts/error-codes/codes.json | 3 +- 4 files changed, 187 insertions(+), 34 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberHooks.js b/packages/react-reconciler/src/ReactFiberHooks.js index 22089c78d4bbe..6741a55e4b42f 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.js +++ b/packages/react-reconciler/src/ReactFiberHooks.js @@ -658,10 +658,6 @@ export function replaySuspendedComponentWithHooks( // only get reset when the component either completes (finishRenderingHooks) // or unwinds (resetHooksOnUnwind). if (__DEV__) { - hookTypesDev = - current !== null - ? ((current._debugHookTypes: any): Array) - : null; hookTypesUpdateIndexDev = -1; // Used for hot reloading: ignorePreviousDependencies = @@ -696,8 +692,13 @@ function renderWithHooksAgain( let numberOfReRenders: number = 0; let children; do { - didScheduleRenderPhaseUpdateDuringThisPass = false; + if (didScheduleRenderPhaseUpdateDuringThisPass) { + // It's possible that a use() value depended on a state that was updated in + // this rerender, so we need to watch for different thenables this time. + thenableState = null; + } thenableIndexCounter = 0; + didScheduleRenderPhaseUpdateDuringThisPass = false; if (numberOfReRenders >= RE_RENDER_LIMIT) { throw new Error( @@ -841,8 +842,7 @@ function updateWorkInProgressHook(): Hook { // This function is used both for updates and for re-renders triggered by a // render phase update. It assumes there is either a current hook we can // clone, or a work-in-progress hook from a previous render pass that we can - // use as a base. When we reach the end of the base list, we must switch to - // the dispatcher used for mounts. + // use as a base. let nextCurrentHook: null | Hook; if (currentHook === null) { const current = currentlyRenderingFiber.alternate; @@ -876,16 +876,10 @@ function updateWorkInProgressHook(): Hook { if (currentFiber === null) { // This is the initial render. This branch is reached when the component // suspends, resumes, then renders an additional hook. - const newHook: Hook = { - memoizedState: null, - - baseState: null, - baseQueue: null, - queue: null, - - next: null, - }; - nextCurrentHook = newHook; + // Should never be reached because we should switch to the mount dispatcher first. + throw new Error( + 'Update hook called on initial render. This is likely a bug in React. Please file an issue.', + ); } else { // This is an update. We should always have a current hook. throw new Error('Rendered more hooks than during the previous render.'); @@ -951,7 +945,24 @@ function use(usable: Usable): T { if (thenableState === null) { thenableState = createThenableState(); } - return trackUsedThenable(thenableState, thenable, index); + const result = trackUsedThenable(thenableState, thenable, index); + if ( + currentlyRenderingFiber.alternate === null && + (workInProgressHook === null + ? currentlyRenderingFiber.memoizedState === null + : workInProgressHook.next === null) + ) { + // Initial render, and either this is the first time the component is + // called, or there were no Hooks called after this use() the previous + // time (perhaps because it threw). Subsequent Hook calls should use the + // mount dispatcher. + if (__DEV__) { + ReactCurrentDispatcher.current = HooksDispatcherOnMountInDEV; + } else { + ReactCurrentDispatcher.current = HooksDispatcherOnMount; + } + } + return result; } else if ( usable.$$typeof === REACT_CONTEXT_TYPE || usable.$$typeof === REACT_SERVER_CONTEXT_TYPE @@ -1998,6 +2009,7 @@ function updateEffectImpl( const nextDeps = deps === undefined ? null : deps; let destroy = undefined; + // currentHook is null when rerendering after a render phase state update. if (currentHook !== null) { const prevEffect = currentHook.memoizedState; destroy = prevEffect.destroy; @@ -2250,12 +2262,10 @@ function updateCallback(callback: T, deps: Array | void | null): T { const hook = updateWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; const prevState = hook.memoizedState; - if (prevState !== null) { - if (nextDeps !== null) { - const prevDeps: Array | null = prevState[1]; - if (areHookInputsEqual(nextDeps, prevDeps)) { - return prevState[0]; - } + if (nextDeps !== null) { + const prevDeps: Array | null = prevState[1]; + if (areHookInputsEqual(nextDeps, prevDeps)) { + return prevState[0]; } } hook.memoizedState = [callback, nextDeps]; @@ -2283,13 +2293,11 @@ function updateMemo( const hook = updateWorkInProgressHook(); const nextDeps = deps === undefined ? null : deps; const prevState = hook.memoizedState; - if (prevState !== null) { - // Assume these are defined. If they're not, areHookInputsEqual will warn. - if (nextDeps !== null) { - const prevDeps: Array | null = prevState[1]; - if (areHookInputsEqual(nextDeps, prevDeps)) { - return prevState[0]; - } + // Assume these are defined. If they're not, areHookInputsEqual will warn. + if (nextDeps !== null) { + const prevDeps: Array | null = prevState[1]; + if (areHookInputsEqual(nextDeps, prevDeps)) { + return prevState[0]; } } if (shouldDoubleInvokeUserFnsInHooksDEV) { diff --git a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js index 7dc6221d6c60a..f27502094cad0 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactHooks-test.internal.js @@ -1076,7 +1076,7 @@ describe('ReactHooks', () => { expect(() => { ReactTestRenderer.create(); }).toThrow( - 'Should have a queue. This is likely a bug in React. Please file an issue.', + 'Update hook called on initial render. This is likely a bug in React. Please file an issue.', ); }).toErrorDev([ 'Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks', diff --git a/packages/react-reconciler/src/__tests__/ReactThenable-test.js b/packages/react-reconciler/src/__tests__/ReactThenable-test.js index eae80546ba5e8..cc51d48c669e3 100644 --- a/packages/react-reconciler/src/__tests__/ReactThenable-test.js +++ b/packages/react-reconciler/src/__tests__/ReactThenable-test.js @@ -5,6 +5,7 @@ let ReactNoop; let Scheduler; let act; let use; +let useDebugValue; let useState; let useMemo; let Suspense; @@ -21,6 +22,7 @@ describe('ReactThenable', () => { Scheduler = require('scheduler'); act = require('jest-react').act; use = React.use; + useDebugValue = React.useDebugValue; useState = React.useState; useMemo = React.useMemo; Suspense = React.Suspense; @@ -794,7 +796,7 @@ describe('ReactThenable', () => { expect(root).toMatchRenderedOutput('(empty)'); }); - test('when replaying a suspended component, reuses the hooks computed during the previous attempt', async () => { + test('when replaying a suspended component, reuses the hooks computed during the previous attempt (Memo)', async () => { function ExcitingText({text}) { // This computes the uppercased version of some text. Pretend it's an // expensive operation that we want to reuse. @@ -846,6 +848,118 @@ describe('ReactThenable', () => { ]); }); + test('when replaying a suspended component, reuses the hooks computed during the previous attempt (State)', async () => { + let _setFruit; + let _setVegetable; + function Kitchen() { + const [fruit, setFruit] = useState('apple'); + _setFruit = setFruit; + const usedFruit = use(getAsyncText(fruit)); + const [vegetable, setVegetable] = useState('carrot'); + _setVegetable = setVegetable; + return ; + } + + // Initial render. + const root = ReactNoop.createRoot(); + await act(async () => { + startTransition(() => { + root.render(); + }); + }); + expect(Scheduler).toHaveYielded(['Async text requested [apple]']); + expect(root).toMatchRenderedOutput(null); + await act(async () => { + resolveTextRequests('apple'); + }); + expect(Scheduler).toHaveYielded([ + 'Async text requested [apple]', + 'apple carrot', + ]); + expect(root).toMatchRenderedOutput('apple carrot'); + + // Update the state variable after the use(). + await act(async () => { + startTransition(() => { + _setVegetable('dill'); + }); + }); + expect(Scheduler).toHaveYielded(['Async text requested [apple]']); + expect(root).toMatchRenderedOutput('apple carrot'); + await act(async () => { + resolveTextRequests('apple'); + }); + expect(Scheduler).toHaveYielded([ + 'Async text requested [apple]', + 'apple dill', + ]); + expect(root).toMatchRenderedOutput('apple dill'); + + // Update the state variable before the use(). The second state is maintained. + await act(async () => { + startTransition(() => { + _setFruit('banana'); + }); + }); + expect(Scheduler).toHaveYielded(['Async text requested [banana]']); + expect(root).toMatchRenderedOutput('apple dill'); + await act(async () => { + resolveTextRequests('banana'); + }); + expect(Scheduler).toHaveYielded([ + 'Async text requested [banana]', + 'banana dill', + ]); + expect(root).toMatchRenderedOutput('banana dill'); + }); + + test('when replaying a suspended component, reuses the hooks computed during the previous attempt (DebugValue+State)', async () => { + // Make sure we don't get a Hook mismatch warning on updates if there were non-stateful Hooks before the use(). + let _setLawyer; + function Lexicon() { + useDebugValue(123); + const avocado = use(getAsyncText('aguacate')); + const [lawyer, setLawyer] = useState('abogado'); + _setLawyer = setLawyer; + return ; + } + + // Initial render. + const root = ReactNoop.createRoot(); + await act(async () => { + startTransition(() => { + root.render(); + }); + }); + expect(Scheduler).toHaveYielded(['Async text requested [aguacate]']); + expect(root).toMatchRenderedOutput(null); + await act(async () => { + resolveTextRequests('aguacate'); + }); + expect(Scheduler).toHaveYielded([ + 'Async text requested [aguacate]', + 'aguacate abogado', + ]); + expect(root).toMatchRenderedOutput('aguacate abogado'); + + // Now update the state. + await act(async () => { + startTransition(() => { + _setLawyer('avocat'); + }); + }); + expect(Scheduler).toHaveYielded(['Async text requested [aguacate]']); + expect(root).toMatchRenderedOutput('aguacate abogado'); + await act(async () => { + resolveTextRequests('aguacate'); + }); + expect(Scheduler).toHaveYielded([ + 'Async text requested [aguacate]', + 'aguacate avocat', + ]); + expect(root).toMatchRenderedOutput('aguacate avocat'); + }); + // @gate enableUseHook test( 'wrap an async function with useMemo to skip running the function ' + @@ -1021,4 +1135,34 @@ describe('ReactThenable', () => { expect(Scheduler).toHaveYielded(['Async text requested [C]', 'C']); expect(root).toMatchRenderedOutput('ABC'); }); + + // @gate enableUseHook + test('use() combined with render phase updates', async () => { + function Async() { + const a = use(Promise.resolve('A')); + const [count, setCount] = useState(0); + if (count === 0) { + setCount(1); + } + const usedCount = use(Promise.resolve(count)); + return ; + } + + function App() { + return ( + }> + + + ); + } + + const root = ReactNoop.createRoot(); + await act(async () => { + startTransition(() => { + root.render(); + }); + }); + expect(Scheduler).toHaveYielded(['A1']); + expect(root).toMatchRenderedOutput('A1'); + }); }); diff --git a/scripts/error-codes/codes.json b/scripts/error-codes/codes.json index cc822f2e0abbd..0e467fc5895ed 100644 --- a/scripts/error-codes/codes.json +++ b/scripts/error-codes/codes.json @@ -451,5 +451,6 @@ "463": "ReactDOMServer.renderToNodeStream(): The Node Stream API is not available in Bun. Use ReactDOMServer.renderToReadableStream() instead.", "464": "ReactDOMServer.renderToStaticNodeStream(): The Node Stream API is not available in Bun. Use ReactDOMServer.renderToReadableStream() instead.", "465": "enableFizzExternalRuntime without enableFloat is not supported. This should never appear in production, since it means you are using a misconfigured React bundle.", - "466": "Trying to call a function from \"use server\" but the callServer option was not implemented in your router runtime." + "466": "Trying to call a function from \"use server\" but the callServer option was not implemented in your router runtime.", + "467": "Update hook called on initial render. This is likely a bug in React. Please file an issue." } \ No newline at end of file From 564166099b5f46dd33f3356b01a72c0314103a18 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Fri, 24 Feb 2023 15:13:05 -0500 Subject: [PATCH 006/103] [DevTools] remove script tag immediately (#26233) Fixes https://github.com/facebook/react/issues/25924 for React DevTools specifically. ## Summary If we remove the script after it's loaded, it creates a race condition with other code. If some other code is searching for the first script tag or first element of the document, this might broke it. ## How did you test this change? I've tested in my local build that even if we remove the script tag immediately, the code is still correctly executed. --- .../src/contentScripts/prepareInjection.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/react-devtools-extensions/src/contentScripts/prepareInjection.js b/packages/react-devtools-extensions/src/contentScripts/prepareInjection.js index b5d667d26254a..4ab0500f59ddb 100644 --- a/packages/react-devtools-extensions/src/contentScripts/prepareInjection.js +++ b/packages/react-devtools-extensions/src/contentScripts/prepareInjection.js @@ -26,10 +26,8 @@ function injectScriptSync(src) { function injectScriptAsync(src) { const script = document.createElement('script'); script.src = src; - script.onload = function () { - script.remove(); - }; nullthrows(document.documentElement).appendChild(script); + nullthrows(script.parentNode).removeChild(script); } let lastDetectionResult; From e7d7d4cb4b61624c5762521370a58d941c1c46e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Sat, 25 Feb 2023 12:10:39 -0500 Subject: [PATCH 007/103] Move Flight Fixture to use Middleware instead of WebDevServer (#26246) This lets us put it in the same server that would be serving this content in a more real world scenario. I also de-CRA:ified this a bit by simplifying pieces we don't need. I have more refactors coming for the SSR pieces but since many are eyeing these fixtures right now I figured I'd push earlier. The design here is that there are two servers: - Global - representing a "CDN" which will also include the SSR server. - Regional - representing something close to the data with low waterfall costs which include the RSC server. This is just an example. These are using the "unbundled" strategy for the RSC server just to show a simple case, but an implementation can use a bundled SSR server. A smart SSR bundler could also put RSC and SSR in the same server and even the same JS environment. It just need to ensure that the module graphs are kept separately - so that the `react-server` condition is respected. This include `react` itself. React will start breaking if this isn't respected because the runtime will get the wrong copy of `react`. Technically, you don't need the *entire* module graph to be separated. It just needs to be any part of the graph that depends on a fork. Like if "Client A" -> "foo" and "Server B" -> "foo", then it's ok for the module "foo" to be shared. However if "foo" -> "bar", and "bar" is forked by the "react-server" condition, then "foo" also needs to be duplicated in the module graph so that it can get two copies of "bar". --- fixtures/flight/config/getHttpsConfig.js | 66 - fixtures/flight/config/modules.js | 2 +- fixtures/flight/config/paths.js | 1 - fixtures/flight/config/webpack.config.js | 47 +- .../persistentCache/createEnvironmentHash.js | 9 - .../flight/config/webpackDevServer.config.js | 133 -- fixtures/flight/package.json | 19 +- fixtures/flight/scripts/build.js | 12 +- fixtures/flight/scripts/start.js | 154 -- fixtures/flight/server/cli.js | 84 - fixtures/flight/server/global.js | 96 ++ fixtures/flight/server/handler.js | 51 - fixtures/flight/server/package.json | 3 +- fixtures/flight/server/region.js | 124 ++ fixtures/flight/yarn.lock | 1359 +---------------- 15 files changed, 293 insertions(+), 1867 deletions(-) delete mode 100644 fixtures/flight/config/getHttpsConfig.js delete mode 100644 fixtures/flight/config/webpack/persistentCache/createEnvironmentHash.js delete mode 100644 fixtures/flight/config/webpackDevServer.config.js delete mode 100644 fixtures/flight/scripts/start.js delete mode 100644 fixtures/flight/server/cli.js create mode 100644 fixtures/flight/server/global.js delete mode 100644 fixtures/flight/server/handler.js create mode 100644 fixtures/flight/server/region.js diff --git a/fixtures/flight/config/getHttpsConfig.js b/fixtures/flight/config/getHttpsConfig.js deleted file mode 100644 index 2120a07ec331b..0000000000000 --- a/fixtures/flight/config/getHttpsConfig.js +++ /dev/null @@ -1,66 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const crypto = require('crypto'); -const chalk = require('react-dev-utils/chalk'); -const paths = require('./paths'); - -// Ensure the certificate and key provided are valid and if not -// throw an easy to debug error -function validateKeyAndCerts({cert, key, keyFile, crtFile}) { - let encrypted; - try { - // publicEncrypt will throw an error with an invalid cert - encrypted = crypto.publicEncrypt(cert, Buffer.from('test')); - } catch (err) { - throw new Error( - `The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}` - ); - } - - try { - // privateDecrypt will throw an error with an invalid key - crypto.privateDecrypt(key, encrypted); - } catch (err) { - throw new Error( - `The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${ - err.message - }` - ); - } -} - -// Read file and throw an error if it doesn't exist -function readEnvFile(file, type) { - if (!fs.existsSync(file)) { - throw new Error( - `You specified ${chalk.cyan( - type - )} in your env, but the file "${chalk.yellow(file)}" can't be found.` - ); - } - return fs.readFileSync(file); -} - -// Get the https config -// Return cert files if provided in env, otherwise just true or false -function getHttpsConfig() { - const {SSL_CRT_FILE, SSL_KEY_FILE, HTTPS} = process.env; - const isHttps = HTTPS === 'true'; - - if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) { - const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE); - const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE); - const config = { - cert: readEnvFile(crtFile, 'SSL_CRT_FILE'), - key: readEnvFile(keyFile, 'SSL_KEY_FILE'), - }; - - validateKeyAndCerts({...config, keyFile, crtFile}); - return config; - } - return isHttps; -} - -module.exports = getHttpsConfig; diff --git a/fixtures/flight/config/modules.js b/fixtures/flight/config/modules.js index d63e41d78dc7e..79723ef3f5f9f 100644 --- a/fixtures/flight/config/modules.js +++ b/fixtures/flight/config/modules.js @@ -3,7 +3,7 @@ const fs = require('fs'); const path = require('path'); const paths = require('./paths'); -const chalk = require('react-dev-utils/chalk'); +const chalk = require('chalk'); const resolve = require('resolve'); /** diff --git a/fixtures/flight/config/paths.js b/fixtures/flight/config/paths.js index 01f2dd1fd295b..1c7df49db7dbe 100644 --- a/fixtures/flight/config/paths.js +++ b/fixtures/flight/config/paths.js @@ -64,7 +64,6 @@ module.exports = { appJsConfig: resolveApp('jsconfig.json'), yarnLockFile: resolveApp('yarn.lock'), testsSetup: resolveModule(resolveApp, 'src/setupTests'), - proxySetup: resolveApp('src/setupProxy.js'), appNodeModules: resolveApp('node_modules'), appWebpackCache: resolveApp('node_modules/.cache'), appTsBuildInfoFile: resolveApp('node_modules/.cache/tsconfig.tsbuildinfo'), diff --git a/fixtures/flight/config/webpack.config.js b/fixtures/flight/config/webpack.config.js index 1ed057352404d..f1579c3a7b7b0 100644 --- a/fixtures/flight/config/webpack.config.js +++ b/fixtures/flight/config/webpack.config.js @@ -5,6 +5,7 @@ const ReactFlightWebpackPlugin = require('react-server-dom-webpack/plugin'); // Fork End const fs = require('fs'); +const {createHash} = require('crypto'); const path = require('path'); const webpack = require('webpack'); const resolve = require('resolve'); @@ -14,9 +15,7 @@ const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin'); const TerserPlugin = require('terser-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const {WebpackManifestPlugin} = require('webpack-manifest-plugin'); const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); -const WorkboxWebpackPlugin = require('workbox-webpack-plugin'); const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin'); const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent'); const ESLintPlugin = require('eslint-webpack-plugin'); @@ -30,7 +29,12 @@ const ForkTsCheckerWebpackPlugin = : require('react-dev-utils/ForkTsCheckerWebpackPlugin'); const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash'); +function createEnvironmentHash(env) { + const hash = createHash('md5'); + hash.update(JSON.stringify(env)); + + return hash.digest('hex'); +} // Source maps are resource heavy and can cause out of memory issue for large source files. const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false'; @@ -632,30 +636,6 @@ module.exports = function (webpackEnv) { filename: 'static/css/[name].[contenthash:8].css', chunkFilename: 'static/css/[name].[contenthash:8].chunk.css', }), - // Generate an asset manifest file with the following content: - // - "files" key: Mapping of all asset filenames to their corresponding - // output file so that tools can pick it up without having to parse - // `index.html` - // - "entrypoints" key: Array of files which are included in `index.html`, - // can be used to reconstruct the HTML if necessary - new WebpackManifestPlugin({ - fileName: 'asset-manifest.json', - publicPath: paths.publicUrlOrPath, - generate: (seed, files, entrypoints) => { - const manifestFiles = files.reduce((manifest, file) => { - manifest[file.name] = file.path; - return manifest; - }, seed); - const entrypointFiles = entrypoints.main.filter( - fileName => !fileName.endsWith('.map') - ); - - return { - files: manifestFiles, - entrypoints: entrypointFiles, - }; - }, - }), // Moment.js is an extremely popular library that bundles large locale files // by default due to how webpack interprets its code. This is a practical // solution that requires the user to opt into importing specific locales. @@ -665,19 +645,6 @@ module.exports = function (webpackEnv) { resourceRegExp: /^\.\/locale$/, contextRegExp: /moment$/, }), - // Generate a service worker script that will precache, and keep up to date, - // the HTML & assets that are part of the webpack build. - isEnvProduction && - fs.existsSync(swSrc) && - new WorkboxWebpackPlugin.InjectManifest({ - swSrc, - dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./, - exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/], - // Bump up the default maximum size (2mb) that's precached, - // to make lazy-loading failure scenarios less likely. - // See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270 - maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, - }), // TypeScript type checking useTypeScript && new ForkTsCheckerWebpackPlugin({ diff --git a/fixtures/flight/config/webpack/persistentCache/createEnvironmentHash.js b/fixtures/flight/config/webpack/persistentCache/createEnvironmentHash.js deleted file mode 100644 index 9f4c3f3551b32..0000000000000 --- a/fixtures/flight/config/webpack/persistentCache/createEnvironmentHash.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; -const {createHash} = require('crypto'); - -module.exports = env => { - const hash = createHash('md5'); - hash.update(JSON.stringify(env)); - - return hash.digest('hex'); -}; diff --git a/fixtures/flight/config/webpackDevServer.config.js b/fixtures/flight/config/webpackDevServer.config.js deleted file mode 100644 index 5b06a4f53b44d..0000000000000 --- a/fixtures/flight/config/webpackDevServer.config.js +++ /dev/null @@ -1,133 +0,0 @@ -'use strict'; - -const fs = require('fs'); -const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware'); -const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware'); -const ignoredFiles = require('react-dev-utils/ignoredFiles'); -const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware'); -const paths = require('./paths'); -const getHttpsConfig = require('./getHttpsConfig'); - -const host = process.env.HOST || '0.0.0.0'; -const sockHost = process.env.WDS_SOCKET_HOST; -const sockPath = process.env.WDS_SOCKET_PATH; // default: '/ws' -const sockPort = process.env.WDS_SOCKET_PORT; - -module.exports = function (proxy, allowedHost) { - const disableFirewall = - !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true'; - return { - // WebpackDevServer 2.4.3 introduced a security fix that prevents remote - // websites from potentially accessing local content through DNS rebinding: - // https://github.com/webpack/webpack-dev-server/issues/887 - // https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a - // However, it made several existing use cases such as development in cloud - // environment or subdomains in development significantly more complicated: - // https://github.com/facebook/create-react-app/issues/2271 - // https://github.com/facebook/create-react-app/issues/2233 - // While we're investigating better solutions, for now we will take a - // compromise. Since our WDS configuration only serves files in the `public` - // folder we won't consider accessing them a vulnerability. However, if you - // use the `proxy` feature, it gets more dangerous because it can expose - // remote code execution vulnerabilities in backends like Django and Rails. - // So we will disable the host check normally, but enable it if you have - // specified the `proxy` setting. Finally, we let you override it if you - // really know what you're doing with a special environment variable. - // Note: ["localhost", ".localhost"] will support subdomains - but we might - // want to allow setting the allowedHosts manually for more complex setups - allowedHosts: disableFirewall ? 'all' : [allowedHost], - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': '*', - 'Access-Control-Allow-Headers': '*', - }, - // Enable gzip compression of generated files. - compress: true, - static: { - // By default WebpackDevServer serves physical files from current directory - // in addition to all the virtual build products that it serves from memory. - // This is confusing because those files won’t automatically be available in - // production build folder unless we copy them. However, copying the whole - // project directory is dangerous because we may expose sensitive files. - // Instead, we establish a convention that only files in `public` directory - // get served. Our build script will copy `public` into the `build` folder. - // In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%: - // - // In JavaScript code, you can access it with `process.env.PUBLIC_URL`. - // Note that we only recommend to use `public` folder as an escape hatch - // for files like `favicon.ico`, `manifest.json`, and libraries that are - // for some reason broken when imported through webpack. If you just want to - // use an image, put it in `src` and `import` it from JavaScript instead. - directory: paths.appPublic, - publicPath: [paths.publicUrlOrPath], - // By default files from `contentBase` will not trigger a page reload. - watch: { - // Reportedly, this avoids CPU overload on some systems. - // https://github.com/facebook/create-react-app/issues/293 - // src/node_modules is not ignored to support absolute imports - // https://github.com/facebook/create-react-app/issues/1065 - ignored: ignoredFiles(paths.appSrc), - }, - }, - client: { - webSocketURL: { - // Enable custom sockjs pathname for websocket connection to hot reloading server. - // Enable custom sockjs hostname, pathname and port for websocket connection - // to hot reloading server. - hostname: sockHost, - pathname: sockPath, - port: sockPort, - }, - overlay: { - errors: true, - warnings: false, - }, - }, - devMiddleware: { - // Fork Start - writeToDisk: filePath => { - return /react-client-manifest\.json$/.test(filePath); - }, - // Fork End - - // It is important to tell WebpackDevServer to use the same "publicPath" path as - // we specified in the webpack config. When homepage is '.', default to serving - // from the root. - // remove last slash so user can land on `/test` instead of `/test/` - publicPath: paths.publicUrlOrPath.slice(0, -1), - }, - - https: getHttpsConfig(), - host, - historyApiFallback: { - // Paths with dots should still use the history fallback. - // See https://github.com/facebook/create-react-app/issues/387. - disableDotRule: true, - index: paths.publicUrlOrPath, - }, - // `proxy` is run between `before` and `after` `webpack-dev-server` hooks - proxy, - onBeforeSetupMiddleware(devServer) { - // Keep `evalSourceMapMiddleware` - // middlewares before `redirectServedPath` otherwise will not have any effect - // This lets us fetch source contents from webpack for the error overlay - devServer.app.use(evalSourceMapMiddleware(devServer)); - - if (fs.existsSync(paths.proxySetup)) { - // This registers user provided middleware for proxy reasons - require(paths.proxySetup)(devServer.app); - } - }, - onAfterSetupMiddleware(devServer) { - // Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match - devServer.app.use(redirectServedPath(paths.publicUrlOrPath)); - - // This service worker file is effectively a 'no-op' that will reset any - // previous service worker registered for the same host:port combination. - // We do this in development to avoid hitting the production cache if - // it used the same host and port. - // https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432 - devServer.app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath)); - }, - }; -}; diff --git a/fixtures/flight/package.json b/fixtures/flight/package.json index 3145a743e769a..57a93807f8296 100644 --- a/fixtures/flight/package.json +++ b/fixtures/flight/package.json @@ -15,11 +15,11 @@ "babel-loader": "^8.2.3", "babel-plugin-named-asset-import": "^0.3.8", "babel-preset-react-app": "^10.0.1", - "bfj": "^7.0.2", "body-parser": "^1.20.1", "browserslist": "^4.18.1", "camelcase": "^6.2.1", "case-sensitive-paths-webpack-plugin": "^2.4.0", + "compression": "^1.7.4", "concurrently": "^7.3.0", "css-loader": "^6.5.1", "css-minimizer-webpack-plugin": "^3.2.0", @@ -56,21 +56,18 @@ "style-loader": "^3.3.1", "tailwindcss": "^3.0.2", "terser-webpack-plugin": "^5.2.5", - "web-vitals": "^2.1.0", "webpack": "^5.64.4", - "webpack-dev-server": "^4.6.0", - "webpack-manifest-plugin": "^4.0.2", - "workbox-webpack-plugin": "^6.4.1" + "webpack-dev-middleware": "^5.3.1" }, "scripts": { "predev": "cp -r ../../build/oss-experimental/* ./node_modules/", "prebuild": "cp -r ../../build/oss-experimental/* ./node_modules/", - "dev": "concurrently \"npm run dev:server\" \"npm run dev:client\"", - "dev:client": "NODE_ENV=development BUILD_PATH=dist node scripts/start.js", - "dev:server": "NODE_ENV=development BUILD_PATH=dist nodemon -- --experimental-loader ./loader/index.js --conditions=react-server server", - "start": "node scripts/build.js && concurrently \"npm run start:server\" \"npm run start:client\"", - "start:client": "cd ./build && python3 -m http.server 3000", - "start:server": "NODE_ENV=production node --experimental-loader ./loader/index.js --conditions=react-server server", + "dev": "concurrently \"npm run dev:region\" \"npm run dev:global\"", + "dev:global": "NODE_ENV=development BUILD_PATH=dist node server/global", + "dev:region": "NODE_ENV=development BUILD_PATH=dist nodemon --watch src --watch dist -- --experimental-loader ./loader/index.js --conditions=react-server server/region", + "start": "node scripts/build.js && concurrently \"npm run start:region\" \"npm run start:global\"", + "start:global": "NODE_ENV=production node server/global", + "start:region": "NODE_ENV=production node --experimental-loader ./loader/index.js --conditions=react-server server/region", "build": "node scripts/build.js", "test": "node scripts/test.js --env=jsdom" }, diff --git a/fixtures/flight/scripts/build.js b/fixtures/flight/scripts/build.js index 20d12bd2ed56f..a32151857ced0 100644 --- a/fixtures/flight/scripts/build.js +++ b/fixtures/flight/scripts/build.js @@ -15,9 +15,8 @@ process.on('unhandledRejection', err => { require('../config/env'); const path = require('path'); -const chalk = require('react-dev-utils/chalk'); +const chalk = require('chalk'); const fs = require('fs-extra'); -const bfj = require('bfj'); const webpack = require('webpack'); const configFactory = require('../config/webpack.config'); const paths = require('../config/paths'); @@ -197,20 +196,13 @@ function build(previousFileSizes) { warnings: messages.warnings, }; - if (writeStatsJson) { - return bfj - .write(paths.appBuild + '/bundle-stats.json', stats.toJson()) - .then(() => resolve(resolveArgs)) - .catch(error => reject(new Error(error))); - } - return resolve(resolveArgs); }); }); } function copyPublicFolder() { - fs.copySync(paths.appPublic, paths.appBuild, { + fs.copySync('public', 'build', { dereference: true, filter: file => file !== paths.appHtml, }); diff --git a/fixtures/flight/scripts/start.js b/fixtures/flight/scripts/start.js deleted file mode 100644 index 75966a7d31f28..0000000000000 --- a/fixtures/flight/scripts/start.js +++ /dev/null @@ -1,154 +0,0 @@ -'use strict'; - -// Do this as the first thing so that any code reading it knows the right env. -process.env.BABEL_ENV = 'development'; -process.env.NODE_ENV = 'development'; - -// Makes the script crash on unhandled rejections instead of silently -// ignoring them. In the future, promise rejections that are not handled will -// terminate the Node.js process with a non-zero exit code. -process.on('unhandledRejection', err => { - throw err; -}); - -// Ensure environment variables are read. -require('../config/env'); - -const fs = require('fs'); -const chalk = require('react-dev-utils/chalk'); -const webpack = require('webpack'); -const WebpackDevServer = require('webpack-dev-server'); -const clearConsole = require('react-dev-utils/clearConsole'); -const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); -const { - choosePort, - createCompiler, - prepareProxy, - prepareUrls, -} = require('react-dev-utils/WebpackDevServerUtils'); -const openBrowser = require('react-dev-utils/openBrowser'); -const semver = require('semver'); -const paths = require('../config/paths'); -const configFactory = require('../config/webpack.config'); -const createDevServerConfig = require('../config/webpackDevServer.config'); -const getClientEnvironment = require('../config/env'); -const react = require(require.resolve('react', {paths: [paths.appPath]})); - -const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); -const useYarn = fs.existsSync(paths.yarnLockFile); -const isInteractive = process.stdout.isTTY; - -// Warn and crash if required files are missing -if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) { - process.exit(1); -} - -// Tools like Cloud9 rely on this. -const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 3000; -const HOST = process.env.HOST || '0.0.0.0'; - -if (process.env.HOST) { - console.log( - chalk.cyan( - `Attempting to bind to HOST environment variable: ${chalk.yellow( - chalk.bold(process.env.HOST) - )}` - ) - ); - console.log( - `If this was unintentional, check that you haven't mistakenly set it in your shell.` - ); - console.log( - `Learn more here: ${chalk.yellow('https://cra.link/advanced-config')}` - ); - console.log(); -} - -// We require that you explicitly set browsers and do not fall back to -// browserslist defaults. -const {checkBrowsers} = require('react-dev-utils/browsersHelper'); -checkBrowsers(paths.appPath, isInteractive) - .then(() => { - // We attempt to use the default port but if it is busy, we offer the user to - // run on a different port. `choosePort()` Promise resolves to the next free port. - return choosePort(HOST, DEFAULT_PORT); - }) - .then(port => { - if (port == null) { - // We have not found a port. - return; - } - - const config = configFactory('development'); - const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; - const appName = require(paths.appPackageJson).name; - - const useTypeScript = fs.existsSync(paths.appTsConfig); - const urls = prepareUrls( - protocol, - HOST, - port, - paths.publicUrlOrPath.slice(0, -1) - ); - // Create a webpack compiler that is configured with custom messages. - const compiler = createCompiler({ - appName, - config, - urls, - useYarn, - useTypeScript, - webpack, - }); - // Load proxy config - const proxySetting = require(paths.appPackageJson).proxy; - const proxyConfig = prepareProxy( - proxySetting, - paths.appPublic, - paths.publicUrlOrPath - ); - // Serve webpack assets generated by the compiler over a web server. - const serverConfig = { - ...createDevServerConfig(proxyConfig, urls.lanUrlForConfig), - host: HOST, - port, - }; - const devServer = new WebpackDevServer(serverConfig, compiler); - // Launch WebpackDevServer. - devServer.startCallback(() => { - if (isInteractive) { - clearConsole(); - } - - if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) { - console.log( - chalk.yellow( - `Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.` - ) - ); - } - - console.log(chalk.cyan('Starting the development server...\n')); - openBrowser(urls.localUrlForBrowser); - }); - - ['SIGINT', 'SIGTERM'].forEach(function (sig) { - process.on(sig, function () { - devServer.close(); - process.exit(); - }); - }); - - if (process.env.CI !== 'true') { - // Gracefully exit when stdin ends - process.stdin.on('end', function () { - devServer.close(); - process.exit(); - }); - } - }) - .catch(err => { - if (err && err.message) { - console.log(err.message); - } - process.exit(1); - }); diff --git a/fixtures/flight/server/cli.js b/fixtures/flight/server/cli.js deleted file mode 100644 index dea40db72ee59..0000000000000 --- a/fixtures/flight/server/cli.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict'; - -const register = require('react-server-dom-webpack/node-register'); -register(); - -const babelRegister = require('@babel/register'); -const path = require('path'); - -babelRegister({ - babelrc: false, - ignore: [ - /\/(build|node_modules)\//, - function (file) { - if ((path.dirname(file) + '/').startsWith(__dirname + '/')) { - // Ignore everything in this folder - // because it's a mix of CJS and ESM - // and working with raw code is easier. - return true; - } - return false; - }, - ], - presets: ['react-app'], - plugins: ['@babel/transform-modules-commonjs'], -}); - -const express = require('express'); -const bodyParser = require('body-parser'); -const app = express(); - -// Application -app.get('/', function (req, res) { - require('./handler.js')(req, res); -}); - -app.options('/', function (req, res) { - res.setHeader('Allow', 'Allow: GET,HEAD,POST'); - res.setHeader('Access-Control-Allow-Origin', '*'); - res.setHeader('Access-Control-Allow-Headers', 'rsc-action'); - res.end(); -}); - -app.post('/', bodyParser.text(), function (req, res) { - require('./handler.js')(req, res); -}); - -app.get('/todos', function (req, res) { - res.setHeader('Access-Control-Allow-Origin', '*'); - res.json([ - { - id: 1, - text: 'Shave yaks', - }, - { - id: 2, - text: 'Eat kale', - }, - ]); -}); - -app.listen(3001, () => { - console.log('Flight Server listening on port 3001...'); -}); - -app.on('error', function (error) { - if (error.syscall !== 'listen') { - throw error; - } - - var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; - - switch (error.code) { - case 'EACCES': - console.error(bind + ' requires elevated privileges'); - process.exit(1); - break; - case 'EADDRINUSE': - console.error(bind + ' is already in use'); - process.exit(1); - break; - default: - throw error; - } -}); diff --git a/fixtures/flight/server/global.js b/fixtures/flight/server/global.js new file mode 100644 index 0000000000000..a626129352683 --- /dev/null +++ b/fixtures/flight/server/global.js @@ -0,0 +1,96 @@ +'use strict'; + +// This is a server to host CDN distributed resources like Webpack bundles and SSR + +const path = require('path'); + +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = process.env.NODE_ENV; + +const register = require('react-server-dom-webpack/node-register'); +register(); + +const babelRegister = require('@babel/register'); +babelRegister({ + babelrc: false, + ignore: [ + /\/(build|node_modules)\//, + function (file) { + if ((path.dirname(file) + '/').startsWith(__dirname + '/')) { + // Ignore everything in this folder + // because it's a mix of CJS and ESM + // and working with raw code is easier. + return true; + } + return false; + }, + ], + presets: ['react-app'], + plugins: ['@babel/transform-modules-commonjs'], +}); + +// Ensure environment variables are read. +require('../config/env'); + +const fs = require('fs'); +const compress = require('compression'); +const chalk = require('chalk'); +const express = require('express'); +const app = express(); + +app.use(compress()); + +if (process.env.NODE_ENV === 'development') { + // In development we host the Webpack server for live bundling. + const webpack = require('webpack'); + const webpackMiddleware = require('webpack-dev-middleware'); + const paths = require('../config/paths'); + const configFactory = require('../config/webpack.config'); + const getClientEnvironment = require('../config/env'); + + const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1)); + + const HOST = '0.0.0.0'; + const PORT = 3000; + + const config = configFactory('development'); + const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'; + const appName = require(paths.appPackageJson).name; + + // Create a webpack compiler that is configured with custom messages. + const compiler = webpack(config); + const devMiddleware = { + writeToDisk: filePath => { + return /(react-client-manifest|react-ssr-manifest)\.json$/.test(filePath); + }, + publicPath: paths.publicUrlOrPath.slice(0, -1), + }; + app.use(webpackMiddleware(compiler, devMiddleware)); + app.use(express.static('public')); +} else { + // In production we host the static build output. + app.use(express.static('build')); +} + +app.listen(3000, () => { + console.log('Global Fizz/Webpack Server listening on port 3000...'); +}); + +app.on('error', function (error) { + if (error.syscall !== 'listen') { + throw error; + } + + switch (error.code) { + case 'EACCES': + console.error('port 3000 requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error('Port 3000 is already in use'); + process.exit(1); + break; + default: + throw error; + } +}); diff --git a/fixtures/flight/server/handler.js b/fixtures/flight/server/handler.js deleted file mode 100644 index b67147b7dca36..0000000000000 --- a/fixtures/flight/server/handler.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; - -const {readFile} = require('fs').promises; -const {resolve} = require('path'); -const React = require('react'); - -module.exports = async function (req, res) { - const {renderToPipeableStream} = await import( - 'react-server-dom-webpack/server' - ); - switch (req.method) { - case 'POST': { - const serverReference = JSON.parse(req.get('rsc-action')); - const {filepath, name} = serverReference; - const action = (await import(filepath))[name]; - // Validate that this is actually a function we intended to expose and - // not the client trying to invoke arbitrary functions. In a real app, - // you'd have a manifest verifying this before even importing it. - if (action.$$typeof !== Symbol.for('react.server.reference')) { - throw new Error('Invalid action'); - } - - const args = JSON.parse(req.body); - const result = action.apply(null, args); - - res.setHeader('Access-Control-Allow-Origin', '*'); - const {pipe} = renderToPipeableStream(result, {}); - pipe(res); - - return; - } - default: { - // const m = require('../src/App.js'); - const m = await import('../src/App.js'); - const dist = process.env.NODE_ENV === 'development' ? 'dist' : 'build'; - const data = await readFile( - resolve(__dirname, `../${dist}/react-client-manifest.json`), - 'utf8' - ); - const App = m.default.default || m.default; - res.setHeader('Access-Control-Allow-Origin', '*'); - const moduleMap = JSON.parse(data); - const {pipe} = renderToPipeableStream( - React.createElement(App), - moduleMap - ); - pipe(res); - return; - } - } -}; diff --git a/fixtures/flight/server/package.json b/fixtures/flight/server/package.json index ad9c35437eda5..5bbefffbabee3 100644 --- a/fixtures/flight/server/package.json +++ b/fixtures/flight/server/package.json @@ -1,4 +1,3 @@ { - "type": "commonjs", - "main": "./cli.js" + "type": "commonjs" } diff --git a/fixtures/flight/server/region.js b/fixtures/flight/server/region.js new file mode 100644 index 0000000000000..feda90f6ed8a3 --- /dev/null +++ b/fixtures/flight/server/region.js @@ -0,0 +1,124 @@ +'use strict'; + +// This is a server to host data-local resources like databases and RSC + +const path = require('path'); + +const register = require('react-server-dom-webpack/node-register'); +register(); + +const babelRegister = require('@babel/register'); +babelRegister({ + babelrc: false, + ignore: [ + /\/(build|node_modules)\//, + function (file) { + if ((path.dirname(file) + '/').startsWith(__dirname + '/')) { + // Ignore everything in this folder + // because it's a mix of CJS and ESM + // and working with raw code is easier. + return true; + } + return false; + }, + ], + presets: ['react-app'], + plugins: ['@babel/transform-modules-commonjs'], +}); + +const express = require('express'); +const bodyParser = require('body-parser'); +const app = express(); +const compress = require('compression'); + +app.use(compress()); + +// Application + +const {readFile} = require('fs').promises; + +const React = require('react'); + +app.get('/', async function (req, res) { + const {renderToPipeableStream} = await import( + 'react-server-dom-webpack/server' + ); + // const m = require('../src/App.js'); + const m = await import('../src/App.js'); + const dist = process.env.NODE_ENV === 'development' ? 'dist' : 'build'; + const data = await readFile( + path.resolve(__dirname, `../${dist}/react-client-manifest.json`), + 'utf8' + ); + const App = m.default.default || m.default; + res.setHeader('Access-Control-Allow-Origin', '*'); + const moduleMap = JSON.parse(data); + const {pipe} = renderToPipeableStream(React.createElement(App), moduleMap); + pipe(res); +}); + +app.options('/', function (req, res) { + res.setHeader('Allow', 'Allow: GET,HEAD,POST'); + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Headers', 'rsc-action'); + res.end(); +}); + +app.post('/', bodyParser.text(), async function (req, res) { + const {renderToPipeableStream} = await import( + 'react-server-dom-webpack/server' + ); + const serverReference = JSON.parse(req.get('rsc-action')); + const {filepath, name} = serverReference; + const action = (await import(filepath))[name]; + // Validate that this is actually a function we intended to expose and + // not the client trying to invoke arbitrary functions. In a real app, + // you'd have a manifest verifying this before even importing it. + if (action.$$typeof !== Symbol.for('react.server.reference')) { + throw new Error('Invalid action'); + } + + const args = JSON.parse(req.body); + const result = action.apply(null, args); + + res.setHeader('Access-Control-Allow-Origin', '*'); + const {pipe} = renderToPipeableStream(result, {}); + pipe(res); +}); + +app.get('/todos', function (req, res) { + res.setHeader('Access-Control-Allow-Origin', '*'); + res.json([ + { + id: 1, + text: 'Shave yaks', + }, + { + id: 2, + text: 'Eat kale', + }, + ]); +}); + +app.listen(3001, () => { + console.log('Regional Flight Server listening on port 3001...'); +}); + +app.on('error', function (error) { + if (error.syscall !== 'listen') { + throw error; + } + + switch (error.code) { + case 'EACCES': + console.error('port 3001 requires elevated privileges'); + process.exit(1); + break; + case 'EADDRINUSE': + console.error('Port 3001 is already in use'); + process.exit(1); + break; + default: + throw error; + } +}); diff --git a/fixtures/flight/yarn.lock b/fixtures/flight/yarn.lock index 687cfafec5297..ecbf97dede7f6 100644 --- a/fixtures/flight/yarn.lock +++ b/fixtures/flight/yarn.lock @@ -15,15 +15,6 @@ "@jridgewell/gen-mapping" "^0.1.0" "@jridgewell/trace-mapping" "^0.3.9" -"@apideck/better-ajv-errors@^0.3.1": - version "0.3.6" - resolved "https://registry.yarnpkg.com/@apideck/better-ajv-errors/-/better-ajv-errors-0.3.6.tgz#957d4c28e886a64a8141f7522783be65733ff097" - integrity sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA== - dependencies: - json-schema "^0.4.0" - jsonpointer "^5.0.0" - leven "^3.1.0" - "@babel/code-frame@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" @@ -74,27 +65,6 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.11.1", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.18.10" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" - integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.18.10" - "@babel/helper-compilation-targets" "^7.18.9" - "@babel/helper-module-transforms" "^7.18.9" - "@babel/helpers" "^7.18.9" - "@babel/parser" "^7.18.10" - "@babel/template" "^7.18.10" - "@babel/traverse" "^7.18.10" - "@babel/types" "^7.18.10" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.1" - semver "^6.3.0" - "@babel/core@^7.12.3": version "7.12.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" @@ -117,6 +87,27 @@ semver "^5.4.1" source-map "^0.5.0" +"@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": + version "7.18.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.10.tgz#39ad504991d77f1f3da91be0b8b949a5bc466fb8" + integrity sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.10" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.10" + "@babel/template" "^7.18.10" + "@babel/traverse" "^7.18.10" + "@babel/types" "^7.18.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + "@babel/eslint-parser@^7.16.3": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.18.9.tgz#255a63796819a97b7578751bb08ab9f2a375a031" @@ -289,13 +280,6 @@ dependencies: "@babel/types" "^7.18.9" -"@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" - integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== - dependencies: - "@babel/types" "^7.18.6" - "@babel/helper-module-imports@^7.12.1": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" @@ -303,6 +287,13 @@ dependencies: "@babel/types" "^7.12.5" +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== + dependencies: + "@babel/types" "^7.18.6" + "@babel/helper-module-transforms@^7.12.1": version "7.12.1" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" @@ -1190,7 +1181,7 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": +"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": version "7.18.10" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.10.tgz#83b8dfe70d7eea1aae5a10635ab0a5fe60dfc0f4" integrity sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA== @@ -1311,7 +1302,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.8.4": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== @@ -1861,11 +1852,6 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - "@nodelib/fs.scandir@2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" @@ -1902,43 +1888,6 @@ schema-utils "^3.0.0" source-map "^0.7.3" -"@rollup/plugin-babel@^5.2.0": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283" - integrity sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@rollup/pluginutils" "^3.1.0" - -"@rollup/plugin-node-resolve@^11.2.1": - version "11.2.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-11.2.1.tgz#82aa59397a29cd4e13248b106e6a4a1880362a60" - integrity sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - "@types/resolve" "1.17.1" - builtin-modules "^3.1.0" - deepmerge "^4.2.2" - is-module "^1.0.0" - resolve "^1.19.0" - -"@rollup/plugin-replace@^2.4.1": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.4.2.tgz#a2d539314fbc77c244858faa523012825068510a" - integrity sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg== - dependencies: - "@rollup/pluginutils" "^3.1.0" - magic-string "^0.25.7" - -"@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== - dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" - picomatch "^2.2.2" - "@rushstack/eslint-patch@^1.1.0": version "1.1.4" resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.1.4.tgz#0c8b74c50f29ee44f423f7416829c0bf8bb5eb27" @@ -1963,16 +1912,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@surma/rollup-plugin-off-main-thread@^2.2.3": - version "2.2.3" - resolved "https://registry.yarnpkg.com/@surma/rollup-plugin-off-main-thread/-/rollup-plugin-off-main-thread-2.2.3.tgz#ee34985952ca21558ab0d952f00298ad2190c053" - integrity sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ== - dependencies: - ejs "^3.1.6" - json5 "^2.2.0" - magic-string "^0.25.0" - string.prototype.matchall "^4.0.6" - "@svgr/babel-plugin-add-jsx-attribute@^5.4.0": version "5.4.0" resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz#81ef61947bb268eb9d50523446f9c638fb355906" @@ -2184,36 +2123,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - "@types/eslint-scope@^3.7.3": version "3.7.4" resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" @@ -2235,35 +2144,11 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== - "@types/estree@^0.0.51": version "0.0.51" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": - version "4.17.30" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.30.tgz#0f2f99617fa8f9696170c46152ccf7500b34ac04" - integrity sha512-gstzbTWro2/nFed1WXtf+TtrpwxH7Ggs4RLYTLbeVgIkUQOI3WG/JKjgeOU1zXDvezllupjrf8OPIdvTbIaVOQ== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*", "@types/express@^4.17.13": - version "4.17.13" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" - integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.18" - "@types/qs" "*" - "@types/serve-static" "*" - "@types/graceful-fs@^4.1.2": version "4.1.4" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.4.tgz#4ff9f641a7c6d1a3508ff88bc3141b152772e753" @@ -2276,13 +2161,6 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== -"@types/http-proxy@^1.17.8": - version "1.17.9" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" - integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== - dependencies: - "@types/node" "*" - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -2328,11 +2206,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/mime@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" - integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== - "@types/node@*": version "14.14.10" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.10.tgz#5958a82e41863cfc71f2307b3748e3491ba03785" @@ -2357,16 +2230,6 @@ version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - "@types/react-dom@^18.0.0": version "18.0.6" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.6.tgz#36652900024842b74607a17786b6662dd1e103a1" @@ -2383,45 +2246,11 @@ "@types/scheduler" "*" csstype "^3.0.2" -"@types/resolve@1.17.1": - version "1.17.1" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.17.1.tgz#3afd6ad8967c77e4376c598a82ddd58f46ec45d6" - integrity sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw== - dependencies: - "@types/node" "*" - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - "@types/scheduler@*": version "0.16.2" resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.0" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.0.tgz#c7930ff61afb334e121a9da780aac0d9b8f34155" - integrity sha512-z5xyF6uh8CbjAu9760KDKsH2FcDxZ2tFCsA4HIMWE6IkiYMXfVoa+4f9KX+FN0ZLsaMw1WNG2ETLA6N+/YA+cg== - dependencies: - "@types/mime" "*" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - "@types/stack-utils@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" @@ -2434,18 +2263,6 @@ dependencies: "@types/jest" "*" -"@types/trusted-types@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" - integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== - -"@types/ws@^8.5.1": - version "8.5.3" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" - integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== - dependencies: - "@types/node" "*" - "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -2695,14 +2512,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.4, accepts@~1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" - dependencies: - mime-types "~2.1.18" - negotiator "0.6.1" - -accepts@~1.3.8: +accepts@~1.3.5: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -2818,7 +2628,7 @@ ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^8.0.0, ajv@^8.6.0, ajv@^8.8.0: +ajv@^8.0.0, ajv@^8.8.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== @@ -2928,15 +2738,6 @@ aria-query@^5.0.0: resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - array-includes@^3.1.1: version "3.1.2" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.2.tgz#a8db03e0b88c8c6aeddc49cb132f9bcab4ebf9c8" @@ -2992,11 +2793,6 @@ ast-types-flow@^0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" -async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -3175,20 +2971,6 @@ balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - -bfj@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2" - integrity sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw== - dependencies: - bluebird "^3.5.5" - check-types "^11.1.1" - hoopy "^0.1.4" - tryer "^1.0.1" - big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -3199,28 +2981,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== -bluebird@^3.5.5: - version "3.7.1" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" - -body-parser@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" - integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.10.3" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - body-parser@^1.20.1: version "1.20.1" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" @@ -3239,16 +2999,6 @@ body-parser@^1.20.1: type-is "~1.6.18" unpipe "1.0.0" -bonjour-service@^1.0.11: - version "1.0.13" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.13.tgz#4ac003dc1626023252d58adf2946f57e5da450c1" - integrity sha512-LWKRU/7EqDUC9CTAQtuZl5HzBALoCYwtLhffW3et7vZMwv3bWLpJf8bRYlMD5OCcDpTfnPgNCV4yo9ZIaJGMiA== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - boolbase@^1.0.0, boolbase@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" @@ -3260,14 +3010,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.1, braces@^3.0.2, braces@~3.0.2: +braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -3318,14 +3061,10 @@ buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" -builtin-modules@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484" - integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw== - bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== bytes@3.1.2: version "3.1.2" @@ -3389,19 +3128,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000888: - version "1.0.30000889" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000889.tgz#53e266c83e725ad3bd2e4a3ea76d5031a8aa4c3e" - -caniuse-lite@^1.0.30001164: - version "1.0.30001165" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001165.tgz#32955490d2f60290bb186bb754f2981917fa744f" - integrity sha512-8cEsSMwXfx7lWSUMA2s08z9dIgsnR5NAqjXP23stdsU3AUWkCr/rr4s4OFtHXn5XXr6+7kam3QFVoYyXNPdJPA== - -caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373: - version "1.0.30001378" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001378.tgz#3d2159bf5a8f9ca093275b0d3ecc717b00f27b67" - integrity sha512-JVQnfoO7FK7WvU4ZkBRbPjaot4+YqxogSDosHv0Hv5mWpUESmN+UubMU6L/hGz8QlQ2aY5U0vR6MOs6j/CXpNA== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000888, caniuse-lite@^1.0.30001164, caniuse-lite@^1.0.30001370, caniuse-lite@^1.0.30001373: + version "1.0.30001457" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz" + integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -3432,7 +3162,7 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: +chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -3450,11 +3180,6 @@ char-regex@^2.0.0: resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-2.0.1.tgz#6dafdb25f9d3349914079f010ba8d0e6ff9cd01e" integrity sha512-oSvEeo6ZUD7NepqAat3RqoucZ5SeqLJgOvVIwkafu6IP3V0pO38s/ypdVUmDDK6qIIHNlYHJAKX9E7R7HoKElw== -check-types@^11.1.1: - version "11.1.2" - resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.1.2.tgz#86a7c12bf5539f6324eb0e70ca8896c0e38f3e2f" - integrity sha512-tzWzvgePgLORb9/3a0YenggReLKAIb2owL03H2Xdoe5pKcUyWRSEQ8xfCar8t2SIAuEDwtmx2da1YB52YuHQMQ== - chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3: version "3.5.3" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" @@ -3581,10 +3306,6 @@ common-path-prefix@^3.0.0: resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== -common-tags@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" - commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -3633,18 +3354,6 @@ confusing-browser-globals@^1.0.11: resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" @@ -3661,15 +3370,6 @@ convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - core-js-compat@^3.21.0, core-js-compat@^3.22.1: version "3.24.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.24.1.tgz#d1af84a17e18dfdd401ee39da9996f9a7ba887de" @@ -3693,10 +3393,6 @@ core-js@^3.19.2: resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.24.1.tgz#cf7724d41724154010a6576b7b57d94c5d66e64f" integrity sha512-0QTBSYSUZ6Gq21utGzkfITDylE8jWC9Ne1D2MrhvlsZBI1x39OdDIVbzSqtgMndIy6BlHxBXpMGqzZmnztg2rg== -core-util-is@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - cosmiconfig@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" @@ -3728,11 +3424,6 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -crypto-random-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" - integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== - css-blank-pseudo@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" @@ -3962,12 +3653,6 @@ debug@4, debug@^4.3.2, debug@^4.3.4: dependencies: ms "2.1.2" -debug@=3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - dependencies: - ms "2.0.0" - debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -4001,13 +3686,6 @@ deepmerge@^4.2.2: resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" @@ -4041,10 +3719,6 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -4055,10 +3729,6 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== -detect-node@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.4.tgz#014ee8f8f669c5c58023da64b8179c083a28c46c" - detect-port-alt@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.6.tgz#24707deabe932d4a3cf621302027c2b266568275" @@ -4103,17 +3773,6 @@ dlv@^1.1.3: resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - -dns-packet@^5.2.2: - version "5.4.0" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.4.0.tgz#1f88477cf9f27e78a213fb6d118ae38e759a879b" - integrity sha512-EgqGeaBB8hLiHLZtp/IbaDQTL8pZ0+IvwzSHA6d7VyMDM+B9hgddEMa9xjK5oYnw0ci0JQ6g2XCD7/f6cafU6g== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - doctrine@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" @@ -4224,13 +3883,6 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -ejs@^3.1.6: - version "3.1.8" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b" - integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ== - dependencies: - jake "^10.8.5" - electron-to-chromium@^1.3.612: version "1.3.617" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.617.tgz#4192fa4db846c6ad51fffe3a06e71727e9699a74" @@ -4269,10 +3921,6 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - enhanced-resolve@^5.10.0: version "5.10.0" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" @@ -4409,10 +4057,6 @@ escalade@^3.1.1: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -4694,23 +4338,10 @@ estraverse@^5.3.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== - esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - -eventemitter3@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb" - events@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -4756,43 +4387,6 @@ expect@^28.0.0: jest-message-util "^28.1.3" jest-util "^28.1.3" -express@^4.17.3: - version "4.18.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" - integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.0" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.10.3" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - fast-deep-equal@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" @@ -4817,11 +4411,6 @@ fast-json-stable-stringify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" -fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -4834,13 +4423,6 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - fb-watchman@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" @@ -4862,13 +4444,6 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -filelist@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - filesize@^8.0.6: version "8.0.7" resolved "https://registry.yarnpkg.com/filesize/-/filesize-8.0.7.tgz#695e70d80f4e47012c132d57a059e80c6b580bd8" @@ -4881,19 +4456,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - find-cache-dir@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" @@ -4938,12 +4500,6 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== -follow-redirects@^1.0.0: - version "1.5.8" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.8.tgz#1dbfe13e45ad969f813e86c00e5296f525c885a1" - dependencies: - debug "=3.1.0" - fork-ts-checker-webpack-plugin@^6.5.0: version "6.5.2" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" @@ -4972,20 +4528,11 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - fraction.js@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - fs-extra@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -5005,16 +4552,6 @@ fs-extra@^9.0.0: jsonfile "^6.0.1" universalify "^2.0.0" -fs-extra@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.0.1.tgz#910da0062437ba4c39fedd863f1675ccfefcb9fc" - integrity sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^1.0.0" - fs-monkey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" @@ -5080,10 +4617,6 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: has "^1.0.3" has-symbols "^1.0.3" -get-own-enumerable-property-symbols@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.1.tgz#6f7764f88ea11e0b514bd9bd860a132259992ca4" - get-package-type@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" @@ -5194,7 +4727,7 @@ graceful-fs@^4.2.4: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graceful-fs@^4.2.6, graceful-fs@^4.2.9: +graceful-fs@^4.2.9: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== @@ -5211,10 +4744,6 @@ gzip-size@^6.0.0: dependencies: duplexer "^0.1.2" -handle-thing@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.0.tgz#0e039695ff50c93fc288557d696f3c1dc6776754" - harmony-reflect@^1.4.6: version "1.6.1" resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" @@ -5272,20 +4801,6 @@ he@^1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hoopy@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" - integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -5293,7 +4808,7 @@ html-encoding-sniffer@^2.0.1: dependencies: whatwg-encoding "^1.0.5" -html-entities@^2.1.0, html-entities@^2.3.2: +html-entities@^2.1.0: version "2.3.3" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== @@ -5337,10 +4852,6 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -5352,24 +4863,6 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.4.0: - version "0.4.13" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.13.tgz#3bd6d6fde6e3172c9334c3b33b6c193d80fe1137" - -http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - http-proxy-agent@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" @@ -5379,26 +4872,6 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -5430,11 +4903,6 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -idb@^7.0.1: - version "7.0.2" - resolved "https://registry.yarnpkg.com/idb/-/idb-7.0.2.tgz#7a067e20dd16539938e456814b7d714ba8db3892" - integrity sha512-jjKrT1EnyZewQ/gCBb/eyiYrhGzws2FeY92Yx8qT9S9GeQAmo4JFVIiWRIfKW/6Ob9A+UDAOW9j9jn58fy2HIg== - identity-obj-proxy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" @@ -5500,7 +4968,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: +inherits@2: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -5522,16 +4990,6 @@ internal-slot@^1.0.3: has "^1.0.3" side-channel "^1.0.4" -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -5631,11 +5089,6 @@ is-glob@^4.0.3: dependencies: is-extglob "^2.1.1" -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE= - is-negative-zero@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" @@ -5658,15 +5111,6 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== -is-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - is-potential-custom-element-name@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" @@ -5693,10 +5137,6 @@ is-regex@^1.1.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" - is-root@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" @@ -5758,10 +5198,6 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -5813,16 +5249,6 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jake@^10.8.5: - version "10.8.5" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" - integrity sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.1" - minimatch "^3.0.4" - jest-changed-files@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" @@ -6294,15 +5720,6 @@ jest-watcher@^28.0.0: jest-util "^28.1.3" string-length "^4.0.1" -jest-worker@^26.2.1: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" @@ -6403,11 +5820,6 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" @@ -6418,7 +5830,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0, json5@^2.1.2, json5@^2.2.0, json5@^2.2.1: +json5@^2.1.0, json5@^2.1.2, json5@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== @@ -6432,11 +5844,6 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsonpointer@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" - integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== - "jsx-ast-utils@^2.4.1 || ^3.0.0": version "3.1.0" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.1.0.tgz#642f1d7b88aa6d7eb9d8f2210e166478444fa891" @@ -6612,13 +6019,6 @@ lz-string@^1.4.4: resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ== -magic-string@^0.25.0, magic-string@^0.25.7: - version "0.25.7" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" - integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== - dependencies: - sourcemap-codec "^1.4.4" - make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -6652,10 +6052,6 @@ memfs@^3.1.2, memfs@^3.4.3: dependencies: fs-monkey "^1.0.3" -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -6665,18 +6061,6 @@ merge2@^1.3.0, merge2@^1.4.1: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== - dependencies: - braces "^3.0.1" - picomatch "^2.0.5" - micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -6695,21 +6079,16 @@ mime-db@1.44.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-db@1.52.0: +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -"mime-db@>= 1.43.0 < 2": - version "1.45.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" - integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== - mime-db@~1.36.0: version "1.36.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" -mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18: +mime-types@^2.1.12: version "2.1.20" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" dependencies: @@ -6736,11 +6115,6 @@ mime-types@~2.1.24: dependencies: mime-db "1.40.0" -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -6757,10 +6131,6 @@ mini-css-extract-plugin@^2.4.5: dependencies: schema-utils "^4.0.0" -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -6774,13 +6144,6 @@ minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" - integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== - dependencies: - brace-expansion "^2.0.1" - minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -6809,23 +6172,10 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - nanoid@^3.3.4: version "3.3.4" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" @@ -6835,10 +6185,6 @@ natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" -negotiator@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" - negotiator@0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" @@ -6857,11 +6203,6 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" -node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -7054,10 +6395,6 @@ object.values@^1.1.5: define-properties "^1.1.3" es-abstract "^1.19.1" -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -7083,7 +6420,7 @@ onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" -open@^8.0.9, open@^8.4.0: +open@^8.4.0: version "8.4.0" resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== @@ -7155,14 +6492,6 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" @@ -7206,15 +6535,6 @@ parse5@6.0.1: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parseurl@~1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - pascal-case@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" @@ -7250,10 +6570,6 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -7273,7 +6589,7 @@ picocolors@^1.0.0: resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1, picomatch@^2.2.2: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -7883,16 +7199,6 @@ prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" -pretty-bytes@^5.3.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.4.1.tgz#cd89f79bbcef21e3d21eb0da68ffe93f803e884b" - integrity sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA== - -pretty-bytes@^5.4.1: - version "5.6.0" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" - integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== - pretty-error@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" @@ -7920,10 +7226,6 @@ pretty-format@^28.0.0, pretty-format@^28.1.3: ansi-styles "^5.0.0" react-is "^18.0.0" -process-nextick-args@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" - promise@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" @@ -7955,14 +7257,6 @@ prop-types@^15.8.1: object-assign "^4.1.1" react-is "^16.13.1" -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -7981,13 +7275,6 @@ q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" -qs@6.10.3: - version "6.10.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" - integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== - dependencies: - side-channel "^1.0.4" - qs@6.11.0: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" @@ -8014,7 +7301,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1, range-parser@~1.2.1: +range-parser@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -8117,26 +7404,6 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -readable-stream@^2.0.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc" - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -8287,10 +7554,6 @@ require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" @@ -8355,11 +7618,6 @@ resolve@^2.0.0-next.3: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -8372,23 +7630,6 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -rollup-plugin-terser@^7.0.0: - version "7.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-7.0.2.tgz#e8fbba4869981b2dc35ae7e8a502d5c6c04d324d" - integrity sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ== - dependencies: - "@babel/code-frame" "^7.10.4" - jest-worker "^26.2.1" - serialize-javascript "^4.0.0" - terser "^5.0.0" - -rollup@^2.43.1: - version "2.78.0" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.78.0.tgz#00995deae70c0f712ea79ad904d5f6b033209d9e" - integrity sha512-4+YfbQC9QEVvKTanHhIAFVUFSRsezvQF8vFOJwtGfb9Bb+r014S+qryr9PSmw8x6sMnPkmFBGAvIFVQxvJxjtg== - optionalDependencies: - fsevents "~2.3.2" - run-parallel@^1.1.9: version "1.1.10" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.10.tgz#60a51b2ae836636c81377df16cb107351bcd13ef" @@ -8401,19 +7642,10 @@ rxjs@^7.0.0: dependencies: tslib "^2.1.0" -safe-buffer@5.1.2, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@5.1.2, safe-buffer@^5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" -safe-buffer@5.2.1, safe-buffer@>=5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -8495,17 +7727,6 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - -selfsigned@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" - integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== - dependencies: - node-forge "^1" - semver@7.0.0, semver@~7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -8538,32 +7759,6 @@ semver@^7.3.5, semver@^7.3.7: dependencies: lru-cache "^6.0.0" -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - serialize-javascript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -8571,33 +7766,6 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha1-03aNabHn2C5c4FD/9bRTvqEqkjk= - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -8663,24 +7831,6 @@ slash@^4.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-list-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" - -source-list-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -8723,45 +7873,11 @@ source-map@^0.7.3: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== -source-map@^0.8.0-beta.0: - version "0.8.0-beta.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" - integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== - dependencies: - whatwg-url "^7.0.0" - -sourcemap-codec@^1.4.4: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - spawn-command@^0.0.2-1: version "0.0.2-1" resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" integrity sha512-n98l9E2RMSJ9ON1AKisHzz7V42VDiBQGY6PB1BwRglz99wpVsSuGzQ+jOi6lFXBGVTCrRpltvjm+/XA+tpeJrg== -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -8787,10 +7903,6 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - string-length@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" @@ -8838,7 +7950,7 @@ string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.matchall@^4.0.6, string.prototype.matchall@^4.0.7: +string.prototype.matchall@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d" integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg== @@ -8900,26 +8012,6 @@ string.prototype.trimstart@^1.0.5: define-properties "^1.1.4" es-abstract "^1.19.5" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - dependencies: - safe-buffer "~5.1.0" - -stringify-object@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" - dependencies: - get-own-enumerable-property-symbols "^3.0.0" - is-obj "^1.0.1" - is-regexp "^1.0.0" - strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -8956,11 +8048,6 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== -strip-comments@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-comments/-/strip-comments-2.0.1.tgz#4ad11c3fbcac177a67a40ac224ca339ca1c1ba9b" - integrity sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw== - strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -9102,21 +8189,6 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -temp-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" - integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== - -tempy@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" - integrity sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw== - dependencies: - is-stream "^2.0.0" - temp-dir "^2.0.0" - type-fest "^0.16.0" - unique-string "^2.0.0" - terminal-link@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" @@ -9136,7 +8208,7 @@ terser-webpack-plugin@^5.1.3, terser-webpack-plugin@^5.2.5: serialize-javascript "^6.0.0" terser "^5.14.1" -terser@^5.0.0, terser@^5.10.0, terser@^5.14.1: +terser@^5.10.0, terser@^5.14.1: version "5.14.2" resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== @@ -9164,10 +8236,6 @@ throat@^6.0.1: resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.1.tgz#d514fedad95740c12c2d7fc70ea863eb51ade375" integrity sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w== -thunky@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.0.2.tgz#a862e018e3fb1ea2ec3fce5d55605cf57f247371" - tmpl@1.0.x: version "1.0.4" resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" @@ -9204,13 +8272,6 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA== - dependencies: - punycode "^2.1.0" - tr46@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" @@ -9230,11 +8291,6 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== -tryer@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" - integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== - tsconfig-paths@^3.14.1: version "3.14.1" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" @@ -9293,11 +8349,6 @@ type-fest@^0.11.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1" integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ== -type-fest@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.16.0.tgz#3240b891a78b0deae910dbeb86553e552a148860" - integrity sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg== - type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -9383,29 +8434,17 @@ uniq@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" -unique-string@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d" - integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg== - dependencies: - crypto-random-string "^2.0.0" - universalify@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== -universalify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d" - integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug== - universalify@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unpipe@1.0.0, unpipe@~1.0.0: +unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -9413,11 +8452,6 @@ unquote@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unquote/-/unquote-1.1.1.tgz#8fded7324ec6e88a0ff8b905e7c098cdc086d544" -upath@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - update-browserslist-db@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" @@ -9432,7 +8466,7 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: +util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" @@ -9447,15 +8481,6 @@ utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" @@ -9472,6 +8497,7 @@ v8-to-istanbul@^8.1.0: vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== w3c-hr-time@^1.0.2: version "1.0.2" @@ -9501,22 +8527,6 @@ watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - dependencies: - minimalistic-assert "^1.0.0" - -web-vitals@^2.1.0: - version "2.1.4" - resolved "https://registry.yarnpkg.com/web-vitals/-/web-vitals-2.1.4.tgz#76563175a475a5e835264d373704f9dde718290c" - integrity sha512-sVWcwhU5mX6crfI5Vd2dC4qchyTqxV8URinzt25XqVh+bHEPGH4C3NPrNionCP7Obx59wrYEbNlw4Z8sjALzZg== - -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== - webidl-conversions@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" @@ -9538,64 +8548,6 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.6.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.10.0.tgz#de270d0009eba050546912be90116e7fd740a9ca" - integrity sha512-7dezwAs+k6yXVFZ+MaL8VnE+APobiO3zvpp3rBHe/HmWQ+avwh0Q3d0xxacOiBybZZ3syTZw9HXzpa3YNbAZDQ== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.0.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.4.2" - -webpack-manifest-plugin@^4.0.2: - version "4.1.1" - resolved "https://registry.yarnpkg.com/webpack-manifest-plugin/-/webpack-manifest-plugin-4.1.1.tgz#10f8dbf4714ff93a215d5a45bcc416d80506f94f" - integrity sha512-YXUAwxtfKIJIKkhg03MKuiFAD72PlrqCiwdwO4VEXdRO5V0ORCNwaOwAZawPZalCbmH9kBDmXnNeQOw+BIEiow== - dependencies: - tapable "^2.0.0" - webpack-sources "^2.2.0" - -webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack-sources@^2.2.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" - integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== - dependencies: - source-list-map "^2.0.1" - source-map "^0.6.1" - webpack-sources@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" @@ -9631,26 +8583,6 @@ webpack@^5.64.4: watchpack "^2.4.0" webpack-sources "^3.2.3" -websocket-driver@>=0.5.1: - version "0.7.0" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.0.tgz#0caf9d2d755d93aee049d4bdd0d3fe2cca2a24eb" - dependencies: - http-parser-js ">=0.4.0" - websocket-extensions ">=0.1.1" - -websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" - whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" @@ -9666,15 +8598,6 @@ whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" -whatwg-url@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" - integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== - dependencies: - lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" - whatwg-url@^8.0.0: version "8.4.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.4.0.tgz#50fb9615b05469591d2b2bd6dfaed2942ed72837" @@ -9726,175 +8649,6 @@ wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" -workbox-background-sync@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz#3141afba3cc8aa2ae14c24d0f6811374ba8ff6a9" - integrity sha512-0r4INQZMyPky/lj4Ou98qxcThrETucOde+7mRGJl13MPJugQNKeZQOdIJe/1AchOP23cTqHcN/YVpD6r8E6I8g== - dependencies: - idb "^7.0.1" - workbox-core "6.5.4" - -workbox-broadcast-update@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-broadcast-update/-/workbox-broadcast-update-6.5.4.tgz#8441cff5417cd41f384ba7633ca960a7ffe40f66" - integrity sha512-I/lBERoH1u3zyBosnpPEtcAVe5lwykx9Yg1k6f8/BGEPGaMMgZrwVrqL1uA9QZ1NGGFoyE6t9i7lBjOlDhFEEw== - dependencies: - workbox-core "6.5.4" - -workbox-build@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-build/-/workbox-build-6.5.4.tgz#7d06d31eb28a878817e1c991c05c5b93409f0389" - integrity sha512-kgRevLXEYvUW9WS4XoziYqZ8Q9j/2ziJYEtTrjdz5/L/cTUa2XfyMP2i7c3p34lgqJ03+mTiz13SdFef2POwbA== - dependencies: - "@apideck/better-ajv-errors" "^0.3.1" - "@babel/core" "^7.11.1" - "@babel/preset-env" "^7.11.0" - "@babel/runtime" "^7.11.2" - "@rollup/plugin-babel" "^5.2.0" - "@rollup/plugin-node-resolve" "^11.2.1" - "@rollup/plugin-replace" "^2.4.1" - "@surma/rollup-plugin-off-main-thread" "^2.2.3" - ajv "^8.6.0" - common-tags "^1.8.0" - fast-json-stable-stringify "^2.1.0" - fs-extra "^9.0.1" - glob "^7.1.6" - lodash "^4.17.20" - pretty-bytes "^5.3.0" - rollup "^2.43.1" - rollup-plugin-terser "^7.0.0" - source-map "^0.8.0-beta.0" - stringify-object "^3.3.0" - strip-comments "^2.0.1" - tempy "^0.6.0" - upath "^1.2.0" - workbox-background-sync "6.5.4" - workbox-broadcast-update "6.5.4" - workbox-cacheable-response "6.5.4" - workbox-core "6.5.4" - workbox-expiration "6.5.4" - workbox-google-analytics "6.5.4" - workbox-navigation-preload "6.5.4" - workbox-precaching "6.5.4" - workbox-range-requests "6.5.4" - workbox-recipes "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" - workbox-streams "6.5.4" - workbox-sw "6.5.4" - workbox-window "6.5.4" - -workbox-cacheable-response@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-cacheable-response/-/workbox-cacheable-response-6.5.4.tgz#a5c6ec0c6e2b6f037379198d4ef07d098f7cf137" - integrity sha512-DCR9uD0Fqj8oB2TSWQEm1hbFs/85hXXoayVwFKLVuIuxwJaihBsLsp4y7J9bvZbqtPJ1KlCkmYVGQKrBU4KAug== - dependencies: - workbox-core "6.5.4" - -workbox-core@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.5.4.tgz#df48bf44cd58bb1d1726c49b883fb1dffa24c9ba" - integrity sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q== - -workbox-expiration@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.5.4.tgz#501056f81e87e1d296c76570bb483ce5e29b4539" - integrity sha512-jUP5qPOpH1nXtjGGh1fRBa1wJL2QlIb5mGpct3NzepjGG2uFFBn4iiEBiI9GUmfAFR2ApuRhDydjcRmYXddiEQ== - dependencies: - idb "^7.0.1" - workbox-core "6.5.4" - -workbox-google-analytics@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-google-analytics/-/workbox-google-analytics-6.5.4.tgz#c74327f80dfa4c1954cbba93cd7ea640fe7ece7d" - integrity sha512-8AU1WuaXsD49249Wq0B2zn4a/vvFfHkpcFfqAFHNHwln3jK9QUYmzdkKXGIZl9wyKNP+RRX30vcgcyWMcZ9VAg== - dependencies: - workbox-background-sync "6.5.4" - workbox-core "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" - -workbox-navigation-preload@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-navigation-preload/-/workbox-navigation-preload-6.5.4.tgz#ede56dd5f6fc9e860a7e45b2c1a8f87c1c793212" - integrity sha512-IIwf80eO3cr8h6XSQJF+Hxj26rg2RPFVUmJLUlM0+A2GzB4HFbQyKkrgD5y2d84g2IbJzP4B4j5dPBRzamHrng== - dependencies: - workbox-core "6.5.4" - -workbox-precaching@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-precaching/-/workbox-precaching-6.5.4.tgz#740e3561df92c6726ab5f7471e6aac89582cab72" - integrity sha512-hSMezMsW6btKnxHB4bFy2Qfwey/8SYdGWvVIKFaUm8vJ4E53JAY+U2JwLTRD8wbLWoP6OVUdFlXsTdKu9yoLTg== - dependencies: - workbox-core "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" - -workbox-range-requests@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-range-requests/-/workbox-range-requests-6.5.4.tgz#86b3d482e090433dab38d36ae031b2bb0bd74399" - integrity sha512-Je2qR1NXCFC8xVJ/Lux6saH6IrQGhMpDrPXWZWWS8n/RD+WZfKa6dSZwU+/QksfEadJEr/NfY+aP/CXFFK5JFg== - dependencies: - workbox-core "6.5.4" - -workbox-recipes@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-recipes/-/workbox-recipes-6.5.4.tgz#cca809ee63b98b158b2702dcfb741b5cc3e24acb" - integrity sha512-QZNO8Ez708NNwzLNEXTG4QYSKQ1ochzEtRLGaq+mr2PyoEIC1xFW7MrWxrONUxBFOByksds9Z4//lKAX8tHyUA== - dependencies: - workbox-cacheable-response "6.5.4" - workbox-core "6.5.4" - workbox-expiration "6.5.4" - workbox-precaching "6.5.4" - workbox-routing "6.5.4" - workbox-strategies "6.5.4" - -workbox-routing@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-routing/-/workbox-routing-6.5.4.tgz#6a7fbbd23f4ac801038d9a0298bc907ee26fe3da" - integrity sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg== - dependencies: - workbox-core "6.5.4" - -workbox-strategies@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-strategies/-/workbox-strategies-6.5.4.tgz#4edda035b3c010fc7f6152918370699334cd204d" - integrity sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw== - dependencies: - workbox-core "6.5.4" - -workbox-streams@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-streams/-/workbox-streams-6.5.4.tgz#1cb3c168a6101df7b5269d0353c19e36668d7d69" - integrity sha512-FXKVh87d2RFXkliAIheBojBELIPnWbQdyDvsH3t74Cwhg0fDheL1T8BqSM86hZvC0ZESLsznSYWw+Va+KVbUzg== - dependencies: - workbox-core "6.5.4" - workbox-routing "6.5.4" - -workbox-sw@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-sw/-/workbox-sw-6.5.4.tgz#d93e9c67924dd153a61367a4656ff4d2ae2ed736" - integrity sha512-vo2RQo7DILVRoH5LjGqw3nphavEjK4Qk+FenXeUsknKn14eCNedHOXWbmnvP4ipKhlE35pvJ4yl4YYf6YsJArA== - -workbox-webpack-plugin@^6.4.1: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-webpack-plugin/-/workbox-webpack-plugin-6.5.4.tgz#baf2d3f4b8f435f3469887cf4fba2b7fac3d0fd7" - integrity sha512-LmWm/zoaahe0EGmMTrSLUi+BjyR3cdGEfU3fS6PN1zKFYbqAKuQ+Oy/27e4VSXsyIwAw8+QDfk1XHNGtZu9nQg== - dependencies: - fast-json-stable-stringify "^2.1.0" - pretty-bytes "^5.4.1" - upath "^1.2.0" - webpack-sources "^1.4.3" - workbox-build "6.5.4" - -workbox-window@6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.5.4.tgz#d991bc0a94dff3c2dbb6b84558cff155ca878e91" - integrity sha512-HnLZJDwYBE+hpG25AQBO8RUWBJRaCsI9ksQJEp3aCOFCaG5kqaToAYXFRAHxzRluM2cQbGzdQF5rjKPWPA1fug== - dependencies: - "@types/trusted-types" "^2.0.2" - workbox-core "6.5.4" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -9923,11 +8677,6 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -ws@^8.4.2: - version "8.8.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" - integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== - xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" From 1173a17e6eea08599005e9f8e7d7a4245783edba Mon Sep 17 00:00:00 2001 From: Josh Story Date: Sat, 25 Feb 2023 11:04:51 -0800 Subject: [PATCH 008/103] [Float][Fizz][Fiber] implement preconnect and prefetchDNS float methods (#26237) Adds two new ReactDOM methods ### `ReactDOM.prefetchDNS(href: string)` In SSR this method will cause a `` to flush before most other content both on intial flush (Shell) and late flushes. It will only emit one link per href. On the client, this method will case the same kind of link to be inserted into the document immediately (when called during render, not during commit) if there is not already a matching element in the document. ### `ReactDOM.preconnect(href: string, options?: { crossOrigin?: string })` In SSR this method will cause a `` to flush before most other content both on intial flush (Shell) and late flushes. It will only emit one link per href + crossorigin combo. On the client, this method will case the same kind of link to be inserted into the document immediately (when called during render, not during commit) if there is not already a matching element in the document. --- .../src/client/ReactDOMFloatClient.js | 107 ++++++++++++- .../src/server/ReactDOMServerFormatConfig.js | 145 +++++++++++++++++- .../src/shared/ReactDOMFloat.js | 26 +++- packages/react-dom/index.classic.fb.js | 4 +- packages/react-dom/index.experimental.js | 4 +- packages/react-dom/index.js | 4 +- packages/react-dom/index.modern.fb.js | 4 +- packages/react-dom/index.stable.js | 4 +- .../src/__tests__/ReactDOMFloat-test.js | 141 +++++++++++++++++ packages/react-dom/src/client/ReactDOM.js | 7 +- 10 files changed, 432 insertions(+), 14 deletions(-) diff --git a/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js b/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js index 7091db0525b9f..f4332cef91945 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js +++ b/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js @@ -18,6 +18,8 @@ import {DOCUMENT_NODE} from '../shared/HTMLNodeType'; import { validatePreloadArguments, validatePreinitArguments, + getValueDescriptorExpectingObjectForWarning, + getValueDescriptorExpectingEnumForWarning, } from '../shared/ReactDOMResourceValidation'; import {createElement, setInitialProperties} from './ReactDOMComponent'; import { @@ -103,12 +105,18 @@ export function cleanupAfterRenderResources() { // We want this to be the default dispatcher on ReactDOMSharedInternals but we don't want to mutate // internals in Module scope. Instead we export it and Internals will import it. There is already a cycle // from Internals -> ReactDOM -> FloatClient -> Internals so this doesn't introduce a new one. -export const ReactDOMClientDispatcher = {preload, preinit}; +export const ReactDOMClientDispatcher = { + prefetchDNS, + preconnect, + preload, + preinit, +}; export type HoistableRoot = Document | ShadowRoot; -// global maps of Resources +// global collections of Resources const preloadPropsMap: Map = new Map(); +const preconnectsSet: Set = new Set(); // getRootNode is missing from IE and old jsdom versions export function getHoistableRoot(container: Container): HoistableRoot { @@ -148,8 +156,101 @@ function getDocumentFromRoot(root: HoistableRoot): Document { return root.ownerDocument || root; } +function preconnectAs( + rel: 'preconnect' | 'dns-prefetch', + crossOrigin: null | '' | 'use-credentials', + href: string, +) { + const ownerDocument = getDocumentForPreloads(); + if (typeof href === 'string' && href && ownerDocument) { + const limitedEscapedHref = + escapeSelectorAttributeValueInsideDoubleQuotes(href); + let key = `link[rel="${rel}"][href="${limitedEscapedHref}"]`; + if (typeof crossOrigin === 'string') { + key += `[crossorigin="${crossOrigin}"]`; + } + if (!preconnectsSet.has(key)) { + preconnectsSet.add(key); + + const preconnectProps = {rel, crossOrigin, href}; + if (null === ownerDocument.querySelector(key)) { + const preloadInstance = createElement( + 'link', + preconnectProps, + ownerDocument, + HTML_NAMESPACE, + ); + setInitialProperties(preloadInstance, 'link', preconnectProps); + markNodeAsResource(preloadInstance); + (ownerDocument.head: any).appendChild(preloadInstance); + } + } + } +} + +// -------------------------------------- +// ReactDOM.prefetchDNS +// -------------------------------------- +function prefetchDNS(href: string, options?: mixed) { + if (__DEV__) { + if (typeof href !== 'string' || !href) { + console.error( + 'ReactDOM.prefetchDNS(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.', + getValueDescriptorExpectingObjectForWarning(href), + ); + } else if (options != null) { + if ( + typeof options === 'object' && + options.hasOwnProperty('crossOrigin') + ) { + console.error( + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + getValueDescriptorExpectingEnumForWarning(options), + ); + } else { + console.error( + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + getValueDescriptorExpectingEnumForWarning(options), + ); + } + } + } + preconnectAs('dns-prefetch', null, href); +} + +// -------------------------------------- +// ReactDOM.preconnect +// -------------------------------------- +function preconnect(href: string, options?: {crossOrigin?: string}) { + if (__DEV__) { + if (typeof href !== 'string' || !href) { + console.error( + 'ReactDOM.preconnect(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.', + getValueDescriptorExpectingObjectForWarning(href), + ); + } else if (options != null && typeof options !== 'object') { + console.error( + 'ReactDOM.preconnect(): Expected the `options` argument (second) to be an object but encountered %s instead. The only supported option at this time is `crossOrigin` which accepts a string.', + getValueDescriptorExpectingEnumForWarning(options), + ); + } else if (options != null && typeof options.crossOrigin !== 'string') { + console.error( + 'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered %s instead. Try removing this option or passing a string value instead.', + getValueDescriptorExpectingObjectForWarning(options.crossOrigin), + ); + } + } + const crossOrigin = + options == null || typeof options.crossOrigin !== 'string' + ? null + : options.crossOrigin === 'use-credentials' + ? 'use-credentials' + : ''; + preconnectAs('preconnect', crossOrigin, href); +} + // -------------------------------------- -// ReactDOM.Preload +// ReactDOM.preload // -------------------------------------- type PreloadAs = ResourceType; type PreloadOptions = {as: PreloadAs, crossOrigin?: string, integrity?: string}; diff --git a/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js b/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js index 782818ba2837c..ce7f63b4ccf6f 100644 --- a/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js +++ b/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js @@ -86,6 +86,8 @@ const ReactDOMCurrentDispatcher = ReactDOMSharedInternals.Dispatcher; const ReactDOMServerDispatcher = enableFloat ? { + prefetchDNS, + preconnect, preload, preinit, } @@ -3464,6 +3466,10 @@ export function writePreamble( } charsetChunks.length = 0; + // emit preconnect resources + resources.preconnects.forEach(flushResourceInPreamble, destination); + resources.preconnects.clear(); + const preconnectChunks = responseState.preconnectChunks; for (i = 0; i < preconnectChunks.length; i++) { writeChunk(destination, preconnectChunks[i]); @@ -3559,6 +3565,9 @@ export function writeHoistables( // We omit charsetChunks because we have already sent the shell and if it wasn't // already sent it is too late now. + resources.preconnects.forEach(flushResourceLate, destination); + resources.preconnects.clear(); + const preconnectChunks = responseState.preconnectChunks; for (i = 0; i < preconnectChunks.length; i++) { writeChunk(destination, preconnectChunks[i]); @@ -4068,7 +4077,10 @@ const Blocked /* */ = 0b0100; // This generally only makes sense for Resources other than PreloadResource const PreloadFlushed /* */ = 0b1000; -type TResource = { +type TResource< + T: 'stylesheet' | 'style' | 'script' | 'preload' | 'preconnect', + P, +> = { type: T, chunks: Array, state: ResourceStateTag, @@ -4099,6 +4111,13 @@ type ResourceDEV = | ImperativeResourceDEV | ImplicitResourceDEV; +type PreconnectProps = { + rel: 'preconnect' | 'dns-prefetch', + href: string, + [string]: mixed, +}; +type PreconnectResource = TResource<'preconnect', null>; + type PreloadProps = { rel: 'preload', as: string, @@ -4131,15 +4150,21 @@ type ScriptProps = { }; type ScriptResource = TResource<'script', null>; -type Resource = StyleResource | ScriptResource | PreloadResource; +type Resource = + | StyleResource + | ScriptResource + | PreloadResource + | PreconnectResource; export type Resources = { // Request local cache preloadsMap: Map, + preconnectsMap: Map, stylesMap: Map, scriptsMap: Map, // Flushing queues for Resource dependencies + preconnects: Set, fontPreloads: Set, // usedImagePreloads: Set, precedences: Map>, @@ -4161,10 +4186,12 @@ export function createResources(): Resources { return { // persistent preloadsMap: new Map(), + preconnectsMap: new Map(), stylesMap: new Map(), scriptsMap: new Map(), // cleared on flush + preconnects: new Set(), fontPreloads: new Set(), // usedImagePreloads: new Set(), precedences: new Map(), @@ -4198,6 +4225,120 @@ function getResourceKey(as: string, href: string): string { return `[${as}]${href}`; } +export function prefetchDNS(href: string, options?: mixed) { + if (!currentResources) { + // While we expect that preconnect calls are primarily going to be observed + // during render because effects and events don't run on the server it is + // still possible that these get called in module scope. This is valid on + // the client since there is still a document to interact with but on the + // server we need a request to associate the call to. Because of this we + // simply return and do not warn. + return; + } + const resources = currentResources; + if (__DEV__) { + if (typeof href !== 'string' || !href) { + console.error( + 'ReactDOM.prefetchDNS(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.', + getValueDescriptorExpectingObjectForWarning(href), + ); + } else if (options != null) { + if ( + typeof options === 'object' && + options.hasOwnProperty('crossOrigin') + ) { + console.error( + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + getValueDescriptorExpectingEnumForWarning(options), + ); + } else { + console.error( + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered %s as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + getValueDescriptorExpectingEnumForWarning(options), + ); + } + } + } + + if (typeof href === 'string' && href) { + const key = getResourceKey('prefetchDNS', href); + let resource = resources.preconnectsMap.get(key); + if (!resource) { + resource = { + type: 'preconnect', + chunks: [], + state: NoState, + props: null, + }; + resources.preconnectsMap.set(key, resource); + pushLinkImpl( + resource.chunks, + ({href, rel: 'dns-prefetch'}: PreconnectProps), + ); + } + resources.preconnects.add(resource); + } +} + +export function preconnect(href: string, options?: {crossOrigin?: string}) { + if (!currentResources) { + // While we expect that preconnect calls are primarily going to be observed + // during render because effects and events don't run on the server it is + // still possible that these get called in module scope. This is valid on + // the client since there is still a document to interact with but on the + // server we need a request to associate the call to. Because of this we + // simply return and do not warn. + return; + } + const resources = currentResources; + if (__DEV__) { + if (typeof href !== 'string' || !href) { + console.error( + 'ReactDOM.preconnect(): Expected the `href` argument (first) to be a non-empty string but encountered %s instead.', + getValueDescriptorExpectingObjectForWarning(href), + ); + } else if (options != null && typeof options !== 'object') { + console.error( + 'ReactDOM.preconnect(): Expected the `options` argument (second) to be an object but encountered %s instead. The only supported option at this time is `crossOrigin` which accepts a string.', + getValueDescriptorExpectingEnumForWarning(options), + ); + } else if (options != null && typeof options.crossOrigin !== 'string') { + console.error( + 'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered %s instead. Try removing this option or passing a string value instead.', + getValueDescriptorExpectingObjectForWarning(options.crossOrigin), + ); + } + } + + if (typeof href === 'string' && href) { + const crossOrigin = + options == null || typeof options.crossOrigin !== 'string' + ? null + : options.crossOrigin === 'use-credentials' + ? 'use-credentials' + : ''; + + const key = `[preconnect][${ + crossOrigin === null ? 'null' : crossOrigin + }]${href}`; + let resource = resources.preconnectsMap.get(key); + if (!resource) { + resource = { + type: 'preconnect', + chunks: [], + state: NoState, + props: null, + }; + resources.preconnectsMap.set(key, resource); + pushLinkImpl( + resource.chunks, + ({rel: 'preconnect', href, crossOrigin}: PreconnectProps), + ); + } + resources.preconnects.add(resource); + } +} + type PreloadAs = 'style' | 'font' | 'script'; type PreloadOptions = { as: PreloadAs, diff --git a/packages/react-dom-bindings/src/shared/ReactDOMFloat.js b/packages/react-dom-bindings/src/shared/ReactDOMFloat.js index 3fabd9fb922f3..99a867286d361 100644 --- a/packages/react-dom-bindings/src/shared/ReactDOMFloat.js +++ b/packages/react-dom-bindings/src/shared/ReactDOMFloat.js @@ -1,11 +1,21 @@ import ReactDOMSharedInternals from 'shared/ReactDOMSharedInternals'; -export function preinit() { +export function prefetchDNS() { const dispatcher = ReactDOMSharedInternals.Dispatcher.current; if (dispatcher) { - dispatcher.preinit.apply(this, arguments); + dispatcher.prefetchDNS.apply(this, arguments); } - // We don't error because preinit needs to be resilient to being called in a variety of scopes + // We don't error because preconnect needs to be resilient to being called in a variety of scopes + // and the runtime may not be capable of responding. The function is optimistic and not critical + // so we favor silent bailout over warning or erroring. +} + +export function preconnect() { + const dispatcher = ReactDOMSharedInternals.Dispatcher.current; + if (dispatcher) { + dispatcher.preconnect.apply(this, arguments); + } + // We don't error because preconnect needs to be resilient to being called in a variety of scopes // and the runtime may not be capable of responding. The function is optimistic and not critical // so we favor silent bailout over warning or erroring. } @@ -19,3 +29,13 @@ export function preload() { // and the runtime may not be capable of responding. The function is optimistic and not critical // so we favor silent bailout over warning or erroring. } + +export function preinit() { + const dispatcher = ReactDOMSharedInternals.Dispatcher.current; + if (dispatcher) { + dispatcher.preinit.apply(this, arguments); + } + // We don't error because preinit needs to be resilient to being called in a variety of scopes + // and the runtime may not be capable of responding. The function is optimistic and not critical + // so we favor silent bailout over warning or erroring. +} diff --git a/packages/react-dom/index.classic.fb.js b/packages/react-dom/index.classic.fb.js index 3b559bb43c419..65425ce24a235 100644 --- a/packages/react-dom/index.classic.fb.js +++ b/packages/react-dom/index.classic.fb.js @@ -32,8 +32,10 @@ export { unstable_flushControlled, unstable_renderSubtreeIntoContainer, unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. - preinit, + prefetchDNS, + preconnect, preload, + preinit, version, } from './src/client/ReactDOM'; diff --git a/packages/react-dom/index.experimental.js b/packages/react-dom/index.experimental.js index 7b8326fb30fbe..5e905c19a6f57 100644 --- a/packages/react-dom/index.experimental.js +++ b/packages/react-dom/index.experimental.js @@ -20,7 +20,9 @@ export { unstable_batchedUpdates, unstable_renderSubtreeIntoContainer, unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. - preinit, + prefetchDNS, + preconnect, preload, + preinit, version, } from './src/client/ReactDOM'; diff --git a/packages/react-dom/index.js b/packages/react-dom/index.js index 1ea57d00072e5..f57e1e97c9249 100644 --- a/packages/react-dom/index.js +++ b/packages/react-dom/index.js @@ -24,7 +24,9 @@ export { unstable_flushControlled, unstable_renderSubtreeIntoContainer, unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. - preinit, + prefetchDNS, + preconnect, preload, + preinit, version, } from './src/client/ReactDOM'; diff --git a/packages/react-dom/index.modern.fb.js b/packages/react-dom/index.modern.fb.js index deddb938ec987..cac8ec594f7b5 100644 --- a/packages/react-dom/index.modern.fb.js +++ b/packages/react-dom/index.modern.fb.js @@ -17,7 +17,9 @@ export { unstable_createEventHandle, unstable_flushControlled, unstable_runWithPriority, // DO NOT USE: Temporarily exposed to migrate off of Scheduler.runWithPriority. - preinit, + prefetchDNS, + preconnect, preload, + preinit, version, } from './src/client/ReactDOM'; diff --git a/packages/react-dom/index.stable.js b/packages/react-dom/index.stable.js index 5d64bf771c6f6..b3b07fe97dc6d 100644 --- a/packages/react-dom/index.stable.js +++ b/packages/react-dom/index.stable.js @@ -19,7 +19,9 @@ export { unmountComponentAtNode, unstable_batchedUpdates, unstable_renderSubtreeIntoContainer, - preinit, + prefetchDNS, + preconnect, preload, + preinit, version, } from './src/client/ReactDOM'; diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index 5f59f81731eb4..e1cc69988c801 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -2295,6 +2295,147 @@ body { ); }); + describe('ReactDOM.prefetchDNS(href)', () => { + it('creates a dns-prefetch resource when called', async () => { + function App({url}) { + ReactDOM.prefetchDNS(url); + ReactDOM.prefetchDNS(url); + ReactDOM.prefetchDNS(url, {}); + ReactDOM.prefetchDNS(url, {crossOrigin: 'use-credentials'}); + return ( + + hello world + + ); + } + + await expect(async () => { + await actIntoEmptyDocument(() => { + renderToPipeableStream().pipe(writable); + }); + }).toErrorDev([ + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + ]); + + expect(getMeaningfulChildren(document)).toEqual( + + + + + hello world + , + ); + + const root = ReactDOMClient.hydrateRoot(document, ); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev([ + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + ]); + expect(getMeaningfulChildren(document)).toEqual( + + + + + hello world + , + ); + + root.render(); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev([ + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + 'ReactDOM.prefetchDNS(): Expected only one argument, `href`, but encountered something with type "object" as a second argument instead. This argument is reserved for future options and is currently disallowed. It looks like the you are attempting to set a crossOrigin property for this DNS lookup hint. Browsers do not perform DNS queries using CORS and setting this attribute on the resource hint has no effect. Try calling ReactDOM.prefetchDNS() with just a single string argument, `href`.', + ]); + expect(getMeaningfulChildren(document)).toEqual( + + + + + + hello world + , + ); + }); + }); + + describe('ReactDOM.preconnect(href, { crossOrigin })', () => { + it('creates a preconnect resource when called', async () => { + function App({url}) { + ReactDOM.preconnect(url); + ReactDOM.preconnect(url); + ReactDOM.preconnect(url, {crossOrigin: true}); + ReactDOM.preconnect(url, {crossOrigin: ''}); + ReactDOM.preconnect(url, {crossOrigin: 'anonymous'}); + ReactDOM.preconnect(url, {crossOrigin: 'use-credentials'}); + return ( + + hello world + + ); + } + + await expect(async () => { + await actIntoEmptyDocument(() => { + renderToPipeableStream().pipe(writable); + }); + }).toErrorDev( + 'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered something with type "boolean" instead. Try removing this option or passing a string value instead.', + ); + + expect(getMeaningfulChildren(document)).toEqual( + + + + + + + hello world + , + ); + + const root = ReactDOMClient.hydrateRoot(document, ); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev( + 'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered something with type "boolean" instead. Try removing this option or passing a string value instead.', + ); + expect(getMeaningfulChildren(document)).toEqual( + + + + + + + hello world + , + ); + + root.render(); + expect(() => { + expect(Scheduler).toFlushWithoutYielding(); + }).toErrorDev( + 'ReactDOM.preconnect(): Expected the `crossOrigin` option (second argument) to be a string but encountered something with type "boolean" instead. Try removing this option or passing a string value instead.', + ); + expect(getMeaningfulChildren(document)).toEqual( + + + + + + + + + + hello world + , + ); + }); + }); + describe('ReactDOM.preload(href, { as: ... })', () => { // @gate enableFloat it('creates a preload resource when called', async () => { diff --git a/packages/react-dom/src/client/ReactDOM.js b/packages/react-dom/src/client/ReactDOM.js index 2da511119aec1..aa7526e15d192 100644 --- a/packages/react-dom/src/client/ReactDOM.js +++ b/packages/react-dom/src/client/ReactDOM.js @@ -75,7 +75,12 @@ import { } from 'react-dom-bindings/src/events/ReactDOMControlledComponent'; import Internals from '../ReactDOMSharedInternals'; -export {preinit, preload} from 'react-dom-bindings/src/shared/ReactDOMFloat'; +export { + prefetchDNS, + preconnect, + preload, + preinit, +} from 'react-dom-bindings/src/shared/ReactDOMFloat'; setAttemptSynchronousHydration(attemptSynchronousHydration); setAttemptDiscreteHydration(attemptDiscreteHydration); From 6ff1733e63fdb948ae973a713741b4526102c73c Mon Sep 17 00:00:00 2001 From: Josh Story Date: Sat, 25 Feb 2023 11:06:09 -0800 Subject: [PATCH 009/103] [Float][Fizz][Fiber] support type for ReactDOM.preload() options (#26239) preloads often need to come with a type attribute which allows browsers to decide if they support the preloading resource's type. If the type is unsupported the preload will not be fetched by the Browser. This change adds support for `type` in `ReactDOM.preload()` as a string option. --- .../src/client/ReactDOMFloatClient.js | 8 +++++++- .../src/server/ReactDOMServerFormatConfig.js | 3 ++- .../src/__tests__/ReactDOMFloat-test.js | 18 ++++++++++++++++-- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js b/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js index f4332cef91945..4dcba9f814905 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js +++ b/packages/react-dom-bindings/src/client/ReactDOMFloatClient.js @@ -253,7 +253,12 @@ function preconnect(href: string, options?: {crossOrigin?: string}) { // ReactDOM.preload // -------------------------------------- type PreloadAs = ResourceType; -type PreloadOptions = {as: PreloadAs, crossOrigin?: string, integrity?: string}; +type PreloadOptions = { + as: PreloadAs, + crossOrigin?: string, + integrity?: string, + type?: string, +}; function preload(href: string, options: PreloadOptions) { if (__DEV__) { validatePreloadArguments(href, options); @@ -309,6 +314,7 @@ function preloadPropsFromPreloadOptions( as, crossOrigin: as === 'font' ? '' : options.crossOrigin, integrity: options.integrity, + type: options.type, }; } diff --git a/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js b/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js index ce7f63b4ccf6f..9bdd89f7f0c8c 100644 --- a/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js +++ b/packages/react-dom-bindings/src/server/ReactDOMServerFormatConfig.js @@ -4344,7 +4344,7 @@ type PreloadOptions = { as: PreloadAs, crossOrigin?: string, integrity?: string, - media?: string, + type?: string, }; export function preload(href: string, options: PreloadOptions) { if (!currentResources) { @@ -4709,6 +4709,7 @@ function preloadPropsFromPreloadOptions( href, crossOrigin: as === 'font' ? '' : options.crossOrigin, integrity: options.integrity, + type: options.type, }; } diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js index e1cc69988c801..b804268af75ab 100644 --- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js @@ -2267,7 +2267,7 @@ body { // @gate enableFloat it('always enforces crossOrigin "anonymous" for font preloads', async () => { function App() { - ReactDOM.preload('foo', {as: 'font'}); + ReactDOM.preload('foo', {as: 'font', type: 'font/woff2'}); ReactDOM.preload('bar', {as: 'font', crossOrigin: 'foo'}); ReactDOM.preload('baz', {as: 'font', crossOrigin: 'use-credentials'}); ReactDOM.preload('qux', {as: 'font', crossOrigin: 'anonymous'}); @@ -2285,7 +2285,13 @@ body { expect(getMeaningfulChildren(document)).toEqual( - + @@ -2488,6 +2494,7 @@ body { function ClientApp() { ReactDOM.preload('foo', {as: 'style'}); + ReactDOM.preload('font', {as: 'font', type: 'font/woff2'}); React.useInsertionEffect(() => ReactDOM.preload('bar', {as: 'script'})); React.useLayoutEffect(() => ReactDOM.preload('baz', {as: 'font'})); React.useEffect(() => ReactDOM.preload('qux', {as: 'style'})); @@ -2507,6 +2514,13 @@ body { + From b2ae9ddb3b497d16a7c27c051da1827d08871138 Mon Sep 17 00:00:00 2001 From: Jan Kassens Date: Mon, 27 Feb 2023 14:04:02 -0500 Subject: [PATCH 010/103] Cleanup enableSyncDefaultUpdate flag (#26236) This feature flag is enabled everywhere. --- .../react-art/src/__tests__/ReactART-test.js | 54 --- .../ReactDOMNativeEventHeuristic-test.js | 6 +- ...DOMServerPartialHydration-test.internal.js | 9 +- .../DOMPluginEventSystem-test.internal.js | 8 +- packages/react-reconciler/src/ReactFiber.js | 7 +- ...asedOnReactExpirationTime-test.internal.js | 8 +- .../src/__tests__/ReactExpiration-test.js | 96 ++---- .../src/__tests__/ReactFlushSync-test.js | 8 +- .../ReactHooksWithNoopRenderer-test.js | 102 ++---- .../src/__tests__/ReactIncremental-test.js | 112 ++----- ...tIncrementalErrorHandling-test.internal.js | 90 +---- .../ReactIncrementalReflection-test.js | 40 +-- .../ReactIncrementalScheduling-test.js | 41 +-- .../ReactIncrementalSideEffects-test.js | 32 +- .../__tests__/ReactIncrementalUpdates-test.js | 108 ++---- .../__tests__/ReactInterleavedUpdates-test.js | 69 +--- .../src/__tests__/ReactLazy-test.internal.js | 8 +- .../src/__tests__/ReactNewContext-test.js | 16 +- .../ReactSchedulerIntegration-test.js | 8 +- .../__tests__/ReactSuspense-test.internal.js | 95 +----- .../src/__tests__/ReactSuspenseList-test.js | 44 +-- .../ReactSuspenseWithNoopRenderer-test.js | 310 +++--------------- .../useMutableSource-test.internal.js | 201 ++---------- .../useMutableSourceHydration-test.js | 26 +- .../__tests__/ReactTestRendererAsync-test.js | 20 +- .../__tests__/ReactProfiler-test.internal.js | 83 +---- ...ofilerDevToolsIntegration-test.internal.js | 8 +- packages/shared/ReactFeatureFlags.js | 3 - .../forks/ReactFeatureFlags.native-fb.js | 1 - .../forks/ReactFeatureFlags.native-oss.js | 1 - .../forks/ReactFeatureFlags.test-renderer.js | 1 - .../ReactFeatureFlags.test-renderer.native.js | 1 - .../ReactFeatureFlags.test-renderer.www.js | 1 - .../shared/forks/ReactFeatureFlags.testing.js | 1 - .../forks/ReactFeatureFlags.testing.www.js | 1 - .../forks/ReactFeatureFlags.www-dynamic.js | 1 - .../shared/forks/ReactFeatureFlags.www.js | 1 - .../src/__tests__/useSubscription-test.js | 32 +- 38 files changed, 271 insertions(+), 1382 deletions(-) diff --git a/packages/react-art/src/__tests__/ReactART-test.js b/packages/react-art/src/__tests__/ReactART-test.js index 6cc38b47b8d7a..714e19d1cc1fe 100644 --- a/packages/react-art/src/__tests__/ReactART-test.js +++ b/packages/react-art/src/__tests__/ReactART-test.js @@ -33,8 +33,6 @@ const ReactTestRenderer = require('react-test-renderer'); // Isolate the noop renderer jest.resetModules(); -const ReactNoop = require('react-noop-renderer'); -const Scheduler = require('scheduler'); let Group; let Shape; @@ -359,58 +357,6 @@ describe('ReactART', () => { doClick(instance); expect(onClick2).toBeCalled(); }); - - // @gate !enableSyncDefaultUpdates - it('can concurrently render with a "primary" renderer while sharing context', () => { - const CurrentRendererContext = React.createContext(null); - - function Yield(props) { - Scheduler.unstable_yieldValue(props.value); - return null; - } - - let ops = []; - function LogCurrentRenderer() { - return ( - - {currentRenderer => { - ops.push(currentRenderer); - return null; - }} - - ); - } - - // Using test renderer instead of the DOM renderer here because async - // testing APIs for the DOM renderer don't exist. - ReactNoop.render( - - - - - - , - ); - - expect(Scheduler).toFlushAndYieldThrough(['A']); - - ReactDOM.render( - - - - - - , - container, - ); - - expect(ops).toEqual([null, 'ART']); - - ops = []; - expect(Scheduler).toFlushAndYield(['B', 'C']); - - expect(ops).toEqual(['Test']); - }); }); describe('ReactARTComponents', () => { diff --git a/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js b/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js index 15605af8702d5..cfdeecf718f03 100644 --- a/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js +++ b/packages/react-dom/src/__tests__/ReactDOMNativeEventHeuristic-test.js @@ -305,11 +305,7 @@ describe('ReactDOMNativeEventHeuristic-test', () => { expect(container.textContent).toEqual('not hovered'); expect(Scheduler).toFlushAndYieldThrough(['hovered']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - expect(container.textContent).toEqual('hovered'); - } else { - expect(container.textContent).toEqual('not hovered'); - } + expect(container.textContent).toEqual('hovered'); }); expect(container.textContent).toEqual('hovered'); }); diff --git a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js index 3886cfe7f3201..0862865f76004 100644 --- a/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js +++ b/packages/react-dom/src/__tests__/ReactDOMServerPartialHydration-test.internal.js @@ -2044,14 +2044,7 @@ describe('ReactDOMServerPartialHydration', () => { suspend = true; await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - expect(Scheduler).toFlushAndYieldThrough(['Before', 'After']); - } else { - expect(Scheduler).toFlushAndYieldThrough(['Before']); - // This took a long time to render. - Scheduler.unstable_advanceTime(1000); - expect(Scheduler).toFlushAndYield(['After']); - } + expect(Scheduler).toFlushAndYieldThrough(['Before', 'After']); // This will cause us to skip the second row completely. }); diff --git a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js index 3cad26f326e1b..6202eec7f3574 100644 --- a/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js +++ b/packages/react-dom/src/events/__tests__/DOMPluginEventSystem-test.internal.js @@ -1965,13 +1965,9 @@ describe('DOMPluginEventSystem', () => { log.length = 0; // Increase counter - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // Yield before committing expect(Scheduler).toFlushAndYieldThrough(['Test']); diff --git a/packages/react-reconciler/src/ReactFiber.js b/packages/react-reconciler/src/ReactFiber.js index b5c89a56df292..e3fc26659c45c 100644 --- a/packages/react-reconciler/src/ReactFiber.js +++ b/packages/react-reconciler/src/ReactFiber.js @@ -33,7 +33,6 @@ import { enableProfilerTimer, enableScopeAPI, enableLegacyHidden, - enableSyncDefaultUpdates, allowConcurrentByDefault, enableTransitionTracing, enableDebugTracing, @@ -459,11 +458,9 @@ export function createHostRootFiber( mode |= StrictLegacyMode | StrictEffectsMode; } if ( - // We only use this flag for our repo tests to check both behaviors. - // TODO: Flip this flag and rename it something like "forceConcurrentByDefaultForTesting" - !enableSyncDefaultUpdates || // Only for internal experiments. - (allowConcurrentByDefault && concurrentUpdatesByDefaultOverride) + allowConcurrentByDefault && + concurrentUpdatesByDefaultOverride ) { mode |= ConcurrentUpdatesByDefaultMode; } diff --git a/packages/react-reconciler/src/__tests__/ReactDisableSchedulerTimeoutBasedOnReactExpirationTime-test.internal.js b/packages/react-reconciler/src/__tests__/ReactDisableSchedulerTimeoutBasedOnReactExpirationTime-test.internal.js index 00608912346c4..2d6828eca1dba 100644 --- a/packages/react-reconciler/src/__tests__/ReactDisableSchedulerTimeoutBasedOnReactExpirationTime-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactDisableSchedulerTimeoutBasedOnReactExpirationTime-test.internal.js @@ -63,13 +63,9 @@ describe('ReactSuspenseList', () => { root.render(); expect(Scheduler).toFlushAndYield([]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield([ 'Suspend! [A]', 'Suspend! [B]', diff --git a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js index 7b96efc2b9f9e..fb041f948f15d 100644 --- a/packages/react-reconciler/src/__tests__/ReactExpiration-test.js +++ b/packages/react-reconciler/src/__tests__/ReactExpiration-test.js @@ -115,13 +115,9 @@ describe('ReactExpiration', () => { } it('increases priority of updates as time progresses', () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(ReactNoop).toMatchRenderedOutput(null); @@ -162,13 +158,9 @@ describe('ReactExpiration', () => { // First, show what happens for updates in two separate events. // Schedule an update. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Advance the timer. Scheduler.unstable_advanceTime(2000); // Partially flush the first update, then interrupt it. @@ -223,13 +215,9 @@ describe('ReactExpiration', () => { // First, show what happens for updates in two separate events. // Schedule an update. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Advance the timer. Scheduler.unstable_advanceTime(2000); // Partially flush the first update, then interrupt it. @@ -301,13 +289,9 @@ describe('ReactExpiration', () => { } // Initial mount - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield([ 'initial [A] [render]', 'initial [B] [render]', @@ -320,13 +304,9 @@ describe('ReactExpiration', () => { ]); // Partial update - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - subscribers.forEach(s => s.setState({text: '1'})); - }); - } else { + React.startTransition(() => { subscribers.forEach(s => s.setState({text: '1'})); - } + }); expect(Scheduler).toFlushAndYieldThrough([ '1 [A] [render]', '1 [B] [render]', @@ -358,13 +338,9 @@ describe('ReactExpiration', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['A']); expect(Scheduler).toFlushAndYieldThrough(['B']); @@ -392,13 +368,9 @@ describe('ReactExpiration', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['A']); expect(Scheduler).toFlushAndYieldThrough(['B']); @@ -426,13 +398,9 @@ describe('ReactExpiration', () => { // current time. ReactNoop = require('react-noop-renderer'); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render('Hi'); - }); - } else { + React.startTransition(() => { ReactNoop.render('Hi'); - } + }); // The update should not have expired yet. flushNextRenderIfExpired(); @@ -455,13 +423,9 @@ describe('ReactExpiration', () => { // Before scheduling an update, advance the current time. Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render('Hi'); - }); - } else { + React.startTransition(() => { ReactNoop.render('Hi'); - } + }); flushNextRenderIfExpired(); expect(Scheduler).toHaveYielded([]); expect(ReactNoop).toMatchRenderedOutput(null); @@ -504,13 +468,9 @@ describe('ReactExpiration', () => { // First demonstrate what happens when there's no starvation await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateNormalPri(); - }); - } else { + React.startTransition(() => { updateNormalPri(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Sync pri: 0']); updateSyncPri(); expect(Scheduler).toHaveYielded(['Sync pri: 1', 'Normal pri: 0']); @@ -528,13 +488,9 @@ describe('ReactExpiration', () => { // Do the same thing, but starve the first update await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateNormalPri(); - }); - } else { + React.startTransition(() => { updateNormalPri(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Sync pri: 1']); // This time, a lot of time has elapsed since the normal pri update @@ -690,13 +646,9 @@ describe('ReactExpiration', () => { expect(root).toMatchRenderedOutput('A0BC'); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield([ 'Suspend! [A1]', 'B', diff --git a/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js b/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js index 5802253e1c1f1..2ec6aa4889420 100644 --- a/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js +++ b/packages/react-reconciler/src/__tests__/ReactFlushSync-test.js @@ -41,13 +41,9 @@ describe('ReactFlushSync', () => { const root = ReactNoop.createRoot(); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // This will yield right before the passive effect fires expect(Scheduler).toFlushUntilNextPaint(['0, 0']); diff --git a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js index 2455f51965c21..6bfd7ae16fed2 100644 --- a/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactHooksWithNoopRenderer-test.js @@ -167,15 +167,10 @@ describe('ReactHooksWithNoopRenderer', () => { // Schedule some updates act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - counter.current.updateCount(1); - counter.current.updateCount(count => count + 10); - }); - } else { + React.startTransition(() => { counter.current.updateCount(1); counter.current.updateCount(count => count + 10); - } + }); // Partially flush without committing expect(Scheduler).toFlushAndYieldThrough(['Count: 11']); @@ -694,24 +689,16 @@ describe('ReactHooksWithNoopRenderer', () => { expect(Scheduler).toFlushAndYield([0]); expect(root).toMatchRenderedOutput(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend!']); expect(root).toMatchRenderedOutput(); // Rendering again should suspend again. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend!']); }); @@ -757,38 +744,25 @@ describe('ReactHooksWithNoopRenderer', () => { expect(root).toMatchRenderedOutput(); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - setLabel('B'); - }); - } else { + React.startTransition(() => { root.render(); setLabel('B'); - } + }); expect(Scheduler).toFlushAndYield(['Suspend!']); expect(root).toMatchRenderedOutput(); // Rendering again should suspend again. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend!']); // Flip the signal back to "cancel" the update. However, the update to // label should still proceed. It shouldn't have been dropped. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield(['B:0']); expect(root).toMatchRenderedOutput(); }); @@ -823,13 +797,9 @@ describe('ReactHooksWithNoopRenderer', () => { ReactNoop.discreteUpdates(() => { setRow(5); }); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - setRow(20); - }); - } else { + React.startTransition(() => { setRow(20); - } + }); }); expect(Scheduler).toHaveYielded(['Up', 'Down']); expect(root).toMatchRenderedOutput(); @@ -1362,13 +1332,9 @@ describe('ReactHooksWithNoopRenderer', () => { ]); // Schedule another update for children, and partially process it. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - setChildStates.forEach(setChildState => setChildState(2)); - }); - } else { + React.startTransition(() => { setChildStates.forEach(setChildState => setChildState(2)); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Child one render']); // Schedule unmount for the parent that unmounts children with pending update. @@ -1674,42 +1640,24 @@ describe('ReactHooksWithNoopRenderer', () => { expect(ReactNoop).toMatchRenderedOutput(); // Rendering again should flush the previous commit's effects - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(, () => - Scheduler.unstable_yieldValue('Sync effect'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render(, () => Scheduler.unstable_yieldValue('Sync effect'), ); - } + }); expect(Scheduler).toFlushAndYieldThrough([ 'Schedule update [0]', 'Count: 0', ]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - expect(ReactNoop).toMatchRenderedOutput(); - expect(Scheduler).toFlushAndYieldThrough([ - 'Count: 0', - 'Sync effect', - 'Schedule update [1]', - 'Count: 1', - ]); - } else { - expect(ReactNoop).toMatchRenderedOutput( - , - ); - expect(Scheduler).toFlushAndYieldThrough(['Sync effect']); - expect(ReactNoop).toMatchRenderedOutput(); - - ReactNoop.flushPassiveEffects(); - expect(Scheduler).toHaveYielded(['Schedule update [1]']); - expect(Scheduler).toFlushAndYield(['Count: 1']); - } + expect(ReactNoop).toMatchRenderedOutput(); + expect(Scheduler).toFlushAndYieldThrough([ + 'Count: 0', + 'Sync effect', + 'Schedule update [1]', + 'Count: 1', + ]); expect(ReactNoop).toMatchRenderedOutput(); }); diff --git a/packages/react-reconciler/src/__tests__/ReactIncremental-test.js b/packages/react-reconciler/src/__tests__/ReactIncremental-test.js index 47323ffc09f4f..21edc33da1711 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncremental-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncremental-test.js @@ -65,17 +65,11 @@ describe('ReactIncremental', () => { return [, ]; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(, () => - Scheduler.unstable_yieldValue('callback'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render(, () => Scheduler.unstable_yieldValue('callback'), ); - } + }); // Do one step of work. expect(ReactNoop.flushNextYield()).toEqual(['Foo']); @@ -162,26 +156,18 @@ describe('ReactIncremental', () => { ReactNoop.render(); expect(Scheduler).toFlushAndYield(['Foo', 'Bar', 'Bar']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush part of the work expect(Scheduler).toFlushAndYieldThrough(['Foo', 'Bar']); // This will abort the previous work and restart ReactNoop.flushSync(() => ReactNoop.render(null)); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush part of the new work expect(Scheduler).toFlushAndYieldThrough(['Foo', 'Bar']); @@ -215,17 +201,7 @@ describe('ReactIncremental', () => { ReactNoop.render(); expect(Scheduler).toFlushWithoutYielding(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - inst.setState( - () => { - Scheduler.unstable_yieldValue('setState1'); - return {text: 'bar'}; - }, - () => Scheduler.unstable_yieldValue('callback1'), - ); - }); - } else { + React.startTransition(() => { inst.setState( () => { Scheduler.unstable_yieldValue('setState1'); @@ -233,24 +209,14 @@ describe('ReactIncremental', () => { }, () => Scheduler.unstable_yieldValue('callback1'), ); - } + }); // Flush part of the work expect(Scheduler).toFlushAndYieldThrough(['setState1']); // This will abort the previous work and restart ReactNoop.flushSync(() => ReactNoop.render()); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - inst.setState( - () => { - Scheduler.unstable_yieldValue('setState2'); - return {text2: 'baz'}; - }, - () => Scheduler.unstable_yieldValue('callback2'), - ); - }); - } else { + React.startTransition(() => { inst.setState( () => { Scheduler.unstable_yieldValue('setState2'); @@ -258,7 +224,7 @@ describe('ReactIncremental', () => { }, () => Scheduler.unstable_yieldValue('callback2'), ); - } + }); // Flush the rest of the work which now includes the low priority expect(Scheduler).toFlushAndYield([ @@ -1878,18 +1844,7 @@ describe('ReactIncremental', () => { 'ShowLocale {"locale":"de"}', 'ShowBoth {"locale":"de"}', ]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - -
- -
-
, - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( @@ -1898,7 +1853,7 @@ describe('ReactIncremental', () => { , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Intl {}']); ReactNoop.render( @@ -2028,22 +1983,7 @@ describe('ReactIncremental', () => { } } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - - - - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( @@ -2056,7 +1996,7 @@ describe('ReactIncremental', () => { , ); - } + }); expect(Scheduler).toFlushAndYieldThrough([ 'Intl {}', 'ShowLocale {"locale":"fr"}', @@ -2746,13 +2686,9 @@ describe('ReactIncremental', () => { return null; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Parent: 1']); // Interrupt at same priority @@ -2772,13 +2708,9 @@ describe('ReactIncremental', () => { return null; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Parent: 1']); // Interrupt at lower priority @@ -2799,13 +2731,9 @@ describe('ReactIncremental', () => { return null; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Parent: 1']); // Interrupt at higher priority diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js index a5c273b25c076..547efa26faf84 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalErrorHandling-test.internal.js @@ -87,23 +87,7 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('oops!'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - - - - - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( @@ -117,7 +101,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - } + }); // Start rendering asynchronously expect(Scheduler).toFlushAndYieldThrough([ @@ -201,23 +185,7 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('oops!'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - - - - - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( @@ -231,7 +199,7 @@ describe('ReactIncrementalErrorHandling', () => { , ); - } + }); // Start rendering asynchronously expect(Scheduler).toFlushAndYieldThrough([ @@ -399,17 +367,11 @@ describe('ReactIncrementalErrorHandling', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(, () => - Scheduler.unstable_yieldValue('commit'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render(, () => Scheduler.unstable_yieldValue('commit'), ); - } + }); // Render the bad component asynchronously expect(Scheduler).toFlushAndYieldThrough(['Parent', 'BadRender']); @@ -451,13 +413,9 @@ describe('ReactIncrementalErrorHandling', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render part of the tree expect(Scheduler).toFlushAndYieldThrough(['A', 'B']); @@ -592,21 +550,13 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('Hello'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['ErrorBoundary render success']); expect(ReactNoop).toMatchRenderedOutput(null); @@ -781,21 +731,13 @@ describe('ReactIncrementalErrorHandling', () => { throw new Error('Hello'); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['RethrowErrorBoundary render']); @@ -1875,13 +1817,9 @@ describe('ReactIncrementalErrorHandling', () => { } await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // Render past the component that throws, then yield. expect(Scheduler).toFlushAndYieldThrough(['Oops']); diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js index 45ecb936587eb..319be4c9f2b9f 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalReflection-test.js @@ -63,13 +63,9 @@ describe('ReactIncrementalReflection', () => { return ; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render part way through but don't yet commit the updates. expect(Scheduler).toFlushAndYieldThrough(['componentWillMount: false']); @@ -117,13 +113,9 @@ describe('ReactIncrementalReflection', () => { expect(instances[0]._isMounted()).toBe(true); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render part way through but don't yet commit the updates so it is not // fully unmounted yet. expect(Scheduler).toFlushAndYieldThrough(['Other']); @@ -206,13 +198,9 @@ describe('ReactIncrementalReflection', () => { return [, ]; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush past Component but don't complete rendering everything yet. expect(Scheduler).toFlushAndYieldThrough([ ['componentWillMount', null], @@ -246,13 +234,9 @@ describe('ReactIncrementalReflection', () => { // The next step will render a new host node but won't get committed yet. // We expect this to mutate the original Fiber. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough([ ['componentWillUpdate', hostSpan], 'render', @@ -273,13 +257,9 @@ describe('ReactIncrementalReflection', () => { expect(ReactNoop.findInstance(classInstance)).toBe(hostDiv); // Render to null but don't commit it yet. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough([ ['componentWillUpdate', hostDiv], 'render', diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js index 3cc006dad1c52..cfb09e497eb12 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalScheduling-test.js @@ -105,15 +105,10 @@ describe('ReactIncrementalScheduling', () => { // Schedule deferred work in the reverse order act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.renderToRootWithID(, 'c'); - ReactNoop.renderToRootWithID(, 'b'); - }); - } else { + React.startTransition(() => { ReactNoop.renderToRootWithID(, 'c'); ReactNoop.renderToRootWithID(, 'b'); - } + }); // Ensure it starts in the order it was scheduled expect(Scheduler).toFlushAndYieldThrough(['c:2']); @@ -122,13 +117,9 @@ describe('ReactIncrementalScheduling', () => { expect(ReactNoop.getChildrenAsJSX('c')).toEqual('c:2'); // Schedule last bit of work, it will get processed the last - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.renderToRootWithID(, 'a'); - }); - } else { + React.startTransition(() => { ReactNoop.renderToRootWithID(, 'a'); - } + }); // Keep performing work in the order it was scheduled expect(Scheduler).toFlushAndYieldThrough(['b:2']); @@ -181,13 +172,9 @@ describe('ReactIncrementalScheduling', () => { } } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render without committing expect(Scheduler).toFlushAndYieldThrough(['render: 0']); @@ -201,13 +188,9 @@ describe('ReactIncrementalScheduling', () => { 'componentDidUpdate: 1', ]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - instance.setState({tick: 2}); - }); - } else { + React.startTransition(() => { instance.setState({tick: 2}); - } + }); expect(Scheduler).toFlushAndYieldThrough(['render: 2']); expect(ReactNoop.flushNextYield()).toEqual([ 'componentDidUpdate: 2', @@ -310,13 +293,9 @@ describe('ReactIncrementalScheduling', () => { return ; } } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // This should be just enough to complete all the work, but not enough to // commit it. diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js index 3e4cd2e4f55b5..fd1361de82205 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalSideEffects-test.js @@ -456,13 +456,9 @@ describe('ReactIncrementalSideEffects', () => { , ); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Flush some of the work without committing expect(Scheduler).toFlushAndYieldThrough(['Foo', 'Bar']); @@ -697,13 +693,9 @@ describe('ReactIncrementalSideEffects', () => { Scheduler.unstable_yieldValue('Foo'); return ; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // This should be just enough to complete the tree without committing it expect(Scheduler).toFlushAndYieldThrough(['Foo']); expect(ReactNoop.getChildrenAsJSX()).toEqual(null); @@ -712,26 +704,18 @@ describe('ReactIncrementalSideEffects', () => { ReactNoop.flushNextYield(); expect(ReactNoop.getChildrenAsJSX()).toEqual(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // This should be just enough to complete the tree without committing it expect(Scheduler).toFlushAndYieldThrough(['Foo']); expect(ReactNoop.getChildrenAsJSX()).toEqual(); // This time, before we commit the tree, we update the root component with // new props - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(ReactNoop.getChildrenAsJSX()).toEqual(); // Now let's commit. We already had a commit that was pending, which will // render 2. diff --git a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js index 1d6ab92a49b56..de60712c11665 100644 --- a/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js +++ b/packages/react-reconciler/src/__tests__/ReactIncrementalUpdates-test.js @@ -152,21 +152,11 @@ describe('ReactIncrementalUpdates', () => { } // Schedule some async updates - if ( - gate( - flags => flags.enableSyncDefaultUpdates || flags.enableUnifiedSyncLane, - ) - ) { - React.startTransition(() => { - instance.setState(createUpdate('a')); - instance.setState(createUpdate('b')); - instance.setState(createUpdate('c')); - }); - } else { + React.startTransition(() => { instance.setState(createUpdate('a')); instance.setState(createUpdate('b')); instance.setState(createUpdate('c')); - } + }); // Begin the updates but don't flush them yet expect(Scheduler).toFlushAndYieldThrough(['a', 'b', 'c']); @@ -183,11 +173,7 @@ describe('ReactIncrementalUpdates', () => { }); // The sync updates should have flushed, but not the async ones. - if ( - gate( - flags => flags.enableSyncDefaultUpdates && flags.enableUnifiedSyncLane, - ) - ) { + if (gate(flags => flags.enableUnifiedSyncLane)) { expect(Scheduler).toHaveYielded(['d', 'e', 'f']); expect(ReactNoop).toMatchRenderedOutput(); } else { @@ -199,11 +185,7 @@ describe('ReactIncrementalUpdates', () => { // Now flush the remaining work. Even though e and f were already processed, // they should be processed again, to ensure that the terminal state // is deterministic. - if ( - gate( - flags => flags.enableSyncDefaultUpdates && !flags.enableUnifiedSyncLane, - ) - ) { + if (gate(flags => !flags.enableUnifiedSyncLane)) { expect(Scheduler).toFlushAndYield([ // Since 'g' is in a transition, we'll process 'd' separately first. // That causes us to process 'd' with 'e' and 'f' rebased. @@ -257,21 +239,11 @@ describe('ReactIncrementalUpdates', () => { } // Schedule some async updates - if ( - gate( - flags => flags.enableSyncDefaultUpdates || flags.enableUnifiedSyncLane, - ) - ) { - React.startTransition(() => { - instance.setState(createUpdate('a')); - instance.setState(createUpdate('b')); - instance.setState(createUpdate('c')); - }); - } else { + React.startTransition(() => { instance.setState(createUpdate('a')); instance.setState(createUpdate('b')); instance.setState(createUpdate('c')); - } + }); // Begin the updates but don't flush them yet expect(Scheduler).toFlushAndYieldThrough(['a', 'b', 'c']); @@ -291,11 +263,7 @@ describe('ReactIncrementalUpdates', () => { }); // The sync updates should have flushed, but not the async ones. - if ( - gate( - flags => flags.enableSyncDefaultUpdates && flags.enableUnifiedSyncLane, - ) - ) { + if (gate(flags => flags.enableUnifiedSyncLane)) { expect(Scheduler).toHaveYielded(['d', 'e', 'f']); } else { // Update d was dropped and replaced by e. @@ -306,11 +274,7 @@ describe('ReactIncrementalUpdates', () => { // Now flush the remaining work. Even though e and f were already processed, // they should be processed again, to ensure that the terminal state // is deterministic. - if ( - gate( - flags => flags.enableSyncDefaultUpdates && !flags.enableUnifiedSyncLane, - ) - ) { + if (gate(flags => !flags.enableUnifiedSyncLane)) { expect(Scheduler).toFlushAndYield([ // Since 'g' is in a transition, we'll process 'd' separately first. // That causes us to process 'd' with 'e' and 'f' rebased. @@ -566,13 +530,9 @@ describe('ReactIncrementalUpdates', () => { } act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); flushNextRenderIfExpired(); expect(Scheduler).toHaveYielded([]); expect(Scheduler).toFlushAndYield([ @@ -582,13 +542,9 @@ describe('ReactIncrementalUpdates', () => { ]); Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - setCount(2); - }); - } else { + React.startTransition(() => { setCount(2); - } + }); flushNextRenderIfExpired(); expect(Scheduler).toHaveYielded([]); }); @@ -607,13 +563,9 @@ describe('ReactIncrementalUpdates', () => { Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); flushNextRenderIfExpired(); expect(Scheduler).toHaveYielded([]); }); @@ -624,26 +576,18 @@ describe('ReactIncrementalUpdates', () => { return text; } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); Scheduler.unstable_advanceTime(10000); flushNextRenderIfExpired(); expect(Scheduler).toHaveYielded(['A']); Scheduler.unstable_advanceTime(10000); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); flushNextRenderIfExpired(); expect(Scheduler).toHaveYielded([]); }); @@ -680,13 +624,9 @@ describe('ReactIncrementalUpdates', () => { expect(root).toMatchRenderedOutput(null); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - pushToLog('A'); - }); - } else { + React.startTransition(() => { pushToLog('A'); - } + }); ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('B'), @@ -749,13 +689,9 @@ describe('ReactIncrementalUpdates', () => { expect(root).toMatchRenderedOutput(null); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - pushToLog('A'); - }); - } else { + React.startTransition(() => { pushToLog('A'); - } + }); ReactNoop.unstable_runWithPriority(ContinuousEventPriority, () => pushToLog('B'), ); diff --git a/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js b/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js index 153d4d28bd3f7..89d9de5226d9e 100644 --- a/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js +++ b/packages/react-reconciler/src/__tests__/ReactInterleavedUpdates-test.js @@ -57,78 +57,15 @@ describe('ReactInterleavedUpdates', () => { expect(root).toMatchRenderedOutput('000'); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateChildren(1); - }); - } else { + React.startTransition(() => { updateChildren(1); - } - // Partially render the children. Only the first one. - expect(Scheduler).toFlushAndYieldThrough([1]); - - // In an interleaved event, schedule an update on each of the children. - // Including the two that haven't rendered yet. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateChildren(2); - }); - } else { - updateChildren(2); - } - - // We should continue rendering without including the interleaved updates. - expect(Scheduler).toFlushUntilNextPaint([1, 1]); - expect(root).toMatchRenderedOutput('111'); - }); - // The interleaved updates flush in a separate render. - expect(Scheduler).toHaveYielded([2, 2, 2]); - expect(root).toMatchRenderedOutput('222'); - }); - - // @gate !enableSyncDefaultUpdates - test('low priority update during an interleaved event is not processed during the current render', async () => { - // Same as previous test, but the interleaved update is lower priority than - // the in-progress render. - const updaters = []; - - function Child() { - const [state, setState] = useState(0); - useEffect(() => { - updaters.push(setState); - }, []); - return ; - } - - function updateChildren(value) { - for (let i = 0; i < updaters.length; i++) { - const setState = updaters[i]; - setState(value); - } - } - - const root = ReactNoop.createRoot(); - - await act(async () => { - root.render( - <> - - - - , - ); - }); - expect(Scheduler).toHaveYielded([0, 0, 0]); - expect(root).toMatchRenderedOutput('000'); - - await act(async () => { - updateChildren(1); + }); // Partially render the children. Only the first one. expect(Scheduler).toFlushAndYieldThrough([1]); // In an interleaved event, schedule an update on each of the children. // Including the two that haven't rendered yet. - startTransition(() => { + React.startTransition(() => { updateChildren(2); }); diff --git a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js index 5f389b7f74384..627bab2368dc3 100644 --- a/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactLazy-test.internal.js @@ -1560,13 +1560,9 @@ describe('ReactLazy', () => { expect(root).toMatchRenderedOutput('AB'); // Swap the position of A and B - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.update(); - }); - } else { + React.startTransition(() => { root.update(); - } + }); expect(Scheduler).toFlushAndYield(['Init B2', 'Loading...']); await lazyChildB2; // We need to flush to trigger the second one to load. diff --git a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js index 6f995d164327f..bc9d4283894d3 100644 --- a/packages/react-reconciler/src/__tests__/ReactNewContext-test.js +++ b/packages/react-reconciler/src/__tests__/ReactNewContext-test.js @@ -881,13 +881,9 @@ describe('ReactNewContext', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); // Render past the Provider, but don't commit yet expect(Scheduler).toFlushAndYieldThrough(['Foo']); @@ -927,13 +923,9 @@ describe('ReactNewContext', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield(['Foo', 'Foo']); // Get a new copy of ReactNoop diff --git a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js index 70344ae700145..8db1a121d8f27 100644 --- a/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSchedulerIntegration-test.js @@ -102,13 +102,9 @@ describe('ReactSchedulerIntegration', () => { scheduleCallback(NormalPriority, () => Scheduler.unstable_yieldValue('C')); // Schedule a React render. React will request a paint after committing it. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render('Update'); - }); - } else { + React.startTransition(() => { root.render('Update'); - } + }); // Advance time just to be sure the next tasks have lower priority Scheduler.unstable_advanceTime(2000); diff --git a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js index 05483e15c7dc1..9c4ba7794b1fa 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspense-test.internal.js @@ -124,13 +124,9 @@ describe('ReactSuspense', () => { // Navigate the shell to now render the child content. // This should suspend. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.update(); - }); - } else { + React.startTransition(() => { root.update(); - } + }); expect(Scheduler).toFlushAndYield([ 'Foo', @@ -239,19 +235,7 @@ describe('ReactSuspense', () => { expect(root).toMatchRenderedOutput('Initial'); // The update will suspend. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.update( - <> - }> - - - - - , - ); - }); - } else { + React.startTransition(() => { root.update( <> }> @@ -261,8 +245,7 @@ describe('ReactSuspense', () => { , ); - } - + }); // Yield past the Suspense boundary but don't complete the last sibling. expect(Scheduler).toFlushAndYieldThrough([ 'Suspend!', @@ -396,76 +379,6 @@ describe('ReactSuspense', () => { expect(root).toMatchRenderedOutput('AB'); }); - // @gate !enableSyncDefaultUpdates - it( - 'interrupts current render when something suspends with a ' + - "delay and we've already skipped over a lower priority update in " + - 'a parent', - () => { - function interrupt() { - // React has a heuristic to batch all updates that occur within the same - // event. This is a trick to circumvent that heuristic. - ReactTestRenderer.create('whatever'); - } - - function App({shouldSuspend, step}) { - return ( - <> - - }> - {shouldSuspend ? : null} - - - - - ); - } - - const root = ReactTestRenderer.create(null, { - unstable_isConcurrent: true, - }); - - root.update(); - expect(Scheduler).toFlushAndYield(['A0', 'B0', 'C0']); - expect(root).toMatchRenderedOutput('A0B0C0'); - - // This update will suspend. - root.update(); - - // Do a bit of work - expect(Scheduler).toFlushAndYieldThrough(['A1']); - - // Schedule another update. This will have lower priority because it's - // a transition. - React.startTransition(() => { - root.update(); - }); - - // Interrupt to trigger a restart. - interrupt(); - - expect(Scheduler).toFlushAndYieldThrough([ - // Should have restarted the first update, because of the interruption - 'A1', - 'Suspend! [Async]', - 'Loading...', - 'B1', - ]); - - // Should not have committed loading state - expect(root).toMatchRenderedOutput('A0B0C0'); - - // After suspending, should abort the first update and switch to the - // second update. So, C1 should not appear in the log. - // TODO: This should work even if React does not yield to the main - // thread. Should use same mechanism as selective hydration to interrupt - // the render before the end of the current slice of work. - expect(Scheduler).toFlushAndYield(['A2', 'B2', 'C2']); - - expect(root).toMatchRenderedOutput('A2B2C2'); - }, - ); - it('mounts a lazy class component in non-concurrent mode', async () => { class Class extends React.Component { componentDidMount() { diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js index 8ff0f35c70fae..701d23854993d 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseList-test.js @@ -1362,13 +1362,9 @@ describe('ReactSuspenseList', () => { } // This render is only CPU bound. Nothing suspends. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['A']); @@ -1546,13 +1542,9 @@ describe('ReactSuspenseList', () => { } // This render is only CPU bound. Nothing suspends. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['A']); @@ -2548,15 +2540,9 @@ describe('ReactSuspenseList', () => { expect(ReactNoop).toMatchRenderedOutput(null); await act(async () => { - // Add a few items at the end. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - updateLowPri(true); - }); - } else { + React.startTransition(() => { updateLowPri(true); - } - + }); // Flush partially through. expect(Scheduler).toFlushAndYieldThrough(['B', 'C']); @@ -2692,14 +2678,9 @@ describe('ReactSuspenseList', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } - + }); expect(Scheduler).toFlushAndYieldThrough([ 'App', 'First Pass A', @@ -2765,14 +2746,9 @@ describe('ReactSuspenseList', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } - + }); expect(Scheduler).toFlushAndYieldThrough([ 'App', 'First Pass A', diff --git a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js index aad8729adde1c..c73cd296b8695 100644 --- a/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js +++ b/packages/react-reconciler/src/__tests__/ReactSuspenseWithNoopRenderer-test.js @@ -205,13 +205,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { ); } - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough([ 'Foo', 'Bar', @@ -281,13 +277,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(Scheduler).toFlushAndYield(['Foo']); // The update will suspend. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield([ 'Foo', 'Bar', @@ -368,18 +360,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { ReactNoop.render(} />); expect(Scheduler).toFlushAndYield([]); // B suspends. Continue rendering the remaining siblings. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - }> - - - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( }> @@ -388,7 +369,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { , ); - } + }); // B suspends. Continue rendering the remaining siblings. expect(Scheduler).toFlushAndYield([ 'A', @@ -452,13 +433,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(Scheduler).toFlushAndYield([]); expect(ReactNoop).toMatchRenderedOutput(null); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend! [Result]', 'Loading...']); expect(ReactNoop).toMatchRenderedOutput(null); @@ -603,26 +580,18 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(Scheduler).toFlushAndYield([]); expect(ReactNoop).toMatchRenderedOutput(null); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'Loading...']); expect(ReactNoop).toMatchRenderedOutput(null); // Advance React's virtual time by enough to fall into a new async bucket, // but not enough to expire the suspense timeout. ReactNoop.expire(120); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend! [A]', 'B', 'Loading...']); expect(ReactNoop).toMatchRenderedOutput(null); @@ -704,35 +673,23 @@ describe('ReactSuspenseWithNoopRenderer', () => { // Schedule an update at several distinct expiration times await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); Scheduler.unstable_advanceTime(1000); expect(Scheduler).toFlushAndYieldThrough(['Sibling']); interrupt(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); Scheduler.unstable_advanceTime(1000); expect(Scheduler).toFlushAndYieldThrough(['Sibling']); interrupt(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); Scheduler.unstable_advanceTime(1000); expect(Scheduler).toFlushAndYieldThrough(['Sibling']); interrupt(); @@ -1049,18 +1006,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { ); expect(Scheduler).toFlushAndYield([]); expect(root).toMatchRenderedOutput(null); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render( - <> - }> - - - - , - ); - }); - } else { + React.startTransition(() => { root.render( <> }> @@ -1069,7 +1015,7 @@ describe('ReactSuspenseWithNoopRenderer', () => { , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Suspend! [Async]', 'Sibling']); await resolveText('Async'); @@ -1135,21 +1081,13 @@ describe('ReactSuspenseWithNoopRenderer', () => { ReactNoop.render(} />); expect(Scheduler).toFlushAndYield([]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - }> - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( }> , ); - } + }); expect(Scheduler).toFlushAndYield(['Suspend! [Async]', 'Loading...']); expect(ReactNoop).toMatchRenderedOutput(null); @@ -1954,13 +1892,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { ReactNoop.render(); expect(Scheduler).toFlushAndYield(['Foo']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); Scheduler.unstable_advanceTime(100); await advanceTimers(100); // Start rendering @@ -1989,22 +1923,14 @@ describe('ReactSuspenseWithNoopRenderer', () => { await advanceTimers(500); // No need to rerender. expect(Scheduler).toFlushWithoutYielding(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // Since this is a transition, we never fallback. - expect(ReactNoop).toMatchRenderedOutput(null); - } else { - expect(ReactNoop).toMatchRenderedOutput(); - } + // Since this is a transition, we never fallback. + expect(ReactNoop).toMatchRenderedOutput(null); // Flush the promise completely await resolveText('A'); // Renders successfully - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // TODO: Why does this render Foo - expect(Scheduler).toFlushAndYield(['Foo', 'A']); - } else { - expect(Scheduler).toFlushAndYield(['A']); - } + // TODO: Why does this render Foo + expect(Scheduler).toFlushAndYield(['Foo', 'A']); expect(ReactNoop).toMatchRenderedOutput(); }); @@ -2138,13 +2064,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { ReactNoop.render(); expect(Scheduler).toFlushAndYield(['Foo']); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Foo']); // Advance some time. @@ -2169,12 +2091,8 @@ describe('ReactSuspenseWithNoopRenderer', () => { // updates as way earlier in the past. This test ensures that we don't // use this assumption to add a very long JND. expect(Scheduler).toFlushWithoutYielding(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // Transitions never fallback. - expect(ReactNoop).toMatchRenderedOutput(null); - } else { - expect(ReactNoop).toMatchRenderedOutput(); - } + // Transitions never fallback. + expect(ReactNoop).toMatchRenderedOutput(null); }); // TODO: flip to "warns" when this is implemented again. @@ -2542,13 +2460,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(Scheduler).toFlushAndYield(['Foo', 'A']); expect(ReactNoop).toMatchRenderedOutput(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield([ 'Foo', @@ -2563,17 +2477,8 @@ describe('ReactSuspenseWithNoopRenderer', () => { Scheduler.unstable_advanceTime(600); await advanceTimers(600); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // Transitions never fall back. - expect(ReactNoop).toMatchRenderedOutput(); - } else { - expect(ReactNoop).toMatchRenderedOutput( - <> - - - , - ); - } + // Transitions never fall back. + expect(ReactNoop).toMatchRenderedOutput(); }); // @gate enableLegacyCache @@ -2598,13 +2503,9 @@ describe('ReactSuspenseWithNoopRenderer', () => { expect(Scheduler).toFlushAndYield(['Foo', 'A']); expect(ReactNoop).toMatchRenderedOutput(); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render(); - }); - } else { + React.startTransition(() => { ReactNoop.render(); - } + }); expect(Scheduler).toFlushAndYield([ 'Foo', @@ -2619,12 +2520,8 @@ describe('ReactSuspenseWithNoopRenderer', () => { Scheduler.unstable_advanceTime(600); await advanceTimers(600); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // Transitions never fall back. - expect(ReactNoop).toMatchRenderedOutput(); - } else { - expect(ReactNoop).toMatchRenderedOutput(); - } + // Transitions never fall back. + expect(ReactNoop).toMatchRenderedOutput(); }); // @gate enableLegacyCache @@ -3160,26 +3057,18 @@ describe('ReactSuspenseWithNoopRenderer', () => { await act(async () => { // Update. Since showing a fallback would hide content that's already // visible, it should suspend for a JND without committing. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend! [First update]']); // Should not display a fallback expect(root).toMatchRenderedOutput(); // Update again. This should also suspend for a JND. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); expect(Scheduler).toFlushAndYield(['Suspend! [Second update]']); // Should not display a fallback @@ -3951,117 +3840,6 @@ describe('ReactSuspenseWithNoopRenderer', () => { ); }); - // @gate enableLegacyCache - // @gate !enableSyncDefaultUpdates - it('regression: ping at high priority causes update to be dropped', async () => { - const {useState, useTransition} = React; - - let setTextA; - function A() { - const [textA, _setTextA] = useState('A'); - setTextA = _setTextA; - return ( - }> - - - ); - } - - let setTextB; - let startTransition; - function B() { - const [textB, _setTextB] = useState('B'); - // eslint-disable-next-line no-unused-vars - const [_, _startTransition] = useTransition(); - startTransition = _startTransition; - setTextB = _setTextB; - return ( - }> - - - ); - } - - function App() { - return ( - <> - - - - ); - } - - const root = ReactNoop.createRoot(); - await act(async () => { - await seedNextTextCache('A'); - await seedNextTextCache('B'); - root.render(); - }); - expect(Scheduler).toHaveYielded(['A', 'B']); - expect(root).toMatchRenderedOutput( - <> - - - , - ); - - await act(async () => { - // Triggers suspense at normal pri - setTextA('A1'); - // Triggers in an unrelated tree at a different pri - startTransition(() => { - // Update A again so that it doesn't suspend on A1. That way we can ping - // the A1 update without also pinging this one. This is a workaround - // because there's currently no way to render at a lower priority (B2) - // without including all updates at higher priority (A1). - setTextA('A2'); - setTextB('B2'); - }); - - expect(Scheduler).toFlushAndYield([ - 'B', - 'Suspend! [A1]', - 'Loading...', - - 'Suspend! [A2]', - 'Loading...', - 'Suspend! [B2]', - 'Loading...', - ]); - expect(root).toMatchRenderedOutput( - <> - - - , - ); - - await resolveText('A1'); - expect(Scheduler).toFlushAndYield([ - 'A1', - 'Suspend! [A2]', - 'Loading...', - 'Suspend! [B2]', - 'Loading...', - ]); - expect(root).toMatchRenderedOutput( - <> - - - , - ); - - await resolveText('A2'); - await resolveText('B2'); - }); - expect(Scheduler).toHaveYielded(['A2', 'B2']); - expect(root).toMatchRenderedOutput( - <> - - - , - ); - }); - // Regression: https://github.com/facebook/react/issues/18486 // @gate enableLegacyCache it('does not get stuck in pending state with render phase updates', async () => { diff --git a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js index 27046562c9709..2ce13bf613f18 100644 --- a/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js +++ b/packages/react-reconciler/src/__tests__/useMutableSource-test.internal.js @@ -215,27 +215,7 @@ describe('useMutableSource', () => { const mutableSource = createMutableSource(source, param => param.version); act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - () => Scheduler.unstable_yieldValue('Sync effect'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { , () => Scheduler.unstable_yieldValue('Sync effect'), ); - } + }); // Do enough work to read from one component expect(Scheduler).toFlushAndYieldThrough(['a:one']); @@ -454,13 +434,9 @@ describe('useMutableSource', () => { // Changing values should schedule an update with React. // Start working on this update but don't finish it. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - source.value = 'two'; - }); - } else { + React.startTransition(() => { source.value = 'two'; - } + }); expect(Scheduler).toFlushAndYieldThrough(['a:two']); // Re-renders that occur before the update is processed @@ -724,33 +700,7 @@ describe('useMutableSource', () => { // Because the store has not changed yet, there are no pending updates, // so it is considered safe to read from when we start this render. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - - , - () => Scheduler.unstable_yieldValue('Sync effect'), - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { , () => Scheduler.unstable_yieldValue('Sync effect'), ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['a:a:one', 'b:b:one']); // Mutating the source should trigger a tear detection on the next read, @@ -865,26 +815,7 @@ describe('useMutableSource', () => { act(() => { // Start a render that uses the mutable source. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { /> , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['a:one']); // Mutate source @@ -1535,17 +1466,7 @@ describe('useMutableSource', () => { expect(root).toMatchRenderedOutput('a0'); await act(async () => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render( - <> - - - - , - ); - }); - } else { + React.startTransition(() => { root.render( <> @@ -1553,7 +1474,7 @@ describe('useMutableSource', () => { , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['a0', 'b0']); // Mutate in an event. This schedules a subscription update on a, which @@ -1689,13 +1610,9 @@ describe('useMutableSource', () => { await act(async () => { // Switch the parent and the child to read using the same config - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.render(); - }); - } else { + React.startTransition(() => { root.render(); - } + }); // Start rendering the parent, but yield before rendering the child expect(Scheduler).toFlushAndYieldThrough(['Parent: 2']); @@ -1706,41 +1623,19 @@ describe('useMutableSource', () => { source.valueB = '3'; }); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - // In default sync mode, all of the updates flush sync. - expect(Scheduler).toFlushAndYieldThrough([ - // The partial render completes - 'Child: 2', - 'Commit: 2, 2', - 'Parent: 3', - 'Child: 3', - ]); - - expect(Scheduler).toFlushAndYield([ - // Now finish the rest of the update - 'Commit: 3, 3', - ]); - } else { - expect(Scheduler).toFlushAndYieldThrough([ - // The partial render completes - 'Child: 2', - 'Commit: 2, 2', - ]); - - // Now there are two pending mutations at different priorities. But they - // both read the same version of the mutable source, so we must render - // them simultaneously. - // - expect(Scheduler).toFlushAndYieldThrough([ - 'Parent: 3', - // Demonstrates that we can yield here - ]); - expect(Scheduler).toFlushAndYield([ - // Now finish the rest of the update - 'Child: 3', - 'Commit: 3, 3', - ]); - } + // In default sync mode, all of the updates flush sync. + expect(Scheduler).toFlushAndYieldThrough([ + // The partial render completes + 'Child: 2', + 'Commit: 2, 2', + 'Parent: 3', + 'Child: 3', + ]); + + expect(Scheduler).toFlushAndYield([ + // Now finish the rest of the update + 'Commit: 3, 3', + ]); }); }); @@ -1860,26 +1755,7 @@ describe('useMutableSource', () => { act(() => { // Start a render that uses the mutable source. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { /> , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['a:one']); const PrevScheduler = Scheduler; @@ -1941,26 +1817,7 @@ describe('useMutableSource', () => { act(() => { // Start a render that uses the mutable source. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactNoop.render( - <> - - - , - ); - }); - } else { + React.startTransition(() => { ReactNoop.render( <> { /> , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['a:one']); const PrevScheduler = Scheduler; diff --git a/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js b/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js index ac709916ce381..48e56959c0a02 100644 --- a/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js +++ b/packages/react-reconciler/src/__tests__/useMutableSourceHydration-test.js @@ -254,23 +254,14 @@ describe('useMutableSourceHydration', () => { expect(() => { act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactDOMClient.hydrateRoot(container, , { - mutableSources: [mutableSource], - onRecoverableError(error) { - Scheduler.unstable_yieldValue('Log error: ' + error.message); - }, - }); - }); - } else { + React.startTransition(() => { ReactDOMClient.hydrateRoot(container, , { mutableSources: [mutableSource], onRecoverableError(error) { Scheduler.unstable_yieldValue('Log error: ' + error.message); }, }); - } + }); expect(Scheduler).toFlushAndYieldThrough(['a:one']); source.value = 'two'; }); @@ -347,23 +338,14 @@ describe('useMutableSourceHydration', () => { /> ); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactDOMClient.hydrateRoot(container, fragment, { - mutableSources: [mutableSource], - onRecoverableError(error) { - Scheduler.unstable_yieldValue('Log error: ' + error.message); - }, - }); - }); - } else { + React.startTransition(() => { ReactDOMClient.hydrateRoot(container, fragment, { mutableSources: [mutableSource], onRecoverableError(error) { Scheduler.unstable_yieldValue('Log error: ' + error.message); }, }); - } + }); expect(Scheduler).toFlushAndYieldThrough(['0:a:one']); source.valueB = 'b:two'; }); diff --git a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js index 03379563c7e59..de0fe8371431f 100644 --- a/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js +++ b/packages/react-test-renderer/src/__tests__/ReactTestRendererAsync-test.js @@ -89,17 +89,11 @@ describe('ReactTestRendererAsync', () => { } let renderer; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer = ReactTestRenderer.create(, { - unstable_isConcurrent: true, - }); - }); - } else { + React.startTransition(() => { renderer = ReactTestRenderer.create(, { unstable_isConcurrent: true, }); - } + }); // Flush the first two siblings expect(Scheduler).toFlushAndYieldThrough(['A:1', 'B:1']); @@ -135,17 +129,11 @@ describe('ReactTestRendererAsync', () => { } let renderer; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer = ReactTestRenderer.create(, { - unstable_isConcurrent: true, - }); - }); - } else { + React.startTransition(() => { renderer = ReactTestRenderer.create(, { unstable_isConcurrent: true, }); - } + }); // Flush the some of the changes, but don't commit expect(Scheduler).toFlushAndYieldThrough(['A:1']); diff --git a/packages/react/src/__tests__/ReactProfiler-test.internal.js b/packages/react/src/__tests__/ReactProfiler-test.internal.js index ba8f049a4370f..c9e124ec7790a 100644 --- a/packages/react/src/__tests__/ReactProfiler-test.internal.js +++ b/packages/react/src/__tests__/ReactProfiler-test.internal.js @@ -196,19 +196,7 @@ describe(`onRender`, () => { return null; }; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactTestRenderer.create( - - - - , - { - unstable_isConcurrent: true, - }, - ); - }); - } else { + React.startTransition(() => { ReactTestRenderer.create( @@ -218,7 +206,7 @@ describe(`onRender`, () => { unstable_isConcurrent: true, }, ); - } + }); // Times are logged until a render is committed. expect(Scheduler).toFlushAndYieldThrough(['first']); @@ -744,17 +732,7 @@ describe(`onRender`, () => { Scheduler.unstable_advanceTime(5); // 0 -> 5 // Render partially, but run out of time before completing. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactTestRenderer.create( - - - - , - {unstable_isConcurrent: true}, - ); - }); - } else { + React.startTransition(() => { ReactTestRenderer.create( @@ -762,7 +740,7 @@ describe(`onRender`, () => { , {unstable_isConcurrent: true}, ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Yield:2']); expect(callback).toHaveBeenCalledTimes(0); @@ -791,20 +769,7 @@ describe(`onRender`, () => { // Render partially, but don't finish. // This partial render should take 5ms of simulated time. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - ReactTestRenderer.create( - - - - - - - , - {unstable_isConcurrent: true}, - ); - }); - } else { + React.startTransition(() => { ReactTestRenderer.create( @@ -815,7 +780,7 @@ describe(`onRender`, () => { , {unstable_isConcurrent: true}, ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Yield:5']); expect(callback).toHaveBeenCalledTimes(0); @@ -857,17 +822,7 @@ describe(`onRender`, () => { // Render a partially update, but don't finish. // This partial render should take 10ms of simulated time. let renderer; - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer = ReactTestRenderer.create( - - - - , - {unstable_isConcurrent: true}, - ); - }); - } else { + React.startTransition(() => { renderer = ReactTestRenderer.create( @@ -875,7 +830,7 @@ describe(`onRender`, () => { , {unstable_isConcurrent: true}, ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Yield:10']); expect(callback).toHaveBeenCalledTimes(0); @@ -944,17 +899,7 @@ describe(`onRender`, () => { // Render a partially update, but don't finish. // This partial render should take 3ms of simulated time. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer.update( - - - - - , - ); - }); - } else { + React.startTransition(() => { renderer.update( @@ -962,7 +907,7 @@ describe(`onRender`, () => { , ); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Yield:3']); expect(callback).toHaveBeenCalledTimes(0); @@ -1068,13 +1013,9 @@ describe(`onRender`, () => { // Render a partially update, but don't finish. // This partial render will take 10ms of actual render time. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - first.setState({renderTime: 10}); - }); - } else { + React.startTransition(() => { first.setState({renderTime: 10}); - } + }); expect(Scheduler).toFlushAndYieldThrough(['FirstComponent:10']); expect(callback).toHaveBeenCalledTimes(0); diff --git a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js index a0fef0cb23139..faa0ade612764 100644 --- a/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js +++ b/packages/react/src/__tests__/ReactProfilerDevToolsIntegration-test.internal.js @@ -155,13 +155,9 @@ describe('ReactProfiler DevTools integration', () => { // for updates. Scheduler.unstable_advanceTime(10000); // Schedule an update. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - root.update(); - }); - } else { + React.startTransition(() => { root.update(); - } + }); // Update B should not instantly expire. expect(Scheduler).toFlushAndYieldThrough([]); diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index e6f890e9992ed..b3da065e1374d 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -135,9 +135,6 @@ export const disableLegacyContext = false; export const enableUseRefAccessWarning = false; -// Enables time slicing for updates that aren't wrapped in startTransition. -export const enableSyncDefaultUpdates = true; - export const enableUnifiedSyncLane = __EXPERIMENTAL__; // Adds an opt-in to time slicing for updates that aren't wrapped in diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index dc8a42920b8aa..7482b84e7cf96 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -67,7 +67,6 @@ export const createRootStrictEffectsByDefault = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = true; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 77dca5a86dae4..29259deed6ecc 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -58,7 +58,6 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 4fec0051cb6ff..2e0079d5eccf8 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -58,7 +58,6 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = __EXPERIMENTAL__; export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 77aaf9e979490..92f5a8ed4eda1 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -57,7 +57,6 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = true; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index 6f639b86d6594..c3ccf711f766f 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -58,7 +58,6 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = false; export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.js b/packages/shared/forks/ReactFeatureFlags.testing.js index fc6f6d8148004..ee17c5053ef86 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.js @@ -58,7 +58,6 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = __EXPERIMENTAL__; export const allowConcurrentByDefault = false; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.testing.www.js b/packages/shared/forks/ReactFeatureFlags.testing.www.js index 02aebb0b0e223..9cbb2929c1a81 100644 --- a/packages/shared/forks/ReactFeatureFlags.testing.www.js +++ b/packages/shared/forks/ReactFeatureFlags.testing.www.js @@ -58,7 +58,6 @@ export const enableUseRefAccessWarning = false; export const disableSchedulerTimeoutInWorkLoop = false; export const enableLazyContextPropagation = false; export const enableLegacyHidden = false; -export const enableSyncDefaultUpdates = true; export const enableUnifiedSyncLane = __EXPERIMENTAL__; export const allowConcurrentByDefault = true; export const enableCustomElementPropertySupport = false; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index 42e9c8a7ab2f4..c754e18430701 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -21,7 +21,6 @@ export const enableUseRefAccessWarning = __VARIANT__; export const enableProfilerNestedUpdateScheduledHook = __VARIANT__; export const disableSchedulerTimeoutInWorkLoop = __VARIANT__; export const enableLazyContextPropagation = __VARIANT__; -export const enableSyncDefaultUpdates = __VARIANT__; export const enableUnifiedSyncLane = __VARIANT__; export const enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index edbc49557aaa6..aa247e2c23b53 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -28,7 +28,6 @@ export const { disableNativeComponentFrames, disableSchedulerTimeoutInWorkLoop, enableLazyContextPropagation, - enableSyncDefaultUpdates, enableUnifiedSyncLane, enableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay, enableTransitionTracing, diff --git a/packages/use-subscription/src/__tests__/useSubscription-test.js b/packages/use-subscription/src/__tests__/useSubscription-test.js index ee89c3dbb9562..aefef75ff9fd7 100644 --- a/packages/use-subscription/src/__tests__/useSubscription-test.js +++ b/packages/use-subscription/src/__tests__/useSubscription-test.js @@ -331,13 +331,9 @@ describe('useSubscription', () => { // Start React update, but don't finish act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer.update(); - }); - } else { + React.startTransition(() => { renderer.update(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Child: b-0']); expect(log).toEqual(['Parent.componentDidMount']); @@ -439,13 +435,9 @@ describe('useSubscription', () => { // Start React update, but don't finish act(() => { - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - renderer.update(); - }); - } else { + React.startTransition(() => { renderer.update(); - } + }); expect(Scheduler).toFlushAndYieldThrough(['Child: b-0']); expect(log).toEqual([]); @@ -623,24 +615,16 @@ describe('useSubscription', () => { // Interrupt with a second mutation "C" -> "D". // This update will not be eagerly evaluated, // but useSubscription() should eagerly close over the updated value to avoid tearing. - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - mutate('C'); - }); - } else { + React.startTransition(() => { mutate('C'); - } + }); expect(Scheduler).toFlushAndYieldThrough([ 'render:first:C', 'render:second:C', ]); - if (gate(flags => flags.enableSyncDefaultUpdates)) { - React.startTransition(() => { - mutate('D'); - }); - } else { + React.startTransition(() => { mutate('D'); - } + }); expect(Scheduler).toFlushAndYield(['render:first:D', 'render:second:D']); // No more pending updates From 38509cce9b2f8b2046d2952645879e2f474ca745 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Tue, 28 Feb 2023 23:27:16 +0100 Subject: [PATCH 011/103] Add preconnect and prefetchDNS to rendering-stub (#26265) ## Summary Adding `preconnect` and `prefetchDNS` to rendering-stub build ## How did you test this change? --- packages/react-dom/server-rendering-stub.js | 2 ++ .../react-dom-server-rendering-stub-test.js | 12 ++++++++++++ .../src/server/ReactDOMServerRenderingStub.js | 7 ++++++- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/react-dom/server-rendering-stub.js b/packages/react-dom/server-rendering-stub.js index e50cb3edb3be1..6d28ee413b3cf 100644 --- a/packages/react-dom/server-rendering-stub.js +++ b/packages/react-dom/server-rendering-stub.js @@ -18,6 +18,8 @@ export {default as __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED} from './s export { createPortal, flushSync, + prefetchDNS, + preconnect, preload, preinit, } from './src/server/ReactDOMServerRenderingStub'; diff --git a/packages/react-dom/src/__tests__/react-dom-server-rendering-stub-test.js b/packages/react-dom/src/__tests__/react-dom-server-rendering-stub-test.js index 1a9aa2de636f6..d51c166bf765d 100644 --- a/packages/react-dom/src/__tests__/react-dom-server-rendering-stub-test.js +++ b/packages/react-dom/src/__tests__/react-dom-server-rendering-stub-test.js @@ -53,6 +53,18 @@ describe('react-dom-server-rendering-stub', () => { ); }); + it('provides preconnect and prefetchDNS exports', async () => { + function App() { + ReactDOM.preconnect('foo', {crossOrigin: 'use-credentials'}); + ReactDOM.prefetchDNS('bar'); + return
foo
; + } + const html = ReactDOMFizzServer.renderToString(); + expect(html).toEqual( + '
foo
', + ); + }); + it('provides a stub for createPortal', async () => { expect(() => { ReactDOM.createPortal(); diff --git a/packages/react-dom/src/server/ReactDOMServerRenderingStub.js b/packages/react-dom/src/server/ReactDOMServerRenderingStub.js index d7509f15495ac..29b3938c28a74 100644 --- a/packages/react-dom/src/server/ReactDOMServerRenderingStub.js +++ b/packages/react-dom/src/server/ReactDOMServerRenderingStub.js @@ -7,7 +7,12 @@ * @flow */ -export {preinit, preload} from 'react-dom-bindings/src/shared/ReactDOMFloat'; +export { + preinit, + preload, + preconnect, + prefetchDNS, +} from 'react-dom-bindings/src/shared/ReactDOMFloat'; export function createPortal() { throw new Error( From 40755c01a68de4b44bc24cca7f03a46140f31d5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Markb=C3=A5ge?= Date: Tue, 28 Feb 2023 19:24:16 -0500 Subject: [PATCH 012/103] [Flight Fixture] Proxy requests through the global server instead of directly (#26257) This proxies requests through the global server instead of requesting RSC responses from the regional server. This is a bit closer to idiomatic, and closer to SSR. This also wires up HMR using the Middleware technique instead of server. This will be an important part of RSC compatibility because there will be a `react-refresh` aspect to the integration. This convention uses `Accept` header to branch a URL between HTML/RSC but it could be anything really. Special headers, URLs etc. We might be more opinionated about this in the future but now it's up to the router. Some fixes for Node 16/17 support in the loader and fetch polyfill. --- fixtures/flight/config/webpack.config.js | 9 ++- fixtures/flight/package.json | 4 +- fixtures/flight/server/global.js | 79 +++++++++++++++++-- fixtures/flight/server/region.js | 15 ++-- fixtures/flight/src/index.js | 10 ++- fixtures/flight/yarn.lock | 30 ++++++- .../src/ReactFlightWebpackNodeLoader.js | 36 ++++++--- .../src/ReactFlightWebpackNodeRegister.js | 15 +++- 8 files changed, 160 insertions(+), 38 deletions(-) diff --git a/fixtures/flight/config/webpack.config.js b/fixtures/flight/config/webpack.config.js index f1579c3a7b7b0..9b4b7edb09c71 100644 --- a/fixtures/flight/config/webpack.config.js +++ b/fixtures/flight/config/webpack.config.js @@ -208,7 +208,13 @@ module.exports = function (webpackEnv) { : isEnvDevelopment && 'cheap-module-source-map', // These are the "entry points" to our application. // This means they will be the "root" imports that are included in JS bundle. - entry: paths.appIndexJs, + entry: isEnvProduction + ? [paths.appIndexJs] + : [ + paths.appIndexJs, + // HMR client + 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000', + ], output: { // The build folder. path: paths.appBuild, @@ -571,6 +577,7 @@ module.exports = function (webpackEnv) { ].filter(Boolean), }, plugins: [ + new webpack.HotModuleReplacementPlugin(), // Generates an `index.html` file with the