UNPKG

next

Version:

The React Framework

127 lines (126 loc) 4.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); 0 && (module.exports = { RenderStage: null, StagedRenderingController: null }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { RenderStage: function() { return RenderStage; }, StagedRenderingController: function() { return StagedRenderingController; } }); const _invarianterror = require("../../shared/lib/invariant-error"); const _promisewithresolvers = require("../../shared/lib/promise-with-resolvers"); var RenderStage = /*#__PURE__*/ function(RenderStage) { RenderStage[RenderStage["Static"] = 1] = "Static"; RenderStage[RenderStage["Runtime"] = 2] = "Runtime"; RenderStage[RenderStage["Dynamic"] = 3] = "Dynamic"; return RenderStage; }({}); class StagedRenderingController { constructor(abortSignal = null){ this.abortSignal = abortSignal; this.currentStage = 1; this.runtimeStagePromise = (0, _promisewithresolvers.createPromiseWithResolvers)(); this.dynamicStagePromise = (0, _promisewithresolvers.createPromiseWithResolvers)(); if (abortSignal) { abortSignal.addEventListener('abort', ()=>{ const { reason } = abortSignal; if (this.currentStage < 2) { this.runtimeStagePromise.promise.catch(ignoreReject) // avoid unhandled rejections ; this.runtimeStagePromise.reject(reason); } if (this.currentStage < 3) { this.dynamicStagePromise.promise.catch(ignoreReject) // avoid unhandled rejections ; this.dynamicStagePromise.reject(reason); } }, { once: true }); } } advanceStage(stage) { // If we're already at the target stage or beyond, do nothing. // (this can happen e.g. if sync IO advanced us to the dynamic stage) if (this.currentStage >= stage) { return; } this.currentStage = stage; // Note that we might be going directly from Static to Dynamic, // so we need to resolve the runtime stage as well. if (stage >= 2) { this.runtimeStagePromise.resolve(); } if (stage >= 3) { this.dynamicStagePromise.resolve(); } } getStagePromise(stage) { switch(stage){ case 2: { return this.runtimeStagePromise.promise; } case 3: { return this.dynamicStagePromise.promise; } default: { stage; throw Object.defineProperty(new _invarianterror.InvariantError(`Invalid render stage: ${stage}`), "__NEXT_ERROR_CODE", { value: "E881", enumerable: false, configurable: true }); } } } waitForStage(stage) { return this.getStagePromise(stage); } delayUntilStage(stage, displayName, resolvedValue) { const ioTriggerPromise = this.getStagePromise(stage); const promise = makeDevtoolsIOPromiseFromIOTrigger(ioTriggerPromise, displayName, resolvedValue); // Analogously to `makeHangingPromise`, we might reject this promise if the signal is invoked. // (e.g. in the case where we don't want want the render to proceed to the dynamic stage and abort it). // We shouldn't consider this an unhandled rejection, so we attach a noop catch handler here to suppress this warning. if (this.abortSignal) { promise.catch(ignoreReject); } return promise; } } function ignoreReject() {} // TODO(restart-on-cache-miss): the layering of `delayUntilStage`, // `makeDevtoolsIOPromiseFromIOTrigger` and and `makeDevtoolsIOAwarePromise` // is confusing, we should clean it up. function makeDevtoolsIOPromiseFromIOTrigger(ioTrigger, displayName, resolvedValue) { // If we create a `new Promise` and give it a displayName // (with no userspace code above us in the stack) // React Devtools will use it as the IO cause when determining "suspended by". // In particular, it should shadow any inner IO that resolved/rejected the promise // (in case of staged rendering, this will be the `setTimeout` that triggers the relevant stage) const promise = new Promise((resolve, reject)=>{ ioTrigger.then(resolve.bind(null, resolvedValue), reject); }); if (displayName !== undefined) { // @ts-expect-error promise.displayName = displayName; } return promise; } //# sourceMappingURL=staged-rendering.js.map