From 5e0cdbbda3719c252b538cdcb57e3b2de85915c5 Mon Sep 17 00:00:00 2001 From: clem Date: Thu, 26 Mar 2026 18:33:14 +0800 Subject: [PATCH] fix: preserve renderDeferred set during beforerestart handler (#126) restart() unconditionally reset renderDeferred to false, overriding any Story.deferRender() call made in a beforerestart handler. Now resets renderDeferred before firing callbacks so it can detect if a handler set it back to true, and preserves that state through the restart. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/store.ts | 13 ++++++++++++- test/unit/store.test.ts | 13 ++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/store.ts b/src/store.ts index 7288c8f..6d77e3b 100644 --- a/src/store.ts +++ b/src/store.ts @@ -516,7 +516,16 @@ export const useStoryStore = create()( const startPassage = storyData.passagesById.get(storyData.startNode); if (!startPassage) return; + // Reset renderDeferred before firing beforerestart so we can detect + // if a handler called deferRender() during the callback. + set((state) => { + state.renderDeferred = false; + }); + fireBeforeRestart(); + + const keepDeferred = get().renderDeferred; + resetPRNG(); resetTriggers(); const initialVars = deepClone(variableDefaults); @@ -535,7 +544,9 @@ export const useStoryStore = create()( state.historyIndex = 0; state.visitCounts = { [startPassage.name]: 1 }; state.renderCounts = { [startPassage.name]: 1 }; - state.renderDeferred = false; + if (!keepDeferred) { + state.renderDeferred = false; + } }); lastNavigationVars = get().variables; diff --git a/test/unit/store.test.ts b/test/unit/store.test.ts index b0e4ccb..72b08c5 100644 --- a/test/unit/store.test.ts +++ b/test/unit/store.test.ts @@ -1,6 +1,6 @@ // @vitest-environment happy-dom import { describe, it, expect, beforeEach } from 'vitest'; -import { useStoryStore } from '../../src/store'; +import { useStoryStore, onBeforeRestart } from '../../src/store'; import { executeStoryInit } from '../../src/story-init'; import type { StoryData, Passage } from '../../src/parser'; import { registerClass, clearRegistry } from '../../src/class-registry'; @@ -870,5 +870,16 @@ describe('useStoryStore', () => { useStoryStore.getState().restart(); expect(useStoryStore.getState().renderDeferred).toBe(false); }); + + it('restart() preserves renderDeferred if set during beforerestart', () => { + const story = makeStoryData([makePassage(1, 'Start', '')]); + useStoryStore.getState().init(story); + const unsub = onBeforeRestart(() => { + useStoryStore.getState().deferRender(); + }); + useStoryStore.getState().restart(); + expect(useStoryStore.getState().renderDeferred).toBe(true); + unsub(); + }); }); });