@rb-games/core 0.1.2 → 0.1.4
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.
- package/dist/{chunk-DOHQE2YZ.js → chunk-C45KDREE.js} +46 -50
- package/dist/chunk-C45KDREE.js.map +1 -0
- package/dist/chunk-JHN6RF66.js +1580 -0
- package/dist/chunk-JHN6RF66.js.map +1 -0
- package/dist/chunk-NAQG7TMS.js +5517 -0
- package/dist/chunk-NAQG7TMS.js.map +1 -0
- package/dist/{chunk-RAEOBW6E.js → chunk-P4GCINNA.js} +3 -3
- package/dist/{chunk-RAEOBW6E.js.map → chunk-P4GCINNA.js.map} +1 -1
- package/dist/{chunk-KOHCRCV3.js → chunk-XHUPUPPW.js} +12 -12
- package/dist/chunk-XHUPUPPW.js.map +1 -0
- package/dist/engine/index.js +5 -6
- package/dist/engine/index.js.map +1 -1
- package/dist/helpers/index.js +12 -9
- package/dist/helpers/index.js.map +1 -1
- package/dist/i18n/index.js +2 -2
- package/dist/particle/index.js +109 -476
- package/dist/particle/index.js.map +1 -1
- package/dist/plugins/index.js +163 -205
- package/dist/plugins/index.js.map +1 -1
- package/dist/state-machine/index.js +12 -12
- package/dist/state-machine/index.js.map +1 -1
- package/dist/store/index.js +3 -4
- package/dist/store/index.js.map +1 -1
- package/dist/ui/components/Skinable.d.ts.map +1 -1
- package/dist/ui/index.js +170 -201
- package/dist/ui/index.js.map +1 -1
- package/dist/utils/index.js +3 -2
- package/dist/vite/index.js +5 -3
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-DOHQE2YZ.js.map +0 -1
- package/dist/chunk-KOHCRCV3.js.map +0 -1
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import '../chunk-
|
|
1
|
+
import { require_merge } from '../chunk-JHN6RF66.js';
|
|
2
|
+
import { __toESM } from '../chunk-G3PMV62Z.js';
|
|
2
3
|
import { EventEmitter } from 'pixi.js';
|
|
3
|
-
import merge from 'lodash/merge';
|
|
4
4
|
|
|
5
|
+
// state-machine/StateMachine.ts
|
|
6
|
+
var import_merge = __toESM(require_merge(), 1);
|
|
5
7
|
var StateMachine = class extends EventEmitter {
|
|
6
|
-
config;
|
|
7
|
-
context;
|
|
8
|
-
isTransitioning = false;
|
|
9
|
-
resolvedStateCache = /* @__PURE__ */ new Map();
|
|
10
8
|
constructor(config) {
|
|
11
9
|
super();
|
|
10
|
+
this.isTransitioning = false;
|
|
11
|
+
this.resolvedStateCache = /* @__PURE__ */ new Map();
|
|
12
12
|
this.config = config;
|
|
13
13
|
if (!this.config.modes[this.config.initialMode]) {
|
|
14
14
|
throw new Error(`Initial mode "${this.config.initialMode}" not found in config`);
|
|
@@ -111,7 +111,7 @@ var StateMachine = class extends EventEmitter {
|
|
|
111
111
|
break;
|
|
112
112
|
}
|
|
113
113
|
}
|
|
114
|
-
const resolved =
|
|
114
|
+
const resolved = (0, import_merge.default)({}, ...chain);
|
|
115
115
|
delete resolved.extends;
|
|
116
116
|
resolved.guards = stateDef.guards;
|
|
117
117
|
resolved.onEnter = stateDef.onEnter;
|
|
@@ -500,13 +500,13 @@ var StateMachine = class extends EventEmitter {
|
|
|
500
500
|
// state-machine/ConfigBuilder.ts
|
|
501
501
|
var ConfigBuilder = class {
|
|
502
502
|
constructor(initialData) {
|
|
503
|
+
this.config = {
|
|
504
|
+
modes: {}
|
|
505
|
+
};
|
|
506
|
+
this.currentMode = null;
|
|
507
|
+
this.currentState = null;
|
|
503
508
|
this.config.initialData = initialData;
|
|
504
509
|
}
|
|
505
|
-
config = {
|
|
506
|
-
modes: {}
|
|
507
|
-
};
|
|
508
|
-
currentMode = null;
|
|
509
|
-
currentState = null;
|
|
510
510
|
/**
|
|
511
511
|
* Define a new mode or switch to an existing mode
|
|
512
512
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../state-machine/StateMachine.ts","../../state-machine/ConfigBuilder.ts","../../state-machine/guards.ts"],"names":["guards"],"mappings":"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","file":"index.js","sourcesContent":["import { EventEmitter } from 'pixi.js';\nimport merge from 'lodash/merge';\nimport type {\n StateKey,\n ModeKey,\n ScopeKey,\n StateContext,\n StateMachineConfig,\n TransitionOptions,\n StateDefinition,\n ScopeConfig,\n ConfigValue,\n StateMachineEvents,\n} from './types';\n\n/**\n * Event-driven state machine with two-level hierarchy (MODE/STATE).\n *\n * Features:\n * - Two-level structure: MODE (NORMAL, FREESPIN, BONUS) → STATE (IDLE, SPIN, MATCH)\n * - State inheritance with lodash merge\n * - Scope-based configuration (ui, scene, audio, etc.)\n * - Dynamic values via resolver functions\n * - Async lifecycle hooks (onEnter, onExit)\n * - Transition guards for validation\n * - Pixi.js EventEmitter for decoupled communication\n *\n * @example\n * ```typescript\n * const config = createConfig<GameData>()\n * .initial('IDLE', 'NORMAL')\n * .mode('NORMAL')\n * .state('IDLE')\n * .scope('ui', { spinButton: { enabled: true } })\n * .state('SPIN')\n * .extends('IDLE')\n * .guard('canEnter', (ctx) => ctx.data.balance >= ctx.data.bet)\n * .build();\n *\n * const machine = new StateMachine(config);\n * await machine.transition('SPIN');\n * ```\n *\n * @template TData - Type of the state machine's data context\n */\nexport class StateMachine<TData = any> extends EventEmitter<StateMachineEvents<TData>> {\n private config: StateMachineConfig<TData>;\n private context: StateContext<TData>;\n private isTransitioning = false;\n private resolvedStateCache = new Map<string, StateDefinition<TData>>();\n\n constructor(config: StateMachineConfig<TData>) {\n super();\n this.config = config;\n\n if (!this.config.modes[this.config.initialMode]) {\n throw new Error(`Initial mode \"${this.config.initialMode}\" not found in config`);\n }\n\n const initialMode = this.config.modes[this.config.initialMode];\n if (!initialMode.states[this.config.initialState]) {\n throw new Error(\n `Initial state \"${this.config.initialState}\" not found in mode \"${this.config.initialMode}\"`,\n );\n }\n\n this.context = {\n currentState: this.config.initialState,\n previousState: null,\n currentMode: this.config.initialMode,\n previousMode: null,\n timestamp: Date.now(),\n data: this.config.initialData ?? ({} as TData),\n metadata: {},\n };\n }\n\n /**\n * Current state key (e.g., 'IDLE', 'SPIN', 'MATCH')\n */\n get state(): StateKey {\n return this.context.currentState;\n }\n\n /**\n * Current mode key (e.g., 'NORMAL', 'FREESPIN', 'BONUS')\n */\n get mode(): ModeKey {\n return this.context.currentMode;\n }\n\n /**\n * Current state data (mutable)\n */\n get data(): TData {\n return this.context.data;\n }\n\n /**\n * Get a readonly copy of the current state context\n *\n * @returns Readonly state context with current state, mode, data, and metadata\n */\n getContext(): Readonly<StateContext<TData>> {\n return { ...this.context };\n }\n\n /**\n * Update state data using an updater function\n *\n * @param updater - Function that receives current data and optionally returns new data\n *\n * @example\n * ```typescript\n * machine.updateData(data => {\n * data.balance = 1000;\n * data.bet = 10;\n * });\n * ```\n */\n updateData(updater: (data: TData) => TData | void): void {\n const result = updater(this.context.data);\n if (result !== undefined) {\n this.context.data = result;\n }\n }\n\n private resolveStateDefinition(state: StateKey, mode?: ModeKey): StateDefinition<TData> {\n const modeKey = mode ?? this.context.currentMode;\n const cacheKey = `${modeKey}:${state}`;\n\n if (this.resolvedStateCache.has(cacheKey)) {\n return this.resolvedStateCache.get(cacheKey)!;\n }\n\n const currentMode = this.config.modes[modeKey];\n const stateDef = currentMode.states[state];\n\n if (!stateDef) {\n throw new Error(`State \"${state}\" not found in mode \"${modeKey}\"`);\n }\n\n if (!stateDef.extends) {\n this.resolvedStateCache.set(cacheKey, stateDef);\n return stateDef;\n }\n\n const chain: StateDefinition<TData>[] = [];\n const visited = new Set<StateKey>();\n let current = stateDef;\n let currentKey = state;\n\n while (current) {\n if (visited.has(currentKey)) {\n throw new Error(`Circular extends detected in state \"${state}\"`);\n }\n visited.add(currentKey);\n chain.unshift(current);\n\n if (current.extends) {\n const parentKey = current.extends;\n const parent = currentMode.states[parentKey];\n if (!parent) {\n throw new Error(`Parent state \"${parentKey}\" not found for state \"${state}\"`);\n }\n current = parent;\n currentKey = parentKey;\n } else {\n break;\n }\n }\n\n const resolved = merge({}, ...chain);\n delete resolved.extends;\n\n // Behavioral properties (guards, hooks) are NOT inherited via extends.\n // Only scopes and metadata are inherited. Each state must define its own guards/hooks.\n resolved.guards = stateDef.guards;\n resolved.onEnter = stateDef.onEnter;\n resolved.onExit = stateDef.onExit;\n\n this.resolvedStateCache.set(cacheKey, resolved);\n return resolved;\n }\n\n private resolveScopeData(scopeConfig: ScopeConfig<TData> | undefined): Record<ScopeKey, any> {\n if (!scopeConfig) return {};\n\n const resolved: Record<ScopeKey, any> = {};\n\n for (const [scopeName, scopeData] of Object.entries(scopeConfig)) {\n resolved[scopeName] = {};\n\n for (const [componentName, componentData] of Object.entries(scopeData)) {\n resolved[scopeName][componentName] = {};\n\n for (const [propName, propValue] of Object.entries(componentData)) {\n resolved[scopeName][componentName][propName] = this.resolveValue(propValue);\n }\n }\n }\n\n return resolved;\n }\n\n private resolveValue<T>(value: ConfigValue<TData, T>): T {\n if (typeof value === 'function') {\n return (value as Function)(this.context);\n }\n return value as T;\n }\n\n /**\n * Get resolved scope data for a specific scope\n *\n * @param scopeName - Name of the scope (e.g., 'ui', 'scene', 'audio')\n * @returns Resolved scope data with all resolver functions evaluated\n *\n * @example\n * ```typescript\n * const uiState = machine.getScope('ui');\n * console.log(uiState.spinButton.enabled); // true\n * ```\n */\n getScope(scopeName: ScopeKey): any {\n const resolvedState = this.resolveStateDefinition(this.context.currentState);\n const scopeData = this.resolveScopeData(resolvedState.scopes);\n return scopeData[scopeName] ?? {};\n }\n\n /**\n * Get all resolved scope data for the current state\n *\n * @returns Object containing all scopes with resolved data\n *\n * @example\n * ```typescript\n * const scopes = machine.getAllScopes();\n * console.log(scopes.ui); // UI scope data\n * console.log(scopes.scene); // Scene scope data\n * ```\n */\n getAllScopes(): Record<ScopeKey, any> {\n const resolvedState = this.resolveStateDefinition(this.context.currentState);\n return this.resolveScopeData(resolvedState.scopes);\n }\n\n /**\n * Transition to a new state within the current mode\n *\n * This is an async operation that:\n * 1. Checks guards (canExit, canEnter)\n * 2. Calls onExit hook of current state\n * 3. Changes the state\n * 4. Calls onEnter hook of target state\n * 5. Emits events (state:exit, state:enter, state:change, scope:update)\n *\n * @param targetState - Target state key to transition to\n * @param options - Transition options\n * @param options.force - Skip guard checks and force transition\n * @param options.silent - Skip event emissions\n * @returns Promise that resolves to true if transition succeeded, false otherwise\n *\n * @example\n * ```typescript\n * // Normal transition\n * await machine.transition('SPIN');\n *\n * // Force transition (skip guards)\n * await machine.transition('SPIN', { force: true });\n *\n * // Silent transition (no events)\n * await machine.transition('SPIN', { silent: true });\n * ```\n *\n * @fires state:exit - When exiting current state\n * @fires state:enter - When entering target state\n * @fires state:change - After state change completes\n * @fires scope:update - For each scope after state change\n * @fires transition:blocked - If guard check fails\n * @fires error - If an error occurs during transition\n */\n async transition(targetState: StateKey, options: TransitionOptions = {}): Promise<boolean> {\n if (this.isTransitioning && !options.force) {\n console.warn('Transition already in progress');\n return false;\n }\n\n const fromState = this.context.currentState;\n if (fromState === targetState) {\n return true;\n }\n\n const currentMode = this.config.modes[this.context.currentMode];\n if (!currentMode.states[targetState]) {\n const error = new Error(\n `State \"${targetState}\" not found in mode \"${this.context.currentMode}\"`,\n );\n if (this.config.strict) {\n throw error;\n }\n this.emit('error', error, this.context);\n return false;\n }\n\n if (!options.force) {\n const canTransition = await this.checkGuards(fromState, targetState);\n if (!canTransition.allowed) {\n this.emit(\n 'transition:blocked',\n fromState,\n targetState,\n canTransition.reason || 'Guard check failed',\n this.context,\n );\n return false;\n }\n }\n\n this.isTransitioning = true;\n\n try {\n if (!options.silent) {\n this.emit('transition:start', fromState, targetState, this.context);\n }\n\n const fromStateDef = this.resolveStateDefinition(fromState);\n if (fromStateDef.onExit) {\n await fromStateDef.onExit(this.context);\n }\n\n if (!options.silent) {\n this.emit('state:exit', fromState, this.context);\n }\n\n const previousState = this.context.currentState;\n this.context = {\n ...this.context,\n currentState: targetState,\n previousState,\n timestamp: Date.now(),\n };\n\n const toStateDef = this.resolveStateDefinition(targetState);\n if (toStateDef.onEnter) {\n await toStateDef.onEnter(this.context);\n }\n\n if (!options.silent) {\n this.emit('state:enter', targetState, this.context);\n this.emit('state:change', fromState, targetState, this.context);\n\n const scopes = this.getAllScopes();\n for (const [scopeName, scopeData] of Object.entries(scopes)) {\n this.emit('scope:update', scopeName, scopeData, this.context);\n this.emit(`scope:update:${scopeName}` as any, scopeData, this.context);\n }\n\n this.emit('transition:complete', fromState, targetState, this.context);\n }\n\n return true;\n } catch (error) {\n this.emit('error', error as Error, this.context);\n return false;\n } finally {\n this.isTransitioning = false;\n }\n }\n\n /**\n * Change to a different mode with an optional initial state\n *\n * This will:\n * 1. Call onExit hook of current mode\n * 2. Clear state resolution cache\n * 3. Change mode and state\n * 4. Call onEnter hook of target mode\n * 5. Call onEnter hook of initial state\n * 6. Emit events\n *\n * @param targetMode - Target mode key to switch to\n * @param initialState - Optional initial state in the target mode (defaults to config.initialState)\n * @returns Promise that resolves to true if mode change succeeded, false otherwise\n *\n * @example\n * ```typescript\n * // Switch to freespin mode\n * await machine.changeMode('FREESPIN', 'IDLE');\n *\n * // Return to normal mode\n * await machine.changeMode('NORMAL', 'IDLE');\n * ```\n *\n * @fires mode:exit - When exiting current mode\n * @fires mode:enter - When entering target mode\n * @fires mode:change - After mode change completes\n * @fires state:enter - When entering initial state\n * @fires scope:update - For each scope after mode change\n */\n async changeMode(targetMode: ModeKey, initialState?: StateKey): Promise<boolean> {\n if (this.context.currentMode === targetMode) {\n return true;\n }\n\n const targetModeDef = this.config.modes[targetMode];\n if (!targetModeDef) {\n const error = new Error(`Mode \"${targetMode}\" not found`);\n if (this.config.strict) {\n throw error;\n }\n this.emit('error', error, this.context);\n return false;\n }\n\n const targetState = initialState ?? this.config.initialState;\n if (!targetModeDef.states[targetState]) {\n const error = new Error(`State \"${targetState}\" not found in mode \"${targetMode}\"`);\n if (this.config.strict) {\n throw error;\n }\n this.emit('error', error, this.context);\n return false;\n }\n\n const fromMode = this.context.currentMode;\n const currentModeDef = this.config.modes[fromMode];\n\n try {\n if (currentModeDef.onExit) {\n await currentModeDef.onExit(this.context);\n }\n\n this.emit('mode:exit', fromMode, this.context);\n\n this.resolvedStateCache.clear();\n\n const previousMode = this.context.currentMode;\n this.context = {\n ...this.context,\n currentMode: targetMode,\n previousMode,\n currentState: targetState,\n previousState: this.context.currentState,\n timestamp: Date.now(),\n };\n\n if (targetModeDef.onEnter) {\n await targetModeDef.onEnter(this.context);\n }\n\n this.emit('mode:enter', targetMode, this.context);\n this.emit('mode:change', fromMode, targetMode, this.context);\n\n const toStateDef = this.resolveStateDefinition(targetState);\n if (toStateDef.onEnter) {\n await toStateDef.onEnter(this.context);\n }\n\n this.emit('state:enter', targetState, this.context);\n\n const scopes = this.getAllScopes();\n for (const [scopeName, scopeData] of Object.entries(scopes)) {\n this.emit('scope:update', scopeName, scopeData, this.context);\n this.emit(`scope:update:${scopeName}` as any, scopeData, this.context);\n }\n\n return true;\n } catch (error) {\n this.emit('error', error as Error, this.context);\n return false;\n }\n }\n\n /**\n * Check if a state exists in the current mode (synchronous, no guard check)\n *\n * @param targetState - State key to check\n * @returns True if state exists in current mode, false otherwise\n *\n * @example\n * ```typescript\n * if (machine.can('SPIN')) {\n * console.log('SPIN state exists');\n * }\n * ```\n */\n can(targetState: StateKey): boolean {\n const currentMode = this.config.modes[this.context.currentMode];\n return !!currentMode?.states[targetState];\n }\n\n /**\n * Check if transition to a state is allowed (async, includes guard check)\n *\n * @param targetState - State key to check\n * @returns Promise that resolves to true if transition is allowed, false otherwise\n *\n * @example\n * ```typescript\n * if (await machine.canAsync('SPIN')) {\n * await machine.transition('SPIN');\n * } else {\n * console.log('Cannot transition to SPIN');\n * }\n * ```\n */\n async canAsync(targetState: StateKey): Promise<boolean> {\n const result = await this.checkGuards(this.context.currentState, targetState);\n return result.allowed;\n }\n\n private async checkGuards(\n fromState: StateKey,\n toState: StateKey,\n ): Promise<{ allowed: boolean; reason?: string }> {\n const fromStateDef = this.resolveStateDefinition(fromState);\n const toStateDef = this.resolveStateDefinition(toState);\n\n if (fromStateDef.guards?.canExit) {\n const canExit = await fromStateDef.guards.canExit(this.context);\n if (!canExit) {\n return { allowed: false, reason: `Cannot exit state \"${fromState}\"` };\n }\n }\n\n if (toStateDef.guards?.canEnter) {\n const canEnter = await toStateDef.guards.canEnter(this.context);\n if (!canEnter) {\n return { allowed: false, reason: `Cannot enter state \"${toState}\"` };\n }\n }\n\n return { allowed: true };\n }\n\n /**\n * Check if current state matches the given state key\n *\n * @param state - State key to compare\n * @returns True if current state matches, false otherwise\n *\n * @example\n * ```typescript\n * if (machine.is('SPIN')) {\n * console.log('Currently spinning');\n * }\n * ```\n */\n is(state: StateKey): boolean {\n return this.context.currentState === state;\n }\n\n /**\n * Check if current mode matches the given mode key\n *\n * @param mode - Mode key to compare\n * @returns True if current mode matches, false otherwise\n *\n * @example\n * ```typescript\n * if (machine.isMode('FREESPIN')) {\n * console.log('In freespin mode');\n * }\n * ```\n */\n isMode(mode: ModeKey): boolean {\n return this.context.currentMode === mode;\n }\n\n /**\n * Reset state machine to initial state and mode\n *\n * Clears cache and resets context to initial configuration\n *\n * @example\n * ```typescript\n * machine.reset();\n * console.log(machine.state); // Initial state\n * console.log(machine.mode); // Initial mode\n * ```\n */\n reset(): void {\n this.resolvedStateCache.clear();\n this.context = {\n currentState: this.config.initialState,\n previousState: null,\n currentMode: this.config.initialMode,\n previousMode: null,\n timestamp: Date.now(),\n data: this.config.initialData ?? ({} as TData),\n metadata: {},\n };\n }\n\n /**\n * Destroy state machine and clean up resources\n *\n * Clears cache and removes all event listeners\n *\n * @example\n * ```typescript\n * machine.destroy();\n * ```\n */\n destroy(): void {\n this.resolvedStateCache.clear();\n this.removeAllListeners();\n }\n}\n","import type {\n StateKey,\n ModeKey,\n ScopeKey,\n StateDefinition,\n StateMachineConfig,\n StateHook,\n TransitionGuard,\n} from './types';\n\n/**\n * Fluent API builder for creating state machine configurations\n *\n * Provides a chainable interface for defining modes, states, scopes, hooks, and guards.\n *\n * @example\n * ```typescript\n * const config = createConfig<GameData>()\n * .initial('IDLE', 'NORMAL')\n * .initialData({ balance: 1000 })\n * .mode('NORMAL')\n * .state('IDLE')\n * .scope('ui', { spinButton: { enabled: true } })\n * .state('SPIN')\n * .extends('IDLE')\n * .guard('canEnter', (ctx) => ctx.data.balance >= ctx.data.bet)\n * .build();\n * ```\n *\n * @template TData - Type of the state machine's data context\n */\nexport class ConfigBuilder<TData = any> {\n constructor(initialData?: TData) {\n this.config.initialData = initialData;\n }\n\n private config: Partial<StateMachineConfig<TData>> = {\n modes: {},\n };\n private currentMode: ModeKey | null = null;\n private currentState: StateKey | null = null;\n\n /**\n * Define a new mode or switch to an existing mode\n *\n * @param name - Mode key (e.g., 'NORMAL', 'FREESPIN', 'BONUS')\n * @returns This builder for chaining\n */\n mode(name: ModeKey): this {\n this.currentMode = name;\n if (!this.config.modes![name]) {\n this.config.modes![name] = { states: {} };\n }\n return this;\n }\n\n /**\n * Define a new state in the current mode\n *\n * @param name - State key (e.g., 'IDLE', 'SPIN', 'MATCH')\n * @returns This builder for chaining\n * @throws Error if mode() hasn't been called first\n */\n state(name: StateKey): this {\n if (!this.currentMode) {\n throw new Error('Must call mode() before state()');\n }\n this.currentState = name;\n const mode = this.config.modes![this.currentMode];\n if (!mode.states[name]) {\n mode.states[name] = {};\n }\n return this;\n }\n\n /**\n * Make current state extend from a parent state (inheritance)\n *\n * Child state will inherit all properties from parent state using lodash merge.\n * Child properties override parent properties.\n *\n * @param parentState - Parent state key to extend from\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .state('IDLE')\n * .scope('ui', { spinButton: { enabled: true, icon: 'spin' } })\n *\n * .state('SPIN')\n * .extends('IDLE') // Inherits from IDLE\n * .scope('ui', { spinButton: { icon: 'stop' } }) // Only override icon\n * ```\n */\n extends(parentState: StateKey): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before extends()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.extends = parentState;\n return this;\n }\n\n /**\n * Define scope configuration for current state\n *\n * Scopes organize related configuration (ui, scene, audio, etc.).\n * Values can be static or resolver functions.\n *\n * @param scopeName - Scope key (e.g., 'ui', 'scene', 'audio')\n * @param scopeData - Scope configuration object\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .scope('ui', {\n * spinButton: {\n * enabled: true,\n * icon: (ctx) => ctx.data.isQuickSpin ? 'quick_spin' : 'spin',\n * },\n * betButtons: { enabled: false },\n * })\n * .scope('scene', {\n * reels: { spinning: true },\n * })\n * ```\n */\n scope(scopeName: ScopeKey, scopeData: Record<string, Record<string, any>>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before scope()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n if (!state.scopes) {\n state.scopes = {};\n }\n state.scopes[scopeName] = scopeData;\n return this;\n }\n\n /**\n * Add onEnter lifecycle hook to current state\n *\n * Called when entering this state. Can be async.\n * Transition waits for this hook to complete.\n *\n * @param hook - Lifecycle hook function\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .onEnter(async (ctx) => {\n * ctx.data.balance -= ctx.data.bet;\n * await scene.playAnimation();\n * })\n * ```\n */\n onEnter(hook: StateHook<TData>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before onEnter()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.onEnter = hook;\n return this;\n }\n\n /**\n * Add onExit lifecycle hook to current state\n *\n * Called when exiting this state. Can be async.\n * Transition waits for this hook to complete.\n *\n * @param hook - Lifecycle hook function\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .onExit(async (ctx) => {\n * await scene.cleanup();\n * })\n * ```\n */\n onExit(hook: StateHook<TData>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before onExit()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.onExit = hook;\n return this;\n }\n\n /**\n * Add transition guard to current state\n *\n * Guards control whether transitions are allowed.\n * Return false to block transition.\n *\n * @param type - Guard type ('canEnter' or 'canExit')\n * @param guard - Guard function\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .guard('canEnter', (ctx) => ctx.data.balance >= ctx.data.bet)\n * .guard('canExit', (ctx) => !ctx.data.isLocked)\n * ```\n */\n guard(type: 'canEnter' | 'canExit', guard: TransitionGuard<TData>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before guard()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n if (!state.guards) {\n state.guards = {};\n }\n state.guards[type] = guard;\n return this;\n }\n\n /**\n * Add metadata to current state\n *\n * @param data - Metadata object\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n */\n metadata(data: Record<string, any>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before metadata()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.metadata = { ...state.metadata, ...data };\n return this;\n }\n\n /**\n * Add lifecycle hook to current mode\n *\n * @param type - Hook type ('onEnter' or 'onExit')\n * @param hook - Lifecycle hook function\n * @returns This builder for chaining\n * @throws Error if mode() hasn't been called first\n *\n * @example\n * ```typescript\n * .mode('FREESPIN')\n * .modeHook('onEnter', (ctx) => {\n * ctx.data.freeSpinsRemaining = 10;\n * })\n * ```\n */\n modeHook(type: 'onEnter' | 'onExit', hook: StateHook<TData>): this {\n if (!this.currentMode) {\n throw new Error('Must call mode() before modeHook()');\n }\n const mode = this.config.modes![this.currentMode];\n mode[type] = hook;\n return this;\n }\n\n /**\n * Set initial state and mode\n *\n * @param state - Initial state key\n * @param mode - Initial mode key\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .initial('IDLE', 'NORMAL')\n * ```\n */\n initial(state: StateKey, mode: ModeKey): this {\n this.config.initialState = state;\n this.config.initialMode = mode;\n return this;\n }\n\n /**\n * Set initial data for state context\n *\n * @param data - Initial data object\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .initialData({ balance: 1000, bet: 10 })\n * ```\n */\n initialData(data: TData): this {\n this.config.initialData = data;\n return this;\n }\n\n /**\n * Enable strict mode (throws errors instead of emitting error events)\n *\n * @param value - Enable strict mode (default: true)\n * @returns This builder for chaining\n */\n strict(value = true): this {\n this.config.strict = value;\n return this;\n }\n\n /**\n * Build and return the final state machine configuration\n *\n * @returns Complete state machine configuration\n * @throws Error if initial state and mode haven't been set\n *\n * @example\n * ```typescript\n * const config = createConfig()\n * .initial('IDLE', 'NORMAL')\n * .mode('NORMAL')\n * .state('IDLE')\n * .build();\n * ```\n */\n build(): StateMachineConfig<TData> {\n if (!this.config.initialState || !this.config.initialMode) {\n throw new Error('Must set initial state and mode');\n }\n return this.config as StateMachineConfig<TData>;\n }\n}\n\n/**\n * Create a new config builder instance\n *\n * @template TData - Type of the state machine's data context\n * @returns New ConfigBuilder instance\n *\n * @example\n * ```typescript\n * interface GameData {\n * balance: number;\n * bet: number;\n * }\n *\n * const config = createConfig<GameData>()\n * .initial('IDLE', 'NORMAL')\n * .initialData({ balance: 1000, bet: 10 })\n * .build();\n * ```\n */\nexport function createConfig<TData = any>(initialData?: TData): ConfigBuilder<TData> {\n return new ConfigBuilder<TData>(initialData);\n}\n","import type { TransitionGuard } from './types';\n\n/**\n * Built-in guard functions for common transition validation scenarios\n *\n * Guards control whether state transitions are allowed.\n * Return true to allow transition, false to block it.\n *\n * @example\n * ```typescript\n * import { guards } from '@rb-games/core/state-machine';\n *\n * .guard('canEnter', guards.and(\n * guards.hasData('balance'),\n * guards.dataGreaterThan('balance', 0)\n * ))\n * ```\n */\nexport const guards = {\n /**\n * Always allow transition\n *\n * @returns Guard that always returns true\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.always())\n * ```\n */\n always: (): TransitionGuard => () => true,\n\n /**\n * Never allow transition\n *\n * @returns Guard that always returns false\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.never())\n * ```\n */\n never: (): TransitionGuard => () => false,\n\n /**\n * Check if data key exists and is not null/undefined\n *\n * @template TData - Type of state data\n * @param key - Data key to check\n * @returns Guard that checks if key exists\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.hasData('balance'))\n * ```\n */\n hasData: <TData = any>(key: keyof TData): TransitionGuard<TData> => {\n return (context) => context.data[key] !== undefined && context.data[key] !== null;\n },\n\n /**\n * Check if data key equals a specific value\n *\n * @template TData - Type of state data\n * @param key - Data key to check\n * @param value - Value to compare against\n * @returns Guard that checks equality\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.dataEquals('gameMode', 'normal'))\n * ```\n */\n dataEquals: <TData = any>(key: keyof TData, value: any): TransitionGuard<TData> => {\n return (context) => context.data[key] === value;\n },\n\n /**\n * Check if data key is greater than a value\n *\n * @template TData - Type of state data\n * @param key - Data key to check (must be number)\n * @param value - Value to compare against\n * @returns Guard that checks if key > value\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.dataGreaterThan('balance', 0))\n * ```\n */\n dataGreaterThan: <TData = any>(key: keyof TData, value: number): TransitionGuard<TData> => {\n return (context) => (context.data[key] as number) > value;\n },\n\n /**\n * Check if data key is less than a value\n *\n * @template TData - Type of state data\n * @param key - Data key to check (must be number)\n * @param value - Value to compare against\n * @returns Guard that checks if key < value\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.dataLessThan('lives', 3))\n * ```\n */\n dataLessThan: <TData = any>(key: keyof TData, value: number): TransitionGuard<TData> => {\n return (context) => (context.data[key] as number) < value;\n },\n\n /**\n * Combine multiple guards with AND logic\n *\n * All guards must return true for transition to be allowed.\n *\n * @template TData - Type of state data\n * @param guards - Guards to combine\n * @returns Guard that checks all guards\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.and(\n * guards.hasData('balance'),\n * guards.dataGreaterThan('balance', 10),\n * (ctx) => ctx.data.isActive\n * ))\n * ```\n */\n and: <TData = any>(...guards: TransitionGuard<TData>[]): TransitionGuard<TData> => {\n return async (context) => {\n for (const guard of guards) {\n const result = await guard(context);\n if (!result) return false;\n }\n return true;\n };\n },\n\n /**\n * Combine multiple guards with OR logic\n *\n * At least one guard must return true for transition to be allowed.\n *\n * @template TData - Type of state data\n * @param guards - Guards to combine\n * @returns Guard that checks any guard\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.or(\n * guards.dataEquals('mode', 'demo'),\n * guards.dataGreaterThan('balance', 0)\n * ))\n * ```\n */\n or: <TData = any>(...guards: TransitionGuard<TData>[]): TransitionGuard<TData> => {\n return async (context) => {\n for (const guard of guards) {\n const result = await guard(context);\n if (result) return true;\n }\n return false;\n };\n },\n\n /**\n * Negate a guard (NOT logic)\n *\n * Returns opposite of the guard's result.\n *\n * @template TData - Type of state data\n * @param guard - Guard to negate\n * @returns Guard that returns opposite result\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.not(\n * guards.dataEquals('isLocked', true)\n * ))\n * ```\n */\n not: <TData = any>(guard: TransitionGuard<TData>): TransitionGuard<TData> => {\n return async (context) => !(await guard(context));\n },\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../../state-machine/StateMachine.ts","../../state-machine/ConfigBuilder.ts","../../state-machine/guards.ts"],"names":["merge","guards"],"mappings":"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","file":"index.js","sourcesContent":["import { EventEmitter } from 'pixi.js';\nimport merge from 'lodash/merge';\nimport type {\n StateKey,\n ModeKey,\n ScopeKey,\n StateContext,\n StateMachineConfig,\n TransitionOptions,\n StateDefinition,\n ScopeConfig,\n ConfigValue,\n StateMachineEvents,\n} from './types';\n\n/**\n * Event-driven state machine with two-level hierarchy (MODE/STATE).\n *\n * Features:\n * - Two-level structure: MODE (NORMAL, FREESPIN, BONUS) → STATE (IDLE, SPIN, MATCH)\n * - State inheritance with lodash merge\n * - Scope-based configuration (ui, scene, audio, etc.)\n * - Dynamic values via resolver functions\n * - Async lifecycle hooks (onEnter, onExit)\n * - Transition guards for validation\n * - Pixi.js EventEmitter for decoupled communication\n *\n * @example\n * ```typescript\n * const config = createConfig<GameData>()\n * .initial('IDLE', 'NORMAL')\n * .mode('NORMAL')\n * .state('IDLE')\n * .scope('ui', { spinButton: { enabled: true } })\n * .state('SPIN')\n * .extends('IDLE')\n * .guard('canEnter', (ctx) => ctx.data.balance >= ctx.data.bet)\n * .build();\n *\n * const machine = new StateMachine(config);\n * await machine.transition('SPIN');\n * ```\n *\n * @template TData - Type of the state machine's data context\n */\nexport class StateMachine<TData = any> extends EventEmitter<StateMachineEvents<TData>> {\n private config: StateMachineConfig<TData>;\n private context: StateContext<TData>;\n private isTransitioning = false;\n private resolvedStateCache = new Map<string, StateDefinition<TData>>();\n\n constructor(config: StateMachineConfig<TData>) {\n super();\n this.config = config;\n\n if (!this.config.modes[this.config.initialMode]) {\n throw new Error(`Initial mode \"${this.config.initialMode}\" not found in config`);\n }\n\n const initialMode = this.config.modes[this.config.initialMode];\n if (!initialMode.states[this.config.initialState]) {\n throw new Error(\n `Initial state \"${this.config.initialState}\" not found in mode \"${this.config.initialMode}\"`,\n );\n }\n\n this.context = {\n currentState: this.config.initialState,\n previousState: null,\n currentMode: this.config.initialMode,\n previousMode: null,\n timestamp: Date.now(),\n data: this.config.initialData ?? ({} as TData),\n metadata: {},\n };\n }\n\n /**\n * Current state key (e.g., 'IDLE', 'SPIN', 'MATCH')\n */\n get state(): StateKey {\n return this.context.currentState;\n }\n\n /**\n * Current mode key (e.g., 'NORMAL', 'FREESPIN', 'BONUS')\n */\n get mode(): ModeKey {\n return this.context.currentMode;\n }\n\n /**\n * Current state data (mutable)\n */\n get data(): TData {\n return this.context.data;\n }\n\n /**\n * Get a readonly copy of the current state context\n *\n * @returns Readonly state context with current state, mode, data, and metadata\n */\n getContext(): Readonly<StateContext<TData>> {\n return { ...this.context };\n }\n\n /**\n * Update state data using an updater function\n *\n * @param updater - Function that receives current data and optionally returns new data\n *\n * @example\n * ```typescript\n * machine.updateData(data => {\n * data.balance = 1000;\n * data.bet = 10;\n * });\n * ```\n */\n updateData(updater: (data: TData) => TData | void): void {\n const result = updater(this.context.data);\n if (result !== undefined) {\n this.context.data = result;\n }\n }\n\n private resolveStateDefinition(state: StateKey, mode?: ModeKey): StateDefinition<TData> {\n const modeKey = mode ?? this.context.currentMode;\n const cacheKey = `${modeKey}:${state}`;\n\n if (this.resolvedStateCache.has(cacheKey)) {\n return this.resolvedStateCache.get(cacheKey)!;\n }\n\n const currentMode = this.config.modes[modeKey];\n const stateDef = currentMode.states[state];\n\n if (!stateDef) {\n throw new Error(`State \"${state}\" not found in mode \"${modeKey}\"`);\n }\n\n if (!stateDef.extends) {\n this.resolvedStateCache.set(cacheKey, stateDef);\n return stateDef;\n }\n\n const chain: StateDefinition<TData>[] = [];\n const visited = new Set<StateKey>();\n let current = stateDef;\n let currentKey = state;\n\n while (current) {\n if (visited.has(currentKey)) {\n throw new Error(`Circular extends detected in state \"${state}\"`);\n }\n visited.add(currentKey);\n chain.unshift(current);\n\n if (current.extends) {\n const parentKey = current.extends;\n const parent = currentMode.states[parentKey];\n if (!parent) {\n throw new Error(`Parent state \"${parentKey}\" not found for state \"${state}\"`);\n }\n current = parent;\n currentKey = parentKey;\n } else {\n break;\n }\n }\n\n const resolved = merge({}, ...chain);\n delete resolved.extends;\n\n // Behavioral properties (guards, hooks) are NOT inherited via extends.\n // Only scopes and metadata are inherited. Each state must define its own guards/hooks.\n resolved.guards = stateDef.guards;\n resolved.onEnter = stateDef.onEnter;\n resolved.onExit = stateDef.onExit;\n\n this.resolvedStateCache.set(cacheKey, resolved);\n return resolved;\n }\n\n private resolveScopeData(scopeConfig: ScopeConfig<TData> | undefined): Record<ScopeKey, any> {\n if (!scopeConfig) return {};\n\n const resolved: Record<ScopeKey, any> = {};\n\n for (const [scopeName, scopeData] of Object.entries(scopeConfig)) {\n resolved[scopeName] = {};\n\n for (const [componentName, componentData] of Object.entries(scopeData)) {\n resolved[scopeName][componentName] = {};\n\n for (const [propName, propValue] of Object.entries(componentData)) {\n resolved[scopeName][componentName][propName] = this.resolveValue(propValue);\n }\n }\n }\n\n return resolved;\n }\n\n private resolveValue<T>(value: ConfigValue<TData, T>): T {\n if (typeof value === 'function') {\n return (value as Function)(this.context);\n }\n return value as T;\n }\n\n /**\n * Get resolved scope data for a specific scope\n *\n * @param scopeName - Name of the scope (e.g., 'ui', 'scene', 'audio')\n * @returns Resolved scope data with all resolver functions evaluated\n *\n * @example\n * ```typescript\n * const uiState = machine.getScope('ui');\n * console.log(uiState.spinButton.enabled); // true\n * ```\n */\n getScope(scopeName: ScopeKey): any {\n const resolvedState = this.resolveStateDefinition(this.context.currentState);\n const scopeData = this.resolveScopeData(resolvedState.scopes);\n return scopeData[scopeName] ?? {};\n }\n\n /**\n * Get all resolved scope data for the current state\n *\n * @returns Object containing all scopes with resolved data\n *\n * @example\n * ```typescript\n * const scopes = machine.getAllScopes();\n * console.log(scopes.ui); // UI scope data\n * console.log(scopes.scene); // Scene scope data\n * ```\n */\n getAllScopes(): Record<ScopeKey, any> {\n const resolvedState = this.resolveStateDefinition(this.context.currentState);\n return this.resolveScopeData(resolvedState.scopes);\n }\n\n /**\n * Transition to a new state within the current mode\n *\n * This is an async operation that:\n * 1. Checks guards (canExit, canEnter)\n * 2. Calls onExit hook of current state\n * 3. Changes the state\n * 4. Calls onEnter hook of target state\n * 5. Emits events (state:exit, state:enter, state:change, scope:update)\n *\n * @param targetState - Target state key to transition to\n * @param options - Transition options\n * @param options.force - Skip guard checks and force transition\n * @param options.silent - Skip event emissions\n * @returns Promise that resolves to true if transition succeeded, false otherwise\n *\n * @example\n * ```typescript\n * // Normal transition\n * await machine.transition('SPIN');\n *\n * // Force transition (skip guards)\n * await machine.transition('SPIN', { force: true });\n *\n * // Silent transition (no events)\n * await machine.transition('SPIN', { silent: true });\n * ```\n *\n * @fires state:exit - When exiting current state\n * @fires state:enter - When entering target state\n * @fires state:change - After state change completes\n * @fires scope:update - For each scope after state change\n * @fires transition:blocked - If guard check fails\n * @fires error - If an error occurs during transition\n */\n async transition(targetState: StateKey, options: TransitionOptions = {}): Promise<boolean> {\n if (this.isTransitioning && !options.force) {\n console.warn('Transition already in progress');\n return false;\n }\n\n const fromState = this.context.currentState;\n if (fromState === targetState) {\n return true;\n }\n\n const currentMode = this.config.modes[this.context.currentMode];\n if (!currentMode.states[targetState]) {\n const error = new Error(\n `State \"${targetState}\" not found in mode \"${this.context.currentMode}\"`,\n );\n if (this.config.strict) {\n throw error;\n }\n this.emit('error', error, this.context);\n return false;\n }\n\n if (!options.force) {\n const canTransition = await this.checkGuards(fromState, targetState);\n if (!canTransition.allowed) {\n this.emit(\n 'transition:blocked',\n fromState,\n targetState,\n canTransition.reason || 'Guard check failed',\n this.context,\n );\n return false;\n }\n }\n\n this.isTransitioning = true;\n\n try {\n if (!options.silent) {\n this.emit('transition:start', fromState, targetState, this.context);\n }\n\n const fromStateDef = this.resolveStateDefinition(fromState);\n if (fromStateDef.onExit) {\n await fromStateDef.onExit(this.context);\n }\n\n if (!options.silent) {\n this.emit('state:exit', fromState, this.context);\n }\n\n const previousState = this.context.currentState;\n this.context = {\n ...this.context,\n currentState: targetState,\n previousState,\n timestamp: Date.now(),\n };\n\n const toStateDef = this.resolveStateDefinition(targetState);\n if (toStateDef.onEnter) {\n await toStateDef.onEnter(this.context);\n }\n\n if (!options.silent) {\n this.emit('state:enter', targetState, this.context);\n this.emit('state:change', fromState, targetState, this.context);\n\n const scopes = this.getAllScopes();\n for (const [scopeName, scopeData] of Object.entries(scopes)) {\n this.emit('scope:update', scopeName, scopeData, this.context);\n this.emit(`scope:update:${scopeName}` as any, scopeData, this.context);\n }\n\n this.emit('transition:complete', fromState, targetState, this.context);\n }\n\n return true;\n } catch (error) {\n this.emit('error', error as Error, this.context);\n return false;\n } finally {\n this.isTransitioning = false;\n }\n }\n\n /**\n * Change to a different mode with an optional initial state\n *\n * This will:\n * 1. Call onExit hook of current mode\n * 2. Clear state resolution cache\n * 3. Change mode and state\n * 4. Call onEnter hook of target mode\n * 5. Call onEnter hook of initial state\n * 6. Emit events\n *\n * @param targetMode - Target mode key to switch to\n * @param initialState - Optional initial state in the target mode (defaults to config.initialState)\n * @returns Promise that resolves to true if mode change succeeded, false otherwise\n *\n * @example\n * ```typescript\n * // Switch to freespin mode\n * await machine.changeMode('FREESPIN', 'IDLE');\n *\n * // Return to normal mode\n * await machine.changeMode('NORMAL', 'IDLE');\n * ```\n *\n * @fires mode:exit - When exiting current mode\n * @fires mode:enter - When entering target mode\n * @fires mode:change - After mode change completes\n * @fires state:enter - When entering initial state\n * @fires scope:update - For each scope after mode change\n */\n async changeMode(targetMode: ModeKey, initialState?: StateKey): Promise<boolean> {\n if (this.context.currentMode === targetMode) {\n return true;\n }\n\n const targetModeDef = this.config.modes[targetMode];\n if (!targetModeDef) {\n const error = new Error(`Mode \"${targetMode}\" not found`);\n if (this.config.strict) {\n throw error;\n }\n this.emit('error', error, this.context);\n return false;\n }\n\n const targetState = initialState ?? this.config.initialState;\n if (!targetModeDef.states[targetState]) {\n const error = new Error(`State \"${targetState}\" not found in mode \"${targetMode}\"`);\n if (this.config.strict) {\n throw error;\n }\n this.emit('error', error, this.context);\n return false;\n }\n\n const fromMode = this.context.currentMode;\n const currentModeDef = this.config.modes[fromMode];\n\n try {\n if (currentModeDef.onExit) {\n await currentModeDef.onExit(this.context);\n }\n\n this.emit('mode:exit', fromMode, this.context);\n\n this.resolvedStateCache.clear();\n\n const previousMode = this.context.currentMode;\n this.context = {\n ...this.context,\n currentMode: targetMode,\n previousMode,\n currentState: targetState,\n previousState: this.context.currentState,\n timestamp: Date.now(),\n };\n\n if (targetModeDef.onEnter) {\n await targetModeDef.onEnter(this.context);\n }\n\n this.emit('mode:enter', targetMode, this.context);\n this.emit('mode:change', fromMode, targetMode, this.context);\n\n const toStateDef = this.resolveStateDefinition(targetState);\n if (toStateDef.onEnter) {\n await toStateDef.onEnter(this.context);\n }\n\n this.emit('state:enter', targetState, this.context);\n\n const scopes = this.getAllScopes();\n for (const [scopeName, scopeData] of Object.entries(scopes)) {\n this.emit('scope:update', scopeName, scopeData, this.context);\n this.emit(`scope:update:${scopeName}` as any, scopeData, this.context);\n }\n\n return true;\n } catch (error) {\n this.emit('error', error as Error, this.context);\n return false;\n }\n }\n\n /**\n * Check if a state exists in the current mode (synchronous, no guard check)\n *\n * @param targetState - State key to check\n * @returns True if state exists in current mode, false otherwise\n *\n * @example\n * ```typescript\n * if (machine.can('SPIN')) {\n * console.log('SPIN state exists');\n * }\n * ```\n */\n can(targetState: StateKey): boolean {\n const currentMode = this.config.modes[this.context.currentMode];\n return !!currentMode?.states[targetState];\n }\n\n /**\n * Check if transition to a state is allowed (async, includes guard check)\n *\n * @param targetState - State key to check\n * @returns Promise that resolves to true if transition is allowed, false otherwise\n *\n * @example\n * ```typescript\n * if (await machine.canAsync('SPIN')) {\n * await machine.transition('SPIN');\n * } else {\n * console.log('Cannot transition to SPIN');\n * }\n * ```\n */\n async canAsync(targetState: StateKey): Promise<boolean> {\n const result = await this.checkGuards(this.context.currentState, targetState);\n return result.allowed;\n }\n\n private async checkGuards(\n fromState: StateKey,\n toState: StateKey,\n ): Promise<{ allowed: boolean; reason?: string }> {\n const fromStateDef = this.resolveStateDefinition(fromState);\n const toStateDef = this.resolveStateDefinition(toState);\n\n if (fromStateDef.guards?.canExit) {\n const canExit = await fromStateDef.guards.canExit(this.context);\n if (!canExit) {\n return { allowed: false, reason: `Cannot exit state \"${fromState}\"` };\n }\n }\n\n if (toStateDef.guards?.canEnter) {\n const canEnter = await toStateDef.guards.canEnter(this.context);\n if (!canEnter) {\n return { allowed: false, reason: `Cannot enter state \"${toState}\"` };\n }\n }\n\n return { allowed: true };\n }\n\n /**\n * Check if current state matches the given state key\n *\n * @param state - State key to compare\n * @returns True if current state matches, false otherwise\n *\n * @example\n * ```typescript\n * if (machine.is('SPIN')) {\n * console.log('Currently spinning');\n * }\n * ```\n */\n is(state: StateKey): boolean {\n return this.context.currentState === state;\n }\n\n /**\n * Check if current mode matches the given mode key\n *\n * @param mode - Mode key to compare\n * @returns True if current mode matches, false otherwise\n *\n * @example\n * ```typescript\n * if (machine.isMode('FREESPIN')) {\n * console.log('In freespin mode');\n * }\n * ```\n */\n isMode(mode: ModeKey): boolean {\n return this.context.currentMode === mode;\n }\n\n /**\n * Reset state machine to initial state and mode\n *\n * Clears cache and resets context to initial configuration\n *\n * @example\n * ```typescript\n * machine.reset();\n * console.log(machine.state); // Initial state\n * console.log(machine.mode); // Initial mode\n * ```\n */\n reset(): void {\n this.resolvedStateCache.clear();\n this.context = {\n currentState: this.config.initialState,\n previousState: null,\n currentMode: this.config.initialMode,\n previousMode: null,\n timestamp: Date.now(),\n data: this.config.initialData ?? ({} as TData),\n metadata: {},\n };\n }\n\n /**\n * Destroy state machine and clean up resources\n *\n * Clears cache and removes all event listeners\n *\n * @example\n * ```typescript\n * machine.destroy();\n * ```\n */\n destroy(): void {\n this.resolvedStateCache.clear();\n this.removeAllListeners();\n }\n}\n","import type {\n StateKey,\n ModeKey,\n ScopeKey,\n StateDefinition,\n StateMachineConfig,\n StateHook,\n TransitionGuard,\n} from './types';\n\n/**\n * Fluent API builder for creating state machine configurations\n *\n * Provides a chainable interface for defining modes, states, scopes, hooks, and guards.\n *\n * @example\n * ```typescript\n * const config = createConfig<GameData>()\n * .initial('IDLE', 'NORMAL')\n * .initialData({ balance: 1000 })\n * .mode('NORMAL')\n * .state('IDLE')\n * .scope('ui', { spinButton: { enabled: true } })\n * .state('SPIN')\n * .extends('IDLE')\n * .guard('canEnter', (ctx) => ctx.data.balance >= ctx.data.bet)\n * .build();\n * ```\n *\n * @template TData - Type of the state machine's data context\n */\nexport class ConfigBuilder<TData = any> {\n constructor(initialData?: TData) {\n this.config.initialData = initialData;\n }\n\n private config: Partial<StateMachineConfig<TData>> = {\n modes: {},\n };\n private currentMode: ModeKey | null = null;\n private currentState: StateKey | null = null;\n\n /**\n * Define a new mode or switch to an existing mode\n *\n * @param name - Mode key (e.g., 'NORMAL', 'FREESPIN', 'BONUS')\n * @returns This builder for chaining\n */\n mode(name: ModeKey): this {\n this.currentMode = name;\n if (!this.config.modes![name]) {\n this.config.modes![name] = { states: {} };\n }\n return this;\n }\n\n /**\n * Define a new state in the current mode\n *\n * @param name - State key (e.g., 'IDLE', 'SPIN', 'MATCH')\n * @returns This builder for chaining\n * @throws Error if mode() hasn't been called first\n */\n state(name: StateKey): this {\n if (!this.currentMode) {\n throw new Error('Must call mode() before state()');\n }\n this.currentState = name;\n const mode = this.config.modes![this.currentMode];\n if (!mode.states[name]) {\n mode.states[name] = {};\n }\n return this;\n }\n\n /**\n * Make current state extend from a parent state (inheritance)\n *\n * Child state will inherit all properties from parent state using lodash merge.\n * Child properties override parent properties.\n *\n * @param parentState - Parent state key to extend from\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .state('IDLE')\n * .scope('ui', { spinButton: { enabled: true, icon: 'spin' } })\n *\n * .state('SPIN')\n * .extends('IDLE') // Inherits from IDLE\n * .scope('ui', { spinButton: { icon: 'stop' } }) // Only override icon\n * ```\n */\n extends(parentState: StateKey): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before extends()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.extends = parentState;\n return this;\n }\n\n /**\n * Define scope configuration for current state\n *\n * Scopes organize related configuration (ui, scene, audio, etc.).\n * Values can be static or resolver functions.\n *\n * @param scopeName - Scope key (e.g., 'ui', 'scene', 'audio')\n * @param scopeData - Scope configuration object\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .scope('ui', {\n * spinButton: {\n * enabled: true,\n * icon: (ctx) => ctx.data.isQuickSpin ? 'quick_spin' : 'spin',\n * },\n * betButtons: { enabled: false },\n * })\n * .scope('scene', {\n * reels: { spinning: true },\n * })\n * ```\n */\n scope(scopeName: ScopeKey, scopeData: Record<string, Record<string, any>>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before scope()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n if (!state.scopes) {\n state.scopes = {};\n }\n state.scopes[scopeName] = scopeData;\n return this;\n }\n\n /**\n * Add onEnter lifecycle hook to current state\n *\n * Called when entering this state. Can be async.\n * Transition waits for this hook to complete.\n *\n * @param hook - Lifecycle hook function\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .onEnter(async (ctx) => {\n * ctx.data.balance -= ctx.data.bet;\n * await scene.playAnimation();\n * })\n * ```\n */\n onEnter(hook: StateHook<TData>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before onEnter()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.onEnter = hook;\n return this;\n }\n\n /**\n * Add onExit lifecycle hook to current state\n *\n * Called when exiting this state. Can be async.\n * Transition waits for this hook to complete.\n *\n * @param hook - Lifecycle hook function\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .onExit(async (ctx) => {\n * await scene.cleanup();\n * })\n * ```\n */\n onExit(hook: StateHook<TData>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before onExit()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.onExit = hook;\n return this;\n }\n\n /**\n * Add transition guard to current state\n *\n * Guards control whether transitions are allowed.\n * Return false to block transition.\n *\n * @param type - Guard type ('canEnter' or 'canExit')\n * @param guard - Guard function\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n *\n * @example\n * ```typescript\n * .guard('canEnter', (ctx) => ctx.data.balance >= ctx.data.bet)\n * .guard('canExit', (ctx) => !ctx.data.isLocked)\n * ```\n */\n guard(type: 'canEnter' | 'canExit', guard: TransitionGuard<TData>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before guard()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n if (!state.guards) {\n state.guards = {};\n }\n state.guards[type] = guard;\n return this;\n }\n\n /**\n * Add metadata to current state\n *\n * @param data - Metadata object\n * @returns This builder for chaining\n * @throws Error if mode() and state() haven't been called first\n */\n metadata(data: Record<string, any>): this {\n if (!this.currentMode || !this.currentState) {\n throw new Error('Must call mode() and state() before metadata()');\n }\n const state = this.config.modes![this.currentMode].states[this.currentState];\n state.metadata = { ...state.metadata, ...data };\n return this;\n }\n\n /**\n * Add lifecycle hook to current mode\n *\n * @param type - Hook type ('onEnter' or 'onExit')\n * @param hook - Lifecycle hook function\n * @returns This builder for chaining\n * @throws Error if mode() hasn't been called first\n *\n * @example\n * ```typescript\n * .mode('FREESPIN')\n * .modeHook('onEnter', (ctx) => {\n * ctx.data.freeSpinsRemaining = 10;\n * })\n * ```\n */\n modeHook(type: 'onEnter' | 'onExit', hook: StateHook<TData>): this {\n if (!this.currentMode) {\n throw new Error('Must call mode() before modeHook()');\n }\n const mode = this.config.modes![this.currentMode];\n mode[type] = hook;\n return this;\n }\n\n /**\n * Set initial state and mode\n *\n * @param state - Initial state key\n * @param mode - Initial mode key\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .initial('IDLE', 'NORMAL')\n * ```\n */\n initial(state: StateKey, mode: ModeKey): this {\n this.config.initialState = state;\n this.config.initialMode = mode;\n return this;\n }\n\n /**\n * Set initial data for state context\n *\n * @param data - Initial data object\n * @returns This builder for chaining\n *\n * @example\n * ```typescript\n * .initialData({ balance: 1000, bet: 10 })\n * ```\n */\n initialData(data: TData): this {\n this.config.initialData = data;\n return this;\n }\n\n /**\n * Enable strict mode (throws errors instead of emitting error events)\n *\n * @param value - Enable strict mode (default: true)\n * @returns This builder for chaining\n */\n strict(value = true): this {\n this.config.strict = value;\n return this;\n }\n\n /**\n * Build and return the final state machine configuration\n *\n * @returns Complete state machine configuration\n * @throws Error if initial state and mode haven't been set\n *\n * @example\n * ```typescript\n * const config = createConfig()\n * .initial('IDLE', 'NORMAL')\n * .mode('NORMAL')\n * .state('IDLE')\n * .build();\n * ```\n */\n build(): StateMachineConfig<TData> {\n if (!this.config.initialState || !this.config.initialMode) {\n throw new Error('Must set initial state and mode');\n }\n return this.config as StateMachineConfig<TData>;\n }\n}\n\n/**\n * Create a new config builder instance\n *\n * @template TData - Type of the state machine's data context\n * @returns New ConfigBuilder instance\n *\n * @example\n * ```typescript\n * interface GameData {\n * balance: number;\n * bet: number;\n * }\n *\n * const config = createConfig<GameData>()\n * .initial('IDLE', 'NORMAL')\n * .initialData({ balance: 1000, bet: 10 })\n * .build();\n * ```\n */\nexport function createConfig<TData = any>(initialData?: TData): ConfigBuilder<TData> {\n return new ConfigBuilder<TData>(initialData);\n}\n","import type { TransitionGuard } from './types';\n\n/**\n * Built-in guard functions for common transition validation scenarios\n *\n * Guards control whether state transitions are allowed.\n * Return true to allow transition, false to block it.\n *\n * @example\n * ```typescript\n * import { guards } from '@rb-games/core/state-machine';\n *\n * .guard('canEnter', guards.and(\n * guards.hasData('balance'),\n * guards.dataGreaterThan('balance', 0)\n * ))\n * ```\n */\nexport const guards = {\n /**\n * Always allow transition\n *\n * @returns Guard that always returns true\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.always())\n * ```\n */\n always: (): TransitionGuard => () => true,\n\n /**\n * Never allow transition\n *\n * @returns Guard that always returns false\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.never())\n * ```\n */\n never: (): TransitionGuard => () => false,\n\n /**\n * Check if data key exists and is not null/undefined\n *\n * @template TData - Type of state data\n * @param key - Data key to check\n * @returns Guard that checks if key exists\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.hasData('balance'))\n * ```\n */\n hasData: <TData = any>(key: keyof TData): TransitionGuard<TData> => {\n return (context) => context.data[key] !== undefined && context.data[key] !== null;\n },\n\n /**\n * Check if data key equals a specific value\n *\n * @template TData - Type of state data\n * @param key - Data key to check\n * @param value - Value to compare against\n * @returns Guard that checks equality\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.dataEquals('gameMode', 'normal'))\n * ```\n */\n dataEquals: <TData = any>(key: keyof TData, value: any): TransitionGuard<TData> => {\n return (context) => context.data[key] === value;\n },\n\n /**\n * Check if data key is greater than a value\n *\n * @template TData - Type of state data\n * @param key - Data key to check (must be number)\n * @param value - Value to compare against\n * @returns Guard that checks if key > value\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.dataGreaterThan('balance', 0))\n * ```\n */\n dataGreaterThan: <TData = any>(key: keyof TData, value: number): TransitionGuard<TData> => {\n return (context) => (context.data[key] as number) > value;\n },\n\n /**\n * Check if data key is less than a value\n *\n * @template TData - Type of state data\n * @param key - Data key to check (must be number)\n * @param value - Value to compare against\n * @returns Guard that checks if key < value\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.dataLessThan('lives', 3))\n * ```\n */\n dataLessThan: <TData = any>(key: keyof TData, value: number): TransitionGuard<TData> => {\n return (context) => (context.data[key] as number) < value;\n },\n\n /**\n * Combine multiple guards with AND logic\n *\n * All guards must return true for transition to be allowed.\n *\n * @template TData - Type of state data\n * @param guards - Guards to combine\n * @returns Guard that checks all guards\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.and(\n * guards.hasData('balance'),\n * guards.dataGreaterThan('balance', 10),\n * (ctx) => ctx.data.isActive\n * ))\n * ```\n */\n and: <TData = any>(...guards: TransitionGuard<TData>[]): TransitionGuard<TData> => {\n return async (context) => {\n for (const guard of guards) {\n const result = await guard(context);\n if (!result) return false;\n }\n return true;\n };\n },\n\n /**\n * Combine multiple guards with OR logic\n *\n * At least one guard must return true for transition to be allowed.\n *\n * @template TData - Type of state data\n * @param guards - Guards to combine\n * @returns Guard that checks any guard\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.or(\n * guards.dataEquals('mode', 'demo'),\n * guards.dataGreaterThan('balance', 0)\n * ))\n * ```\n */\n or: <TData = any>(...guards: TransitionGuard<TData>[]): TransitionGuard<TData> => {\n return async (context) => {\n for (const guard of guards) {\n const result = await guard(context);\n if (result) return true;\n }\n return false;\n };\n },\n\n /**\n * Negate a guard (NOT logic)\n *\n * Returns opposite of the guard's result.\n *\n * @template TData - Type of state data\n * @param guard - Guard to negate\n * @returns Guard that returns opposite result\n *\n * @example\n * ```typescript\n * .guard('canEnter', guards.not(\n * guards.dataEquals('isLocked', true)\n * ))\n * ```\n */\n not: <TData = any>(guard: TransitionGuard<TData>): TransitionGuard<TData> => {\n return async (context) => !(await guard(context));\n },\n};\n"]}
|
package/dist/store/index.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import '../chunk-G3PMV62Z.js';
|
|
2
2
|
import { EventEmitter } from 'pixi.js';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var _DataStore = class _DataStore extends EventEmitter {
|
|
5
5
|
constructor(contextId, initialData) {
|
|
6
6
|
super();
|
|
7
7
|
this.contextId = contextId;
|
|
8
8
|
this._data = initialData;
|
|
9
9
|
this._proxy = this.createProxy(initialData);
|
|
10
10
|
}
|
|
11
|
-
static instances = /* @__PURE__ */ new Map();
|
|
12
|
-
_data;
|
|
13
|
-
_proxy;
|
|
14
11
|
/**
|
|
15
12
|
* Create a Proxy that intercepts property access and mutations
|
|
16
13
|
*/
|
|
@@ -191,6 +188,8 @@ var DataStore = class _DataStore extends EventEmitter {
|
|
|
191
188
|
this.emit("data:updated", this._proxy, "reset", initialData);
|
|
192
189
|
}
|
|
193
190
|
};
|
|
191
|
+
_DataStore.instances = /* @__PURE__ */ new Map();
|
|
192
|
+
var DataStore = _DataStore;
|
|
194
193
|
|
|
195
194
|
export { DataStore };
|
|
196
195
|
//# sourceMappingURL=index.js.map
|
package/dist/store/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../store/DataStore.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { EventEmitter } from 'pixi.js';\n\n/**\n * Events emitted by DataStore when data changes\n * Generic event structure for any property change\n */\nexport interface DataStoreEvents<T = any> {\n 'data:updated': (data: T, property: keyof T, value: any) => void;\n [key: `property:${string}`]: (value: any, oldValue: any) => void;\n}\n\n/**\n * Context-based singleton data store with Proxy pattern for reactive state management.\n *\n * Provides centralized, type-safe, reactive state management with automatic event emission.\n * Uses Proxy to intercept property access and mutations, enabling 2-way binding.\n *\n * @template T - Type of the data structure to store\n *\n * @example\n * ```typescript\n * interface GameData {\n * config: ConfigContext;\n * platform: Platform;\n * bet: number;\n * }\n *\n * // Create instance with initial data\n * const store = DataStore.createInstance<GameData>('Game', {\n * config: {} as ConfigContext,\n * platform: {} as Platform,\n * bet: 10,\n * });\n *\n * // Access properties - fully type-safe\n * const balance = store.data.platform.balance;\n *\n * // Mutations automatically emit events\n * store.data.bet = 20; // Emits 'property:bet' and 'data:updated'\n *\n * // Listen to specific property changes\n * store.on('property:bet', (newValue, oldValue) => {\n * console.log(`Bet changed from ${oldValue} to ${newValue}`);\n * });\n *\n * // Listen to any data change\n * store.on('data:updated', (data, property, value) => {\n * console.log(`${String(property)} changed to`, value);\n * });\n *\n * // Cleanup\n * DataStore.destroyInstance('Game');\n * ```\n */\nexport class DataStore<T extends Record<string, any> = any> extends EventEmitter<\n DataStoreEvents<T>\n> {\n private static instances = new Map<string, DataStore<any>>();\n\n private _data: T;\n private _proxy: T;\n\n private constructor(\n private readonly contextId: string,\n initialData: T,\n ) {\n super();\n this._data = initialData;\n this._proxy = this.createProxy(initialData);\n }\n\n /**\n * Create a Proxy that intercepts property access and mutations\n */\n private createProxy(target: T): T {\n return new Proxy(target, {\n get: (obj, prop) => {\n const value = obj[prop as keyof T];\n\n // If value is an object, wrap it in a proxy too (deep reactivity)\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return this.createNestedProxy(value, prop as string);\n }\n\n return value;\n },\n\n set: (obj, prop, value) => {\n const oldValue = obj[prop as keyof T];\n\n // Only emit if value actually changed\n if (oldValue !== value) {\n obj[prop as keyof T] = value;\n\n // Emit specific property change event\n this.emit(`property:${String(prop)}` as any, value, oldValue);\n\n // Emit general data updated event\n this.emit('data:updated', this._proxy, prop as keyof T, value);\n }\n\n return true;\n },\n });\n }\n\n /**\n * Create nested proxy for deep reactivity\n */\n private createNestedProxy(target: any, parentKey: string): any {\n return new Proxy(target, {\n set: (obj, prop, value) => {\n const oldValue = obj[prop];\n\n if (oldValue !== value) {\n obj[prop] = value;\n\n // Emit nested property change\n const fullPath = `${parentKey}.${String(prop)}`;\n this.emit(`property:${fullPath}` as any, value, oldValue);\n this.emit('data:updated', this._proxy, parentKey as keyof T, target);\n }\n\n return true;\n },\n });\n }\n\n /**\n * Get reactive data proxy\n */\n get data(): T {\n return this._proxy;\n }\n\n /**\n * Get raw data (non-reactive)\n */\n getRawData(): T {\n return this._data;\n }\n\n /**\n * Create or get existing instance for a context.\n *\n * @template T - Type of the data structure\n * @param contextId - Unique identifier for the game context (e.g., \"Game\", \"FreeSpinGame\")\n * @param initialData - Initial data structure\n * @returns DataStore instance for the specified context\n *\n * @example\n * ```typescript\n * interface GameData {\n * config: ConfigContext;\n * platform: Platform;\n * bet: number;\n * }\n *\n * const store = DataStore.createInstance<GameData>('Game', {\n * config: {} as ConfigContext,\n * platform: {} as Platform,\n * bet: 10,\n * });\n * ```\n */\n static createInstance<T extends Record<string, any>>(\n contextId: string,\n initialData: T,\n ): DataStore<T> {\n if (!DataStore.instances.has(contextId)) {\n const instance = new DataStore<T>(contextId, initialData);\n DataStore.instances.set(contextId, instance);\n }\n return DataStore.instances.get(contextId)! as DataStore<T>;\n }\n\n /**\n * Get existing instance for a context.\n *\n * @template T - Type of the data structure\n * @param contextId - Unique identifier for the game context\n * @returns DataStore instance for the specified context\n * @throws Error if instance doesn't exist\n *\n * @example\n * ```typescript\n * const store = DataStore.getInstance<GameData>('Game');\n * ```\n */\n static getInstance<T extends Record<string, any> = any>(contextId: string): DataStore<T> {\n const instance = DataStore.instances.get(contextId);\n if (!instance) {\n throw new Error(`DataStore instance \"${contextId}\" not found. Call createInstance() first.`);\n }\n return instance as DataStore<T>;\n }\n\n /**\n * Check if instance exists for a context.\n *\n * @param contextId - Unique identifier for the game context\n * @returns True if instance exists, false otherwise\n */\n static hasInstance(contextId: string): boolean {\n return DataStore.instances.has(contextId);\n }\n\n /**\n * Destroy instance for a context and cleanup all listeners.\n *\n * @param contextId - Unique identifier for the game context\n *\n * @example\n * ```typescript\n * DataStore.destroyInstance('BonusGame');\n * ```\n */\n static destroyInstance(contextId: string): void {\n const instance = DataStore.instances.get(contextId);\n if (instance) {\n instance.removeAllListeners();\n DataStore.instances.delete(contextId);\n }\n }\n\n /**\n * Get all active context IDs.\n *\n * @returns Array of context IDs\n */\n static getActiveContexts(): string[] {\n return Array.from(DataStore.instances.keys());\n }\n\n /**\n * Destroy all instances and cleanup.\n */\n static destroyAll(): void {\n const contexts = Array.from(DataStore.instances.keys());\n for (const contextId of contexts) {\n DataStore.destroyInstance(contextId);\n }\n }\n\n /**\n * Get context ID of this instance.\n */\n getContextId(): string {\n return this.contextId;\n }\n\n /**\n * Update multiple properties at once without triggering individual events.\n * Useful for batch updates.\n *\n * @param updates - Partial data to update\n *\n * @example\n * ```typescript\n * store.batchUpdate({\n * bet: 20,\n * isQuickSpin: true,\n * });\n * ```\n */\n batchUpdate(updates: Partial<T>): void {\n Object.assign(this._data, updates);\n this.emit('data:updated', this._proxy, 'batch' as keyof T, updates);\n }\n\n /**\n * Reset store to initial state.\n *\n * @param initialData - New initial data\n */\n reset(initialData: T): void {\n this._data = initialData;\n this._proxy = this.createProxy(initialData);\n this.emit('data:updated', this._proxy, 'reset' as keyof T, initialData);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../store/DataStore.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { EventEmitter } from 'pixi.js';\n\n/**\n * Events emitted by DataStore when data changes\n * Generic event structure for any property change\n */\nexport interface DataStoreEvents<T = any> {\n 'data:updated': (data: T, property: keyof T, value: any) => void;\n [key: `property:${string}`]: (value: any, oldValue: any) => void;\n}\n\n/**\n * Context-based singleton data store with Proxy pattern for reactive state management.\n *\n * Provides centralized, type-safe, reactive state management with automatic event emission.\n * Uses Proxy to intercept property access and mutations, enabling 2-way binding.\n *\n * @template T - Type of the data structure to store\n *\n * @example\n * ```typescript\n * interface GameData {\n * config: ConfigContext;\n * platform: Platform;\n * bet: number;\n * }\n *\n * // Create instance with initial data\n * const store = DataStore.createInstance<GameData>('Game', {\n * config: {} as ConfigContext,\n * platform: {} as Platform,\n * bet: 10,\n * });\n *\n * // Access properties - fully type-safe\n * const balance = store.data.platform.balance;\n *\n * // Mutations automatically emit events\n * store.data.bet = 20; // Emits 'property:bet' and 'data:updated'\n *\n * // Listen to specific property changes\n * store.on('property:bet', (newValue, oldValue) => {\n * console.log(`Bet changed from ${oldValue} to ${newValue}`);\n * });\n *\n * // Listen to any data change\n * store.on('data:updated', (data, property, value) => {\n * console.log(`${String(property)} changed to`, value);\n * });\n *\n * // Cleanup\n * DataStore.destroyInstance('Game');\n * ```\n */\nexport class DataStore<T extends Record<string, any> = any> extends EventEmitter<\n DataStoreEvents<T>\n> {\n private static instances = new Map<string, DataStore<any>>();\n\n private _data: T;\n private _proxy: T;\n\n private constructor(\n private readonly contextId: string,\n initialData: T,\n ) {\n super();\n this._data = initialData;\n this._proxy = this.createProxy(initialData);\n }\n\n /**\n * Create a Proxy that intercepts property access and mutations\n */\n private createProxy(target: T): T {\n return new Proxy(target, {\n get: (obj, prop) => {\n const value = obj[prop as keyof T];\n\n // If value is an object, wrap it in a proxy too (deep reactivity)\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n return this.createNestedProxy(value, prop as string);\n }\n\n return value;\n },\n\n set: (obj, prop, value) => {\n const oldValue = obj[prop as keyof T];\n\n // Only emit if value actually changed\n if (oldValue !== value) {\n obj[prop as keyof T] = value;\n\n // Emit specific property change event\n this.emit(`property:${String(prop)}` as any, value, oldValue);\n\n // Emit general data updated event\n this.emit('data:updated', this._proxy, prop as keyof T, value);\n }\n\n return true;\n },\n });\n }\n\n /**\n * Create nested proxy for deep reactivity\n */\n private createNestedProxy(target: any, parentKey: string): any {\n return new Proxy(target, {\n set: (obj, prop, value) => {\n const oldValue = obj[prop];\n\n if (oldValue !== value) {\n obj[prop] = value;\n\n // Emit nested property change\n const fullPath = `${parentKey}.${String(prop)}`;\n this.emit(`property:${fullPath}` as any, value, oldValue);\n this.emit('data:updated', this._proxy, parentKey as keyof T, target);\n }\n\n return true;\n },\n });\n }\n\n /**\n * Get reactive data proxy\n */\n get data(): T {\n return this._proxy;\n }\n\n /**\n * Get raw data (non-reactive)\n */\n getRawData(): T {\n return this._data;\n }\n\n /**\n * Create or get existing instance for a context.\n *\n * @template T - Type of the data structure\n * @param contextId - Unique identifier for the game context (e.g., \"Game\", \"FreeSpinGame\")\n * @param initialData - Initial data structure\n * @returns DataStore instance for the specified context\n *\n * @example\n * ```typescript\n * interface GameData {\n * config: ConfigContext;\n * platform: Platform;\n * bet: number;\n * }\n *\n * const store = DataStore.createInstance<GameData>('Game', {\n * config: {} as ConfigContext,\n * platform: {} as Platform,\n * bet: 10,\n * });\n * ```\n */\n static createInstance<T extends Record<string, any>>(\n contextId: string,\n initialData: T,\n ): DataStore<T> {\n if (!DataStore.instances.has(contextId)) {\n const instance = new DataStore<T>(contextId, initialData);\n DataStore.instances.set(contextId, instance);\n }\n return DataStore.instances.get(contextId)! as DataStore<T>;\n }\n\n /**\n * Get existing instance for a context.\n *\n * @template T - Type of the data structure\n * @param contextId - Unique identifier for the game context\n * @returns DataStore instance for the specified context\n * @throws Error if instance doesn't exist\n *\n * @example\n * ```typescript\n * const store = DataStore.getInstance<GameData>('Game');\n * ```\n */\n static getInstance<T extends Record<string, any> = any>(contextId: string): DataStore<T> {\n const instance = DataStore.instances.get(contextId);\n if (!instance) {\n throw new Error(`DataStore instance \"${contextId}\" not found. Call createInstance() first.`);\n }\n return instance as DataStore<T>;\n }\n\n /**\n * Check if instance exists for a context.\n *\n * @param contextId - Unique identifier for the game context\n * @returns True if instance exists, false otherwise\n */\n static hasInstance(contextId: string): boolean {\n return DataStore.instances.has(contextId);\n }\n\n /**\n * Destroy instance for a context and cleanup all listeners.\n *\n * @param contextId - Unique identifier for the game context\n *\n * @example\n * ```typescript\n * DataStore.destroyInstance('BonusGame');\n * ```\n */\n static destroyInstance(contextId: string): void {\n const instance = DataStore.instances.get(contextId);\n if (instance) {\n instance.removeAllListeners();\n DataStore.instances.delete(contextId);\n }\n }\n\n /**\n * Get all active context IDs.\n *\n * @returns Array of context IDs\n */\n static getActiveContexts(): string[] {\n return Array.from(DataStore.instances.keys());\n }\n\n /**\n * Destroy all instances and cleanup.\n */\n static destroyAll(): void {\n const contexts = Array.from(DataStore.instances.keys());\n for (const contextId of contexts) {\n DataStore.destroyInstance(contextId);\n }\n }\n\n /**\n * Get context ID of this instance.\n */\n getContextId(): string {\n return this.contextId;\n }\n\n /**\n * Update multiple properties at once without triggering individual events.\n * Useful for batch updates.\n *\n * @param updates - Partial data to update\n *\n * @example\n * ```typescript\n * store.batchUpdate({\n * bet: 20,\n * isQuickSpin: true,\n * });\n * ```\n */\n batchUpdate(updates: Partial<T>): void {\n Object.assign(this._data, updates);\n this.emit('data:updated', this._proxy, 'batch' as keyof T, updates);\n }\n\n /**\n * Reset store to initial state.\n *\n * @param initialData - New initial data\n */\n reset(initialData: T): void {\n this._data = initialData;\n this._proxy = this.createProxy(initialData);\n this.emit('data:updated', this._proxy, 'reset' as keyof T, initialData);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Skinable.d.ts","sourceRoot":"","sources":["../../../ui/components/Skinable.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAI5D,wBAAgB,QAAQ,CAAC,SAAS,EAAE,KAAK,SAAS,WAAW,EAAE,IAAI,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"Skinable.d.ts","sourceRoot":"","sources":["../../../ui/components/Skinable.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,CAAC,CAAC,GAAG,EAAE,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;AAI5D,wBAAgB,QAAQ,CAAC,SAAS,EAAE,KAAK,SAAS,WAAW,EAAE,IAAI,EAAE,KAAK,GAmDrC,KACjC,GAAG,IAAI,EAAE,qBAAqB,CAAC,KAAK,CAAC,KAClC,YAAY,CAAC,KAAK,CAAC;iBATT,CACX,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,IAAI,EAC3C,IAAI,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,KACnC,IAAI;iBACI,MAAM,SAAS,GAAG,IAAI;CAKK,CAC3C;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AACH,eAAO,MAAM,UAAU,GAAI,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrF,GAAG,CAAC,EACJ,GAAG,CAAC,KACH,CAAC,GAAG,CAmBN,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,wBAAgB,gBAAgB,CAAC,SAAS;QAGjB,SAAS,GAAG,IAAI;WACb,SAAS,GAAG,IAAI,GAAG,IAAI;EAOlD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAClD,gBAAgB,EAAE,MAAM,SAAS,GAAG,IAAI,EACxC,YAAY,CAAC,EAAE,SAAS,GAAG,IAAI,GAC9B,SAAS,GAAG,IAAI,CAQlB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAC3C,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,CAAA;CAAE,CAAC,GACnD,IAAI,CAON;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAC1C,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,CAAA;CAAE,CAAC,GACnD,IAAI,CAON;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EACzC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,CAAA;CAAE,CAAC,GACnD,IAAI,CAON;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EACzC,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,CAAA;CAAE,CAAC,EACpD,iBAAiB,CAAC,EAAE,OAAO,GAC1B,IAAI,CAON"}
|