@drincs/pixi-vn-ink
Version:
Pixi'VN gives you the ability to write your own narrative using Ink
369 lines (360 loc) • 17.4 kB
text/typescript
import { PixiVNJson, PixiVNJsonLabelStep as PixiVNJsonLabelStep$1, PixiVNJsonOperation as PixiVNJsonOperation$1 } from '@drincs/pixi-vn-json';
export { PixiVNJson, TextReplaces, VariableGetter } from '@drincs/pixi-vn-json';
import { StepLabelProps } from '@drincs/pixi-vn';
import { PixiVNJsonLabelStep, PixiVNJsonOperation } from '@drincs/pixi-vn-json/schema';
import { ZodType } from 'zod';
import { C as CompileSharedType } from './types-D6WoW3qe.cjs';
/**
* @deprecated Use {@link TextReplaces} instead.
*
* This function is called after the {@link onInkTranslate} function is called.
* It will replace the text between square brackets.
* It can be used for example to replace the character id with the character name:
* If there are a character with a name "John" and id "john", and the text is "Hello, my name is [john]",
* the following function will return "Hello, my name is John"
* @param getTextToReplace The function to get the text to replace
* @example
* ```ts
* import { onReplaceTextAfterTranslation } from 'pixi-vn-ink'
* import { getCharacterById } from "@drincs/pixi-vn";
*
* onReplaceTextAfterTranslation((key) => {
* let character = getCharacterById(key)
* if (character) {
* return character.name
* }
*
* // if return undefined, the system will not replace the character id
* return undefined
* })
* ```
*/
declare function onReplaceTextAfterTranslation(getTextToReplace: (
/**
* The key to be replaced
*/
key: string) => string | undefined): void;
/**
* @deprecated Use {@link TextReplaces} instead.
*
* This function is called before the {@link onInkTranslate} function is called.
* It will replace the text between square brackets.
* It can be used for example to replace the normal method for replacing the text [key] with a new method to replace the text {{key}}.
* It can be used for example to optimize the text replacement with i18next, using the {@link onInkTranslate} function.
* If there are a text is "Hello, my name is [john]", the following function will return "Hello, my name is {{john}}"
* @param getTextToReplace The function to get the text to replace
* @example
* ```ts
* import { onReplaceTextBeforeTranslation, onInkTranslate } from 'pixi-vn-ink'
* import { useTranslation } from "react-i18next";
* import { john } from "../values/characters"
*
* const { t } = useTranslation(["narration"]);
*
* onInkTranslate((text) => {
* return t(text, {
* john: john.name
* })
* })
*
* onReplaceTextBeforeTranslation((key) => {
* return `{{${key}}}`
* })
* ```
*/
declare function onReplaceTextBeforeTranslation(getTextToReplace: (
/**
* The key to be replaced
*/
key: string) => string | undefined): void;
/**
* This function set the function to translate the text
* @param t The function to translate the text
* @example
* ```ts
* import { onInkTranslate } from 'pixi-vn-ink'
* import { useTranslation } from "react-i18next";
*
* const { t } = useTranslation(["narration"]);
* onInkTranslate((text) => {
* return t(text)
* })
* ```
*/
declare function onInkTranslate(t: (text: string) => string): void;
/**
* Generate a json object with the keys of the labels and the values of the text to be translated
* @param pixivnJson The labels to be used in the narrative. They will be added to the system
* @param json If you want to add more keys to the existing json
* @param options The options to set the default value if the key is not found
* @returns The json object with the keys of the labels and the values of the text to be translated
* @example
* ```ts
* import { generateTranslateJson, importInkText } from 'pixi-vn-ink'
*
* importInkText( your_ink_text_here ).then((labels) => {
* let json = generateTranslateJson(labels)
* })
* ```
*/
declare function generateJsonInkTranslation(pixivnJson: PixiVNJson, json?: object, options?: {
/**
* Default value to set if the key is not found
* @default "copy_key"
*/
defaultValue?: "empty_string" | "copy_key";
}): Promise<object>;
/**
* A handler function invoked for each Hashtag-Command that passes the {@link HashtagHandlerOptions.validation} check.
*
* @param command The Hashtag-Command split into tokens. Corresponds to a line starting with `#`.
* For example `# navigate scene_name "Hello World"` becomes `["navigate", "scene_name", "Hello World"]`.
* Use `""` to embed a literal space inside a single token.
* @param props The properties of the current step.
* @param convertListStringToObj Utility function that converts an alternating key/value list into
* a plain object. For example `["name", "John", "age", "20"]` → `{ name: "John", age: 20 }`.
* @returns
* - `true` – the command was handled; stop processing further handlers and skip the default interpreter.
* - A `string` – treat the returned value as a new Hashtag-Command and re-interpret it.
* - `false` / `Promise<false>` – not handled; pass to the next registered handler.
*/
type HashtagHandler = (
/**
* A Hashtag-Command to run. It corresponds to a line of code that starts with `#`.
* This is an array of strings, it is the Hashtag-Command that was split by spaces. For add a space in a string, you need to use `""`.
* For example, the Hashtag-Command `# command "Hello World"` will be split into `["command", "Hello World"]`.
*/
command: string[],
/**
* The properties of the step. It is an object that contains the properties of the step.
*/
props: StepLabelProps,
/**
* It is often useful after writing a basic Hashtag-Command to add parameters with the following logic: "field name" "value".
* Furthermore, these parameters can be written in a different order, to simplify writing.
* This function is used to convert an array that has the following logic into a json. Here is an example:
* This is the array: `["name", "John", "age", "20", "position", "{ x: 2, y 3 }"]` and this is the json: `{name: "John", age: 20, position: { x: 2, y: 3 }}`.
*/
convertListStringToObj: (listParm: string[]) => object) => boolean | string | Promise<boolean | string>;
/**
* A mapper function that converts a specific Hashtag-Command token list into a
* {@link PixiVNJsonOperation} (or `undefined` when the command only modifies the step without
* producing an operation, e.g. `call` / `jump`).
*
* Unlike {@link HashtagHandler}, a mapper is purely synchronous and is **selected** by its
* validation rule rather than deciding for itself whether to handle the command. The selection
* logic in {@link HashtagCommands.convertOperation} tests each mapper's
* {@link HashtagHandlerOptions.validation} against the full token list; only the first matching
* mapper is called.
*
* @returns The {@link PixiVNJsonOperation} to enqueue, or `undefined` if the command only produces
* side-effects on `step` (such as setting `labelToOpen`).
*/
type MapperHandler = (
/**
* The full token list produced by parsing the Hashtag-Command (output of `convertTagTolist`).
* For example the tag `# pause video bg` produces `["pause", "video", "bg"]`.
*/
list: string[],
/**
* The current label step. The mapper may mutate this (e.g. set `labelToOpen` or delete
* `goNextStep`) before returning the operation.
*/
step: PixiVNJsonLabelStep) => PixiVNJsonOperation | undefined;
/**
* Configuration options for a Hashtag-Command handler registered via {@link HashtagCommands.add}.
*/
interface HashtagHandlerOptions {
/**
* A unique name that identifies this handler.
* Used for documentation and debugging purposes.
*/
name: string;
/**
* An optional human-readable description of what this handler does.
* Used for documentation purposes. Supports multi-line descriptions.
*/
description?: string;
/**
* Determines whether this handler should be invoked for a given command.
*
* - `RegExp` – the command tokens are joined with a space (`script.join(" ")`) and tested
* against the regular expression. The handler is invoked only if the regex matches.
* - `ZodType<string[]>` – the command token array is validated with
* `schema.safeParse(script)`. The handler is invoked only if validation succeeds.
*
* @example
* ```ts
* // RegExp: only handle commands that start with "navigate"
* validation: /^navigate\b/
*
* // Zod: only handle commands whose first element is "navigate" and second is a non-empty string
* import { z } from "zod"
* validation: z.tuple([z.literal("navigate"), z.string().min(1)]).rest(z.string())
* ```
*/
validation: RegExp | ZodType<string[]>;
/**
* Whether this handler is deprecated. Deprecated handlers should still function correctly
* but may be replaced by newer alternatives in the future.
*/
deprecated?: boolean;
}
/**
* This is a container for the functions related to the Hashtag-Command, a system that allows to run custom operations from the Ink command using a special syntax. The Hashtag-Command is a string that starts with `#` and is followed by the operation type and its parameters. The system will interpret the Hashtag-Command and run the corresponding operation before running the step. The developer can also add custom handlers to run custom operations from the Hashtag-Command using the {@link add} function.
*/
declare namespace HashtagCommands {
/**
* @deprecated Use the two-parameter overload with {@link HashtagHandlerOptions} instead.
*/
function add(handler: HashtagHandler): void;
/**
* This function add a new handler (middleware) that will be called before the system interprets a possible Hashtag-Command that starts with `#`.
* The developer can use this function to run a custom Hashtag-Command. If the function returns `true`, the system will not interpret the Hashtag-Command.
* If returns a array of strings, the system will interpret the array as a new Hashtag-Command.
* @param handler The handler to run a custom Hashtag-Command
* @param opts Configuration for this handler, including its name, optional description, and validation rule.
* @example
* ```ts
* import { HashtagScript } from 'pixi-vn-ink'
*
* HashtagScript.add((script, props, convertListStringToObj) => {
* // script: # navigate scene_name prop1 "value 1" prop2 "value 2"
* if (script[0] === "navigate" && script.length > 1) {
* let prop = undefined
* if (script.length > 2) {
* prop = convertListStringToObj(script.slice(2))
* }
* navigateTo(script[1], prop)
* return true
* }
* return false
* }, { name: "navigate-command", validation: /^navigate\b/ })
* ```
*/
function add(handler: HashtagHandler, opts: HashtagHandlerOptions): void;
/**
* This function returns an array of all the registered handlers with their configuration. It can be used to get information about the registered handlers, for example, to display a list of available Hashtag-Commands in a debug menu.
* @returns An array of all the registered handlers with their configuration.
*/
function info(): HashtagHandlerOptions[];
/**
* Registers a new mapper that converts a specific Hashtag-Command pattern into a
* {@link PixiVNJsonOperation}.
*
* Mappers are evaluated in registration order by
* {@link HashtagCommands.convertOperation} **before** the built-in `switch` table. The
* first mapper whose {@link HashtagHandlerOptions.validation} matches the raw token list is
* called and its return value is used as the operation; subsequent mappers (and the built-in
* switch) are skipped.
*
* Use `addMapper` instead of {@link add} when you want to extend or override the built-in
* command → operation translation without intercepting the full handler pipeline.
*
* @param handler A {@link MapperHandler} that receives the full token list and the current
* step, and returns either a {@link PixiVNJsonOperation} or `undefined`.
* @param opts Configuration including a name, optional description, and the validation rule
* used to select this mapper.
*
* @example
* ```ts
* import { HashtagCommands } from 'pixi-vn-ink'
* import { z } from 'zod'
*
* // Handle: # navigate scene_name
* HashtagCommands.addMapper(
* (list, step) => {
* step.labelToOpen = { label: list[1], type: "jump" }
* step.goNextStep = undefined
* return undefined
* },
* {
* name: "navigate-command",
* validation: z.tuple([z.literal("navigate"), z.string()]),
* },
* )
* ```
*/
function addMapper(handler: MapperHandler, opts: HashtagHandlerOptions): void;
/**
* This function clear all the handlers added with the {@link add} function.
*/
function clear(): void;
/**
* Removes all mapper handlers registered with {@link addMapper}.
*
* Useful in tests to reset the mapper state between test cases, or in applications that need
* to replace the default mappers with a custom set.
*/
function clearMappers(): void;
/**
* This function run the Hashtag-Command, it will be called before running the step. It will interpret the Hashtag-Command and return the corresponding operation to run before the step. If the Hashtag-Command is not valid, it will return undefined and the system will run the step normally.
* @param tag The Hashtag-Command to interpret, it is the string that starts with `#` and is followed by the operation type and its parameters.
* @param step The step that will be run after the Hashtag-Command, the system will run the Hashtag-Command before running the step, so the operation returned by this function will be executed before the step. The step can be modified by the Hashtag-Command, for example, it can change the dialogue or the goNextStep properties of the step.
* @param props The properties of the step label, it can be used to get information about the step and the label, for example, the label name or the step index. It can also be used to store custom properties that can be accessed by the handlers of the Hashtag-Command.
* @returns The operation to run before the step, if the Hashtag-Command is not valid, it will return undefined and the system will run the step normally.
*/
function run(tag: string, step: PixiVNJsonLabelStep$1, props: StepLabelProps): Promise<PixiVNJsonOperation$1 | undefined>;
function convertTagTolist(tag: string, options?: {
mergeInkVariables?: boolean;
}): string[];
function convertOperation(list: string[], step: PixiVNJsonLabelStep$1): PixiVNJsonOperation$1 | undefined;
/**
* For example:
* Into Ink text:
* duration 3 name "C J" surname Smith position "{ x: 2, y 3 }"
* into string list:
* ["duration", "3", "x", "2", "y", "3", "name", "C J", "surname", "Smith", "position", "{ x: 2, y 3 }"]
* into object:
* { "duration": 3, "x": 2, "y": 3, "name": "C J", "surname": "Smith", "position": { x: 2, y 3 } }
*/
function convertListStringToObj(listParm: string[]): object;
/**
* Merges valid JSON-like blocks delimited by { }
* into single strings.
*
* Rules:
* - Braces must be balanced.
* - Inner blocks are processed before parent blocks.
* - Every generated block is validated with JSON5.parse().
* - If a block is invalid:
* - the block remains split
* - all parent blocks also remain split
* - Unmatched braces are treated as normal strings.
*/
function mergeJsonBlocks(tokens: string[]): string[];
}
/**
* @deprecated This function is deprecated, use {@link HashtagCommands.add} instead
*/
declare function onInkHashtagScript(runCustomHashtagScript: HashtagHandler): void;
/**
* This function imports string or array of strings written in ink language into the Pixi’VN engine.
* @example
* ```ts
* import { importInkText } from 'pixi-vn'
* importInkText(`
* === back_in_london ===
* Hello, World!
* `).then(() => {
* GameStepManager.callLabel("back_in_london", {})
* })
* ```
* @param texts string or array of strings written in ink language
* @returns
*/
declare function importInkText(texts: string | string[]): Promise<string[]>;
/**
* This function imports data in PixiVNJson format into the Pixi’VN engine.
* @param data data in PixiVNJson format
* @returns the same data passed as parameter
*/
declare function importJson(data: PixiVNJson | PixiVNJson[]): Promise<void>;
type LoaderSharedType = Pick<CompileSharedType, "enums" | "functions">;
/**
* This function converts string written in ink language into the LabelJsonType.
* @param text string or array of strings written in ink language
* @returns LabelJsonType or undefined
*/
declare function convertInkToJson(text: string, options?: Partial<LoaderSharedType>): PixiVNJson | undefined;
export { HashtagCommands, type HashtagHandler, convertInkToJson as convertInkText, convertInkToJson, generateJsonInkTranslation, importInkText, importJson, onInkHashtagScript, onInkTranslate, onReplaceTextAfterTranslation, onReplaceTextBeforeTranslation };