import { AssetsManifest } from '@drincs/pixi-vn/pixi.js'; import { Plugin } from 'vite'; /** @const {string} API endpoint for characters data - GET to retrieve, POST to update */ declare const PIXIVN_DEV_API_CHARACTERS = "/__pixi-vn/characters"; /** @const {string} API endpoint for narration labels - GET to retrieve, POST to update */ declare const PIXIVN_DEV_API_LABELS = "/__pixi-vn/labels"; /** @const {string} API endpoint for assets manifest - GET to retrieve, POST to update */ declare const PIXIVN_DEV_API_ASSETS_MANIFEST = "/__pixi-vn/assets/manifest"; /** @const {string} API endpoint for canvas options - GET to retrieve, POST to update */ declare const PIXIVN_DEV_API_CANVAS_OPTIONS = "/__pixi-vn/canvas-options"; /** * Either a plain {@link AssetsManifest}, or a function that resolves one — see * {@link VitePluginPixivnOptions.assetsManifest}. */ type AssetsManifestOption = AssetsManifest | ((ssrLoadModule: (id: string) => Promise) => AssetsManifest | undefined | Promise); /** * Options for {@link vitePluginPixivn}. */ interface VitePluginPixivnOptions { /** * Glob / path of module(s) that set up all game content as side effects: * characters, labels, hashtag-command handlers, text-replace handlers, etc. * * The plugin loads these files server-side (via Vite SSR) at startup so that * every downstream plugin that depends on the registered data — most notably * `vitePluginInk` for JSON compilation — has the full registry available * before it runs. This also works during `vite build`. * * Pointing to a barrel file that re-exports everything is the simplest option. * All patterns are resolved relative to Vite `root`. * * @example "./src/content/index.ts" * @example "./src/content/*.ts" */ content?: string | string[]; /** * Glob / path of module(s) whose side effects register characters via * `RegisteredCharacters.add(...)`. * * Use when characters are defined separately from other content. * * @example "./src/characters.ts" */ characters?: string | string[]; /** * Glob / path of module(s) whose side effects register narration labels via * `RegisteredLabels.register(...)`. * * @example "./src/*.label.ts" */ labels?: string | string[]; /** * Path to the auto-generated TypeScript file that combines compile-time type * augmentations and runtime `as const` arrays for all currently known entity IDs. * * When provided, the plugin generates (or overwrites) this file: * - after all content modules have been loaded at startup, * - after every hot-reload of a watched content file, * - whenever `api.setExternalLabels` or `api.clearExternalLabels` is called. * * The generated file contains: * - `declare module` augmentations for `PixivnCharacterIds` and `PixivnLabelIds`, * narrowing `CharacterIdType` / `LabelIdType` to unions of known string literals. * - `export const characterIds` and `export const labelIds` as `as const` arrays, * usable at runtime for validation (e.g. `z.enum(characterIds)`). * * The generated file is **excluded from HMR** so that updating it never * triggers a full-page reload. * * The path may be absolute or relative to Vite `root`. * * @example "./src/pixi-vn.keys.gen.ts" */ typeFilePath?: string; /** * A PIXI.js {@link AssetsManifest} describing all asset bundles and their aliases — or a * function that resolves one, for manifests that aren't known synchronously at * plugin-creation time (e.g. one produced by an asset pipeline such as `@assetpack/core`, or * merged together from several sources in an app-owned module). * * **Prefer the function form for anything backed by a generated file.** A *static* * `import manifest from "./manifest.gen.json"` in `vite.config.ts` makes Vite treat that file * as a config dependency — restarting the whole server on every change to it — which is * disastrous when the very same config's own asset pipeline rewrites that file on every * startup: an infinite restart loop. The function form sidesteps this entirely: nothing in * `vite.config.ts` itself reads or imports the file; the plugin calls your function lazily, * from inside its own plugin hooks, whenever it needs a fresh manifest. * * The function receives an `ssrLoadModule`-like loader (bound to whichever context is * available — the running dev server, or a dedicated temporary server with this plugin's own * `resolve` forwarded during `vite build`) so it can load `@/`-aliased app modules the same * way `content` / `characters` / `labels` do — e.g. to import a module that merges an asset * pipeline's generated manifest with hand-written bundles. Return `undefined` if there's * nothing to register yet (e.g. the pipeline hasn't produced output on a fresh checkout). * * The plugin calls this function whenever it (re)loads content — at startup, and on every * hot-reload — and, since it generally can't know which file(s) your function's own import * depends on, also on every other file change (excluding its own generated * {@link VitePluginPixivnOptions.typeFilePath}), so a change to a manifest generated by * another plugin is picked up without any direct coupling between the two. * * Either way — plain value or function — once a manifest is registered, the plugin: * - writes `export const bundleIds` and `export const assetAliasIds` — `as const` runtime * arrays of every bundle name and every asset alias found in the manifest — to * {@link VitePluginPixivnOptions.typeFilePath}, and augments `PixivnBundleIds` / * `PixivnAssetAliasIds` in `@drincs/pixi-vn/canvas` (the same `declare module` pattern used * for `PixivnCharacterIds` / `PixivnLabelIds`), narrowing `BundleIdType` / `AssetAliasIdType` * (also exported from `@drincs/pixi-vn/canvas`) from `string` to unions of known literals. * - seeds the dev-server's `GET /__pixi-vn/assets/manifest` endpoint with this manifest * immediately, so it is available without the browser having to `POST` it first (see * {@link PIXIVN_DEV_API_ASSETS_MANIFEST}). A later `POST` (deprecated) still overrides it. * * `api.setAssetsManifest(manifest)` remains available as a lower-level escape hatch for * pushing an already-computed manifest from outside this plugin entirely (e.g. from a * separate Vite plugin that doesn't need `ssrLoadModule` access). * * @example * ```ts * // vite.config.ts — a manifest merged from a generated file plus hand-written bundles * vitePluginPixivn({ * typeFilePath: "./src/pixi-vn.keys.gen.ts", * assetsManifest: async (ssrLoadModule) => { * const mod = await ssrLoadModule("/src/assets/index.ts"); * return mod.manifest; * }, * }) * ``` * * @example * ```ts * // vite.config.ts — a genuinely static manifest, known up front * vitePluginPixivn({ * assetsManifest: { bundles: [{ name: "ui", assets: { logo: "logo.png" } }] }, * typeFilePath: "./src/pixi-vn.keys.gen.ts", * }) * ``` */ assetsManifest?: AssetsManifestOption; } /** * Creates a Vite plugin for Pixi'VN integration. * * **Static content loading** * * When {@link VitePluginPixivnOptions.content}, {@link VitePluginPixivnOptions.characters}, or * {@link VitePluginPixivnOptions.labels} are provided, the matched files are executed server-side * via Vite SSR at startup, populating `RegisteredCharacters`, `RegisteredLabels`, and any other * singletons before downstream plugins (such as `vitePluginInk`) run — including during * `vite build`. * * **Auto-generated type file** * * When {@link VitePluginPixivnOptions.typeFilePath} is provided, the plugin writes a * TypeScript declaration file that augments `PixivnCharacterIds` in `@drincs/pixi-vn/characters` * and `PixivnLabelIds` in `@drincs/pixi-vn/narration` with all currently known IDs. * This narrows `CharacterIdType` and `LabelIdType` from `string` to unions of known literals, * giving compile-time safety for character lookups, `narration.call`, `narration.jump`, etc. * * The file is regenerated whenever the character or label set changes (content reload or * external-label updates). It is **excluded from HMR** so regenerating it never triggers a page reload. * * **Auto-generated list file** * * When {@link VitePluginPixivnOptions.listFilePath} is provided, the plugin writes a * TypeScript file that exports runtime `as const` arrays of all currently known IDs: * `characterIds` and `labelIds`. These arrays can be used for runtime validation * (e.g. `z.enum(characterIds)`) and are regenerated on the same triggers as the type file. * * **Asset bundles / aliases** * * When a PIXI.js `AssetsManifest` is registered — via {@link VitePluginPixivnOptions.assetsManifest} * or, for manifests produced by an async asset pipeline, `api.setAssetsManifest(manifest)` — the * same {@link VitePluginPixivnOptions.typeFilePath} also gets `export const bundleIds` / * `export const assetAliasIds` (`as const` arrays) plus `declare module` augmentations for * `PixivnBundleIds` / `PixivnAssetAliasIds` in `@drincs/pixi-vn/canvas` — narrowing that module's * `BundleIdType` / `AssetAliasIdType` from `string` to unions of known literals, exactly like * `PixivnCharacterIds` / `PixivnLabelIds` narrow `CharacterIdType` / `LabelIdType` above. The * manifest also immediately backs the `GET /__pixi-vn/assets/manifest` endpoint below. * * **External label providers** * * Other Vite plugins can inject label IDs via the plugin API without needing to register * them through SSR-loaded modules: * - `api.setExternalLabels(providerId, labels)` — registers (or replaces) the label list for * the given provider and regenerates the type file. * - `api.clearExternalLabels(providerId)` — removes all labels for the given provider and * regenerates the type file. * * **Dev-server HTTP endpoints** * * - `GET /__pixi-vn/characters` — retrieve registered characters * - `POST /__pixi-vn/characters` — *(deprecated)* update from client; use the `characters` option instead * - `GET /__pixi-vn/labels` — retrieve narration labels * - `POST /__pixi-vn/labels` — *(deprecated)* update from client; use the `labels` / `content` option instead * - `GET /__pixi-vn/assets/manifest` — retrieve PIXI assets manifest (immediately available * when the `assetsManifest` option is set or `api.setAssetsManifest` has been called; otherwise * 404 until a client `POST`) * - `POST /__pixi-vn/assets/manifest` — *(deprecated)* update from client; use the * `assetsManifest` option instead * - `GET /__pixi-vn/canvas-options` — retrieve canvas rendering options * - `POST /__pixi-vn/canvas-options` — update canvas options from client * * **Plugin API** (consumed by `vitePluginInk`): * - `api.contentLoaded` — `Promise` that resolves once all content modules have finished * loading. Await this before generating JSON files. * - `api.characters` — the list of registered characters (populated after `contentLoaded`). * - `api.onReload(cb)` — register a callback that fires after every hot-content-reload. * - `api.setExternalLabels(providerId, labels)` — add/replace labels from an external provider. * - `api.clearExternalLabels(providerId)` — remove labels previously set for a provider. * - `api.setAssetsManifest(manifest)` — register/replace the assets manifest after * plugin-creation time (e.g. once an async asset pipeline finishes); see * {@link VitePluginPixivnOptions.assetsManifest}. * * @example * ```ts * // vite.config.ts * import { defineConfig } from "vite"; * import { vitePluginPixivn } from "@drincs/pixi-vn/vite"; * * export default defineConfig({ * plugins: [ * vitePluginPixivn({ * content: "./src/content/index.ts", * typeFilePath: "./src/pixi-vn.gen.d.ts", * }), * ], * }); * ``` * * @param options - Optional plugin configuration. * @returns A Vite plugin. */ declare function vitePluginPixivn(options?: VitePluginPixivnOptions): Plugin; export { PIXIVN_DEV_API_ASSETS_MANIFEST, PIXIVN_DEV_API_CANVAS_OPTIONS, PIXIVN_DEV_API_CHARACTERS, PIXIVN_DEV_API_LABELS, type VitePluginPixivnOptions, vitePluginPixivn };