aispritejs 0.1.0 → 0.1.2

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.
@@ -32,6 +32,9 @@ var InputTypeError = class extends Error {
32
32
 
33
33
  // src/sprite/compile.ts
34
34
  var DEFAULT_FRAME_DURATION = 100;
35
+ function isObject(v) {
36
+ return typeof v === "object" && v !== null && !Array.isArray(v);
37
+ }
35
38
  function compileGraph(graph) {
36
39
  const stateEntries = Object.entries(graph.states);
37
40
  if (stateEntries.length === 0) {
@@ -45,32 +48,41 @@ function compileGraph(graph) {
45
48
  }
46
49
  }
47
50
  const defaultDuration = graph.defaultFrameDuration ?? DEFAULT_FRAME_DURATION;
48
- if (!(defaultDuration > 0)) {
49
- throw new InvalidGraphError(`defaultFrameDuration must be > 0, got ${defaultDuration}`);
51
+ if (!Number.isFinite(defaultDuration) || defaultDuration <= 0) {
52
+ throw new InvalidGraphError(
53
+ `defaultFrameDuration must be a finite number > 0, got ${defaultDuration}`
54
+ );
50
55
  }
51
56
  if (graph.frames) {
52
57
  for (const [key, timing] of Object.entries(graph.frames)) {
53
- if (timing.duration !== void 0 && !(timing.duration > 0)) {
54
- throw new InvalidGraphError(`frame "${key}" duration must be > 0, got ${timing.duration}`);
58
+ if (!isObject(timing)) {
59
+ throw new InvalidGraphError(`frame "${key}" timing must be an object`);
60
+ }
61
+ if (timing.duration !== void 0 && (!Number.isFinite(timing.duration) || timing.duration <= 0)) {
62
+ throw new InvalidGraphError(
63
+ `frame "${key}" duration must be a finite number > 0, got ${timing.duration}`
64
+ );
55
65
  }
56
66
  }
57
67
  }
58
68
  const initial = graph.initial ?? stateEntries[0][0];
59
- if (!(initial in graph.states)) {
69
+ if (!Object.hasOwn(graph.states, initial)) {
60
70
  throw new InvalidGraphError(`initial state "${initial}" is not declared`);
61
71
  }
62
72
  const states = /* @__PURE__ */ new Map();
63
73
  for (const [name, st] of stateEntries) {
64
74
  const frameKeys = graph.animations[st.animation];
65
- if (frameKeys === void 0) {
75
+ if (frameKeys === void 0 || !Object.hasOwn(graph.animations, st.animation)) {
66
76
  throw new InvalidGraphError(`state "${name}" references unknown animation "${st.animation}"`);
67
77
  }
68
78
  if (frameKeys.length === 0) {
69
79
  throw new InvalidGraphError(`animation "${st.animation}" (state "${name}") has no frames`);
70
80
  }
71
81
  const speed = st.speed ?? 1;
72
- if (!(speed > 0)) {
73
- throw new InvalidGraphError(`state "${name}" speed must be > 0, got ${speed}`);
82
+ if (!Number.isFinite(speed) || speed <= 0) {
83
+ throw new InvalidGraphError(
84
+ `state "${name}" speed must be a finite number > 0, got ${speed}`
85
+ );
74
86
  }
75
87
  const loop = st.loop === true;
76
88
  if (loop && st.onEnd !== void 0) {
@@ -78,7 +90,7 @@ function compileGraph(graph) {
78
90
  `state "${name}" loops, so onEnd "${st.onEnd}" would never fire; set loop:false or drop onEnd`
79
91
  );
80
92
  }
81
- if (st.onEnd !== void 0 && !(st.onEnd in graph.states)) {
93
+ if (st.onEnd !== void 0 && !Object.hasOwn(graph.states, st.onEnd)) {
82
94
  throw new InvalidGraphError(`state "${name}" onEnd target "${st.onEnd}" is not declared`);
83
95
  }
84
96
  const cumulative = [];
@@ -100,17 +112,23 @@ function compileGraph(graph) {
100
112
  }
101
113
  const compiled = [];
102
114
  graph.transitions.forEach((t, order) => {
103
- if (t.from !== "*" && !(t.from in graph.states)) {
115
+ if (!isObject(t)) {
116
+ throw new InvalidGraphError(`transition #${order} must be an object`);
117
+ }
118
+ if (t.when !== void 0 && !Array.isArray(t.when)) {
119
+ throw new InvalidGraphError(`transition #${order} "when" must be an array`);
120
+ }
121
+ if (t.from !== "*" && !Object.hasOwn(graph.states, t.from)) {
104
122
  throw new InvalidGraphError(`transition #${order} from "${t.from}" is not a declared state`);
105
123
  }
106
- if (!(t.to in graph.states)) {
124
+ if (!Object.hasOwn(graph.states, t.to)) {
107
125
  throw new InvalidGraphError(`transition #${order} to "${t.to}" is not a declared state`);
108
126
  }
109
127
  const conditions = [];
110
128
  const triggers = [];
111
129
  for (const c of t.when ?? []) {
112
130
  const def = graph.inputs[c.input];
113
- if (def === void 0) {
131
+ if (def === void 0 || !Object.hasOwn(graph.inputs, c.input)) {
114
132
  throw new InvalidGraphError(
115
133
  `transition #${order} condition references unknown input "${c.input}"`
116
134
  );
@@ -363,7 +381,7 @@ function createSpriteAnimator(graph) {
363
381
  }
364
382
  function update(deltaMs) {
365
383
  if (disposed) throw new SpriteAnimatorDisposedError();
366
- elapsed += (deltaMs > 0 ? deltaMs : 0) * current.speed;
384
+ elapsed += (Number.isFinite(deltaMs) && deltaMs > 0 ? deltaMs : 0) * current.speed;
367
385
  const chosen = resolve();
368
386
  if (chosen) {
369
387
  enter(chosen.to, chosen.triggers);
@@ -1 +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.cjs","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"]}
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.cjs","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\n/** @internal */\nexport function isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\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 (!Number.isFinite(defaultDuration) || defaultDuration <= 0) {\n throw new InvalidGraphError(\n `defaultFrameDuration must be a finite number > 0, got ${defaultDuration}`,\n );\n }\n\n if (graph.frames) {\n for (const [key, timing] of Object.entries(graph.frames)) {\n if (!isObject(timing as unknown)) {\n throw new InvalidGraphError(`frame \"${key}\" timing must be an object`);\n }\n if (\n timing.duration !== undefined &&\n (!Number.isFinite(timing.duration) || timing.duration <= 0)\n ) {\n throw new InvalidGraphError(\n `frame \"${key}\" duration must be a finite number > 0, got ${timing.duration}`,\n );\n }\n }\n }\n\n const initial = graph.initial ?? stateEntries[0]![0];\n if (!Object.hasOwn(graph.states, initial)) {\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 || !Object.hasOwn(graph.animations, st.animation)) {\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 (!Number.isFinite(speed) || speed <= 0) {\n throw new InvalidGraphError(\n `state \"${name}\" speed must be a finite number > 0, got ${speed}`,\n );\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 && !Object.hasOwn(graph.states, st.onEnd)) {\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 (!isObject(t as unknown)) {\n throw new InvalidGraphError(`transition #${order} must be an object`);\n }\n if (t.when !== undefined && !Array.isArray(t.when)) {\n throw new InvalidGraphError(`transition #${order} \"when\" must be an array`);\n }\n if (t.from !== \"*\" && !Object.hasOwn(graph.states, t.from)) {\n throw new InvalidGraphError(`transition #${order} from \"${t.from}\" is not a declared state`);\n }\n if (!Object.hasOwn(graph.states, t.to)) {\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 || !Object.hasOwn(graph.inputs, c.input)) {\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 (non-finite or non-positive dt clamped to 0 for determinism).\n // NOTE: `elapsed` accumulates without bound in looping states (intentional design choice).\n // Drift from floating-point accumulation is sub-ULP-relevant only after continuous play\n // on the order of years; a periodic reset (e.g. on state entry) would be premature.\n elapsed += (Number.isFinite(deltaMs) && 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"]}
@@ -1,5 +1,5 @@
1
1
  import { Sprite, Texture, Spritesheet } from 'pixi.js';
2
- import { b as SpriteGraph } from '../types-DKMFvfx9.cjs';
2
+ import { b as SpriteGraph } from '../types-BS72pefJ.cjs';
3
3
 
4
4
  /**
5
5
  * Thrown by {@link createPixiSpriteAnimator} when the supplied textures are
@@ -1,5 +1,5 @@
1
1
  import { Sprite, Texture, Spritesheet } from 'pixi.js';
2
- import { b as SpriteGraph } from '../types-DKMFvfx9.js';
2
+ import { b as SpriteGraph } from '../types-BS72pefJ.js';
3
3
 
4
4
  /**
5
5
  * Thrown by {@link createPixiSpriteAnimator} when the supplied textures are
@@ -30,6 +30,9 @@ var InputTypeError = class extends Error {
30
30
 
31
31
  // src/sprite/compile.ts
32
32
  var DEFAULT_FRAME_DURATION = 100;
33
+ function isObject(v) {
34
+ return typeof v === "object" && v !== null && !Array.isArray(v);
35
+ }
33
36
  function compileGraph(graph) {
34
37
  const stateEntries = Object.entries(graph.states);
35
38
  if (stateEntries.length === 0) {
@@ -43,32 +46,41 @@ function compileGraph(graph) {
43
46
  }
44
47
  }
45
48
  const defaultDuration = graph.defaultFrameDuration ?? DEFAULT_FRAME_DURATION;
46
- if (!(defaultDuration > 0)) {
47
- throw new InvalidGraphError(`defaultFrameDuration must be > 0, got ${defaultDuration}`);
49
+ if (!Number.isFinite(defaultDuration) || defaultDuration <= 0) {
50
+ throw new InvalidGraphError(
51
+ `defaultFrameDuration must be a finite number > 0, got ${defaultDuration}`
52
+ );
48
53
  }
49
54
  if (graph.frames) {
50
55
  for (const [key, timing] of Object.entries(graph.frames)) {
51
- if (timing.duration !== void 0 && !(timing.duration > 0)) {
52
- throw new InvalidGraphError(`frame "${key}" duration must be > 0, got ${timing.duration}`);
56
+ if (!isObject(timing)) {
57
+ throw new InvalidGraphError(`frame "${key}" timing must be an object`);
58
+ }
59
+ if (timing.duration !== void 0 && (!Number.isFinite(timing.duration) || timing.duration <= 0)) {
60
+ throw new InvalidGraphError(
61
+ `frame "${key}" duration must be a finite number > 0, got ${timing.duration}`
62
+ );
53
63
  }
54
64
  }
55
65
  }
56
66
  const initial = graph.initial ?? stateEntries[0][0];
57
- if (!(initial in graph.states)) {
67
+ if (!Object.hasOwn(graph.states, initial)) {
58
68
  throw new InvalidGraphError(`initial state "${initial}" is not declared`);
59
69
  }
60
70
  const states = /* @__PURE__ */ new Map();
61
71
  for (const [name, st] of stateEntries) {
62
72
  const frameKeys = graph.animations[st.animation];
63
- if (frameKeys === void 0) {
73
+ if (frameKeys === void 0 || !Object.hasOwn(graph.animations, st.animation)) {
64
74
  throw new InvalidGraphError(`state "${name}" references unknown animation "${st.animation}"`);
65
75
  }
66
76
  if (frameKeys.length === 0) {
67
77
  throw new InvalidGraphError(`animation "${st.animation}" (state "${name}") has no frames`);
68
78
  }
69
79
  const speed = st.speed ?? 1;
70
- if (!(speed > 0)) {
71
- throw new InvalidGraphError(`state "${name}" speed must be > 0, got ${speed}`);
80
+ if (!Number.isFinite(speed) || speed <= 0) {
81
+ throw new InvalidGraphError(
82
+ `state "${name}" speed must be a finite number > 0, got ${speed}`
83
+ );
72
84
  }
73
85
  const loop = st.loop === true;
74
86
  if (loop && st.onEnd !== void 0) {
@@ -76,7 +88,7 @@ function compileGraph(graph) {
76
88
  `state "${name}" loops, so onEnd "${st.onEnd}" would never fire; set loop:false or drop onEnd`
77
89
  );
78
90
  }
79
- if (st.onEnd !== void 0 && !(st.onEnd in graph.states)) {
91
+ if (st.onEnd !== void 0 && !Object.hasOwn(graph.states, st.onEnd)) {
80
92
  throw new InvalidGraphError(`state "${name}" onEnd target "${st.onEnd}" is not declared`);
81
93
  }
82
94
  const cumulative = [];
@@ -98,17 +110,23 @@ function compileGraph(graph) {
98
110
  }
99
111
  const compiled = [];
100
112
  graph.transitions.forEach((t, order) => {
101
- if (t.from !== "*" && !(t.from in graph.states)) {
113
+ if (!isObject(t)) {
114
+ throw new InvalidGraphError(`transition #${order} must be an object`);
115
+ }
116
+ if (t.when !== void 0 && !Array.isArray(t.when)) {
117
+ throw new InvalidGraphError(`transition #${order} "when" must be an array`);
118
+ }
119
+ if (t.from !== "*" && !Object.hasOwn(graph.states, t.from)) {
102
120
  throw new InvalidGraphError(`transition #${order} from "${t.from}" is not a declared state`);
103
121
  }
104
- if (!(t.to in graph.states)) {
122
+ if (!Object.hasOwn(graph.states, t.to)) {
105
123
  throw new InvalidGraphError(`transition #${order} to "${t.to}" is not a declared state`);
106
124
  }
107
125
  const conditions = [];
108
126
  const triggers = [];
109
127
  for (const c of t.when ?? []) {
110
128
  const def = graph.inputs[c.input];
111
- if (def === void 0) {
129
+ if (def === void 0 || !Object.hasOwn(graph.inputs, c.input)) {
112
130
  throw new InvalidGraphError(
113
131
  `transition #${order} condition references unknown input "${c.input}"`
114
132
  );
@@ -361,7 +379,7 @@ function createSpriteAnimator(graph) {
361
379
  }
362
380
  function update(deltaMs) {
363
381
  if (disposed) throw new SpriteAnimatorDisposedError();
364
- elapsed += (deltaMs > 0 ? deltaMs : 0) * current.speed;
382
+ elapsed += (Number.isFinite(deltaMs) && deltaMs > 0 ? deltaMs : 0) * current.speed;
365
383
  const chosen = resolve();
366
384
  if (chosen) {
367
385
  enter(chosen.to, chosen.triggers);