Best JavaScript code snippet using playwright-internal
ReactFiberThrow.old.js
Source:ReactFiberThrow.old.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import type {Fiber} from './ReactInternalTypes';10import type {FiberRoot} from './ReactInternalTypes';11import type {Lane, Lanes} from './ReactFiberLane';12import type {CapturedValue} from './ReactCapturedValue';13import type {Update} from './ReactUpdateQueue.old';14import type {Wakeable} from 'shared/ReactTypes';15import type {SuspenseContext} from './ReactFiberSuspenseContext.old';16import getComponentName from 'shared/getComponentName';17import {18 ClassComponent,19 HostRoot,20 SuspenseComponent,21 IncompleteClassComponent,22} from './ReactWorkTags';23import {24 DidCapture,25 Incomplete,26 NoFlags,27 ShouldCapture,28 LifecycleEffectMask,29 ForceUpdateForLegacySuspense,30} from './ReactFiberFlags';31import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.old';32import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';33import {34 enableDebugTracing,35 enableSchedulingProfiler,36} from 'shared/ReactFeatureFlags';37import {createCapturedValue} from './ReactCapturedValue';38import {39 enqueueCapturedUpdate,40 createUpdate,41 CaptureUpdate,42 ForceUpdate,43 enqueueUpdate,44} from './ReactUpdateQueue.old';45import {markFailedErrorBoundaryForHotReloading} from './ReactFiberHotReloading.old';46import {47 suspenseStackCursor,48 InvisibleParentSuspenseContext,49 hasSuspenseContext,50} from './ReactFiberSuspenseContext.old';51import {52 renderDidError,53 onUncaughtError,54 markLegacyErrorBoundaryAsFailed,55 isAlreadyFailedLegacyErrorBoundary,56 pingSuspendedRoot,57} from './ReactFiberWorkLoop.old';58import {logCapturedError} from './ReactFiberErrorLogger';59import {logComponentSuspended} from './DebugTracing';60import {markComponentSuspended} from './SchedulingProfiler';61import {62 SyncLane,63 NoTimestamp,64 includesSomeLane,65 mergeLanes,66 pickArbitraryLane,67} from './ReactFiberLane';68const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;69function createRootErrorUpdate(70 fiber: Fiber,71 errorInfo: CapturedValue<mixed>,72 lane: Lane,73): Update<mixed> {74 const update = createUpdate(NoTimestamp, lane);75 // Unmount the root by rendering null.76 update.tag = CaptureUpdate;77 // Caution: React DevTools currently depends on this property78 // being called "element".79 update.payload = {element: null};80 const error = errorInfo.value;81 update.callback = () => {82 onUncaughtError(error);83 logCapturedError(fiber, errorInfo);84 };85 return update;86}87function createClassErrorUpdate(88 fiber: Fiber,89 errorInfo: CapturedValue<mixed>,90 lane: Lane,91): Update<mixed> {92 const update = createUpdate(NoTimestamp, lane);93 update.tag = CaptureUpdate;94 const getDerivedStateFromError = fiber.type.getDerivedStateFromError;95 if (typeof getDerivedStateFromError === 'function') {96 const error = errorInfo.value;97 update.payload = () => {98 logCapturedError(fiber, errorInfo);99 return getDerivedStateFromError(error);100 };101 }102 const inst = fiber.stateNode;103 if (inst !== null && typeof inst.componentDidCatch === 'function') {104 update.callback = function callback() {105 if (__DEV__) {106 markFailedErrorBoundaryForHotReloading(fiber);107 }108 if (typeof getDerivedStateFromError !== 'function') {109 // To preserve the preexisting retry behavior of error boundaries,110 // we keep track of which ones already failed during this batch.111 // This gets reset before we yield back to the browser.112 // TODO: Warn in strict mode if getDerivedStateFromError is113 // not defined.114 markLegacyErrorBoundaryAsFailed(this);115 // Only log here if componentDidCatch is the only error boundary method defined116 logCapturedError(fiber, errorInfo);117 }118 const error = errorInfo.value;119 const stack = errorInfo.stack;120 this.componentDidCatch(error, {121 componentStack: stack !== null ? stack : '',122 });123 if (__DEV__) {124 if (typeof getDerivedStateFromError !== 'function') {125 // If componentDidCatch is the only error boundary method defined,126 // then it needs to call setState to recover from errors.127 // If no state update is scheduled then the boundary will swallow the error.128 if (!includesSomeLane(fiber.lanes, (SyncLane: Lane))) {129 console.error(130 '%s: Error boundaries should implement getDerivedStateFromError(). ' +131 'In that method, return a state update to display an error message or fallback UI.',132 getComponentName(fiber.type) || 'Unknown',133 );134 }135 }136 }137 };138 } else if (__DEV__) {139 update.callback = () => {140 markFailedErrorBoundaryForHotReloading(fiber);141 };142 }143 return update;144}145function attachPingListener(root: FiberRoot, wakeable: Wakeable, lanes: Lanes) {146 // Attach a listener to the promise to "ping" the root and retry. But only if147 // one does not already exist for the lanes we're currently rendering (which148 // acts like a "thread ID" here).149 let pingCache = root.pingCache;150 let threadIDs;151 if (pingCache === null) {152 pingCache = root.pingCache = new PossiblyWeakMap();153 threadIDs = new Set();154 pingCache.set(wakeable, threadIDs);155 } else {156 threadIDs = pingCache.get(wakeable);157 if (threadIDs === undefined) {158 threadIDs = new Set();159 pingCache.set(wakeable, threadIDs);160 }161 }162 if (!threadIDs.has(lanes)) {163 // Memoize using the thread ID to prevent redundant listeners.164 threadIDs.add(lanes);165 const ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);166 wakeable.then(ping, ping);167 }168}169function throwException(170 root: FiberRoot,171 returnFiber: Fiber,172 sourceFiber: Fiber,173 value: mixed,174 rootRenderLanes: Lanes,175) {176 // The source fiber did not complete.177 sourceFiber.flags |= Incomplete;178 // Its effect list is no longer valid.179 sourceFiber.firstEffect = sourceFiber.lastEffect = null;180 if (181 value !== null &&182 typeof value === 'object' &&183 typeof value.then === 'function'184 ) {185 // This is a wakeable.186 const wakeable: Wakeable = (value: any);187 if (__DEV__) {188 if (enableDebugTracing) {189 if (sourceFiber.mode & DebugTracingMode) {190 const name = getComponentName(sourceFiber.type) || 'Unknown';191 logComponentSuspended(name, wakeable);192 }193 }194 }195 if (enableSchedulingProfiler) {196 markComponentSuspended(sourceFiber, wakeable);197 }198 if ((sourceFiber.mode & BlockingMode) === NoMode) {199 // Reset the memoizedState to what it was before we attempted200 // to render it.201 const currentSource = sourceFiber.alternate;202 if (currentSource) {203 sourceFiber.updateQueue = currentSource.updateQueue;204 sourceFiber.memoizedState = currentSource.memoizedState;205 sourceFiber.lanes = currentSource.lanes;206 } else {207 sourceFiber.updateQueue = null;208 sourceFiber.memoizedState = null;209 }210 }211 const hasInvisibleParentBoundary = hasSuspenseContext(212 suspenseStackCursor.current,213 (InvisibleParentSuspenseContext: SuspenseContext),214 );215 // Schedule the nearest Suspense to re-render the timed out view.216 let workInProgress = returnFiber;217 do {218 if (219 workInProgress.tag === SuspenseComponent &&220 shouldCaptureSuspense(workInProgress, hasInvisibleParentBoundary)221 ) {222 // Found the nearest boundary.223 // Stash the promise on the boundary fiber. If the boundary times out, we'll224 // attach another listener to flip the boundary back to its normal state.225 const wakeables: Set<Wakeable> = (workInProgress.updateQueue: any);226 if (wakeables === null) {227 const updateQueue = (new Set(): any);228 updateQueue.add(wakeable);229 workInProgress.updateQueue = updateQueue;230 } else {231 wakeables.add(wakeable);232 }233 // If the boundary is outside of blocking mode, we should *not*234 // suspend the commit. Pretend as if the suspended component rendered235 // null and keep rendering. In the commit phase, we'll schedule a236 // subsequent synchronous update to re-render the Suspense.237 //238 // Note: It doesn't matter whether the component that suspended was239 // inside a blocking mode tree. If the Suspense is outside of it, we240 // should *not* suspend the commit.241 if ((workInProgress.mode & BlockingMode) === NoMode) {242 workInProgress.flags |= DidCapture;243 sourceFiber.flags |= ForceUpdateForLegacySuspense;244 // We're going to commit this fiber even though it didn't complete.245 // But we shouldn't call any lifecycle methods or callbacks. Remove246 // all lifecycle effect tags.247 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);248 if (sourceFiber.tag === ClassComponent) {249 const currentSourceFiber = sourceFiber.alternate;250 if (currentSourceFiber === null) {251 // This is a new mount. Change the tag so it's not mistaken for a252 // completed class component. For example, we should not call253 // componentWillUnmount if it is deleted.254 sourceFiber.tag = IncompleteClassComponent;255 } else {256 // When we try rendering again, we should not reuse the current fiber,257 // since it's known to be in an inconsistent state. Use a force update to258 // prevent a bail out.259 const update = createUpdate(NoTimestamp, SyncLane);260 update.tag = ForceUpdate;261 enqueueUpdate(sourceFiber, update);262 }263 }264 // The source fiber did not complete. Mark it with Sync priority to265 // indicate that it still has pending work.266 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);267 // Exit without suspending.268 return;269 }270 // Confirmed that the boundary is in a concurrent mode tree. Continue271 // with the normal suspend path.272 //273 // After this we'll use a set of heuristics to determine whether this274 // render pass will run to completion or restart or "suspend" the commit.275 // The actual logic for this is spread out in different places.276 //277 // This first principle is that if we're going to suspend when we complete278 // a root, then we should also restart if we get an update or ping that279 // might unsuspend it, and vice versa. The only reason to suspend is280 // because you think you might want to restart before committing. However,281 // it doesn't make sense to restart only while in the period we're suspended.282 //283 // Restarting too aggressively is also not good because it starves out any284 // intermediate loading state. So we use heuristics to determine when.285 // Suspense Heuristics286 //287 // If nothing threw a Promise or all the same fallbacks are already showing,288 // then don't suspend/restart.289 //290 // If this is an initial render of a new tree of Suspense boundaries and291 // those trigger a fallback, then don't suspend/restart. We want to ensure292 // that we can show the initial loading state as quickly as possible.293 //294 // If we hit a "Delayed" case, such as when we'd switch from content back into295 // a fallback, then we should always suspend/restart. Transitions apply296 // to this case. If none is defined, JND is used instead.297 //298 // If we're already showing a fallback and it gets "retried", allowing us to show299 // another level, but there's still an inner boundary that would show a fallback,300 // then we suspend/restart for 500ms since the last time we showed a fallback301 // anywhere in the tree. This effectively throttles progressive loading into a302 // consistent train of commits. This also gives us an opportunity to restart to303 // get to the completed state slightly earlier.304 //305 // If there's ambiguity due to batching it's resolved in preference of:306 // 1) "delayed", 2) "initial render", 3) "retry".307 //308 // We want to ensure that a "busy" state doesn't get force committed. We want to309 // ensure that new initial loading states can commit as soon as possible.310 attachPingListener(root, wakeable, rootRenderLanes);311 workInProgress.flags |= ShouldCapture;312 workInProgress.lanes = rootRenderLanes;313 return;314 }315 // This boundary already captured during this render. Continue to the next316 // boundary.317 workInProgress = workInProgress.return;318 } while (workInProgress !== null);319 // No boundary was found. Fallthrough to error mode.320 // TODO: Use invariant so the message is stripped in prod?321 value = new Error(322 (getComponentName(sourceFiber.type) || 'A React component') +323 ' suspended while rendering, but no fallback UI was specified.\n' +324 '\n' +325 'Add a <Suspense fallback=...> component higher in the tree to ' +326 'provide a loading indicator or placeholder to display.',327 );328 }329 // We didn't find a boundary that could handle this type of exception. Start330 // over and traverse parent path again, this time treating the exception331 // as an error.332 renderDidError();333 value = createCapturedValue(value, sourceFiber);334 let workInProgress = returnFiber;335 do {336 switch (workInProgress.tag) {337 case HostRoot: {338 const errorInfo = value;339 workInProgress.flags |= ShouldCapture;340 const lane = pickArbitraryLane(rootRenderLanes);341 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);342 const update = createRootErrorUpdate(workInProgress, errorInfo, lane);343 enqueueCapturedUpdate(workInProgress, update);344 return;345 }346 case ClassComponent:347 // Capture and retry348 const errorInfo = value;349 const ctor = workInProgress.type;350 const instance = workInProgress.stateNode;351 if (352 (workInProgress.flags & DidCapture) === NoFlags &&353 (typeof ctor.getDerivedStateFromError === 'function' ||354 (instance !== null &&355 typeof instance.componentDidCatch === 'function' &&356 !isAlreadyFailedLegacyErrorBoundary(instance)))357 ) {358 workInProgress.flags |= ShouldCapture;359 const lane = pickArbitraryLane(rootRenderLanes);360 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);361 // Schedule the error boundary to re-render using updated state362 const update = createClassErrorUpdate(363 workInProgress,364 errorInfo,365 lane,366 );367 enqueueCapturedUpdate(workInProgress, update);368 return;369 }370 break;371 default:372 break;373 }374 workInProgress = workInProgress.return;375 } while (workInProgress !== null);376}...
ReactFiberThrow.new.js
Source:ReactFiberThrow.new.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import type {Fiber} from './ReactInternalTypes';10import type {FiberRoot} from './ReactInternalTypes';11import type {Lane, Lanes} from './ReactFiberLane';12import type {CapturedValue} from './ReactCapturedValue';13import type {Update} from './ReactUpdateQueue.new';14import type {Wakeable} from 'shared/ReactTypes';15import type {SuspenseContext} from './ReactFiberSuspenseContext.new';16import getComponentName from 'shared/getComponentName';17import {18 ClassComponent,19 HostRoot,20 SuspenseComponent,21 IncompleteClassComponent,22} from './ReactWorkTags';23import {24 DidCapture,25 Incomplete,26 NoFlags,27 ShouldCapture,28 LifecycleEffectMask,29 ForceUpdateForLegacySuspense,30} from './ReactFiberFlags';31import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent.new';32import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';33import {34 enableDebugTracing,35 enableSchedulingProfiler,36} from 'shared/ReactFeatureFlags';37import {createCapturedValue} from './ReactCapturedValue';38import {39 enqueueCapturedUpdate,40 createUpdate,41 CaptureUpdate,42 ForceUpdate,43 enqueueUpdate,44} from './ReactUpdateQueue.new';45import {markFailedErrorBoundaryForHotReloading} from './ReactFiberHotReloading.new';46import {47 suspenseStackCursor,48 InvisibleParentSuspenseContext,49 hasSuspenseContext,50} from './ReactFiberSuspenseContext.new';51import {52 renderDidError,53 onUncaughtError,54 markLegacyErrorBoundaryAsFailed,55 isAlreadyFailedLegacyErrorBoundary,56 pingSuspendedRoot,57} from './ReactFiberWorkLoop.new';58import {logCapturedError} from './ReactFiberErrorLogger';59import {logComponentSuspended} from './DebugTracing';60import {markComponentSuspended} from './SchedulingProfiler';61import {62 SyncLane,63 NoTimestamp,64 includesSomeLane,65 mergeLanes,66 pickArbitraryLane,67} from './ReactFiberLane';68const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;69function createRootErrorUpdate(70 fiber: Fiber,71 errorInfo: CapturedValue<mixed>,72 lane: Lane,73): Update<mixed> {74 const update = createUpdate(NoTimestamp, lane);75 // Unmount the root by rendering null.76 update.tag = CaptureUpdate;77 // Caution: React DevTools currently depends on this property78 // being called "element".79 update.payload = {element: null};80 const error = errorInfo.value;81 update.callback = () => {82 onUncaughtError(error);83 logCapturedError(fiber, errorInfo);84 };85 return update;86}87function createClassErrorUpdate(88 fiber: Fiber,89 errorInfo: CapturedValue<mixed>,90 lane: Lane,91): Update<mixed> {92 const update = createUpdate(NoTimestamp, lane);93 update.tag = CaptureUpdate;94 const getDerivedStateFromError = fiber.type.getDerivedStateFromError;95 if (typeof getDerivedStateFromError === 'function') {96 const error = errorInfo.value;97 update.payload = () => {98 logCapturedError(fiber, errorInfo);99 return getDerivedStateFromError(error);100 };101 }102 const inst = fiber.stateNode;103 if (inst !== null && typeof inst.componentDidCatch === 'function') {104 update.callback = function callback() {105 if (__DEV__) {106 markFailedErrorBoundaryForHotReloading(fiber);107 }108 if (typeof getDerivedStateFromError !== 'function') {109 // To preserve the preexisting retry behavior of error boundaries,110 // we keep track of which ones already failed during this batch.111 // This gets reset before we yield back to the browser.112 // TODO: Warn in strict mode if getDerivedStateFromError is113 // not defined.114 markLegacyErrorBoundaryAsFailed(this);115 // Only log here if componentDidCatch is the only error boundary method defined116 logCapturedError(fiber, errorInfo);117 }118 const error = errorInfo.value;119 const stack = errorInfo.stack;120 this.componentDidCatch(error, {121 componentStack: stack !== null ? stack : '',122 });123 if (__DEV__) {124 if (typeof getDerivedStateFromError !== 'function') {125 // If componentDidCatch is the only error boundary method defined,126 // then it needs to call setState to recover from errors.127 // If no state update is scheduled then the boundary will swallow the error.128 if (!includesSomeLane(fiber.lanes, (SyncLane: Lane))) {129 console.error(130 '%s: Error boundaries should implement getDerivedStateFromError(). ' +131 'In that method, return a state update to display an error message or fallback UI.',132 getComponentName(fiber.type) || 'Unknown',133 );134 }135 }136 }137 };138 } else if (__DEV__) {139 update.callback = () => {140 markFailedErrorBoundaryForHotReloading(fiber);141 };142 }143 return update;144}145function attachPingListener(root: FiberRoot, wakeable: Wakeable, lanes: Lanes) {146 // Attach a listener to the promise to "ping" the root and retry. But only if147 // one does not already exist for the lanes we're currently rendering (which148 // acts like a "thread ID" here).149 let pingCache = root.pingCache;150 let threadIDs;151 if (pingCache === null) {152 pingCache = root.pingCache = new PossiblyWeakMap();153 threadIDs = new Set();154 pingCache.set(wakeable, threadIDs);155 } else {156 threadIDs = pingCache.get(wakeable);157 if (threadIDs === undefined) {158 threadIDs = new Set();159 pingCache.set(wakeable, threadIDs);160 }161 }162 if (!threadIDs.has(lanes)) {163 // Memoize using the thread ID to prevent redundant listeners.164 threadIDs.add(lanes);165 const ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);166 wakeable.then(ping, ping);167 }168}169function throwException(170 root: FiberRoot,171 returnFiber: Fiber,172 sourceFiber: Fiber,173 value: mixed,174 rootRenderLanes: Lanes,175) {176 // The source fiber did not complete.177 sourceFiber.flags |= Incomplete;178 if (179 value !== null &&180 typeof value === 'object' &&181 typeof value.then === 'function'182 ) {183 // This is a wakeable.184 const wakeable: Wakeable = (value: any);185 if (__DEV__) {186 if (enableDebugTracing) {187 if (sourceFiber.mode & DebugTracingMode) {188 const name = getComponentName(sourceFiber.type) || 'Unknown';189 logComponentSuspended(name, wakeable);190 }191 }192 }193 if (enableSchedulingProfiler) {194 markComponentSuspended(sourceFiber, wakeable);195 }196 if ((sourceFiber.mode & BlockingMode) === NoMode) {197 // Reset the memoizedState to what it was before we attempted198 // to render it.199 const currentSource = sourceFiber.alternate;200 if (currentSource) {201 sourceFiber.updateQueue = currentSource.updateQueue;202 sourceFiber.memoizedState = currentSource.memoizedState;203 sourceFiber.lanes = currentSource.lanes;204 } else {205 sourceFiber.updateQueue = null;206 sourceFiber.memoizedState = null;207 }208 }209 const hasInvisibleParentBoundary = hasSuspenseContext(210 suspenseStackCursor.current,211 (InvisibleParentSuspenseContext: SuspenseContext),212 );213 // Schedule the nearest Suspense to re-render the timed out view.214 let workInProgress = returnFiber;215 do {216 if (217 workInProgress.tag === SuspenseComponent &&218 shouldCaptureSuspense(workInProgress, hasInvisibleParentBoundary)219 ) {220 // Found the nearest boundary.221 // Stash the promise on the boundary fiber. If the boundary times out, we'll222 // attach another listener to flip the boundary back to its normal state.223 const wakeables: Set<Wakeable> = (workInProgress.updateQueue: any);224 if (wakeables === null) {225 const updateQueue = (new Set(): any);226 updateQueue.add(wakeable);227 workInProgress.updateQueue = updateQueue;228 } else {229 wakeables.add(wakeable);230 }231 // If the boundary is outside of blocking mode, we should *not*232 // suspend the commit. Pretend as if the suspended component rendered233 // null and keep rendering. In the commit phase, we'll schedule a234 // subsequent synchronous update to re-render the Suspense.235 //236 // Note: It doesn't matter whether the component that suspended was237 // inside a blocking mode tree. If the Suspense is outside of it, we238 // should *not* suspend the commit.239 if ((workInProgress.mode & BlockingMode) === NoMode) {240 workInProgress.flags |= DidCapture;241 sourceFiber.flags |= ForceUpdateForLegacySuspense;242 // We're going to commit this fiber even though it didn't complete.243 // But we shouldn't call any lifecycle methods or callbacks. Remove244 // all lifecycle effect tags.245 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);246 if (sourceFiber.tag === ClassComponent) {247 const currentSourceFiber = sourceFiber.alternate;248 if (currentSourceFiber === null) {249 // This is a new mount. Change the tag so it's not mistaken for a250 // completed class component. For example, we should not call251 // componentWillUnmount if it is deleted.252 sourceFiber.tag = IncompleteClassComponent;253 } else {254 // When we try rendering again, we should not reuse the current fiber,255 // since it's known to be in an inconsistent state. Use a force update to256 // prevent a bail out.257 const update = createUpdate(NoTimestamp, SyncLane);258 update.tag = ForceUpdate;259 enqueueUpdate(sourceFiber, update);260 }261 }262 // The source fiber did not complete. Mark it with Sync priority to263 // indicate that it still has pending work.264 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);265 // Exit without suspending.266 return;267 }268 // Confirmed that the boundary is in a concurrent mode tree. Continue269 // with the normal suspend path.270 //271 // After this we'll use a set of heuristics to determine whether this272 // render pass will run to completion or restart or "suspend" the commit.273 // The actual logic for this is spread out in different places.274 //275 // This first principle is that if we're going to suspend when we complete276 // a root, then we should also restart if we get an update or ping that277 // might unsuspend it, and vice versa. The only reason to suspend is278 // because you think you might want to restart before committing. However,279 // it doesn't make sense to restart only while in the period we're suspended.280 //281 // Restarting too aggressively is also not good because it starves out any282 // intermediate loading state. So we use heuristics to determine when.283 // Suspense Heuristics284 //285 // If nothing threw a Promise or all the same fallbacks are already showing,286 // then don't suspend/restart.287 //288 // If this is an initial render of a new tree of Suspense boundaries and289 // those trigger a fallback, then don't suspend/restart. We want to ensure290 // that we can show the initial loading state as quickly as possible.291 //292 // If we hit a "Delayed" case, such as when we'd switch from content back into293 // a fallback, then we should always suspend/restart. Transitions apply294 // to this case. If none is defined, JND is used instead.295 //296 // If we're already showing a fallback and it gets "retried", allowing us to show297 // another level, but there's still an inner boundary that would show a fallback,298 // then we suspend/restart for 500ms since the last time we showed a fallback299 // anywhere in the tree. This effectively throttles progressive loading into a300 // consistent train of commits. This also gives us an opportunity to restart to301 // get to the completed state slightly earlier.302 //303 // If there's ambiguity due to batching it's resolved in preference of:304 // 1) "delayed", 2) "initial render", 3) "retry".305 //306 // We want to ensure that a "busy" state doesn't get force committed. We want to307 // ensure that new initial loading states can commit as soon as possible.308 attachPingListener(root, wakeable, rootRenderLanes);309 workInProgress.flags |= ShouldCapture;310 workInProgress.lanes = rootRenderLanes;311 return;312 }313 // This boundary already captured during this render. Continue to the next314 // boundary.315 workInProgress = workInProgress.return;316 } while (workInProgress !== null);317 // No boundary was found. Fallthrough to error mode.318 // TODO: Use invariant so the message is stripped in prod?319 value = new Error(320 (getComponentName(sourceFiber.type) || 'A React component') +321 ' suspended while rendering, but no fallback UI was specified.\n' +322 '\n' +323 'Add a <Suspense fallback=...> component higher in the tree to ' +324 'provide a loading indicator or placeholder to display.',325 );326 }327 // We didn't find a boundary that could handle this type of exception. Start328 // over and traverse parent path again, this time treating the exception329 // as an error.330 renderDidError();331 value = createCapturedValue(value, sourceFiber);332 let workInProgress = returnFiber;333 do {334 switch (workInProgress.tag) {335 case HostRoot: {336 const errorInfo = value;337 workInProgress.flags |= ShouldCapture;338 const lane = pickArbitraryLane(rootRenderLanes);339 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);340 const update = createRootErrorUpdate(workInProgress, errorInfo, lane);341 enqueueCapturedUpdate(workInProgress, update);342 return;343 }344 case ClassComponent:345 // Capture and retry346 const errorInfo = value;347 const ctor = workInProgress.type;348 const instance = workInProgress.stateNode;349 if (350 (workInProgress.flags & DidCapture) === NoFlags &&351 (typeof ctor.getDerivedStateFromError === 'function' ||352 (instance !== null &&353 typeof instance.componentDidCatch === 'function' &&354 !isAlreadyFailedLegacyErrorBoundary(instance)))355 ) {356 workInProgress.flags |= ShouldCapture;357 const lane = pickArbitraryLane(rootRenderLanes);358 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);359 // Schedule the error boundary to re-render using updated state360 const update = createClassErrorUpdate(361 workInProgress,362 errorInfo,363 lane,364 );365 enqueueCapturedUpdate(workInProgress, update);366 return;367 }368 break;369 default:370 break;371 }372 workInProgress = workInProgress.return;373 } while (workInProgress !== null);374}...
ReactFiberThrow.js
Source:ReactFiberThrow.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import type {Fiber} from './ReactFiber';10import type {FiberRoot} from './ReactFiberRoot';11import type {ExpirationTime} from './ReactFiberExpirationTime';12import type {CapturedValue} from './ReactCapturedValue';13import type {Update} from './ReactUpdateQueue';14import type {Thenable} from './ReactFiberWorkLoop';15import type {SuspenseContext} from './ReactFiberSuspenseContext';16import getComponentName from 'shared/getComponentName';17import {18 ClassComponent,19 HostRoot,20 SuspenseComponent,21 IncompleteClassComponent,22} from 'shared/ReactWorkTags';23import {24 DidCapture,25 Incomplete,26 NoEffect,27 ShouldCapture,28 LifecycleEffectMask,29} from 'shared/ReactSideEffectTags';30import {NoMode, BlockingMode} from './ReactTypeOfMode';31import {shouldCaptureSuspense} from './ReactFiberSuspenseComponent';32import {createCapturedValue} from './ReactCapturedValue';33import {34 enqueueCapturedUpdate,35 createUpdate,36 CaptureUpdate,37 ForceUpdate,38 enqueueUpdate,39} from './ReactUpdateQueue';40import {logError} from './ReactFiberCommitWork';41import {getStackByFiberInDevAndProd} from './ReactCurrentFiber';42import {markFailedErrorBoundaryForHotReloading} from './ReactFiberHotReloading';43import {44 suspenseStackCursor,45 InvisibleParentSuspenseContext,46 hasSuspenseContext,47} from './ReactFiberSuspenseContext';48import {49 renderDidError,50 onUncaughtError,51 markLegacyErrorBoundaryAsFailed,52 isAlreadyFailedLegacyErrorBoundary,53 pingSuspendedRoot,54 checkForWrongSuspensePriorityInDEV,55} from './ReactFiberWorkLoop';56import {Sync} from './ReactFiberExpirationTime';57const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;58function createRootErrorUpdate(59 fiber: Fiber,60 errorInfo: CapturedValue<mixed>,61 expirationTime: ExpirationTime,62): Update<mixed> {63 const update = createUpdate(expirationTime, null);64 // Unmount the root by rendering null.65 update.tag = CaptureUpdate;66 // Caution: React DevTools currently depends on this property67 // being called "element".68 update.payload = {element: null};69 const error = errorInfo.value;70 update.callback = () => {71 onUncaughtError(error);72 logError(fiber, errorInfo);73 };74 return update;75}76function createClassErrorUpdate(77 fiber: Fiber,78 errorInfo: CapturedValue<mixed>,79 expirationTime: ExpirationTime,80): Update<mixed> {81 const update = createUpdate(expirationTime, null);82 update.tag = CaptureUpdate;83 const getDerivedStateFromError = fiber.type.getDerivedStateFromError;84 if (typeof getDerivedStateFromError === 'function') {85 const error = errorInfo.value;86 update.payload = () => {87 logError(fiber, errorInfo);88 return getDerivedStateFromError(error);89 };90 }91 const inst = fiber.stateNode;92 if (inst !== null && typeof inst.componentDidCatch === 'function') {93 update.callback = function callback() {94 if (__DEV__) {95 markFailedErrorBoundaryForHotReloading(fiber);96 }97 if (typeof getDerivedStateFromError !== 'function') {98 // To preserve the preexisting retry behavior of error boundaries,99 // we keep track of which ones already failed during this batch.100 // This gets reset before we yield back to the browser.101 // TODO: Warn in strict mode if getDerivedStateFromError is102 // not defined.103 markLegacyErrorBoundaryAsFailed(this);104 // Only log here if componentDidCatch is the only error boundary method defined105 logError(fiber, errorInfo);106 }107 const error = errorInfo.value;108 const stack = errorInfo.stack;109 this.componentDidCatch(error, {110 componentStack: stack !== null ? stack : '',111 });112 if (__DEV__) {113 if (typeof getDerivedStateFromError !== 'function') {114 // If componentDidCatch is the only error boundary method defined,115 // then it needs to call setState to recover from errors.116 // If no state update is scheduled then the boundary will swallow the error.117 if (fiber.expirationTime !== Sync) {118 console.error(119 '%s: Error boundaries should implement getDerivedStateFromError(). ' +120 'In that method, return a state update to display an error message or fallback UI.',121 getComponentName(fiber.type) || 'Unknown',122 );123 }124 }125 }126 };127 } else if (__DEV__) {128 update.callback = () => {129 markFailedErrorBoundaryForHotReloading(fiber);130 };131 }132 return update;133}134function attachPingListener(135 root: FiberRoot,136 renderExpirationTime: ExpirationTime,137 thenable: Thenable,138) {139 // Attach a listener to the promise to "ping" the root and retry. But140 // only if one does not already exist for the current render expiration141 // time (which acts like a "thread ID" here).142 let pingCache = root.pingCache;143 let threadIDs;144 if (pingCache === null) {145 pingCache = root.pingCache = new PossiblyWeakMap();146 threadIDs = new Set();147 pingCache.set(thenable, threadIDs);148 } else {149 threadIDs = pingCache.get(thenable);150 if (threadIDs === undefined) {151 threadIDs = new Set();152 pingCache.set(thenable, threadIDs);153 }154 }155 if (!threadIDs.has(renderExpirationTime)) {156 // Memoize using the thread ID to prevent redundant listeners.157 threadIDs.add(renderExpirationTime);158 let ping = pingSuspendedRoot.bind(159 null,160 root,161 thenable,162 renderExpirationTime,163 );164 thenable.then(ping, ping);165 }166}167function throwException(168 root: FiberRoot,169 returnFiber: Fiber,170 sourceFiber: Fiber,171 value: mixed,172 renderExpirationTime: ExpirationTime,173) {174 // The source fiber did not complete.175 sourceFiber.effectTag |= Incomplete;176 // Its effect list is no longer valid.177 sourceFiber.firstEffect = sourceFiber.lastEffect = null;178 if (179 value !== null &&180 typeof value === 'object' &&181 typeof value.then === 'function'182 ) {183 // This is a thenable.184 const thenable: Thenable = (value: any);185 if ((sourceFiber.mode & BlockingMode) === NoMode) {186 // Reset the memoizedState to what it was before we attempted187 // to render it.188 let currentSource = sourceFiber.alternate;189 if (currentSource) {190 sourceFiber.memoizedState = currentSource.memoizedState;191 sourceFiber.expirationTime = currentSource.expirationTime;192 } else {193 sourceFiber.memoizedState = null;194 }195 }196 checkForWrongSuspensePriorityInDEV(sourceFiber);197 let hasInvisibleParentBoundary = hasSuspenseContext(198 suspenseStackCursor.current,199 (InvisibleParentSuspenseContext: SuspenseContext),200 );201 // Schedule the nearest Suspense to re-render the timed out view.202 let workInProgress = returnFiber;203 do {204 if (205 workInProgress.tag === SuspenseComponent &&206 shouldCaptureSuspense(workInProgress, hasInvisibleParentBoundary)207 ) {208 // Found the nearest boundary.209 // Stash the promise on the boundary fiber. If the boundary times out, we'll210 // attach another listener to flip the boundary back to its normal state.211 const thenables: Set<Thenable> = (workInProgress.updateQueue: any);212 if (thenables === null) {213 const updateQueue = (new Set(): any);214 updateQueue.add(thenable);215 workInProgress.updateQueue = updateQueue;216 } else {217 thenables.add(thenable);218 }219 // If the boundary is outside of blocking mode, we should *not*220 // suspend the commit. Pretend as if the suspended component rendered221 // null and keep rendering. In the commit phase, we'll schedule a222 // subsequent synchronous update to re-render the Suspense.223 //224 // Note: It doesn't matter whether the component that suspended was225 // inside a blocking mode tree. If the Suspense is outside of it, we226 // should *not* suspend the commit.227 if ((workInProgress.mode & BlockingMode) === NoMode) {228 workInProgress.effectTag |= DidCapture;229 // We're going to commit this fiber even though it didn't complete.230 // But we shouldn't call any lifecycle methods or callbacks. Remove231 // all lifecycle effect tags.232 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);233 if (sourceFiber.tag === ClassComponent) {234 const currentSourceFiber = sourceFiber.alternate;235 if (currentSourceFiber === null) {236 // This is a new mount. Change the tag so it's not mistaken for a237 // completed class component. For example, we should not call238 // componentWillUnmount if it is deleted.239 sourceFiber.tag = IncompleteClassComponent;240 } else {241 // When we try rendering again, we should not reuse the current fiber,242 // since it's known to be in an inconsistent state. Use a force update to243 // prevent a bail out.244 const update = createUpdate(Sync, null);245 update.tag = ForceUpdate;246 enqueueUpdate(sourceFiber, update);247 }248 }249 // The source fiber did not complete. Mark it with Sync priority to250 // indicate that it still has pending work.251 sourceFiber.expirationTime = Sync;252 // Exit without suspending.253 return;254 }255 // Confirmed that the boundary is in a concurrent mode tree. Continue256 // with the normal suspend path.257 //258 // After this we'll use a set of heuristics to determine whether this259 // render pass will run to completion or restart or "suspend" the commit.260 // The actual logic for this is spread out in different places.261 //262 // This first principle is that if we're going to suspend when we complete263 // a root, then we should also restart if we get an update or ping that264 // might unsuspend it, and vice versa. The only reason to suspend is265 // because you think you might want to restart before committing. However,266 // it doesn't make sense to restart only while in the period we're suspended.267 //268 // Restarting too aggressively is also not good because it starves out any269 // intermediate loading state. So we use heuristics to determine when.270 // Suspense Heuristics271 //272 // If nothing threw a Promise or all the same fallbacks are already showing,273 // then don't suspend/restart.274 //275 // If this is an initial render of a new tree of Suspense boundaries and276 // those trigger a fallback, then don't suspend/restart. We want to ensure277 // that we can show the initial loading state as quickly as possible.278 //279 // If we hit a "Delayed" case, such as when we'd switch from content back into280 // a fallback, then we should always suspend/restart. SuspenseConfig applies to281 // this case. If none is defined, JND is used instead.282 //283 // If we're already showing a fallback and it gets "retried", allowing us to show284 // another level, but there's still an inner boundary that would show a fallback,285 // then we suspend/restart for 500ms since the last time we showed a fallback286 // anywhere in the tree. This effectively throttles progressive loading into a287 // consistent train of commits. This also gives us an opportunity to restart to288 // get to the completed state slightly earlier.289 //290 // If there's ambiguity due to batching it's resolved in preference of:291 // 1) "delayed", 2) "initial render", 3) "retry".292 //293 // We want to ensure that a "busy" state doesn't get force committed. We want to294 // ensure that new initial loading states can commit as soon as possible.295 attachPingListener(root, renderExpirationTime, thenable);296 workInProgress.effectTag |= ShouldCapture;297 workInProgress.expirationTime = renderExpirationTime;298 return;299 }300 // This boundary already captured during this render. Continue to the next301 // boundary.302 workInProgress = workInProgress.return;303 } while (workInProgress !== null);304 // No boundary was found. Fallthrough to error mode.305 // TODO: Use invariant so the message is stripped in prod?306 value = new Error(307 (getComponentName(sourceFiber.type) || 'A React component') +308 ' suspended while rendering, but no fallback UI was specified.\n' +309 '\n' +310 'Add a <Suspense fallback=...> component higher in the tree to ' +311 'provide a loading indicator or placeholder to display.' +312 getStackByFiberInDevAndProd(sourceFiber),313 );314 }315 // We didn't find a boundary that could handle this type of exception. Start316 // over and traverse parent path again, this time treating the exception317 // as an error.318 renderDidError();319 value = createCapturedValue(value, sourceFiber);320 let workInProgress = returnFiber;321 do {322 switch (workInProgress.tag) {323 case HostRoot: {324 const errorInfo = value;325 workInProgress.effectTag |= ShouldCapture;326 workInProgress.expirationTime = renderExpirationTime;327 const update = createRootErrorUpdate(328 workInProgress,329 errorInfo,330 renderExpirationTime,331 );332 enqueueCapturedUpdate(workInProgress, update);333 return;334 }335 case ClassComponent:336 // Capture and retry337 const errorInfo = value;338 const ctor = workInProgress.type;339 const instance = workInProgress.stateNode;340 if (341 (workInProgress.effectTag & DidCapture) === NoEffect &&342 (typeof ctor.getDerivedStateFromError === 'function' ||343 (instance !== null &&344 typeof instance.componentDidCatch === 'function' &&345 !isAlreadyFailedLegacyErrorBoundary(instance)))346 ) {347 workInProgress.effectTag |= ShouldCapture;348 workInProgress.expirationTime = renderExpirationTime;349 // Schedule the error boundary to re-render using updated state350 const update = createClassErrorUpdate(351 workInProgress,352 errorInfo,353 renderExpirationTime,354 );355 enqueueCapturedUpdate(workInProgress, update);356 return;357 }358 break;359 default:360 break;361 }362 workInProgress = workInProgress.return;363 } while (workInProgress !== null);364}...
ReactFiberScheduler.js
Source:ReactFiberScheduler.js
1/**2 * Copyright (c) Facebook, Inc. and its affiliates.3 *4 * This source code is licensed under the MIT license found in the5 * LICENSE file in the root directory of this source tree.6 *7 * @flow8 */9import {enableNewScheduler} from 'shared/ReactFeatureFlags';10import {11 requestCurrentTime as requestCurrentTime_old,12 computeExpirationForFiber as computeExpirationForFiber_old,13 captureCommitPhaseError as captureCommitPhaseError_old,14 onUncaughtError as onUncaughtError_old,15 renderDidSuspend as renderDidSuspend_old,16 renderDidError as renderDidError_old,17 pingSuspendedRoot as pingSuspendedRoot_old,18 retryTimedOutBoundary as retryTimedOutBoundary_old,19 resolveRetryThenable as resolveRetryThenable_old,20 markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_old,21 isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_old,22 scheduleWork as scheduleWork_old,23 flushRoot as flushRoot_old,24 batchedUpdates as batchedUpdates_old,25 unbatchedUpdates as unbatchedUpdates_old,26 flushSync as flushSync_old,27 flushControlled as flushControlled_old,28 deferredUpdates as deferredUpdates_old,29 syncUpdates as syncUpdates_old,30 interactiveUpdates as interactiveUpdates_old,31 flushInteractiveUpdates as flushInteractiveUpdates_old,32 computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_old,33 flushPassiveEffects as flushPassiveEffects_old,34 warnIfNotCurrentlyActingUpdatesInDev as warnIfNotCurrentlyActingUpdatesInDev_old,35 inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_old,36} from './ReactFiberScheduler.old';37import {38 requestCurrentTime as requestCurrentTime_new,39 computeExpirationForFiber as computeExpirationForFiber_new,40 captureCommitPhaseError as captureCommitPhaseError_new,41 onUncaughtError as onUncaughtError_new,42 renderDidSuspend as renderDidSuspend_new,43 renderDidError as renderDidError_new,44 pingSuspendedRoot as pingSuspendedRoot_new,45 retryTimedOutBoundary as retryTimedOutBoundary_new,46 resolveRetryThenable as resolveRetryThenable_new,47 markLegacyErrorBoundaryAsFailed as markLegacyErrorBoundaryAsFailed_new,48 isAlreadyFailedLegacyErrorBoundary as isAlreadyFailedLegacyErrorBoundary_new,49 scheduleWork as scheduleWork_new,50 flushRoot as flushRoot_new,51 batchedUpdates as batchedUpdates_new,52 unbatchedUpdates as unbatchedUpdates_new,53 flushSync as flushSync_new,54 flushControlled as flushControlled_new,55 deferredUpdates as deferredUpdates_new,56 syncUpdates as syncUpdates_new,57 interactiveUpdates as interactiveUpdates_new,58 flushInteractiveUpdates as flushInteractiveUpdates_new,59 computeUniqueAsyncExpiration as computeUniqueAsyncExpiration_new,60 flushPassiveEffects as flushPassiveEffects_new,61 warnIfNotCurrentlyActingUpdatesInDev as warnIfNotCurrentlyActingUpdatesInDev_new,62 inferStartTimeFromExpirationTime as inferStartTimeFromExpirationTime_new,63} from './ReactFiberScheduler.new';64// enableNewScheduler é½ä¸º falseï¼æ以æ们åªç old ç代ç 65export const requestCurrentTime = enableNewScheduler66 ? requestCurrentTime_new67 : requestCurrentTime_old;68export const computeExpirationForFiber = enableNewScheduler69 ? computeExpirationForFiber_new70 : computeExpirationForFiber_old;71export const captureCommitPhaseError = enableNewScheduler72 ? captureCommitPhaseError_new73 : captureCommitPhaseError_old;74export const onUncaughtError = enableNewScheduler75 ? onUncaughtError_new76 : onUncaughtError_old;77export const renderDidSuspend = enableNewScheduler78 ? renderDidSuspend_new79 : renderDidSuspend_old;80export const renderDidError = enableNewScheduler81 ? renderDidError_new82 : renderDidError_old;83export const pingSuspendedRoot = enableNewScheduler84 ? pingSuspendedRoot_new85 : pingSuspendedRoot_old;86export const retryTimedOutBoundary = enableNewScheduler87 ? retryTimedOutBoundary_new88 : retryTimedOutBoundary_old;89export const resolveRetryThenable = enableNewScheduler90 ? resolveRetryThenable_new91 : resolveRetryThenable_old;92export const markLegacyErrorBoundaryAsFailed = enableNewScheduler93 ? markLegacyErrorBoundaryAsFailed_new94 : markLegacyErrorBoundaryAsFailed_old;95export const isAlreadyFailedLegacyErrorBoundary = enableNewScheduler96 ? isAlreadyFailedLegacyErrorBoundary_new97 : isAlreadyFailedLegacyErrorBoundary_old;98export const scheduleWork = enableNewScheduler99 ? scheduleWork_new100 : scheduleWork_old;101export const flushRoot = enableNewScheduler ? flushRoot_new : flushRoot_old;102export const batchedUpdates = enableNewScheduler103 ? batchedUpdates_new104 : batchedUpdates_old;105export const unbatchedUpdates = enableNewScheduler106 ? unbatchedUpdates_new107 : unbatchedUpdates_old;108export const flushSync = enableNewScheduler ? flushSync_new : flushSync_old;109export const flushControlled = enableNewScheduler110 ? flushControlled_new111 : flushControlled_old;112export const deferredUpdates = enableNewScheduler113 ? deferredUpdates_new114 : deferredUpdates_old;115export const syncUpdates = enableNewScheduler116 ? syncUpdates_new117 : syncUpdates_old;118export const interactiveUpdates = enableNewScheduler119 ? interactiveUpdates_new120 : interactiveUpdates_old;121export const flushInteractiveUpdates = enableNewScheduler122 ? flushInteractiveUpdates_new123 : flushInteractiveUpdates_old;124export const computeUniqueAsyncExpiration = enableNewScheduler125 ? computeUniqueAsyncExpiration_new126 : computeUniqueAsyncExpiration_old;127export const flushPassiveEffects = enableNewScheduler128 ? flushPassiveEffects_new129 : flushPassiveEffects_old;130export const warnIfNotCurrentlyActingUpdatesInDev = enableNewScheduler131 ? warnIfNotCurrentlyActingUpdatesInDev_new132 : warnIfNotCurrentlyActingUpdatesInDev_old;133export const inferStartTimeFromExpirationTime = enableNewScheduler134 ? inferStartTimeFromExpirationTime_new135 : inferStartTimeFromExpirationTime_old;136export type Thenable = {137 then(resolve: () => mixed, reject?: () => mixed): void | Thenable,...
FiberThrow.js
Source:FiberThrow.js
1import {2 Incomplete,3 FunctionComponent,4 SuspenseComponent,5 ShouldCapture,6} from '@Jeact/shared/Constants';7import {8 suspenseStackCursor, 9 InvisibleParentSuspenseContext,10 shouldCaptureSuspense,11} from '@Jeact/vDOM/FiberSuspenseContext';12import {13 renderDidError,14 pingSuspendedRoot,15} from '@Jeact/vDOM/FiberWorkLoop';16function attachPingListener(root, wakeable, lanes){17 let pingCache = root.pingCache;18 let threadIDs;19 if (pingCache === null){20 pingCache = root.pingCache = new WeakMap();21 threadIDs = new Set();22 pingCache.set(wakeable, threadIDs);23 } else {24 threadIDs = pingCache.get(wakeable);25 if(threadIDs === undefined){26 threadIDs = new Set();27 pingCache.set(wakeable, threadIDs);28 }29 }30 if (!threadIDs.has(lanes)){31 threadIDs.add(lanes);32 const ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);33 wakeable.then(ping, ping);34 }35}36export function throwException(37 root, 38 returnFiber, 39 sourceFiber,40 value,41 rootRenderLanes42){43 sourceFiber.flags |= Incomplete;44 if(45 value !==null &&46 typeof value === 'object' &&47 typeof value.then === 'function'48 ){49 const wakeable = value;50 // hasSuspenseContext()51 const hasInvisibleParent = 52 (suspenseStackCursor.current & 53 InvisibleParentSuspenseContext) !== 0;54 // Schedule the nearest Suspense to re-render the timed out view.55 let wip = returnFiber;56 do {57 if(58 wip.tag === SuspenseComponent &&59 shouldCaptureSuspense(60 wip, 61 hasInvisibleParent62 )63 ){64 // Found the nearest boundary.65 //66 // Stash the promise.67 const wakeables = wip.updateQueue;68 if (wakeables === null){ 69 const updateQueue = new Set();70 updateQueue.add(wakeable);71 wip.updateQueue = updateQueue;72 } else {73 wakeables.add(wakeable);74 }75 attachPingListener(root, wakeable, rootRenderLanes);76 wip.flags |= ShouldCapture;77 wip.lanes = rootRenderLanes;78 return;79 }80 wip = wip.return;81 } while (wip !== null);82 }83 renderDidError();//update exit status...
Using AI Code Generation
1const { pingSuspendedRoot } = require('playwright/lib/server/chromium/crPage');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch();5 const context = await browser.newContext();6 const page = await context.newPage();7 await pingSuspendedRoot(page);8 await page.screenshot({ path: 'example.png' });9 await browser.close();10})();11const { chromium } = require('playwright');12(async () => {13 const browser = await chromium.launch();14 const context = await browser.newContext();15 const page = await context.newPage();16 await page.screenshot({ path: 'example.png' });17 await browser.close();18})();
Using AI Code Generation
1const playwright = require('playwright');2(async () => {3 for (const browserType of BROWSER) {4 const browser = await playwright[browserType].launch({5 });6 const context = await browser.newContext();7 const page = await context.newPage();8 await page.evaluate(() => {9 window['playwright'].pingSuspendedRoot(document.body, 1000);10 });11 await browser.close();12 }13})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await browser.close();7})();8const { chromium } = require('playwright');9const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');10describe('Ping Suspended Root', () => {11 it('should ping suspended root', async () => {12 const browser = await chromium.launch();13 const page = await browser.newPage();14 await browser.close();15 });16});
Using AI Code Generation
1const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');2const { chromium } = require('playwright');3(async () => {4 const browser = await chromium.launch({ headless: false });5 const context = await browser.newContext();6 const page = await context.newPage();7 await page.screenshot({ path: `test.png` });8 await pingSuspendedRoot(page, 'test.png');9 await browser.close();10})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await pingSuspendedRoot(page);7 await browser.close();8})();9const { chromium } = require('playwright');10const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 await pingSuspendedRoot(page);16 await browser.close();17})();18const { chromium } = require('playwright');19const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');20(async () => {21 const browser = await chromium.launch();22 const context = await browser.newContext();23 const page = await context.newPage();24 await pingSuspendedRoot(page);25 await browser.close();26})();27const { chromium } = require('playwright');28const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');29(async () => {30 const browser = await chromium.launch();31 const context = await browser.newContext();32 const page = await context.newPage();33 const elementHandle = await page.$('body');34 await pingSuspendedRoot(elementHandle);35 await browser.close();36})();37const { chromium } = require('playwright');38const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');39(async () => {40 const browser = await chromium.launch();41 const context = await browser.newContext();
Using AI Code Generation
1const playwright = require('playwright');2const fs = require('fs');3(async () => {4 const browser = await playwright.chromium.launch();5 const page = await browser.newPage();6 await page.setContent('<div>Hello world</div>');7 const root = await page.mainFrame().executionContext().evaluateHandle(() => document.body);8 const result = await page._delegate.pingSuspendedRoot(root._remoteObject.objectId);9 fs.writeFileSync('result.txt', result);10 await browser.close();11})();12const playwright = require('playwright');13const fs = require('fs');14(async () => {15 const browser = await playwright.chromium.launch();16 const page = await browser.newPage();17 await page.setContent('<div>Hello world</div>');18 const root = await page.mainFrame().executionContext().evaluateHandle(() => document.body);19 const result = await page._delegate.pingSuspendedRoot(root._remoteObject.objectId);20 fs.writeFileSync('result.txt', result);21 await browser.close();22})();
Using AI Code Generation
1const { chromium } = require('playwright');2const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');3(async () => {4 const browser = await chromium.launch();5 const page = await browser.newPage();6 await pingSuspendedRoot(page);7 await browser.close();8})();9const { chromium } = require('playwright');10const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');11(async () => {12 const browser = await chromium.launch();13 const page = await browser.newPage();14 await pingSuspendedRoot(page);15 await browser.close();16})();17const { chromium } = require('playwright');18const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');19(async () => {20 const browser = await chromium.launch();21 const page = await browser.newPage();22 await pingSuspendedRoot(page);23 await browser.close();24})();25const { chromium } = require('playwright');26const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');27(async () => {28 const browser = await chromium.launch();29 const page = await browser.newPage();30 await pingSuspendedRoot(page);31 await browser.close();32})();33const { chromium } = require('playwright');34const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/recorderSupplement');35(async () => {36 const browser = await chromium.launch();37 const page = await browser.newPage();
Using AI Code Generation
1const { pingSuspendedRoot } = require('playwright/lib/server/supplements/recorder/supplements/recorderSupplement.js');2const { chromium } = require('playwright');3const { chromium } = require('playwright');4(async () => {5 const browser = await chromium.launch();6 const context = await browser.newContext();7 const page = await context.newPage();8 await page.fill('input[name="q"]', 'Hello World!');9 await page.click('input[type="submit"]');10 await page.click('text=Playwright');11 await page.waitForTimeout(1000);12 await page.click('text=GitHub');13 await page.waitForTimeout(1000);
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!