From 7d2ee8b74cb00cdf9fb971debef2f16632dc7d9a Mon Sep 17 00:00:00 2001 From: Micah Geisel Date: Thu, 5 Feb 2026 10:54:25 -0600 Subject: [PATCH] remove mutable state to fix race condition causing concurrent renders to throw an exception. --- src/core/frames/frame_controller.js | 6 +----- src/core/session.js | 6 +----- src/core/view.js | 9 ++++----- 3 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/core/frames/frame_controller.js b/src/core/frames/frame_controller.js index 7487e4363..baeb82853 100644 --- a/src/core/frames/frame_controller.js +++ b/src/core/frames/frame_controller.js @@ -281,11 +281,7 @@ export class FrameController { detail: { render } } = event - if (this.view.renderer && render) { - this.view.renderer.renderElement = render - } - - return !defaultPrevented + return { immediateRender: !defaultPrevented, render } } viewRenderedSnapshot(_snapshot, _isPreview, _renderMethod) {} diff --git a/src/core/session.js b/src/core/session.js index 1e9f1c7bd..3b99fdf6c 100644 --- a/src/core/session.js +++ b/src/core/session.js @@ -340,11 +340,7 @@ export class Session { detail: { render } } = event - if (this.view.renderer && render) { - this.view.renderer.renderElement = render - } - - return !defaultPrevented + return { immediateRender: !defaultPrevented, render } } viewRenderedSnapshot(_snapshot, _isPreview, renderMethod) { diff --git a/src/core/view.js b/src/core/view.js index dad1eb2e9..1ca1678ba 100644 --- a/src/core/view.js +++ b/src/core/view.js @@ -65,20 +65,19 @@ export class View { if (shouldRender) { try { this.renderPromise = new Promise((resolve) => (this.#resolveRenderPromise = resolve)) - this.renderer = renderer await this.prepareToRenderSnapshot(renderer) const renderInterception = new Promise((resolve) => (this.#resolveInterceptionPromise = resolve)) - const options = { resume: this.#resolveInterceptionPromise, render: this.renderer.renderElement, renderMethod: this.renderer.renderMethod } - const immediateRender = this.delegate.allowsImmediateRender(snapshot, options) + const options = { resume: this.#resolveInterceptionPromise, render: renderer.renderElement, renderMethod: renderer.renderMethod } + const { immediateRender, render } = this.delegate.allowsImmediateRender(snapshot, options) + if (render) renderer.renderElement = render if (!immediateRender) await renderInterception await this.renderSnapshot(renderer) - this.delegate.viewRenderedSnapshot(snapshot, isPreview, this.renderer.renderMethod) + this.delegate.viewRenderedSnapshot(snapshot, isPreview, options.renderMethod) this.delegate.preloadOnLoadLinksForView(this.element) this.finishRenderingSnapshot(renderer) } finally { - delete this.renderer this.#resolveRenderPromise(undefined) delete this.renderPromise }