@series-inc/rundot-game-sdk 5.1.3 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,33 +1,33 @@
1
- # RUN.game SDK API
2
-
3
- Build connected HTML5 games that integrate deeply with the RUN.game platform. This package provides the client SDK used by hosted games as well as the local mock environment for development.
4
-
5
- ## Highlights
6
-
7
- - Typed APIs for RUN.game platform services (simulation, rooms, analytics, ads, and more)
8
- - Host-aware tooling including lifecycle hooks, safe-area utilities, and asset loading helpers
9
-
10
- ## Quick Start
11
-
12
- ### Installation
13
-
14
- ```bash
15
- npm install @series-inc/rundot-game-sdk@latest
16
- ```
17
-
18
- ### Initialize
19
-
20
- ```typescript
21
- import { default as RundotGameAPI } from '@series-inc/rundot-game-sdk/api'
22
-
23
- // Initialize the API
24
- await RundotGameAPI.initializeAsync()
25
- ```
26
-
27
- ## Documentation
28
-
29
- The complete RUN.game SDK manuals live on [Run.game Docs](https://series-1.gitbook.io/getreel-docs). Start there for setup guides, API references, tutorials, and best practices.
30
-
31
- ## Support & Links
32
-
1
+ # RUN.game SDK API
2
+
3
+ Build connected HTML5 games that integrate deeply with the RUN.game platform. This package provides the client SDK used by hosted games as well as the local mock environment for development.
4
+
5
+ ## Highlights
6
+
7
+ - Typed APIs for RUN.game platform services (simulation, rooms, analytics, ads, and more)
8
+ - Host-aware tooling including lifecycle hooks, safe-area utilities, and asset loading helpers
9
+
10
+ ## Quick Start
11
+
12
+ ### Installation
13
+
14
+ ```bash
15
+ npm install @series-inc/rundot-game-sdk@latest
16
+ ```
17
+
18
+ ### Initialize
19
+
20
+ ```typescript
21
+ import { default as RundotGameAPI } from '@series-inc/rundot-game-sdk/api'
22
+
23
+ // Initialize the API
24
+ await RundotGameAPI.initializeAsync()
25
+ ```
26
+
27
+ ## Documentation
28
+
29
+ The complete RUN.game SDK manuals live on [Run.game Docs](https://series-1.gitbook.io/getreel-docs). Start there for setup guides, API references, tutorials, and best practices.
30
+
31
+ ## Support & Links
32
+
33
33
  - [Join our Discord!](https://discord.gg/NcjhKQHx)
@@ -1,5 +1,5 @@
1
- import { MockAdsApi, MockLifecycleApi, MockAnalyticsApi, getSandboxConfig, createMockStorageApi, MockAvatarApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, SandboxProfileApi, MockDeviceApi, MockEnvironmentApi, MockSystemApi, MockCdnApi, MockTimeApi, MockAiApi, MockHapticsApi, MockFeaturesApi, MockLoggingApi, MockIapApi, MockSocialApi, initializeRoomsApi, MockPreloaderApi, MockSharedAssetsApi, RundotGameRoom, getCloudRunUrl, buildFunctionsBaseUrl } from './chunk-UWRHIZXS.js';
2
- import './chunk-3GKY3LY5.js';
1
+ import { MockAdsApi, MockLifecycleApi, MockAnalyticsApi, getSandboxConfig, createMockStorageApi, MockAvatarApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, SandboxProfileApi, MockDeviceApi, MockEnvironmentApi, MockSystemApi, MockCdnApi, MockTimeApi, MockAiApi, MockHapticsApi, MockFeaturesApi, MockLoggingApi, MockIapApi, MockSocialApi, initializeRoomsApi, MockPreloaderApi, MockSharedAssetsApi, RundotGameRoom, getCloudRunUrl, buildFunctionsBaseUrl } from './chunk-4ROGEXJO.js';
2
+ import './chunk-CJU2J3S6.js';
3
3
 
4
4
  // src/firebase/localSandboxIdentity.ts
5
5
  var DEFAULT_PLAYER_ID = "player1";
@@ -2172,5 +2172,5 @@ var SandboxHost = class {
2172
2172
  };
2173
2173
 
2174
2174
  export { SandboxHost };
2175
- //# sourceMappingURL=SandboxHost-5K4EMDXV.js.map
2176
- //# sourceMappingURL=SandboxHost-5K4EMDXV.js.map
2175
+ //# sourceMappingURL=SandboxHost-OSPEPZ37.js.map
2176
+ //# sourceMappingURL=SandboxHost-OSPEPZ37.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/firebase/localSandboxIdentity.ts","../src/firebase/firebaseClient.ts","../src/storage/FirestoreStorageApi.ts","../src/http/callRemoteFunction.ts","../src/simulation/HttpSimulationApi.ts","../src/rooms/HttpRoomsApi.ts","../src/rooms/FirestoreRoomsApi.ts","../src/rooms/CompositeRemoteRoomsApi.ts","../src/leaderboard/HttpLeaderboardApi.ts","../src/ugc/HttpUgcApi.ts","../src/imageGen/HttpImageGenApi.ts","../src/SandboxHost.ts"],"names":["app"],"mappings":"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","file":"SandboxHost-OSPEPZ37.js","sourcesContent":["/**\r\n * Local sandbox identity helpers.\r\n *\r\n * These are used only for local Firebase Auth emulator mode to allow multiple\r\n * concurrent \"players\" (player1, player2, ...) across different browser profiles.\r\n */\r\n\r\nconst DEFAULT_PLAYER_ID = 'player1'\r\n\r\n/**\r\n * Normalize a requested player id to the supported format.\r\n *\r\n * - Empty/invalid values fall back to \"player1\"\r\n * - Accepts \"playerN\" (N >= 1)\r\n */\r\nexport function normalizeLocalSandboxPlayerId(value: unknown): string {\r\n if (typeof value !== 'string') return DEFAULT_PLAYER_ID\r\n const trimmed = value.trim().toLowerCase()\r\n if (trimmed.length === 0) return DEFAULT_PLAYER_ID\r\n\r\n const match = trimmed.match(/^player(\\d+)$/)\r\n if (!match) return DEFAULT_PLAYER_ID\r\n\r\n const n = Number(match[1])\r\n if (!Number.isFinite(n) || n < 1) return DEFAULT_PLAYER_ID\r\n return `player${n}`\r\n}\r\n\r\n/**\r\n * Build a deterministic email address for a local sandbox player id.\r\n */\r\nexport function buildLocalSandboxEmail(playerId: unknown): string {\r\n const normalized = normalizeLocalSandboxPlayerId(playerId)\r\n return `rundot-game-sandbox+${normalized}@local.test`\r\n}\r\n\r\n\r\n","/**\r\n * Firebase Web SDK wrapper for sandbox mode.\r\n *\r\n * This client provides:\r\n * 1. Firebase initialization with environment-specific config\r\n * 2. Google OAuth authentication (persisted in IndexedDB)\r\n * 3. Firestore helpers for direct database operations\r\n * 4. Emulator connection for local development\r\n *\r\n * Auth flow:\r\n * - User signs in once with Google via popup\r\n * - Firebase Auth persists session in IndexedDB\r\n * - Session survives browser restarts (valid for weeks/months)\r\n * - All API calls use the same auth session\r\n */\r\n\r\nimport { getSandboxConfig, type SandboxConfig } from '../config/sandbox'\r\nimport { buildLocalSandboxEmail, normalizeLocalSandboxPlayerId } from './localSandboxIdentity'\r\n\r\n// Firebase types - we use dynamic imports to avoid bundling Firebase in production\r\ntype FirebaseApp = import('firebase/app').FirebaseApp\r\ntype Auth = import('firebase/auth').Auth\r\ntype User = import('firebase/auth').User\r\ntype UserCredential = import('firebase/auth').UserCredential\r\ntype Firestore = import('firebase/firestore').Firestore\r\n\r\n/**\r\n * Firebase client interface providing auth and Firestore access.\r\n */\r\nexport interface FirebaseClient {\r\n app: FirebaseApp\r\n auth: Auth\r\n firestore: Firestore\r\n config: SandboxConfig\r\n\r\n // Auth helpers\r\n isSignedIn(): boolean\r\n getProfileId(): string | null\r\n signInWithGoogle(): Promise<UserCredential>\r\n /**\r\n * Local-only: sign in as a deterministic test user (player1, player2, ...).\r\n * Uses the Auth emulator and email/password.\r\n */\r\n signInWithLocalPlayer(playerId: string): Promise<UserCredential>\r\n signOut(): Promise<void>\r\n getIdToken(): Promise<string | null>\r\n getIdTokenOrThrow(): Promise<string>\r\n getCurrentUser(): User | null\r\n onAuthStateChanged(callback: (user: User | null) => void): () => void\r\n\r\n // Firestore helpers\r\n doc: typeof import('firebase/firestore').doc\r\n collection: typeof import('firebase/firestore').collection\r\n getDoc: typeof import('firebase/firestore').getDoc\r\n setDoc: typeof import('firebase/firestore').setDoc\r\n updateDoc: typeof import('firebase/firestore').updateDoc\r\n deleteDoc: typeof import('firebase/firestore').deleteDoc\r\n addDoc: typeof import('firebase/firestore').addDoc\r\n query: typeof import('firebase/firestore').query\r\n where: typeof import('firebase/firestore').where\r\n orderBy: typeof import('firebase/firestore').orderBy\r\n limit: typeof import('firebase/firestore').limit\r\n onSnapshot: typeof import('firebase/firestore').onSnapshot\r\n serverTimestamp: typeof import('firebase/firestore').serverTimestamp\r\n deleteField: typeof import('firebase/firestore').deleteField\r\n}\r\n\r\nconst APP_NAME = 'rundot-game-sandbox'\r\nlet firebaseClientPromise: Promise<FirebaseClient> | null = null\r\nlet cachedClient: FirebaseClient | null = null\r\n\r\nconst LOCAL_TEST_PASSWORD = 'rundot-game-dev-password'\r\n\r\n/**\r\n * Get the Firebase client instance.\r\n * Initializes Firebase on first call and caches the instance.\r\n */\r\nexport async function getFirebaseClient(): Promise<FirebaseClient> {\r\n if (cachedClient) {\r\n return cachedClient\r\n }\r\n\r\n if (!firebaseClientPromise) {\r\n firebaseClientPromise = initializeFirebaseClient()\r\n }\r\n\r\n cachedClient = await firebaseClientPromise\r\n return cachedClient\r\n}\r\n\r\n/**\r\n * Check if Firebase has been initialized.\r\n */\r\nexport function isFirebaseInitialized(): boolean {\r\n return cachedClient !== null\r\n}\r\n\r\n/**\r\n * Initialize the Firebase client with dynamic imports.\r\n */\r\nasync function initializeFirebaseClient(): Promise<FirebaseClient> {\r\n const config = getSandboxConfig()\r\n console.log('[RUN.game SDK] Config:', config?.target, config?.gameId)\r\n if (!config || !config.firebaseConfig) {\r\n throw new Error(\r\n '[Run.game SDK] Cannot initialize Firebase: Sandbox config not available. ' +\r\n 'Make sure the Vite plugin is configured correctly.'\r\n )\r\n }\r\n\r\n // Dynamic imports to avoid bundling Firebase in production builds\r\n // The Vite plugin handles optimizeDeps configuration to make this work in dev\r\n console.log('[RUN.game SDK] Importing Firebase modules...')\r\n const [\r\n firebaseApp,\r\n firebaseAuth,\r\n firebaseFirestore,\r\n ] = await Promise.all([\r\n import('firebase/app'),\r\n import('firebase/auth'),\r\n import('firebase/firestore'),\r\n ])\r\n const { initializeApp, getApps, getApp } = firebaseApp\r\n const { getAuth, GoogleAuthProvider, signInWithPopup, signInWithRedirect, getRedirectResult, signInWithEmailAndPassword, createUserWithEmailAndPassword, browserLocalPersistence, setPersistence, connectAuthEmulator } = firebaseAuth\r\n const { getFirestore, connectFirestoreEmulator, doc, collection, getDoc, setDoc, updateDoc, deleteDoc, addDoc, query, where, orderBy, limit, onSnapshot, serverTimestamp, deleteField } = firebaseFirestore\r\n console.log('[RUN.game SDK] Firebase modules imported')\r\n\r\n // Initialize or get existing app\r\n console.log('[RUN.game SDK] Getting/creating Firebase app...')\r\n const existingApps = getApps()\r\n const existingApp = existingApps.find(app => app.name === APP_NAME)\r\n const app = existingApp ?? initializeApp(config.firebaseConfig!, APP_NAME)\r\n console.log('[RUN.game SDK] Firebase app ready:', app.name)\r\n\r\n // Initialize Auth\r\n console.log('[RUN.game SDK] Getting auth...')\r\n const auth = getAuth(app)\r\n console.log('[RUN.game SDK] Auth ready')\r\n\r\n // Connect to Auth emulator for local mode\r\n // This is required because the Functions emulator validates tokens against the Auth emulator\r\n // For non-local targets (dev/staging), we use real Firebase Auth with Google OAuth\r\n const isLocalMode = config.target === 'local'\r\n if (isLocalMode && config.authEmulatorHost) {\r\n console.log('[RUN.game SDK] Connecting to Auth emulator:', config.authEmulatorHost)\r\n try {\r\n connectAuthEmulator(auth, `http://${config.authEmulatorHost}`, { disableWarnings: true })\r\n console.log('[RUN.game SDK] Auth emulator connected')\r\n } catch (e) {\r\n console.log('[RUN.game SDK] Auth emulator connection error (may already be connected):', e)\r\n }\r\n } else {\r\n console.log('[RUN.game SDK] Using real Firebase Auth (target:', config.target, ')')\r\n }\r\n\r\n // Set persistence FIRST (must await before checking auth state)\r\n console.log('[RUN.game SDK] Setting persistence...')\r\n try {\r\n await setPersistence(auth, browserLocalPersistence)\r\n console.log('[RUN.game SDK] Persistence set')\r\n } catch (e) {\r\n console.log('[RUN.game SDK] Persistence error:', e)\r\n }\r\n\r\n // Wait for auth state to be restored from IndexedDB\r\n // This is crucial - Firebase needs time to restore the persisted session\r\n console.log('[RUN.game SDK] Waiting for auth state restoration...')\r\n const initialUser = await new Promise<User | null>((resolve) => {\r\n const unsubscribe = auth.onAuthStateChanged((user) => {\r\n console.log('[RUN.game SDK] onAuthStateChanged fired, user:', user?.uid ?? 'null')\r\n unsubscribe()\r\n resolve(user)\r\n })\r\n // Timeout fallback in case onAuthStateChanged doesn't fire\r\n setTimeout(() => {\r\n unsubscribe()\r\n resolve(null)\r\n }, 3000)\r\n })\r\n console.log('[RUN.game SDK] Auth state restored, user:', initialUser?.uid ?? 'none')\r\n\r\n // Check for redirect result (this captures the result of signInWithRedirect)\r\n // Only needed if no user was restored from persistence\r\n const googleProvider = new GoogleAuthProvider()\r\n if (!initialUser) {\r\n console.log('[RUN.game SDK] No persisted user, checking for redirect result...')\r\n try {\r\n const redirectResult = await getRedirectResult(auth)\r\n if (redirectResult?.user) {\r\n console.log('[RUN.game SDK] Sign-in redirect completed successfully, user:', redirectResult.user.uid)\r\n } else {\r\n console.log('[RUN.game SDK] No redirect result (normal page load or redirect state lost)')\r\n }\r\n } catch (error) {\r\n console.error('[RUN.game SDK] Redirect sign-in error:', error)\r\n }\r\n } else {\r\n console.log('[RUN.game SDK] User already restored from persistence, skipping redirect check')\r\n }\r\n\r\n // Log current auth state\r\n console.log('[RUN.game SDK] Current auth state:', auth.currentUser ? `signed in as ${auth.currentUser.uid}` : 'not signed in')\r\n\r\n // Initialize Firestore\r\n console.log('[RUN.game SDK] Getting Firestore...')\r\n const firestore = getFirestore(app)\r\n\r\n // Connect to Firestore emulator for local development\r\n if (config.target === 'local' && config.firestoreEmulatorHost) {\r\n console.log('[RUN.game SDK] Connecting to Firestore emulator:', config.firestoreEmulatorHost)\r\n try {\r\n const [host, port] = config.firestoreEmulatorHost.split(':')\r\n connectFirestoreEmulator(firestore, host, parseInt(port, 10))\r\n console.log('[RUN.game SDK] Firestore emulator connected')\r\n } catch (e) {\r\n console.log('[RUN.game SDK] Firestore emulator already connected or error:', e)\r\n }\r\n }\r\n\r\n const client: FirebaseClient = {\r\n app,\r\n auth,\r\n firestore,\r\n config,\r\n\r\n // Auth helpers\r\n isSignedIn(): boolean {\r\n return auth.currentUser !== null\r\n },\r\n\r\n getProfileId(): string | null {\r\n return auth.currentUser?.uid ?? null\r\n },\r\n\r\n async signInWithGoogle(): Promise<UserCredential> {\r\n // For local mode (Auth emulator), use email/password instead of Google OAuth\r\n // The Auth emulator doesn't support real Google OAuth\r\n if (isLocalMode) {\r\n // Backwards-compatible default: player1\r\n return this.signInWithLocalPlayer('player1')\r\n }\r\n\r\n // For dev/staging, use real Google OAuth\r\n console.log('[RUN.game SDK] Signing in with Google popup...')\r\n const result = await signInWithPopup(auth, googleProvider)\r\n console.log('[RUN.game SDK] Sign-in successful, user:', result.user.uid)\r\n return result\r\n },\r\n\r\n async signInWithLocalPlayer(playerId: string): Promise<UserCredential> {\r\n if (!isLocalMode) {\r\n throw new Error('[Run.game SDK] signInWithLocalPlayer is only available in local (emulator) mode.')\r\n }\r\n\r\n const normalizedPlayerId = normalizeLocalSandboxPlayerId(playerId)\r\n const email = buildLocalSandboxEmail(normalizedPlayerId)\r\n console.log('[RUN.game SDK] Local mode: signing in as', normalizedPlayerId, '(', email, ')')\r\n\r\n try {\r\n const result = await signInWithEmailAndPassword(auth, email, LOCAL_TEST_PASSWORD)\r\n console.log('[RUN.game SDK] Local sign-in successful, user:', result.user.uid)\r\n return result\r\n } catch (error: unknown) {\r\n const authError = error as { code?: string }\r\n if (authError.code === 'auth/user-not-found' || authError.code === 'auth/invalid-credential') {\r\n console.log('[RUN.game SDK] Local test user not found, creating:', email)\r\n const result = await createUserWithEmailAndPassword(auth, email, LOCAL_TEST_PASSWORD)\r\n console.log('[RUN.game SDK] Local test user created, user:', result.user.uid)\r\n return result\r\n }\r\n throw error\r\n }\r\n },\r\n\r\n async signOut(): Promise<void> {\r\n return auth.signOut()\r\n },\r\n\r\n async getIdToken(): Promise<string | null> {\r\n const user = auth.currentUser\r\n if (!user) {\r\n console.log('[RUN.game SDK] getIdToken: No current user')\r\n return null\r\n }\r\n // Force refresh to ensure we get a fresh token\r\n console.log('[RUN.game SDK] getIdToken: Refreshing token for user:', user.uid)\r\n const token = await user.getIdToken(true)\r\n console.log('[RUN.game SDK] getIdToken: Got token, length:', token?.length)\r\n return token\r\n },\r\n\r\n async getIdTokenOrThrow(): Promise<string> {\r\n const user = auth.currentUser\r\n console.log('[RUN.game SDK] getIdTokenOrThrow: currentUser =', user ? user.uid : null)\r\n if (!user) {\r\n throw new Error(\r\n '[Run.game SDK] Not signed in. Click the Run.game Sandbox toolbar to sign in.'\r\n )\r\n }\r\n // Force refresh to ensure we get a fresh token\r\n console.log('[RUN.game SDK] getIdTokenOrThrow: Forcing token refresh...')\r\n try {\r\n const token = await user.getIdToken(true)\r\n console.log('[RUN.game SDK] getIdTokenOrThrow: Got fresh token, length:', token?.length)\r\n return token\r\n } catch (error) {\r\n console.error('[RUN.game SDK] getIdTokenOrThrow: Token refresh failed:', error)\r\n // If token refresh fails (e.g., emulator restarted), sign out and prompt re-auth\r\n console.log('[RUN.game SDK] getIdTokenOrThrow: Signing out stale session...')\r\n await auth.signOut()\r\n throw new Error(\r\n '[Run.game SDK] Session expired. Please sign in again via the Run.game toolbar.'\r\n )\r\n }\r\n },\r\n\r\n getCurrentUser(): User | null {\r\n return auth.currentUser\r\n },\r\n\r\n onAuthStateChanged(callback: (user: User | null) => void): () => void {\r\n return auth.onAuthStateChanged(callback)\r\n },\r\n\r\n // Firestore helpers\r\n doc,\r\n collection,\r\n getDoc,\r\n setDoc,\r\n updateDoc,\r\n deleteDoc,\r\n addDoc,\r\n query,\r\n where,\r\n orderBy,\r\n limit,\r\n onSnapshot,\r\n serverTimestamp,\r\n deleteField,\r\n }\r\n\r\n console.log('[RUN.game SDK] Firebase client initialization complete!')\r\n return client\r\n}\r\n\r\n/**\r\n * Subscribe to a Firestore document and receive real-time updates.\r\n *\r\n * @param path - Firestore document path (e.g., \"profiles/abc123/h5AppStorage/myAppId\")\r\n * @param onChange - Callback invoked when the document changes\r\n * @returns Unsubscribe function to stop listening\r\n */\r\nexport async function observeFirestoreDocument<T>(\r\n path: string,\r\n onChange: (data: T | null) => void,\r\n): Promise<() => void> {\r\n const client = await getFirebaseClient()\r\n const segments = path.split('/').filter(segment => segment.length > 0)\r\n\r\n if (segments.length === 0) {\r\n throw new Error(`[Run.game SDK] Invalid Firestore path \"${path}\".`)\r\n }\r\n\r\n const ref = client.doc(client.firestore, segments.join('/'))\r\n const unsubscribe = client.onSnapshot(\r\n ref,\r\n (snapshot) => {\r\n onChange(snapshot.exists() ? (snapshot.data() as T) : null)\r\n },\r\n (error) => {\r\n console.error('[RUN.game SDK] Firestore subscription error:', error)\r\n },\r\n )\r\n\r\n return unsubscribe\r\n}\r\n\r\n/**\r\n * Filter condition for Firestore collection queries.\r\n */\r\nexport interface FirestoreFilter {\r\n field: string\r\n op: '<' | '<=' | '==' | '!=' | '>=' | '>' | 'array-contains' | 'in' | 'not-in' | 'array-contains-any'\r\n value: unknown\r\n}\r\n\r\n/**\r\n * Order specification for Firestore collection queries.\r\n */\r\nexport interface FirestoreOrder {\r\n field: string\r\n direction: 'asc' | 'desc'\r\n}\r\n\r\n/**\r\n * Options for observeFirestoreCollection.\r\n */\r\nexport interface FirestoreCollectionOptions {\r\n filters?: FirestoreFilter[]\r\n orderBy?: FirestoreOrder[]\r\n limitCount?: number\r\n}\r\n\r\n/**\r\n * Subscribe to a Firestore collection query and receive real-time updates.\r\n *\r\n * @param collectionPath - Firestore collection path (e.g., \"h5_rooms/roomId/messages\")\r\n * @param options - Query filters and ordering\r\n * @param onChange - Callback invoked when query results change\r\n * @returns Unsubscribe function to stop listening\r\n */\r\nexport async function observeFirestoreCollection<T>(\r\n collectionPath: string,\r\n options: FirestoreCollectionOptions,\r\n onChange: (docs: Array<T & { id: string }>) => void,\r\n): Promise<() => void> {\r\n const client = await getFirebaseClient()\r\n\r\n const collectionRef = client.collection(client.firestore, collectionPath)\r\n\r\n // Build query constraints\r\n const constraints: Array<\r\n ReturnType<typeof client.where> |\r\n ReturnType<typeof client.orderBy> |\r\n ReturnType<typeof client.limit>\r\n > = []\r\n\r\n if (options.filters) {\r\n for (const filter of options.filters) {\r\n constraints.push(client.where(filter.field, filter.op, filter.value))\r\n }\r\n }\r\n\r\n if (options.orderBy) {\r\n for (const order of options.orderBy) {\r\n constraints.push(client.orderBy(order.field, order.direction))\r\n }\r\n }\r\n\r\n if (options.limitCount) {\r\n constraints.push(client.limit(options.limitCount))\r\n }\r\n\r\n const q = client.query(collectionRef, ...constraints)\r\n\r\n const unsubscribe = client.onSnapshot(\r\n q,\r\n (snapshot) => {\r\n const docs = snapshot.docs.map(doc => ({\r\n id: doc.id,\r\n ...doc.data(),\r\n })) as Array<T & { id: string }>\r\n onChange(docs)\r\n },\r\n (error) => {\r\n console.error('[RUN.game SDK] Firestore collection subscription error:', error)\r\n },\r\n )\r\n\r\n return unsubscribe\r\n}\r\n","/**\r\n * Firestore-backed storage API for sandbox mode.\r\n *\r\n * Implements the same storage interface as the mobile app, using direct Firestore writes.\r\n *\r\n * Paths:\r\n * - App storage: profiles/{profileId}/h5AppStorage/{appId}\r\n * - Global storage: profiles/{profileId}/h5GlobalStorage/data\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost.\r\n * Do NOT import from barrel exports (storage/index.ts) - use direct import path instead.\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport { StorageApi } from './StorageApi'\r\nimport { getFirebaseClient, type FirebaseClient } from '../firebase/firebaseClient'\r\n\r\ntype FirestoreStorageType = 'app' | 'global'\r\n\r\n/**\r\n * Firestore-backed implementation of StorageApi.\r\n */\r\nexport class FirestoreStorageApi implements StorageApi {\r\n private readonly type: FirestoreStorageType\r\n private readonly appId?: string\r\n private client: FirebaseClient | null = null\r\n\r\n constructor(type: FirestoreStorageType, appId?: string) {\r\n this.type = type\r\n this.appId = appId\r\n\r\n if (type === 'app' && !appId) {\r\n throw new Error('[RUN.game SDK] App storage requires an appId')\r\n }\r\n }\r\n\r\n private async getClient(): Promise<FirebaseClient> {\r\n if (!this.client) {\r\n this.client = await getFirebaseClient()\r\n }\r\n return this.client\r\n }\r\n\r\n private getProfileId(): string {\r\n if (!this.client) {\r\n throw new Error('[RUN.game SDK] Firebase not initialized. Call getClient() first.')\r\n }\r\n const profileId = this.client.getProfileId()\r\n if (!profileId) {\r\n throw new Error('[RUN.game SDK] Not signed in. Click the RUN.game toolbar to sign in with Google.')\r\n }\r\n return profileId\r\n }\r\n\r\n private async getDocRef() {\r\n const client = await this.getClient()\r\n const profileId = this.getProfileId()\r\n\r\n if (this.type === 'app') {\r\n return client.doc(client.firestore, `profiles/${profileId}/h5AppStorage/${this.appId}`)\r\n } else {\r\n return client.doc(client.firestore, `profiles/${profileId}/h5GlobalStorage/data`)\r\n }\r\n }\r\n\r\n async getItem(key: string): Promise<string | null> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n const snapshot = await client.getDoc(docRef)\r\n\r\n if (!snapshot.exists()) {\r\n return null\r\n }\r\n\r\n const data = snapshot.data()\r\n const value = data?.[key]\r\n\r\n // Return null if key doesn't exist, otherwise return the value as string\r\n if (value === undefined || value === null) {\r\n return null\r\n }\r\n\r\n return typeof value === 'string' ? value : JSON.stringify(value)\r\n }\r\n\r\n async setItem(key: string, value: string): Promise<void> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n\r\n await client.setDoc(\r\n docRef,\r\n {\r\n [key]: value,\r\n lastUpdated: client.serverTimestamp(),\r\n },\r\n { merge: true },\r\n )\r\n }\r\n\r\n async removeItem(key: string): Promise<void> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n\r\n try {\r\n await client.updateDoc(docRef, {\r\n [key]: client.deleteField(),\r\n })\r\n } catch (error) {\r\n // Document might not exist, which is fine for removeItem\r\n const err = error as { code?: string }\r\n if (err.code !== 'not-found') {\r\n throw error\r\n }\r\n }\r\n }\r\n\r\n async clear(): Promise<void> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n\r\n try {\r\n await client.deleteDoc(docRef)\r\n } catch (error) {\r\n // Document might not exist, which is fine for clear\r\n const err = error as { code?: string }\r\n if (err.code !== 'not-found') {\r\n throw error\r\n }\r\n }\r\n }\r\n\r\n async key(index: number): Promise<string | null> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n const snapshot = await client.getDoc(docRef)\r\n\r\n if (!snapshot.exists()) {\r\n return null\r\n }\r\n\r\n const data = snapshot.data() || {}\r\n const keys = Object.keys(data).filter((k) => k !== 'lastUpdated')\r\n\r\n if (index < 0 || index >= keys.length) {\r\n return null\r\n }\r\n\r\n return keys[index]\r\n }\r\n\r\n async length(): Promise<number> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n const snapshot = await client.getDoc(docRef)\r\n\r\n if (!snapshot.exists()) {\r\n return 0\r\n }\r\n\r\n const data = snapshot.data() || {}\r\n // Exclude lastUpdated from count\r\n return Object.keys(data).filter((k) => k !== 'lastUpdated').length\r\n }\r\n\r\n async getAllItems(): Promise<string[]> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n const snapshot = await client.getDoc(docRef)\r\n\r\n if (!snapshot.exists()) {\r\n return []\r\n }\r\n\r\n const data = snapshot.data() || {}\r\n // Return all keys except lastUpdated\r\n return Object.keys(data).filter((k) => k !== 'lastUpdated')\r\n }\r\n\r\n async getAllData(): Promise<Record<string, string>> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n const snapshot = await client.getDoc(docRef)\r\n\r\n if (!snapshot.exists()) {\r\n return {}\r\n }\r\n\r\n const data = snapshot.data() || {}\r\n const result: Record<string, string> = {}\r\n\r\n for (const [key, value] of Object.entries(data)) {\r\n if (key === 'lastUpdated') continue\r\n result[key] = typeof value === 'string' ? value : JSON.stringify(value)\r\n }\r\n\r\n return result\r\n }\r\n\r\n async setMultipleItems(items: { key: string; value: string }[]): Promise<void> {\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n\r\n const updates: Record<string, unknown> = {\r\n lastUpdated: client.serverTimestamp(),\r\n }\r\n\r\n for (const item of items) {\r\n updates[item.key] = item.value\r\n }\r\n\r\n await client.setDoc(docRef, updates, { merge: true })\r\n }\r\n\r\n async removeMultipleItems(keys: string[]): Promise<void> {\r\n // No-op on empty input to match MockStorageApi behavior and avoid invalid Firestore updateDoc({})\r\n // which throws: \"At least one field is required.\"\r\n if (keys.length === 0) {\r\n return\r\n }\r\n\r\n const client = await this.getClient()\r\n const docRef = await this.getDocRef()\r\n\r\n const updates: Record<string, unknown> = {}\r\n for (const key of keys) {\r\n updates[key] = client.deleteField()\r\n }\r\n\r\n // Defensive: if all keys were filtered out for some reason, avoid calling updateDoc with {}\r\n if (Object.keys(updates).length === 0) {\r\n return\r\n }\r\n\r\n try {\r\n await client.updateDoc(docRef, updates)\r\n } catch (error) {\r\n const err = error as { code?: string }\r\n if (err.code !== 'not-found') {\r\n throw error\r\n }\r\n }\r\n }\r\n}\r\n","/**\r\n * HTTP wrapper for calling Cloud Functions.\r\n *\r\n * Gets the ID token from Firebase Auth (user signs in once via Google).\r\n * Token is refreshed automatically by Firebase SDK.\r\n *\r\n * @example\r\n * ```typescript\r\n * const state = await callRemoteFunction<SimulationState>('apiGetSimulationState', {\r\n * appId: 'my-game',\r\n * })\r\n * ```\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost\r\n * and other sandbox-only modules. Do NOT import from barrel exports (http/index.ts).\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\n\r\nimport { getSandboxConfig, buildFunctionsBaseUrl } from '../config/sandbox'\r\nimport { getFirebaseClient } from '../firebase/firebaseClient'\r\n\r\n/**\r\n * Type for a function that invokes a remote Cloud Function.\r\n */\r\nexport type RemoteFunctionInvoker = <TResponse>(\r\n functionName: string,\r\n payload?: unknown,\r\n) => Promise<TResponse>\r\n\r\n/**\r\n * Call a Cloud Function via HTTP POST with Bearer token authentication.\r\n *\r\n * @param functionName - Name of the Cloud Function to call (e.g., 'apiGetSimulationState')\r\n * @param payload - Optional JSON payload to send in the request body\r\n * @returns The JSON response from the function\r\n * @throws Error if not signed in or if the request fails\r\n */\r\nexport async function callRemoteFunction<TResponse>(\r\n functionName: string,\r\n payload?: unknown,\r\n): Promise<TResponse> {\r\n console.log('[RUN.game SDK] callRemoteFunction:', functionName)\r\n const config = getSandboxConfig()\r\n\r\n if (!config) {\r\n throw new Error(\r\n '[Run.game SDK] Sandbox mode is not enabled. ' +\r\n 'Make sure the Vite plugin is configured and you are running in dev mode.'\r\n )\r\n }\r\n\r\n // Get token from Firebase Auth (user must be signed in)\r\n console.log('[RUN.game SDK] callRemoteFunction: Getting Firebase client...')\r\n const client = await getFirebaseClient()\r\n console.log('[RUN.game SDK] callRemoteFunction: Getting ID token...')\r\n const idToken = await client.getIdTokenOrThrow()\r\n console.log('[RUN.game SDK] callRemoteFunction: Got token, making request...')\r\n\r\n const baseUrl = buildFunctionsBaseUrl(config)\r\n const url = `${baseUrl}/${functionName}`\r\n\r\n const response = await fetchWithRetry(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${idToken}`,\r\n },\r\n body: JSON.stringify(payload ?? {}),\r\n }, config.rpcMaxRetries ?? 0, config.rpcRetryDelayMs ?? 1000)\r\n\r\n if (!response.ok) {\r\n const errorMessage = await extractErrorMessage(response, functionName)\r\n throw new Error(errorMessage)\r\n }\r\n\r\n const text = await response.text()\r\n try {\r\n return JSON.parse(text) as TResponse\r\n } catch {\r\n throw new Error(\r\n `[Run.game SDK] Backend call to ${functionName} returned invalid JSON: ${text.substring(0, 100)}`\r\n )\r\n }\r\n}\r\n\r\n/**\r\n * Fetch with retry logic for transient failures.\r\n */\r\nasync function fetchWithRetry(\r\n url: string,\r\n options: RequestInit,\r\n maxRetries: number,\r\n retryDelayMs: number,\r\n): Promise<Response> {\r\n let lastError: Error | null = null\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n const response = await fetch(url, options)\r\n\r\n // Don't retry client errors (4xx), only server errors (5xx)\r\n if (response.ok || (response.status >= 400 && response.status < 500)) {\r\n return response\r\n }\r\n\r\n // Server error - might be transient, retry if we have attempts left\r\n if (attempt < maxRetries) {\r\n await delay(retryDelayMs)\r\n continue\r\n }\r\n\r\n return response\r\n } catch (error) {\r\n lastError = error instanceof Error ? error : new Error(String(error))\r\n\r\n if (attempt < maxRetries) {\r\n await delay(retryDelayMs)\r\n continue\r\n }\r\n\r\n throw lastError\r\n }\r\n }\r\n\r\n throw lastError ?? new Error('[Run.game SDK] Request failed with no error details')\r\n}\r\n\r\n/**\r\n * Extract a meaningful error message from a failed response.\r\n */\r\nasync function extractErrorMessage(response: Response, functionName: string): Promise<string> {\r\n try {\r\n const errorBody = await response.json()\r\n const message = errorBody.error || errorBody.message || response.statusText\r\n return `[Run.game SDK] Backend call to ${functionName} failed (${response.status}): ${message}`\r\n } catch {\r\n return `[Run.game SDK] Backend call to ${functionName} failed (${response.status}): ${response.statusText}`\r\n }\r\n}\r\n\r\n/**\r\n * Simple delay helper.\r\n */\r\nfunction delay(ms: number): Promise<void> {\r\n return new Promise(resolve => setTimeout(resolve, ms))\r\n}\r\n\r\n/**\r\n * Create a remote function invoker with a custom implementation.\r\n * Useful for testing or custom authentication flows.\r\n */\r\nexport function createRemoteFunctionInvoker(\r\n invoke: RemoteFunctionInvoker = callRemoteFunction,\r\n): RemoteFunctionInvoker {\r\n return invoke\r\n}\r\n","/**\r\n * HTTP-backed {@link SimulationApi} implementation for sandbox mode.\r\n *\r\n * Uses HTTP calls to Cloud Functions for all operations.\r\n * Real-time subscriptions use Firestore listeners.\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost.\r\n * Do NOT import from barrel exports (simulation/index.ts) - use direct import path instead.\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport {\r\n CollectRecipeResult,\r\n ExecuteRecipeOptions,\r\n ExecuteRecipeResponse,\r\n ExecuteScopedRecipeResult,\r\n ExecuteScopedRecipeOptions,\r\n GetActiveRunsOptions,\r\n GetAvailableRecipesOptions,\r\n GetAvailableRecipesResult,\r\n GetBatchRecipeRequirements,\r\n Recipe,\r\n SimulationApi,\r\n SimulationAvailableItem,\r\n SimulationAssignment,\r\n SimulationBatchOperation,\r\n SimulationBatchOperationsResult,\r\n SimulationPowerPreview,\r\n SimulationSlotMutationResult,\r\n SimulationSlotValidationResult,\r\n SimulationSlotContainer,\r\n SimulationRunSummary,\r\n SimulationState,\r\n TriggerRecipeChainOptions,\r\n ResetStateOptions,\r\n ResetStateResult,\r\n} from './SimulationApi'\r\nimport { callRemoteFunction, type RemoteFunctionInvoker } from '../http/callRemoteFunction'\r\nimport {\r\n RecipeRequirementResult,\r\n RundotGameSimulationConfig,\r\n SimulationSubscribeOptions,\r\n SimulationSnapshotUpdate,\r\n} from '../rundot-game-api/types'\r\nimport {\r\n observeFirestoreDocument,\r\n observeFirestoreCollection,\r\n} from '../firebase/firebaseClient'\r\n\r\n/**\r\n * Firestore document structure for simulation state.\r\n */\r\ninterface FirestoreSimulationState {\r\n inventory?: Record<string, number | string>\r\n disabledRecipes?: string[]\r\n sharedAssets?: Record<string, unknown>\r\n lastUpdated?: unknown\r\n}\r\n\r\n/**\r\n * Firestore document structure for simulation runs.\r\n */\r\ninterface FirestoreSimulationRun {\r\n id: string\r\n recipeId: string\r\n status: string\r\n startTime: unknown\r\n expiresAt: unknown\r\n entity?: string\r\n inputs?: Record<string, number | string>\r\n outputs?: Record<string, number | string>\r\n profileId: string\r\n appId: string\r\n roomId?: string\r\n}\r\n\r\n/**\r\n * HTTP-based implementation of SimulationApi for sandbox mode.\r\n */\r\nexport class HttpSimulationApi implements SimulationApi {\r\n private readonly appId: string\r\n private _simulationConfig: RundotGameSimulationConfig | null = null\r\n private readonly callRemote: RemoteFunctionInvoker\r\n private readonly getProfileId: () => string\r\n private readonly activeSubscriptions: Set<() => void> = new Set()\r\n\r\n constructor(\r\n appId: string,\r\n options: {\r\n callRemote?: RemoteFunctionInvoker\r\n getProfileId: () => string\r\n },\r\n ) {\r\n this.appId = appId\r\n this.callRemote = options.callRemote ?? callRemoteFunction\r\n this.getProfileId = options.getProfileId\r\n }\r\n\r\n isEnabled(): boolean {\r\n return true\r\n }\r\n\r\n // ===== SUBSCRIPTION (FIRESTORE) =====\r\n\r\n async subscribeAsync(\r\n options: SimulationSubscribeOptions,\r\n ): Promise<() => void> {\r\n this.ensureValidSubscribeOptions(options)\r\n\r\n const roomId = options.roomId\r\n const unsubscribers: Array<() => void> = []\r\n\r\n let lastInventorySignature: string | null = null\r\n let lastRunsSignature: string | null = null\r\n let latestInventory: Record<string, number | string> = {}\r\n let latestRuns: SimulationRunSummary[] = []\r\n\r\n const requestedEntityIds = Array.isArray(options.entities)\r\n ? options.entities.filter((e): e is string => typeof e === 'string' && e.length > 0)\r\n : []\r\n\r\n const requestedTags = Array.isArray(options.tags)\r\n ? options.tags.filter((t): t is string => typeof t === 'string' && t.length > 0)\r\n : []\r\n\r\n const wantsInventory = requestedEntityIds.length > 0 || requestedTags.length > 0\r\n const wantsActiveRuns = Boolean(options.activeRuns)\r\n\r\n const cleanupPartialSubscriptions = (): void => {\r\n for (const unsub of unsubscribers) {\r\n try {\r\n unsub()\r\n } catch (e) {\r\n console.error('[RUN.game SDK] Error during simulation subscription cleanup:', e)\r\n }\r\n }\r\n }\r\n\r\n const sendUpdate = (): void => {\r\n const snapshot: SimulationSnapshotUpdate = {\r\n type: 'snapshot',\r\n timestamp: Date.now(),\r\n }\r\n if (wantsInventory) {\r\n snapshot.entities = Object.entries(latestInventory).map(([entityId, quantity]) => ({\r\n entityId,\r\n quantity,\r\n }))\r\n }\r\n if (wantsActiveRuns) {\r\n snapshot.activeRuns = latestRuns\r\n }\r\n options.onUpdate(snapshot)\r\n }\r\n\r\n try {\r\n let allowedEntityIds: Set<string> | null = null\r\n if (wantsInventory) {\r\n allowedEntityIds = new Set<string>()\r\n for (const id of requestedEntityIds) {\r\n allowedEntityIds.add(id)\r\n }\r\n\r\n if (requestedTags.length > 0) {\r\n const config = await this.getConfigAsync(roomId)\r\n const requestedTagSet = new Set(requestedTags)\r\n for (const [entityId, entityDef] of Object.entries(config.entities || {})) {\r\n const tags = entityDef?.tags || []\r\n if (Array.isArray(tags) && tags.some((t) => requestedTagSet.has(t))) {\r\n allowedEntityIds.add(entityId)\r\n }\r\n }\r\n }\r\n\r\n // Subscribe to state document (inventory) only when inventory is requested.\r\n const statePath = roomId\r\n ? `h5_rooms/${roomId}/h5_simulation/${this.appId}`\r\n : `profiles/${this.getProfileId()}/h5_simulation/${this.appId}`\r\n\r\n const unsubscribeState = await observeFirestoreDocument<FirestoreSimulationState>(\r\n statePath,\r\n (doc) => {\r\n const inventory = doc?.inventory ?? {}\r\n const filteredInventory: Record<string, number | string> = {}\r\n\r\n for (const [entityId, quantity] of Object.entries(inventory)) {\r\n if (!allowedEntityIds || allowedEntityIds.has(entityId)) {\r\n filteredInventory[entityId] = quantity\r\n }\r\n }\r\n\r\n const signature = JSON.stringify(filteredInventory)\r\n if (signature !== lastInventorySignature) {\r\n lastInventorySignature = signature\r\n latestInventory = filteredInventory\r\n sendUpdate()\r\n }\r\n },\r\n )\r\n unsubscribers.push(unsubscribeState)\r\n }\r\n\r\n // Subscribe to active runs if requested\r\n if (wantsActiveRuns) {\r\n const filters = roomId\r\n ? [\r\n { field: 'roomId', op: '==' as const, value: roomId },\r\n { field: 'appId', op: '==' as const, value: this.appId },\r\n { field: 'status', op: 'in' as const, value: ['running', 'awaiting_collection'] },\r\n ]\r\n : [\r\n { field: 'profileId', op: '==' as const, value: this.getProfileId() },\r\n { field: 'appId', op: '==' as const, value: this.appId },\r\n { field: 'status', op: 'in' as const, value: ['running', 'awaiting_collection'] },\r\n ]\r\n\r\n const unsubscribeRuns = await observeFirestoreCollection<FirestoreSimulationRun>(\r\n 'h5_simulation_runs',\r\n {\r\n filters,\r\n orderBy: [{ field: 'expiresAt', direction: 'desc' }],\r\n },\r\n (docs) => {\r\n const runs: SimulationRunSummary[] = docs.map((doc) => ({\r\n id: doc.id,\r\n recipeId: doc.recipeId,\r\n status: doc.status as 'running' | 'awaiting_collection',\r\n startTime: normalizeTimestamp(doc.startTime),\r\n expiresAt: normalizeTimestamp(doc.expiresAt),\r\n entity: doc.entity,\r\n inputs: doc.inputs,\r\n outputs: doc.outputs,\r\n }))\r\n\r\n const signature = JSON.stringify(runs)\r\n if (signature !== lastRunsSignature) {\r\n lastRunsSignature = signature\r\n latestRuns = runs\r\n sendUpdate()\r\n }\r\n },\r\n )\r\n unsubscribers.push(unsubscribeRuns)\r\n }\r\n } catch (error) {\r\n cleanupPartialSubscriptions()\r\n throw error\r\n }\r\n\r\n const unsubscribe = (): void => {\r\n for (const unsub of unsubscribers) {\r\n try {\r\n unsub()\r\n } catch (e) {\r\n console.error('[RUN.game SDK] Error during simulation subscription cleanup:', e)\r\n }\r\n }\r\n this.activeSubscriptions.delete(unsubscribe)\r\n }\r\n\r\n this.activeSubscriptions.add(unsubscribe)\r\n return unsubscribe\r\n }\r\n\r\n // ===== STATE & CONFIG (HTTP) =====\r\n\r\n async getStateAsync(roomId?: string): Promise<SimulationState> {\r\n return this.callRemote<SimulationState>('apiGetSimulationState', {\r\n appId: this.appId,\r\n roomId,\r\n })\r\n }\r\n\r\n async getConfigAsync(roomId?: string): Promise<RundotGameSimulationConfig> {\r\n if (this._simulationConfig) {\r\n return this._simulationConfig\r\n }\r\n\r\n const config = await this.callRemote<RundotGameSimulationConfig>('apiGetSimulationConfig', {\r\n appId: this.appId,\r\n roomId,\r\n })\r\n\r\n if (config) {\r\n this._simulationConfig = config\r\n return config\r\n }\r\n\r\n throw new Error('No simulation configuration available')\r\n }\r\n\r\n // ===== RECIPE EXECUTION (HTTP) =====\r\n\r\n executeRecipeAsync(\r\n recipeId: string,\r\n inputs?: Record<string, unknown>,\r\n options?: ExecuteRecipeOptions,\r\n ): Promise<ExecuteRecipeResponse> {\r\n return this.callRemote<ExecuteRecipeResponse>('apiExecuteSimulationRecipe', {\r\n appId: this.appId,\r\n recipeId,\r\n inputs,\r\n roomId: options?.roomId,\r\n batchAmount: options?.batchAmount,\r\n allowPartialBatch: options?.allowPartialBatch,\r\n entity: options?.entity,\r\n nonce: options?.nonce,\r\n })\r\n }\r\n\r\n collectRecipeAsync(runId: string): Promise<CollectRecipeResult> {\r\n return this.callRemote<CollectRecipeResult>('apiCollectRecipeRewards', {\r\n appId: this.appId,\r\n runId,\r\n })\r\n }\r\n\r\n\r\n resetStateAsync(options?: ResetStateOptions): Promise<ResetStateResult> {\r\n return this.callRemote<ResetStateResult>('apiResetSimulationAndInventoryState', {\r\n appId: this.appId,\r\n initializeRecipe: options?.initializeRecipe,\r\n })\r\n }\r\n\r\n getActiveRunsAsync(options?: GetActiveRunsOptions): Promise<SimulationRunSummary[]> {\r\n return this.callRemote<SimulationRunSummary[]>('apiGetSimulationActiveRuns', {\r\n appId: this.appId,\r\n roomId: options?.roomId,\r\n })\r\n }\r\n\r\n executeScopedRecipeAsync(\r\n recipeId: string,\r\n entity: string,\r\n inputs?: Record<string, unknown>,\r\n options?: ExecuteScopedRecipeOptions,\r\n ): Promise<ExecuteScopedRecipeResult> {\r\n return this.callRemote<ExecuteScopedRecipeResult>('apiExecuteScopedRecipe', {\r\n appId: this.appId,\r\n recipeId,\r\n entity,\r\n inputs,\r\n roomId: options?.roomId ?? null,\r\n options,\r\n })\r\n }\r\n\r\n getAvailableRecipesAsync(options?: GetAvailableRecipesOptions): Promise<GetAvailableRecipesResult> {\r\n return this.callRemote<GetAvailableRecipesResult>('apiGetAvailableRecipes', {\r\n appId: this.appId,\r\n roomId: options?.roomId || null,\r\n includeActorRecipes: options?.includeActorRecipes || false,\r\n })\r\n }\r\n\r\n getRecipeRequirementsAsync(recipe: Recipe): Promise<RecipeRequirementResult> {\r\n return this.callRemote<RecipeRequirementResult>('apiGetRecipeRequirements', {\r\n appId: this.appId,\r\n recipeId: recipe.recipeId,\r\n nonce: recipe.nonce,\r\n entity: recipe.entity,\r\n batchAmount: recipe.batchAmount,\r\n })\r\n }\r\n\r\n getBatchRecipeRequirementsAsync(recipes: Recipe[]): Promise<GetBatchRecipeRequirements> {\r\n return this.callRemote<GetBatchRecipeRequirements>('apiGetBatchRecipeRequirements', {\r\n appId: this.appId,\r\n recipes,\r\n })\r\n }\r\n\r\n triggerRecipeChainAsync(\r\n recipeId: string,\r\n options?: TriggerRecipeChainOptions,\r\n ): Promise<ExecuteRecipeResponse> {\r\n return this.callRemote<ExecuteRecipeResponse>('apiTriggerRecipeChain', {\r\n appId: this.appId,\r\n triggerRecipeId: recipeId,\r\n context: options?.context,\r\n roomId: options?.roomId,\r\n })\r\n }\r\n\r\n // ===== FIELD RESOLUTION & METADATA (HTTP) =====\r\n\r\n async resolveFieldValueAsync(\r\n entityId: string,\r\n fieldPath: string,\r\n entity?: string,\r\n ): Promise<unknown> {\r\n const response = await this.callRemote<{ value: unknown }>('apiResolveFieldValue', {\r\n appId: this.appId,\r\n entityId,\r\n fieldPath,\r\n entity,\r\n })\r\n return response.value\r\n }\r\n\r\n getEntityMetadataAsync(entityId: string): Promise<Record<string, unknown>> {\r\n return this.callRemote<Record<string, unknown>>('apiGetEntityMetadata', {\r\n appId: this.appId,\r\n entityId,\r\n })\r\n }\r\n\r\n // ===== SLOT MANAGEMENT (HTTP) =====\r\n\r\n async getSlotContainersAsync(): Promise<SimulationSlotContainer[]> {\r\n const response = await this.callRemote<{ containers?: SimulationSlotContainer[] }>(\r\n 'apiGetSlotContainers',\r\n { appId: this.appId },\r\n )\r\n return response.containers || []\r\n }\r\n\r\n async getSlotAssignmentsAsync(containerId: string): Promise<SimulationAssignment[]> {\r\n const response = await this.callRemote<\r\n SimulationAssignment[] | { assignments?: SimulationAssignment[] }\r\n >('apiGetSlotAssignments', {\r\n appId: this.appId,\r\n containerId,\r\n })\r\n return Array.isArray(response) ? response : response.assignments || []\r\n }\r\n\r\n assignItemToSlotAsync(\r\n containerId: string,\r\n slotId: string,\r\n itemId: string,\r\n ): Promise<SimulationSlotMutationResult> {\r\n return this.callRemote<SimulationSlotMutationResult>('apiAssignItemToSlot', {\r\n appId: this.appId,\r\n containerId,\r\n slotId,\r\n itemId,\r\n })\r\n }\r\n\r\n removeItemFromSlotAsync(containerId: string, slotId: string): Promise<SimulationSlotMutationResult> {\r\n return this.callRemote<SimulationSlotMutationResult>('apiRemoveItemFromSlot', {\r\n appId: this.appId,\r\n containerId,\r\n slotId,\r\n })\r\n }\r\n\r\n async getAvailableItemsAsync(containerId: string, slotId: string): Promise<SimulationAvailableItem[]> {\r\n const response = await this.callRemote<{ availableItems?: SimulationAvailableItem[] }>(\r\n 'apiGetAvailableItemsForSlot',\r\n {\r\n appId: this.appId,\r\n containerId,\r\n slotId,\r\n },\r\n )\r\n return response.availableItems || []\r\n }\r\n\r\n calculatePowerPreviewAsync(\r\n containerId: string,\r\n slotId: string,\r\n candidateItemId: string,\r\n ): Promise<SimulationPowerPreview> {\r\n return this.callRemote<SimulationPowerPreview>('apiCalculatePowerPreview', {\r\n appId: this.appId,\r\n containerId,\r\n slotId,\r\n candidateItemId,\r\n })\r\n }\r\n\r\n validateSlotAssignmentAsync(\r\n containerId: string,\r\n slotId: string,\r\n itemId: string,\r\n ): Promise<SimulationSlotValidationResult> {\r\n return this.callRemote<SimulationSlotValidationResult>('apiValidateSlotAssignment', {\r\n appId: this.appId,\r\n containerId,\r\n slotId,\r\n itemId,\r\n })\r\n }\r\n\r\n executeBatchOperationsAsync(\r\n operations: Array<SimulationBatchOperation>,\r\n validateOnly?: boolean,\r\n ): Promise<SimulationBatchOperationsResult> {\r\n return this.callRemote<SimulationBatchOperationsResult>('apiBatchSlotOperations', {\r\n appId: this.appId,\r\n operations,\r\n validateOnly,\r\n })\r\n }\r\n\r\n // ===== HELPERS =====\r\n\r\n private ensureValidSubscribeOptions(\r\n options: unknown,\r\n ): asserts options is SimulationSubscribeOptions {\r\n if (typeof options !== 'object' || options === null) {\r\n throw new Error('Simulation subscribe requires an options object')\r\n }\r\n\r\n const opts = options as Record<string, unknown>\r\n\r\n if (typeof opts.onUpdate !== 'function') {\r\n throw new Error('Simulation subscribe requires an onUpdate callback')\r\n }\r\n\r\n const hasFilter =\r\n (Array.isArray(opts.entities) && opts.entities.length > 0) ||\r\n (Array.isArray(opts.tags) && opts.tags.length > 0) ||\r\n Boolean(opts.activeRuns)\r\n\r\n if (!hasFilter) {\r\n throw new Error(\r\n 'Simulation subscribe requires at least one filter (entities, tags, activeRuns)',\r\n )\r\n }\r\n }\r\n\r\n destroy(): void {\r\n for (const unsubscribe of this.activeSubscriptions) {\r\n unsubscribe()\r\n }\r\n this.activeSubscriptions.clear()\r\n }\r\n}\r\n\r\n/**\r\n * Normalize Firestore Timestamp or epoch milliseconds to Unix timestamp in milliseconds.\r\n */\r\nfunction normalizeTimestamp(value: unknown): number {\r\n if (value === null || value === undefined) {\r\n return 0\r\n }\r\n\r\n if (\r\n typeof value === 'object' &&\r\n 'toMillis' in value &&\r\n typeof (value as { toMillis: unknown }).toMillis === 'function'\r\n ) {\r\n return (value as { toMillis: () => number }).toMillis()\r\n }\r\n\r\n if (typeof value === 'object' && '_seconds' in value) {\r\n const ts = value as { _seconds: number; _nanoseconds?: number }\r\n return ts._seconds * 1000 + Math.floor((ts._nanoseconds ?? 0) / 1_000_000)\r\n }\r\n\r\n if (typeof value === 'number') {\r\n return value\r\n }\r\n\r\n return 0\r\n}\r\n","/**\r\n * HTTP-backed rooms API for lifecycle operations.\r\n *\r\n * Handles room creation, joining, leaving, starting, and kicking via Cloud Functions.\r\n * Room data, messages, and subscriptions are handled by FirestoreRoomsApi.\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase (via callRemoteFunction) and should\r\n * ONLY be imported by SandboxHost. Do NOT import from barrel exports (rooms/index.ts).\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport {\r\n CreateRoomOptions,\r\n JoinOrCreateRoomOptions,\r\n JoinOrCreateResult,\r\n ListRoomsOptions,\r\n StartRoomGameOptions,\r\n} from './RoomsApi'\r\nimport {\r\n RundotGameRoom,\r\n RundotGameRoomPayload,\r\n RoomEnvelopeResponse,\r\n RoomsEnvelopeResponse,\r\n JoinOrCreateRoomEnvelopeResponse,\r\n} from './RundotGameRoom'\r\nimport { callRemoteFunction, type RemoteFunctionInvoker } from '../http/callRemoteFunction'\r\n\r\n/**\r\n * HTTP-based rooms API for lifecycle operations.\r\n */\r\nexport class HttpRoomsApi {\r\n private readonly appId: string\r\n private readonly callRemote: RemoteFunctionInvoker\r\n private readonly getProfileId: () => string\r\n\r\n constructor(\r\n appId: string,\r\n options: {\r\n callRemote?: RemoteFunctionInvoker\r\n getProfileId: () => string\r\n },\r\n ) {\r\n this.appId = appId\r\n this.callRemote = options.callRemote ?? callRemoteFunction\r\n this.getProfileId = options.getProfileId\r\n }\r\n\r\n async createRoomAsync(options: CreateRoomOptions): Promise<RundotGameRoom> {\r\n const response = await this.callRemote<RoomEnvelopeResponse>('apiCreateH5Room', {\r\n appId: this.appId,\r\n options: {\r\n maxPlayers: options.maxPlayers ?? 4,\r\n gameType: options.gameType,\r\n isPrivate: options.isPrivate ?? false,\r\n roomCode: options.roomCode,\r\n name: options.name,\r\n description: options.description,\r\n customMetadata: options.customMetadata,\r\n data: options.data,\r\n },\r\n })\r\n\r\n return new RundotGameRoom(response.room)\r\n }\r\n\r\n async joinOrCreateRoomAsync(options: JoinOrCreateRoomOptions): Promise<JoinOrCreateResult> {\r\n const response = await this.callRemote<JoinOrCreateRoomEnvelopeResponse>('apiJoinOrCreateH5Room', {\r\n appId: this.appId,\r\n options: {\r\n matchCriteria: options.matchCriteria,\r\n createOptions: {\r\n maxPlayers: options.createOptions.maxPlayers ?? 4,\r\n gameType: options.createOptions.gameType,\r\n isPrivate: options.createOptions.isPrivate ?? false,\r\n name: options.createOptions.name,\r\n description: options.createOptions.description,\r\n customMetadata: options.createOptions.customMetadata,\r\n data: options.createOptions.data,\r\n },\r\n },\r\n })\r\n\r\n return {\r\n action: response.action,\r\n room: new RundotGameRoom(response.room),\r\n playersJoined: response.playersJoined,\r\n }\r\n }\r\n\r\n async joinRoomByCodeAsync(roomCode: string): Promise<RundotGameRoom> {\r\n const response = await this.callRemote<RoomEnvelopeResponse>('apiJoinH5RoomByCode', {\r\n appId: this.appId,\r\n roomCode,\r\n })\r\n\r\n return new RundotGameRoom(response.room)\r\n }\r\n\r\n async getUserRoomsAsync(options?: ListRoomsOptions): Promise<RundotGameRoom[]> {\r\n const response = await this.callRemote<RoomsEnvelopeResponse>('apiGetUserH5Rooms', {\r\n appId: this.appId,\r\n includeArchived: options?.includeArchived ?? false,\r\n })\r\n\r\n return response.rooms.map((roomPayload) => new RundotGameRoom(roomPayload))\r\n }\r\n\r\n async leaveRoomAsync(room: RundotGameRoom): Promise<void> {\r\n await this.callRemote<void>('apiLeaveH5Room', {\r\n appId: this.appId,\r\n roomId: room.id,\r\n })\r\n }\r\n\r\n async kickPlayerAsync(\r\n room: RundotGameRoom,\r\n targetProfileId: string,\r\n options?: { reason?: string },\r\n ): Promise<void> {\r\n await this.callRemote<void>('apiKickH5RoomPlayer', {\r\n appId: this.appId,\r\n roomId: room.id,\r\n targetProfileId,\r\n reason: options?.reason,\r\n })\r\n }\r\n\r\n async startRoomGameAsync(room: RundotGameRoom, options?: StartRoomGameOptions): Promise<void> {\r\n // Backend contract: req.body must include { roomId, options: { gameConfig, turnOrder } }\r\n await this.callRemote<RoomEnvelopeResponse>('apiStartH5Game', {\r\n roomId: room.id,\r\n options: {\r\n gameConfig: options?.gameConfig ?? {}, // Default to {} like Production\r\n turnOrder: options?.turnOrder ?? null,\r\n },\r\n })\r\n }\r\n}\r\n","/**\r\n * Firestore-backed rooms API for data, messages, and subscriptions.\r\n *\r\n * Handles direct Firestore operations for room data (like mobile app).\r\n * Room lifecycle (create, join, leave, start, kick) is handled by HttpRoomsApi.\r\n *\r\n * Paths:\r\n * - Room document: h5_rooms/{roomId}\r\n * - Messages: h5_rooms/{roomId}/messages\r\n * - Proposed moves: h5_rooms/{roomId}/proposed_moves\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost.\r\n * Do NOT import from barrel exports (rooms/index.ts) - use direct import path instead.\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport {\r\n RoomSubscriptionOptions,\r\n RoomDataUpdate,\r\n RoomMessageEvent,\r\n ProposedMoveEvent,\r\n UpdateRoomDataOptions,\r\n RoomMessageRequest,\r\n ProposeMoveRequest,\r\n ProposeMoveResult,\r\n ValidateMoveVerdict,\r\n ValidateMoveResult,\r\n} from './RoomsApi'\r\nimport { RundotGameRoom, RundotGameRoomPayload } from './RundotGameRoom'\r\nimport { getFirebaseClient, type FirebaseClient } from '../firebase/firebaseClient'\r\n\r\n// Firestore types for snapshot callbacks\r\ntype DocumentSnapshot = import('firebase/firestore').DocumentSnapshot\r\ntype QuerySnapshot = import('firebase/firestore').QuerySnapshot\r\ntype DocumentChange = import('firebase/firestore').DocumentChange\r\ntype FirestoreError = import('firebase/firestore').FirestoreError\r\n\r\n/**\r\n * Firestore-backed rooms API for data operations.\r\n */\r\nexport class FirestoreRoomsApi {\r\n private client: FirebaseClient | null = null\r\n private readonly activeSubscriptions: Set<() => void> = new Set()\r\n\r\n private async getClient(): Promise<FirebaseClient> {\r\n if (!this.client) {\r\n this.client = await getFirebaseClient()\r\n }\r\n return this.client\r\n }\r\n\r\n private getProfileId(): string {\r\n if (!this.client) {\r\n throw new Error('[Run.game SDK] Firebase not initialized. Call getClient() first.')\r\n }\r\n const profileId = this.client.getProfileId()\r\n if (!profileId) {\r\n throw new Error('[Run.game SDK] Not signed in. Click the RUN.game toolbar to sign in with Google.')\r\n }\r\n return profileId\r\n }\r\n\r\n // ===== ROOM DATA OPERATIONS =====\r\n\r\n async getRoomDataAsync(room: RundotGameRoom): Promise<Record<string, unknown>> {\r\n const client = await this.getClient()\r\n const roomRef = client.doc(client.firestore, `h5_rooms/${room.id}`)\r\n const snapshot = await client.getDoc(roomRef)\r\n\r\n if (!snapshot.exists()) {\r\n throw new Error(`Room ${room.id} not found`)\r\n }\r\n\r\n const roomData = snapshot.data()\r\n return (roomData?.data as Record<string, unknown>) || {}\r\n }\r\n\r\n async updateRoomDataAsync(\r\n room: RundotGameRoom,\r\n updates: Record<string, unknown>,\r\n options?: UpdateRoomDataOptions,\r\n ): Promise<void> {\r\n const client = await this.getClient()\r\n const roomRef = client.doc(client.firestore, `h5_rooms/${room.id}`)\r\n\r\n const merge = options?.merge !== false\r\n\r\n // Firestore semantics:\r\n // - Setting `data: updates` replaces the entire `data` map.\r\n // - Updating `data.<key>` fields merges individual keys into the `data` map.\r\n //\r\n // We support both:\r\n // - merge=true (default): merge updates into existing `data`\r\n // - merge=false: replace `data` entirely with `updates`\r\n if (merge) {\r\n const updateData: Record<string, unknown> = {\r\n updatedAt: client.serverTimestamp(),\r\n }\r\n\r\n for (const [key, value] of Object.entries(updates)) {\r\n // NOTE: Firestore interprets '.' as a path separator.\r\n // Callers should avoid keys with '.' unless they intend nested updates.\r\n updateData[`data.${key}`] = value\r\n }\r\n\r\n await client.updateDoc(roomRef, updateData)\r\n return\r\n }\r\n\r\n await client.updateDoc(roomRef, {\r\n data: updates,\r\n updatedAt: client.serverTimestamp(),\r\n })\r\n }\r\n\r\n // ===== MESSAGE OPERATIONS =====\r\n\r\n async sendRoomMessageAsync(room: RundotGameRoom, request: RoomMessageRequest): Promise<string> {\r\n const client = await this.getClient()\r\n const messagesRef = client.collection(client.firestore, `h5_rooms/${room.id}/messages`)\r\n\r\n const messageDoc = await client.addDoc(messagesRef, {\r\n roomId: room.id,\r\n senderId: this.getProfileId(),\r\n content: request.message.content || '',\r\n type: request.message.type || 'chat',\r\n metadata: request.metadata || {},\r\n timestamp: client.serverTimestamp(),\r\n })\r\n\r\n return messageDoc.id\r\n }\r\n\r\n // ===== PROPOSED MOVES =====\r\n\r\n async proposeMoveAsync(room: RundotGameRoom, request: ProposeMoveRequest): Promise<ProposeMoveResult> {\r\n const client = await this.getClient()\r\n const movesRef = client.collection(client.firestore, `h5_rooms/${room.id}/proposed_moves`)\r\n\r\n const moveDoc = await client.addDoc(movesRef, {\r\n proposerProfileId: this.getProfileId(),\r\n roomId: room.id,\r\n gameSpecificState: request.gameSpecificState,\r\n moveType: request.moveType,\r\n clientContext: request.clientContext || {},\r\n clientProposalId: request.clientProposalId,\r\n timestamp: client.serverTimestamp(),\r\n serverGenericValidationStatus: 'pending',\r\n })\r\n\r\n return { proposedMoveId: moveDoc.id }\r\n }\r\n\r\n async validateMoveAsync(\r\n room: RundotGameRoom,\r\n moveId: string,\r\n verdict: ValidateMoveVerdict,\r\n ): Promise<ValidateMoveResult> {\r\n const client = await this.getClient()\r\n const moveRef = client.doc(client.firestore, `h5_rooms/${room.id}/proposed_moves/${moveId}`)\r\n\r\n await client.updateDoc(moveRef, {\r\n serverGenericValidationStatus: verdict.isValid ? 'valid' : 'invalid',\r\n serverGenericValidationReason: verdict.reason || null,\r\n validatorId: verdict.validatorId || this.getProfileId(),\r\n updatedAt: client.serverTimestamp(),\r\n })\r\n\r\n return {\r\n success: true,\r\n moveId,\r\n isValid: verdict.isValid,\r\n reason: verdict.reason,\r\n }\r\n }\r\n\r\n // ===== SUBSCRIPTIONS =====\r\n\r\n async subscribeAsync(room: RundotGameRoom, options?: RoomSubscriptionOptions): Promise<() => void> {\r\n const client = await this.getClient()\r\n const unsubscribers: Array<() => void> = []\r\n\r\n const cleanupPartialSubscriptions = (): void => {\r\n for (const unsub of unsubscribers) {\r\n try {\r\n unsub()\r\n } catch (e) {\r\n console.error('[RUN.game SDK] Error during room subscription cleanup:', e)\r\n }\r\n }\r\n }\r\n\r\n try {\r\n // Subscribe to room data\r\n if (options?.onData) {\r\n const roomRef = client.doc(client.firestore, `h5_rooms/${room.id}`)\r\n const unsubscribeData = client.onSnapshot(\r\n roomRef,\r\n (snapshot: DocumentSnapshot) => {\r\n if (snapshot.exists()) {\r\n const roomData = {\r\n id: snapshot.id,\r\n ...snapshot.data(),\r\n } as RundotGameRoomPayload\r\n\r\n const update: RoomDataUpdate = {\r\n type: 'H5_ROOM_DATA_UPDATED',\r\n roomId: room.id,\r\n roomData,\r\n timestamp: Date.now(),\r\n }\r\n options.onData!(update)\r\n }\r\n },\r\n (error: FirestoreError) => {\r\n console.error('[RUN.game SDK] Room subscription error:', error)\r\n },\r\n )\r\n unsubscribers.push(unsubscribeData)\r\n }\r\n\r\n // Subscribe to messages\r\n if (options?.onMessages) {\r\n const messagesRef = client.collection(client.firestore, `h5_rooms/${room.id}/messages`)\r\n const messagesQuery = client.query(\r\n messagesRef,\r\n client.orderBy('timestamp', 'desc'),\r\n client.limit(50),\r\n )\r\n\r\n const unsubscribeMessages = client.onSnapshot(\r\n messagesQuery,\r\n (snapshot: QuerySnapshot) => {\r\n snapshot.docChanges().forEach((change: DocumentChange) => {\r\n const messageData = {\r\n id: change.doc.id,\r\n ...change.doc.data(),\r\n }\r\n\r\n let eventType: 'H5_ROOM_MESSAGE_RECEIVED' | 'H5_ROOM_MESSAGE_UPDATED' | 'H5_ROOM_MESSAGE_DELETED'\r\n if (change.type === 'added') {\r\n eventType = 'H5_ROOM_MESSAGE_RECEIVED'\r\n } else if (change.type === 'modified') {\r\n eventType = 'H5_ROOM_MESSAGE_UPDATED'\r\n } else {\r\n eventType = 'H5_ROOM_MESSAGE_DELETED'\r\n }\r\n\r\n const event: RoomMessageEvent = {\r\n type: eventType,\r\n roomId: room.id,\r\n message: messageData,\r\n timestamp: Date.now(),\r\n }\r\n options.onMessages!(event)\r\n })\r\n },\r\n (error: FirestoreError) => {\r\n console.error('[RUN.game SDK] Messages subscription error:', error)\r\n },\r\n )\r\n unsubscribers.push(unsubscribeMessages)\r\n }\r\n\r\n // Subscribe to proposed moves (game events)\r\n if (options?.onGameEvents) {\r\n const movesRef = client.collection(client.firestore, `h5_rooms/${room.id}/proposed_moves`)\r\n const movesQuery = client.query(\r\n movesRef,\r\n client.orderBy('timestamp', 'desc'),\r\n client.limit(10),\r\n )\r\n\r\n const unsubscribeMoves = client.onSnapshot(\r\n movesQuery,\r\n (snapshot: QuerySnapshot) => {\r\n snapshot.docChanges().forEach((change: DocumentChange) => {\r\n const moveData = {\r\n id: change.doc.id,\r\n ...change.doc.data(),\r\n }\r\n\r\n const event: ProposedMoveEvent = {\r\n type: 'app:h5:proposedMoveValidationUpdated',\r\n roomId: room.id,\r\n proposedMoveData: moveData,\r\n proposedMoveId: change.doc.id,\r\n changeType: change.type,\r\n timestamp: Date.now(),\r\n }\r\n options.onGameEvents!(event)\r\n })\r\n },\r\n (error: FirestoreError) => {\r\n console.error('[RUN.game SDK] Proposed moves subscription error:', error)\r\n },\r\n )\r\n unsubscribers.push(unsubscribeMoves)\r\n }\r\n } catch (error) {\r\n cleanupPartialSubscriptions()\r\n throw error\r\n }\r\n\r\n // Create combined unsubscribe function\r\n const unsubscribe = (): void => {\r\n for (const unsub of unsubscribers) {\r\n try {\r\n unsub()\r\n } catch (e) {\r\n console.error('[RUN.game SDK] Error during room subscription cleanup:', e)\r\n }\r\n }\r\n this.activeSubscriptions.delete(unsubscribe)\r\n }\r\n\r\n this.activeSubscriptions.add(unsubscribe)\r\n return unsubscribe\r\n }\r\n\r\n /**\r\n * Clean up all active subscriptions.\r\n */\r\n destroy(): void {\r\n for (const unsubscribe of this.activeSubscriptions) {\r\n unsubscribe()\r\n }\r\n this.activeSubscriptions.clear()\r\n }\r\n}\r\n","/**\r\n * Composite rooms API for sandbox mode.\r\n *\r\n * Combines HttpRoomsApi (lifecycle operations) with FirestoreRoomsApi (data/subscriptions).\r\n * This matches how the mobile app works - HTTP for server-managed operations,\r\n * direct Firestore for data and real-time subscriptions.\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost.\r\n * Do NOT import from barrel exports (rooms/index.ts) - use direct import path instead.\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport {\r\n RoomsApi,\r\n CreateRoomOptions,\r\n JoinOrCreateRoomOptions,\r\n JoinOrCreateResult,\r\n ListRoomsOptions,\r\n RoomSubscriptionOptions,\r\n UpdateRoomDataOptions,\r\n RoomMessageRequest,\r\n StartRoomGameOptions,\r\n ProposeMoveRequest,\r\n ProposeMoveResult,\r\n ValidateMoveVerdict,\r\n ValidateMoveResult,\r\n} from './RoomsApi'\r\nimport { RundotGameRoom } from './RundotGameRoom'\r\nimport { HttpRoomsApi } from './HttpRoomsApi'\r\nimport { FirestoreRoomsApi } from './FirestoreRoomsApi'\r\n\r\n/**\r\n * Composite implementation that delegates to HTTP or Firestore as appropriate.\r\n */\r\nexport class CompositeRemoteRoomsApi implements RoomsApi {\r\n private readonly httpApi: HttpRoomsApi\r\n private readonly firestoreApi: FirestoreRoomsApi\r\n\r\n constructor(httpApi: HttpRoomsApi, firestoreApi: FirestoreRoomsApi) {\r\n this.httpApi = httpApi\r\n this.firestoreApi = firestoreApi\r\n }\r\n\r\n // ===== HTTP-backed lifecycle operations =====\r\n\r\n async createRoomAsync(options: CreateRoomOptions): Promise<RundotGameRoom> {\r\n return this.httpApi.createRoomAsync(options)\r\n }\r\n\r\n async joinOrCreateRoomAsync(options: JoinOrCreateRoomOptions): Promise<JoinOrCreateResult> {\r\n return this.httpApi.joinOrCreateRoomAsync(options)\r\n }\r\n\r\n async joinRoomByCodeAsync(roomCode: string): Promise<RundotGameRoom> {\r\n return this.httpApi.joinRoomByCodeAsync(roomCode)\r\n }\r\n\r\n async getUserRoomsAsync(options?: ListRoomsOptions): Promise<RundotGameRoom[]> {\r\n return this.httpApi.getUserRoomsAsync(options)\r\n }\r\n\r\n async leaveRoomAsync(room: RundotGameRoom): Promise<void> {\r\n return this.httpApi.leaveRoomAsync(room)\r\n }\r\n\r\n async kickPlayerAsync(\r\n room: RundotGameRoom,\r\n targetProfileId: string,\r\n options?: { reason?: string },\r\n ): Promise<void> {\r\n return this.httpApi.kickPlayerAsync(room, targetProfileId, options)\r\n }\r\n\r\n async startRoomGameAsync(room: RundotGameRoom, options?: StartRoomGameOptions): Promise<void> {\r\n return this.httpApi.startRoomGameAsync(room, options)\r\n }\r\n\r\n // ===== Firestore-backed data operations =====\r\n\r\n async subscribeAsync(room: RundotGameRoom, options?: RoomSubscriptionOptions): Promise<() => void> {\r\n return this.firestoreApi.subscribeAsync(room, options)\r\n }\r\n\r\n async updateRoomDataAsync(\r\n room: RundotGameRoom,\r\n updates: Record<string, unknown>,\r\n options?: UpdateRoomDataOptions,\r\n ): Promise<void> {\r\n return this.firestoreApi.updateRoomDataAsync(room, updates, options)\r\n }\r\n\r\n async getRoomDataAsync(room: RundotGameRoom): Promise<Record<string, unknown>> {\r\n return this.firestoreApi.getRoomDataAsync(room)\r\n }\r\n\r\n async sendRoomMessageAsync(room: RundotGameRoom, message: RoomMessageRequest): Promise<string> {\r\n return this.firestoreApi.sendRoomMessageAsync(room, message)\r\n }\r\n\r\n async proposeMoveAsync(room: RundotGameRoom, request: ProposeMoveRequest): Promise<ProposeMoveResult> {\r\n return this.firestoreApi.proposeMoveAsync(room, request)\r\n }\r\n\r\n async validateMoveAsync(\r\n room: RundotGameRoom,\r\n moveId: string,\r\n verdict: ValidateMoveVerdict,\r\n ): Promise<ValidateMoveResult> {\r\n return this.firestoreApi.validateMoveAsync(room, moveId, verdict)\r\n }\r\n\r\n /**\r\n * Clean up all active subscriptions.\r\n */\r\n destroy(): void {\r\n this.firestoreApi.destroy()\r\n }\r\n}\r\n","/**\r\n * HTTP-backed {@link LeaderboardApi} implementation for sandbox mode.\r\n *\r\n * All operations call Cloud Functions directly via HTTP.\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase (via callRemoteFunction) and should\r\n * ONLY be imported by SandboxHost. Do NOT import from barrel exports (leaderboard/index.ts).\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport {\r\n LeaderboardApi,\r\n ScoreToken,\r\n SubmitScoreParams,\r\n SubmitScoreResult,\r\n GetPagedScoresOptions,\r\n PagedScoresResponse,\r\n PlayerRankOptions,\r\n PlayerRankResult,\r\n GetPodiumScoresOptions,\r\n PodiumScoresResponse,\r\n} from './LeaderboardApi'\r\nimport { callRemoteFunction, type RemoteFunctionInvoker } from '../http/callRemoteFunction'\r\n\r\n/**\r\n * HTTP-based implementation of LeaderboardApi for sandbox mode.\r\n */\r\nexport class HttpLeaderboardApi implements LeaderboardApi {\r\n private readonly appId: string\r\n private readonly callRemote: RemoteFunctionInvoker\r\n private readonly getProfileId: () => string\r\n\r\n constructor(\r\n appId: string,\r\n options: {\r\n callRemote?: RemoteFunctionInvoker\r\n getProfileId: () => string\r\n },\r\n ) {\r\n this.appId = appId\r\n this.callRemote = options.callRemote ?? callRemoteFunction\r\n this.getProfileId = options.getProfileId\r\n }\r\n\r\n async createScoreToken(mode?: string): Promise<ScoreToken> {\r\n return this.callRemote<ScoreToken>('apiCreateScoreToken', {\r\n appId: this.appId,\r\n mode: mode || 'default',\r\n })\r\n }\r\n\r\n async submitScore(params: SubmitScoreParams): Promise<SubmitScoreResult> {\r\n return this.callRemote<SubmitScoreResult>('apiSubmitScore', {\r\n appId: this.appId,\r\n token: params.token,\r\n score: params.score,\r\n duration: params.duration,\r\n mode: params.mode || 'default',\r\n telemetry: params.telemetry,\r\n metadata: params.metadata,\r\n })\r\n }\r\n\r\n async getPagedScores(options?: GetPagedScoresOptions): Promise<PagedScoresResponse> {\r\n return this.callRemote<PagedScoresResponse>('apiGetPagedScores', {\r\n appId: this.appId,\r\n mode: options?.mode || 'default',\r\n period: options?.period || 'alltime',\r\n periodDate: options?.periodDate,\r\n cursor: options?.cursor,\r\n limit: options?.limit,\r\n variant: options?.variant || 'standard',\r\n topCount: options?.topCount,\r\n contextAhead: options?.contextAhead,\r\n contextBehind: options?.contextBehind,\r\n })\r\n }\r\n\r\n async getMyRank(options?: PlayerRankOptions): Promise<PlayerRankResult> {\r\n return this.callRemote<PlayerRankResult>('apiGetMyRank', {\r\n appId: this.appId,\r\n mode: options?.mode || 'default',\r\n period: options?.period || 'alltime',\r\n periodDate: options?.periodDate,\r\n })\r\n }\r\n\r\n async getPodiumScores(options?: GetPodiumScoresOptions): Promise<PodiumScoresResponse> {\r\n return this.callRemote<PodiumScoresResponse>('apiGetPodiumScores', {\r\n appId: this.appId,\r\n mode: options?.mode || 'default',\r\n period: options?.period || 'alltime',\r\n periodDate: options?.periodDate,\r\n topCount: options?.topCount,\r\n contextAhead: options?.contextAhead,\r\n contextBehind: options?.contextBehind,\r\n })\r\n }\r\n}\r\n","/**\r\n * HTTP-backed UGC API implementation for SandboxHost\r\n *\r\n * All operations call Cloud Run directly via HTTP with Firebase Auth token.\r\n *\r\n * ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost.\r\n * Do NOT import from barrel exports (ugc/index.ts).\r\n * This ensures Firebase is not bundled in production builds.\r\n */\r\nimport {\r\n UgcApi,\r\n UgcEntry,\r\n UgcCreateParams,\r\n UgcUpdateParams,\r\n UgcListParams,\r\n UgcListResponse,\r\n UgcBrowseParams,\r\n UgcBrowseResponse,\r\n UgcReportParams,\r\n} from './UgcApi'\r\nimport { getFirebaseClient } from '../firebase/firebaseClient'\r\nimport { getCloudRunUrl } from '../config/sandbox'\r\n\r\n/**\r\n * Remove undefined values from an object (Firestore doesn't accept undefined).\r\n */\r\nfunction omitUndefined<T extends Record<string, unknown>>(obj: T): Partial<T> {\r\n const result: Partial<T> = {}\r\n for (const key of Object.keys(obj) as Array<keyof T>) {\r\n if (obj[key] !== undefined) {\r\n result[key] = obj[key]\r\n }\r\n }\r\n return result\r\n}\r\n\r\n/**\r\n * Make an authenticated request to Cloud Run.\r\n */\r\nasync function callCloudRun<TResponse>(\r\n method: string,\r\n endpoint: string,\r\n body?: unknown,\r\n): Promise<TResponse> {\r\n const client = await getFirebaseClient()\r\n const idToken = await client.getIdTokenOrThrow()\r\n const baseUrl = getCloudRunUrl()\r\n const url = `${baseUrl}${endpoint}`\r\n\r\n const options: RequestInit = {\r\n method,\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${idToken}`,\r\n },\r\n }\r\n\r\n if (body !== undefined) {\r\n options.body = JSON.stringify(body)\r\n }\r\n\r\n const response = await fetch(url, options)\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text()\r\n let errorMessage = `Cloud Run request failed (${response.status})`\r\n try {\r\n const errorJson = JSON.parse(errorText)\r\n errorMessage = errorJson.error || errorJson.message || errorMessage\r\n } catch {\r\n if (errorText) {\r\n errorMessage = errorText\r\n }\r\n }\r\n throw new Error(errorMessage)\r\n }\r\n\r\n const text = await response.text()\r\n if (!text) {\r\n return {} as TResponse // OK for void-returning methods (delete, report)\r\n }\r\n\r\n return JSON.parse(text) as TResponse\r\n}\r\n\r\nexport class HttpUgcApi implements UgcApi {\r\n private readonly appId: string\r\n\r\n constructor(appId: string) {\r\n this.appId = appId\r\n }\r\n\r\n async create(params: UgcCreateParams): Promise<UgcEntry> {\r\n return callCloudRun<UgcEntry>('POST', `/v1/ugc/${this.appId}/entries`, omitUndefined({\r\n contentType: params.contentType,\r\n data: params.data,\r\n isPublic: params.isPublic,\r\n title: params.title,\r\n tags: params.tags,\r\n }))\r\n }\r\n\r\n async update(params: UgcUpdateParams): Promise<UgcEntry> {\r\n return callCloudRun<UgcEntry>('PUT', `/v1/ugc/${this.appId}/entries/${params.id}`, omitUndefined({\r\n data: params.data,\r\n isPublic: params.isPublic,\r\n title: params.title,\r\n tags: params.tags,\r\n }))\r\n }\r\n\r\n async delete(id: string): Promise<void> {\r\n await callCloudRun<void>('DELETE', `/v1/ugc/${this.appId}/entries/${id}`)\r\n }\r\n\r\n async get(id: string): Promise<UgcEntry | null> {\r\n try {\r\n return await callCloudRun<UgcEntry>('GET', `/v1/ugc/${this.appId}/entries/${id}`)\r\n } catch (error: unknown) {\r\n // Return null for not found errors (case-insensitive, also handles 404 status)\r\n if (error instanceof Error) {\r\n const msg = error.message.toLowerCase()\r\n if (msg.includes('not found') || msg.includes('(404)')) {\r\n return null\r\n }\r\n }\r\n throw error\r\n }\r\n }\r\n\r\n async listMine(params?: UgcListParams): Promise<UgcListResponse> {\r\n const queryParams = new URLSearchParams()\r\n if (params?.contentType) queryParams.set('contentType', params.contentType)\r\n if (params?.cursor) queryParams.set('cursor', params.cursor)\r\n if (params?.limit) queryParams.set('limit', String(params.limit))\r\n\r\n const query = queryParams.toString()\r\n const endpoint = `/v1/ugc/${this.appId}/mine${query ? `?${query}` : ''}`\r\n\r\n return callCloudRun<UgcListResponse>('GET', endpoint)\r\n }\r\n\r\n async browse(params?: UgcBrowseParams): Promise<UgcBrowseResponse> {\r\n // Browse uses POST to pass body params (matching the route definition)\r\n return callCloudRun<UgcBrowseResponse>('POST', `/v1/ugc/${this.appId}/browse`, omitUndefined({\r\n contentType: params?.contentType,\r\n cursor: params?.cursor,\r\n limit: params?.limit,\r\n sortBy: params?.sortBy,\r\n }))\r\n }\r\n\r\n // Phase 2: Engagement methods\r\n\r\n async like(id: string): Promise<{ likeCount: number }> {\r\n return callCloudRun<{ likeCount: number }>('POST', `/v1/ugc/${this.appId}/entries/${id}/like`)\r\n }\r\n\r\n async unlike(id: string): Promise<{ likeCount: number }> {\r\n return callCloudRun<{ likeCount: number }>('DELETE', `/v1/ugc/${this.appId}/entries/${id}/like`)\r\n }\r\n\r\n async recordUse(id: string): Promise<{ useCount: number }> {\r\n return callCloudRun<{ useCount: number }>('POST', `/v1/ugc/${this.appId}/entries/${id}/use`)\r\n }\r\n\r\n async report(params: UgcReportParams): Promise<void> {\r\n await callCloudRun<void>('POST', `/v1/ugc/${this.appId}/entries/${params.id}/report`, omitUndefined({\r\n reason: params.reason,\r\n details: params.details,\r\n }))\r\n }\r\n}\r\n","// ⚠️ SANDBOX-ONLY: This file depends on Firebase and should ONLY be imported by SandboxHost.\r\n// Do NOT import from barrel exports (imageGen/index.ts).\r\n\r\nimport { ImageGenApi, ImageGenParams, ImageGenResult } from './ImageGenApi';\r\nimport { getFirebaseClient } from '../firebase/firebaseClient';\r\nimport { getCloudRunUrl } from '../config/sandbox';\r\n\r\nexport class HttpImageGenApi implements ImageGenApi {\r\n private readonly appId: string;\r\n\r\n constructor(appId: string) {\r\n this.appId = appId;\r\n }\r\n\r\n async generate(params: ImageGenParams): Promise<ImageGenResult> {\r\n const client = await getFirebaseClient();\r\n const idToken = await client.getIdTokenOrThrow();\r\n const baseUrl = getCloudRunUrl();\r\n const url = `${baseUrl}/v1/imagegen/${this.appId}/generate`;\r\n\r\n const response = await fetch(url, {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n 'Authorization': `Bearer ${idToken}`,\r\n },\r\n body: JSON.stringify(params),\r\n });\r\n\r\n if (!response.ok) {\r\n const errorText = await response.text();\r\n let errorMessage = `Image generation failed (${response.status})`;\r\n try {\r\n const errorJson = JSON.parse(errorText);\r\n errorMessage = errorJson.error || errorJson.message || errorMessage;\r\n } catch {\r\n if (errorText) errorMessage = errorText;\r\n }\r\n throw new Error(errorMessage);\r\n }\r\n\r\n return response.json();\r\n }\r\n}\r\n","import { AnalyticsApi, MockAnalyticsApi } from './analytics'\r\nimport { Host, InitializationContext, InitializationOptions } from './Host.ts'\r\nimport { AdsApi, MockAdsApi } from './ads'\r\nimport { createMockStorageApi, StorageApi } from './storage'\r\nimport { FirestoreStorageApi } from './storage/FirestoreStorageApi'\r\nimport { Avatar3dApi, MockAvatarApi } from './avatar3d'\r\nimport { RundotGameAPI } from './rundot-game-api/types.ts'\r\nimport { MockNavigationApi, NavigationApi } from './navigation'\r\nimport { MockNotificationsApi, NotificationsApi } from './notifications'\r\nimport { MockPopupsApi, PopupsApi } from './popups'\r\nimport { ProfileApi, SandboxProfileApi } from './profile'\r\nimport { SystemApi, MockSystemApi } from './system'\r\nimport { MockDeviceApi } from './device'\r\nimport { MockEnvironmentApi } from './environment'\r\nimport { CdnApi, MockCdnApi } from './cdn'\r\nimport { MockTimeApi, TimeApi } from './time'\r\nimport { AiApi, MockAiApi } from './ai'\r\nimport { HapticsApi, MockHapticsApi } from './haptics'\r\nimport { FeaturesApi, MockFeaturesApi } from './features'\r\nimport { LifecycleApi, MockLifecycleApi } from './lifecycles'\r\nimport { SimulationApi } from './simulation'\r\nimport { HttpSimulationApi } from './simulation/HttpSimulationApi'\r\nimport { RoomsApi, initializeRoomsApi } from './rooms'\r\nimport { HttpRoomsApi } from './rooms/HttpRoomsApi'\r\nimport { FirestoreRoomsApi } from './rooms/FirestoreRoomsApi'\r\nimport { CompositeRemoteRoomsApi } from './rooms/CompositeRemoteRoomsApi'\r\nimport { LoggingApi, MockLoggingApi } from './logging'\r\nimport { IapApi, MockIapApi } from './iap'\r\nimport { RundotGameMessageId } from './RundotGameMessageId.ts'\r\nimport {\r\n MockOverlay,\r\n MockActionSheetItem,\r\n MockActionSheetOptions,\r\n} from './MockOverlay'\r\nimport { MockSharedAssetsApi } from './shared-assets'\r\nimport { LeaderboardApi } from './leaderboard'\r\nimport { UgcApi } from './ugc'\r\nimport { HttpLeaderboardApi } from './leaderboard/HttpLeaderboardApi'\r\nimport { HttpUgcApi } from './ugc/HttpUgcApi'\r\nimport { MockPreloaderApi, PreloaderApi } from './game-preloader'\r\nimport { SocialApi } from './social/SocialApi'\r\nimport { MockSocialApi } from './social/MockSocialApi'\r\nimport { getSandboxConfig } from './config/sandbox'\r\nimport { getFirebaseClient, type FirebaseClient } from './firebase/firebaseClient'\r\nimport { callRemoteFunction } from './http/callRemoteFunction'\r\nimport { ImageGenApi } from './imageGen/ImageGenApi'\r\nimport { HttpImageGenApi } from './imageGen/HttpImageGenApi'\r\n\r\nenum SandboxHostState {\r\n PLAYING,\r\n PAUSED,\r\n SLEEPING,\r\n TERMINATED,\r\n}\r\n\r\n/**\r\n * SandboxHost connects to a real backend (local emulator, dev, or staging)\r\n * for browser-based development with live data.\r\n */\r\nexport class SandboxHost implements Host {\r\n readonly ads: AdsApi\r\n readonly analytics: AnalyticsApi\r\n readonly deviceCache: StorageApi\r\n readonly appStorage: StorageApi\r\n readonly globalStorage: StorageApi\r\n readonly avatar3d: Avatar3dApi\r\n readonly navigation: NavigationApi\r\n readonly notifications: NotificationsApi\r\n readonly popups: PopupsApi\r\n readonly profile: ProfileApi\r\n readonly system: SystemApi\r\n readonly cdn: CdnApi\r\n readonly time: TimeApi\r\n readonly ai: AiApi\r\n readonly haptics: HapticsApi\r\n readonly features: FeaturesApi\r\n readonly lifecycle: LifecycleApi\r\n readonly simulation: SimulationApi\r\n readonly rooms: RoomsApi\r\n readonly logging: LoggingApi\r\n readonly iap: IapApi\r\n readonly leaderboard: LeaderboardApi\r\n readonly ugc: UgcApi\r\n readonly preloader: PreloaderApi\r\n readonly social: SocialApi\r\n readonly imageGen: ImageGenApi\r\n\r\n context?: InitializationContext\r\n\r\n private state: SandboxHostState = SandboxHostState.PLAYING\r\n\r\n get isInitialized() {\r\n return this._isInitialized\r\n }\r\n\r\n private readonly rundotGameApi: RundotGameAPI\r\n private _isInitialized: boolean = false\r\n private readonly _overlay: MockOverlay\r\n\r\n private readonly _mockLifecyclesApi: MockLifecycleApi\r\n private readonly _mockAdsApi: MockAdsApi\r\n private client: FirebaseClient | null = null\r\n private clientReady: Promise<FirebaseClient> | null = null\r\n private authUnsubscribe: (() => void) | null = null\r\n private readonly cleanupFunctions: Array<() => void> = []\r\n private authStateChangeId: number = 0\r\n private authStateUid: string | null = null\r\n\r\n constructor(rundotGameApi: RundotGameAPI) {\r\n this.rundotGameApi = rundotGameApi\r\n this._overlay = this.createOverlay()\r\n this._mockAdsApi = new MockAdsApi(this._overlay)\r\n this._mockLifecyclesApi = new MockLifecycleApi()\r\n\r\n this.ads = this._mockAdsApi\r\n this.analytics = new MockAnalyticsApi()\r\n\r\n // Get sandbox configuration (guaranteed to exist when SandboxHost is created)\r\n const sandboxConfig = getSandboxConfig()!\r\n const gameId = sandboxConfig.gameId\r\n\r\n console.log('[RUN.game SDK] SandboxHost: Connecting to:', sandboxConfig.target)\r\n\r\n // profileId is fetched from Firebase Auth (set after user signs in)\r\n const getProfileId = (): string => {\r\n if (this.client && this.client.isSignedIn()) {\r\n return this.client.getProfileId() || 'unknown-user'\r\n }\r\n return 'unknown-user'\r\n }\r\n\r\n // Use Firestore-backed storage APIs\r\n this.deviceCache = createMockStorageApi('deviceCache', '') // deviceCache stays local\r\n this.appStorage = new FirestoreStorageApi('app', gameId)\r\n this.globalStorage = new FirestoreStorageApi('global')\r\n\r\n // Use HTTP-backed simulation API with Firestore subscriptions\r\n this.simulation = new HttpSimulationApi(gameId, { getProfileId })\r\n\r\n // Use HTTP-backed leaderboard API\r\n this.leaderboard = new HttpLeaderboardApi(gameId, { getProfileId })\r\n this.ugc = new HttpUgcApi(gameId)\r\n\r\n // Use composite rooms API (HTTP for lifecycle, Firestore for data)\r\n const httpRoomsApi = new HttpRoomsApi(gameId, { getProfileId })\r\n const firestoreRoomsApi = new FirestoreRoomsApi()\r\n this.rooms = new CompositeRemoteRoomsApi(httpRoomsApi, firestoreRoomsApi)\r\n\r\n // Shared mock APIs (UI/system - same behavior as MockHost)\r\n this.avatar3d = new MockAvatarApi(rundotGameApi)\r\n this.navigation = new MockNavigationApi(rundotGameApi)\r\n this.notifications = new MockNotificationsApi(rundotGameApi)\r\n this.popups = new MockPopupsApi(this._overlay)\r\n this.profile = new SandboxProfileApi(rundotGameApi)\r\n\r\n const deviceApi = new MockDeviceApi(rundotGameApi)\r\n const environmentApi = new MockEnvironmentApi(rundotGameApi)\r\n this.system = new MockSystemApi(deviceApi, environmentApi, rundotGameApi)\r\n\r\n this.cdn = new MockCdnApi(rundotGameApi)\r\n this.time = new MockTimeApi(rundotGameApi)\r\n this.ai = new MockAiApi()\r\n this.haptics = new MockHapticsApi(rundotGameApi)\r\n this.features = new MockFeaturesApi()\r\n this.lifecycle = this._mockLifecyclesApi\r\n this.logging = new MockLoggingApi()\r\n this.iap = new MockIapApi()\r\n this.social = new MockSocialApi()\r\n this.imageGen = new HttpImageGenApi(gameId)\r\n\r\n initializeRoomsApi(this.rundotGameApi, this)\r\n\r\n this.preloader = new MockPreloaderApi()\r\n rundotGameApi.isMock = () => true\r\n this.rundotGameApi.sharedAssets = new MockSharedAssetsApi(this.rundotGameApi)\r\n\r\n // Set up Firebase auth and sign-in for toolbar\r\n this.setupSandboxSignIn()\r\n }\r\n\r\n /**\r\n * Set up global sign-in/sign-out functions and auth state broadcasting.\r\n */\r\n private setupSandboxSignIn(): void {\r\n if (typeof window === 'undefined') return\r\n\r\n // Broadcast auth state to toolbar\r\n const broadcastAuthState = (user: import('firebase/auth').User | null): void => {\r\n window.dispatchEvent(\r\n new CustomEvent('rundot-game-auth-state-changed', {\r\n detail: {\r\n signedIn: user !== null,\r\n user: user\r\n ? {\r\n uid: user.uid,\r\n email: user.email,\r\n displayName: user.displayName,\r\n }\r\n : null,\r\n },\r\n })\r\n )\r\n }\r\n\r\n // Initialize Firebase client and set up auth state listener\r\n // Store promise to fix race condition - sign-in can await this\r\n console.log('[RUN.game SDK] SandboxHost: Initializing Firebase client...')\r\n this.clientReady = getFirebaseClient().then((client) => {\r\n this.client = client\r\n console.log('[RUN.game SDK] SandboxHost: Firebase client initialized, currentUser:', client.getCurrentUser()?.uid ?? 'none')\r\n\r\n // Listen for auth state changes and broadcast to toolbar\r\n this.authUnsubscribe = client.onAuthStateChanged(async (user) => {\r\n const changeId = ++this.authStateChangeId\r\n const expectedUid = user?.uid ?? null\r\n this.authStateUid = expectedUid\r\n const isStale = (): boolean =>\r\n this.authStateChangeId !== changeId || this.authStateUid !== expectedUid\r\n\r\n console.log('[RUN.game SDK] SandboxHost: Auth state changed, user:', user?.uid ?? 'signed out')\r\n broadcastAuthState(user)\r\n\r\n // IMPORTANT: In sandbox, profileId must match backend (Firebase Auth UID).\r\n // Set _profileData immediately so room membership checks work without races.\r\n if (!user) {\r\n this.rundotGameApi._profileData = undefined\r\n return\r\n }\r\n\r\n // Step 1: Set a placeholder profile immediately with correct id (uid).\r\n // This prevents \"created then removed\" flows where the app checks membership\r\n // against RundotGameAPI.getProfile().id before the backend profile fetch completes.\r\n // Sandbox users are always authenticated (via OAuth), never anonymous.\r\n this.rundotGameApi._profileData = {\r\n id: user.uid,\r\n username: user.email || user.displayName || user.uid.slice(-8),\r\n name: user.displayName || undefined,\r\n avatarUrl: user.photoURL || null,\r\n isAnonymous: false,\r\n }\r\n\r\n if (isStale()) return\r\n\r\n // Step 2: Ensure a backend profile exists (idempotent).\r\n await this.ensureProfileExists(user)\r\n\r\n if (isStale()) return\r\n\r\n // Step 3: Fetch backend profile and upgrade _profileData with canonical fields.\r\n try {\r\n const backendProfile = await callRemoteFunction<{\r\n id?: string\r\n username?: string\r\n name?: string\r\n avatarUrl?: string | null\r\n userId?: string\r\n } | null>('getProfile', {})\r\n\r\n if (isStale()) return\r\n\r\n if (backendProfile?.id && backendProfile?.username) {\r\n this.rundotGameApi._profileData = {\r\n id: backendProfile.id,\r\n username: backendProfile.username,\r\n name: backendProfile.name || undefined,\r\n avatarUrl: backendProfile.avatarUrl ?? null,\r\n // Sandbox users are always authenticated (via OAuth), never anonymous\r\n isAnonymous: false,\r\n }\r\n }\r\n } catch (error) {\r\n console.warn('[RUN.game SDK] SandboxHost: Failed to fetch backend profile:', error)\r\n }\r\n })\r\n\r\n return client\r\n })\r\n\r\n this.clientReady.catch((error) => {\r\n console.error('[RUN.game SDK] SandboxHost: Firebase client init failed:', error)\r\n })\r\n\r\n // Listen for toolbar requesting current auth state\r\n const checkAuthHandler = async (): Promise<void> => {\r\n const client = await getFirebaseClient()\r\n broadcastAuthState(client.getCurrentUser())\r\n }\r\n window.addEventListener('rundot-game-check-auth-state', checkAuthHandler)\r\n this.cleanupFunctions.push(() => window.removeEventListener('rundot-game-check-auth-state', checkAuthHandler))\r\n\r\n // Expose global sign-in function for toolbar button\r\n // IMPORTANT: Must call signInWithGoogle synchronously from click to avoid popup blocker.\r\n // If client isn't ready yet, we throw an error rather than awaiting (which would break popup).\r\n window.__RUNDOT_GAME_SANDBOX_SIGN_IN__ = () => {\r\n // Fast path: client already initialized (normal case after page load)\r\n if (this.client) {\r\n return this.client.signInWithGoogle()\r\n .then(() => console.log('[RUN.game SDK] Google sign-in successful'))\r\n .catch((error) => {\r\n console.error('[RUN.game SDK] Google sign-in failed:', error)\r\n throw error\r\n })\r\n }\r\n\r\n // Slow path: client not ready yet (user clicked very fast)\r\n // We can't await here without triggering popup blocker, so throw helpful error\r\n if (!this.clientReady) {\r\n throw new Error('[RUN.game SDK] Firebase not configured.')\r\n }\r\n\r\n console.warn('[RUN.game SDK] Firebase client still initializing, please wait a moment...')\r\n throw new Error('[RUN.game SDK] Firebase client still initializing. Please wait a moment and try again.')\r\n }\r\n\r\n // Expose global local sign-in-as function for toolbar button (local emulator mode only)\r\n window.__RUNDOT_GAME_SANDBOX_SIGN_IN_AS__ = (playerId: string) => {\r\n if (this.client) {\r\n return this.client.signInWithLocalPlayer(playerId)\r\n .then(() => console.log('[RUN.game SDK] Local sign-in successful'))\r\n .catch((error) => {\r\n console.error('[RUN.game SDK] Local sign-in failed:', error)\r\n throw error\r\n })\r\n }\r\n\r\n if (!this.clientReady) {\r\n throw new Error('[RUN.game SDK] Firebase not configured.')\r\n }\r\n\r\n console.warn('[RUN.game SDK] Firebase client still initializing, please wait a moment...')\r\n throw new Error('[RUN.game SDK] Firebase client still initializing. Please wait a moment and try again.')\r\n }\r\n\r\n // Expose global sign-out function for toolbar button\r\n window.__RUNDOT_GAME_SANDBOX_SIGN_OUT__ = async () => {\r\n try {\r\n const client = await getFirebaseClient()\r\n await client.signOut()\r\n console.log('[RUN.game SDK] Sign-out successful')\r\n } catch (error) {\r\n console.error('[RUN.game SDK] Sign-out failed:', error)\r\n throw error\r\n }\r\n }\r\n\r\n // Track global functions for cleanup\r\n this.cleanupFunctions.push(() => {\r\n delete window.__RUNDOT_GAME_SANDBOX_SIGN_IN__\r\n delete window.__RUNDOT_GAME_SANDBOX_SIGN_IN_AS__\r\n delete window.__RUNDOT_GAME_SANDBOX_SIGN_OUT__\r\n })\r\n }\r\n\r\n /**\r\n * Ensure a profile exists for the signed-in user.\r\n * Checks if profile exists first to avoid overwriting existing profiles on staging/dev.\r\n * Only creates a new profile if one doesn't exist.\r\n */\r\n private async ensureProfileExists(user: import('firebase/auth').User): Promise<void> {\r\n try {\r\n console.log('[RUN.game SDK] Checking if profile exists for user:', user.uid)\r\n\r\n // First, check if profile already exists\r\n try {\r\n const existingProfile = await callRemoteFunction<{ id: string } | null>('getProfile', {})\r\n if (existingProfile?.id) {\r\n console.log('[RUN.game SDK] Profile already exists:', existingProfile.id)\r\n return\r\n }\r\n } catch (checkError: unknown) {\r\n // 404 or \"not found\" means no profile - continue to create\r\n // Other errors we'll log but still try to create\r\n const err = checkError as { message?: string; status?: number }\r\n if (!err?.message?.includes('not found') && err?.status !== 404) {\r\n console.warn('[RUN.game SDK] Error checking profile, will attempt creation:', err?.message)\r\n }\r\n }\r\n\r\n // Profile doesn't exist - create one\r\n console.log('[RUN.game SDK] No profile found, creating one for user:', user.uid)\r\n const shortId = user.uid.slice(-8)\r\n const timestamp = Date.now()\r\n\r\n await callRemoteFunction('createUserProfile', {\r\n name: user.displayName || `Dev User ${shortId}`,\r\n username: `dev_${shortId}_${timestamp}`,\r\n description: 'Auto-created for sandbox development',\r\n isAnonymous: false, // Sandbox users are authenticated, not anonymous\r\n onboardingCompleted: true,\r\n })\r\n\r\n console.log('[RUN.game SDK] Profile created for user:', user.uid)\r\n } catch (error: unknown) {\r\n // Profile creation failed - log but don't throw\r\n const message = error instanceof Error ? error.message : String(error)\r\n console.warn('[RUN.game SDK] Could not ensure profile exists:', message)\r\n }\r\n }\r\n\r\n initialize(_options?: InitializationOptions): Promise<InitializationContext> {\r\n this._isInitialized = true\r\n\r\n // Populate system data on RundotGameAPI instance\r\n this.rundotGameApi._profileData = this.profile.getCurrentProfile()\r\n this.rundotGameApi._deviceData = this.system.getDevice()\r\n this.rundotGameApi._environmentData = this.system.getEnvironment()\r\n\r\n this.rundotGameApi._localeData = this.rundotGameApi._mock?.locale || 'en-US'\r\n this.rundotGameApi._languageCodeData = this.rundotGameApi._mock?.languageCode || 'en'\r\n\r\n this.context = {\r\n initializeAsleep: false,\r\n safeArea: this.rundotGameApi._safeAreaData,\r\n launchParams: _options?.launchParams || {\"SANDBOX_LAUNCH_PARAMS_KEY\": \"SANDBOX_LAUNCH_PARAMS_VALUE\"},\r\n shareParams: _options?.shareParams || {\"SANDBOX_SHARE_PARAMS_KEY\": \"SANDBOX_SHARE_PARAMS_VALUE\"},\r\n }\r\n\r\n return Promise.resolve(this.context)\r\n }\r\n\r\n // ============================================================\r\n // Overlay and UI methods (shared with MockHost)\r\n // ============================================================\r\n\r\n private createOverlay(): MockOverlay {\r\n const overlayContainer = document.createElement('div')\r\n overlayContainer.id = 'rundot-game-sandbox-overlay'\r\n overlayContainer.style.cssText = `\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n pointer-events: none;\r\n z-index: 10000;\r\n `\r\n document.body.appendChild(overlayContainer)\r\n\r\n // const menuButton = this.createOverlayButton(\r\n // 'close',\r\n // 'Menu',\r\n // { x: window.innerWidth - 48, y: 16, width: 32, height: 32 },\r\n // () => {\r\n // this.handleMenuButtonClicked()\r\n // },\r\n // 'rgba(59, 130, 246, 0.7)',\r\n // '#FFFFFF',\r\n // )\r\n // overlayContainer.appendChild(menuButton)\r\n\r\n const adOverlay = this.setupAdOverlay()\r\n const actionSheet = this.setupActionSheetOverlay()\r\n\r\n const resizeHandler = (): void => {\r\n this.updateOverlayLayout()\r\n }\r\n window.addEventListener('resize', resizeHandler)\r\n this.cleanupFunctions.push(() => window.removeEventListener('resize', resizeHandler))\r\n\r\n return {\r\n container: overlayContainer,\r\n elements: {},\r\n appVisibilityState: 'visible',\r\n actionSheetOverlay: actionSheet,\r\n adOverlay: adOverlay,\r\n showAdOverlay: () => {\r\n return this.showAdOverlay('rewarded')\r\n },\r\n showActionSheet: (items, options) => {\r\n return this.showActionSheetOverlay(items, options)\r\n },\r\n }\r\n }\r\n\r\n private async handleMenuButtonClicked() {\r\n if (this.state === SandboxHostState.PLAYING) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.PAUSE)\r\n this.state = SandboxHostState.PAUSED\r\n }\r\n\r\n const actionSheetItems: MockActionSheetItem[] = []\r\n\r\n const awakeAction: MockActionSheetItem = { label: '⏰ Awake', id: 'awakeAction' }\r\n const sleepAction: MockActionSheetItem = { label: '💤 Sleep', id: 'sleepAction' }\r\n const quitAction: MockActionSheetItem = { label: '🛑 Quit', id: 'quitAction' }\r\n const playAction: MockActionSheetItem = { label: '▶️ Play', id: 'playAction' }\r\n\r\n if (this.state === SandboxHostState.PAUSED) {\r\n actionSheetItems.push(sleepAction)\r\n } else if (this.state === SandboxHostState.SLEEPING) {\r\n actionSheetItems.push(awakeAction)\r\n }\r\n\r\n if (this.state !== SandboxHostState.TERMINATED) {\r\n actionSheetItems.push(quitAction)\r\n } else if (this.state === SandboxHostState.TERMINATED) {\r\n actionSheetItems.push(playAction)\r\n }\r\n\r\n const action = await this.showActionSheetOverlay(actionSheetItems)\r\n\r\n if (action === awakeAction.id) {\r\n this.tryAwake()\r\n } else if (action === sleepAction.id) {\r\n this.trySleep()\r\n } else if (action === playAction.id) {\r\n this.tryPlay()\r\n } else if (action === quitAction.id) {\r\n this.tryQuit()\r\n } else {\r\n this.tryResume()\r\n }\r\n }\r\n\r\n private tryAwake() {\r\n if (this.state === SandboxHostState.SLEEPING) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.AWAKE)\r\n this.state = SandboxHostState.PAUSED\r\n }\r\n }\r\n\r\n private trySleep() {\r\n if (this.state === SandboxHostState.PAUSED) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.SLEEP)\r\n this.state = SandboxHostState.SLEEPING\r\n }\r\n }\r\n\r\n private tryPlay() {\r\n if (this.state === SandboxHostState.TERMINATED) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.AWAKE)\r\n this.state = SandboxHostState.PAUSED\r\n this.triggerLifecycleEvent(RundotGameMessageId.RESUME)\r\n this.state = SandboxHostState.PLAYING\r\n }\r\n }\r\n\r\n private tryQuit() {\r\n if (this.state === SandboxHostState.PLAYING) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.PAUSE)\r\n this.state = SandboxHostState.PAUSED\r\n }\r\n\r\n if (this.state === SandboxHostState.PAUSED) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.SLEEP)\r\n this.state = SandboxHostState.SLEEPING\r\n }\r\n\r\n if (this.state === SandboxHostState.SLEEPING) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.QUIT)\r\n this.state = SandboxHostState.TERMINATED\r\n }\r\n }\r\n\r\n private tryResume() {\r\n if (this.state === SandboxHostState.PAUSED) {\r\n this.triggerLifecycleEvent(RundotGameMessageId.RESUME)\r\n this.state = SandboxHostState.PLAYING\r\n }\r\n }\r\n\r\n private async showAdOverlay(type: 'interstitial' | 'rewarded'): Promise<boolean> {\r\n return new Promise((resolve) => {\r\n const overlay = this._overlay\r\n const adOverlay = overlay.adOverlay\r\n\r\n overlay.adOverlay.innerHTML = ''\r\n\r\n const heading = document.createElement('h1')\r\n heading.style.cssText = `\r\n font-size: 24px;\r\n margin-bottom: 20px;\r\n text-align: center;\r\n `\r\n heading.innerText = type === 'interstitial' ? 'INTERSTITIAL AD' : 'REWARDED VIDEO AD'\r\n overlay.adOverlay.appendChild(heading)\r\n\r\n const content = document.createElement('div')\r\n content.style.cssText = `\r\n width: 300px;\r\n height: 250px;\r\n background-color: #1e40af;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin-bottom: 20px;\r\n border-radius: 8px;\r\n `\r\n content.innerText = 'Mock Ad Content'\r\n adOverlay.appendChild(content)\r\n\r\n const timer = document.createElement('p')\r\n timer.style.cssText = `\r\n margin-bottom: 20px;\r\n font-size: 16px;\r\n `\r\n timer.innerText = 'Normally ads would have a timer...'\r\n adOverlay.appendChild(timer)\r\n\r\n const okButton = document.createElement('button')\r\n okButton.style.cssText = `\r\n padding: 10px 40px;\r\n background-color: #2563eb;\r\n color: white;\r\n border: none;\r\n border-radius: 4px;\r\n font-size: 16px;\r\n cursor: pointer;\r\n `\r\n okButton.innerText = 'Close Ad'\r\n adOverlay.appendChild(okButton)\r\n\r\n adOverlay.style.display = 'flex'\r\n\r\n okButton.onclick = () => {\r\n this.hideAdOverlay()\r\n resolve(true)\r\n }\r\n })\r\n }\r\n\r\n private hideAdOverlay() {\r\n const overlay = this._overlay\r\n if (overlay.adOverlay) {\r\n overlay.adOverlay.style.display = 'none'\r\n }\r\n }\r\n\r\n private setupActionSheetOverlay() {\r\n const actionSheetOverlay = document.createElement('div')\r\n actionSheetOverlay.id = 'rundot-game-action-sheet-overlay'\r\n actionSheetOverlay.style.cssText = `\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(0, 0, 0, 0.5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 10600;\r\n font-family: sans-serif;\r\n display: none;\r\n `\r\n document.body.appendChild(actionSheetOverlay)\r\n return actionSheetOverlay\r\n }\r\n\r\n private createOverlayButton(\r\n id: string,\r\n text: string,\r\n position: { x: number; y: number; width: number; height: number },\r\n onClick: () => void,\r\n background: string,\r\n color: string,\r\n ) {\r\n const button = document.createElement('button')\r\n button.id = `rundot-game-sandbox-${id}-button`\r\n button.innerText = text\r\n button.style.cssText = `\r\n position: absolute;\r\n left: ${position.x}px;\r\n top: ${position.y}px;\r\n width: ${position.width}px;\r\n min-width: ${position.width}px;\r\n height: ${position.height}px;\r\n background: ${background};\r\n color: ${color};\r\n border: none;\r\n border-radius: 8px;\r\n font-family: sans-serif;\r\n font-weight: bold;\r\n font-size: ${Math.min(position.width, position.height) / 3}px;\r\n cursor: pointer;\r\n pointer-events: auto;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n opacity: 0.9;\r\n transition: opacity 0.2s;\r\n `\r\n button.addEventListener('click', onClick)\r\n button.addEventListener('mouseover', () => {\r\n button.style.opacity = '1'\r\n })\r\n button.addEventListener('mouseout', () => {\r\n button.style.opacity = '0.9'\r\n })\r\n\r\n return button\r\n }\r\n\r\n private updateOverlayLayout(): void {\r\n // No-op: sandbox uses its own toolbar, no overlay needed\r\n }\r\n\r\n private triggerLifecycleEvent(name: string) {\r\n console.log('Trigger Lifecycle Event: ', name)\r\n\r\n if (name === RundotGameMessageId.PAUSE) {\r\n this._mockLifecyclesApi.triggerPauseCallbacks()\r\n } else if (name === RundotGameMessageId.RESUME) {\r\n this._mockLifecyclesApi.triggerResumeCallbacks()\r\n } else if (name === RundotGameMessageId.QUIT) {\r\n this._mockLifecyclesApi.triggerQuitCallbacks()\r\n } else if (name === RundotGameMessageId.AWAKE) {\r\n this._mockLifecyclesApi.triggerAwakeCallbacks()\r\n } else if (name === RundotGameMessageId.SLEEP) {\r\n this._mockLifecyclesApi.triggerSleepCallbacks()\r\n }\r\n }\r\n\r\n private setupAdOverlay() {\r\n const adOverlay = document.createElement('div')\r\n adOverlay.id = 'rundot-game-ad-overlay'\r\n adOverlay.style.cssText = `\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n width: 100%;\r\n height: 100%;\r\n background-color: rgba(37, 99, 235, 0.9);\r\n color: white;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 10500;\r\n font-family: sans-serif;\r\n display: none;\r\n `\r\n document.body.appendChild(adOverlay)\r\n return adOverlay\r\n }\r\n\r\n private showActionSheetOverlay(\r\n items: MockActionSheetItem[],\r\n options?: MockActionSheetOptions,\r\n ): Promise<string | number | null> {\r\n return new Promise((resolve) => {\r\n const overlay = this._overlay\r\n overlay.actionSheetOverlay.innerHTML = ''\r\n overlay.actionSheetOverlay.style.display = 'flex'\r\n\r\n const actionSheet = document.createElement('div')\r\n actionSheet.className = 'rundot-game-action-sheet'\r\n actionSheet.style.cssText = `\r\n background-color: white;\r\n border-radius: 8px;\r\n width: 80%;\r\n max-width: 400px;\r\n max-height: 80%;\r\n display: flex;\r\n flex-direction: column;\r\n overflow: hidden;\r\n color: black;\r\n `\r\n\r\n if (options?.title) {\r\n const titleContainer = document.createElement('div')\r\n titleContainer.style.cssText = `\r\n padding: 16px;\r\n border-bottom: 1px solid #eaeaea;\r\n font-weight: bold;\r\n font-size: 18px;\r\n text-align: center;\r\n color: black;\r\n `\r\n titleContainer.innerText = options.title\r\n actionSheet.appendChild(titleContainer)\r\n }\r\n\r\n if (options?.message) {\r\n const messageContainer = document.createElement('div')\r\n messageContainer.style.cssText = `\r\n padding: 8px 16px;\r\n color: #666;\r\n font-size: 14px;\r\n text-align: center;\r\n `\r\n messageContainer.innerText = options.message\r\n actionSheet.appendChild(messageContainer)\r\n }\r\n\r\n const optionsContainer = document.createElement('div')\r\n optionsContainer.style.cssText = `\r\n overflow-y: auto;\r\n max-height: 300px;\r\n `\r\n\r\n items.forEach((item, index) => {\r\n const optionItem = document.createElement('div')\r\n optionItem.style.cssText = `\r\n padding: 12px 16px;\r\n border-bottom: 1px solid #eaeaea;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n transition: background-color 0.2s;\r\n color: black;\r\n `\r\n\r\n optionItem.addEventListener('mouseover', () => {\r\n optionItem.style.backgroundColor = '#f5f5f5'\r\n })\r\n\r\n optionItem.addEventListener('mouseout', () => {\r\n optionItem.style.backgroundColor = 'white'\r\n })\r\n\r\n if (item.icon) {\r\n const iconSpan = document.createElement('span')\r\n iconSpan.style.cssText = `\r\n margin-right: 12px;\r\n font-size: 16px;\r\n `\r\n iconSpan.innerText = item.icon\r\n optionItem.appendChild(iconSpan)\r\n }\r\n\r\n const labelSpan = document.createElement('span')\r\n labelSpan.style.cssText = `color: black;`\r\n labelSpan.innerText = item.label\r\n optionItem.appendChild(labelSpan)\r\n\r\n optionItem.addEventListener('click', () => {\r\n this.hideActionSheetOverlay()\r\n const optionId = item.id !== undefined ? item.id : index\r\n resolve(optionId)\r\n })\r\n\r\n optionsContainer.appendChild(optionItem)\r\n })\r\n\r\n actionSheet.appendChild(optionsContainer)\r\n\r\n if (!options?.disableCancel) {\r\n const cancelButton = document.createElement('div')\r\n cancelButton.style.cssText = `\r\n padding: 14px 16px;\r\n text-align: center;\r\n font-weight: bold;\r\n cursor: pointer;\r\n color: #3b82f6;\r\n border-top: 1px solid #eaeaea;\r\n `\r\n cancelButton.innerText = options?.cancelButtonText || 'Cancel'\r\n cancelButton.addEventListener('click', () => {\r\n this.hideActionSheetOverlay()\r\n resolve(null)\r\n })\r\n\r\n actionSheet.appendChild(cancelButton)\r\n }\r\n\r\n if (!options?.disableCancel) {\r\n const closeButton = document.createElement('div')\r\n closeButton.style.cssText = `\r\n position: absolute;\r\n top: 8px;\r\n right: 8px;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 12px;\r\n background-color: rgba(0,0,0,0.1);\r\n color: #666;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n font-size: 14px;\r\n `\r\n closeButton.innerText = '✕'\r\n closeButton.addEventListener('click', () => {\r\n this.hideActionSheetOverlay()\r\n resolve(null)\r\n })\r\n\r\n actionSheet.appendChild(closeButton)\r\n }\r\n\r\n // Always append the action sheet to the DOM.\r\n // Cancel/close affordances are optional, but the sheet itself must render even when\r\n // `disableCancel` is true (in that case the user must select an option).\r\n overlay.actionSheetOverlay.appendChild(actionSheet)\r\n })\r\n }\r\n\r\n private hideActionSheetOverlay() {\r\n const overlay = this._overlay\r\n if (overlay.actionSheetOverlay) {\r\n overlay.actionSheetOverlay.style.display = 'none'\r\n }\r\n }\r\n\r\n /**\r\n * Clean up all resources held by SandboxHost.\r\n * Call this when the host is no longer needed to prevent memory leaks.\r\n */\r\n destroy(): void {\r\n // Unsubscribe from Firebase auth state changes\r\n if (this.authUnsubscribe) {\r\n this.authUnsubscribe()\r\n this.authUnsubscribe = null\r\n }\r\n\r\n // Run all cleanup functions (removes event listeners, global functions)\r\n for (const cleanup of this.cleanupFunctions) {\r\n try {\r\n cleanup()\r\n } catch (e) {\r\n console.warn('[RUN.game SDK] Cleanup error:', e)\r\n }\r\n }\r\n this.cleanupFunctions.length = 0\r\n\r\n // Clean up simulation subscriptions\r\n if (this.simulation && 'destroy' in this.simulation) {\r\n (this.simulation as { destroy(): void }).destroy()\r\n }\r\n\r\n // Clean up rooms subscriptions\r\n if (this.rooms && 'destroy' in this.rooms) {\r\n (this.rooms as { destroy(): void }).destroy()\r\n }\r\n\r\n // Remove DOM elements\r\n if (typeof document !== 'undefined') {\r\n const overlay = this._overlay\r\n if (overlay.container?.parentNode) {\r\n overlay.container.parentNode.removeChild(overlay.container)\r\n }\r\n if (overlay.adOverlay?.parentNode) {\r\n overlay.adOverlay.parentNode.removeChild(overlay.adOverlay)\r\n }\r\n if (overlay.actionSheetOverlay?.parentNode) {\r\n overlay.actionSheetOverlay.parentNode.removeChild(overlay.actionSheetOverlay)\r\n }\r\n }\r\n\r\n // Clear references\r\n this.client = null\r\n this.clientReady = null\r\n }\r\n}\r\n"]}
@@ -1,4 +1,4 @@
1
- import { createMockDelay, MOCK_DELAYS, isWebPlatform } from './chunk-3GKY3LY5.js';
1
+ import { createMockDelay, MOCK_DELAYS, isWebPlatform } from './chunk-CJU2J3S6.js';
2
2
 
3
3
  // src/RundotGameMessageId.ts
4
4
  var RundotGameMessageId = /* @__PURE__ */ ((RundotGameMessageId2) => {
@@ -1495,7 +1495,7 @@ var RpcIapApi = class {
1495
1495
  }
1496
1496
  }
1497
1497
  async openStore() {
1498
- return await this.rpcClient.call("H5_IAP_OPEN_STORE" /* H5_IAP_OPEN_STORE */);
1498
+ return await this.rpcClient.call("H5_IAP_OPEN_STORE" /* H5_IAP_OPEN_STORE */, void 0, -1);
1499
1499
  }
1500
1500
  async getCurrencyIcon() {
1501
1501
  return await this.rpcClient.call("H5_IAP_GET_CURRENCY_ICON" /* H5_IAP_GET_CURRENCY_ICON */);
@@ -3465,5 +3465,5 @@ function getCloudRunUrl() {
3465
3465
  }
3466
3466
 
3467
3467
  export { BaseCdnApi, DEFAULT_SHARED_LIB_CDN_BASE, EMBEDDED_LIBRARIES, EMBEDDED_LIBRARY_BY_KEY, HapticFeedbackStyle, HostCdnApi, HostDeviceApi, HostEnvironmentApi, HostProfileApi, HostSystemApi, HostTimeApi, MODULE_TO_LIBRARY_SPECIFIERS, MockAdsApi, MockAiApi, MockAnalyticsApi, MockAvatarApi, MockCdnApi, MockDeviceApi, MockEnvironmentApi, MockFeaturesApi, MockHapticsApi, MockIapApi, MockLifecycleApi, MockLoggingApi, MockNavigationApi, MockNotificationsApi, MockPopupsApi, MockPreloaderApi, MockProfileApi, MockSharedAssetsApi, MockSocialApi, MockStorageApi, MockSystemApi, MockTimeApi, ROOM_GAME_PHASES, RpcAdsApi, RpcAiApi, RpcAnalyticsApi, RpcAvatarApi, RpcFeaturesApi, RpcHapticsApi, RpcIapApi, RpcLifecycleApi, RpcLoggingApi, RpcNavigationApi, RpcNotificationsApi, RpcPopupsApi, RpcPreloaderApi, RpcRoomsApi, RpcSharedAssetsApi, RpcStorageApi, RundotGameMessageId, RundotGameRoom, SandboxProfileApi, base64ToArrayBuffer, base64ToUtf8, buildFunctionsBaseUrl, createMockStorageApi, getCloudRunUrl, getLibraryDefinition, getSandboxConfig, initializeAds, initializeAi, initializeAnalytics, initializeAvatar3d, initializeCdn, initializeFeaturesApi, initializeHaptics, initializeIap, initializeLifecycleApi, initializeLocalNotifications, initializeLoggingApi, initializePopups, initializePreloader, initializeProfile, initializeRoomsApi, initializeStackNavigation, initializeStorage, initializeSystem, initializeTime, isPacificDaylightTime, isSandboxEnabled, setupRoomNotifications };
3468
- //# sourceMappingURL=chunk-UWRHIZXS.js.map
3469
- //# sourceMappingURL=chunk-UWRHIZXS.js.map
3468
+ //# sourceMappingURL=chunk-4ROGEXJO.js.map
3469
+ //# sourceMappingURL=chunk-4ROGEXJO.js.map