How to use pingSuspendedRoot method in Playwright Internal

Best JavaScript code snippet using playwright-internal

ReactFiberThrow.old.js

Source:ReactFiberThrow.old.js Github

copy

Full Screen

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}...

Full Screen

Full Screen

ReactFiberThrow.new.js

Source:ReactFiberThrow.new.js Github

copy

Full Screen

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}...

Full Screen

Full Screen

ReactFiberThrow.js

Source:ReactFiberThrow.js Github

copy

Full Screen

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}...

Full Screen

Full Screen

ReactFiberScheduler.js

Source:ReactFiberScheduler.js Github

copy

Full Screen

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,...

Full Screen

Full Screen

FiberThrow.js

Source:FiberThrow.js Github

copy

Full Screen

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...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

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})();

Full Screen

Using AI Code Generation

copy

Full Screen

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})();

Full Screen

Using AI Code Generation

copy

Full Screen

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});

Full Screen

Using AI Code Generation

copy

Full Screen

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})();

Full Screen

Using AI Code Generation

copy

Full Screen

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();

Full Screen

Using AI Code Generation

copy

Full Screen

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})();

Full Screen

Using AI Code Generation

copy

Full Screen

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();

Full Screen

Using AI Code Generation

copy

Full Screen

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);

Full Screen

Playwright tutorial

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.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful