narraleaf-react 0.9.0-beta.4 → 0.9.0

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.
@@ -40,9 +40,17 @@ export declare const SceneActionTypes: {
40
40
  readonly setBackgroundMusic: "scene:setBackgroundMusic";
41
41
  readonly preUnmount: "scene:preUnmount";
42
42
  readonly transitionToScene: "scene:transitionToScene";
43
+ readonly nvlBlock: "scene:nvlBlock";
44
+ readonly nvlShow: "scene:nvlShow";
45
+ readonly nvlHide: "scene:nvlHide";
46
+ readonly nvlEnd: "scene:nvlEnd";
47
+ };
48
+ export type NvlBlockOptions = {
49
+ showTransition?: Partial<TransformDefinitions.CommonTransformProps>;
50
+ hideTransition?: Partial<TransformDefinitions.CommonTransformProps>;
43
51
  };
44
52
  export type SceneActionContentType = {
45
- [K in typeof SceneActionTypes[keyof typeof SceneActionTypes]]: K extends typeof SceneActionTypes["action"] ? Scene : K extends typeof SceneActionTypes["init"] ? [Scene] : K extends typeof SceneActionTypes["exit"] ? [] : K extends typeof SceneActionTypes["jumpTo"] ? [Scene] : K extends typeof SceneActionTypes["setBackgroundMusic"] ? [Sound | null, number?] : K extends typeof SceneActionTypes["preUnmount"] ? [] : K extends typeof SceneActionTypes["transitionToScene"] ? [ImageTransition, Scene | undefined, ImageSrc | Color | undefined] : any;
53
+ [K in typeof SceneActionTypes[keyof typeof SceneActionTypes]]: K extends typeof SceneActionTypes["action"] ? Scene : K extends typeof SceneActionTypes["init"] ? [Scene] : K extends typeof SceneActionTypes["exit"] ? [] : K extends typeof SceneActionTypes["jumpTo"] ? [Scene] : K extends typeof SceneActionTypes["setBackgroundMusic"] ? [Sound | null, number?] : K extends typeof SceneActionTypes["preUnmount"] ? [] : K extends typeof SceneActionTypes["transitionToScene"] ? [ImageTransition, Scene | undefined, ImageSrc | Color | undefined] : K extends typeof SceneActionTypes["nvlBlock"] ? [LogicAction.Actions[], NvlBlockOptions] : K extends typeof SceneActionTypes["nvlShow"] ? [Partial<TransformDefinitions.CommonTransformProps>?] : K extends typeof SceneActionTypes["nvlHide"] ? [Partial<TransformDefinitions.CommonTransformProps>?] : K extends typeof SceneActionTypes["nvlEnd"] ? [NvlBlockOptions?] : any;
46
54
  };
