aispritejs 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/sprite/errors.ts","../../src/sprite/compile.ts","../../src/sprite/emitter.ts","../../src/sprite/inputs.ts","../../src/sprite/machine.ts","../../src/pixi/animator.ts"],"names":["v"],"mappings":"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","file":"index.js","sourcesContent":["// aispritejs — named error classes. Named errors instead of bare throws let\n// callers branch on failure mode (e.g. distinguish a typo'd input from a\n// post-dispose call) and keep stack traces meaningful.\n\n/**\n * Thrown by `setInput` / `fireTrigger` / `update` / `reset` after the animator\n * has been disposed.\n *\n * @public\n */\nexport class SpriteAnimatorDisposedError extends Error {\n constructor() {\n super(\"aispritejs: animator has been disposed; this operation is not allowed\");\n this.name = \"SpriteAnimatorDisposedError\";\n }\n}\n\n/**\n * Thrown by `createSpriteAnimator` when the graph fails validation — a state\n * references a missing animation, a transition points at an unknown state, a\n * condition uses an operator the input kind does not support, a duration is\n * non-positive, and so on. Fail-fast: an invalid graph never produces a\n * half-built animator.\n *\n * @public\n */\nexport class InvalidGraphError extends Error {\n constructor(message: string) {\n super(`aispritejs: invalid graph — ${message}`);\n this.name = \"InvalidGraphError\";\n }\n}\n\n/**\n * Thrown by `setInput` / `fireTrigger` when the named input is not declared in\n * the graph's `inputs` block.\n *\n * @public\n */\nexport class UnknownInputError extends Error {\n readonly input: string;\n constructor(input: string) {\n super(`aispritejs: unknown input \"${input}\"; declare it in the graph's inputs block`);\n this.name = \"UnknownInputError\";\n this.input = input;\n }\n}\n\n/**\n * Thrown when an input is used against its kind — `setInput` with the wrong\n * value type, `setInput` on a Trigger, or `fireTrigger` on a non-Trigger.\n *\n * @public\n */\nexport class InputTypeError extends Error {\n readonly input: string;\n constructor(input: string, message: string) {\n super(`aispritejs: input \"${input}\" — ${message}`);\n this.name = \"InputTypeError\";\n this.input = input;\n }\n}\n","// aispritejs — graph compiler. Validates every cross-reference the type system\n// cannot (animation existence, transition targets, operator/kind compatibility,\n// positive durations) and normalises the graph into a precomputed runtime form:\n// per-state cumulative frame timings and per-state transition candidate lists\n// sorted by (priority desc, declared-order asc). All allocation happens here,\n// once, so `update()` stays allocation-free.\n\nimport { InvalidGraphError } from \"./errors.js\";\nimport type { InputStore } from \"./inputs.js\";\nimport type { SpriteGraph } from \"./types.js\";\n\n/** A compiled condition: a closure that reads the live store and returns a boolean. */\nexport type ConditionFn = (store: InputStore) => boolean;\n\nexport interface CompiledTransition {\n readonly from: string;\n readonly to: string;\n readonly priority: number;\n /** Declared index — the deterministic tie-break when priorities are equal. */\n readonly order: number;\n /** AND-ed at runtime; empty means \"matches unconditionally\". */\n readonly conditions: readonly ConditionFn[];\n /** Trigger input names this transition consumes when taken. */\n readonly triggers: readonly string[];\n}\n\nexport interface CompiledState {\n readonly name: string;\n readonly animation: string;\n readonly loop: boolean;\n readonly speed: number;\n readonly onEnd: string | undefined;\n readonly frameKeys: readonly string[];\n /** `cumulative[i]` = summed duration of frames `0..i`; last entry === `total`. */\n readonly cumulative: readonly number[];\n readonly total: number;\n}\n\nexport interface CompiledGraph {\n readonly initial: string;\n readonly states: ReadonlyMap<string, CompiledState>;\n readonly candidatesByState: ReadonlyMap<string, readonly CompiledTransition[]>;\n}\n\nconst DEFAULT_FRAME_DURATION = 100;\n\nexport function compileGraph(graph: SpriteGraph): CompiledGraph {\n const stateEntries = Object.entries(graph.states);\n if (stateEntries.length === 0) {\n throw new InvalidGraphError(\"states must declare at least one state\");\n }\n\n // Inputs: types are enforced by TS, but a graph loaded from untyped JSON can\n // still carry a bad `type`. Validate so a bad input fails here, not silently.\n for (const [name, def] of Object.entries(graph.inputs)) {\n if (def.type !== \"number\" && def.type !== \"boolean\" && def.type !== \"trigger\") {\n throw new InvalidGraphError(\n `input \"${name}\" has unknown type \"${(def as { type: string }).type}\"`,\n );\n }\n }\n\n const defaultDuration = graph.defaultFrameDuration ?? DEFAULT_FRAME_DURATION;\n if (!(defaultDuration > 0)) {\n throw new InvalidGraphError(`defaultFrameDuration must be > 0, got ${defaultDuration}`);\n }\n\n if (graph.frames) {\n for (const [key, timing] of Object.entries(graph.frames)) {\n if (timing.duration !== undefined && !(timing.duration > 0)) {\n throw new InvalidGraphError(`frame \"${key}\" duration must be > 0, got ${timing.duration}`);\n }\n }\n }\n\n const initial = graph.initial ?? stateEntries[0]![0];\n if (!(initial in graph.states)) {\n throw new InvalidGraphError(`initial state \"${initial}\" is not declared`);\n }\n\n // --- compile states -----------------------------------------------------\n const states = new Map<string, CompiledState>();\n for (const [name, st] of stateEntries) {\n const frameKeys = graph.animations[st.animation];\n if (frameKeys === undefined) {\n throw new InvalidGraphError(`state \"${name}\" references unknown animation \"${st.animation}\"`);\n }\n if (frameKeys.length === 0) {\n throw new InvalidGraphError(`animation \"${st.animation}\" (state \"${name}\") has no frames`);\n }\n const speed = st.speed ?? 1;\n if (!(speed > 0)) {\n throw new InvalidGraphError(`state \"${name}\" speed must be > 0, got ${speed}`);\n }\n const loop = st.loop === true;\n if (loop && st.onEnd !== undefined) {\n throw new InvalidGraphError(\n `state \"${name}\" loops, so onEnd \"${st.onEnd}\" would never fire; set loop:false or drop onEnd`,\n );\n }\n if (st.onEnd !== undefined && !(st.onEnd in graph.states)) {\n throw new InvalidGraphError(`state \"${name}\" onEnd target \"${st.onEnd}\" is not declared`);\n }\n\n const cumulative: number[] = [];\n let running = 0;\n for (const key of frameKeys) {\n running += graph.frames?.[key]?.duration ?? defaultDuration;\n cumulative.push(running);\n }\n\n states.set(name, {\n name,\n animation: st.animation,\n loop,\n speed,\n onEnd: st.onEnd,\n frameKeys,\n cumulative,\n total: running,\n });\n }\n\n // --- compile transitions ------------------------------------------------\n const compiled: CompiledTransition[] = [];\n graph.transitions.forEach((t, order) => {\n if (t.from !== \"*\" && !(t.from in graph.states)) {\n throw new InvalidGraphError(`transition #${order} from \"${t.from}\" is not a declared state`);\n }\n if (!(t.to in graph.states)) {\n throw new InvalidGraphError(`transition #${order} to \"${t.to}\" is not a declared state`);\n }\n\n const conditions: ConditionFn[] = [];\n const triggers: string[] = [];\n for (const c of t.when ?? []) {\n const def = graph.inputs[c.input];\n if (def === undefined) {\n throw new InvalidGraphError(\n `transition #${order} condition references unknown input \"${c.input}\"`,\n );\n }\n compileCondition(order, c.input, c.op, c.value, def.type, conditions, triggers);\n }\n\n compiled.push({\n from: t.from,\n to: t.to,\n priority: t.priority ?? 0,\n order,\n conditions,\n triggers,\n });\n });\n\n // --- group candidates per state (own + Any-State), sorted ---------------\n const candidatesByState = new Map<string, readonly CompiledTransition[]>();\n for (const [name] of stateEntries) {\n const list = compiled.filter((t) => t.from === name || t.from === \"*\");\n // Stable by construction (declared order), but make the tie-break explicit.\n list.sort((a, b) => b.priority - a.priority || a.order - b.order);\n candidatesByState.set(name, list);\n }\n\n return { initial, states, candidatesByState };\n}\n\nfunction compileCondition(\n order: number,\n input: string,\n op: string,\n value: number | boolean | undefined,\n kind: \"number\" | \"boolean\" | \"trigger\",\n out: ConditionFn[],\n triggers: string[],\n): void {\n switch (op) {\n case \"Trigger\": {\n if (kind !== \"trigger\") {\n throw new InvalidGraphError(\n `transition #${order}: op Trigger requires a trigger input, but \"${input}\" is ${kind}`,\n );\n }\n if (value !== undefined) {\n throw new InvalidGraphError(\n `transition #${order}: Trigger condition on \"${input}\" must not carry a value`,\n );\n }\n out.push((s) => s.isPending(input));\n triggers.push(input);\n return;\n }\n case \"GreaterThan\":\n case \"LessThan\": {\n if (kind !== \"number\") {\n throw new InvalidGraphError(\n `transition #${order}: op ${op} requires a number input, but \"${input}\" is ${kind}`,\n );\n }\n if (typeof value !== \"number\") {\n throw new InvalidGraphError(\n `transition #${order}: op ${op} on \"${input}\" needs a numeric value`,\n );\n }\n const v = value;\n out.push(\n op === \"GreaterThan\" ? (s) => s.readNumber(input) > v : (s) => s.readNumber(input) < v,\n );\n return;\n }\n case \"Equals\":\n case \"NotEquals\": {\n if (kind === \"trigger\") {\n throw new InvalidGraphError(\n `transition #${order}: op ${op} cannot apply to trigger input \"${input}\"`,\n );\n }\n if (kind === \"number\") {\n if (typeof value !== \"number\") {\n throw new InvalidGraphError(\n `transition #${order}: op ${op} on number input \"${input}\" needs a numeric value`,\n );\n }\n const v = value;\n out.push(\n op === \"Equals\" ? (s) => s.readNumber(input) === v : (s) => s.readNumber(input) !== v,\n );\n return;\n }\n // kind === \"boolean\"\n if (typeof value !== \"boolean\") {\n throw new InvalidGraphError(\n `transition #${order}: op ${op} on boolean input \"${input}\" needs a boolean value`,\n );\n }\n const v = value;\n out.push(\n op === \"Equals\" ? (s) => s.readBoolean(input) === v : (s) => s.readBoolean(input) !== v,\n );\n return;\n }\n default:\n throw new InvalidGraphError(`transition #${order}: unknown operator \"${op}\"`);\n }\n}\n","// aispritejs — a tiny single-payload typed signal. This is the package's OWN\n// emitter; it deliberately does NOT import `aieventjs` or any sibling (P0\n// zero-cross-package rule). Two instances back `onStateChange` and\n// `onComplete`.\n\nimport type { ListenerOptions, Unsubscribe } from \"./types.js\";\n\n/**\n * A typed fan-out of one payload `P`. `emit` is allocation-free in the common\n * case; it snapshots listeners only when there is at least one, so a handler\n * that unsubscribes (or a `once` handler) cannot corrupt the in-flight\n * iteration.\n */\nexport interface Signal<P> {\n on(handler: (payload: P) => void, options?: ListenerOptions): Unsubscribe;\n emit(payload: P): void;\n /** Drop every listener (used by `dispose`). */\n clear(): void;\n}\n\nexport function createSignal<P>(): Signal<P> {\n const listeners = new Set<(payload: P) => void>();\n\n function on(handler: (payload: P) => void, options?: ListenerOptions): Unsubscribe {\n // An already-aborted signal means the listener is dead on arrival.\n if (options?.signal?.aborted) return () => {};\n\n let detachAbort: (() => void) | undefined;\n // One teardown shared by the unsubscribe return, the once-wrapper, and the\n // abort handler, so every path also detaches the abort listener — a `once`\n // handler that passed a `{ signal }` must not leave the abort listener\n // attached after it fires.\n const cleanup: Unsubscribe = () => {\n listeners.delete(wrapped);\n if (detachAbort) {\n detachAbort();\n detachAbort = undefined;\n }\n };\n\n let wrapped: (payload: P) => void = handler;\n if (options?.once) {\n wrapped = (payload) => {\n cleanup();\n handler(payload);\n };\n }\n listeners.add(wrapped);\n\n const sig = options?.signal;\n if (sig) {\n const onAbort = () => cleanup();\n sig.addEventListener(\"abort\", onAbort, { once: true });\n detachAbort = () => sig.removeEventListener(\"abort\", onAbort);\n }\n\n return cleanup;\n }\n\n function emit(payload: P): void {\n if (listeners.size === 0) return;\n // Snapshot so a handler that unsubscribes (including the once-wrapper)\n // during dispatch does not perturb this pass.\n for (const fn of [...listeners]) fn(payload);\n }\n\n function clear(): void {\n listeners.clear();\n }\n\n return { on, emit, clear };\n}\n","// aispritejs — the input store. Holds Number / Boolean values and Trigger\n// pending flags with O(1) lookup. All declared inputs are seeded at\n// construction so reads are total (the compiler guarantees every condition\n// references a declared input of the matching kind, so the non-null reads\n// below are sound).\n\nimport { InputTypeError, UnknownInputError } from \"./errors.js\";\nimport type { InputDef } from \"./types.js\";\n\nexport interface InputStore {\n /** Set a Number/Boolean input. Throws on unknown name or kind mismatch. */\n setInput(name: string, value: number | boolean): void;\n /** Mark a Trigger pending. Throws on unknown name or non-Trigger. */\n fireTrigger(name: string): void;\n /** Read a Number input (caller guarantees `name` is a declared Number). */\n readNumber(name: string): number;\n /** Read a Boolean input (caller guarantees `name` is a declared Boolean). */\n readBoolean(name: string): boolean;\n /** Whether a Trigger is currently pending. */\n isPending(name: string): boolean;\n /** Consume (reset) a pending Trigger after a transition takes it. */\n consume(name: string): void;\n /** Restore every input to its declared default and clear all triggers. */\n reset(): void;\n}\n\ntype Kind = \"number\" | \"boolean\" | \"trigger\";\n\nexport function createInputStore(inputs: Readonly<Record<string, InputDef>>): InputStore {\n const kinds = new Map<string, Kind>();\n const numberDefaults = new Map<string, number>();\n const booleanDefaults = new Map<string, boolean>();\n const numbers = new Map<string, number>();\n const booleans = new Map<string, boolean>();\n const triggers = new Map<string, boolean>();\n\n for (const [name, def] of Object.entries(inputs)) {\n kinds.set(name, def.type);\n if (def.type === \"number\") {\n const d = def.default ?? 0;\n numberDefaults.set(name, d);\n numbers.set(name, d);\n } else if (def.type === \"boolean\") {\n const d = def.default ?? false;\n booleanDefaults.set(name, d);\n booleans.set(name, d);\n } else {\n triggers.set(name, false);\n }\n }\n\n function setInput(name: string, value: number | boolean): void {\n const kind = kinds.get(name);\n if (kind === undefined) throw new UnknownInputError(name);\n if (kind === \"trigger\") {\n throw new InputTypeError(name, \"is a Trigger; use fireTrigger()\");\n }\n if (kind === \"number\") {\n if (typeof value !== \"number\") {\n throw new InputTypeError(name, `expects a number, received ${typeof value}`);\n }\n if (Number.isNaN(value)) {\n throw new InputTypeError(name, \"cannot be set to NaN\");\n }\n numbers.set(name, value);\n return;\n }\n // kind === \"boolean\"\n if (typeof value !== \"boolean\") {\n throw new InputTypeError(name, `expects a boolean, received ${typeof value}`);\n }\n booleans.set(name, value);\n }\n\n function fireTrigger(name: string): void {\n const kind = kinds.get(name);\n if (kind === undefined) throw new UnknownInputError(name);\n if (kind !== \"trigger\") {\n throw new InputTypeError(name, \"is not a Trigger; use setInput()\");\n }\n triggers.set(name, true);\n }\n\n return {\n setInput,\n fireTrigger,\n // `!` is sound: every declared input is seeded at construction and the\n // compiler validates that conditions only read declared inputs of the\n // matching kind, so these reads always hit a present entry.\n readNumber: (name) => numbers.get(name)!,\n readBoolean: (name) => booleans.get(name)!,\n isPending: (name) => triggers.get(name) === true,\n consume: (name) => {\n triggers.set(name, false);\n },\n reset: () => {\n for (const [name, d] of numberDefaults) numbers.set(name, d);\n for (const [name, d] of booleanDefaults) booleans.set(name, d);\n for (const name of triggers.keys()) triggers.set(name, false);\n },\n };\n}\n","// aispritejs — the input-driven visual state machine (the \"RiveSpriteStateMachine\"\n// engine), exposed only through the `createSpriteAnimator` factory. Implemented\n// as closures, not a class, so methods never depend on `this` and the\n// constructor surface stays hidden (family convention: public API = createX).\n//\n// Determinism: the only state advanced by `update` is `elapsed` (by `dt * speed`)\n// plus the input store; transitions are resolved over precomputed, deterministically\n// ordered candidate lists. Identical input + dt sequences therefore yield identical\n// frame sequences. The no-transition path allocates nothing.\n\nimport { type CompiledState, compileGraph } from \"./compile.js\";\nimport { createSignal } from \"./emitter.js\";\nimport { SpriteAnimatorDisposedError } from \"./errors.js\";\nimport { createInputStore } from \"./inputs.js\";\nimport type {\n CompleteHandler,\n ListenerOptions,\n SpriteAnimator,\n SpriteGraph,\n StateChangeHandler,\n Unsubscribe,\n} from \"./types.js\";\n\ninterface StateChangePayload {\n readonly to: string;\n readonly from: string;\n}\n\nconst NO_TRIGGERS: readonly string[] = [];\n\n/**\n * Build a renderer-agnostic visual animator from an input-driven graph.\n *\n * @param graph - inputs, states, transitions, animations (+ optional per-frame\n * timings). Validated eagerly; an invalid graph throws {@link InvalidGraphError}\n * and no animator is returned.\n * @returns a {@link SpriteAnimator}.\n *\n * @public\n */\nexport function createSpriteAnimator(graph: SpriteGraph): SpriteAnimator {\n const compiled = compileGraph(graph);\n const store = createInputStore(graph.inputs);\n const stateChange = createSignal<StateChangePayload>();\n const complete = createSignal<string>();\n\n let current: CompiledState = mustState(compiled.initial);\n let elapsed = 0;\n let completed = false;\n let activeFrameIndex = 0;\n // Every compiled state has >= 1 frame (validated), so frame 0 always exists.\n let activeFrameKey: string = current.frameKeys[0]!;\n let disposed = false;\n\n // `name` is always an initial / transition `to` / `onEnd` target, all\n // validated to exist by compileGraph, so the lookup never misses.\n function mustState(name: string): CompiledState {\n return compiled.states.get(name)!;\n }\n\n /** Enter `to`, optionally consuming the triggers the taking transition used. */\n function enter(to: string, consume: readonly string[]): void {\n const from = current.name;\n for (let i = 0; i < consume.length; i++) {\n store.consume(consume[i]!);\n }\n current = mustState(to);\n elapsed = 0;\n completed = false;\n activeFrameIndex = 0;\n activeFrameKey = current.frameKeys[0]!;\n // A self-re-entry (to === from) restarts the clip but is not a state change.\n if (to !== from) stateChange.emit({ to, from });\n }\n\n /**\n * First *effective* transition leaving `current` (own + Any-State), in\n * (priority desc, declared order) — or `undefined`. A transition whose target\n * equals the current state is effective only if it consumes a Trigger (a\n * Number/Boolean self-loop would otherwise restart the clip every frame).\n */\n function resolve(): { to: string; triggers: readonly string[] } | undefined {\n // Every state has a candidate list (built for all states by compileGraph).\n const list = compiled.candidatesByState.get(current.name)!;\n for (let i = 0; i < list.length; i++) {\n const t = list[i]!;\n let ok = true;\n const conds = t.conditions;\n for (let j = 0; j < conds.length; j++) {\n if (!conds[j]!(store)) {\n ok = false;\n break;\n }\n }\n if (!ok) continue;\n if (t.to === current.name && t.triggers.length === 0) continue;\n return { to: t.to, triggers: t.triggers };\n }\n return undefined;\n }\n\n function update(deltaMs: number): void {\n if (disposed) throw new SpriteAnimatorDisposedError();\n\n // Advance the playback timer (negative dt clamped to 0 for determinism).\n elapsed += (deltaMs > 0 ? deltaMs : 0) * current.speed;\n\n // Evaluate input-driven transitions first; an explicit transition wins over\n // implicit end-of-clip behaviour.\n const chosen = resolve();\n if (chosen) {\n enter(chosen.to, chosen.triggers);\n return;\n }\n\n // Compute the active frame from accumulated time vs cumulative durations.\n const cs = current;\n const n = cs.frameKeys.length;\n let ended = false;\n if (!cs.loop && elapsed >= cs.total) {\n activeFrameIndex = n - 1;\n ended = true;\n } else {\n const t = cs.loop ? elapsed % cs.total : elapsed;\n let i = 0;\n // First index whose cumulative end exceeds t (i < n-1 keeps it in range,\n // and t < total guarantees a match no later than the last frame).\n while (i < n - 1 && t >= cs.cumulative[i]!) i++;\n activeFrameIndex = i;\n }\n activeFrameKey = cs.frameKeys[activeFrameIndex]!;\n\n // Fire onComplete once for a finished non-looping clip, then auto-transition.\n if (ended && !completed) {\n completed = true;\n complete.emit(cs.name);\n if (cs.onEnd !== undefined) enter(cs.onEnd, NO_TRIGGERS);\n }\n }\n\n function reset(): void {\n if (disposed) throw new SpriteAnimatorDisposedError();\n const from = current.name;\n store.reset();\n current = mustState(compiled.initial);\n elapsed = 0;\n completed = false;\n activeFrameIndex = 0;\n activeFrameKey = current.frameKeys[0]!;\n if (from !== compiled.initial) stateChange.emit({ to: compiled.initial, from });\n }\n\n function dispose(): void {\n if (disposed) return;\n disposed = true;\n stateChange.clear();\n complete.clear();\n }\n\n return {\n setInput(name, value) {\n if (disposed) throw new SpriteAnimatorDisposedError();\n store.setInput(name, value);\n },\n fireTrigger(name) {\n if (disposed) throw new SpriteAnimatorDisposedError();\n store.fireTrigger(name);\n },\n update,\n reset,\n dispose,\n onStateChange(handler: StateChangeHandler, options?: ListenerOptions): Unsubscribe {\n if (disposed) return () => {};\n return stateChange.on((p) => handler(p.to, p.from), options);\n },\n onComplete(handler: CompleteHandler, options?: ListenerOptions): Unsubscribe {\n if (disposed) return () => {};\n return complete.on(handler, options);\n },\n get activeState() {\n return current.name;\n },\n get activeFrameKey() {\n return activeFrameKey;\n },\n get activeFrameIndex() {\n return activeFrameIndex;\n },\n get disposed() {\n return disposed;\n },\n };\n}\n","// aispritejs/pixi — the PixiJS v8 renderer adapter. It binds the\n// renderer-agnostic core to a `PIXI.Sprite`: on each update it swaps the\n// sprite's texture to the core's active frame and (by default) applies that\n// frame's atlas anchor.\n//\n// `pixi.js` is imported **type-only**, so the built subpath contains no runtime\n// `pixi.js` require — the peer is needed only by the consumer who passes real\n// Sprite / Spritesheet instances. `pixi.js` is declared as an OPTIONAL\n// peerDependency; the core (`aispritejs`) never imports this module.\n\nimport type { Sprite, Spritesheet, Texture } from \"pixi.js\";\nimport { type SpriteGraph, createSpriteAnimator } from \"../sprite/index.js\";\n\n/**\n * Thrown by {@link createPixiSpriteAnimator} when the supplied textures are\n * missing one or more frame keys the graph's animations reference. Fail-fast at\n * construction, so `update()` never has to guard.\n *\n * @public\n */\nexport class MissingTextureError extends Error {\n readonly keys: readonly string[];\n constructor(keys: readonly string[]) {\n super(`aispritejs/pixi: no texture for frame key(s): ${keys.join(\", \")}`);\n this.name = \"MissingTextureError\";\n this.keys = keys;\n }\n}\n\n/** Frame-key → texture lookup. A PixiJS `Spritesheet` exposes one as `.textures`. */\nexport type TextureMap = Record<string, Texture>;\n\n/**\n * Options for {@link createPixiSpriteAnimator}.\n *\n * @public\n */\nexport interface PixiSpriteAnimatorOptions {\n /**\n * Apply each frame's atlas anchor (`texture.defaultAnchor`) to the sprite when\n * the frame changes — preserving non-centre / foot pivots. Default `true`.\n * Set `false` to manage the anchor yourself.\n */\n readonly applyAnchor?: boolean;\n}\n\n/**\n * A PixiJS-bound animator: the core machine plus a sprite whose texture tracks\n * the active frame.\n *\n * @public\n */\nexport interface PixiSpriteAnimator {\n /** The bound sprite, updated in place. */\n readonly sprite: Sprite;\n /** Run the core machine for `deltaMs`, then sync the sprite's texture. */\n update(deltaMs: number): void;\n /** Set a Number / Boolean input on the core machine. */\n setInput(name: string, value: number | boolean): void;\n /** Fire a Trigger on the core machine. */\n fireTrigger(name: string): void;\n /** Reset the core machine and re-sync the sprite. */\n reset(): void;\n /** Dispose the core machine. Idempotent. Does not destroy the sprite. */\n dispose(): void;\n /** Current state name. */\n readonly activeState: string;\n /** Current frame key. */\n readonly activeFrameKey: string;\n /** `true` once disposed. */\n readonly disposed: boolean;\n}\n\nfunction toTextureMap(src: Spritesheet | TextureMap): TextureMap {\n // A Spritesheet exposes its frame textures under `.textures`; a plain map is\n // used directly. (If you have a frame literally named \"textures\", pass\n // `spritesheet.textures` instead of the spritesheet.)\n const maybe = src as { textures?: unknown };\n if (maybe.textures && typeof maybe.textures === \"object\") {\n return maybe.textures as TextureMap;\n }\n return src as TextureMap;\n}\n\n/**\n * Bind an input-driven {@link SpriteGraph} to a PixiJS `Sprite`.\n *\n * @param sprite - a plain `Sprite` to drive; its `texture` (and, by default,\n * `anchor`) are updated in place. The adapter owns frame selection, so if a\n * *playing* `AnimatedSprite` is passed (it extends `Sprite`), its internal\n * playback is stopped to stop it fighting the adapter for the texture.\n * @param graph - the input-driven graph (same shape the core consumes).\n * @param textures - a `Spritesheet` or a frame-key → `Texture` map covering\n * every frame the graph references.\n * @param options - see {@link PixiSpriteAnimatorOptions}.\n * @returns a {@link PixiSpriteAnimator}.\n * @throws {@link MissingTextureError} if a referenced frame key has no texture.\n * @throws {@link InvalidGraphError} if the graph is invalid.\n *\n * @public\n */\nexport function createPixiSpriteAnimator(\n sprite: Sprite,\n graph: SpriteGraph,\n textures: Spritesheet | TextureMap,\n options?: PixiSpriteAnimatorOptions,\n): PixiSpriteAnimator {\n const map = toTextureMap(textures);\n const applyAnchor = options?.applyAnchor !== false;\n\n // The adapter owns the sprite's texture/anchor. An AnimatedSprite (which\n // extends Sprite, so the type permits it) drives its own texture from an\n // internal ticker; if it is playing it would fight our frame swaps. Stop it.\n // Structural check — pixi.js is type-only here, so no `instanceof`.\n const playable = sprite as { stop?: () => void };\n if (typeof playable.stop === \"function\") playable.stop();\n\n // Fail-fast: every frame key reachable from the graph must have a texture.\n const missing = new Set<string>();\n for (const frameKeys of Object.values(graph.animations)) {\n for (const key of frameKeys) {\n if (!(key in map)) missing.add(key);\n }\n }\n if (missing.size > 0) throw new MissingTextureError([...missing]);\n\n const core = createSpriteAnimator(graph);\n\n // Swap the sprite's texture (and anchor) only when the active frame changes.\n let boundKey = \"\";\n function sync(): void {\n const key = core.activeFrameKey;\n if (key === boundKey) return;\n boundKey = key;\n const tex = map[key]!; // verified present above\n sprite.texture = tex;\n if (applyAnchor && tex.defaultAnchor) {\n sprite.anchor.set(tex.defaultAnchor.x, tex.defaultAnchor.y);\n }\n }\n sync(); // bind the initial frame before the first update\n\n return {\n sprite,\n update(deltaMs) {\n core.update(deltaMs);\n sync();\n },\n setInput(name, value) {\n core.setInput(name, value);\n },\n fireTrigger(name) {\n core.fireTrigger(name);\n },\n reset() {\n core.reset();\n sync();\n },\n dispose() {\n core.dispose();\n },\n get activeState() {\n return core.activeState;\n },\n get activeFrameKey() {\n return core.activeFrameKey;\n },\n get disposed() {\n return core.disposed;\n },\n };\n}\n"]}
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Declaration of a continuous **Number** input (e.g. `speed`). Read/written
3
+ * with {@link SpriteAnimator.setInput}.
4
+ *
5
+ * @public
6
+ */
7
+ interface NumberInputDef {
8
+ readonly type: "number";
9
+ /** Value before any `setInput`. Defaults to `0`. */
10
+ readonly default?: number;
11
+ }
12
+ /**
13
+ * Declaration of a toggle **Boolean** input (e.g. `isGrounded`). Read/written
14
+ * with {@link SpriteAnimator.setInput}.
15
+ *
16
+ * @public
17
+ */
18
+ interface BooleanInputDef {
19
+ readonly type: "boolean";
20
+ /** Value before any `setInput`. Defaults to `false`. */
21
+ readonly default?: boolean;
22
+ }
23
+ /**
24
+ * Declaration of a one-shot **Trigger** input (e.g. `jump`). Fired with
25
+ * {@link SpriteAnimator.fireTrigger}; auto-resets when a transition consumes
26
+ * it. A trigger has no stored value and no `default`.
27
+ *
28
+ * @public
29
+ */
30
+ interface TriggerInputDef {
31
+ readonly type: "trigger";
32
+ }
33
+ /**
34
+ * One of the three input kinds that drive the visual state machine.
35
+ *
36
+ * @public
37
+ */
38
+ type InputDef = NumberInputDef | BooleanInputDef | TriggerInputDef;
39
+ /**
40
+ * A visual state: which animation plays, whether it loops, how fast, and what
41
+ * to do when a non-looping clip ends.
42
+ *
43
+ * @public
44
+ */
45
+ interface StateDef {
46
+ /** Key into {@link SpriteGraph.animations}. Must reference a non-empty list. */
47
+ readonly animation: string;
48
+ /**
49
+ * `true` — the clip wraps forever; `onComplete` never fires for this state.
50
+ * `false` (default) — the clip plays once and holds the last frame, firing
51
+ * `onComplete` exactly once on the update that reaches the end.
52
+ */
53
+ readonly loop?: boolean;
54
+ /**
55
+ * Playback-speed multiplier applied as a time scale on `dt` (so `2` plays
56
+ * twice as fast, `0.5` half speed). Must be `> 0`. Defaults to `1`.
57
+ */
58
+ readonly speed?: number;
59
+ /**
60
+ * Optional state to auto-transition to when a **non-looping** clip ends —
61
+ * the visual equivalent of "attack → return to idle". Fires `onComplete`
62
+ * first, then switches (firing `onStateChange`). Must reference a declared
63
+ * state, and requires `loop` to be `false` (combining it with `loop:true` is
64
+ * rejected at load, since the clip would never end).
65
+ */
66
+ readonly onEnd?: string;
67
+ }
68
+ /**
69
+ * Comparison operator for a {@link TransitionCondition}.
70
+ *
71
+ * - `Equals` / `NotEquals` — Number or Boolean inputs.
72
+ * - `GreaterThan` / `LessThan` — Number inputs only.
73
+ * - `Trigger` — Trigger inputs only; satisfied while the trigger is pending,
74
+ * and **consumes** it when the owning transition is taken.
75
+ *
76
+ * @public
77
+ */
78
+ type ConditionOp = "Equals" | "NotEquals" | "GreaterThan" | "LessThan" | "Trigger";
79
+ /**
80
+ * A single check over one input. A {@link TransitionDef} fires only when all
81
+ * of its conditions hold (logical AND).
82
+ *
83
+ * @public
84
+ */
85
+ interface TransitionCondition {
86
+ /** Name of a declared input in {@link SpriteGraph.inputs}. */
87
+ readonly input: string;
88
+ /** The comparison; must be valid for the input's kind. */
89
+ readonly op: ConditionOp;
90
+ /**
91
+ * Right-hand operand for `Equals` / `NotEquals` / `GreaterThan` / `LessThan`.
92
+ * Its type must match the input kind (number for Number, boolean for
93
+ * Boolean). Omitted for `Trigger`.
94
+ */
95
+ readonly value?: number | boolean;
96
+ }
97
+ /**
98
+ * A directed edge in the transition graph: from one state (or **Any State**)
99
+ * to another when all conditions hold.
100
+ *
101
+ * @public
102
+ */
103
+ interface TransitionDef {
104
+ /**
105
+ * Source state name, or `"*"` for an **Any-State** transition that is
106
+ * evaluated from every state.
107
+ */
108
+ readonly from: string;
109
+ /** Target state name. Must reference a declared state. */
110
+ readonly to: string;
111
+ /**
112
+ * Conditions that must all hold (AND). An empty/omitted list matches
113
+ * unconditionally — rarely useful except with a `Trigger` elsewhere.
114
+ */
115
+ readonly when?: readonly TransitionCondition[];
116
+ /**
117
+ * Higher wins. Among satisfied transitions, the highest priority is taken;
118
+ * ties break by declared order (earliest first). An integer; defaults to `0`.
119
+ * (The JSON Schema constrains it to `integer`; TypeScript widens it to
120
+ * `number`.)
121
+ */
122
+ readonly priority?: number;
123
+ }
124
+ /**
125
+ * Per-frame timing read by the core. The full PixiJS-v8 atlas frame object
126
+ * (with `frame`, `anchor`, `sourceSize`, …) is assignable here — the core
127
+ * only ever reads `duration`.
128
+ *
129
+ * @public
130
+ */
131
+ interface FrameTiming {
132
+ /** Display time of this frame in milliseconds. Must be `> 0` if present. */
133
+ readonly duration?: number;
134
+ }
135
+ /**
136
+ * The complete input-driven control graph plus the frame data the core needs
137
+ * to compute timing. The `animations` / `frames` blocks mirror a PixiJS-v8
138
+ * spritesheet; `inputs` / `states` / `transitions` are `aispritejs`-specific.
139
+ *
140
+ * @public
141
+ */
142
+ interface SpriteGraph {
143
+ /** Animation name → ordered list of frame keys. Each list must be non-empty. */
144
+ readonly animations: Readonly<Record<string, readonly string[]>>;
145
+ /**
146
+ * Optional per-frame timing keyed by frame key. Frames absent here (or
147
+ * present without a `duration`) fall back to {@link SpriteGraph.defaultFrameDuration}.
148
+ */
149
+ readonly frames?: Readonly<Record<string, FrameTiming>>;
150
+ /** Input declarations keyed by input name. */
151
+ readonly inputs: Readonly<Record<string, InputDef>>;
152
+ /** State declarations keyed by state name. Must be non-empty. */
153
+ readonly states: Readonly<Record<string, StateDef>>;
154
+ /** Transition edges, evaluated every `update`. */
155
+ readonly transitions: readonly TransitionDef[];
156
+ /**
157
+ * Name of the starting state. Defaults to the first key of `states` in
158
+ * declaration order. Must reference a declared state.
159
+ */
160
+ readonly initial?: string;
161
+ /**
162
+ * Fallback frame duration (ms) for frames without explicit timing.
163
+ * Must be `> 0`. Defaults to `100`.
164
+ */
165
+ readonly defaultFrameDuration?: number;
166
+ }
167
+ /**
168
+ * Handler for {@link SpriteAnimator.onStateChange}. Called after the machine
169
+ * switches state, with the new and previous state names.
170
+ *
171
+ * @public
172
+ */
173
+ type StateChangeHandler = (to: string, from: string) => void;
174
+ /**
175
+ * Handler for {@link SpriteAnimator.onComplete}. Called once when a
176
+ * non-looping state's clip reaches its end, with that state's name.
177
+ *
178
+ * @public
179
+ */
180
+ type CompleteHandler = (state: string) => void;
181
+ /**
182
+ * Options shared by every `on...` subscription.
183
+ *
184
+ * @public
185
+ */
186
+ interface ListenerOptions {
187
+ /** Aborting this signal removes the listener. */
188
+ readonly signal?: AbortSignal;
189
+ /** Remove the listener automatically after its first call. */
190
+ readonly once?: boolean;
191
+ }
192
+ /**
193
+ * Returned by every `on...` subscription; call it to remove the listener.
194
+ * Idempotent.
195
+ *
196
+ * @public
197
+ */
198
+ type Unsubscribe = () => void;
199
+ /**
200
+ * The renderer-agnostic visual animator returned by `createSpriteAnimator`.
201
+ *
202
+ * Set inputs, call {@link SpriteAnimator.update} once per frame with the
203
+ * elapsed milliseconds, then read {@link SpriteAnimator.activeFrameKey} and
204
+ * hand it to a renderer adapter. The core never touches a canvas, the DOM, or
205
+ * PixiJS.
206
+ *
207
+ * @public
208
+ */
209
+ interface SpriteAnimator {
210
+ /**
211
+ * Set a Number or Boolean input. Throws {@link UnknownInputError} if the
212
+ * name is not declared and {@link InputTypeError} on a kind mismatch (or if
213
+ * the name is a Trigger — use {@link SpriteAnimator.fireTrigger}).
214
+ */
215
+ setInput(name: string, value: number | boolean): void;
216
+ /**
217
+ * Mark a Trigger pending. It stays pending until a transition that checks it
218
+ * is taken, which consumes it. Throws {@link UnknownInputError} /
219
+ * {@link InputTypeError} for an unknown or non-Trigger input.
220
+ */
221
+ fireTrigger(name: string): void;
222
+ /**
223
+ * Advance by `deltaMs` (clamped at `0`): evaluate transitions, recompute the
224
+ * active frame, and fire `onComplete` for a finished non-looping clip.
225
+ * Deterministic — identical inputs and `dt` sequences yield identical frames.
226
+ * Throws {@link SpriteAnimatorDisposedError} after `dispose`.
227
+ */
228
+ update(deltaMs: number): void;
229
+ /**
230
+ * Return to the initial state and reset every input to its default, without
231
+ * releasing buffers. Fires `onStateChange` only if the state actually
232
+ * changed. Throws {@link SpriteAnimatorDisposedError} after `dispose`.
233
+ */
234
+ reset(): void;
235
+ /** Release all listeners. Idempotent; subsequent mutators throw. */
236
+ dispose(): void;
237
+ /** Subscribe to state changes. Returns an unsubscribe. */
238
+ onStateChange(handler: StateChangeHandler, options?: ListenerOptions): Unsubscribe;
239
+ /** Subscribe to non-looping clip completions. Returns an unsubscribe. */
240
+ onComplete(handler: CompleteHandler, options?: ListenerOptions): Unsubscribe;
241
+ /** Current state name. */
242
+ readonly activeState: string;
243
+ /** Current frame key (into the atlas `frames`), for the renderer adapter. */
244
+ readonly activeFrameKey: string;
245
+ /** Index of the current frame within its animation's frame list. */
246
+ readonly activeFrameIndex: number;
247
+ /** `true` once {@link SpriteAnimator.dispose} has been called. */
248
+ readonly disposed: boolean;
249
+ }
250
+
251
+ export type { BooleanInputDef as B, CompleteHandler as C, FrameTiming as F, InputDef as I, ListenerOptions as L, NumberInputDef as N, StateDef as S, TransitionDef as T, Unsubscribe as U, SpriteAnimator as a, SpriteGraph as b, ConditionOp as c, StateChangeHandler as d, TransitionCondition as e, TriggerInputDef as f };
@@ -0,0 +1,251 @@
1
+ /**
2
+ * Declaration of a continuous **Number** input (e.g. `speed`). Read/written
3
+ * with {@link SpriteAnimator.setInput}.
4
+ *
5
+ * @public
6
+ */
7
+ interface NumberInputDef {
8
+ readonly type: "number";
9
+ /** Value before any `setInput`. Defaults to `0`. */
10
+ readonly default?: number;
11
+ }
12
+ /**
13
+ * Declaration of a toggle **Boolean** input (e.g. `isGrounded`). Read/written
14
+ * with {@link SpriteAnimator.setInput}.
15
+ *
16
+ * @public
17
+ */
18
+ interface BooleanInputDef {
19
+ readonly type: "boolean";
20
+ /** Value before any `setInput`. Defaults to `false`. */
21
+ readonly default?: boolean;
22
+ }
23
+ /**
24
+ * Declaration of a one-shot **Trigger** input (e.g. `jump`). Fired with
25
+ * {@link SpriteAnimator.fireTrigger}; auto-resets when a transition consumes
26
+ * it. A trigger has no stored value and no `default`.
27
+ *
28
+ * @public
29
+ */
30
+ interface TriggerInputDef {
31
+ readonly type: "trigger";
32
+ }
33
+ /**
34
+ * One of the three input kinds that drive the visual state machine.
35
+ *
36
+ * @public
37
+ */
38
+ type InputDef = NumberInputDef | BooleanInputDef | TriggerInputDef;
39
+ /**
40
+ * A visual state: which animation plays, whether it loops, how fast, and what
41
+ * to do when a non-looping clip ends.
42
+ *
43
+ * @public
44
+ */
45
+ interface StateDef {
46
+ /** Key into {@link SpriteGraph.animations}. Must reference a non-empty list. */
47
+ readonly animation: string;
48
+ /**
49
+ * `true` — the clip wraps forever; `onComplete` never fires for this state.
50
+ * `false` (default) — the clip plays once and holds the last frame, firing
51
+ * `onComplete` exactly once on the update that reaches the end.
52
+ */
53
+ readonly loop?: boolean;
54
+ /**
55
+ * Playback-speed multiplier applied as a time scale on `dt` (so `2` plays
56
+ * twice as fast, `0.5` half speed). Must be `> 0`. Defaults to `1`.
57
+ */
58
+ readonly speed?: number;
59
+ /**
60
+ * Optional state to auto-transition to when a **non-looping** clip ends —
61
+ * the visual equivalent of "attack → return to idle". Fires `onComplete`
62
+ * first, then switches (firing `onStateChange`). Must reference a declared
63
+ * state, and requires `loop` to be `false` (combining it with `loop:true` is
64
+ * rejected at load, since the clip would never end).
65
+ */
66
+ readonly onEnd?: string;
67
+ }
68
+ /**
69
+ * Comparison operator for a {@link TransitionCondition}.
70
+ *
71
+ * - `Equals` / `NotEquals` — Number or Boolean inputs.
72
+ * - `GreaterThan` / `LessThan` — Number inputs only.
73
+ * - `Trigger` — Trigger inputs only; satisfied while the trigger is pending,
74
+ * and **consumes** it when the owning transition is taken.
75
+ *
76
+ * @public
77
+ */
78
+ type ConditionOp = "Equals" | "NotEquals" | "GreaterThan" | "LessThan" | "Trigger";
79
+ /**
80
+ * A single check over one input. A {@link TransitionDef} fires only when all
81
+ * of its conditions hold (logical AND).
82
+ *
83
+ * @public
84
+ */
85
+ interface TransitionCondition {
86
+ /** Name of a declared input in {@link SpriteGraph.inputs}. */
87
+ readonly input: string;
88
+ /** The comparison; must be valid for the input's kind. */
89
+ readonly op: ConditionOp;
90
+ /**
91
+ * Right-hand operand for `Equals` / `NotEquals` / `GreaterThan` / `LessThan`.
92
+ * Its type must match the input kind (number for Number, boolean for
93
+ * Boolean). Omitted for `Trigger`.
94
+ */
95
+ readonly value?: number | boolean;
96
+ }
97
+ /**
98
+ * A directed edge in the transition graph: from one state (or **Any State**)
99
+ * to another when all conditions hold.
100
+ *
101
+ * @public
102
+ */
103
+ interface TransitionDef {
104
+ /**
105
+ * Source state name, or `"*"` for an **Any-State** transition that is
106
+ * evaluated from every state.
107
+ */
108
+ readonly from: string;
109
+ /** Target state name. Must reference a declared state. */
110
+ readonly to: string;
111
+ /**
112
+ * Conditions that must all hold (AND). An empty/omitted list matches
113
+ * unconditionally — rarely useful except with a `Trigger` elsewhere.
114
+ */
115
+ readonly when?: readonly TransitionCondition[];
116
+ /**
117
+ * Higher wins. Among satisfied transitions, the highest priority is taken;
118
+ * ties break by declared order (earliest first). An integer; defaults to `0`.
119
+ * (The JSON Schema constrains it to `integer`; TypeScript widens it to
120
+ * `number`.)
121
+ */
122
+ readonly priority?: number;
123
+ }
124
+ /**
125
+ * Per-frame timing read by the core. The full PixiJS-v8 atlas frame object
126
+ * (with `frame`, `anchor`, `sourceSize`, …) is assignable here — the core
127
+ * only ever reads `duration`.
128
+ *
129
+ * @public
130
+ */
131
+ interface FrameTiming {
132
+ /** Display time of this frame in milliseconds. Must be `> 0` if present. */
133
+ readonly duration?: number;
134
+ }
135
+ /**
136
+ * The complete input-driven control graph plus the frame data the core needs
137
+ * to compute timing. The `animations` / `frames` blocks mirror a PixiJS-v8
138
+ * spritesheet; `inputs` / `states` / `transitions` are `aispritejs`-specific.
139
+ *
140
+ * @public
141
+ */
142
+ interface SpriteGraph {
143
+ /** Animation name → ordered list of frame keys. Each list must be non-empty. */
144
+ readonly animations: Readonly<Record<string, readonly string[]>>;
145
+ /**
146
+ * Optional per-frame timing keyed by frame key. Frames absent here (or
147
+ * present without a `duration`) fall back to {@link SpriteGraph.defaultFrameDuration}.
148
+ */
149
+ readonly frames?: Readonly<Record<string, FrameTiming>>;
150
+ /** Input declarations keyed by input name. */
151
+ readonly inputs: Readonly<Record<string, InputDef>>;
152
+ /** State declarations keyed by state name. Must be non-empty. */
153
+ readonly states: Readonly<Record<string, StateDef>>;
154
+ /** Transition edges, evaluated every `update`. */
155
+ readonly transitions: readonly TransitionDef[];
156
+ /**
157
+ * Name of the starting state. Defaults to the first key of `states` in
158
+ * declaration order. Must reference a declared state.
159
+ */
160
+ readonly initial?: string;
161
+ /**
162
+ * Fallback frame duration (ms) for frames without explicit timing.
163
+ * Must be `> 0`. Defaults to `100`.
164
+ */
165
+ readonly defaultFrameDuration?: number;
166
+ }
167
+ /**
168
+ * Handler for {@link SpriteAnimator.onStateChange}. Called after the machine
169
+ * switches state, with the new and previous state names.
170
+ *
171
+ * @public
172
+ */
173
+ type StateChangeHandler = (to: string, from: string) => void;
174
+ /**
175
+ * Handler for {@link SpriteAnimator.onComplete}. Called once when a
176
+ * non-looping state's clip reaches its end, with that state's name.
177
+ *
178
+ * @public
179
+ */
180
+ type CompleteHandler = (state: string) => void;
181
+ /**
182
+ * Options shared by every `on...` subscription.
183
+ *
184
+ * @public
185
+ */
186
+ interface ListenerOptions {
187
+ /** Aborting this signal removes the listener. */
188
+ readonly signal?: AbortSignal;
189
+ /** Remove the listener automatically after its first call. */
190
+ readonly once?: boolean;
191
+ }
192
+ /**
193
+ * Returned by every `on...` subscription; call it to remove the listener.
194
+ * Idempotent.
195
+ *
196
+ * @public
197
+ */
198
+ type Unsubscribe = () => void;
199
+ /**
200
+ * The renderer-agnostic visual animator returned by `createSpriteAnimator`.
201
+ *
202
+ * Set inputs, call {@link SpriteAnimator.update} once per frame with the
203
+ * elapsed milliseconds, then read {@link SpriteAnimator.activeFrameKey} and
204
+ * hand it to a renderer adapter. The core never touches a canvas, the DOM, or
205
+ * PixiJS.
206
+ *
207
+ * @public
208
+ */
209
+ interface SpriteAnimator {
210
+ /**
211
+ * Set a Number or Boolean input. Throws {@link UnknownInputError} if the
212
+ * name is not declared and {@link InputTypeError} on a kind mismatch (or if
213
+ * the name is a Trigger — use {@link SpriteAnimator.fireTrigger}).
214
+ */
215
+ setInput(name: string, value: number | boolean): void;
216
+ /**
217
+ * Mark a Trigger pending. It stays pending until a transition that checks it
218
+ * is taken, which consumes it. Throws {@link UnknownInputError} /
219
+ * {@link InputTypeError} for an unknown or non-Trigger input.
220
+ */
221
+ fireTrigger(name: string): void;
222
+ /**
223
+ * Advance by `deltaMs` (clamped at `0`): evaluate transitions, recompute the
224
+ * active frame, and fire `onComplete` for a finished non-looping clip.
225
+ * Deterministic — identical inputs and `dt` sequences yield identical frames.
226
+ * Throws {@link SpriteAnimatorDisposedError} after `dispose`.
227
+ */
228
+ update(deltaMs: number): void;
229
+ /**
230
+ * Return to the initial state and reset every input to its default, without
231
+ * releasing buffers. Fires `onStateChange` only if the state actually
232
+ * changed. Throws {@link SpriteAnimatorDisposedError} after `dispose`.
233
+ */
234
+ reset(): void;
235
+ /** Release all listeners. Idempotent; subsequent mutators throw. */
236
+ dispose(): void;
237
+ /** Subscribe to state changes. Returns an unsubscribe. */
238
+ onStateChange(handler: StateChangeHandler, options?: ListenerOptions): Unsubscribe;
239
+ /** Subscribe to non-looping clip completions. Returns an unsubscribe. */
240
+ onComplete(handler: CompleteHandler, options?: ListenerOptions): Unsubscribe;
241
+ /** Current state name. */
242
+ readonly activeState: string;
243
+ /** Current frame key (into the atlas `frames`), for the renderer adapter. */
244
+ readonly activeFrameKey: string;
245
+ /** Index of the current frame within its animation's frame list. */
246
+ readonly activeFrameIndex: number;
247
+ /** `true` once {@link SpriteAnimator.dispose} has been called. */
248
+ readonly disposed: boolean;
249
+ }
250
+
251
+ export type { BooleanInputDef as B, CompleteHandler as C, FrameTiming as F, InputDef as I, ListenerOptions as L, NumberInputDef as N, StateDef as S, TransitionDef as T, Unsubscribe as U, SpriteAnimator as a, SpriteGraph as b, ConditionOp as c, StateChangeHandler as d, TransitionCondition as e, TriggerInputDef as f };