@drincs/pixi-vn 1.8.25 → 1.9.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.
Files changed (55) hide show
  1. package/README.md +66 -33
  2. package/dist/{ContainerMemory-D2HtgX7w.d.cts → ContainerMemory-BpDgacyr.d.cts} +2 -15
  3. package/dist/{ContainerMemory-D2HtgX7w.d.ts → ContainerMemory-BpDgacyr.d.ts} +2 -15
  4. package/dist/{HistoryChoiceMenuOption-DVMD78W7.d.cts → HistoryChoiceMenuOption-BxMSXnyI.d.cts} +1 -1
  5. package/dist/{HistoryChoiceMenuOption-B8RfQz5H.d.ts → HistoryChoiceMenuOption-hSI4SHV-.d.ts} +1 -1
  6. package/dist/{HistoryGameState-CmjUtlkV.d.ts → HistoryGameState-C8ATx9K6.d.ts} +1 -1
  7. package/dist/{HistoryGameState-C28NcKKl.d.cts → HistoryGameState-CGfvq5iL.d.cts} +1 -1
  8. package/dist/{HistoryStep-G9dUn0Lf.d.cts → HistoryStep-WGB6nA4N.d.cts} +5 -0
  9. package/dist/{HistoryStep-G9dUn0Lf.d.ts → HistoryStep-WGB6nA4N.d.ts} +5 -0
  10. package/dist/{OpenedLabel-DLfFuZgk.d.ts → OpenedLabel-CmRdzTXP.d.ts} +1 -1
  11. package/dist/{OpenedLabel-BxfL31aQ.d.cts → OpenedLabel-Cmd675NI.d.cts} +1 -1
  12. package/dist/SoundGameState-C_6ZsQX6.d.cts +186 -0
  13. package/dist/SoundGameState-C_6ZsQX6.d.ts +186 -0
  14. package/dist/{StorageGameState-CtjNJpvE.d.cts → StorageGameState-C3PGrFPr.d.cts} +2 -2
  15. package/dist/{StorageGameState-BJy57o6K.d.ts → StorageGameState-jAexrJLj.d.ts} +2 -2
  16. package/dist/canvas.cjs +2 -2
  17. package/dist/canvas.d.cts +267 -26
  18. package/dist/canvas.d.ts +267 -26
  19. package/dist/canvas.mjs +2 -2
  20. package/dist/characters.cjs +1 -1
  21. package/dist/characters.mjs +1 -1
  22. package/dist/chunk-HD353M4B.mjs +1 -0
  23. package/dist/chunk-I7DOUH5V.mjs +1 -0
  24. package/dist/history.cjs +1 -1
  25. package/dist/history.d.cts +38 -15
  26. package/dist/history.d.ts +38 -15
  27. package/dist/history.mjs +1 -1
  28. package/dist/index.cjs +2 -2
  29. package/dist/index.d.cts +152 -34
  30. package/dist/index.d.ts +152 -34
  31. package/dist/index.mjs +2 -2
  32. package/dist/motion.cjs +1 -1
  33. package/dist/motion.mjs +1 -1
  34. package/dist/narration.cjs +2 -2
  35. package/dist/narration.d.cts +196 -52
  36. package/dist/narration.d.ts +196 -52
  37. package/dist/narration.mjs +2 -2
  38. package/dist/pixi/browser.js +163 -152
  39. package/dist/sound.cjs +1 -1
  40. package/dist/sound.d.cts +313 -6
  41. package/dist/sound.d.ts +313 -6
  42. package/dist/sound.mjs +1 -1
  43. package/dist/storage.cjs +1 -1
  44. package/dist/storage.d.cts +50 -3
  45. package/dist/storage.d.ts +50 -3
  46. package/dist/storage.mjs +1 -1
  47. package/dist/vite.cjs +4 -2
  48. package/dist/vite.d.cts +19 -0
  49. package/dist/vite.d.ts +19 -0
  50. package/dist/vite.mjs +4 -2
  51. package/package.json +3 -2
  52. package/dist/SoundManagerInterface-Dd0b88_N.d.cts +0 -436
  53. package/dist/SoundManagerInterface-Dd0b88_N.d.ts +0 -436
  54. package/dist/chunk-GIYMPXBT.mjs +0 -1
  55. package/dist/chunk-IWAXXFXE.mjs +0 -1