47
55
  export declare const StoryActionTypes: {
48
56
  readonly action: "story:action";
@@ -103,9 +111,10 @@ export declare const ControlActionTypes: {
103
111
  readonly while: "control:while";
104
112
  readonly break: "control:break";
105
113
  readonly sleep: "control:sleep";
114
+ readonly waitForClick: "control:waitForClick";
106
115
  };
107
116
  export type ControlActionContentType = {
108
- [K in typeof ControlActionTypes[keyof typeof ControlActionTypes]]: K extends "control:do" ? [LogicAction.Actions[]] : K extends "control:doAsync" ? [LogicAction.Actions[]] : K extends "control:any" ? [LogicAction.Actions[]] : K extends "control:all" ? [LogicAction.Actions[]] : K extends "control:parallel" ? [LogicAction.Actions[]] : K extends "control:allAsync" ? [LogicAction.Actions[]] : K extends "control:repeat" ? [LogicAction.Actions[], number] : K extends "control:while" ? [LogicAction.Actions[], Lambda<boolean>] : K extends "control:break" ? [] : K extends "control:sleep" ? [LogicAction.Actions[], number | Awaitable<any> | Promise<any>] : any;
117
+ [K in typeof ControlActionTypes[keyof typeof ControlActionTypes]]: K extends "control:do" ? [LogicAction.Actions[]] : K extends "control:doAsync" ? [LogicAction.Actions[]] : K extends "control:any" ? [LogicAction.Actions[]] : K extends "control:all" ? [LogicAction.Actions[]] : K extends "control:parallel" ? [LogicAction.Actions[]] : K extends "control:allAsync" ? [LogicAction.Actions[]] : K extends "control:repeat" ? [LogicAction.Actions[], number] : K extends "control:while" ? [LogicAction.Actions[], Lambda<boolean>] : K extends "control:break" ? [] : K extends "control:sleep" ? [LogicAction.Actions[], number | Awaitable<any> | Promise<any>] : K extends "control:waitForClick" ? [] : any;
109
118
  };
110
119
  export declare const TextActionTypes: {
111
120
  readonly action: "text:action";
@@ -1,4 +1,4 @@
1
- import { LogicAction } from "../action/logicAction";
1
+ import type { LogicAction } from "../action/logicAction";
2
2
  import { Chainable } from "../action/chain";
3
3
  export declare class Actionable<StateData extends Record<string, any> | null = Record<string, any>, Self extends Actionable = any> extends Chainable<LogicAction.Actions, Self> {
4
4
  constructor();
@@ -19,6 +19,7 @@ export declare class ControlAction<T extends typeof ControlActionTypes[keyof typ
19
19
  readonly while: "control:while";
20
20
  readonly break: "control:break";
21
21
  readonly sleep: "control:sleep";
22
+ readonly waitForClick: "control:waitForClick";
22
23
  };
23
24
  static executeActionsAsync(gameState: GameState, action: LogicAction.Actions): Awaitable<void>;
24
25
  checkActionChain(actions: LogicAction.Actions[]): LogicAction.Actions[];
@@ -10,9 +10,10 @@ import { Story } from "../../elements/story";
10
10
  import { ImageTransition } from "../../elements/transition/transitions/image/imageTransition";
11
11
  import { ActionSearchOptions } from "../../types";
12
12
  import { ExposedState, ExposedStateType } from "../../../player/type";
13
+ import type { TransformDefinitions } from "../../elements/transform/type";
13
14
  import { ImageDataRaw } from "../../elements/displayable/image";
14
15
  import { ActionExecutionInjection, ExecutedActionResult } from "../action";
15
- type SceneSnapshot = {
16
+ export type SceneSnapshot = {
16
17
  state: SceneDataRaw | null;
17
18
  local: Record<string, any>;
18
19
  element: PlayerStateElementSnapshot;
@@ -27,6 +28,10 @@ export declare class SceneAction<T extends typeof SceneActionTypes[keyof typeof
27
28
  readonly setBackgroundMusic: "scene:setBackgroundMusic";
28
29
  readonly preUnmount: "scene:preUnmount";
29
30
  readonly transitionToScene: "scene:transitionToScene";
31
+ readonly nvlBlock: "scene:nvlBlock";
32
+ readonly nvlShow: "scene:nvlShow";
33
+ readonly nvlHide: "scene:nvlHide";
34
+ readonly nvlEnd: "scene:nvlEnd";
30
35
  };
31
36
  static handleSceneInit(scene: Scene, next: CalledActionResult, state: GameState, awaitable: Awaitable<CalledActionResult, any>): {
32
37
  type: any;
@@ -43,10 +48,10 @@ export declare class SceneAction<T extends typeof SceneActionTypes[keyof typeof
43
48
  static restoreSceneSnapshot(snapshot: SceneSnapshot, state: GameState): void;
44
49
  applyTransition(gameState: GameState, transition: ImageTransition, injection: ActionExecutionInjection): Awaitable<CalledActionResult, CalledActionResult>;
45
50
  exit(state: GameState): void;
51
+ applyNvlVisibility(gameState: GameState, visible: boolean, options: Partial<TransformDefinitions.CommonTransformProps> | undefined, injection: ActionExecutionInjection): CalledActionResult | Awaitable<CalledActionResult, CalledActionResult>;
46
52
  executeAction(gameState: GameState, injection: ActionExecutionInjection): ExecutedActionResult;
47
53
  getFutureActions(story: Story, searchOptions?: ActionSearchOptions): LogicAction.Actions[];
48
54
  _sceneNotFoundError(sceneId: string): Error;
49
55
  getSceneName(scene: Scene | string): string;
50
56
  stringify(story: Story, seen: Set<LogicAction.Actions>, _strict: boolean): string;
51
57
  }
52
- export {};
@@ -155,7 +155,7 @@ export declare class StackModel {
155
155
  * The undo/history system will then re-insert the action
156
156
  * manually (see LiveGame.undo) to avoid having two copies
157
157
  * of the same action after deserialisation.
158
- * @returns Snapshot that can be passed to {@link StackModel.deserialize}.
158
+ * @returns Snapshot that can be passed to StackModel.deserialize.
159
159
  */
160
160
  serialize(frozen?: boolean): StackModelRawData;
161
161
  reset(): void;
@@ -16,4 +16,5 @@ import { Persistent } from "../elements/persistent";
16
16
  import { Service } from "../elements/service";
17
17
  import { Layer } from "../elements/layer";
18
18
  import { Video } from "../elements/video";
19
- export { Character, Condition, Control, Image, Lambda, Menu, Scene, Script, Sentence, Sound, Story, Transform, Word, Text, Pause, Persistent, Service, Layer, Video, };
19
+ import { NVLToken } from "../elements/nvl";
20
+ export { Character, Condition, Control, Image, Lambda, Menu, NVLToken, Scene, Script, Sentence, Sound, Story, Transform, Word, Text, Pause, Persistent, Service, Layer, Video, };
@@ -79,6 +79,16 @@ export declare class Control extends Actionable {
79
79
  * @chainable
80
80
  */
81
81
  static sleep(duration: number | Awaitable<any> | Promise<any>): ChainedControl;
82
+ /**
83
+ * Pause execution until the user clicks anywhere on the stage (excluding GUI/Page elements).
84
+ * Similar to inserting a pause with no duration in a Sentence.
85
+ * @chainable
86
+ * @example
87
+ * ```ts
88
+ * Control.waitForClick();
89
+ * ```
90
+ */
91
+ static waitForClick(): ChainedControl;
82
92
  constructor(/**@internal */ config?: Partial<ControlConfig>);
83
93
  /**
84
94
  * Execute actions in order, waiting for each action to complete
@@ -126,4 +136,9 @@ export declare class Control extends Actionable {
126
136
  * @chainable
127
137
  */
128
138
  sleep(duration: number | Awaitable<any> | Promise<any>): ChainedControl;
139
+ /**
140
+ * Wait for user to click the stage (excluding GUI elements)
141
+ * @chainable
142
+ */
143
+ waitForClick(): ChainedControl;
129
144
  }
@@ -0,0 +1,41 @@
1
+ import { Actionable } from "../action/actionable";
2
+ import { LogicAction } from "../action/logicAction";
3
+ import { Chained, Proxied } from "../action/chain";
4
+ import type { TransformDefinitions } from "../elements/transform/type";
5
+ import type { Scene } from "../elements/scene";
6
+ type ChainedNVL = Proxied<NVLToken, Chained<LogicAction.Actions>>;
7
+ export declare class NVLToken extends Actionable<null, NVLToken> {
8
+ constructor(scene: Scene);
9
+ /**
10
+ * Show the NVL layer with optional transition
11
+ * @param options - Optional transition properties for showing the NVL layer
12
+ * @chainable
13
+ * @example
14
+ * ```ts
15
+ * nvl.show({ duration: 500 });
16
+ * ```
17
+ */
18
+ show(options?: Partial<TransformDefinitions.CommonTransformProps>): ChainedNVL;
19
+ /**
20
+ * Hide the NVL layer with optional transition
21
+ * Does not exit NVL mode or clear dialogs
22
+ * @param options - Optional transition properties for hiding the NVL layer
23
+ * @chainable
24
+ * @example
25
+ * ```ts
26
+ * nvl.hide({ duration: 500 });
27
+ * ```
28
+ */
29
+ hide(options?: Partial<TransformDefinitions.CommonTransformProps>): ChainedNVL;
30
+ /**
31
+ * Force exit NVL mode immediately
32
+ * Clears all accumulated dialogs and hides the NVL layer
33
+ * @chainable
34
+ * @example
35
+ * ```ts
36
+ * nvl.end();
37
+ * ```
38
+ */
39
+ end(): ChainedNVL;
40
+ }
41
+ export {};
@@ -7,6 +7,8 @@ import { ActionStatements, Persistent } from "../common/core";
7
7
  import { Chained, Proxied } from "../action/chain";
8
8
  import { ImageTransition } from "../elements/transition/transitions/image/imageTransition";
9
9
  import { Layer } from "../elements/layer";
10
+ import { NVLToken } from "./nvl";
11
+ import type { TransformDefinitions } from "../elements/transform/type";
10
12
  export interface ISceneUserConfig {
11
13
  /**
12
14
  * Background music
@@ -79,6 +81,31 @@ export declare class Scene extends Constructable<LogicAction.Actions, Scene> {
79
81
  * ```
80
82
  */
81
83
  setBackgroundMusic(sound: Sound | null, fade?: number): ChainedScene;
84
+ /**
85
+ * Create an NVL (Novel) mode block for displaying accumulated dialog.
86
+ * In NVL mode, dialogs are stacked on screen rather than replacing each other.
87
+ * @param actions - Actions to execute within NVL mode, or a callback receiving an NVLToken
88
+ * @chainable
89
+ * @example
90
+ * ```ts
91
+ * scene.nvl([
92
+ * character.say("First line"),
93
+ * character.say("Second line"),
94
+ * character.say("Third line"),
95
+ * ]);
96
+ * ```
97
+ * @example
98
+ * ```ts
99
+ * scene.nvl(nvl => [
100
+ * nvl.show({ duration: 500 }),
101
+ * character.say("Line 1"),
102
+ * character.say("Line 2"),
103
+ * nvl.hide({ duration: 500 }),
104
+ * ]);
105
+ * ```
106
+ */
107
+ nvl(actions: ActionStatements | ((nvl: NVLToken) => ActionStatements)): ChainableAction;
108
+ nvl(options: Partial<TransformDefinitions.CommonTransformProps>, actions: ActionStatements | ((nvl: NVLToken) => ActionStatements)): ChainableAction;
82
109
  /**
83
110
  * Register the list of actions (or an action-generating callback) that this scene will execute.
84
111
  * @param actions - Either a list of actions or a factory that receives the scene and returns actions.
@@ -7,7 +7,7 @@ import { PlayerStateData } from "../player/gameState";
7
7
  import { GuardConfig } from "../player/guard";
8
8
  import React from "react";
9
9
  import { StackModel, StackModelRawData } from "./action/stackModel";
10
- import { MenuComponent, NotificationComponent, SayComponent } from "./common/player";
10
+ import { MenuComponent, NotificationComponent, NvlDialogComponent, SayComponent } from "./common/player";
11
11
  import { Color, LiveGameEventToken } from "./types";
12
12
  export interface SavedGameMetaData {
13
13
  /**
@@ -276,6 +276,11 @@ export type GameConfig = {
276
276
  * @default DefaultSay
277
277
  */
278
278
  dialog: SayComponent;
279
+ /**
280
+ * The component to use for NVL mode dialog
281
+ * @default DefaultNvlContainer
282
+ */
283
+ nvlDialog: NvlDialogComponent;
279
284
  /**
280
285
  * The function to call when an error occurs
281
286
  * @default () => {}
@@ -1,8 +1,10 @@
1
1
  import { DefaultDialog } from "../../../game/player/elements/say/Dialog";
2
2
  import { DefaultMenu } from "../../../game/player/elements/menu/PlayerMenu";
3
3
  import { DefaultNotification } from "../elements/notification/PlayerNotification";
4
+ import { DefaultNvlContainer } from "../elements/nvl/DefaultNvlContainer";
4
5
  export declare const DefaultElements: {
5
6
  readonly say: typeof DefaultDialog;
6
7
  readonly menu: typeof DefaultMenu;
7
8
  readonly notification: typeof DefaultNotification;
9
+ readonly nvlDialog: typeof DefaultNvlContainer;
8
10
  };
@@ -0,0 +1,4 @@
1
+ import React from "react";
2
+ import { INvlContainerProps } from "./type";
3
+ export declare function DefaultNvlContainer({ renderDialogItem, dialogs }: INvlContainerProps): React.JSX.Element;
4
+ export default DefaultNvlContainer;
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import { NvlContainerProps, INvlContainerProps } from "./type";
3
+ export declare function NvlContainer({ children, className, style }: NvlContainerProps): React.JSX.Element;
4
+ export declare function BaseNvlContainer({ renderDialogItem: _renderDialogItem, ...props }: INvlContainerProps & NvlContainerProps): React.JSX.Element;
5
+ export default NvlContainer;
@@ -0,0 +1,13 @@
1
+ import React from "react";
2
+ import { NvlDialogEntry } from "../../gameState";
3
+ import { NvlContextValue } from "./type";
4
+ declare const NvlContext: React.Context<NvlContextValue>;
5
+ export declare function useNvl(): NvlContextValue;
6
+ export declare function useNvlDialogs(): NvlDialogEntry[];
7
+ export declare function useIsNvlMode(): boolean;
8
+ export declare function useIsNvlVisible(): boolean;
9
+ export interface NvlProviderProps {
10
+ children: React.ReactNode;
11
+ }
12
+ export declare function NvlProvider({ children }: NvlProviderProps): React.JSX.Element;
13
+ export default NvlContext;
@@ -0,0 +1,7 @@
1
+ import React from "react";
2
+ import { NvlDialogListProps, NvlDialogItemProps } from "./type";
3
+ export declare function NvlDialogList({ children, className, style, renderDialogItem }: NvlDialogListProps): React.JSX.Element;
4
+ export declare function DefaultNvlDialogItem({ entry, index, className, style, texts }: NvlDialogItemProps & {
5
+ texts?: React.ReactNode;
6
+ }): React.JSX.Element;
7
+ export default NvlDialogList;
@@ -0,0 +1,49 @@
1
+ import type { GameState, NvlDialogEntry, NvlState } from "../../gameState";
2
+ import type { TransformDefinitions } from "../../../nlcore/elements/transform/type";
3
+ import type { Word } from "../../../nlcore/elements/character/word";
4
+ import type { Pausing } from "../../../nlcore/elements/character/pause";
5
+ import React from "react";
6
+ export type NvlDialogProxy = {
7
+ entry: NvlDialogEntry;
8
+ index: number;
9
+ isActive: boolean;
10
+ gameState: GameState;
11
+ words: Word<Pausing | string>[];
12
+ useTypeEffect: boolean;
13
+ };
14
+ export interface INvlContainerProps {
15
+ dialogs?: NvlDialogProxy[];
16
+ renderDialogItem?: NvlDialogItemRenderer;
17
+ }
18
+ export interface NvlContainerProps {
19
+ children?: React.ReactNode;
20
+ className?: string;
21
+ style?: React.CSSProperties;
22
+ }
23
+ export interface NvlDialogListProps {
24
+ children?: React.ReactNode;
25
+ className?: string;
26
+ style?: React.CSSProperties;
27
+ renderDialogItem?: NvlDialogItemRenderer;
28
+ }
29
+ export interface NvlDialogItemProps {
30
+ entry: NvlDialogEntry;
31
+ index: number;
32
+ className?: string;
33
+ style?: React.CSSProperties;
34
+ }
35
+ export interface NvlDialogItemRenderProps {
36
+ entry: NvlDialogEntry;
37
+ index: number;
38
+ isActive: boolean;
39
+ nametag: React.ReactNode;
40
+ texts: React.ReactNode;
41
+ }
42
+ export type NvlDialogItemRenderer = (props: NvlDialogItemRenderProps) => React.ReactNode;
43
+ export interface NvlContextValue {
44
+ state: NvlState;
45
+ dialogs: NvlDialogEntry[];
46
+ isActive: boolean;
47
+ isVisible: boolean;
48
+ transitionOptions: Partial<TransformDefinitions.CommonTransformProps> | null;
49
+ }
@@ -0,0 +1,14 @@
1
+ import { DialogState } from "../say/UIDialog";
2
+ import { GameState } from "../../gameState";
3
+ import type { NvlDialogEntry } from "../../gameState";
4
+ import type { Word } from "../../../nlcore/elements/character/word";
5
+ import type { Pausing } from "../../../nlcore/elements/character/pause";
6
+ type UseNvlDialogStateParams = {
7
+ entry: NvlDialogEntry;
8
+ gameState: GameState;
9
+ words: Word<Pausing | string>[];
10
+ isActive: boolean;
11
+ useTypeEffect: boolean;
12
+ };
13
+ export declare function useNvlDialogState({ entry, gameState, words, isActive, useTypeEffect, }: UseNvlDialogStateParams): DialogState;
14
+ export {};
@@ -1,2 +1,9 @@
1
1
  import React from "react";
2
- export default function Nametag({ ...props }: Readonly<React.HTMLAttributes<HTMLDivElement>>): React.JSX.Element;
2
+ import type { Character } from "../../../nlcore/elements/character";
3
+ import type { NvlDialogEntry } from "../../gameState";
4
+ type NametagProps = React.HTMLAttributes<HTMLDivElement> & {
5
+ entry?: NvlDialogEntry;
6
+ character?: Character | null;
7
+ };
8
+ export default function Nametag({ entry, character, ...props }: Readonly<NametagProps>): React.JSX.Element;
9
+ export {};
@@ -6,6 +6,7 @@ import { Color } from "../../../../game/nlcore/types";
6
6
  import React from "react";
7
7
  import { DialogElementProps } from "./type";
8
8
  import { DialogState } from "./UIDialog";
9
+ import type { NvlDialogEntry } from "../../gameState";
9
10
  type BaseTextsProps = {
10
11
  /**
11
12
  * The default color of the text
@@ -28,10 +29,17 @@ export interface TextsProps extends DialogElementProps {
28
29
  count?: number;
29
30
  words?: Word<Pausing | string>[];
30
31
  }
32
+ export type EntryTextsProps = BaseTextsProps & {
33
+ entry: NvlDialogEntry;
34
+ gameState: GameState;
35
+ words: Word<Pausing | string>[];
36
+ useTypeEffect: boolean;
37
+ isActive: boolean;
38
+ };
31
39
  export declare function RawTexts(props: BaseTextsProps): React.JSX.Element;
32
40
  /**
33
41
  * Context-based wrapper component
34
42
  * Provides integration with the sentence context
35
43
  */
36
- export declare function Texts(props: BaseTextsProps): React.JSX.Element;
44
+ export declare function Texts(props: BaseTextsProps | EntryTextsProps): React.JSX.Element;
37
45
  export default Texts;
@@ -8,16 +8,20 @@ import { GameState } from "../gameState";
8
8
  import { Storable } from "../../nlcore/elements/persistent/storable";
9
9
  import { LiveGame } from "../../nlcore/game/liveGame";
10
10
  import { INotificationsProps, NotificationsProps } from "./notification/type";
11
+ import { INvlContainerProps } from "./nvl/type";
11
12
  export type Components<T extends Record<string, any>> = (props: Readonly<T>) => React.JSX.Element;
12
13
  export type SayComponent = Components<IDialogProps>;
13
14
  export type MenuComponent = Components<IUserMenuProps>;
14
15
  export type NotificationComponent = Components<INotificationsProps>;
16
+ export type NvlDialogComponent = Components<INvlContainerProps>;
15
17
  export type ComponentsTypes = {
16
18
  say: SayComponent;
17
19
  menu: MenuComponent;
18
20
  notification: NotificationComponent;
21
+ nvlDialog: NvlDialogComponent;
19
22
  };
20
23
  export type { SayElementProps, MenuElementProps, NotificationsProps as INotificationProps, };
24
+ export type { INvlContainerProps, NvlDialogItemRenderProps } from "./nvl/type";
21
25
  export type PlayerEventContext = {
22
26
  game: Game;
23
27
  gameState: GameState;
@@ -10,6 +10,7 @@ import { Storable } from "../nlcore/elements/persistent/storable";
10
10
  import { Game } from "../nlcore/game";
11
11
  import { Clickable, MenuElement, TextElement } from "./gameState.type";
12
12
  import { Sentence } from "../nlcore/elements/character/sentence";
13
+ import { type SceneSnapshot } from "../nlcore/action/actions/sceneAction";
13
14
  import { Logger } from "../../util/logger";
14
15
  import { Story } from "../nlcore/elements/story";
15
16
  import { LiveGame } from "../nlcore/game/liveGame";
@@ -24,6 +25,28 @@ import { Timelines } from "./Tasks";
24
25
  import { Notification, NotificationManager } from "./lib/notification";
25
26
  import { ActionHistoryManager } from "../../game/nlcore/action/actionHistory";
26
27
  import { GameHistoryManager } from "../../game/nlcore/action/gameHistory";
28
+ import type { Character } from "../nlcore/elements/character";
29
+ import type { TransformDefinitions } from "../nlcore/elements/transform/type";
30
+ import type { NvlBlockOptions } from "../nlcore/action/actionTypes";
31
+ export type NvlDialogEntry = {
32
+ id: string;
33
+ actionId: string;
34
+ character: Character | null;
35
+ sentence: Sentence;
36
+ text: string;
37
+ };
38
+ export type NvlDialogPhase = "idle" | "typing" | "awaitAdvance";
39
+ export type NvlState = {
40
+ active: boolean;
41
+ visible: boolean;
42
+ sessionId: string | null;
43
+ dialogs: NvlDialogEntry[];
44
+ options: NvlBlockOptions | null;
45
+ activeDialogId: string | null;
46
+ phase: NvlDialogPhase;
47
+ pendingAdvance: boolean;
48
+ isTyping: boolean;
49
+ };
27
50
  type Legacy_PlayerStateElement = {
28
51
  texts: Clickable<TextElement>[];
29
52
  menus: Clickable<MenuElement, Chosen>[];
@@ -47,6 +70,23 @@ export type PlayerStateElement = {
47
70
  texts: Clickable<TextElement>[];
48
71
  menus: Clickable<MenuElement, Chosen>[];
49
72
  };
73
+ export type NvlStateData = {
74
+ active: boolean;
75
+ visible: boolean;
76
+ sessionId: string | null;
77
+ options?: NvlBlockOptions | null;
78
+ activeDialogId?: string | null;
79
+ phase?: NvlDialogPhase;
80
+ pendingAdvance?: boolean;
81
+ dialogIds?: string[];
82
+ dialogs?: NvlDialogEntryData[];
83
+ };
84
+ export type NvlDialogEntryData = {
85
+ id: string;
86
+ actionId?: string;
87
+ text: string;
88
+ characterId: string | null;
89
+ };
50
90
  export type PlayerStateData = {
51
91
  scenes: {
52
92
  sceneId: string;
@@ -61,6 +101,11 @@ export type PlayerStateData = {
61
101
  }[];
62
102
  audio: AudioManagerDataRaw;
63
103
  videos: [videoId: string, videoState: VideoStateRaw][];
104
+ nvlState?: NvlStateData;
105
+ };
106
+ export type PresentationSnapshot = {
107
+ scenes: SceneSnapshot[];
108
+ nvlState: NvlState;
64
109
  };
65
110
  interface StageUtils {
66
111
  update: () => void;
@@ -73,9 +118,16 @@ type GameStateEvents = {
73
118
  "event:state.player.skip": [force?: boolean];
74
119
  "event:state.player.lineEnd": [];
75
120
  "event:state.player.requestFlush": [];
121
+ "event:state.player.stageClick": [];
76
122
  "event.state.onExpose": [unknown, ExposedState[ExposedStateType]];
77
123
  "event:state.onRender": [];
78
124
  "event:state:flushPreloadedScenes": [];
125
+ "event:state.nvl.enter": [sessionId: string, options: NvlBlockOptions | null];
126
+ "event:state.nvl.exit": [];
127
+ "event:state.nvl.dialogComplete": [dialogId: string];
128
+ "event:state.nvl.dialogAppend": [entry: NvlDialogEntry];
129
+ "event:state.nvl.visibilityChange": [visible: boolean, options?: Partial<TransformDefinitions.CommonTransformProps>];
130
+ "event:state.nvl.change": [state: NvlState];
79
131
  };
80
132
  /**
81
133
  * Core game state management class
@@ -86,6 +138,8 @@ export declare class GameState {
86
138
  [K in keyof GameStateEvents]: K;
87
139
  };
88
140
  private state;
141
+ private nvlState;
142
+ private _suppressNextNvlTyping;
89
143
  currentHandling: CalledActionResult | null;
90
144
  stage: StageUtils;
91
145
  game: Game;
@@ -106,6 +160,8 @@ export declare class GameState {
106
160
  readonly actionHistory: ActionHistoryManager;
107
161
  readonly gameHistory: GameHistoryManager;
108
162
  pageRouter: null;
163
+ private stageClickBuffer;
164
+ private readonly nvlAdvanceWaiters;
109
165
  constructor(game: Game, stage: StageUtils);
110
166
  get deps(): number;
111
167
  addVideo(video: Video): this;
@@ -138,6 +194,78 @@ export declare class GameState {
138
194
  createMenu(menu: MenuData, afterChoose?: (choice: Chosen) => void, scene?: Scene): LiveGameEventToken & {
139
195
  prompt: null | string;
140
196
  };
197
+ /**
198
+ * Enter NVL mode
199
+ * @param options - Optional block options for transitions
200
+ */
201
+ enterNvlMode(options?: NvlBlockOptions | null): this;
202
+ /**
203
+ * Exit NVL mode
204
+ * @param options - Optional block options for transitions
205
+ */
206
+ exitNvlMode(options?: NvlBlockOptions | null): this;
207
+ /**
208
+ * Set NVL layer visibility without exiting NVL mode
209
+ * @param visible - Whether to show or hide the NVL layer
210
+ * @param options - Optional transition properties
211
+ */
212
+ setNvlVisibility(visible: boolean, options?: Partial<TransformDefinitions.CommonTransformProps>): this;
213
+ /**
214
+ * Append a dialog to the NVL dialog list
215
+ * @param entry - The dialog entry to append
216
+ */
217
+ appendNvlDialog(entry: NvlDialogEntry): this;
218
+ /**
219
+ * Remove a dialog from the NVL dialog list
220
+ * @param id - The dialog id to remove
221
+ */
222
+ removeNvlDialog(id: string): this;
223
+ /**
224
+ * Get current NVL dialogs
225
+ */
226
+ getNvlDialogs(): NvlDialogEntry[];
227
+ /**
228
+ * Check if currently in NVL mode
229
+ */
230
+ isNvlMode(): boolean;
231
+ /**
232
+ * Get NVL state
233
+ */
234
+ getNvlState(): NvlState;
235
+ /**
236
+ * Create a snapshot of the current NVL state.
237
+ */
238
+ createNvlSnapshot(): NvlState;
239
+ createPresentationSnapshot(): PresentationSnapshot;
240
+ /**
241
+ * Restore NVL state and refresh UI.
242
+ */
243
+ restoreNvlSnapshot(snapshot: NvlState): this;
244
+ restorePresentationSnapshot(snapshot: PresentationSnapshot): this;
245
+ /**
246
+ * Clear NVL dialogs
247
+ */
248
+ clearNvlDialogs(): this;
249
+ setNvlActiveDialog(dialogId: string | null, isTyping: boolean): this;
250
+ setNvlTyping(isTyping: boolean): this;
251
+ getNvlDialog(dialogId: string): NvlDialogEntry | null;
252
+ getActiveNvlDialogForAction(actionId: string): NvlDialogEntry | null;
253
+ getLatestNvlDialogForAction(actionId: string): NvlDialogEntry | null;
254
+ allocateNvlDialogId(actionId: string): string;
255
+ ensureNvlDialog(entry: NvlDialogEntry): {
256
+ created: boolean;
257
+ entry: NvlDialogEntry;
258
+ };
259
+ activateNvlDialog(dialogId: string, phase?: Exclude<NvlDialogPhase, "idle">, preserveProgress?: boolean): this;
260
+ waitForNvlAdvance(dialogId: string, resolve: () => void): LiveGameEventToken;
261
+ requestNvlAdvance(dialogId: string): "ignore" | "typing" | "advance";
262
+ requestNvlSkip(dialogId: string): "ignore" | "typing" | "advance";
263
+ completeNvlTyping(dialogId: string): boolean;
264
+ settleNvlDialog(dialogId: string): this;
265
+ suppressNextNvlTyping(): this;
266
+ consumeNvlTypingSuppression(): boolean;
267
+ recordStageClick(): this;
268
+ consumeStageClick(maxAgeMs?: number): boolean;
141
269
  createDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
142
270
  disposeDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this;
143
271
  forceReset(): void;
@@ -186,6 +314,9 @@ export declare class GameState {
186
314
  fromElementSnapshot(snapshot: PlayerStateElementSnapshot): PlayerStateElement;
187
315
  private removeElements;
188
316
  private resetLayers;
317
+ private syncNvlDerivedState;
318
+ private emitNvlStateChange;
319
+ private resolveNvlAdvance;
189
320
  private createWaitableAction;
190
321
  private sceneNotFound;
191
322
  private layerNotFound;
@@ -15,4 +15,8 @@ import { RootPath } from "./lib/PageRouter/router";
15
15
  import { FixedAspectRatioContainer } from "./lib/FixedAspectRatioContainer";
16
16
  import { useKeyBinding } from "./lib/keyMap";
17
17
  import { useLiveGame } from "./lib/useLiveGame";
18
- export { Isolated, usePreference, Stage, GameMenu, Item, Notifications, Texts, Nametag, Dialog, useDialog, useVoiceState, Page, Layout, LayoutRouterProvider, PageInjectContext, RootPath, FixedAspectRatioContainer, useKeyBinding, useLiveGame, };
18
+ import { NvlContainer } from "./elements/nvl/NvlContainer";
19
+ import { DefaultNvlContainer } from "./elements/nvl/DefaultNvlContainer";
20
+ import { NvlDialogList, DefaultNvlDialogItem } from "./elements/nvl/NvlDialogList";
21
+ import { NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible } from "./elements/nvl/NvlContext";
22
+ export { Isolated, usePreference, Stage, GameMenu, Item, Notifications, Texts, Nametag, Dialog, useDialog, useVoiceState, Page, Layout, LayoutRouterProvider, PageInjectContext, RootPath, FixedAspectRatioContainer, useKeyBinding, useLiveGame, NvlContainer, DefaultNvlContainer, NvlDialogList, DefaultNvlDialogItem, NvlProvider, useNvl, useNvlDialogs, useIsNvlMode, useIsNvlVisible, };