gffe-game-core 1.0.0 → 1.0.1

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.
@@ -53,7 +53,7 @@ var d = class {
53
53
  return e.Mobile = "mobile", e.Tablet = "tablet", e.Desktop = "desktop", e;
54
54
  }({}), m = /* @__PURE__ */ function(e) {
55
55
  return e.Portrait = "portrait", e.Landscape = "landscape", e;
56
- }({}), h = "1.0.0", g = class {
56
+ }({}), h = "1.0.1", g = class {
57
57
  state;
58
58
  logState;
59
59
  listeners = /* @__PURE__ */ new Set();
@@ -418,7 +418,7 @@ var d = class {
418
418
  handleMessage(e) {
419
419
  let t;
420
420
  try {
421
- t = JSON.parse(e.data);
421
+ if (t = JSON.parse(e.data), typeof t == "object" && t && "updateType" in t && t.updateType === "ROOM_TYPE") return;
422
422
  } catch {
423
423
  this.handleProtocolError(new b(y.SocketInvalidMessage, "Received invalid JSON from WebSocket server", "errors.connection", v.Fatal, { data: e.data }));
424
424
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"gffe-game-core.js","names":["$emit"],"sources":["../src/assets/AssetManager.ts","../src/audio/AudioManager.ts","../src/store/store.types.ts","../src/version.ts","../src/store/CoreStore.ts","../src/ui/UIManager.ts","../src/errors/error.types.ts","../src/errors/CoreError.ts","../src/url/URLManager.ts","../src/language/LanguageManager.ts","../src/errors/ErrorManager.ts","../src/socket/socket.types.ts","../src/socket/SocketManager.ts","../src/operator/utils/load-script.ts","../src/operator/providers/GFFEOperatorProvider.ts","../src/operator/providers/NullOperatorProvider.ts","../src/operator/OperatorBridge.ts","../src/theme/Theme.ts","../src/theme/ThemeManager.ts","../src/Core.ts","../src/vue/core.context.ts","../src/vue/useCore.ts","../src/vue/useCoreStore.ts","../src/vue/components/ErrorOverlay.vue","../src/vue/components/ErrorOverlay.vue","../src/vue/components/ErrorOverlay.ts"],"sourcesContent":["import type { AssetDefinition, AssetManifest } from './asset.types'\r\n\r\nexport class AssetManager {\r\n private readonly assets = new Map<string, unknown>()\r\n\r\n async load(manifest: AssetManifest): Promise<void> {\r\n const entries = Object.entries(manifest)\r\n\r\n await Promise.all(\r\n entries.map(([key, definition]) => this.loadAsset(key, definition)),\r\n )\r\n }\r\n\r\n get<T>(key: string): T {\r\n const asset = this.assets.get(key)\r\n\r\n if (!asset) {\r\n throw new Error(`Asset \"${key}\" is not loaded`)\r\n }\r\n\r\n return asset as T\r\n }\r\n\r\n private async loadAsset(\r\n key: string,\r\n\r\n definition: AssetDefinition,\r\n ): Promise<void> {\r\n switch (definition.type) {\r\n case 'audio':\r\n await this.loadAudio(\r\n key,\r\n\r\n definition.src,\r\n )\r\n\r\n break\r\n\r\n default:\r\n throw new Error(`Unsupported asset type: ${definition.type}`)\r\n }\r\n }\r\n\r\n private loadAudio(key: string, src: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const audio = new Audio()\r\n\r\n audio.preload = 'auto'\r\n\r\n const handleLoaded = () => {\r\n cleanup()\r\n this.assets.set(key, audio)\r\n resolve()\r\n }\r\n\r\n const handleError = () => {\r\n cleanup()\r\n reject(new Error(`Failed to load audio asset \"${key}\"`))\r\n }\r\n\r\n const cleanup = () => {\r\n audio.removeEventListener('canplaythrough', handleLoaded)\r\n\r\n audio.removeEventListener('error', handleError)\r\n }\r\n\r\n audio.addEventListener('canplaythrough', handleLoaded, { once: true })\r\n audio.addEventListener('error', handleError, { once: true })\r\n\r\n audio.src = src\r\n audio.load()\r\n })\r\n }\r\n}\r\n","import type { AssetManager } from '../assets/AssetManager'\r\nimport type { CoreStore } from '../store/CoreStore'\r\nimport type { AudioKey, AudioPlayOptions } from './audio.types'\r\n\r\nexport class AudioManager {\r\n constructor(\r\n private readonly assets: AssetManager,\r\n private readonly store: CoreStore,\r\n ) {}\r\n\r\n play(key: AudioKey, options: AudioPlayOptions = {}): void {\r\n if (!this.store.state.settings.sounds) {\r\n return\r\n }\r\n\r\n const source = this.assets.get<HTMLAudioElement>(key)\r\n const audio = source.cloneNode(true) as HTMLAudioElement\r\n\r\n audio.volume = this.normalizeVolume(options.volume ?? 1)\r\n audio.loop = options.loop ?? false\r\n\r\n void audio.play().catch((error) => {\r\n console.error(`Failed to play audio \"${key}\"`, error)\r\n })\r\n }\r\n\r\n private normalizeVolume(volume: number): number {\r\n return Math.min(1, Math.max(0, volume))\r\n }\r\n}\r\n","import type { CoreErrorState } from '../errors/error.types'\r\n\r\nexport enum DeviceType {\r\n Mobile = 'mobile',\r\n Tablet = 'tablet',\r\n Desktop = 'desktop',\r\n}\r\n\r\nexport enum Orientation {\r\n Portrait = 'portrait',\r\n Landscape = 'landscape',\r\n}\r\n\r\nexport interface AppState {\r\n theme: string | null\r\n version: string\r\n coreVersion: string\r\n provider: string\r\n initialized: boolean\r\n}\r\n\r\nexport interface SettingsState {\r\n sounds: boolean\r\n}\r\n\r\nexport interface UIState {\r\n screenWidth: number\r\n screenHeight: number\r\n device: DeviceType\r\n orientation: Orientation\r\n}\r\n\r\nexport interface LanguageState {\r\n current: string\r\n fallback: string\r\n loaded: boolean\r\n}\r\n\r\nexport interface CoreStoreOptions {\r\n appVersion: string\r\n provider?: string\r\n\r\n defaultLanguage: string\r\n fallbackLanguage: string\r\n\r\n logState?: boolean\r\n}\r\n\r\nexport interface CoreState {\r\n app: AppState\r\n settings: SettingsState\r\n ui: UIState\r\n language: LanguageState\r\n error: CoreErrorState | null\r\n}\r\n","declare const __CORE_VERSION__: string\r\n\r\nexport const CORE_VERSION = __CORE_VERSION__","import type { CoreErrorState } from '../errors/error.types'\r\nimport {\r\n DeviceType,\r\n Orientation,\r\n type CoreState,\r\n type CoreStoreOptions,\r\n type UIState,\r\n} from './store.types'\r\nimport { CORE_VERSION } from '../version'\r\n\r\ntype StoreListener = () => void\r\n\r\nexport class CoreStore {\r\n readonly state: CoreState\r\n\r\n private readonly logState: boolean\r\n private readonly listeners = new Set<StoreListener>()\r\n\r\n constructor(options: CoreStoreOptions) {\r\n this.logState = options.logState ?? false\r\n this.state = {\r\n app: {\r\n version: options.appVersion,\r\n coreVersion: CORE_VERSION,\r\n provider: options.provider ?? '',\r\n initialized: false,\r\n theme: 'default',\r\n },\r\n\r\n settings: {\r\n sounds: true,\r\n },\r\n\r\n ui: {\r\n screenWidth: 0,\r\n screenHeight: 0,\r\n device: DeviceType.Desktop,\r\n orientation: Orientation.Landscape,\r\n },\r\n\r\n language: {\r\n current: options.defaultLanguage,\r\n fallback: options.fallbackLanguage,\r\n loaded: false,\r\n },\r\n\r\n error: null,\r\n }\r\n }\r\n\r\n setSounds(enabled: boolean): void {\r\n if (this.state.settings.sounds === enabled) {\r\n return\r\n }\r\n\r\n this.state.settings.sounds = enabled\r\n this.notify()\r\n }\r\n\r\n setUI(ui: UIState): void {\r\n const current = this.state.ui\r\n\r\n if (\r\n current.screenWidth === ui.screenWidth &&\r\n current.screenHeight === ui.screenHeight &&\r\n current.device === ui.device &&\r\n current.orientation === ui.orientation\r\n ) {\r\n return\r\n }\r\n\r\n this.state.ui = ui\r\n\r\n this.notify()\r\n }\r\n\r\n setInitialized(initialized: boolean): void {\r\n if (this.state.app.initialized === initialized) {\r\n return\r\n }\r\n\r\n this.state.app.initialized = initialized\r\n\r\n this.notify()\r\n }\r\n\r\n setLanguage(\r\n language: string,\r\n\r\n loaded: boolean,\r\n ): void {\r\n const current = this.state.language\r\n\r\n if (current.current === language && current.loaded === loaded) {\r\n return\r\n }\r\n\r\n this.state.language = {\r\n ...current,\r\n current: language,\r\n loaded,\r\n }\r\n\r\n this.notify()\r\n }\r\n\r\n setTheme(theme: string | null): void {\r\n this.state.app.theme = theme\r\n\r\n this.notify()\r\n }\r\n\r\n setError(error: CoreErrorState | null): void {\r\n this.state.error = error\r\n this.notify()\r\n }\r\n\r\n subscribe(listener: StoreListener): () => void {\r\n this.listeners.add(listener)\r\n\r\n return () => {\r\n this.listeners.delete(listener)\r\n }\r\n }\r\n\r\n private notify(): void {\r\n this.log()\r\n this.listeners.forEach((listener) => {\r\n listener()\r\n })\r\n }\r\n\r\n private log(): void {\r\n if (!this.logState) {\r\n return\r\n }\r\n\r\n console.groupCollapsed(\r\n '%c CORE State ',\r\n [\r\n 'background: #111827',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n )\r\n\r\n console.log(structuredClone(this.state))\r\n console.groupEnd()\r\n }\r\n}\r\n","import type { CoreStore } from '../store/CoreStore'\r\nimport { DeviceType, Orientation } from '../store/store.types'\r\nimport type { UIEventMap, UIManagerOptions } from './ui.types'\r\n\r\ntype UIEvent = keyof UIEventMap\r\ntype UIListener<T extends UIEvent> = (payload: UIEventMap[T]) => void\r\n\r\nexport class UIManager {\r\n private readonly mobileBreakpoint: number\r\n private readonly tabletBreakpoint: number\r\n private readonly listeners = new Map<UIEvent, Set<(payload: any) => void>>()\r\n\r\n constructor(\r\n private readonly store: CoreStore,\r\n\r\n options: UIManagerOptions = {},\r\n ) {\r\n this.mobileBreakpoint = options.mobileBreakpoint ?? 768\r\n\r\n this.tabletBreakpoint = options.tabletBreakpoint ?? 1200\r\n }\r\n\r\n initialize(): void {\r\n this.update()\r\n\r\n window.addEventListener(\r\n 'resize',\r\n\r\n this.handleResize,\r\n )\r\n }\r\n\r\n destroy(): void {\r\n window.removeEventListener(\r\n 'resize',\r\n\r\n this.handleResize,\r\n )\r\n }\r\n\r\n getDevice(): DeviceType {\r\n return this.store.state.ui.device\r\n }\r\n\r\n getOrientation(): Orientation {\r\n return this.store.state.ui.orientation\r\n }\r\n\r\n on<T extends UIEvent>(\r\n event: T,\r\n\r\n listener: UIListener<T>,\r\n ): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(\r\n event,\r\n\r\n new Set(),\r\n )\r\n }\r\n\r\n this.listeners.get(event)!.add(listener)\r\n\r\n return () => {\r\n this.listeners\r\n\r\n .get(event)\r\n\r\n ?.delete(listener)\r\n }\r\n }\r\n\r\n private handleResize = (): void => {\r\n this.update()\r\n }\r\n\r\n private update(): void {\r\n const width = window.innerWidth\r\n\r\n const height = window.innerHeight\r\n\r\n const device = this.resolveDevice(width)\r\n\r\n const orientation = this.resolveOrientation(\r\n width,\r\n\r\n height,\r\n )\r\n\r\n this.store.setUI({\r\n screenWidth: width,\r\n\r\n screenHeight: height,\r\n\r\n device,\r\n\r\n orientation,\r\n })\r\n\r\n this.updateBodyClasses(\r\n device,\r\n\r\n orientation,\r\n )\r\n\r\n this.emit('resize', {\r\n width,\r\n\r\n height,\r\n\r\n device,\r\n\r\n orientation,\r\n })\r\n }\r\n\r\n private resolveDevice(width: number): DeviceType {\r\n if (width < this.mobileBreakpoint) {\r\n return DeviceType.Mobile\r\n }\r\n\r\n if (width < this.tabletBreakpoint) {\r\n return DeviceType.Tablet\r\n }\r\n\r\n return DeviceType.Desktop\r\n }\r\n\r\n private resolveOrientation(\r\n width: number,\r\n\r\n height: number,\r\n ): Orientation {\r\n return width >= height ? Orientation.Landscape : Orientation.Portrait\r\n }\r\n\r\n private updateBodyClasses(\r\n device: DeviceType,\r\n\r\n orientation: Orientation,\r\n ): void {\r\n const body = document.body\r\n\r\n Object.values(DeviceType).forEach((value) => {\r\n body.classList.remove(`device-${value}`)\r\n })\r\n\r\n Object.values(Orientation).forEach((value) => {\r\n body.classList.remove(`orientation-${value}`)\r\n })\r\n\r\n body.classList.add(\r\n `device-${device}`,\r\n\r\n `orientation-${orientation}`,\r\n )\r\n }\r\n\r\n private emit<T extends UIEvent>(\r\n event: T,\r\n\r\n payload: UIEventMap[T],\r\n ): void {\r\n this.listeners\r\n\r\n .get(event)\r\n\r\n ?.forEach((listener) => {\r\n listener(payload)\r\n })\r\n }\r\n}\r\n","export enum CoreErrorSeverity {\r\n Fatal = 'fatal',\r\n Recoverable = 'recoverable',\r\n}\r\n\r\nexport enum CoreErrorCode {\r\n UrlMissingParameter = 'URL_MISSING_PARAMETER',\r\n\r\n SocketConnectionFailed = 'SOCKET_CONNECTION_FAILED',\r\n SocketDisconnected = 'SOCKET_DISCONNECTED',\r\n SocketNotConnected = 'SOCKET_NOT_CONNECTED',\r\n SocketSendFailed = 'SOCKET_SEND_FAILED',\r\n SocketInvalidMessage = 'SOCKET_INVALID_MESSAGE',\r\n SocketRequestTimeout = 'SOCKET_REQUEST_TIMEOUT',\r\n SocketProtocolMismatch = 'SOCKET_PROTOCOL_MISMATCH',\r\n\r\n RGSRequestFailed = 'RGS_REQUEST_FAILED',\r\n\r\n Unknown = 'UNKNOWN_ERROR',\r\n}\r\n\r\nexport interface CoreErrorContext {\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface CoreErrorState {\r\n /** False when the operator accepted responsibility for displaying this error. */\r\n displayIngame?: boolean\r\n code: CoreErrorCode\r\n severity: CoreErrorSeverity\r\n message: string\r\n userMessageKey: string\r\n context?: CoreErrorContext\r\n}\r\n","import type { CoreErrorContext } from './error.types'\r\nimport { CoreErrorCode, CoreErrorSeverity } from './error.types'\r\n\r\nexport class CoreError extends Error {\r\n constructor(\r\n public readonly code: CoreErrorCode,\r\n message: string,\r\n\r\n public readonly userMessageKey: string,\r\n public readonly severity: CoreErrorSeverity = CoreErrorSeverity.Fatal,\r\n public readonly context?: CoreErrorContext,\r\n ) {\r\n super(message)\r\n this.name = 'CoreError'\r\n }\r\n}\r\n","import type { URLParams, URLParamsConfig } from './url.types'\r\nimport { CoreError } from '../errors/CoreError'\r\nimport { CoreErrorCode, CoreErrorSeverity } from '../errors/error.types'\r\n\r\nexport class URLManager {\r\n private params: URLParams = {}\r\n\r\n constructor(private readonly config: URLParamsConfig) {}\r\n\r\n initialize(): void {\r\n const searchParams = new URLSearchParams(window.location.search)\r\n\r\n const params: URLParams = {}\r\n\r\n for (const [key, definition] of Object.entries(this.config)) {\r\n const source = definition.source ?? key\r\n\r\n const rawValue = searchParams.get(source)\r\n\r\n params[key] =\r\n rawValue !== null && rawValue.trim() !== ''\r\n ? rawValue.trim()\r\n : (definition.default ?? '')\r\n }\r\n\r\n this.params = params\r\n }\r\n\r\n validate(): void {\r\n for (const [key, definition] of Object.entries(this.config)) {\r\n if (!definition.required) {\r\n continue\r\n }\r\n\r\n const value = this.params[key]\r\n\r\n if (value !== '') {\r\n continue\r\n }\r\n\r\n const source = definition.source ?? key\r\n\r\n throw new CoreError(\r\n CoreErrorCode.UrlMissingParameter,\r\n `Missing required URL parameter: \"${source}\"`,\r\n 'errors.initialization',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n parameter: source,\r\n },\r\n )\r\n }\r\n }\r\n\r\n get(key: string): string {\r\n return this.params[key] ?? ''\r\n }\r\n\r\n getAll(): Readonly<URLParams> {\r\n return this.params\r\n }\r\n}\r\n","import type { CoreStore } from '../store/CoreStore'\r\n\r\nimport type {\r\n LanguageCode,\r\n LanguageManagerOptions,\r\n LanguageMessages,\r\n} from './language.types'\r\n\r\nexport class LanguageManager {\r\n private currentLanguage: LanguageCode\r\n\r\n private messages: LanguageMessages = {}\r\n\r\n constructor(\r\n private readonly store: CoreStore,\r\n private readonly options: LanguageManagerOptions,\r\n ) {\r\n this.currentLanguage = options.defaultLanguage\r\n }\r\n\r\n async initialize(language?: LanguageCode): Promise<void> {\r\n await this.load(language ?? this.options.defaultLanguage)\r\n }\r\n\r\n async load(language: LanguageCode): Promise<void> {\r\n const loader = this.options.loaders[language]\r\n\r\n if (!loader) {\r\n await this.loadFallback()\r\n return\r\n }\r\n\r\n try {\r\n this.messages = await loader()\r\n\r\n this.currentLanguage = language\r\n\r\n this.store.setLanguage(language, true)\r\n } catch {\r\n await this.loadFallback()\r\n }\r\n }\r\n\r\n getLanguage(): LanguageCode {\r\n return this.currentLanguage\r\n }\r\n\r\n getMessages(): LanguageMessages {\r\n return this.messages\r\n }\r\n\r\n private async loadFallback(): Promise<void> {\r\n const fallback = this.options.fallbackLanguage\r\n\r\n const loader = this.options.loaders[fallback]\r\n\r\n if (!loader) {\r\n throw new Error(`Fallback language \"${fallback}\" is not configured`)\r\n }\r\n\r\n this.messages = await loader()\r\n\r\n this.currentLanguage = fallback\r\n\r\n this.store.setLanguage(fallback, true)\r\n }\r\n}\r\n","import type { OperatorBridge } from '../operator/OperatorBridge'\r\nimport type { CoreStore } from '../store/CoreStore'\r\n\r\nimport { CoreError } from './CoreError'\r\n\r\nimport { CoreErrorCode } from './error.types'\r\n\r\nexport class ErrorManager {\r\n constructor(\r\n private readonly store: CoreStore,\r\n private readonly operator?: OperatorBridge,\r\n ) {}\r\n\r\n handle(error: unknown): void {\r\n const coreError =\r\n error instanceof CoreError\r\n ? error\r\n : new CoreError(\r\n CoreErrorCode.Unknown,\r\n\r\n error instanceof Error ? error.message : 'Unknown error',\r\n\r\n 'errors.generic',\r\n )\r\n\r\n this.log(coreError)\r\n\r\n const context = coreError.context\r\n const errorType = context?.errorType\r\n const errorCode = context?.errorCode\r\n const errorTitle = context?.title\r\n const delegated = this.operator?.tryDelegateError({\r\n errorType: typeof errorType === 'string' ? errorType : coreError.code,\r\n code: typeof errorCode === 'string' || typeof errorCode === 'number'\r\n ? errorCode\r\n : coreError.code,\r\n title: typeof errorTitle === 'string' ? errorTitle : 'Error',\r\n text: coreError.message,\r\n }) ?? false\r\n\r\n this.store.setError({\r\n displayIngame: !delegated,\r\n code: coreError.code,\r\n severity: coreError.severity,\r\n message: coreError.message,\r\n userMessageKey: coreError.userMessageKey,\r\n context: coreError.context,\r\n })\r\n }\r\n\r\n clear(): void {\r\n this.store.setError(null)\r\n }\r\n\r\n private log(error: CoreError): void {\r\n console.groupCollapsed(\r\n '%c CORE Error ',\r\n [\r\n 'background: #991b1b',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n )\r\n\r\n console.error({\r\n code: error.code,\r\n message: error.message,\r\n context: error.context,\r\n })\r\n\r\n console.groupEnd()\r\n }\r\n}\r\n","export enum SocketState {\r\n Disconnected = 'disconnected',\r\n Connecting = 'connecting',\r\n Connected = 'connected',\r\n}\r\n\r\nexport interface SocketMessage {\r\n requestType: string\r\n}\r\n\r\nexport interface SocketErrorObject {\r\n operatorCode?: string\r\n operatorMessage?: string\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface SocketResponseError {\r\n errorType: string | null\r\n errorCode: number | string\r\n errorMessage: string\r\n errorObject: SocketErrorObject | null\r\n}\r\n\r\nexport interface SocketErrorResponse {\r\n requestType: string\r\n updateType: 'ERROR'\r\n error: SocketResponseError\r\n\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface SocketConfig {\r\n urlSuffix?: string\r\n requestTimeout?: number\r\n\r\n heartbeat?: {\r\n enabled: boolean\r\n interval: number\r\n timeout?: number\r\n message: SocketMessage\r\n }\r\n\r\n eventTypes?: string[]\r\n}\r\n\r\nexport type SocketBroadcastListener<T = unknown> = (\r\n message: T,\r\n requestType: string,\r\n) => void\r\n\r\nexport interface SocketDisconnectPayload {\r\n code: number\r\n reason: string\r\n wasClean: boolean\r\n}\r\n\r\nexport type SocketDisconnectListener = (payload: SocketDisconnectPayload) => void\r\n\r\nexport enum SocketLogType {\r\n Frontend = 'Frontend',\r\n Backend = 'Backend',\r\n Broadcast = 'Broadcast',\r\n Error = 'Error',\r\n}\r\n\r\nexport type SocketEvent = 'connect' | 'disconnect' | 'message' | 'error'\r\n\r\nexport type SocketEventListener<T = unknown> = (payload: T) => void\r\n","import { CoreError } from '../errors/CoreError'\r\nimport { CoreErrorCode, CoreErrorSeverity } from '../errors/error.types'\r\n\r\nimport {\r\n SocketLogType,\r\n SocketState,\r\n type SocketBroadcastListener,\r\n type SocketConfig,\r\n type SocketDisconnectListener,\r\n type SocketDisconnectPayload,\r\n type SocketMessage,\r\n} from './socket.types'\r\n\r\ninterface PendingRequest {\r\n requestType: string\r\n resolve: (message: unknown) => void\r\n reject: (error: CoreError) => void\r\n timeout: ReturnType<typeof setTimeout>\r\n}\r\n\r\nexport class SocketManager {\r\n private socket: WebSocket | null = null\r\n private state: SocketState = SocketState.Disconnected\r\n private lastAction: string | null = null\r\n private pendingRequest: PendingRequest | null = null\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null\r\n private heartbeatResponseTimer: ReturnType<typeof setTimeout> | null = null\r\n private intentionalDisconnect = false\r\n private readonly broadcastListeners = new Set<SocketBroadcastListener>()\r\n private readonly disconnectListeners = new Set<SocketDisconnectListener>()\r\n private readonly heartbeatChecks = new Set<(connected: boolean) => void>()\r\n\r\n constructor(private readonly config: SocketConfig) {}\r\n\r\n connect(endpoint: string): Promise<void> {\r\n const url = this.buildUrl(endpoint)\r\n\r\n this.intentionalDisconnect = false\r\n\r\n if (this.state === SocketState.Connected) {\r\n return Promise.resolve()\r\n }\r\n\r\n if (this.state === SocketState.Connecting) {\r\n return Promise.reject(\r\n new CoreError(\r\n CoreErrorCode.SocketConnectionFailed,\r\n 'WebSocket connection is already in progress',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n url,\r\n },\r\n ),\r\n )\r\n }\r\n\r\n this.state = SocketState.Connecting\r\n\r\n return new Promise((resolve, reject) => {\r\n try {\r\n this.socket = new WebSocket(url)\r\n\r\n this.socket.onopen = () => {\r\n this.state = SocketState.Connected\r\n\r\n console.log('[Socket] Connected', url)\r\n\r\n resolve()\r\n }\r\n\r\n this.socket.onmessage = (event) => {\r\n this.handleMessage(event)\r\n }\r\n\r\n this.socket.onerror = () => {\r\n if (this.state !== SocketState.Connecting) {\r\n return\r\n }\r\n\r\n this.state = SocketState.Disconnected\r\n\r\n const error = new CoreError(\r\n CoreErrorCode.SocketConnectionFailed,\r\n `Failed to connect to WebSocket: \"${url}\"`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n url,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error)\r\n\r\n this.socket = null\r\n\r\n reject(error)\r\n }\r\n\r\n this.socket.onclose = (event) => {\r\n this.handleDisconnect({\r\n code: event.code,\r\n reason: event.reason,\r\n wasClean: event.wasClean,\r\n })\r\n }\r\n } catch (error) {\r\n this.state = SocketState.Disconnected\r\n this.socket = null\r\n\r\n const coreError = new CoreError(\r\n CoreErrorCode.SocketConnectionFailed,\r\n error instanceof Error\r\n ? error.message\r\n : 'Failed to create WebSocket connection',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n url,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, coreError)\r\n\r\n reject(coreError)\r\n }\r\n })\r\n }\r\n\r\n disconnect(): void {\r\n this.intentionalDisconnect = true\r\n this.stopHeartbeat()\r\n this.clearPendingRequest()\r\n this.resolveHeartbeatChecks(false)\r\n\r\n if (!this.socket) {\r\n this.state = SocketState.Disconnected\r\n return\r\n }\r\n\r\n const socket = this.socket\r\n\r\n socket.onclose = null\r\n socket.close()\r\n this.socket = null\r\n\r\n this.state = SocketState.Disconnected\r\n }\r\n\r\n send(message: SocketMessage): void {\r\n if (!this.socket || this.state !== SocketState.Connected) {\r\n const error = new CoreError(\r\n CoreErrorCode.SocketNotConnected,\r\n 'Cannot send message: WebSocket is not connected',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType: message.requestType,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error, message.requestType)\r\n\r\n throw error\r\n }\r\n\r\n try {\r\n this.socket.send(JSON.stringify(message))\r\n\r\n this.log(SocketLogType.Frontend, message, message.requestType)\r\n } catch (error) {\r\n const coreError = new CoreError(\r\n CoreErrorCode.SocketSendFailed,\r\n error instanceof Error\r\n ? error.message\r\n : 'Failed to send WebSocket message',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType: message.requestType,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, coreError, message.requestType)\r\n\r\n throw coreError\r\n }\r\n }\r\n\r\n request<TResponse>(message: SocketMessage): Promise<TResponse> {\r\n if (this.pendingRequest) {\r\n const error = new CoreError(\r\n CoreErrorCode.SocketProtocolMismatch,\r\n `Cannot send \"${message.requestType}\" while \"${this.lastAction}\" is still pending`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n pendingRequestType: this.lastAction,\r\n requestType: message.requestType,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error, message.requestType)\r\n\r\n return Promise.reject(error)\r\n }\r\n\r\n return new Promise<TResponse>((resolve, reject) => {\r\n const requestType = message.requestType\r\n\r\n const timeout = setTimeout(() => {\r\n const error = new CoreError(\r\n CoreErrorCode.SocketRequestTimeout,\r\n `WebSocket request \"${requestType}\" timed out`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType,\r\n timeout: this.config.requestTimeout ?? 10_000,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error, requestType)\r\n\r\n this.clearPendingRequest()\r\n\r\n reject(error)\r\n }, this.config.requestTimeout ?? 10_000)\r\n\r\n this.lastAction = requestType\r\n\r\n this.pendingRequest = {\r\n requestType,\r\n resolve: resolve as (message: unknown) => void,\r\n reject,\r\n timeout,\r\n }\r\n\r\n try {\r\n this.send(message)\r\n } catch (error) {\r\n this.clearPendingRequest()\r\n\r\n reject(\r\n error instanceof CoreError\r\n ? error\r\n : new CoreError(\r\n CoreErrorCode.SocketSendFailed,\r\n 'Failed to send WebSocket request',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType,\r\n },\r\n ),\r\n )\r\n }\r\n })\r\n }\r\n\r\n getState(): SocketState {\r\n return this.state\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.state === SocketState.Connected\r\n }\r\n\r\n /**\r\n * Subscribes to messages whose requestType is configured in eventTypes.\r\n *\r\n * @example\r\n * const unsubscribe = core.socket.onBroadcast<GameUpdate>((message, requestType) => {\r\n * console.log(requestType, message)\r\n * })\r\n *\r\n * unsubscribe()\r\n */\r\n onBroadcast<T = unknown>(listener: SocketBroadcastListener<T>): () => void {\r\n const broadcastListener = listener as SocketBroadcastListener\r\n\r\n this.broadcastListeners.add(broadcastListener)\r\n\r\n return () => {\r\n this.broadcastListeners.delete(broadcastListener)\r\n }\r\n }\r\n\r\n onDisconnect(listener: SocketDisconnectListener): () => void {\r\n this.disconnectListeners.add(listener)\r\n\r\n return () => {\r\n this.disconnectListeners.delete(listener)\r\n }\r\n }\r\n\r\n checkConnection(): Promise<boolean> {\r\n if (!this.isConnected()) {\r\n return Promise.resolve(false)\r\n }\r\n\r\n if (!this.config.heartbeat?.enabled) {\r\n return Promise.resolve(true)\r\n }\r\n\r\n return new Promise((resolve) => {\r\n this.heartbeatChecks.add(resolve)\r\n this.sendHeartbeat()\r\n })\r\n }\r\n\r\n private handleMessage(event: MessageEvent): void {\r\n let message: unknown\r\n\r\n try {\r\n message = JSON.parse(event.data)\r\n } catch {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketInvalidMessage,\r\n 'Received invalid JSON from WebSocket server',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n data: event.data,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n const requestType = this.getRequestType(message)\r\n\r\n if (!requestType) {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketInvalidMessage,\r\n 'WebSocket message does not contain a valid requestType',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n message,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n /*\r\n * Heartbeat responses are independent from\r\n * normal request/response correlation.\r\n */\r\n if (requestType === this.config.heartbeat?.message.requestType) {\r\n this.log(SocketLogType.Backend, message, requestType)\r\n this.clearHeartbeatResponseTimer()\r\n this.resolveHeartbeatChecks(true)\r\n\r\n return\r\n }\r\n\r\n /*\r\n * Broadcasts / server events are unsolicited\r\n * and do not affect the pending request.\r\n */\r\n if (this.config.eventTypes?.includes(requestType)) {\r\n this.log(SocketLogType.Broadcast, message, requestType)\r\n this.emitBroadcast(message, requestType)\r\n\r\n return\r\n }\r\n\r\n /*\r\n * Everything below this point is considered\r\n * a response to a pending request.\r\n */\r\n if (!this.pendingRequest || !this.lastAction) {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketProtocolMismatch,\r\n `Received unexpected WebSocket response \"${requestType}\"`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n receivedRequestType: requestType,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n /*\r\n * The response must match the request\r\n * currently waiting for a response.\r\n */\r\n if (requestType !== this.lastAction) {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketProtocolMismatch,\r\n `Expected response \"${this.lastAction}\" but received \"${requestType}\"`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n expectedRequestType: this.lastAction,\r\n receivedRequestType: requestType,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n /*\r\n * The protocol correlation is valid.\r\n *\r\n * An RGS ERROR response is still a valid\r\n * response to the request, so the Promise\r\n * must be resolved. The caller decides how\r\n * to handle the RGS/operator error.\r\n */\r\n this.log(\r\n this.isErrorResponse(message)\r\n ? SocketLogType.Error\r\n : SocketLogType.Backend,\r\n message,\r\n requestType,\r\n )\r\n\r\n const pending = this.pendingRequest\r\n\r\n this.clearPendingRequest()\r\n\r\n pending.resolve(message)\r\n }\r\n\r\n private emitBroadcast(message: unknown, requestType: string): void {\r\n for (const listener of [...this.broadcastListeners]) {\r\n try {\r\n listener(message, requestType)\r\n } catch (error) {\r\n this.log(SocketLogType.Error, error, `broadcast:${requestType}`)\r\n }\r\n }\r\n }\r\n\r\n private emitDisconnect(payload: SocketDisconnectPayload): void {\r\n for (const listener of [...this.disconnectListeners]) {\r\n try {\r\n listener(payload)\r\n } catch (error) {\r\n this.log(SocketLogType.Error, error, 'disconnect')\r\n }\r\n }\r\n }\r\n\r\n private handleDisconnect(payload: SocketDisconnectPayload): void {\r\n const shouldNotify = !this.intentionalDisconnect\r\n\r\n this.stopHeartbeat()\r\n this.state = SocketState.Disconnected\r\n this.socket = null\r\n this.clearPendingRequest()\r\n this.resolveHeartbeatChecks(false)\r\n\r\n console.log('[Socket] Disconnected', payload)\r\n\r\n if (shouldNotify) {\r\n this.emitDisconnect(payload)\r\n }\r\n }\r\n\r\n private handleHeartbeatTimeout(): void {\r\n if (!this.isConnected()) {\r\n this.resolveHeartbeatChecks(false)\r\n return\r\n }\r\n\r\n const socket = this.socket\r\n\r\n if (socket) {\r\n socket.onclose = null\r\n }\r\n\r\n this.handleDisconnect({\r\n code: 4000,\r\n reason: 'heartbeat_timeout',\r\n wasClean: false,\r\n })\r\n\r\n socket?.close(4000, 'heartbeat_timeout')\r\n }\r\n\r\n private sendHeartbeat(): void {\r\n const heartbeat = this.config.heartbeat\r\n\r\n if (!heartbeat?.enabled || this.heartbeatResponseTimer) {\r\n return\r\n }\r\n\r\n try {\r\n this.send(heartbeat.message)\r\n\r\n this.heartbeatResponseTimer = setTimeout(\r\n () => this.handleHeartbeatTimeout(),\r\n heartbeat.timeout ?? Math.max(5_000, heartbeat.interval),\r\n )\r\n } catch {\r\n this.handleHeartbeatTimeout()\r\n }\r\n }\r\n\r\n private clearHeartbeatResponseTimer(): void {\r\n if (!this.heartbeatResponseTimer) return\r\n\r\n clearTimeout(this.heartbeatResponseTimer)\r\n this.heartbeatResponseTimer = null\r\n }\r\n\r\n private resolveHeartbeatChecks(connected: boolean): void {\r\n for (const resolve of [...this.heartbeatChecks]) {\r\n resolve(connected)\r\n }\r\n\r\n this.heartbeatChecks.clear()\r\n }\r\n\r\n private getRequestType(message: unknown): string | null {\r\n if (!message || typeof message !== 'object') {\r\n return null\r\n }\r\n\r\n const data = message as Record<string, unknown>\r\n\r\n /*\r\n * RGS error response:\r\n *\r\n * {\r\n * requestType: \"login\",\r\n * updateType: \"ERROR\",\r\n * ...\r\n * }\r\n */\r\n if (typeof data.requestType === 'string') {\r\n return data.requestType\r\n }\r\n\r\n /*\r\n * RGS successful response:\r\n *\r\n * {\r\n * response: {\r\n * requestType: \"login\",\r\n * ...\r\n * }\r\n * }\r\n */\r\n if (data.response && typeof data.response === 'object') {\r\n const response = data.response as Record<string, unknown>\r\n\r\n if (typeof response.requestType === 'string') {\r\n return response.requestType\r\n }\r\n }\r\n\r\n return null\r\n }\r\n\r\n private handleProtocolError(error: CoreError): void {\r\n this.log(SocketLogType.Error, error)\r\n\r\n if (this.pendingRequest) {\r\n const pending = this.pendingRequest\r\n\r\n this.clearPendingRequest()\r\n\r\n pending.reject(error)\r\n return\r\n }\r\n\r\n /*\r\n * Later this error must be emitted to Core,\r\n * because there may be no active request\r\n * Promise capable of propagating it.\r\n */\r\n }\r\n private clearPendingRequest(): void {\r\n if (this.pendingRequest) {\r\n clearTimeout(this.pendingRequest.timeout)\r\n }\r\n\r\n this.pendingRequest = null\r\n this.lastAction = null\r\n }\r\n\r\n private buildUrl(endpoint: string): string {\r\n const normalizedEndpoint = endpoint\r\n .replace(/^https?:\\/\\//, '')\r\n .replace(/^wss?:\\/\\//, '')\r\n .replace(/\\/+$/, '')\r\n\r\n const suffix = (this.config.urlSuffix ?? '').replace(/^\\/+/, '')\r\n\r\n return suffix\r\n ? `wss://${normalizedEndpoint}/${suffix}`\r\n : `wss://${normalizedEndpoint}`\r\n }\r\n\r\n private isErrorResponse(message: unknown): boolean {\r\n if (!message || typeof message !== 'object') {\r\n return false\r\n }\r\n\r\n const data = message as Record<string, unknown>\r\n\r\n return data.updateType === 'ERROR'\r\n }\r\n\r\n private log(type: SocketLogType, data: unknown, label?: string): void {\r\n const styles: Record<SocketLogType, string> = {\r\n [SocketLogType.Frontend]: [\r\n 'background: #2563eb',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n\r\n [SocketLogType.Backend]: [\r\n 'background: #059669',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n\r\n [SocketLogType.Broadcast]: [\r\n 'background: #7c3aed',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n\r\n [SocketLogType.Error]: [\r\n 'background: #991b1b',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n }\r\n\r\n const suffix = label ? ` ${label}` : ''\r\n\r\n console.groupCollapsed(\r\n `%c CORE WebSocket · ${type} %c${suffix}`,\r\n styles[type],\r\n ['color: #6b7280', 'font-weight: normal'].join(';'),\r\n )\r\n\r\n if (type === SocketLogType.Error) {\r\n console.error(data)\r\n } else {\r\n console.log(data)\r\n }\r\n\r\n console.groupEnd()\r\n }\r\n\r\n startHeartbeat(): void {\r\n const heartbeat = this.config.heartbeat\r\n\r\n if (!heartbeat?.enabled || this.heartbeatTimer) {\r\n return\r\n }\r\n\r\n this.heartbeatTimer = setInterval(() => {\r\n this.sendHeartbeat()\r\n }, heartbeat.interval)\r\n }\r\n\r\n stopHeartbeat(): void {\r\n this.clearHeartbeatResponseTimer()\r\n\r\n if (!this.heartbeatTimer) {\r\n return\r\n }\r\n\r\n clearInterval(this.heartbeatTimer)\r\n\r\n this.heartbeatTimer = null\r\n }\r\n}\r\n","export const loadScript = (src: string): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n const existing = document.querySelector<HTMLScriptElement>(\r\n `script[src=\"${src}\"]`,\r\n )\r\n\r\n if (existing) {\r\n if (existing.dataset.loaded === 'true') {\r\n resolve()\r\n return\r\n }\r\n\r\n existing.addEventListener('load', () => resolve(), { once: true })\r\n existing.addEventListener(\r\n 'error',\r\n () => reject(new Error(`Failed to load script: \"${src}\"`)),\r\n { once: true },\r\n )\r\n return\r\n }\r\n\r\n const script = document.createElement('script')\r\n script.type = 'text/javascript'\r\n script.async = true\r\n script.src = src\r\n script.addEventListener(\r\n 'load',\r\n () => {\r\n script.dataset.loaded = 'true'\r\n resolve()\r\n },\r\n { once: true },\r\n )\r\n script.addEventListener(\r\n 'error',\r\n () => {\r\n reject(new Error(`Failed to load script: \"${src}\"`))\r\n },\r\n { once: true },\r\n )\r\n\r\n document.head.appendChild(script)\r\n })\r\n}\r\n","import type {\r\n BalanceUpdatePayload,\r\n NotifyErrorPayload,\r\n OperatorCallbacks,\r\n OperatorConfig,\r\n OperatorInformation,\r\n} from '../operator.types'\r\n\r\nimport type { OperatorProvider } from './OperatorProvider'\r\n\r\nimport { loadScript } from '../utils/load-script'\r\n\r\nexport class GFFEOperatorProvider implements OperatorProvider {\r\n private api: Window['GFFEAPI']\r\n\r\n constructor(private readonly config: OperatorConfig) {}\r\n\r\n async initialize(callbacks: OperatorCallbacks): Promise<void> {\r\n if (!this.config.providerUrl) {\r\n throw new Error('GFFE provider URL is not configured')\r\n }\r\n\r\n await loadScript(this.config.providerUrl)\r\n\r\n this.api = window.GFFEAPI\r\n\r\n if (!this.api) {\r\n throw new Error(\r\n 'GFFEAPI is not available after loading the provider script',\r\n )\r\n }\r\n\r\n await this.api.initialize({\r\n onStopAutoplay: callbacks.onStopAutoplay ?? (() => {}),\r\n onUpdateBalance: callbacks.onUpdateBalance ?? (() => {}),\r\n onToggleAudio: callbacks.onToggleAudio ?? (() => {}),\r\n onShowIngameModal: callbacks.onShowIngameModal ?? (() => {}),\r\n onToggleCloak: callbacks.onToggleCloak ?? (() => {}),\r\n onVisibilityChange: callbacks.onVisibilityChange ?? (() => {}),\r\n onGetGameConfig:\r\n callbacks.onGetGameConfig ??\r\n (() => ({\r\n supportsPortraitMode: true,\r\n supportsLandscapeMode: true,\r\n })),\r\n onCustomCommand: callbacks.onCustomCommand ?? (() => {}),\r\n })\r\n }\r\n\r\n destroy(): void {\r\n this.api = undefined\r\n }\r\n\r\n isActive(): boolean {\r\n return this.api?.isWrapperActive() ?? false\r\n }\r\n\r\n getOperatorInformation(): OperatorInformation | null {\r\n return this.api?.getOperatorInformation() ?? null\r\n }\r\n\r\n notifyLoadingStarted(): void {\r\n this.api?.notifyLoadingStarted()\r\n }\r\n\r\n notifyLoadingProgress(percentage: number): void {\r\n this.api?.notifyLoadingProgress({\r\n percentage,\r\n })\r\n }\r\n\r\n notifyLoadingEnded(): void {\r\n this.api?.notifyLoadingEnded()\r\n }\r\n\r\n notifyGameReady(): void {\r\n this.api?.notifyGameIsReady()\r\n }\r\n\r\n notifyBalanceUpdate(payload: BalanceUpdatePayload): void {\r\n this.api?.notifyBalanceUpdate(payload)\r\n }\r\n\r\n notifyStakeUpdate(bet: number): void {\r\n this.api?.notifyStakeUpdate({\r\n bet,\r\n })\r\n }\r\n\r\n notifyRoundStart(): void {\r\n this.api?.notifyRoundStart()\r\n }\r\n\r\n notifyRoundEnd(): void {\r\n this.api?.notifyRoundEnd()\r\n }\r\n\r\n notifyAudioChanged(enabled: boolean): void {\r\n this.api?.notifyToggleAudio({\r\n enabled,\r\n })\r\n }\r\n\r\n visitLobby(): void {\r\n this.api?.visitLobby()\r\n }\r\n\r\n visitCashier(): void {\r\n this.api?.visitCashier()\r\n }\r\n\r\n\tvisitHistory(historyURL: string): void {\r\n\t\tthis.api?.visitHistory({ historyUrl: historyURL });\r\n\t}\r\n\r\n notifyError(payload: NotifyErrorPayload): void {\r\n if (!this.api?.notifyError) {\r\n throw new Error('GFFEAPI.notifyError is not available')\r\n }\r\n\r\n this.api.notifyError({\r\n\t\t\t...payload,\r\n\t\t\terrorType: this.mapErrorType(payload.errorType)\r\n\t\t})\r\n }\r\n\r\n\tprivate mapErrorType(errorType: string): string {\r\n // Map error codes to error types as needed\r\n // This is a placeholder implementation\r\n switch (errorType) {\r\n case 'critical':\r\n return 'CRITICAL_ERROR';\r\n case 'insufficient_funds':\r\n return 'INSUFFICIENT_FUNDS';\r\n default:\r\n return 'CRITICAL_ERROR';\r\n }\r\n }\r\n}\r\n","import type {\r\n BalanceUpdatePayload,\r\n NotifyErrorPayload,\r\n OperatorCallbacks,\r\n OperatorInformation,\r\n} from '../operator.types'\r\n\r\nimport type { OperatorProvider } from './OperatorProvider'\r\n\r\nexport class NullOperatorProvider implements OperatorProvider {\r\n async initialize(_callbacks: OperatorCallbacks): Promise<void> {}\r\n\r\n destroy(): void {}\r\n\r\n isActive(): boolean {\r\n return false\r\n }\r\n\r\n getOperatorInformation(): OperatorInformation | null {\r\n return null\r\n }\r\n\r\n notifyLoadingStarted(): void {}\r\n\r\n notifyLoadingProgress(_percentage: number): void {}\r\n\r\n notifyLoadingEnded(): void {}\r\n\r\n notifyGameReady(): void {}\r\n\r\n notifyBalanceUpdate(_payload: BalanceUpdatePayload): void {}\r\n\r\n notifyStakeUpdate(_bet: number): void {}\r\n\r\n notifyRoundStart(): void {}\r\n\r\n notifyRoundEnd(): void {}\r\n\r\n notifyAudioChanged(_enabled: boolean): void {}\r\n\r\n visitLobby(): void {}\r\n\r\n visitCashier(): void {}\r\n\r\n notifyError(_payload: NotifyErrorPayload): void {}\r\n\r\n\tvisitHistory(historyURL: string): void {}\r\n}\r\n","import type {\r\n BalanceUpdatePayload,\r\n NotifyErrorPayload,\r\n OperatorCallbacks,\r\n OperatorConfig,\r\n OperatorInformation,\r\n} from './operator.types'\r\n\r\nimport type { OperatorProvider } from './providers/OperatorProvider'\r\n//providers\r\nimport { GFFEOperatorProvider } from './providers/GFFEOperatorProvider'\r\nimport { NullOperatorProvider } from './providers/NullOperatorProvider'\r\n\r\nexport class OperatorBridge {\r\n private provider: OperatorProvider\r\n\r\n constructor(\r\n private readonly config: OperatorConfig,\r\n private readonly logState = false,\r\n ) {\r\n this.provider = new NullOperatorProvider()\r\n }\r\n\r\n async initialize(callbacks: OperatorCallbacks): Promise<void> {\r\n this.log('Initialize', {\r\n enabled: this.config.enabled,\r\n provider: this.config.provider,\r\n operatorID: this.config.operatorID ?? null,\r\n })\r\n\r\n if (!this.config.enabled) {\r\n return\r\n }\r\n this.provider = this.createProvider()\r\n\r\n await this.provider.initialize(this.wrapCallbacks(callbacks))\r\n\r\n this.log('Initialized', {\r\n active: this.provider.isActive(),\r\n })\r\n }\r\n\r\n destroy(): void {\r\n this.provider.destroy()\r\n }\r\n\r\n isActive(): boolean {\r\n return this.provider.isActive()\r\n }\r\n\r\n getOperatorInformation(): OperatorInformation | null {\r\n const information = this.provider.getOperatorInformation()\r\n \r\n this.log('Operator Information', information)\r\n\r\n return information\r\n }\r\n\r\n notifyLoadingStarted(): void {\r\n this.log('notifyLoadingStarted')\r\n this.provider.notifyLoadingStarted()\r\n }\r\n\r\n notifyLoadingProgress(percentage: number): void {\r\n this.log('notifyLoadingProgress()', { percentage })\r\n this.provider.notifyLoadingProgress(percentage)\r\n }\r\n\r\n notifyLoadingEnded(): void {\r\n this.log('notifyLoadingEnded()')\r\n this.provider.notifyLoadingEnded()\r\n }\r\n\r\n notifyGameReady(): void {\r\n this.log('notifyGameReady()')\r\n this.provider.notifyGameReady()\r\n }\r\n\r\n notifyBalanceUpdate(payload: BalanceUpdatePayload): void {\r\n this.log('notifyBalanceUpdate()', { payload })\r\n this.provider.notifyBalanceUpdate(payload)\r\n }\r\n\r\n notifyStakeUpdate(bet: number): void {\r\n this.log('notifyStakeUpdate()', { bet })\r\n this.provider.notifyStakeUpdate(bet)\r\n }\r\n\r\n notifyRoundStart(): void {\r\n this.log('notifyRoundStart()')\r\n this.provider.notifyRoundStart()\r\n }\r\n\r\n notifyRoundEnd(): void {\r\n this.log('notifyRoundEnd()')\r\n this.provider.notifyRoundEnd()\r\n }\r\n\r\n notifyAudioChanged(enabled: boolean): void {\r\n this.log('notifyAudioChanged()', { enabled })\r\n this.provider.notifyAudioChanged(enabled)\r\n }\r\n\r\n visitLobby(): void {\r\n this.log('visitLobby()')\r\n this.provider.visitLobby()\r\n }\r\n\r\n visitCashier(): void {\r\n this.log('visitCashier()')\r\n this.provider.visitCashier()\r\n }\r\n\r\n\tvisitHistory(historyURL: string): void {\r\n \t\tthis.log('visitHistory()')\r\n this.provider.visitHistory(historyURL)\r\n\t}\r\n\r\n notifyError(payload: NotifyErrorPayload): void {\r\n this.log('notifyError', payload)\r\n this.provider.notifyError(payload)\r\n }\r\n\r\n tryDelegateError(payload: NotifyErrorPayload): boolean {\r\n try {\r\n if (this.shouldDisplayIngameErrors()) return false\r\n this.notifyError(payload)\r\n return true\r\n } catch (error) {\r\n this.log('Error delegation failed; using ingame display', error)\r\n return false\r\n }\r\n }\r\n\r\n\t private mapErrorType(errorType: string): string {\r\n // Map error codes to error types as needed\r\n // This is a placeholder implementation\r\n switch (errorType) {\r\n case 'critical':\r\n return 'CRITICAL_ERROR';\r\n case 'insufficient_funds':\r\n return 'INSUFFICIENT_FUNDS';\r\n default:\r\n return 'CRITICAL_ERROR';\r\n }\r\n }\r\n\r\n private createProvider(): OperatorProvider {\r\n switch (this.config.provider) {\r\n case 'gffe':\r\n return new GFFEOperatorProvider(this.config)\r\n\r\n default:\r\n return new NullOperatorProvider()\r\n }\r\n }\r\n\r\n private wrapCallbacks(callbacks: OperatorCallbacks): OperatorCallbacks {\r\n return {\r\n onStopAutoplay: () => {\r\n this.log('← Stop Autoplay')\r\n callbacks.onStopAutoplay?.()\r\n },\r\n\r\n onUpdateBalance: () => {\r\n this.log('← Update Balance')\r\n callbacks.onUpdateBalance?.()\r\n },\r\n\r\n onToggleAudio: (payload) => {\r\n this.log('← Toggle Audio', payload)\r\n callbacks.onToggleAudio?.(payload)\r\n },\r\n\r\n onShowIngameModal: (payload) => {\r\n this.log('← Show Ingame Modal', payload)\r\n callbacks.onShowIngameModal?.(payload)\r\n },\r\n\r\n onToggleCloak: (payload) => {\r\n this.log('← Toggle Cloak', payload)\r\n callbacks.onToggleCloak?.(payload)\r\n },\r\n\r\n onVisibilityChange: (payload) => {\r\n this.log('← Visibility Change', payload)\r\n callbacks.onVisibilityChange?.(payload)\r\n },\r\n\r\n onGetGameConfig: () => {\r\n const config = callbacks.onGetGameConfig?.()\r\n this.log('← Get Game Config', config)\r\n\r\n return (\r\n config ?? {\r\n supportsPortraitMode: true,\r\n supportsLandscapeMode: true,\r\n }\r\n )\r\n },\r\n\r\n onCustomCommand: (payload) => {\r\n this.log('← Custom Command', payload)\r\n callbacks.onCustomCommand?.(payload)\r\n },\r\n }\r\n }\r\n\r\n shouldDisplayIngameErrors(): boolean {\r\n if (!this.config.enabled) {\r\n return true\r\n }\r\n\r\n return this.getOperatorInformation()?.hideIngameErrors !== true\r\n }\r\n\r\n private log(\r\n action: string,\r\n\r\n payload?: unknown,\r\n ): void {\r\n if (!this.logState) return\r\n\r\n console.groupCollapsed(\r\n `%c CORE Operator %c ${action}`,\r\n [\r\n 'background: #4f46e5',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n 'color: #6b7280; font-weight: normal;',\r\n )\r\n\r\n if (payload !== undefined) {\r\n console.log(payload)\r\n }\r\n\r\n console.groupEnd()\r\n }\r\n}\r\n","import type { ThemeDefinition } from './theme.types'\r\n\r\nexport class Theme implements ThemeDefinition {\r\n readonly theme: string\r\n readonly prefix: string\r\n readonly default?: boolean\r\n readonly cssUrl?: string\r\n readonly images: Readonly<Record<string, string>>\r\n private readonly loadedImages = new Map<string, string>()\r\n\r\n constructor(definition: ThemeDefinition) {\r\n this.theme = definition.theme\r\n this.prefix = definition.prefix\r\n this.default = definition.default\r\n this.cssUrl = definition.cssUrl\r\n this.images = { ...definition.images }\r\n }\r\n\r\n getImage(name: string): string | undefined {\r\n return this.loadedImages.get(name)\r\n }\r\n\r\n async loadImages(timeout: number): Promise<void> {\r\n await Promise.all(\r\n Object.entries(this.images).map(([name, src]) =>\r\n this.loadImage(name, src, timeout),\r\n ),\r\n )\r\n }\r\n\r\n private loadImage(name: string, src: string, timeout: number): Promise<void> {\r\n return new Promise((resolve) => {\r\n const image = new Image()\r\n const finish = (loaded: boolean) => {\r\n clearTimeout(timer)\r\n image.onload = null\r\n image.onerror = null\r\n if (loaded) this.loadedImages.set(name, src)\r\n resolve()\r\n }\r\n const timer = setTimeout(() => finish(false), timeout)\r\n image.onload = () => finish(true)\r\n image.onerror = () => finish(false)\r\n image.src = src\r\n })\r\n }\r\n}\r\n","import { Theme } from './Theme'\r\nimport type { ThemeConfig, ThemeDefinition } from './theme.types'\r\n\r\nexport class ThemeManager {\r\n private currentTheme: Theme | null = null\r\n private stylesheet: HTMLLinkElement | null = null\r\n private initializationVersion = 0\r\n\r\n constructor(private readonly config: ThemeConfig) {}\r\n\r\n async initialize(requestedTheme?: string | null): Promise<string | null> {\r\n const version = ++this.initializationVersion\r\n const definition = this.resolveTheme(requestedTheme)\r\n\r\n if (!definition) {\r\n this.removeCurrentTheme()\r\n return null\r\n }\r\n\r\n try {\r\n await this.applyTheme(definition, version)\r\n } catch (error) {\r\n if (version !== this.initializationVersion) return this.getThemeName()\r\n console.warn(`Failed to load theme \"${definition.theme}\"`, error)\r\n const fallback = this.config.themes.find((item) => item.default)\r\n\r\n if (fallback && fallback !== definition) {\r\n try {\r\n await this.applyTheme(fallback, version)\r\n } catch (fallbackError) {\r\n console.warn('Failed to load the default theme', fallbackError)\r\n if (version === this.initializationVersion) this.removeCurrentTheme()\r\n }\r\n } else {\r\n this.removeCurrentTheme()\r\n }\r\n }\r\n\r\n return this.getThemeName()\r\n }\r\n\r\n getTheme(): Theme | null {\r\n return this.currentTheme\r\n }\r\n\r\n getThemeName(): string | null {\r\n return this.currentTheme?.theme ?? null\r\n }\r\n\r\n private resolveTheme(requestedTheme?: string | null): ThemeDefinition | null {\r\n return (\r\n this.config.themes.find((item) => item.theme === requestedTheme) ??\r\n this.config.themes.find((item) => item.default) ??\r\n null\r\n )\r\n }\r\n\r\n private async applyTheme(definition: ThemeDefinition, version: number): Promise<void> {\r\n const theme = new Theme(definition)\r\n const timeout = this.config.resourceTimeout ?? 10000\r\n const [stylesheet] = await Promise.all([\r\n theme.cssUrl ? this.loadStylesheet(theme.cssUrl, timeout) : Promise.resolve(null),\r\n theme.loadImages(timeout),\r\n ])\r\n\r\n if (version !== this.initializationVersion) {\r\n stylesheet?.remove()\r\n return\r\n }\r\n\r\n this.removeCurrentTheme()\r\n document.body.classList.add(`${theme.prefix}-${theme.theme}`)\r\n if (stylesheet) stylesheet.media = 'all'\r\n this.stylesheet = stylesheet\r\n this.currentTheme = theme\r\n }\r\n\r\n private loadStylesheet(src: string, timeout: number): Promise<HTMLLinkElement> {\r\n return new Promise((resolve, reject) => {\r\n const link = document.createElement('link')\r\n link.rel = 'stylesheet'\r\n link.href = src\r\n // Load the next stylesheet without applying it before the theme is ready.\r\n link.media = 'not all'\r\n\r\n const cleanup = () => {\r\n clearTimeout(timer)\r\n link.onload = null\r\n link.onerror = null\r\n }\r\n const fail = () => {\r\n cleanup()\r\n link.remove()\r\n reject(new Error(`Failed to load theme stylesheet \"${src}\"`))\r\n }\r\n const timer = setTimeout(fail, timeout)\r\n link.onload = () => {\r\n cleanup()\r\n resolve(link)\r\n }\r\n link.onerror = fail\r\n document.head.appendChild(link)\r\n })\r\n }\r\n\r\n private removeCurrentTheme(): void {\r\n if (this.currentTheme) {\r\n document.body.classList.remove(\r\n `${this.currentTheme.prefix}-${this.currentTheme.theme}`,\r\n )\r\n }\r\n this.stylesheet?.remove()\r\n this.stylesheet = null\r\n this.currentTheme = null\r\n }\r\n}\r\n","import type { CoreConfig } from './core.types'\r\n\r\nimport { AssetManager } from './assets/AssetManager'\r\nimport { AudioManager } from './audio/AudioManager'\r\nimport { CoreStore } from './store/CoreStore'\r\nimport { UIManager } from './ui/UIManager'\r\nimport { URLManager } from './url/URLManager'\r\nimport { LanguageManager } from './language/LanguageManager'\r\nimport { ErrorManager } from './errors/ErrorManager'\r\nimport { SocketManager } from './socket/SocketManager'\r\nimport { OperatorBridge } from './operator/OperatorBridge'\r\nimport { ThemeManager } from './theme/ThemeManager'\r\n\r\nexport class Core {\r\n readonly store: CoreStore\r\n readonly assets: AssetManager\r\n readonly audio: AudioManager\r\n readonly ui: UIManager\r\n readonly language: LanguageManager\r\n readonly url: URLManager\r\n readonly errors: ErrorManager\r\n readonly socket: SocketManager\r\n readonly operator: OperatorBridge\r\n readonly theme: ThemeManager\r\n\r\n constructor(private readonly config: CoreConfig) {\r\n this.store = new CoreStore({\r\n appVersion: this.config.app.version,\r\n provider: this.config.app.provider,\r\n defaultLanguage: this.config.language.defaultLanguage,\r\n fallbackLanguage: this.config.language.fallbackLanguage,\r\n logState: this.config.debug?.logState,\r\n })\r\n this.assets = new AssetManager()\r\n this.audio = new AudioManager(this.assets, this.store)\r\n this.ui = new UIManager(this.store, this.config.ui)\r\n this.language = new LanguageManager(this.store, this.config.language)\r\n this.url = new URLManager(this.config.url)\r\n this.socket = new SocketManager(config.socket)\r\n this.operator = new OperatorBridge(\r\n config.operator ?? {\r\n enabled: false,\r\n provider: 'default',\r\n },\r\n config.debug?.logState ?? false,\r\n )\r\n this.errors = new ErrorManager(this.store, this.operator)\r\n this.theme = new ThemeManager(\r\n config.theme ?? {\r\n themes: [],\r\n },\r\n )\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n const minimumLoadingTime = new Promise<void>((resolve) => {\r\n setTimeout(resolve, this.config.app.minimumLoadingTime ?? 0)\r\n })\r\n\r\n try {\r\n // 0. UI\r\n this.ui.initialize()\r\n\r\n // 1. Parse URL parameters\r\n this.url.initialize()\r\n\r\n // 2. Language\r\n await this.language.initialize(this.url.get('lang'))\r\n\r\n // 3. Validate URL parameters\r\n this.url.validate()\r\n\r\n // 4. Theme Generator\r\n const theme = await this.theme.initialize(this.url.get('theme'))\r\n this.store.setTheme(theme)\r\n\r\n // 4. WebSocket connection\r\n\r\n await this.socket.connect(this.url.get('endpoint'))\r\n\r\n // 7. assets\r\n await this.assets.load(this.config.assets)\r\n\r\n // 8. bets\r\n await minimumLoadingTime\r\n\r\n } catch (error) {\r\n this.errors.handle(error)\r\n }\r\n }\r\n\r\n completeInitialization(): void {\r\n this.store.setInitialized(true)\r\n }\r\n}\r\n","import type { InjectionKey } from 'vue'\r\nimport type { Core } from '../Core'\r\n\r\nexport const CORE_KEY: InjectionKey<Core> = Symbol('core')\r\n","import { inject } from 'vue'\r\nimport { CORE_KEY } from './core.context'\r\nimport type { Core } from '../Core'\r\n\r\nexport const useCore = (): Core => {\r\n const core = inject(CORE_KEY)\r\n\r\n if (!core) {\r\n throw new Error('Core is not available. Make sure CORE_KEY is provided.')\r\n }\r\n\r\n return core\r\n}\r\n\r\n ","import { onUnmounted, shallowRef, triggerRef } from 'vue'\r\nimport { useCore } from './useCore'\r\n\r\nexport const useCoreStore = () => {\r\n const core = useCore()\r\n const state = shallowRef(core.store.state)\r\n\r\n const unsubscribe = core.store.subscribe(() => {\r\n triggerRef(state)\r\n })\r\n\r\n onUnmounted(() => {\r\n unsubscribe()\r\n })\r\n\r\n return {\r\n state,\r\n }\r\n}\r\n","<script setup lang=\"ts\">\r\nimport { useCoreStore } from '../useCoreStore'\r\n\r\nconst { state } = useCoreStore()\r\n\r\ndefineProps<{\r\n title: string\r\n message: string\r\n actionLabel?: string\r\n}>()\r\n\r\ndefineEmits<{\r\n action: []\r\n}>()\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"state.error?.displayIngame !== false\"\r\n class=\"core-error\"\r\n >\r\n <div class=\"core-error__content\">\r\n <div class=\"core-error__icon\">\r\n !\r\n </div>\r\n\r\n <h2 class=\"core-error__title\">\r\n {{ title }}\r\n </h2>\r\n\r\n <p class=\"core-error__message\">\r\n {{ message }}\r\n </p>\r\n\r\n <button\r\n v-if=\"actionLabel\"\r\n type=\"button\"\r\n class=\"core-error__action\"\r\n @click=\"$emit('action')\"\r\n >\r\n {{ actionLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.core-error {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 9999;\r\n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n padding: 40px;\r\n\r\n background: rgba(10, 15, 25, 0.78);\r\n backdrop-filter: blur(4px);\r\n}\r\n\r\n.core-error__content {\r\n width: min(560px, 100%);\r\n padding: 42px 48px;\r\n\r\n text-align: center;\r\n\r\n background: rgba(255, 255, 255, 0.96);\r\n border-radius: 20px;\r\n\r\n box-shadow:\r\n 0 24px 80px rgba(0, 0, 0, 0.35),\r\n 0 4px 16px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.core-error__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n width: 64px;\r\n height: 64px;\r\n margin: 0 auto 22px;\r\n\r\n border-radius: 50%;\r\n\r\n background: #b91c1c;\r\n color: #fff;\r\n\r\n font-size: 42px;\r\n font-weight: 700;\r\n line-height: 1;\r\n}\r\n\r\n.core-error__title {\r\n margin: 0 0 14px;\r\n\r\n color: #111827;\r\n\r\n font-size: 30px;\r\n font-weight: 700;\r\n}\r\n\r\n.core-error__message {\r\n margin: 0;\r\n\r\n color: #4b5563;\r\n\r\n font-size: 20px;\r\n line-height: 1.5;\r\n}\r\n\r\n.core-error__action {\r\n min-width: 160px;\r\n min-height: 48px;\r\n margin-top: 26px;\r\n padding: 10px 24px;\r\n border: 0;\r\n border-radius: 4px;\r\n background: #186cf0;\r\n color: #fff;\r\n cursor: pointer;\r\n font: inherit;\r\n font-weight: 700;\r\n text-transform: uppercase;\r\n}\r\n\r\n.core-error__action:focus-visible {\r\n outline: 3px solid #111827;\r\n outline-offset: 3px;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\nimport { useCoreStore } from '../useCoreStore'\r\n\r\nconst { state } = useCoreStore()\r\n\r\ndefineProps<{\r\n title: string\r\n message: string\r\n actionLabel?: string\r\n}>()\r\n\r\ndefineEmits<{\r\n action: []\r\n}>()\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"state.error?.displayIngame !== false\"\r\n class=\"core-error\"\r\n >\r\n <div class=\"core-error__content\">\r\n <div class=\"core-error__icon\">\r\n !\r\n </div>\r\n\r\n <h2 class=\"core-error__title\">\r\n {{ title }}\r\n </h2>\r\n\r\n <p class=\"core-error__message\">\r\n {{ message }}\r\n </p>\r\n\r\n <button\r\n v-if=\"actionLabel\"\r\n type=\"button\"\r\n class=\"core-error__action\"\r\n @click=\"$emit('action')\"\r\n >\r\n {{ actionLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.core-error {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 9999;\r\n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n padding: 40px;\r\n\r\n background: rgba(10, 15, 25, 0.78);\r\n backdrop-filter: blur(4px);\r\n}\r\n\r\n.core-error__content {\r\n width: min(560px, 100%);\r\n padding: 42px 48px;\r\n\r\n text-align: center;\r\n\r\n background: rgba(255, 255, 255, 0.96);\r\n border-radius: 20px;\r\n\r\n box-shadow:\r\n 0 24px 80px rgba(0, 0, 0, 0.35),\r\n 0 4px 16px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.core-error__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n width: 64px;\r\n height: 64px;\r\n margin: 0 auto 22px;\r\n\r\n border-radius: 50%;\r\n\r\n background: #b91c1c;\r\n color: #fff;\r\n\r\n font-size: 42px;\r\n font-weight: 700;\r\n line-height: 1;\r\n}\r\n\r\n.core-error__title {\r\n margin: 0 0 14px;\r\n\r\n color: #111827;\r\n\r\n font-size: 30px;\r\n font-weight: 700;\r\n}\r\n\r\n.core-error__message {\r\n margin: 0;\r\n\r\n color: #4b5563;\r\n\r\n font-size: 20px;\r\n line-height: 1.5;\r\n}\r\n\r\n.core-error__action {\r\n min-width: 160px;\r\n min-height: 48px;\r\n margin-top: 26px;\r\n padding: 10px 24px;\r\n border: 0;\r\n border-radius: 4px;\r\n background: #186cf0;\r\n color: #fff;\r\n cursor: pointer;\r\n font: inherit;\r\n font-weight: 700;\r\n text-transform: uppercase;\r\n}\r\n\r\n.core-error__action:focus-visible {\r\n outline: 3px solid #111827;\r\n outline-offset: 3px;\r\n}\r\n</style>\r\n","import type { DefineComponent } from 'vue'\r\n\r\nimport ErrorOverlay from './ErrorOverlay.vue'\r\n\r\ntype ErrorOverlayProps = {\r\n title: string\r\n message: string\r\n actionLabel?: string\r\n}\r\n\r\nconst component = ErrorOverlay as DefineComponent<ErrorOverlayProps>\r\n\r\nexport default component\r\n"],"mappings":"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"}
1
+ {"version":3,"file":"gffe-game-core.js","names":["$emit"],"sources":["../src/assets/AssetManager.ts","../src/audio/AudioManager.ts","../src/store/store.types.ts","../src/version.ts","../src/store/CoreStore.ts","../src/ui/UIManager.ts","../src/errors/error.types.ts","../src/errors/CoreError.ts","../src/url/URLManager.ts","../src/language/LanguageManager.ts","../src/errors/ErrorManager.ts","../src/socket/socket.types.ts","../src/socket/SocketManager.ts","../src/operator/utils/load-script.ts","../src/operator/providers/GFFEOperatorProvider.ts","../src/operator/providers/NullOperatorProvider.ts","../src/operator/OperatorBridge.ts","../src/theme/Theme.ts","../src/theme/ThemeManager.ts","../src/Core.ts","../src/vue/core.context.ts","../src/vue/useCore.ts","../src/vue/useCoreStore.ts","../src/vue/components/ErrorOverlay.vue","../src/vue/components/ErrorOverlay.vue","../src/vue/components/ErrorOverlay.ts"],"sourcesContent":["import type { AssetDefinition, AssetManifest } from './asset.types'\r\n\r\nexport class AssetManager {\r\n private readonly assets = new Map<string, unknown>()\r\n\r\n async load(manifest: AssetManifest): Promise<void> {\r\n const entries = Object.entries(manifest)\r\n\r\n await Promise.all(\r\n entries.map(([key, definition]) => this.loadAsset(key, definition)),\r\n )\r\n }\r\n\r\n get<T>(key: string): T {\r\n const asset = this.assets.get(key)\r\n\r\n if (!asset) {\r\n throw new Error(`Asset \"${key}\" is not loaded`)\r\n }\r\n\r\n return asset as T\r\n }\r\n\r\n private async loadAsset(\r\n key: string,\r\n\r\n definition: AssetDefinition,\r\n ): Promise<void> {\r\n switch (definition.type) {\r\n case 'audio':\r\n await this.loadAudio(\r\n key,\r\n\r\n definition.src,\r\n )\r\n\r\n break\r\n\r\n default:\r\n throw new Error(`Unsupported asset type: ${definition.type}`)\r\n }\r\n }\r\n\r\n private loadAudio(key: string, src: string): Promise<void> {\r\n return new Promise((resolve, reject) => {\r\n const audio = new Audio()\r\n\r\n audio.preload = 'auto'\r\n\r\n const handleLoaded = () => {\r\n cleanup()\r\n this.assets.set(key, audio)\r\n resolve()\r\n }\r\n\r\n const handleError = () => {\r\n cleanup()\r\n reject(new Error(`Failed to load audio asset \"${key}\"`))\r\n }\r\n\r\n const cleanup = () => {\r\n audio.removeEventListener('canplaythrough', handleLoaded)\r\n\r\n audio.removeEventListener('error', handleError)\r\n }\r\n\r\n audio.addEventListener('canplaythrough', handleLoaded, { once: true })\r\n audio.addEventListener('error', handleError, { once: true })\r\n\r\n audio.src = src\r\n audio.load()\r\n })\r\n }\r\n}\r\n","import type { AssetManager } from '../assets/AssetManager'\r\nimport type { CoreStore } from '../store/CoreStore'\r\nimport type { AudioKey, AudioPlayOptions } from './audio.types'\r\n\r\nexport class AudioManager {\r\n constructor(\r\n private readonly assets: AssetManager,\r\n private readonly store: CoreStore,\r\n ) {}\r\n\r\n play(key: AudioKey, options: AudioPlayOptions = {}): void {\r\n if (!this.store.state.settings.sounds) {\r\n return\r\n }\r\n\r\n const source = this.assets.get<HTMLAudioElement>(key)\r\n const audio = source.cloneNode(true) as HTMLAudioElement\r\n\r\n audio.volume = this.normalizeVolume(options.volume ?? 1)\r\n audio.loop = options.loop ?? false\r\n\r\n void audio.play().catch((error) => {\r\n console.error(`Failed to play audio \"${key}\"`, error)\r\n })\r\n }\r\n\r\n private normalizeVolume(volume: number): number {\r\n return Math.min(1, Math.max(0, volume))\r\n }\r\n}\r\n","import type { CoreErrorState } from '../errors/error.types'\r\n\r\nexport enum DeviceType {\r\n Mobile = 'mobile',\r\n Tablet = 'tablet',\r\n Desktop = 'desktop',\r\n}\r\n\r\nexport enum Orientation {\r\n Portrait = 'portrait',\r\n Landscape = 'landscape',\r\n}\r\n\r\nexport interface AppState {\r\n theme: string | null\r\n version: string\r\n coreVersion: string\r\n provider: string\r\n initialized: boolean\r\n}\r\n\r\nexport interface SettingsState {\r\n sounds: boolean\r\n}\r\n\r\nexport interface UIState {\r\n screenWidth: number\r\n screenHeight: number\r\n device: DeviceType\r\n orientation: Orientation\r\n}\r\n\r\nexport interface LanguageState {\r\n current: string\r\n fallback: string\r\n loaded: boolean\r\n}\r\n\r\nexport interface CoreStoreOptions {\r\n appVersion: string\r\n provider?: string\r\n\r\n defaultLanguage: string\r\n fallbackLanguage: string\r\n\r\n logState?: boolean\r\n}\r\n\r\nexport interface CoreState {\r\n app: AppState\r\n settings: SettingsState\r\n ui: UIState\r\n language: LanguageState\r\n error: CoreErrorState | null\r\n}\r\n","declare const __CORE_VERSION__: string\r\n\r\nexport const CORE_VERSION = __CORE_VERSION__","import type { CoreErrorState } from '../errors/error.types'\r\nimport {\r\n DeviceType,\r\n Orientation,\r\n type CoreState,\r\n type CoreStoreOptions,\r\n type UIState,\r\n} from './store.types'\r\nimport { CORE_VERSION } from '../version'\r\n\r\ntype StoreListener = () => void\r\n\r\nexport class CoreStore {\r\n readonly state: CoreState\r\n\r\n private readonly logState: boolean\r\n private readonly listeners = new Set<StoreListener>()\r\n\r\n constructor(options: CoreStoreOptions) {\r\n this.logState = options.logState ?? false\r\n this.state = {\r\n app: {\r\n version: options.appVersion,\r\n coreVersion: CORE_VERSION,\r\n provider: options.provider ?? '',\r\n initialized: false,\r\n theme: 'default',\r\n },\r\n\r\n settings: {\r\n sounds: true,\r\n },\r\n\r\n ui: {\r\n screenWidth: 0,\r\n screenHeight: 0,\r\n device: DeviceType.Desktop,\r\n orientation: Orientation.Landscape,\r\n },\r\n\r\n language: {\r\n current: options.defaultLanguage,\r\n fallback: options.fallbackLanguage,\r\n loaded: false,\r\n },\r\n\r\n error: null,\r\n }\r\n }\r\n\r\n setSounds(enabled: boolean): void {\r\n if (this.state.settings.sounds === enabled) {\r\n return\r\n }\r\n\r\n this.state.settings.sounds = enabled\r\n this.notify()\r\n }\r\n\r\n setUI(ui: UIState): void {\r\n const current = this.state.ui\r\n\r\n if (\r\n current.screenWidth === ui.screenWidth &&\r\n current.screenHeight === ui.screenHeight &&\r\n current.device === ui.device &&\r\n current.orientation === ui.orientation\r\n ) {\r\n return\r\n }\r\n\r\n this.state.ui = ui\r\n\r\n this.notify()\r\n }\r\n\r\n setInitialized(initialized: boolean): void {\r\n if (this.state.app.initialized === initialized) {\r\n return\r\n }\r\n\r\n this.state.app.initialized = initialized\r\n\r\n this.notify()\r\n }\r\n\r\n setLanguage(\r\n language: string,\r\n\r\n loaded: boolean,\r\n ): void {\r\n const current = this.state.language\r\n\r\n if (current.current === language && current.loaded === loaded) {\r\n return\r\n }\r\n\r\n this.state.language = {\r\n ...current,\r\n current: language,\r\n loaded,\r\n }\r\n\r\n this.notify()\r\n }\r\n\r\n setTheme(theme: string | null): void {\r\n this.state.app.theme = theme\r\n\r\n this.notify()\r\n }\r\n\r\n setError(error: CoreErrorState | null): void {\r\n this.state.error = error\r\n this.notify()\r\n }\r\n\r\n subscribe(listener: StoreListener): () => void {\r\n this.listeners.add(listener)\r\n\r\n return () => {\r\n this.listeners.delete(listener)\r\n }\r\n }\r\n\r\n private notify(): void {\r\n this.log()\r\n this.listeners.forEach((listener) => {\r\n listener()\r\n })\r\n }\r\n\r\n private log(): void {\r\n if (!this.logState) {\r\n return\r\n }\r\n\r\n console.groupCollapsed(\r\n '%c CORE State ',\r\n [\r\n 'background: #111827',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n )\r\n\r\n console.log(structuredClone(this.state))\r\n console.groupEnd()\r\n }\r\n}\r\n","import type { CoreStore } from '../store/CoreStore'\r\nimport { DeviceType, Orientation } from '../store/store.types'\r\nimport type { UIEventMap, UIManagerOptions } from './ui.types'\r\n\r\ntype UIEvent = keyof UIEventMap\r\ntype UIListener<T extends UIEvent> = (payload: UIEventMap[T]) => void\r\n\r\nexport class UIManager {\r\n private readonly mobileBreakpoint: number\r\n private readonly tabletBreakpoint: number\r\n private readonly listeners = new Map<UIEvent, Set<(payload: any) => void>>()\r\n\r\n constructor(\r\n private readonly store: CoreStore,\r\n\r\n options: UIManagerOptions = {},\r\n ) {\r\n this.mobileBreakpoint = options.mobileBreakpoint ?? 768\r\n\r\n this.tabletBreakpoint = options.tabletBreakpoint ?? 1200\r\n }\r\n\r\n initialize(): void {\r\n this.update()\r\n\r\n window.addEventListener(\r\n 'resize',\r\n\r\n this.handleResize,\r\n )\r\n }\r\n\r\n destroy(): void {\r\n window.removeEventListener(\r\n 'resize',\r\n\r\n this.handleResize,\r\n )\r\n }\r\n\r\n getDevice(): DeviceType {\r\n return this.store.state.ui.device\r\n }\r\n\r\n getOrientation(): Orientation {\r\n return this.store.state.ui.orientation\r\n }\r\n\r\n on<T extends UIEvent>(\r\n event: T,\r\n\r\n listener: UIListener<T>,\r\n ): () => void {\r\n if (!this.listeners.has(event)) {\r\n this.listeners.set(\r\n event,\r\n\r\n new Set(),\r\n )\r\n }\r\n\r\n this.listeners.get(event)!.add(listener)\r\n\r\n return () => {\r\n this.listeners\r\n\r\n .get(event)\r\n\r\n ?.delete(listener)\r\n }\r\n }\r\n\r\n private handleResize = (): void => {\r\n this.update()\r\n }\r\n\r\n private update(): void {\r\n const width = window.innerWidth\r\n\r\n const height = window.innerHeight\r\n\r\n const device = this.resolveDevice(width)\r\n\r\n const orientation = this.resolveOrientation(\r\n width,\r\n\r\n height,\r\n )\r\n\r\n this.store.setUI({\r\n screenWidth: width,\r\n\r\n screenHeight: height,\r\n\r\n device,\r\n\r\n orientation,\r\n })\r\n\r\n this.updateBodyClasses(\r\n device,\r\n\r\n orientation,\r\n )\r\n\r\n this.emit('resize', {\r\n width,\r\n\r\n height,\r\n\r\n device,\r\n\r\n orientation,\r\n })\r\n }\r\n\r\n private resolveDevice(width: number): DeviceType {\r\n if (width < this.mobileBreakpoint) {\r\n return DeviceType.Mobile\r\n }\r\n\r\n if (width < this.tabletBreakpoint) {\r\n return DeviceType.Tablet\r\n }\r\n\r\n return DeviceType.Desktop\r\n }\r\n\r\n private resolveOrientation(\r\n width: number,\r\n\r\n height: number,\r\n ): Orientation {\r\n return width >= height ? Orientation.Landscape : Orientation.Portrait\r\n }\r\n\r\n private updateBodyClasses(\r\n device: DeviceType,\r\n\r\n orientation: Orientation,\r\n ): void {\r\n const body = document.body\r\n\r\n Object.values(DeviceType).forEach((value) => {\r\n body.classList.remove(`device-${value}`)\r\n })\r\n\r\n Object.values(Orientation).forEach((value) => {\r\n body.classList.remove(`orientation-${value}`)\r\n })\r\n\r\n body.classList.add(\r\n `device-${device}`,\r\n\r\n `orientation-${orientation}`,\r\n )\r\n }\r\n\r\n private emit<T extends UIEvent>(\r\n event: T,\r\n\r\n payload: UIEventMap[T],\r\n ): void {\r\n this.listeners\r\n\r\n .get(event)\r\n\r\n ?.forEach((listener) => {\r\n listener(payload)\r\n })\r\n }\r\n}\r\n","export enum CoreErrorSeverity {\r\n Fatal = 'fatal',\r\n Recoverable = 'recoverable',\r\n}\r\n\r\nexport enum CoreErrorCode {\r\n UrlMissingParameter = 'URL_MISSING_PARAMETER',\r\n\r\n SocketConnectionFailed = 'SOCKET_CONNECTION_FAILED',\r\n SocketDisconnected = 'SOCKET_DISCONNECTED',\r\n SocketNotConnected = 'SOCKET_NOT_CONNECTED',\r\n SocketSendFailed = 'SOCKET_SEND_FAILED',\r\n SocketInvalidMessage = 'SOCKET_INVALID_MESSAGE',\r\n SocketRequestTimeout = 'SOCKET_REQUEST_TIMEOUT',\r\n SocketProtocolMismatch = 'SOCKET_PROTOCOL_MISMATCH',\r\n\r\n RGSRequestFailed = 'RGS_REQUEST_FAILED',\r\n\r\n Unknown = 'UNKNOWN_ERROR',\r\n}\r\n\r\nexport interface CoreErrorContext {\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface CoreErrorState {\r\n /** False when the operator accepted responsibility for displaying this error. */\r\n displayIngame?: boolean\r\n code: CoreErrorCode\r\n severity: CoreErrorSeverity\r\n message: string\r\n userMessageKey: string\r\n context?: CoreErrorContext\r\n}\r\n","import type { CoreErrorContext } from './error.types'\r\nimport { CoreErrorCode, CoreErrorSeverity } from './error.types'\r\n\r\nexport class CoreError extends Error {\r\n constructor(\r\n public readonly code: CoreErrorCode,\r\n message: string,\r\n\r\n public readonly userMessageKey: string,\r\n public readonly severity: CoreErrorSeverity = CoreErrorSeverity.Fatal,\r\n public readonly context?: CoreErrorContext,\r\n ) {\r\n super(message)\r\n this.name = 'CoreError'\r\n }\r\n}\r\n","import type { URLParams, URLParamsConfig } from './url.types'\r\nimport { CoreError } from '../errors/CoreError'\r\nimport { CoreErrorCode, CoreErrorSeverity } from '../errors/error.types'\r\n\r\nexport class URLManager {\r\n private params: URLParams = {}\r\n\r\n constructor(private readonly config: URLParamsConfig) {}\r\n\r\n initialize(): void {\r\n const searchParams = new URLSearchParams(window.location.search)\r\n\r\n const params: URLParams = {}\r\n\r\n for (const [key, definition] of Object.entries(this.config)) {\r\n const source = definition.source ?? key\r\n\r\n const rawValue = searchParams.get(source)\r\n\r\n params[key] =\r\n rawValue !== null && rawValue.trim() !== ''\r\n ? rawValue.trim()\r\n : (definition.default ?? '')\r\n }\r\n\r\n this.params = params\r\n }\r\n\r\n validate(): void {\r\n for (const [key, definition] of Object.entries(this.config)) {\r\n if (!definition.required) {\r\n continue\r\n }\r\n\r\n const value = this.params[key]\r\n\r\n if (value !== '') {\r\n continue\r\n }\r\n\r\n const source = definition.source ?? key\r\n\r\n throw new CoreError(\r\n CoreErrorCode.UrlMissingParameter,\r\n `Missing required URL parameter: \"${source}\"`,\r\n 'errors.initialization',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n parameter: source,\r\n },\r\n )\r\n }\r\n }\r\n\r\n get(key: string): string {\r\n return this.params[key] ?? ''\r\n }\r\n\r\n getAll(): Readonly<URLParams> {\r\n return this.params\r\n }\r\n}\r\n","import type { CoreStore } from '../store/CoreStore'\r\n\r\nimport type {\r\n LanguageCode,\r\n LanguageManagerOptions,\r\n LanguageMessages,\r\n} from './language.types'\r\n\r\nexport class LanguageManager {\r\n private currentLanguage: LanguageCode\r\n\r\n private messages: LanguageMessages = {}\r\n\r\n constructor(\r\n private readonly store: CoreStore,\r\n private readonly options: LanguageManagerOptions,\r\n ) {\r\n this.currentLanguage = options.defaultLanguage\r\n }\r\n\r\n async initialize(language?: LanguageCode): Promise<void> {\r\n await this.load(language ?? this.options.defaultLanguage)\r\n }\r\n\r\n async load(language: LanguageCode): Promise<void> {\r\n const loader = this.options.loaders[language]\r\n\r\n if (!loader) {\r\n await this.loadFallback()\r\n return\r\n }\r\n\r\n try {\r\n this.messages = await loader()\r\n\r\n this.currentLanguage = language\r\n\r\n this.store.setLanguage(language, true)\r\n } catch {\r\n await this.loadFallback()\r\n }\r\n }\r\n\r\n getLanguage(): LanguageCode {\r\n return this.currentLanguage\r\n }\r\n\r\n getMessages(): LanguageMessages {\r\n return this.messages\r\n }\r\n\r\n private async loadFallback(): Promise<void> {\r\n const fallback = this.options.fallbackLanguage\r\n\r\n const loader = this.options.loaders[fallback]\r\n\r\n if (!loader) {\r\n throw new Error(`Fallback language \"${fallback}\" is not configured`)\r\n }\r\n\r\n this.messages = await loader()\r\n\r\n this.currentLanguage = fallback\r\n\r\n this.store.setLanguage(fallback, true)\r\n }\r\n}\r\n","import type { OperatorBridge } from '../operator/OperatorBridge'\r\nimport type { CoreStore } from '../store/CoreStore'\r\n\r\nimport { CoreError } from './CoreError'\r\n\r\nimport { CoreErrorCode } from './error.types'\r\n\r\nexport class ErrorManager {\r\n constructor(\r\n private readonly store: CoreStore,\r\n private readonly operator?: OperatorBridge,\r\n ) {}\r\n\r\n handle(error: unknown): void {\r\n const coreError =\r\n error instanceof CoreError\r\n ? error\r\n : new CoreError(\r\n CoreErrorCode.Unknown,\r\n\r\n error instanceof Error ? error.message : 'Unknown error',\r\n\r\n 'errors.generic',\r\n )\r\n\r\n this.log(coreError)\r\n\r\n const context = coreError.context\r\n const errorType = context?.errorType\r\n const errorCode = context?.errorCode\r\n const errorTitle = context?.title\r\n const delegated = this.operator?.tryDelegateError({\r\n errorType: typeof errorType === 'string' ? errorType : coreError.code,\r\n code: typeof errorCode === 'string' || typeof errorCode === 'number'\r\n ? errorCode\r\n : coreError.code,\r\n title: typeof errorTitle === 'string' ? errorTitle : 'Error',\r\n text: coreError.message,\r\n }) ?? false\r\n\r\n this.store.setError({\r\n displayIngame: !delegated,\r\n code: coreError.code,\r\n severity: coreError.severity,\r\n message: coreError.message,\r\n userMessageKey: coreError.userMessageKey,\r\n context: coreError.context,\r\n })\r\n }\r\n\r\n clear(): void {\r\n this.store.setError(null)\r\n }\r\n\r\n private log(error: CoreError): void {\r\n console.groupCollapsed(\r\n '%c CORE Error ',\r\n [\r\n 'background: #991b1b',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n )\r\n\r\n console.error({\r\n code: error.code,\r\n message: error.message,\r\n context: error.context,\r\n })\r\n\r\n console.groupEnd()\r\n }\r\n}\r\n","export enum SocketState {\r\n Disconnected = 'disconnected',\r\n Connecting = 'connecting',\r\n Connected = 'connected',\r\n}\r\n\r\nexport interface SocketMessage {\r\n requestType: string\r\n}\r\n\r\nexport interface SocketErrorObject {\r\n operatorCode?: string\r\n operatorMessage?: string\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface SocketResponseError {\r\n errorType: string | null\r\n errorCode: number | string\r\n errorMessage: string\r\n errorObject: SocketErrorObject | null\r\n}\r\n\r\nexport interface SocketErrorResponse {\r\n requestType: string\r\n updateType: 'ERROR'\r\n error: SocketResponseError\r\n\r\n [key: string]: unknown\r\n}\r\n\r\nexport interface SocketConfig {\r\n urlSuffix?: string\r\n requestTimeout?: number\r\n\r\n heartbeat?: {\r\n enabled: boolean\r\n interval: number\r\n timeout?: number\r\n message: SocketMessage\r\n }\r\n\r\n eventTypes?: string[]\r\n}\r\n\r\nexport type SocketBroadcastListener<T = unknown> = (\r\n message: T,\r\n requestType: string,\r\n) => void\r\n\r\nexport interface SocketDisconnectPayload {\r\n code: number\r\n reason: string\r\n wasClean: boolean\r\n}\r\n\r\nexport type SocketDisconnectListener = (payload: SocketDisconnectPayload) => void\r\n\r\nexport enum SocketLogType {\r\n Frontend = 'Frontend',\r\n Backend = 'Backend',\r\n Broadcast = 'Broadcast',\r\n Error = 'Error',\r\n}\r\n\r\nexport type SocketEvent = 'connect' | 'disconnect' | 'message' | 'error'\r\n\r\nexport type SocketEventListener<T = unknown> = (payload: T) => void\r\n","import { CoreError } from '../errors/CoreError'\r\nimport { CoreErrorCode, CoreErrorSeverity } from '../errors/error.types'\r\n\r\nimport {\r\n SocketLogType,\r\n SocketState,\r\n type SocketBroadcastListener,\r\n type SocketConfig,\r\n type SocketDisconnectListener,\r\n type SocketDisconnectPayload,\r\n type SocketMessage,\r\n} from './socket.types'\r\n\r\ninterface PendingRequest {\r\n requestType: string\r\n resolve: (message: unknown) => void\r\n reject: (error: CoreError) => void\r\n timeout: ReturnType<typeof setTimeout>\r\n}\r\n\r\nexport class SocketManager {\r\n private socket: WebSocket | null = null\r\n private state: SocketState = SocketState.Disconnected\r\n private lastAction: string | null = null\r\n private pendingRequest: PendingRequest | null = null\r\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null\r\n private heartbeatResponseTimer: ReturnType<typeof setTimeout> | null = null\r\n private intentionalDisconnect = false\r\n private readonly broadcastListeners = new Set<SocketBroadcastListener>()\r\n private readonly disconnectListeners = new Set<SocketDisconnectListener>()\r\n private readonly heartbeatChecks = new Set<(connected: boolean) => void>()\r\n\r\n constructor(private readonly config: SocketConfig) {}\r\n\r\n connect(endpoint: string): Promise<void> {\r\n const url = this.buildUrl(endpoint)\r\n\r\n this.intentionalDisconnect = false\r\n\r\n if (this.state === SocketState.Connected) {\r\n return Promise.resolve()\r\n }\r\n\r\n if (this.state === SocketState.Connecting) {\r\n return Promise.reject(\r\n new CoreError(\r\n CoreErrorCode.SocketConnectionFailed,\r\n 'WebSocket connection is already in progress',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n url,\r\n },\r\n ),\r\n )\r\n }\r\n\r\n this.state = SocketState.Connecting\r\n\r\n return new Promise((resolve, reject) => {\r\n try {\r\n this.socket = new WebSocket(url)\r\n\r\n this.socket.onopen = () => {\r\n this.state = SocketState.Connected\r\n\r\n console.log('[Socket] Connected', url)\r\n\r\n resolve()\r\n }\r\n\r\n this.socket.onmessage = (event) => {\r\n this.handleMessage(event)\r\n }\r\n\r\n this.socket.onerror = () => {\r\n if (this.state !== SocketState.Connecting) {\r\n return\r\n }\r\n\r\n this.state = SocketState.Disconnected\r\n\r\n const error = new CoreError(\r\n CoreErrorCode.SocketConnectionFailed,\r\n `Failed to connect to WebSocket: \"${url}\"`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n url,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error)\r\n\r\n this.socket = null\r\n\r\n reject(error)\r\n }\r\n\r\n this.socket.onclose = (event) => {\r\n this.handleDisconnect({\r\n code: event.code,\r\n reason: event.reason,\r\n wasClean: event.wasClean,\r\n })\r\n }\r\n } catch (error) {\r\n this.state = SocketState.Disconnected\r\n this.socket = null\r\n\r\n const coreError = new CoreError(\r\n CoreErrorCode.SocketConnectionFailed,\r\n error instanceof Error\r\n ? error.message\r\n : 'Failed to create WebSocket connection',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n url,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, coreError)\r\n\r\n reject(coreError)\r\n }\r\n })\r\n }\r\n\r\n disconnect(): void {\r\n this.intentionalDisconnect = true\r\n this.stopHeartbeat()\r\n this.clearPendingRequest()\r\n this.resolveHeartbeatChecks(false)\r\n\r\n if (!this.socket) {\r\n this.state = SocketState.Disconnected\r\n return\r\n }\r\n\r\n const socket = this.socket\r\n\r\n socket.onclose = null\r\n socket.close()\r\n this.socket = null\r\n\r\n this.state = SocketState.Disconnected\r\n }\r\n\r\n send(message: SocketMessage): void {\r\n if (!this.socket || this.state !== SocketState.Connected) {\r\n const error = new CoreError(\r\n CoreErrorCode.SocketNotConnected,\r\n 'Cannot send message: WebSocket is not connected',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType: message.requestType,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error, message.requestType)\r\n\r\n throw error\r\n }\r\n\r\n try {\r\n this.socket.send(JSON.stringify(message))\r\n\r\n this.log(SocketLogType.Frontend, message, message.requestType)\r\n } catch (error) {\r\n const coreError = new CoreError(\r\n CoreErrorCode.SocketSendFailed,\r\n error instanceof Error\r\n ? error.message\r\n : 'Failed to send WebSocket message',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType: message.requestType,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, coreError, message.requestType)\r\n\r\n throw coreError\r\n }\r\n }\r\n\r\n request<TResponse>(message: SocketMessage): Promise<TResponse> {\r\n if (this.pendingRequest) {\r\n const error = new CoreError(\r\n CoreErrorCode.SocketProtocolMismatch,\r\n `Cannot send \"${message.requestType}\" while \"${this.lastAction}\" is still pending`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n pendingRequestType: this.lastAction,\r\n requestType: message.requestType,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error, message.requestType)\r\n\r\n return Promise.reject(error)\r\n }\r\n\r\n return new Promise<TResponse>((resolve, reject) => {\r\n const requestType = message.requestType\r\n\r\n const timeout = setTimeout(() => {\r\n const error = new CoreError(\r\n CoreErrorCode.SocketRequestTimeout,\r\n `WebSocket request \"${requestType}\" timed out`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType,\r\n timeout: this.config.requestTimeout ?? 10_000,\r\n },\r\n )\r\n\r\n this.log(SocketLogType.Error, error, requestType)\r\n\r\n this.clearPendingRequest()\r\n\r\n reject(error)\r\n }, this.config.requestTimeout ?? 10_000)\r\n\r\n this.lastAction = requestType\r\n\r\n this.pendingRequest = {\r\n requestType,\r\n resolve: resolve as (message: unknown) => void,\r\n reject,\r\n timeout,\r\n }\r\n\r\n try {\r\n this.send(message)\r\n } catch (error) {\r\n this.clearPendingRequest()\r\n\r\n reject(\r\n error instanceof CoreError\r\n ? error\r\n : new CoreError(\r\n CoreErrorCode.SocketSendFailed,\r\n 'Failed to send WebSocket request',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n requestType,\r\n },\r\n ),\r\n )\r\n }\r\n })\r\n }\r\n\r\n getState(): SocketState {\r\n return this.state\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.state === SocketState.Connected\r\n }\r\n\r\n /**\r\n * Subscribes to messages whose requestType is configured in eventTypes.\r\n *\r\n * @example\r\n * const unsubscribe = core.socket.onBroadcast<GameUpdate>((message, requestType) => {\r\n * console.log(requestType, message)\r\n * })\r\n *\r\n * unsubscribe()\r\n */\r\n onBroadcast<T = unknown>(listener: SocketBroadcastListener<T>): () => void {\r\n const broadcastListener = listener as SocketBroadcastListener\r\n\r\n this.broadcastListeners.add(broadcastListener)\r\n\r\n return () => {\r\n this.broadcastListeners.delete(broadcastListener)\r\n }\r\n }\r\n\r\n onDisconnect(listener: SocketDisconnectListener): () => void {\r\n this.disconnectListeners.add(listener)\r\n\r\n return () => {\r\n this.disconnectListeners.delete(listener)\r\n }\r\n }\r\n\r\n checkConnection(): Promise<boolean> {\r\n if (!this.isConnected()) {\r\n return Promise.resolve(false)\r\n }\r\n\r\n if (!this.config.heartbeat?.enabled) {\r\n return Promise.resolve(true)\r\n }\r\n\r\n return new Promise((resolve) => {\r\n this.heartbeatChecks.add(resolve)\r\n this.sendHeartbeat()\r\n })\r\n }\r\n\r\n private handleMessage(event: MessageEvent): void {\r\n let message: unknown\r\n\r\n try {\r\n message = JSON.parse(event.data)\r\n\r\n\t\t\tif (\r\n\t\t\t\tmessage !== null &&\r\n\t\t\t\ttypeof message === 'object' &&\r\n\t\t\t\t'updateType' in message &&\r\n\t\t\t\tmessage.updateType === 'ROOM_TYPE'\r\n\t\t\t\t) {\r\n\t\t\t\t\treturn\r\n\t\t\t\t}\r\n } catch {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketInvalidMessage,\r\n 'Received invalid JSON from WebSocket server',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n data: event.data,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n const requestType = this.getRequestType(message)\r\n\r\n if (!requestType) {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketInvalidMessage,\r\n 'WebSocket message does not contain a valid requestType',\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n message,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n /*\r\n * Heartbeat responses are independent from\r\n * normal request/response correlation.\r\n */\r\n if (requestType === this.config.heartbeat?.message.requestType) {\r\n this.log(SocketLogType.Backend, message, requestType)\r\n this.clearHeartbeatResponseTimer()\r\n this.resolveHeartbeatChecks(true)\r\n\r\n return\r\n }\r\n\r\n /*\r\n * Broadcasts / server events are unsolicited\r\n * and do not affect the pending request.\r\n */\r\n if (this.config.eventTypes?.includes(requestType)) {\r\n this.log(SocketLogType.Broadcast, message, requestType)\r\n this.emitBroadcast(message, requestType)\r\n\r\n return\r\n }\r\n\r\n /*\r\n * Everything below this point is considered\r\n * a response to a pending request.\r\n */\r\n if (!this.pendingRequest || !this.lastAction) {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketProtocolMismatch,\r\n `Received unexpected WebSocket response \"${requestType}\"`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n receivedRequestType: requestType,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n /*\r\n * The response must match the request\r\n * currently waiting for a response.\r\n */\r\n if (requestType !== this.lastAction) {\r\n this.handleProtocolError(\r\n new CoreError(\r\n CoreErrorCode.SocketProtocolMismatch,\r\n `Expected response \"${this.lastAction}\" but received \"${requestType}\"`,\r\n 'errors.connection',\r\n CoreErrorSeverity.Fatal,\r\n {\r\n expectedRequestType: this.lastAction,\r\n receivedRequestType: requestType,\r\n },\r\n ),\r\n )\r\n\r\n return\r\n }\r\n\r\n /*\r\n * The protocol correlation is valid.\r\n *\r\n * An RGS ERROR response is still a valid\r\n * response to the request, so the Promise\r\n * must be resolved. The caller decides how\r\n * to handle the RGS/operator error.\r\n */\r\n this.log(\r\n this.isErrorResponse(message)\r\n ? SocketLogType.Error\r\n : SocketLogType.Backend,\r\n message,\r\n requestType,\r\n )\r\n\r\n const pending = this.pendingRequest\r\n\r\n this.clearPendingRequest()\r\n\r\n pending.resolve(message)\r\n }\r\n\r\n private emitBroadcast(message: unknown, requestType: string): void {\r\n for (const listener of [...this.broadcastListeners]) {\r\n try {\r\n listener(message, requestType)\r\n } catch (error) {\r\n this.log(SocketLogType.Error, error, `broadcast:${requestType}`)\r\n }\r\n }\r\n }\r\n\r\n private emitDisconnect(payload: SocketDisconnectPayload): void {\r\n for (const listener of [...this.disconnectListeners]) {\r\n try {\r\n listener(payload)\r\n } catch (error) {\r\n this.log(SocketLogType.Error, error, 'disconnect')\r\n }\r\n }\r\n }\r\n\r\n private handleDisconnect(payload: SocketDisconnectPayload): void {\r\n const shouldNotify = !this.intentionalDisconnect\r\n\r\n this.stopHeartbeat()\r\n this.state = SocketState.Disconnected\r\n this.socket = null\r\n this.clearPendingRequest()\r\n this.resolveHeartbeatChecks(false)\r\n\r\n console.log('[Socket] Disconnected', payload)\r\n\r\n if (shouldNotify) {\r\n this.emitDisconnect(payload)\r\n }\r\n }\r\n\r\n private handleHeartbeatTimeout(): void {\r\n if (!this.isConnected()) {\r\n this.resolveHeartbeatChecks(false)\r\n return\r\n }\r\n\r\n const socket = this.socket\r\n\r\n if (socket) {\r\n socket.onclose = null\r\n }\r\n\r\n this.handleDisconnect({\r\n code: 4000,\r\n reason: 'heartbeat_timeout',\r\n wasClean: false,\r\n })\r\n\r\n socket?.close(4000, 'heartbeat_timeout')\r\n }\r\n\r\n private sendHeartbeat(): void {\r\n const heartbeat = this.config.heartbeat\r\n\r\n if (!heartbeat?.enabled || this.heartbeatResponseTimer) {\r\n return\r\n }\r\n\r\n try {\r\n this.send(heartbeat.message)\r\n\r\n this.heartbeatResponseTimer = setTimeout(\r\n () => this.handleHeartbeatTimeout(),\r\n heartbeat.timeout ?? Math.max(5_000, heartbeat.interval),\r\n )\r\n } catch {\r\n this.handleHeartbeatTimeout()\r\n }\r\n }\r\n\r\n private clearHeartbeatResponseTimer(): void {\r\n if (!this.heartbeatResponseTimer) return\r\n\r\n clearTimeout(this.heartbeatResponseTimer)\r\n this.heartbeatResponseTimer = null\r\n }\r\n\r\n private resolveHeartbeatChecks(connected: boolean): void {\r\n for (const resolve of [...this.heartbeatChecks]) {\r\n resolve(connected)\r\n }\r\n\r\n this.heartbeatChecks.clear()\r\n }\r\n\r\n private getRequestType(message: unknown): string | null {\r\n if (!message || typeof message !== 'object') {\r\n return null\r\n }\r\n\r\n const data = message as Record<string, unknown>\r\n\r\n /*\r\n * RGS error response:\r\n *\r\n * {\r\n * requestType: \"login\",\r\n * updateType: \"ERROR\",\r\n * ...\r\n * }\r\n */\r\n if (typeof data.requestType === 'string') {\r\n return data.requestType\r\n }\r\n\r\n /*\r\n * RGS successful response:\r\n *\r\n * {\r\n * response: {\r\n * requestType: \"login\",\r\n * ...\r\n * }\r\n * }\r\n */\r\n if (data.response && typeof data.response === 'object') {\r\n const response = data.response as Record<string, unknown>\r\n\r\n if (typeof response.requestType === 'string') {\r\n return response.requestType\r\n }\r\n }\r\n\r\n return null\r\n }\r\n\r\n private handleProtocolError(error: CoreError): void {\r\n this.log(SocketLogType.Error, error)\r\n\r\n if (this.pendingRequest) {\r\n const pending = this.pendingRequest\r\n\r\n this.clearPendingRequest()\r\n\r\n pending.reject(error)\r\n return\r\n }\r\n\r\n /*\r\n * Later this error must be emitted to Core,\r\n * because there may be no active request\r\n * Promise capable of propagating it.\r\n */\r\n }\r\n private clearPendingRequest(): void {\r\n if (this.pendingRequest) {\r\n clearTimeout(this.pendingRequest.timeout)\r\n }\r\n\r\n this.pendingRequest = null\r\n this.lastAction = null\r\n }\r\n\r\n private buildUrl(endpoint: string): string {\r\n const normalizedEndpoint = endpoint\r\n .replace(/^https?:\\/\\//, '')\r\n .replace(/^wss?:\\/\\//, '')\r\n .replace(/\\/+$/, '')\r\n\r\n const suffix = (this.config.urlSuffix ?? '').replace(/^\\/+/, '')\r\n\r\n return suffix\r\n ? `wss://${normalizedEndpoint}/${suffix}`\r\n : `wss://${normalizedEndpoint}`\r\n }\r\n\r\n private isErrorResponse(message: unknown): boolean {\r\n if (!message || typeof message !== 'object') {\r\n return false\r\n }\r\n\r\n const data = message as Record<string, unknown>\r\n\r\n return data.updateType === 'ERROR'\r\n }\r\n\r\n private log(type: SocketLogType, data: unknown, label?: string): void {\r\n const styles: Record<SocketLogType, string> = {\r\n [SocketLogType.Frontend]: [\r\n 'background: #2563eb',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n\r\n [SocketLogType.Backend]: [\r\n 'background: #059669',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n\r\n [SocketLogType.Broadcast]: [\r\n 'background: #7c3aed',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n\r\n [SocketLogType.Error]: [\r\n 'background: #991b1b',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n }\r\n\r\n const suffix = label ? ` ${label}` : ''\r\n\r\n console.groupCollapsed(\r\n `%c CORE WebSocket · ${type} %c${suffix}`,\r\n styles[type],\r\n ['color: #6b7280', 'font-weight: normal'].join(';'),\r\n )\r\n\r\n if (type === SocketLogType.Error) {\r\n console.error(data)\r\n } else {\r\n console.log(data)\r\n }\r\n\r\n console.groupEnd()\r\n }\r\n\r\n startHeartbeat(): void {\r\n const heartbeat = this.config.heartbeat\r\n\r\n if (!heartbeat?.enabled || this.heartbeatTimer) {\r\n return\r\n }\r\n\r\n this.heartbeatTimer = setInterval(() => {\r\n this.sendHeartbeat()\r\n }, heartbeat.interval)\r\n }\r\n\r\n stopHeartbeat(): void {\r\n this.clearHeartbeatResponseTimer()\r\n\r\n if (!this.heartbeatTimer) {\r\n return\r\n }\r\n\r\n clearInterval(this.heartbeatTimer)\r\n\r\n this.heartbeatTimer = null\r\n }\r\n}\r\n","export const loadScript = (src: string): Promise<void> => {\r\n return new Promise((resolve, reject) => {\r\n const existing = document.querySelector<HTMLScriptElement>(\r\n `script[src=\"${src}\"]`,\r\n )\r\n\r\n if (existing) {\r\n if (existing.dataset.loaded === 'true') {\r\n resolve()\r\n return\r\n }\r\n\r\n existing.addEventListener('load', () => resolve(), { once: true })\r\n existing.addEventListener(\r\n 'error',\r\n () => reject(new Error(`Failed to load script: \"${src}\"`)),\r\n { once: true },\r\n )\r\n return\r\n }\r\n\r\n const script = document.createElement('script')\r\n script.type = 'text/javascript'\r\n script.async = true\r\n script.src = src\r\n script.addEventListener(\r\n 'load',\r\n () => {\r\n script.dataset.loaded = 'true'\r\n resolve()\r\n },\r\n { once: true },\r\n )\r\n script.addEventListener(\r\n 'error',\r\n () => {\r\n reject(new Error(`Failed to load script: \"${src}\"`))\r\n },\r\n { once: true },\r\n )\r\n\r\n document.head.appendChild(script)\r\n })\r\n}\r\n","import type {\r\n BalanceUpdatePayload,\r\n NotifyErrorPayload,\r\n OperatorCallbacks,\r\n OperatorConfig,\r\n OperatorInformation,\r\n} from '../operator.types'\r\n\r\nimport type { OperatorProvider } from './OperatorProvider'\r\n\r\nimport { loadScript } from '../utils/load-script'\r\n\r\nexport class GFFEOperatorProvider implements OperatorProvider {\r\n private api: Window['GFFEAPI']\r\n\r\n constructor(private readonly config: OperatorConfig) {}\r\n\r\n async initialize(callbacks: OperatorCallbacks): Promise<void> {\r\n if (!this.config.providerUrl) {\r\n throw new Error('GFFE provider URL is not configured')\r\n }\r\n\r\n await loadScript(this.config.providerUrl)\r\n\r\n this.api = window.GFFEAPI\r\n\r\n if (!this.api) {\r\n throw new Error(\r\n 'GFFEAPI is not available after loading the provider script',\r\n )\r\n }\r\n\r\n await this.api.initialize({\r\n onStopAutoplay: callbacks.onStopAutoplay ?? (() => {}),\r\n onUpdateBalance: callbacks.onUpdateBalance ?? (() => {}),\r\n onToggleAudio: callbacks.onToggleAudio ?? (() => {}),\r\n onShowIngameModal: callbacks.onShowIngameModal ?? (() => {}),\r\n onToggleCloak: callbacks.onToggleCloak ?? (() => {}),\r\n onVisibilityChange: callbacks.onVisibilityChange ?? (() => {}),\r\n onGetGameConfig:\r\n callbacks.onGetGameConfig ??\r\n (() => ({\r\n supportsPortraitMode: true,\r\n supportsLandscapeMode: true,\r\n })),\r\n onCustomCommand: callbacks.onCustomCommand ?? (() => {}),\r\n })\r\n }\r\n\r\n destroy(): void {\r\n this.api = undefined\r\n }\r\n\r\n isActive(): boolean {\r\n return this.api?.isWrapperActive() ?? false\r\n }\r\n\r\n getOperatorInformation(): OperatorInformation | null {\r\n return this.api?.getOperatorInformation() ?? null\r\n }\r\n\r\n notifyLoadingStarted(): void {\r\n this.api?.notifyLoadingStarted()\r\n }\r\n\r\n notifyLoadingProgress(percentage: number): void {\r\n this.api?.notifyLoadingProgress({\r\n percentage,\r\n })\r\n }\r\n\r\n notifyLoadingEnded(): void {\r\n this.api?.notifyLoadingEnded()\r\n }\r\n\r\n notifyGameReady(): void {\r\n this.api?.notifyGameIsReady()\r\n }\r\n\r\n notifyBalanceUpdate(payload: BalanceUpdatePayload): void {\r\n this.api?.notifyBalanceUpdate(payload)\r\n }\r\n\r\n notifyStakeUpdate(bet: number): void {\r\n this.api?.notifyStakeUpdate({\r\n bet,\r\n })\r\n }\r\n\r\n notifyRoundStart(): void {\r\n this.api?.notifyRoundStart()\r\n }\r\n\r\n notifyRoundEnd(): void {\r\n this.api?.notifyRoundEnd()\r\n }\r\n\r\n notifyAudioChanged(enabled: boolean): void {\r\n this.api?.notifyToggleAudio({\r\n enabled,\r\n })\r\n }\r\n\r\n visitLobby(): void {\r\n this.api?.visitLobby()\r\n }\r\n\r\n visitCashier(): void {\r\n this.api?.visitCashier()\r\n }\r\n\r\n\tvisitHistory(historyURL: string): void {\r\n\t\tthis.api?.visitHistory({ historyUrl: historyURL });\r\n\t}\r\n\r\n notifyError(payload: NotifyErrorPayload): void {\r\n if (!this.api?.notifyError) {\r\n throw new Error('GFFEAPI.notifyError is not available')\r\n }\r\n\r\n this.api.notifyError({\r\n\t\t\t...payload,\r\n\t\t\terrorType: this.mapErrorType(payload.errorType)\r\n\t\t})\r\n }\r\n\r\n\tprivate mapErrorType(errorType: string): string {\r\n // Map error codes to error types as needed\r\n // This is a placeholder implementation\r\n switch (errorType) {\r\n case 'critical':\r\n return 'CRITICAL_ERROR';\r\n case 'insufficient_funds':\r\n return 'INSUFFICIENT_FUNDS';\r\n default:\r\n return 'CRITICAL_ERROR';\r\n }\r\n }\r\n}\r\n","import type {\r\n BalanceUpdatePayload,\r\n NotifyErrorPayload,\r\n OperatorCallbacks,\r\n OperatorInformation,\r\n} from '../operator.types'\r\n\r\nimport type { OperatorProvider } from './OperatorProvider'\r\n\r\nexport class NullOperatorProvider implements OperatorProvider {\r\n async initialize(_callbacks: OperatorCallbacks): Promise<void> {}\r\n\r\n destroy(): void {}\r\n\r\n isActive(): boolean {\r\n return false\r\n }\r\n\r\n getOperatorInformation(): OperatorInformation | null {\r\n return null\r\n }\r\n\r\n notifyLoadingStarted(): void {}\r\n\r\n notifyLoadingProgress(_percentage: number): void {}\r\n\r\n notifyLoadingEnded(): void {}\r\n\r\n notifyGameReady(): void {}\r\n\r\n notifyBalanceUpdate(_payload: BalanceUpdatePayload): void {}\r\n\r\n notifyStakeUpdate(_bet: number): void {}\r\n\r\n notifyRoundStart(): void {}\r\n\r\n notifyRoundEnd(): void {}\r\n\r\n notifyAudioChanged(_enabled: boolean): void {}\r\n\r\n visitLobby(): void {}\r\n\r\n visitCashier(): void {}\r\n\r\n notifyError(_payload: NotifyErrorPayload): void {}\r\n\r\n\tvisitHistory(historyURL: string): void {}\r\n}\r\n","import type {\r\n BalanceUpdatePayload,\r\n NotifyErrorPayload,\r\n OperatorCallbacks,\r\n OperatorConfig,\r\n OperatorInformation,\r\n} from './operator.types'\r\n\r\nimport type { OperatorProvider } from './providers/OperatorProvider'\r\n//providers\r\nimport { GFFEOperatorProvider } from './providers/GFFEOperatorProvider'\r\nimport { NullOperatorProvider } from './providers/NullOperatorProvider'\r\n\r\nexport class OperatorBridge {\r\n private provider: OperatorProvider\r\n\r\n constructor(\r\n private readonly config: OperatorConfig,\r\n private readonly logState = false,\r\n ) {\r\n this.provider = new NullOperatorProvider()\r\n }\r\n\r\n async initialize(callbacks: OperatorCallbacks): Promise<void> {\r\n this.log('Initialize', {\r\n enabled: this.config.enabled,\r\n provider: this.config.provider,\r\n operatorID: this.config.operatorID ?? null,\r\n })\r\n\r\n if (!this.config.enabled) {\r\n return\r\n }\r\n this.provider = this.createProvider()\r\n\r\n await this.provider.initialize(this.wrapCallbacks(callbacks))\r\n\r\n this.log('Initialized', {\r\n active: this.provider.isActive(),\r\n })\r\n }\r\n\r\n destroy(): void {\r\n this.provider.destroy()\r\n }\r\n\r\n isActive(): boolean {\r\n return this.provider.isActive()\r\n }\r\n\r\n getOperatorInformation(): OperatorInformation | null {\r\n const information = this.provider.getOperatorInformation()\r\n \r\n this.log('Operator Information', information)\r\n\r\n return information\r\n }\r\n\r\n notifyLoadingStarted(): void {\r\n this.log('notifyLoadingStarted')\r\n this.provider.notifyLoadingStarted()\r\n }\r\n\r\n notifyLoadingProgress(percentage: number): void {\r\n this.log('notifyLoadingProgress()', { percentage })\r\n this.provider.notifyLoadingProgress(percentage)\r\n }\r\n\r\n notifyLoadingEnded(): void {\r\n this.log('notifyLoadingEnded()')\r\n this.provider.notifyLoadingEnded()\r\n }\r\n\r\n notifyGameReady(): void {\r\n this.log('notifyGameReady()')\r\n this.provider.notifyGameReady()\r\n }\r\n\r\n notifyBalanceUpdate(payload: BalanceUpdatePayload): void {\r\n this.log('notifyBalanceUpdate()', { payload })\r\n this.provider.notifyBalanceUpdate(payload)\r\n }\r\n\r\n notifyStakeUpdate(bet: number): void {\r\n this.log('notifyStakeUpdate()', { bet })\r\n this.provider.notifyStakeUpdate(bet)\r\n }\r\n\r\n notifyRoundStart(): void {\r\n this.log('notifyRoundStart()')\r\n this.provider.notifyRoundStart()\r\n }\r\n\r\n notifyRoundEnd(): void {\r\n this.log('notifyRoundEnd()')\r\n this.provider.notifyRoundEnd()\r\n }\r\n\r\n notifyAudioChanged(enabled: boolean): void {\r\n this.log('notifyAudioChanged()', { enabled })\r\n this.provider.notifyAudioChanged(enabled)\r\n }\r\n\r\n visitLobby(): void {\r\n this.log('visitLobby()')\r\n this.provider.visitLobby()\r\n }\r\n\r\n visitCashier(): void {\r\n this.log('visitCashier()')\r\n this.provider.visitCashier()\r\n }\r\n\r\n\tvisitHistory(historyURL: string): void {\r\n \t\tthis.log('visitHistory()')\r\n this.provider.visitHistory(historyURL)\r\n\t}\r\n\r\n notifyError(payload: NotifyErrorPayload): void {\r\n this.log('notifyError', payload)\r\n this.provider.notifyError(payload)\r\n }\r\n\r\n tryDelegateError(payload: NotifyErrorPayload): boolean {\r\n try {\r\n if (this.shouldDisplayIngameErrors()) return false\r\n this.notifyError(payload)\r\n return true\r\n } catch (error) {\r\n this.log('Error delegation failed; using ingame display', error)\r\n return false\r\n }\r\n }\r\n\r\n\t private mapErrorType(errorType: string): string {\r\n // Map error codes to error types as needed\r\n // This is a placeholder implementation\r\n switch (errorType) {\r\n case 'critical':\r\n return 'CRITICAL_ERROR';\r\n case 'insufficient_funds':\r\n return 'INSUFFICIENT_FUNDS';\r\n default:\r\n return 'CRITICAL_ERROR';\r\n }\r\n }\r\n\r\n private createProvider(): OperatorProvider {\r\n switch (this.config.provider) {\r\n case 'gffe':\r\n return new GFFEOperatorProvider(this.config)\r\n\r\n default:\r\n return new NullOperatorProvider()\r\n }\r\n }\r\n\r\n private wrapCallbacks(callbacks: OperatorCallbacks): OperatorCallbacks {\r\n return {\r\n onStopAutoplay: () => {\r\n this.log('← Stop Autoplay')\r\n callbacks.onStopAutoplay?.()\r\n },\r\n\r\n onUpdateBalance: () => {\r\n this.log('← Update Balance')\r\n callbacks.onUpdateBalance?.()\r\n },\r\n\r\n onToggleAudio: (payload) => {\r\n this.log('← Toggle Audio', payload)\r\n callbacks.onToggleAudio?.(payload)\r\n },\r\n\r\n onShowIngameModal: (payload) => {\r\n this.log('← Show Ingame Modal', payload)\r\n callbacks.onShowIngameModal?.(payload)\r\n },\r\n\r\n onToggleCloak: (payload) => {\r\n this.log('← Toggle Cloak', payload)\r\n callbacks.onToggleCloak?.(payload)\r\n },\r\n\r\n onVisibilityChange: (payload) => {\r\n this.log('← Visibility Change', payload)\r\n callbacks.onVisibilityChange?.(payload)\r\n },\r\n\r\n onGetGameConfig: () => {\r\n const config = callbacks.onGetGameConfig?.()\r\n this.log('← Get Game Config', config)\r\n\r\n return (\r\n config ?? {\r\n supportsPortraitMode: true,\r\n supportsLandscapeMode: true,\r\n }\r\n )\r\n },\r\n\r\n onCustomCommand: (payload) => {\r\n this.log('← Custom Command', payload)\r\n callbacks.onCustomCommand?.(payload)\r\n },\r\n }\r\n }\r\n\r\n shouldDisplayIngameErrors(): boolean {\r\n if (!this.config.enabled) {\r\n return true\r\n }\r\n\r\n return this.getOperatorInformation()?.hideIngameErrors !== true\r\n }\r\n\r\n private log(\r\n action: string,\r\n\r\n payload?: unknown,\r\n ): void {\r\n if (!this.logState) return\r\n\r\n console.groupCollapsed(\r\n `%c CORE Operator %c ${action}`,\r\n [\r\n 'background: #4f46e5',\r\n 'color: #ffffff',\r\n 'font-weight: bold',\r\n 'padding: 3px 8px',\r\n 'border-radius: 3px',\r\n ].join(';'),\r\n 'color: #6b7280; font-weight: normal;',\r\n )\r\n\r\n if (payload !== undefined) {\r\n console.log(payload)\r\n }\r\n\r\n console.groupEnd()\r\n }\r\n}\r\n","import type { ThemeDefinition } from './theme.types'\r\n\r\nexport class Theme implements ThemeDefinition {\r\n readonly theme: string\r\n readonly prefix: string\r\n readonly default?: boolean\r\n readonly cssUrl?: string\r\n readonly images: Readonly<Record<string, string>>\r\n private readonly loadedImages = new Map<string, string>()\r\n\r\n constructor(definition: ThemeDefinition) {\r\n this.theme = definition.theme\r\n this.prefix = definition.prefix\r\n this.default = definition.default\r\n this.cssUrl = definition.cssUrl\r\n this.images = { ...definition.images }\r\n }\r\n\r\n getImage(name: string): string | undefined {\r\n return this.loadedImages.get(name)\r\n }\r\n\r\n async loadImages(timeout: number): Promise<void> {\r\n await Promise.all(\r\n Object.entries(this.images).map(([name, src]) =>\r\n this.loadImage(name, src, timeout),\r\n ),\r\n )\r\n }\r\n\r\n private loadImage(name: string, src: string, timeout: number): Promise<void> {\r\n return new Promise((resolve) => {\r\n const image = new Image()\r\n const finish = (loaded: boolean) => {\r\n clearTimeout(timer)\r\n image.onload = null\r\n image.onerror = null\r\n if (loaded) this.loadedImages.set(name, src)\r\n resolve()\r\n }\r\n const timer = setTimeout(() => finish(false), timeout)\r\n image.onload = () => finish(true)\r\n image.onerror = () => finish(false)\r\n image.src = src\r\n })\r\n }\r\n}\r\n","import { Theme } from './Theme'\r\nimport type { ThemeConfig, ThemeDefinition } from './theme.types'\r\n\r\nexport class ThemeManager {\r\n private currentTheme: Theme | null = null\r\n private stylesheet: HTMLLinkElement | null = null\r\n private initializationVersion = 0\r\n\r\n constructor(private readonly config: ThemeConfig) {}\r\n\r\n async initialize(requestedTheme?: string | null): Promise<string | null> {\r\n const version = ++this.initializationVersion\r\n const definition = this.resolveTheme(requestedTheme)\r\n\r\n if (!definition) {\r\n this.removeCurrentTheme()\r\n return null\r\n }\r\n\r\n try {\r\n await this.applyTheme(definition, version)\r\n } catch (error) {\r\n if (version !== this.initializationVersion) return this.getThemeName()\r\n console.warn(`Failed to load theme \"${definition.theme}\"`, error)\r\n const fallback = this.config.themes.find((item) => item.default)\r\n\r\n if (fallback && fallback !== definition) {\r\n try {\r\n await this.applyTheme(fallback, version)\r\n } catch (fallbackError) {\r\n console.warn('Failed to load the default theme', fallbackError)\r\n if (version === this.initializationVersion) this.removeCurrentTheme()\r\n }\r\n } else {\r\n this.removeCurrentTheme()\r\n }\r\n }\r\n\r\n return this.getThemeName()\r\n }\r\n\r\n getTheme(): Theme | null {\r\n return this.currentTheme\r\n }\r\n\r\n getThemeName(): string | null {\r\n return this.currentTheme?.theme ?? null\r\n }\r\n\r\n private resolveTheme(requestedTheme?: string | null): ThemeDefinition | null {\r\n return (\r\n this.config.themes.find((item) => item.theme === requestedTheme) ??\r\n this.config.themes.find((item) => item.default) ??\r\n null\r\n )\r\n }\r\n\r\n private async applyTheme(definition: ThemeDefinition, version: number): Promise<void> {\r\n const theme = new Theme(definition)\r\n const timeout = this.config.resourceTimeout ?? 10000\r\n const [stylesheet] = await Promise.all([\r\n theme.cssUrl ? this.loadStylesheet(theme.cssUrl, timeout) : Promise.resolve(null),\r\n theme.loadImages(timeout),\r\n ])\r\n\r\n if (version !== this.initializationVersion) {\r\n stylesheet?.remove()\r\n return\r\n }\r\n\r\n this.removeCurrentTheme()\r\n document.body.classList.add(`${theme.prefix}-${theme.theme}`)\r\n if (stylesheet) stylesheet.media = 'all'\r\n this.stylesheet = stylesheet\r\n this.currentTheme = theme\r\n }\r\n\r\n private loadStylesheet(src: string, timeout: number): Promise<HTMLLinkElement> {\r\n return new Promise((resolve, reject) => {\r\n const link = document.createElement('link')\r\n link.rel = 'stylesheet'\r\n link.href = src\r\n // Load the next stylesheet without applying it before the theme is ready.\r\n link.media = 'not all'\r\n\r\n const cleanup = () => {\r\n clearTimeout(timer)\r\n link.onload = null\r\n link.onerror = null\r\n }\r\n const fail = () => {\r\n cleanup()\r\n link.remove()\r\n reject(new Error(`Failed to load theme stylesheet \"${src}\"`))\r\n }\r\n const timer = setTimeout(fail, timeout)\r\n link.onload = () => {\r\n cleanup()\r\n resolve(link)\r\n }\r\n link.onerror = fail\r\n document.head.appendChild(link)\r\n })\r\n }\r\n\r\n private removeCurrentTheme(): void {\r\n if (this.currentTheme) {\r\n document.body.classList.remove(\r\n `${this.currentTheme.prefix}-${this.currentTheme.theme}`,\r\n )\r\n }\r\n this.stylesheet?.remove()\r\n this.stylesheet = null\r\n this.currentTheme = null\r\n }\r\n}\r\n","import type { CoreConfig } from './core.types'\r\n\r\nimport { AssetManager } from './assets/AssetManager'\r\nimport { AudioManager } from './audio/AudioManager'\r\nimport { CoreStore } from './store/CoreStore'\r\nimport { UIManager } from './ui/UIManager'\r\nimport { URLManager } from './url/URLManager'\r\nimport { LanguageManager } from './language/LanguageManager'\r\nimport { ErrorManager } from './errors/ErrorManager'\r\nimport { SocketManager } from './socket/SocketManager'\r\nimport { OperatorBridge } from './operator/OperatorBridge'\r\nimport { ThemeManager } from './theme/ThemeManager'\r\n\r\nexport class Core {\r\n readonly store: CoreStore\r\n readonly assets: AssetManager\r\n readonly audio: AudioManager\r\n readonly ui: UIManager\r\n readonly language: LanguageManager\r\n readonly url: URLManager\r\n readonly errors: ErrorManager\r\n readonly socket: SocketManager\r\n readonly operator: OperatorBridge\r\n readonly theme: ThemeManager\r\n\r\n constructor(private readonly config: CoreConfig) {\r\n this.store = new CoreStore({\r\n appVersion: this.config.app.version,\r\n provider: this.config.app.provider,\r\n defaultLanguage: this.config.language.defaultLanguage,\r\n fallbackLanguage: this.config.language.fallbackLanguage,\r\n logState: this.config.debug?.logState,\r\n })\r\n this.assets = new AssetManager()\r\n this.audio = new AudioManager(this.assets, this.store)\r\n this.ui = new UIManager(this.store, this.config.ui)\r\n this.language = new LanguageManager(this.store, this.config.language)\r\n this.url = new URLManager(this.config.url)\r\n this.socket = new SocketManager(config.socket)\r\n this.operator = new OperatorBridge(\r\n config.operator ?? {\r\n enabled: false,\r\n provider: 'default',\r\n },\r\n config.debug?.logState ?? false,\r\n )\r\n this.errors = new ErrorManager(this.store, this.operator)\r\n this.theme = new ThemeManager(\r\n config.theme ?? {\r\n themes: [],\r\n },\r\n )\r\n }\r\n\r\n async initialize(): Promise<void> {\r\n const minimumLoadingTime = new Promise<void>((resolve) => {\r\n setTimeout(resolve, this.config.app.minimumLoadingTime ?? 0)\r\n })\r\n\r\n try {\r\n // 0. UI\r\n this.ui.initialize()\r\n\r\n // 1. Parse URL parameters\r\n this.url.initialize()\r\n\r\n // 2. Language\r\n await this.language.initialize(this.url.get('lang'))\r\n\r\n // 3. Validate URL parameters\r\n this.url.validate()\r\n\r\n // 4. Theme Generator\r\n const theme = await this.theme.initialize(this.url.get('theme'))\r\n this.store.setTheme(theme)\r\n\r\n // 4. WebSocket connection\r\n\r\n await this.socket.connect(this.url.get('endpoint'))\r\n\r\n // 7. assets\r\n await this.assets.load(this.config.assets)\r\n\r\n // 8. bets\r\n await minimumLoadingTime\r\n\r\n } catch (error) {\r\n this.errors.handle(error)\r\n }\r\n }\r\n\r\n completeInitialization(): void {\r\n this.store.setInitialized(true)\r\n }\r\n}\r\n","import type { InjectionKey } from 'vue'\r\nimport type { Core } from '../Core'\r\n\r\nexport const CORE_KEY: InjectionKey<Core> = Symbol('core')\r\n","import { inject } from 'vue'\r\nimport { CORE_KEY } from './core.context'\r\nimport type { Core } from '../Core'\r\n\r\nexport const useCore = (): Core => {\r\n const core = inject(CORE_KEY)\r\n\r\n if (!core) {\r\n throw new Error('Core is not available. Make sure CORE_KEY is provided.')\r\n }\r\n\r\n return core\r\n}\r\n\r\n ","import { onUnmounted, shallowRef, triggerRef } from 'vue'\r\nimport { useCore } from './useCore'\r\n\r\nexport const useCoreStore = () => {\r\n const core = useCore()\r\n const state = shallowRef(core.store.state)\r\n\r\n const unsubscribe = core.store.subscribe(() => {\r\n triggerRef(state)\r\n })\r\n\r\n onUnmounted(() => {\r\n unsubscribe()\r\n })\r\n\r\n return {\r\n state,\r\n }\r\n}\r\n","<script setup lang=\"ts\">\r\nimport { useCoreStore } from '../useCoreStore'\r\n\r\nconst { state } = useCoreStore()\r\n\r\ndefineProps<{\r\n title: string\r\n message: string\r\n actionLabel?: string\r\n}>()\r\n\r\ndefineEmits<{\r\n action: []\r\n}>()\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"state.error?.displayIngame !== false\"\r\n class=\"core-error\"\r\n >\r\n <div class=\"core-error__content\">\r\n <div class=\"core-error__icon\">\r\n !\r\n </div>\r\n\r\n <h2 class=\"core-error__title\">\r\n {{ title }}\r\n </h2>\r\n\r\n <p class=\"core-error__message\">\r\n {{ message }}\r\n </p>\r\n\r\n <button\r\n v-if=\"actionLabel\"\r\n type=\"button\"\r\n class=\"core-error__action\"\r\n @click=\"$emit('action')\"\r\n >\r\n {{ actionLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.core-error {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 9999;\r\n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n padding: 40px;\r\n\r\n background: rgba(10, 15, 25, 0.78);\r\n backdrop-filter: blur(4px);\r\n}\r\n\r\n.core-error__content {\r\n width: min(560px, 100%);\r\n padding: 42px 48px;\r\n\r\n text-align: center;\r\n\r\n background: rgba(255, 255, 255, 0.96);\r\n border-radius: 20px;\r\n\r\n box-shadow:\r\n 0 24px 80px rgba(0, 0, 0, 0.35),\r\n 0 4px 16px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.core-error__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n width: 64px;\r\n height: 64px;\r\n margin: 0 auto 22px;\r\n\r\n border-radius: 50%;\r\n\r\n background: #b91c1c;\r\n color: #fff;\r\n\r\n font-size: 42px;\r\n font-weight: 700;\r\n line-height: 1;\r\n}\r\n\r\n.core-error__title {\r\n margin: 0 0 14px;\r\n\r\n color: #111827;\r\n\r\n font-size: 30px;\r\n font-weight: 700;\r\n}\r\n\r\n.core-error__message {\r\n margin: 0;\r\n\r\n color: #4b5563;\r\n\r\n font-size: 20px;\r\n line-height: 1.5;\r\n}\r\n\r\n.core-error__action {\r\n min-width: 160px;\r\n min-height: 48px;\r\n margin-top: 26px;\r\n padding: 10px 24px;\r\n border: 0;\r\n border-radius: 4px;\r\n background: #186cf0;\r\n color: #fff;\r\n cursor: pointer;\r\n font: inherit;\r\n font-weight: 700;\r\n text-transform: uppercase;\r\n}\r\n\r\n.core-error__action:focus-visible {\r\n outline: 3px solid #111827;\r\n outline-offset: 3px;\r\n}\r\n</style>\r\n","<script setup lang=\"ts\">\r\nimport { useCoreStore } from '../useCoreStore'\r\n\r\nconst { state } = useCoreStore()\r\n\r\ndefineProps<{\r\n title: string\r\n message: string\r\n actionLabel?: string\r\n}>()\r\n\r\ndefineEmits<{\r\n action: []\r\n}>()\r\n</script>\r\n\r\n<template>\r\n <div\r\n v-if=\"state.error?.displayIngame !== false\"\r\n class=\"core-error\"\r\n >\r\n <div class=\"core-error__content\">\r\n <div class=\"core-error__icon\">\r\n !\r\n </div>\r\n\r\n <h2 class=\"core-error__title\">\r\n {{ title }}\r\n </h2>\r\n\r\n <p class=\"core-error__message\">\r\n {{ message }}\r\n </p>\r\n\r\n <button\r\n v-if=\"actionLabel\"\r\n type=\"button\"\r\n class=\"core-error__action\"\r\n @click=\"$emit('action')\"\r\n >\r\n {{ actionLabel }}\r\n </button>\r\n </div>\r\n </div>\r\n</template>\r\n\r\n<style scoped>\r\n.core-error {\r\n position: fixed;\r\n inset: 0;\r\n z-index: 9999;\r\n\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n padding: 40px;\r\n\r\n background: rgba(10, 15, 25, 0.78);\r\n backdrop-filter: blur(4px);\r\n}\r\n\r\n.core-error__content {\r\n width: min(560px, 100%);\r\n padding: 42px 48px;\r\n\r\n text-align: center;\r\n\r\n background: rgba(255, 255, 255, 0.96);\r\n border-radius: 20px;\r\n\r\n box-shadow:\r\n 0 24px 80px rgba(0, 0, 0, 0.35),\r\n 0 4px 16px rgba(0, 0, 0, 0.2);\r\n}\r\n\r\n.core-error__icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n\r\n width: 64px;\r\n height: 64px;\r\n margin: 0 auto 22px;\r\n\r\n border-radius: 50%;\r\n\r\n background: #b91c1c;\r\n color: #fff;\r\n\r\n font-size: 42px;\r\n font-weight: 700;\r\n line-height: 1;\r\n}\r\n\r\n.core-error__title {\r\n margin: 0 0 14px;\r\n\r\n color: #111827;\r\n\r\n font-size: 30px;\r\n font-weight: 700;\r\n}\r\n\r\n.core-error__message {\r\n margin: 0;\r\n\r\n color: #4b5563;\r\n\r\n font-size: 20px;\r\n line-height: 1.5;\r\n}\r\n\r\n.core-error__action {\r\n min-width: 160px;\r\n min-height: 48px;\r\n margin-top: 26px;\r\n padding: 10px 24px;\r\n border: 0;\r\n border-radius: 4px;\r\n background: #186cf0;\r\n color: #fff;\r\n cursor: pointer;\r\n font: inherit;\r\n font-weight: 700;\r\n text-transform: uppercase;\r\n}\r\n\r\n.core-error__action:focus-visible {\r\n outline: 3px solid #111827;\r\n outline-offset: 3px;\r\n}\r\n</style>\r\n","import type { DefineComponent } from 'vue'\r\n\r\nimport ErrorOverlay from './ErrorOverlay.vue'\r\n\r\ntype ErrorOverlayProps = {\r\n title: string\r\n message: string\r\n actionLabel?: string\r\n}\r\n\r\nconst component = ErrorOverlay as DefineComponent<ErrorOverlayProps>\r\n\r\nexport default component\r\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SocketManager.d.ts","sourceRoot":"","sources":["../../src/socket/SocketManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,WAAW,EACX,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAE7B,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAA;AASvB,qBAAa,aAAa;IAYZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXnC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,KAAK,CAAwC;IACrD,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,sBAAsB,CAA6C;IAC3E,OAAO,CAAC,qBAAqB,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqC;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsC;IAC1E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0C;gBAE7C,MAAM,EAAE,YAAY;IAEjD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+FxC,UAAU,IAAI,IAAI;IAoBlB,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAwClC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;IAuE9D,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB;;;;;;;;;OASG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAU1E,YAAY,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAQ5D,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAenC,OAAO,CAAC,aAAa;IA8HrB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,sBAAsB;IAqB9B,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,GAAG;IAoDX,cAAc,IAAI,IAAI;IAYtB,aAAa,IAAI,IAAI;CAWtB"}
1
+ {"version":3,"file":"SocketManager.d.ts","sourceRoot":"","sources":["../../src/socket/SocketManager.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,WAAW,EACX,KAAK,uBAAuB,EAC5B,KAAK,YAAY,EACjB,KAAK,wBAAwB,EAE7B,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAA;AASvB,qBAAa,aAAa;IAYZ,OAAO,CAAC,QAAQ,CAAC,MAAM;IAXnC,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,KAAK,CAAwC;IACrD,OAAO,CAAC,UAAU,CAAsB;IACxC,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,cAAc,CAA8C;IACpE,OAAO,CAAC,sBAAsB,CAA6C;IAC3E,OAAO,CAAC,qBAAqB,CAAQ;IACrC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqC;IACxE,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAsC;IAC1E,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA0C;gBAE7C,MAAM,EAAE,YAAY;IAEjD,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+FxC,UAAU,IAAI,IAAI;IAoBlB,IAAI,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAwClC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC;IAuE9D,QAAQ,IAAI,WAAW;IAIvB,WAAW,IAAI,OAAO;IAItB;;;;;;;;;OASG;IACH,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,uBAAuB,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;IAU1E,YAAY,CAAC,QAAQ,EAAE,wBAAwB,GAAG,MAAM,IAAI;IAQ5D,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IAenC,OAAO,CAAC,aAAa;IAuIrB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,gBAAgB;IAgBxB,OAAO,CAAC,sBAAsB;IAqB9B,OAAO,CAAC,aAAa;IAmBrB,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,cAAc;IAyCtB,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,mBAAmB;IAS3B,OAAO,CAAC,QAAQ;IAahB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,GAAG;IAoDX,cAAc,IAAI,IAAI;IAYtB,aAAa,IAAI,IAAI;CAWtB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gffe-game-core",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Reusable frontend core library for GFFE games",
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",