package/dist/index.d.cts CHANGED
@@ -1,4 +1,3 @@
1
- import { S as SoundGameState, a as SoundManagerInterface } from './SoundManagerInterface-Dd0b88_N.cjs';
2
1
  import * as canvasUtils from '@drincs/pixi-vn/canvas';
3
2
  export * from '@drincs/pixi-vn/canvas';
4
3
  import * as characterUtils from '@drincs/pixi-vn/characters';
@@ -17,31 +16,21 @@ export * from '@drincs/pixi-vn/sound';
17
16
  import * as storageUtils from '@drincs/pixi-vn/storage';
18
17
  export * from '@drincs/pixi-vn/storage';
19
18
  export { C as CachedMap } from './CachedMap-DZLvJAnA.cjs';
20
- import { P as PauseType, R as RepeatType, e as CanvasGameState } from './ContainerMemory-D2HtgX7w.cjs';
21
- import { H as HistoryGameState } from './HistoryGameState-C28NcKKl.cjs';
22
- import { S as StorageGameState } from './StorageGameState-CtjNJpvE.cjs';
23
- import { O as OpenedLabel } from './OpenedLabel-BxfL31aQ.cjs';
19
+ import { e as CanvasGameState } from './ContainerMemory-BpDgacyr.cjs';
20
+ import { H as HistoryGameState } from './HistoryGameState-CGfvq5iL.cjs';
21
+ import { S as SoundGameState } from './SoundGameState-C_6ZsQX6.cjs';
22
+ import { S as StorageGameState } from './StorageGameState-C3PGrFPr.cjs';
23
+ import { O as OpenedLabel } from './OpenedLabel-Cmd675NI.cjs';
24
24
  import { Devtools } from '@pixi/devtools';
25
- import 'tone';
26
25
  import 'lru-cache';
27
26
  import '@drincs/pixi-vn';
28
- import './HistoryStep-G9dUn0Lf.cjs';
27
+ import './HistoryStep-WGB6nA4N.cjs';
29
28
  import 'microdiff';
29
+ import 'tone';
30
30
  import './StorageElementType-C7ETezlL.cjs';
31
31
 
32
- var version = "1.8.25";
32
+ var version = "1.9.1";
33
33
 
34
- /**
35
- * @deprecated
36
- */
37
- declare const Repeat: RepeatType;
38
- /**
39
- * Pause the tickers for a duration.
40
- * @param duration Duration in seconds
41
- * @returns The pause object
42
- * @deprecated
43
- */
44
- declare function Pause(duration: number): PauseType;
45
34
  /**
46
35
  * Is a special alias to indicate the game layer.
47
36
  */
