@rohal12/spindle 0.37.0 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/pkg/format.js +1 -1
- package/package.json +1 -1
- package/src/index.tsx +4 -2
- package/src/store.ts +21 -10
- package/src/story-api.ts +2 -8
package/package.json
CHANGED
package/src/index.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { render } from 'preact';
|
|
2
2
|
import { App } from './components/App';
|
|
3
3
|
import { parseStoryData } from './parser';
|
|
4
|
-
import { useStoryStore } from './store';
|
|
4
|
+
import { useStoryStore, fireStoryInit } from './store';
|
|
5
5
|
import { installStoryAPI } from './story-api';
|
|
6
6
|
import { resetIdCounters } from './action-registry';
|
|
7
7
|
import { executeStoryInit } from './story-init';
|
|
@@ -101,7 +101,6 @@ function boot() {
|
|
|
101
101
|
|
|
102
102
|
// Execute StoryInit passage if it exists
|
|
103
103
|
executeStoryInit();
|
|
104
|
-
useStoryStore.getState().bumpInitCount();
|
|
105
104
|
|
|
106
105
|
// Restore session state if the page was refreshed
|
|
107
106
|
const sessionPayload = loadSession(storyData.ifid);
|
|
@@ -109,6 +108,9 @@ function boot() {
|
|
|
109
108
|
useStoryStore.getState().loadFromPayload(sessionPayload);
|
|
110
109
|
}
|
|
111
110
|
|
|
111
|
+
// Fire storyinit after all state is settled (defaults + StoryInit + session)
|
|
112
|
+
fireStoryInit();
|
|
113
|
+
|
|
112
114
|
// Pass 1: Pre-scan all widget passages to discover block widgets.
|
|
113
115
|
// Register them as block macros BEFORE any tokenize/buildAST calls,
|
|
114
116
|
// so that widget bodies using other block widgets parse correctly
|
package/src/store.ts
CHANGED
|
@@ -176,6 +176,26 @@ function resetModuleState(base: Record<string, unknown>): void {
|
|
|
176
176
|
serializedHistory = [];
|
|
177
177
|
}
|
|
178
178
|
|
|
179
|
+
// ---------------------------------------------------------------------------
|
|
180
|
+
// storyinit callbacks (direct invocation — avoids Zustand subscription issues)
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
|
|
183
|
+
type StoryInitListener = () => void;
|
|
184
|
+
let storyInitListeners: StoryInitListener[] = [];
|
|
185
|
+
|
|
186
|
+
/** Register a callback to run after StoryInit completes (boot + every restart). */
|
|
187
|
+
export function onStoryInit(cb: StoryInitListener): () => void {
|
|
188
|
+
storyInitListeners.push(cb);
|
|
189
|
+
return () => {
|
|
190
|
+
storyInitListeners = storyInitListeners.filter((l) => l !== cb);
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** Fire all storyinit listeners. Called after all state resets are complete. */
|
|
195
|
+
export function fireStoryInit(): void {
|
|
196
|
+
for (const cb of storyInitListeners) cb();
|
|
197
|
+
}
|
|
198
|
+
|
|
179
199
|
// ---------------------------------------------------------------------------
|
|
180
200
|
// Store
|
|
181
201
|
// ---------------------------------------------------------------------------
|
|
@@ -207,7 +227,6 @@ export interface StoryState {
|
|
|
207
227
|
renderCounts: Record<string, number>;
|
|
208
228
|
knownSaves: Record<string, true>;
|
|
209
229
|
playthroughId: string;
|
|
210
|
-
initCount: number;
|
|
211
230
|
maxHistory: number;
|
|
212
231
|
saveError: string | null;
|
|
213
232
|
loadError: string | null;
|
|
@@ -215,7 +234,6 @@ export interface StoryState {
|
|
|
215
234
|
nextTransition: TransitionConfig | null;
|
|
216
235
|
nobr: boolean;
|
|
217
236
|
|
|
218
|
-
bumpInitCount: () => void;
|
|
219
237
|
setMaxHistory: (limit: number) => void;
|
|
220
238
|
init: (
|
|
221
239
|
storyData: StoryData,
|
|
@@ -260,7 +278,6 @@ export const useStoryStore = create<StoryState>()(
|
|
|
260
278
|
renderCounts: {},
|
|
261
279
|
knownSaves: {},
|
|
262
280
|
playthroughId: '',
|
|
263
|
-
initCount: 0,
|
|
264
281
|
maxHistory: 40,
|
|
265
282
|
saveError: null,
|
|
266
283
|
loadError: null,
|
|
@@ -268,12 +285,6 @@ export const useStoryStore = create<StoryState>()(
|
|
|
268
285
|
nextTransition: null,
|
|
269
286
|
nobr: false,
|
|
270
287
|
|
|
271
|
-
bumpInitCount: () => {
|
|
272
|
-
set((state) => {
|
|
273
|
-
state.initCount++;
|
|
274
|
-
});
|
|
275
|
-
},
|
|
276
|
-
|
|
277
288
|
setMaxHistory: (limit: number) => {
|
|
278
289
|
set((state) => {
|
|
279
290
|
state.maxHistory = Math.max(1, Math.round(limit));
|
|
@@ -503,8 +514,8 @@ export const useStoryStore = create<StoryState>()(
|
|
|
503
514
|
|
|
504
515
|
lastNavigationVars = get().variables;
|
|
505
516
|
executeStoryInit();
|
|
506
|
-
get().bumpInitCount();
|
|
507
517
|
clearSession(storyData.ifid);
|
|
518
|
+
fireStoryInit();
|
|
508
519
|
|
|
509
520
|
// Start a new playthrough on restart
|
|
510
521
|
startNewPlaythrough(storyData.ifid)
|
package/src/story-api.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useStoryStore } from './store';
|
|
1
|
+
import { useStoryStore, onStoryInit } from './store';
|
|
2
2
|
import type { Passage } from './parser';
|
|
3
3
|
import { settings } from './settings';
|
|
4
4
|
import type {
|
|
@@ -359,13 +359,7 @@ function createStoryAPI(): StoryAPI {
|
|
|
359
359
|
}
|
|
360
360
|
|
|
361
361
|
if (event === 'storyinit') {
|
|
362
|
-
|
|
363
|
-
return useStoryStore.subscribe((state) => {
|
|
364
|
-
if (state.initCount !== prevCount) {
|
|
365
|
-
prevCount = state.initCount;
|
|
366
|
-
(callback as StoryInitCallback)();
|
|
367
|
-
}
|
|
368
|
-
});
|
|
362
|
+
return onStoryInit(callback as StoryInitCallback);
|
|
369
363
|
}
|
|
370
364
|
|
|
371
365
|
if (event === 'actionsChanged') {
|