@drincs/nqtr
Version:
A complete system introducing the concepts of location, time and event, producing the framework of a not-quite-point-and-click adventure game.
161 lines (158 loc) • 5.38 kB
text/typescript
import { Plugin } from 'vite';
/**
* Options for {@link vitePluginNqtr}.
*/
interface VitePluginNqtrOptions {
/**
* Glob / path of module(s) whose side effects register activities via
* `RegisteredActivities.add(...)`.
*
* @example "./src/activities.ts"
* @example "./src/activities/*.ts"
*/
activities?: string | string[];
/**
* Glob / path of module(s) whose side effects register commitments via
* `RegisteredCommitments.add(...)`.
*
* @example "./src/commitments.ts"
*/
commitments?: string | string[];
/**
* Glob / path of module(s) whose side effects register locations via
* `RegisteredLocations.add(...)`.
*
* @example "./src/locations.ts"
*/
locations?: string | string[];
/**
* Glob / path of module(s) whose side effects register maps via
* `RegisteredMaps.add(...)`.
*
* @example "./src/maps.ts"
*/
maps?: string | string[];
/**
* Glob / path of module(s) whose side effects register quests via
* `RegisteredQuests.add(...)`.
*
* @example "./src/quests.ts"
* @example "./src/*.quest.ts"
*/
quests?: string | string[];
/**
* Glob / path of module(s) whose side effects register rooms via
* `RegisteredRooms.add(...)`.
*
* @example "./src/rooms.ts"
*/
rooms?: string | string[];
/**
* Path to the auto-generated TypeScript file that contains both:
* - `as const` runtime arrays of all currently known entity IDs
* (e.g. `nqtrActivityIds`, `nqtrRoomIds`, …) — import these into
* {@link createNqtrHandler} for runtime validation of Ink hashtag commands.
* - a `declare module` augmentation of the six `Nqtr*Ids` interfaces in
* `@drincs/nqtr/registries` — gives compile-time–safe ID types once the
* file is included in the project's TypeScript compilation.
*
* 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.
*
* The generated file is **excluded from HMR** so that regenerating it
* never triggers a full-page reload.
*
* The path may be absolute or relative to Vite `root`.
*
* @example "./src/nqtr.keys.gen.ts"
*/
typeFilePath?: string;
}
/**
* Creates a Vite plugin that generates TypeScript declaration files with
* compile-time–safe ID types for all six NQTR entity registries:
* activities, commitments, locations, maps, quests, and rooms.
*
* ---
*
* **How it works**
*
* At startup (and after every hot-module reload), the plugin executes the
* content modules listed in the options server-side via Vite SSR. Those
* modules register entities by calling `RegisteredActivities.add(...)`,
* `RegisteredRooms.add(...)`, etc. The plugin then reads back the IDs from
* all six registries and writes a `.d.ts` declaration file that augments the
* `Nqtr*Ids` interfaces in `@drincs/nqtr/registries`.
*
* ---
*
* **Pixi-VN integration**
*
* If `vitePluginPixivn` (from `@drincs/pixi-vn/vite`) is present in the same
* Vite config, this plugin automatically waits for its `contentLoaded`
* signal before reading registry state. This means you can pass a single
* `content` barrel file to `vitePluginPixivn` and have both plugins read from
* it without duplicating the option:
*
* ```ts
* // vite.config.ts
* import { vitePluginPixivn } from "@drincs/pixi-vn/vite";
* import { vitePluginNqtr } from "@drincs/nqtr/vite";
*
* export default defineConfig({
* plugins: [
* vitePluginPixivn({ content: "./src/content/index.ts" }),
* vitePluginNqtr({ typeFilePath: "./src/nqtr.keys.gen.ts" }),
* ],
* });
* ```
*
* The nqtr plugin will piggy-back on pixi-vn's content loading and re-run
* type generation on every hot-reload triggered by the pixi-vn plugin.
*
* ---
*
* **Standalone usage** (without pixi-vn)
*
* Target specific entity files directly:
*
* ```ts
* vitePluginNqtr({
* activities: "./src/activities/*.ts",
* rooms: "./src/rooms.ts",
* locations: "./src/locations.ts",
* maps: "./src/maps.ts",
* typeFilePath: "./src/nqtr.keys.gen.ts",
* })
* ```
*
* ---
*
* **Generated file**
*
* The file written to {@link VitePluginNqtrOptions.typeFilePath} looks like:
*
* ```ts
* // nqtr.keys.gen.ts — auto-generated, do not edit manually
* export const nqtrActivityIds = ["study", "cook"] as const;
* export const nqtrRoomIds = ["bedroom", "kitchen"] as const;
* // …
*
* declare module "@drincs/nqtr/registries" {
* interface NqtrActivityIds { "study": never; "cook": never; }
* interface NqtrRoomIds { "bedroom": never; "kitchen": never; }
* // …
* }
* ```
*
* The `as const` arrays can be passed to {@link createNqtrHandler} for runtime
* validation of Ink hashtag commands. The `declare module` augmentation narrows
* the `*IdType` helpers (`ActivityIdType`, `RoomIdType`, …) from `string` to
* the union of known literal IDs at compile time.
*
* @param options - Optional plugin configuration.
* @returns A Vite plugin.
*/
declare function vitePluginNqtr(options?: VitePluginNqtrOptions): Plugin;
export { type VitePluginNqtrOptions, vitePluginNqtr };