@@ -218,15 +207,9 @@ declare namespace Game {
218
207
  function exportGameState(): GameState;
219
208
  /**
220
209
  * Load the save data
221
- * @param data The save data
210
+ * @param data The save data object to restore the game state from.
222
211
  */
223
212
  function restoreGameState(data: GameState): Promise<void>;
224
- /**
225
- * @deprecated Use `restoreGameState(data)` (without the `navigate` argument) and configure navigation via `Game.init({ navigate })` or `Game.onNavigate(...)`.
226
- * @param data The save data
227
- * @param navigate Navigation function to use for this restore call.
228
- */
229
- function restoreGameState(data: GameState, navigate: (path: string) => void | Promise<void>): Promise<void>;
230
213
  /**
231
214
  * Start the game with a label. This function will clear all the game data and start the narration from the specified label.
232
215
  * @param label The label to start the game with. It can be a string or a LabelAbstract instance. If it is a string, it will be used as the id of the label to start. If it is a LabelAbstract instance, it will be used directly. If the label is not found, an error will be thrown.
@@ -250,10 +233,6 @@ declare namespace Game {
250
233
  * ```
251
234
  */
252
235
  function onEnd(value: narrationUtils.StepLabelType): void;
253
- /**
254
- * @deprecated Game.onError is deprecated. Use Game.addOnError / Game.removeOnError to register multiple handlers.
255
- */
256
- function onError(handler: (type: "step", error: any, props: narrationUtils.StepLabelPropsType) => void | Promise<void>): () => void;
257
236
  /**
258
237
  * Register an error handler. Multiple handlers can be registered; they
259
238
  * will be executed in registration order.
@@ -346,6 +325,27 @@ declare namespace Game {
346
325
  closeCurrentLabel?: boolean;
347
326
  type: string;
348
327
  }, defaultStart: () => Promise<narrationUtils.StepLabelResultType>) => narrationUtils.StepLabelResultType | Promise<narrationUtils.StepLabelResultType>): void;
328
+ /**
329
+ * Is a function that will be executed every time the current label is about to close because it
330
+ * naturally ran out of steps and control is returning to the label that called it.
331
+ *
332
+ * By default (when this is not set), the label closes immediately, exactly like before this hook
333
+ * existed. If you set it, you take control: call `defaultClose()` yourself whenever you actually
334
+ * want the label to close — right away, or later (e.g. on a subsequent player action in your
335
+ * template). Until `defaultClose()` is called, the label stays open and narration does not
336
+ * continue into the parent label.
337
+ *
338
+ * This does not fire for a `jump` or a choice's `closeCurrentLabel` option - those close the
339
+ * current label as part of starting a new one, so {@link onLabelStarting} already covers
340
+ * deferring them.
341
+ * @example
342
+ * ```ts
343
+ * Game.onLabelClosing((labelId, props, defaultClose) => {
344
+ * pendingLabelClose = defaultClose; // keep it for later, don't run it now
345
+ * })
346
+ * ```
347
+ */
348
+ function onLabelClosing(value: (labelId: narrationUtils.LabelIdType, props: narrationUtils.StepLabelPropsType, defaultClose: () => Promise<narrationUtils.StepLabelResultType>) => narrationUtils.StepLabelResultType | Promise<narrationUtils.StepLabelResultType>): void;
349
349
  /**
350
350
  * Function to be executed when navigation is requested.
351
351
  * @example
@@ -364,11 +364,131 @@ declare namespace Game {
364
364
  */
365
365
  function addOnPreContinue(handler: () => Promise<void> | void): void;
366
366
  function removeOnPreContinue(handler: () => Promise<void> | void): void;
367
+ /**
368
+ * Lets an AI agent (or any external script/browser console) drive and inspect a running game
369
+ * through `window`, without needing to know the app's own UI wiring. Not enabled by default —
370
+ * something must opt in, typically only in development. Two pieces are needed:
371
+ * - `enable()`/`disable()` turn the `window` bridge on/off — the `@drincs/pixi-vn/vite` plugin's
372
+ * `testing` option does this automatically while its dev server is running, with no extra code.
373
+ * - `setProps(props)` keeps the live app props (`navigate`/`t`/`toast`/etc.) available to every
374
+ * action — call it unconditionally from wherever your app builds those props (e.g. at the end
375
+ * of a `useGameProps()`-style hook), since every action needs up-to-date props whether or not
376
+ * testing happens to be enabled right now.
377
+ * See the `pixi-vn-testing` skill for the full guide (activation patterns, the complete command
378
+ * surface, and cookbook snippets for a browser-driven test session).
379
+ */
380
+ namespace testing {
381
+ /**
382
+ * One error captured by {@link enable} while testing is active, via {@link Game.addOnError}.
383
+ */
384
+ interface GameTestingErrorEntry {
385
+ error: unknown;
386
+ timestamp: number;
387
+ }
388
+ /**
389
+ * A read-only snapshot of everything a test session typically needs to decide its next
390
+ * action, gathered from {@link narrationUtils.narration} and {@link historyUtils.stepHistory}
391
+ * in a single call instead of reading several properties one by one.
392
+ */
393
+ interface GameTestingState {
394
+ dialogue: narrationUtils.DialogueInterface | undefined;
395
+ dialogueGlue: boolean;
396
+ choices: narrationUtils.StoredIndexedChoiceInterface[] | undefined;
397
+ input: {
398
+ isRequired: boolean;
399
+ type: string | undefined;
400
+ value: storageUtils.StorageElementType;
401
+ };
402
+ canContinue: boolean;
403
+ canGoBack: boolean;
404
+ labelsOpened: narrationUtils.OpenedLabel[];
405
+ currentLabelId: string | undefined;
406
+ stepCounter: number;
407
+ }
408
+ /**
409
+ * The object attached to `window` (and returned) by {@link enable}. Every action method
410
+ * merges the most recent props passed to {@link setProps} with any `extraProps` given here,
411
+ * then delegates to the matching narration/history call — so calling these behaves exactly
412
+ * like a real player action (the same `navigate`/`t`/`toast`/etc. the real UI uses).
413
+ *
414
+ * `narration`, `storage`, `stepHistory` and `Game` are also exposed directly for anything not
415
+ * covered by the action methods (e.g. `storage.set(...)`, `Game.exportGameState()`).
416
+ */
417
+ interface GameTestingAPI<T extends {} = {}> {
418
+ readonly Game: typeof Game;
419
+ readonly narration: narrationUtils.NarrationManagerInterface;
420
+ readonly storage: storageUtils.StorageManagerInterface;
421
+ readonly stepHistory: historyUtils.HistoryManagerInterface;
422
+ /**
423
+ * The most recent props passed to {@link setProps} — whatever your app's `StepLabelProps`
424
+ * augmentation defines (e.g. `navigate`, `toast`). Useful to drive the app's UI directly
425
+ * during a test session — e.g. `pixiVN.props.navigate("/settings")` — not just narration,
426
+ * for full control over what's on screen.
427
+ */
428
+ readonly props: narrationUtils.StepLabelPropsType<T>;
429
+ /** {@link Game.start} using the live props plus any `extraProps`. */
430
+ start(label: narrationUtils.LabelAbstract<any, T> | narrationUtils.LabelIdType, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
431
+ /** {@link narrationUtils.NarrationManagerInterface.continue} using the live props plus any `extraProps`. */
432
+ continue(extraProps?: Partial<T>, options?: {
433
+ steps?: number;
434
+ runNow?: boolean;
435
+ }): Promise<narrationUtils.StepLabelResultType>;
436
+ /** {@link narrationUtils.NarrationManagerInterface.call} using the live props plus any `extraProps`. */
437
+ call(label: narrationUtils.LabelAbstract<any, T> | narrationUtils.LabelIdType, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
438
+ /** {@link narrationUtils.NarrationManagerInterface.jump} using the live props plus any `extraProps`. */
439
+ jump(label: narrationUtils.LabelAbstract<any, T> | narrationUtils.LabelIdType, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
440
+ /**
441
+ * Selects the currently open choice with this `choiceIndex` (as seen in
442
+ * `getState().choices`), using the live props plus any `extraProps`.
443
+ * @throws when no open choice has that index.
444
+ */
445
+ selectChoice(choiceIndex: number, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
446
+ /** Resolves a pending `narration.input.request(...)` with `value`, exactly like the player typing an answer and confirming. */
447
+ setInput(value: storageUtils.StorageElementType): void;
448
+ /** {@link historyUtils.HistoryManagerInterface.back} using the live props plus any `extraProps`. */
449
+ goBack(extraProps?: Partial<T>, options?: {
450
+ steps?: number;
451
+ }): Promise<narrationUtils.StepLabelResultType>;
452
+ /** {@link narrationUtils.NarrationLabelsInterface.closeCurrent} */
453
+ closeCurrentLabel(): void;
454
+ /** {@link narrationUtils.NarrationLabelsInterface.closeAll}. **Can end the game.** */
455
+ closeAllLabels(): void;
456
+ /** A snapshot of dialogue/choices/input/canContinue/canGoBack/labels — see {@link GameTestingState}. */
457
+ getState(): GameTestingState;
458
+ /** Errors caught via {@link Game.addOnError} since `enable()` was called (or since the last {@link clearErrors}). */
459
+ readonly errors: GameTestingErrorEntry[];
460
+ clearErrors(): void;
461
+ }
462
+ /**
463
+ * Updates the live props every {@link GameTestingAPI} action merges `extraProps` on top of.
464
+ * Call this unconditionally from wherever your app builds its `StepLabelProps` (e.g. the end
465
+ * of a `useGameProps()`-style hook that already runs throughout the app) — it's a cheap
466
+ * assignment, safe to call whether or not testing is currently {@link enable}d.
467
+ * @param props The app's current `StepLabelProps` (the same object your UI passes to
468
+ * `narration.continue`/`Game.start`).
469
+ */
470
+ function setProps<T extends {} = {}>(props: narrationUtils.StepLabelPropsType<T>): void;
471
+ /**
472
+ * Enables the testing API: builds it, attaches it to `window[windowKey]` (default
473
+ * `"pixiVN"`), and returns it. Calling this again replaces the previous session.
474
+ * @param options.windowKey The property name to attach the API under on `window`. @default "pixiVN"
475
+ */
476
+ function enable<T extends {} = {}>(options?: {
477
+ windowKey?: string;
478
+ }): GameTestingAPI<T>;
479
+ /**
480
+ * Disables a session started with {@link enable}: removes the error handler and, if it's
481
+ * still the current value, deletes `window[windowKey]`. No-op if testing isn't enabled.
482
+ */
483
+ function disable(): void;
484
+ /** Whether a testing session is currently active. */
485
+ function isEnabled(): boolean;
486
+ }
367
487
  }
368
488
  declare const _default: {
369
489
  canvas: canvasUtils.CanvasManagerInterface;
370
490
  narration: narrationUtils.NarrationManagerInterface;
371
- sound: SoundManagerInterface;
491
+ sound: soundUtils.SoundManagerInterface;
372
492
  storage: storageUtils.StorageManagerInterface;
373
493
  history: historyUtils.HistoryManagerInterface;
374
494
  Game: typeof Game;
@@ -379,9 +499,7 @@ declare const _default: {
379
499
  narrationUtils: typeof narrationUtils;
380
500
  soundUtils: typeof soundUtils;
381
501
  CANVAS_APP_GAME_LAYER_ALIAS: string;
382
- Pause: typeof Pause;
383
- Repeat: "repeat";
384
502
  PIXIVN_VERSION: string;
385
503
  };
386
504
 
387
- export { CANVAS_APP_GAME_LAYER_ALIAS, Game, type GameState, type GameStepStateData, version as PIXIVN_VERSION, Pause, Repeat, SYSTEM_RESERVED_STORAGE_KEYS, createExportableElement, _default as default };
505
+ export { CANVAS_APP_GAME_LAYER_ALIAS, Game, type GameState, type GameStepStateData, version as PIXIVN_VERSION, SYSTEM_RESERVED_STORAGE_KEYS, createExportableElement, _default as default };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { S as SoundGameState, a as SoundManagerInterface } from './SoundManagerInterface-Dd0b88_N.js';
2
1
  import * as canvasUtils from '@drincs/pixi-vn/canvas';
3
2
  export * from '@drincs/pixi-vn/canvas';
4
3
  import * as characterUtils from '@drincs/pixi-vn/characters';
@@ -17,31 +16,21 @@ export * from '@drincs/pixi-vn/sound';
17
16
  import * as storageUtils from '@drincs/pixi-vn/storage';
18
17
  export * from '@drincs/pixi-vn/storage';
19
18
  export { C as CachedMap } from './CachedMap-DZLvJAnA.js';
20
- import { P as PauseType, R as RepeatType, e as CanvasGameState } from './ContainerMemory-D2HtgX7w.js';
21
- import { H as HistoryGameState } from './HistoryGameState-CmjUtlkV.js';
22
- import { S as StorageGameState } from './StorageGameState-BJy57o6K.js';
23
- import { O as OpenedLabel } from './OpenedLabel-DLfFuZgk.js';
19
+ import { e as CanvasGameState } from './ContainerMemory-BpDgacyr.js';
20
+ import { H as HistoryGameState } from './HistoryGameState-C8ATx9K6.js';
21
+ import { S as SoundGameState } from './SoundGameState-C_6ZsQX6.js';
22
+ import { S as StorageGameState } from './StorageGameState-jAexrJLj.js';
23
+ import { O as OpenedLabel } from './OpenedLabel-CmRdzTXP.js';
24
24
  import { Devtools } from '@pixi/devtools';
25
- import 'tone';
26
25
  import 'lru-cache';
27
26
  import '@drincs/pixi-vn';
28
- import './HistoryStep-G9dUn0Lf.js';
27
+ import './HistoryStep-WGB6nA4N.js';
29
28
  import 'microdiff';
29
+ import 'tone';
30
30
  import './StorageElementType-C7ETezlL.js';
31
31
 
32
- var version = "1.8.25";
32
+ var version = "1.9.1";
33
33
 
34
- /**
35
- * @deprecated
36
- */
37
- declare const Repeat: RepeatType;
38
- /**
39
- * Pause the tickers for a duration.
40
- * @param duration Duration in seconds
41
- * @returns The pause object
42
- * @deprecated
43
- */
44
- declare function Pause(duration: number): PauseType;
45
34
  /**
46
35
  * Is a special alias to indicate the game layer.
47
36
  */
@@ -218,15 +207,9 @@ declare namespace Game {
218
207
  function exportGameState(): GameState;
219
208
  /**
220
209
  * Load the save data
221
- * @param data The save data
210
+ * @param data The save data object to restore the game state from.
222
211
  */
223
212
  function restoreGameState(data: GameState): Promise<void>;
224
- /**
225
- * @deprecated Use `restoreGameState(data)` (without the `navigate` argument) and configure navigation via `Game.init({ navigate })` or `Game.onNavigate(...)`.
226
- * @param data The save data
227
- * @param navigate Navigation function to use for this restore call.
228
- */
229
- function restoreGameState(data: GameState, navigate: (path: string) => void | Promise<void>): Promise<void>;
230
213
  /**
231
214
  * Start the game with a label. This function will clear all the game data and start the narration from the specified label.
232
215
  * @param label The label to start the game with. It can be a string or a LabelAbstract instance. If it is a string, it will be used as the id of the label to start. If it is a LabelAbstract instance, it will be used directly. If the label is not found, an error will be thrown.
@@ -250,10 +233,6 @@ declare namespace Game {
250
233
  * ```
251
234
  */
252
235
  function onEnd(value: narrationUtils.StepLabelType): void;
253
- /**
254
- * @deprecated Game.onError is deprecated. Use Game.addOnError / Game.removeOnError to register multiple handlers.
255
- */
256
- function onError(handler: (type: "step", error: any, props: narrationUtils.StepLabelPropsType) => void | Promise<void>): () => void;
257
236
  /**
258
237
  * Register an error handler. Multiple handlers can be registered; they
259
238
  * will be executed in registration order.
@@ -346,6 +325,27 @@ declare namespace Game {
346
325
  closeCurrentLabel?: boolean;
347
326
  type: string;
348
327
  }, defaultStart: () => Promise<narrationUtils.StepLabelResultType>) => narrationUtils.StepLabelResultType | Promise<narrationUtils.StepLabelResultType>): void;
328
+ /**
329
+ * Is a function that will be executed every time the current label is about to close because it
330
+ * naturally ran out of steps and control is returning to the label that called it.
331
+ *
332
+ * By default (when this is not set), the label closes immediately, exactly like before this hook
333
+ * existed. If you set it, you take control: call `defaultClose()` yourself whenever you actually
334
+ * want the label to close — right away, or later (e.g. on a subsequent player action in your
335
+ * template). Until `defaultClose()` is called, the label stays open and narration does not
336
+ * continue into the parent label.
337
+ *
338
+ * This does not fire for a `jump` or a choice's `closeCurrentLabel` option - those close the
339
+ * current label as part of starting a new one, so {@link onLabelStarting} already covers
340
+ * deferring them.
341
+ * @example
342
+ * ```ts
343
+ * Game.onLabelClosing((labelId, props, defaultClose) => {
344
+ * pendingLabelClose = defaultClose; // keep it for later, don't run it now
345
+ * })
346
+ * ```
347
+ */
348
+ function onLabelClosing(value: (labelId: narrationUtils.LabelIdType, props: narrationUtils.StepLabelPropsType, defaultClose: () => Promise<narrationUtils.StepLabelResultType>) => narrationUtils.StepLabelResultType | Promise<narrationUtils.StepLabelResultType>): void;
349
349
  /**
350
350
  * Function to be executed when navigation is requested.
351
351
  * @example
@@ -364,11 +364,131 @@ declare namespace Game {
364
364
  */
365
365
  function addOnPreContinue(handler: () => Promise<void> | void): void;
366
366
  function removeOnPreContinue(handler: () => Promise<void> | void): void;
367
+ /**
368
+ * Lets an AI agent (or any external script/browser console) drive and inspect a running game
369
+ * through `window`, without needing to know the app's own UI wiring. Not enabled by default —
370
+ * something must opt in, typically only in development. Two pieces are needed:
371
+ * - `enable()`/`disable()` turn the `window` bridge on/off — the `@drincs/pixi-vn/vite` plugin's
372
+ * `testing` option does this automatically while its dev server is running, with no extra code.
373
+ * - `setProps(props)` keeps the live app props (`navigate`/`t`/`toast`/etc.) available to every
374
+ * action — call it unconditionally from wherever your app builds those props (e.g. at the end
375
+ * of a `useGameProps()`-style hook), since every action needs up-to-date props whether or not
376
+ * testing happens to be enabled right now.
377
+ * See the `pixi-vn-testing` skill for the full guide (activation patterns, the complete command
378
+ * surface, and cookbook snippets for a browser-driven test session).
379
+ */
380
+ namespace testing {
381
+ /**
382
+ * One error captured by {@link enable} while testing is active, via {@link Game.addOnError}.
383
+ */
384
+ interface GameTestingErrorEntry {
385
+ error: unknown;
386
+ timestamp: number;
387
+ }
388
+ /**
389
+ * A read-only snapshot of everything a test session typically needs to decide its next
390
+ * action, gathered from {@link narrationUtils.narration} and {@link historyUtils.stepHistory}
391
+ * in a single call instead of reading several properties one by one.
392
+ */
393
+ interface GameTestingState {
394
+ dialogue: narrationUtils.DialogueInterface | undefined;
395
+ dialogueGlue: boolean;
396
+ choices: narrationUtils.StoredIndexedChoiceInterface[] | undefined;
397
+ input: {
398
+ isRequired: boolean;
399
+ type: string | undefined;
400
+ value: storageUtils.StorageElementType;
401
+ };
402
+ canContinue: boolean;
403
+ canGoBack: boolean;
404
+ labelsOpened: narrationUtils.OpenedLabel[];
405
+ currentLabelId: string | undefined;
406
+ stepCounter: number;
407
+ }
408
+ /**
409
+ * The object attached to `window` (and returned) by {@link enable}. Every action method
410
+ * merges the most recent props passed to {@link setProps} with any `extraProps` given here,
411
+ * then delegates to the matching narration/history call — so calling these behaves exactly
412
+ * like a real player action (the same `navigate`/`t`/`toast`/etc. the real UI uses).
413
+ *
414
+ * `narration`, `storage`, `stepHistory` and `Game` are also exposed directly for anything not
415
+ * covered by the action methods (e.g. `storage.set(...)`, `Game.exportGameState()`).
416
+ */
417
+ interface GameTestingAPI<T extends {} = {}> {
418
+ readonly Game: typeof Game;
419
+ readonly narration: narrationUtils.NarrationManagerInterface;
420
+ readonly storage: storageUtils.StorageManagerInterface;
421
+ readonly stepHistory: historyUtils.HistoryManagerInterface;
422
+ /**
423
+ * The most recent props passed to {@link setProps} — whatever your app's `StepLabelProps`
424
+ * augmentation defines (e.g. `navigate`, `toast`). Useful to drive the app's UI directly
425
+ * during a test session — e.g. `pixiVN.props.navigate("/settings")` — not just narration,
426
+ * for full control over what's on screen.
427
+ */
428
+ readonly props: narrationUtils.StepLabelPropsType<T>;
429
+ /** {@link Game.start} using the live props plus any `extraProps`. */
430
+ start(label: narrationUtils.LabelAbstract<any, T> | narrationUtils.LabelIdType, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
431
+ /** {@link narrationUtils.NarrationManagerInterface.continue} using the live props plus any `extraProps`. */
432
+ continue(extraProps?: Partial<T>, options?: {
433
+ steps?: number;
434
+ runNow?: boolean;
435
+ }): Promise<narrationUtils.StepLabelResultType>;
436
+ /** {@link narrationUtils.NarrationManagerInterface.call} using the live props plus any `extraProps`. */
437
+ call(label: narrationUtils.LabelAbstract<any, T> | narrationUtils.LabelIdType, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
438
+ /** {@link narrationUtils.NarrationManagerInterface.jump} using the live props plus any `extraProps`. */
439
+ jump(label: narrationUtils.LabelAbstract<any, T> | narrationUtils.LabelIdType, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
440
+ /**
441
+ * Selects the currently open choice with this `choiceIndex` (as seen in
442
+ * `getState().choices`), using the live props plus any `extraProps`.
443
+ * @throws when no open choice has that index.
444
+ */
445
+ selectChoice(choiceIndex: number, extraProps?: Partial<T>): Promise<narrationUtils.StepLabelResultType>;
446
+ /** Resolves a pending `narration.input.request(...)` with `value`, exactly like the player typing an answer and confirming. */
447
+ setInput(value: storageUtils.StorageElementType): void;
448
+ /** {@link historyUtils.HistoryManagerInterface.back} using the live props plus any `extraProps`. */
449
+ goBack(extraProps?: Partial<T>, options?: {
450
+ steps?: number;
451
+ }): Promise<narrationUtils.StepLabelResultType>;
452
+ /** {@link narrationUtils.NarrationLabelsInterface.closeCurrent} */
453
+ closeCurrentLabel(): void;
454
+ /** {@link narrationUtils.NarrationLabelsInterface.closeAll}. **Can end the game.** */
455
+ closeAllLabels(): void;
456
+ /** A snapshot of dialogue/choices/input/canContinue/canGoBack/labels — see {@link GameTestingState}. */
457
+ getState(): GameTestingState;
458
+ /** Errors caught via {@link Game.addOnError} since `enable()` was called (or since the last {@link clearErrors}). */
459
+ readonly errors: GameTestingErrorEntry[];
460
+ clearErrors(): void;
461
+ }
462
+ /**
463
+ * Updates the live props every {@link GameTestingAPI} action merges `extraProps` on top of.
464
+ * Call this unconditionally from wherever your app builds its `StepLabelProps` (e.g. the end
465
+ * of a `useGameProps()`-style hook that already runs throughout the app) — it's a cheap
466
+ * assignment, safe to call whether or not testing is currently {@link enable}d.
467
+ * @param props The app's current `StepLabelProps` (the same object your UI passes to
468
+ * `narration.continue`/`Game.start`).
469
+ */
470
+ function setProps<T extends {} = {}>(props: narrationUtils.StepLabelPropsType<T>): void;
471
+ /**
472
+ * Enables the testing API: builds it, attaches it to `window[windowKey]` (default
473
+ * `"pixiVN"`), and returns it. Calling this again replaces the previous session.
474
+ * @param options.windowKey The property name to attach the API under on `window`. @default "pixiVN"
475
+ */
476
+ function enable<T extends {} = {}>(options?: {
477
+ windowKey?: string;
478
+ }): GameTestingAPI<T>;
479
+ /**
480
+ * Disables a session started with {@link enable}: removes the error handler and, if it's
481
+ * still the current value, deletes `window[windowKey]`. No-op if testing isn't enabled.
482
+ */
483
+ function disable(): void;
484
+ /** Whether a testing session is currently active. */
485
+ function isEnabled(): boolean;
486
+ }
367
487
  }
368
488
  declare const _default: {
369
489
  canvas: canvasUtils.CanvasManagerInterface;
370
490
  narration: narrationUtils.NarrationManagerInterface;
371
- sound: SoundManagerInterface;
491
+ sound: soundUtils.SoundManagerInterface;
372
492
  storage: storageUtils.StorageManagerInterface;
373
493
  history: historyUtils.HistoryManagerInterface;
374
494
  Game: typeof Game;
@@ -379,9 +499,7 @@ declare const _default: {
379
499
  narrationUtils: typeof narrationUtils;
380
500
  soundUtils: typeof soundUtils;
381
501
  CANVAS_APP_GAME_LAYER_ALIAS: string;
382
- Pause: typeof Pause;
383
- Repeat: "repeat";
384
502
  PIXIVN_VERSION: string;
385
503
  };
386
504
 
387
- export { CANVAS_APP_GAME_LAYER_ALIAS, Game, type GameState, type GameStepStateData, version as PIXIVN_VERSION, Pause, Repeat, SYSTEM_RESERVED_STORAGE_KEYS, createExportableElement, _default as default };
505
+ export { CANVAS_APP_GAME_LAYER_ALIAS, Game, type GameState, type GameStepStateData, version as PIXIVN_VERSION, SYSTEM_RESERVED_STORAGE_KEYS, createExportableElement, _default as default };