@mentra/sdk 3.0.0-alpha.1 → 3.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/server/index.d.ts +3 -12
- package/dist/app/server/index.d.ts.map +1 -1
- package/dist/index.js +162 -116
- package/dist/index.js.map +16 -16
- package/dist/internal/_SessionManager.d.ts.map +1 -1
- package/dist/session/MentraSession.d.ts.map +1 -1
- package/dist/session/internal/_V2CameraShim.d.ts +0 -1
- package/dist/session/internal/_V2CameraShim.d.ts.map +1 -1
- package/dist/session/internal/_V2EventManagerShim.d.ts +0 -1
- package/dist/session/internal/_V2EventManagerShim.d.ts.map +1 -1
- package/dist/session/internal/_V2SessionShim.d.ts +0 -4
- package/dist/session/internal/_V2SessionShim.d.ts.map +1 -1
- package/dist/session/managers/CameraManager.d.ts +0 -1
- package/dist/session/managers/CameraManager.d.ts.map +1 -1
- package/dist/session/managers/DeviceManager.d.ts +1 -17
- package/dist/session/managers/DeviceManager.d.ts.map +1 -1
- package/dist/session/managers/LedManager.d.ts +19 -4
- package/dist/session/managers/LedManager.d.ts.map +1 -1
- package/dist/session/managers/LocationManager.d.ts +41 -10
- package/dist/session/managers/LocationManager.d.ts.map +1 -1
- package/dist/session/managers/PermissionsManager.d.ts +43 -0
- package/dist/session/managers/PermissionsManager.d.ts.map +1 -1
- package/dist/session/managers/PhoneManager.d.ts +1 -57
- package/dist/session/managers/PhoneManager.d.ts.map +1 -1
- package/dist/session/managers/SpeakerManager.d.ts.map +1 -1
- package/dist/session.js +144 -86
- package/dist/session.js.map +10 -10
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -20,18 +20,18 @@
|
|
|
20
20
|
"/**\n * 🎮 Event Manager Module\n */\nimport EventEmitter from \"events\";\nimport type { Logger } from \"pino\";\nimport {\n StreamType,\n ExtendedStreamType,\n AppSettings,\n WebSocketError,\n // Event data types\n ButtonPress,\n HeadPosition,\n PhoneNotification,\n TranscriptionData,\n TranslationData,\n GlassesBatteryUpdate,\n PhoneBatteryUpdate,\n GlassesConnectionState,\n LocationUpdate,\n Vad,\n AudioChunk,\n CalendarEvent,\n VpsCoordinates,\n // Language stream helpers\n createTranscriptionStream,\n isValidLanguageCode,\n createTranslationStream,\n isLanguageStream,\n parseLanguageStream,\n CustomMessage,\n StreamStatus,\n PhotoTaken,\n ManagedStreamStatus,\n PhoneNotificationDismissed,\n Capabilities,\n TouchEvent,\n createTouchEventStream,\n} from \"../../types\";\nimport { DashboardMode } from \"../../types/dashboard\";\nimport { PermissionErrorDetail } from \"../../types/messages/cloud-to-app\";\nimport { calendarWarnLog, microPhoneWarnLog } from \"../../utils/permissions-utils\";\n\n/** 🎯 Type-safe event handler function */\ntype Handler<T> = (data: T) => void;\n\n/** 🔄 System events not tied to streams */\ninterface SystemEvents {\n connected: AppSettings | undefined;\n disconnected:\n | string\n | {\n message: string; // Human-readable close message\n code: number; // WebSocket close code (1000 = normal)\n reason: string; // Reason provided by server\n wasClean: boolean; // Whether this was a clean closure\n permanent?: boolean; // Whether this is a permanent disconnection (no more reconnection attempts)\n sessionEnded?: boolean; // Whether this disconnection is due to user session ending\n };\n error: WebSocketError | Error;\n settings_update: AppSettings;\n capabilities_update: {\n capabilities: Capabilities | null;\n modelName: string | null;\n timestamp?: Date;\n };\n dashboard_mode_change: { mode: DashboardMode | \"none\" };\n dashboard_always_on_change: { enabled: boolean };\n custom_message: CustomMessage;\n permission_error: {\n message: string;\n details: PermissionErrorDetail[];\n timestamp?: Date;\n };\n permission_denied: {\n stream: string;\n requiredPermission: string;\n message: string;\n };\n}\n\n/** 📡 All possible event types */\ntype EventType = ExtendedStreamType | keyof SystemEvents;\n\n/** 📦 Map of stream types to their data types */\nexport interface StreamDataTypes {\n [StreamType.BUTTON_PRESS]: ButtonPress;\n [StreamType.HEAD_POSITION]: HeadPosition;\n [StreamType.PHONE_NOTIFICATION]: PhoneNotification;\n [StreamType.TRANSCRIPTION]: TranscriptionData;\n [StreamType.TRANSLATION]: TranslationData;\n [StreamType.GLASSES_BATTERY_UPDATE]: GlassesBatteryUpdate;\n [StreamType.PHONE_BATTERY_UPDATE]: PhoneBatteryUpdate;\n [StreamType.GLASSES_CONNECTION_STATE]: GlassesConnectionState;\n [StreamType.LOCATION_UPDATE]: LocationUpdate;\n [StreamType.CALENDAR_EVENT]: CalendarEvent;\n [StreamType.VAD]: Vad;\n [StreamType.PHONE_NOTIFICATION_DISMISSED]: PhoneNotificationDismissed;\n [StreamType.AUDIO_CHUNK]: AudioChunk;\n [StreamType.VIDEO]: ArrayBuffer;\n [StreamType.STREAM_STATUS]: StreamStatus;\n [StreamType.MANAGED_STREAM_STATUS]: ManagedStreamStatus;\n [StreamType.VPS_COORDINATES]: VpsCoordinates;\n [StreamType.PHOTO_TAKEN]: PhotoTaken;\n [StreamType.OPEN_DASHBOARD]: never;\n [StreamType.START_APP]: never;\n [StreamType.STOP_APP]: never;\n [StreamType.ALL]: never;\n [StreamType.WILDCARD]: never;\n}\n\n/** 📦 Data type for an event */\nexport type EventData<T extends EventType> = T extends keyof StreamDataTypes\n ? StreamDataTypes[T]\n : T extends keyof SystemEvents\n ? SystemEvents[T]\n : T extends string\n ? T extends `${StreamType.TRANSCRIPTION}:${string}`\n ? TranscriptionData\n : T extends `${StreamType.TRANSLATION}:${string}`\n ? TranslationData\n : never\n : never;\n\nexport class EventManager {\n private emitter: EventEmitter;\n private handlers: Map<EventType, Set<Handler<unknown>>>;\n private lastLanguageTranscriptioCleanupHandler: () => void;\n private lastLanguageTranslationCleanupHandler: () => void;\n private logger: Logger;\n\n constructor(\n private subscribe: (type: ExtendedStreamType) => void,\n private unsubscribe: (type: ExtendedStreamType) => void,\n private packageName: string,\n private baseUrl: string,\n logger: Logger,\n ) {\n this.emitter = new EventEmitter();\n this.handlers = new Map();\n this.lastLanguageTranscriptioCleanupHandler = () => {};\n this.lastLanguageTranslationCleanupHandler = () => {};\n this.logger = logger;\n }\n\n // Convenience handlers for common event types\n\n onTranscription(handler: Handler<TranscriptionData>) {\n // Only make the API call if we have a base URL (server-side environment)\n microPhoneWarnLog(this.baseUrl, this.packageName, this.onTranscription.name, this.logger);\n\n return this.addHandler(createTranscriptionStream(\"en-US\"), handler);\n }\n\n /**\n * 🎤 Listen for transcription events in a specific language\n * @param language - Language code (e.g., \"en-US\") or \"auto\" for automatic detection\n * @param handler - Function to handle transcription data\n * @param optionsOrBoolean - Optional configuration object or boolean (backward compatible)\n * @param optionsOrBoolean.disableLanguageIdentification - Disable language identification (defaults to false/enabled)\n * @param optionsOrBoolean.hints - Array of language code hints to improve detection (e.g., [\"es\", \"fr\"])\n * @returns Cleanup function to remove the handler\n * @throws Error if language code is invalid\n */\n onTranscriptionForLanguage(\n language: string,\n handler: Handler<TranscriptionData>,\n optionsOrBoolean?:\n | boolean\n | {\n disableLanguageIdentification?: boolean;\n hints?: string[];\n },\n ): () => void {\n if (language !== \"auto\" && !isValidLanguageCode(language)) {\n throw new Error(`Invalid language code: ${language}`);\n }\n this.lastLanguageTranscriptioCleanupHandler();\n\n // Handle backward compatibility: boolean or options object\n const options =\n typeof optionsOrBoolean === \"boolean\" ? { disableLanguageIdentification: optionsOrBoolean } : optionsOrBoolean;\n\n const streamType = createTranscriptionStream(language, options);\n this.lastLanguageTranscriptioCleanupHandler = this.addHandler(streamType, handler);\n return this.lastLanguageTranscriptioCleanupHandler;\n }\n\n /**\n * 🌐 Listen for translation events for a specific language pair\n * @param sourceLanguage - Source language code (e.g., \"es-ES\")\n * @param targetLanguage - Target language code (e.g., \"en-US\")\n * @param handler - Function to handle translation data\n * @returns Cleanup function to remove the handler\n * @throws Error if language codes are invalid\n */\n ontranslationForLanguage(\n sourceLanguage: string,\n targetLanguage: string,\n handler: Handler<TranslationData>,\n ): () => void {\n microPhoneWarnLog(this.baseUrl || \"\", this.packageName, this.ontranslationForLanguage.name, this.logger);\n if (!isValidLanguageCode(sourceLanguage)) {\n throw new Error(`Invalid source language code: ${sourceLanguage}`);\n }\n if (!isValidLanguageCode(targetLanguage)) {\n throw new Error(`Invalid target language code: ${targetLanguage}`);\n }\n\n this.lastLanguageTranslationCleanupHandler();\n const streamType = createTranslationStream(sourceLanguage, targetLanguage);\n this.lastLanguageTranslationCleanupHandler = this.addHandler(streamType, handler);\n\n return this.lastLanguageTranslationCleanupHandler;\n }\n\n onHeadPosition(handler: Handler<HeadPosition>) {\n return this.addHandler(StreamType.HEAD_POSITION, handler);\n }\n\n onButtonPress(handler: Handler<ButtonPress>) {\n return this.addHandler(StreamType.BUTTON_PRESS, handler);\n }\n\n onTouchEvent(gestureOrHandler: string | Handler<TouchEvent>, handler?: Handler<TouchEvent>): () => void {\n // Handle both: onTouchEvent(handler) and onTouchEvent(\"forward_swipe\", handler)\n if (typeof gestureOrHandler === \"function\") {\n // Subscribe to all touch events\n return this.addHandler(StreamType.TOUCH_EVENT, gestureOrHandler);\n } else {\n // Subscribe to specific gesture\n const gestureStream = createTouchEventStream(gestureOrHandler);\n return this.addHandler(gestureStream, handler!);\n }\n }\n\n onPhoneNotifications(handler: Handler<PhoneNotification>) {\n return this.addHandler(StreamType.PHONE_NOTIFICATION, handler);\n }\n\n onPhoneNotificationDismissed(handler: Handler<PhoneNotificationDismissed>) {\n return this.addHandler(StreamType.PHONE_NOTIFICATION_DISMISSED, handler);\n }\n\n onGlassesBattery(handler: Handler<GlassesBatteryUpdate>) {\n return this.addHandler(StreamType.GLASSES_BATTERY_UPDATE, handler);\n }\n\n onPhoneBattery(handler: Handler<PhoneBatteryUpdate>) {\n return this.addHandler(StreamType.PHONE_BATTERY_UPDATE, handler);\n }\n\n onVoiceActivity(handler: Handler<Vad>) {\n microPhoneWarnLog(this.baseUrl || \"\", this.packageName, this.onVoiceActivity.name, this.logger);\n return this.addHandler(StreamType.VAD, handler);\n }\n\n onLocation(handler: Handler<LocationUpdate>) {\n return this.addHandler(StreamType.LOCATION_UPDATE, handler);\n }\n\n onCalendarEvent(handler: Handler<CalendarEvent>) {\n return this.addHandler(StreamType.CALENDAR_EVENT, handler);\n }\n\n /**\n * 🎤 Listen for audio chunk data\n * @param handler - Function to handle audio chunks\n * @returns Cleanup function to remove the handler\n */\n onAudioChunk(handler: Handler<AudioChunk>) {\n return this.addHandler(StreamType.AUDIO_CHUNK, handler);\n }\n\n // System event handlers\n\n onConnected(handler: Handler<SystemEvents[\"connected\"]>) {\n this.emitter.on(\"connected\", handler);\n return () => this.emitter.off(\"connected\", handler);\n }\n\n onDisconnected(handler: Handler<SystemEvents[\"disconnected\"]>) {\n this.emitter.on(\"disconnected\", handler);\n return () => this.emitter.off(\"disconnected\", handler);\n }\n\n onError(handler: Handler<SystemEvents[\"error\"]>) {\n this.emitter.on(\"error\", handler);\n return () => this.emitter.off(\"error\", handler);\n }\n\n onSettingsUpdate(handler: Handler<SystemEvents[\"settings_update\"]>) {\n this.emitter.on(\"settings_update\", handler);\n return () => this.emitter.off(\"settings_update\", handler);\n }\n\n /**\n * 🔧 Listen for device capabilities updates\n * @param handler - Function to handle capabilities updates\n * @returns Cleanup function to remove the handler\n */\n onCapabilitiesUpdate(handler: Handler<SystemEvents[\"capabilities_update\"]>) {\n this.emitter.on(\"capabilities_update\", handler);\n return () => this.emitter.off(\"capabilities_update\", handler);\n }\n\n /**\n * 🌐 Listen for dashboard mode changes\n * @param handler - Function to handle dashboard mode changes\n * @returns Cleanup function to remove the handler\n */\n onDashboardModeChange(handler: Handler<SystemEvents[\"dashboard_mode_change\"]>) {\n this.emitter.on(\"dashboard_mode_change\", handler);\n return () => this.emitter.off(\"dashboard_mode_change\", handler);\n }\n\n /**\n * 🌐 Listen for dashboard always-on mode changes\n * @param handler - Function to handle dashboard always-on mode changes\n * @returns Cleanup function to remove the handler\n */\n onDashboardAlwaysOnChange(handler: Handler<SystemEvents[\"dashboard_always_on_change\"]>) {\n this.emitter.on(\"dashboard_always_on_change\", handler);\n return () => this.emitter.off(\"dashboard_always_on_change\", handler);\n }\n\n /**\n * 🚫 Listen for permission errors when subscriptions are rejected\n * @param handler - Function to handle permission errors\n * @returns Cleanup function to remove the handler\n */\n onPermissionError(handler: Handler<SystemEvents[\"permission_error\"]>) {\n this.emitter.on(\"permission_error\", handler);\n return () => this.emitter.off(\"permission_error\", handler);\n }\n\n /**\n * 🚫 Listen for individual permission denied events for specific streams\n * @param handler - Function to handle permission denied events\n * @returns Cleanup function to remove the handler\n */\n onPermissionDenied(handler: Handler<SystemEvents[\"permission_denied\"]>) {\n this.emitter.on(\"permission_denied\", handler);\n return () => this.emitter.off(\"permission_denied\", handler);\n }\n\n /**\n * 🔄 Listen for changes to a specific setting\n * @param key - Setting key to monitor\n * @param handler - Function to handle setting value changes\n * @returns Cleanup function to remove the handler\n */\n onSettingChange<T>(key: string, handler: (value: T, previousValue: T | undefined) => void): () => void {\n let previousValue: T | undefined = undefined;\n\n const settingsHandler = (settings: AppSettings) => {\n try {\n const setting = settings.find((s) => s.key === key);\n if (setting) {\n // Only call handler if value has changed\n if (setting.value !== previousValue) {\n const newValue = setting.value as T;\n handler(newValue, previousValue);\n previousValue = newValue;\n }\n }\n } catch (error: unknown) {\n this.logger.debug({ key, error }, `Error in onSettingChange handler for key \"${key}\"`);\n }\n };\n\n this.emitter.on(\"settings_update\", settingsHandler);\n this.emitter.on(\"connected\", settingsHandler); // Also check when first connected\n\n return () => {\n this.emitter.off(\"settings_update\", settingsHandler);\n this.emitter.off(\"connected\", settingsHandler);\n };\n }\n\n /**\n * 🔄 Generic event handler\n *\n * Use this for stream types without specific handler methods\n */\n on<T extends ExtendedStreamType>(type: T, handler: Handler<EventData<T>>): () => void {\n // Check permissions for specific stream types\n if (type === StreamType.CALENDAR_EVENT) {\n calendarWarnLog(this.baseUrl, this.packageName, \"on\", this.logger);\n }\n return this.addHandler(type, handler);\n }\n\n /**\n * ➕ Add an event handler and subscribe if needed\n */\n private addHandler<T extends ExtendedStreamType>(type: T, handler: Handler<EventData<T>>): () => void {\n const handlers = this.handlers.get(type) ?? new Set();\n\n if (handlers.size === 0) {\n this.handlers.set(type, handlers);\n this.subscribe(type);\n }\n handlers.add(handler as Handler<unknown>);\n return () => this.removeHandler(type, handler);\n }\n\n /**\n * ➖ Remove an event handler\n */\n private removeHandler<T extends ExtendedStreamType>(type: T, handler: Handler<EventData<T>>): void {\n const handlers = this.handlers.get(type);\n if (!handlers) return;\n\n handlers.delete(handler as Handler<unknown>);\n if (handlers.size === 0) {\n this.handlers.delete(type);\n this.unsubscribe(type);\n }\n }\n\n /**\n * 🔍 Get all currently registered stream types\n * Returns the streams that have at least one handler registered.\n * Used to derive subscriptions from handlers (single source of truth).\n *\n * This is the fix for Bug 007: subscriptions are now derived from handlers\n * instead of being stored separately, preventing drift between the two.\n */\n getRegisteredStreams(): ExtendedStreamType[] {\n return Array.from(this.handlers.keys()) as ExtendedStreamType[];\n }\n\n /**\n * 🔍 Find a registered stream that matches the incoming stream type.\n *\n * For non-language streams: exact match (existing behavior).\n * For language streams: compare base type + transcribeLanguage\n * (+ translateLanguage for translations), ignoring query params like ?hints=.\n *\n * This allows the SDK to receive data from a cloud stream whose subscription\n * string doesn't include the same query params as the handler's subscription.\n * For example, incoming \"transcription:en-US\" matches handler \"transcription:en-US?hints=ja\".\n */\n findMatchingStream(incoming: ExtendedStreamType): ExtendedStreamType | null {\n // Fast path: exact match\n if (this.handlers.has(incoming)) {\n return incoming;\n }\n\n // For language streams, try base-language matching\n if (isLanguageStream(incoming as string)) {\n const incomingParsed = parseLanguageStream(incoming);\n if (!incomingParsed) return null;\n\n for (const key of this.handlers.keys()) {\n if (!isLanguageStream(key as string)) continue;\n\n const keyParsed = parseLanguageStream(key as ExtendedStreamType);\n if (!keyParsed) continue;\n\n // Compare base type\n if (keyParsed.type !== incomingParsed.type) continue;\n\n // Compare transcribe language\n if (keyParsed.transcribeLanguage !== incomingParsed.transcribeLanguage) continue;\n\n // For translations, also compare target language\n if (incomingParsed.translateLanguage || keyParsed.translateLanguage) {\n if (keyParsed.translateLanguage !== incomingParsed.translateLanguage) continue;\n }\n\n return key as ExtendedStreamType;\n }\n }\n\n return null;\n }\n\n /**\n * 📡 Emit an event to all registered handlers with error isolation\n */\n emit<T extends EventType>(event: T, data: EventData<T>): void {\n try {\n // Emit to EventEmitter handlers (system events)\n this.emitter.emit(event, data);\n\n // Emit to stream handlers if applicable\n const handlers = this.handlers.get(event);\n\n if (handlers) {\n // Create array of handlers to prevent modification during iteration\n const handlersArray = Array.from(handlers);\n\n // Execute each handler in isolated try/catch to prevent one handler\n // from crashing the entire App\n handlersArray.forEach((handler) => {\n try {\n (handler as Handler<EventData<T>>)(data);\n } catch (handlerError: unknown) {\n // Log at debug — the error event (emitted below) is the primary output path\n this.logger.debug(\n { event: String(event), error: handlerError },\n `Error in handler for event '${String(event)}'`,\n );\n\n // Emit an error event for tracking purposes\n if (event !== \"error\") {\n // Prevent infinite recursion\n const errorMessage = handlerError instanceof Error ? handlerError.message : String(handlerError);\n\n this.emitter.emit(\"error\", new Error(`Handler error for event '${String(event)}': ${errorMessage}`));\n }\n }\n });\n }\n\n // Fallback: if this is an error event and nobody is listening, log it.\n // This prevents errors from being silently swallowed when dev has no onError handler.\n if (event === \"error\" && this.emitter.listenerCount(\"error\") === 0 && (!handlers || handlers.size === 0)) {\n const error = data as unknown as Error;\n this.logger.error(error?.message ?? String(data));\n }\n } catch (emitError: unknown) {\n // Catch any errors in the emission process itself\n this.logger.debug({ event: String(event), error: emitError }, `Fatal error emitting event '${String(event)}'`);\n\n // Try to emit an error event if we're not already handling an error\n if (event !== \"error\") {\n try {\n const errorMessage = emitError instanceof Error ? emitError.message : String(emitError);\n\n this.emitter.emit(\"error\", new Error(`Event emission error for '${String(event)}': ${errorMessage}`));\n } catch {\n // If even this fails, log it — nothing more we can do\n this.logger.debug(\"Failed to emit error event after emission failure\");\n }\n }\n }\n }\n\n /**\n * 📨 Listen for custom messages with a specific action\n * @param action - The action identifier to filter by\n * @param handler - Function to handle the message\n * @returns Cleanup function to remove the handler\n * @deprecated Use settings.onMentraosChange() instead for system settings.\n * This method was used for datetime updates but is no longer needed.\n * Will be removed in a future version.\n */\n onCustomMessage(action: string, handler: (payload: any) => void): () => void {\n const messageHandler = (message: CustomMessage) => {\n if (message.action === action) {\n handler(message.payload);\n }\n };\n\n this.emitter.on(\"custom_message\", messageHandler);\n return () => this.emitter.off(\"custom_message\", messageHandler);\n }\n\n onVpsCoordinates(handler: Handler<VpsCoordinates>) {\n return this.addHandler(StreamType.VPS_COORDINATES, handler);\n }\n\n /**\n * 📸 Listen for photo responses\n * @param handler - Function to handle photo response data\n * @returns Cleanup function to remove the handler\n */\n onPhotoTaken(handler: Handler<PhotoTaken>) {\n return this.addHandler(StreamType.PHOTO_TAKEN, handler);\n }\n}\n",
|
|
21
21
|
"/**\n * Dashboard API Implementation\n *\n * Provides dashboard functionality for Apps, allowing them to write content\n * to the dashboard and respond to dashboard mode changes.\n */\n// import { systemApps } from '../../constants';\nimport {\n DashboardAPI,\n DashboardContentAPI,\n DashboardMode,\n DashboardSystemAPI,\n DashboardContentUpdate,\n DashboardModeChange,\n DashboardSystemUpdate,\n} from \"../../types/dashboard\"\nimport {AppToCloudMessageType} from \"../../types/message-types\"\nimport {EventManager} from \"./events\"\n\n// Import AppSession interface for typing\nimport type {AppSession} from \"./index\"\nimport dotenv from \"dotenv\"\n// Load environment variables from .env file\ndotenv.config()\n\nconst SYSTEM_DASHBOARD_PACKAGE_NAME = process.env.SYSTEM_DASHBOARD_PACKAGE_NAME || \"system.augmentos.dashboard\"\n\n/**\n * Implementation of DashboardSystemAPI interface for system dashboard App\n */\nexport class DashboardSystemManager implements DashboardSystemAPI {\n private session: AppSession\n private packageName: string\n\n constructor(session: AppSession, packageName: string) {\n this.session = session\n this.packageName = packageName\n }\n\n setTopLeft(content: string): void {\n this.updateSystemSection(\"topLeft\", content)\n }\n\n setTopRight(content: string): void {\n this.updateSystemSection(\"topRight\", content)\n }\n\n setBottomLeft(content: string): void {\n this.updateSystemSection(\"bottomLeft\", content)\n }\n\n setBottomRight(content: string): void {\n this.updateSystemSection(\"bottomRight\", content)\n }\n\n setViewMode(mode: DashboardMode): void {\n const message: DashboardModeChange = {\n type: AppToCloudMessageType.DASHBOARD_MODE_CHANGE,\n packageName: this.packageName,\n sessionId: `${this.session.getSessionId()}-${this.packageName}`,\n mode,\n timestamp: new Date(),\n }\n this.session.sendMessage(message)\n }\n\n private updateSystemSection(section: \"topLeft\" | \"topRight\" | \"bottomLeft\" | \"bottomRight\", content: string): void {\n const message: DashboardSystemUpdate = {\n type: AppToCloudMessageType.DASHBOARD_SYSTEM_UPDATE,\n packageName: this.packageName,\n sessionId: `${this.session.getSessionId()}-${this.packageName}`,\n section,\n content,\n timestamp: new Date(),\n }\n this.session.sendMessage(message)\n }\n}\n\n/**\n * Implementation of DashboardContentAPI interface for all Apps\n */\nexport class DashboardContentManager implements DashboardContentAPI {\n private session: AppSession\n private packageName: string\n private events: EventManager\n private currentMode: DashboardMode | \"none\" = \"none\"\n // private alwaysOnEnabled: boolean = false;\n\n constructor(session: AppSession, packageName: string, events: EventManager) {\n this.session = session\n this.packageName = packageName\n this.events = events\n }\n\n write(content: string, targets: DashboardMode[] = [DashboardMode.MAIN]): void {\n const message: DashboardContentUpdate = {\n type: AppToCloudMessageType.DASHBOARD_CONTENT_UPDATE,\n packageName: this.packageName,\n sessionId: `${this.session.getSessionId()}-${this.packageName}`,\n content,\n modes: targets,\n timestamp: new Date(),\n }\n this.session.sendMessage(message)\n }\n\n writeToMain(content: string): void {\n this.write(content, [DashboardMode.MAIN])\n }\n\n writeToExpanded(content: string): void {\n const message: DashboardContentUpdate = {\n type: AppToCloudMessageType.DASHBOARD_CONTENT_UPDATE,\n packageName: this.packageName,\n sessionId: `${this.session.getSessionId()}-${this.packageName}`,\n content,\n modes: [DashboardMode.EXPANDED],\n timestamp: new Date(),\n }\n this.session.sendMessage(message)\n }\n\n // writeToAlwaysOn(content: string): void {\n // this.write(content, [DashboardMode.ALWAYS_ON]);\n // }\n\n async getCurrentMode(): Promise<DashboardMode | \"none\"> {\n return this.currentMode\n }\n\n // async isAlwaysOnEnabled(): Promise<boolean> {\n // return this.alwaysOnEnabled;\n // }\n\n onModeChange(callback: (mode: DashboardMode | \"none\") => void): () => void {\n return this.events.onDashboardModeChange((data) => {\n this.currentMode = data.mode\n callback(data.mode)\n })\n }\n\n // onAlwaysOnChange(callback: (enabled: boolean) => void): () => void {\n // return this.events.onDashboardAlwaysOnChange((data) => {\n // this.alwaysOnEnabled = data.enabled;\n // callback(data.enabled);\n // });\n // }\n\n // Internal methods to update state\n setCurrentMode(mode: DashboardMode | \"none\"): void {\n this.currentMode = mode\n this.events.emit(\"dashboard_mode_change\", {mode})\n }\n\n // setAlwaysOnEnabled(enabled: boolean): void {\n // this.alwaysOnEnabled = enabled;\n // this.events.emit('dashboard_always_on_change', { enabled });\n // }\n}\n\n/**\n * Dashboard Manager - Main class that manages dashboard functionality\n * Each AppSession instance gets its own DashboardManager instance\n */\nexport class DashboardManager implements DashboardAPI {\n public content: DashboardContentAPI\n public system?: DashboardSystemAPI\n\n constructor(session: AppSession) {\n const packageName = session.getPackageName()\n const events = session.events\n\n // Create content API (available to all Apps)\n this.content = new DashboardContentManager(session, packageName, events)\n\n // Add system API if this is the system dashboard App\n if (packageName === SYSTEM_DASHBOARD_PACKAGE_NAME) {\n session.logger.info({service: \"SDK:DashboardManager\"}, \"Initializing system dashboard manager\")\n this.system = new DashboardSystemManager(session, packageName)\n } else {\n session.logger.info({service: \"SDK:DashboardManager\"}, `Not the system dashboard: ${packageName}`)\n }\n }\n}\n",
|
|
22
22
|
"/**\n * 🔐 App Token Utilities\n *\n * Provides utilities for working with App tokens.\n */\nimport * as jwt from 'jsonwebtoken';\nimport { AppTokenPayload, TokenValidationResult, TokenConfig } from '../../types/token';\n\n/**\n * Default token expiration (1 day)\n */\nconst DEFAULT_EXPIRATION = 60 * 60 * 24; // seconds * minutes * hours (1 day).\n\n/**\n * Create a App token for a user session\n *\n * @param payload - Token payload data\n * @param config - Token configuration\n * @returns JWT token string\n *\n * @example\n * ```typescript\n * const token = createToken(\n * {\n * userId: 'user123',\n * packageName: 'org.example.myapp',\n * sessionId: 'session789'\n * },\n * { secretKey: 'your_secret_key' }\n * );\n * ```\n */\nexport function createToken(\n payload: Omit<AppTokenPayload, 'iat' | 'exp'>,\n config: TokenConfig\n): string {\n return jwt.sign(\n payload,\n config.secretKey,\n { expiresIn: config.expiresIn || DEFAULT_EXPIRATION }\n );\n}\n\n/**\n * Validate and decode a App token\n *\n * @param token - JWT token string\n * @param secretKey - Secret key used for validation\n * @returns Token validation result\n *\n * @example\n * ```typescript\n * const result = validateToken('eyJhbGciOiJIUzI1...', 'your_secret_key');\n * if (result.valid) {\n * // Use result.payload\n * }\n * ```\n */\nexport function validateToken(\n token: string,\n secretKey: string\n): TokenValidationResult {\n try {\n const decoded = jwt.verify(token, secretKey) as AppTokenPayload;\n return {\n valid: true,\n payload: decoded\n };\n } catch (error) {\n return {\n valid: false,\n error: error instanceof Error ? error.message : 'Unknown error'\n };\n }\n}\n\n/**\n * Generate a webview URL with an embedded App token\n *\n * @param baseUrl - Base URL of the webview\n * @param token - JWT token string\n * @returns Full URL with token parameter\n *\n * @example\n * ```typescript\n * const url = generateWebviewUrl(\n * 'https://example.com/webview',\n * 'eyJhbGciOiJIUzI1...'\n * );\n * // Returns: https://example.com/webview?token=eyJhbGciOiJIUzI1...\n * ```\n */\nexport function generateWebviewUrl(baseUrl: string, token: string): string {\n const url = new URL(baseUrl);\n url.searchParams.append('token', token);\n return url.toString();\n}\n\n/**\n * Extract a App token from a URL\n *\n * @param url - URL string containing a token parameter\n * @returns Token string or null if not found\n *\n * @example\n * ```typescript\n * const token = extractTokenFromUrl(\n * 'https://example.com/webview?token=eyJhbGciOiJIUzI1...'\n * );\n * ```\n */\nexport function extractTokenFromUrl(url: string): string | null {\n try {\n const parsedUrl = new URL(url);\n return parsedUrl.searchParams.get('token');\n } catch (error) {\n return null;\n }\n}",
|
|
23
|
-
"import EventEmitter from \"events\";\nimport type { Logger } from \"pino\";\nimport { createLogger, type LoggerConfig } from \"../logging/logger\";\nimport type { AppConfig, AppSettings, Capabilities } from \"../types\";\nimport { AppToCloudMessageType, CloudToAppMessageType } from \"../types/message-types\";\nimport type { Transport } from \"../transport/Transport\";\nimport { CameraManager } from \"./managers/CameraManager\";\nimport { DashboardManager } from \"./managers/DashboardManager\";\nimport { DeviceManager } from \"./managers/DeviceManager\";\nimport { DisplayManager } from \"./managers/DisplayManager\";\nimport { LedManager } from \"./managers/LedManager\";\nimport { LocationManager } from \"./managers/LocationManager\";\nimport { MicManager } from \"./managers/MicManager\";\nimport { PermissionsManager } from \"./managers/PermissionsManager\";\nimport { PhoneManager } from \"./managers/PhoneManager\";\nimport { SpeakerManager } from \"./managers/SpeakerManager\";\nimport { StorageManager } from \"./managers/StorageManager\";\nimport { TimeUtils } from \"./managers/TimeUtils\";\nimport { TranscriptionManager } from \"./managers/TranscriptionManager\";\nimport { TranslationManager } from \"./managers/TranslationManager\";\nimport { _MessageRouter } from \"./internal/_MessageRouter\";\nimport { _ConnectionManager } from \"./internal/_ConnectionManager\";\nimport { _SubscriptionManager } from \"./internal/_SubscriptionManager\";\n\nexport interface MentraSessionConfig extends LoggerConfig {\n packageName: string;\n apiKey: string;\n sessionId: string;\n transport: Transport;\n userId?: string;\n serverUrl?: string;\n autoReconnect?: boolean;\n maxReconnectAttempts?: number;\n reconnectDelay?: number;\n logger?: Logger;\n}\n\ntype SessionEventMap = {\n connected: [AppSettings];\n disconnected: [{ code: number; reason: string; permanent: boolean }];\n error: [Error];\n stopped: [string];\n settings: [AppSettings];\n reconnected: [];\n};\n\nconst DEFAULT_RECONNECT_ATTEMPTS = 3;\nconst DEFAULT_RECONNECT_DELAY_MS = 1_000;\nconst DEFAULT_PARKED_TIMEOUT_MS = 30_000;\nconst SDK_VERSION = \"3.0.0-hono.8\";\n\nexport class MentraSession {\n readonly transport: Transport;\n readonly logger: Logger;\n\n readonly permissions: PermissionsManager;\n readonly transcription: TranscriptionManager;\n readonly translation: TranslationManager;\n readonly display: DisplayManager;\n readonly speaker: SpeakerManager;\n readonly mic: MicManager;\n readonly device: DeviceManager;\n readonly phone: PhoneManager;\n readonly camera: CameraManager;\n readonly led: LedManager;\n readonly location: LocationManager;\n readonly dashboard: DashboardManager;\n readonly storage: StorageManager;\n readonly time: TimeUtils;\n\n settingsData: AppSettings = [];\n mentraosSettings: Record<string, any> = {};\n appConfig: AppConfig | null = null;\n capabilities: Capabilities | null = null;\n private runtimeSessionId: string;\n private hasCompletedInitialConnect = false;\n\n private readonly config: Required<\n Pick<\n MentraSessionConfig,\n \"packageName\" | \"apiKey\" | \"sessionId\" | \"autoReconnect\" | \"maxReconnectAttempts\" | \"reconnectDelay\"\n >\n > &\n Pick<MentraSessionConfig, \"userId\" | \"serverUrl\">;\n private readonly lifecycle = new EventEmitter();\n private readonly cleanupTasks: Array<() => void | Promise<void>> = [];\n private readonly _router: _MessageRouter;\n private readonly _subscriptions: _SubscriptionManager;\n private readonly _lifecycleManager: _ConnectionManager;\n\n constructor(config: MentraSessionConfig) {\n this.transport = config.transport;\n this.runtimeSessionId = config.sessionId;\n this.config = {\n packageName: config.packageName,\n apiKey: config.apiKey,\n sessionId: config.sessionId,\n userId: config.userId,\n serverUrl: config.serverUrl,\n autoReconnect: config.autoReconnect ?? true,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULT_RECONNECT_ATTEMPTS,\n reconnectDelay: config.reconnectDelay ?? DEFAULT_RECONNECT_DELAY_MS,\n };\n\n this.logger =\n config.logger ??\n createLogger({\n logLevel: config.logLevel,\n verbose: config.verbose,\n }).child({\n packageName: this.config.packageName,\n sessionId: this.config.sessionId,\n service: \"mentra-session\",\n });\n\n // SDK internal logger — tagged with _sdk: true so the clean transport\n // filters it to warn+ in the terminal. BetterStack still gets everything.\n // Developer's session.logger (above) has no _sdk tag → always visible.\n const sdkLogger = this.logger.child({ _sdk: true });\n\n this._router = new _MessageRouter(sdkLogger);\n this._subscriptions = new _SubscriptionManager({\n logger: sdkLogger,\n isConnected: () => this.isConnected,\n sendMessage: this.sendMessage.bind(this),\n getPackageName: () => this.config.packageName,\n getSessionId: () => this.runtimeSessionId,\n });\n this._lifecycleManager = new _ConnectionManager({\n transport: this.transport,\n logger: sdkLogger,\n autoReconnect: this.config.autoReconnect,\n maxReconnectAttempts: this.config.maxReconnectAttempts,\n reconnectDelay: this.config.reconnectDelay,\n onTransportReady: () => this.sendHandshake(),\n onTextMessage: (raw) => this.handleTextMessage(raw),\n onBinaryMessage: (data) => this.mic.handleBinaryAudio(data),\n onClose: (info) => this.emit(\"disconnected\", info),\n onError: (error) => {\n this.emit(\"error\", error);\n this.logger.error(error, \"MentraSession transport error\");\n },\n });\n\n this.permissions = new PermissionsManager({ logger: sdkLogger });\n\n const deps = {\n router: this._router.dataStreamRouter,\n messageHandlers: this._router.messageHandlers,\n addSubscription: (stream: string) => this._subscriptions.add(stream),\n removeSubscription: (stream: string) => this._subscriptions.remove(stream),\n sendMessage: this.sendMessage.bind(this),\n sendBinary: this.sendBinary.bind(this),\n logger: sdkLogger,\n getPackageName: () => this.config.packageName,\n getSessionId: () => this.runtimeSessionId,\n getServerUrl: () => this.getServerUrl(),\n permissions: this.permissions,\n };\n\n this.transcription = new TranscriptionManager(deps);\n this.translation = new TranslationManager(deps);\n this.display = new DisplayManager(deps);\n this.speaker = new SpeakerManager(deps);\n this.mic = new MicManager(deps);\n this.device = new DeviceManager(deps);\n this.phone = new PhoneManager(deps);\n this.camera = new CameraManager(deps);\n this.led = new LedManager(deps);\n this.location = new LocationManager(deps);\n this.dashboard = new DashboardManager(deps);\n this.storage = new StorageManager(deps, {\n userId: this.config.userId ?? \"unknown-user\",\n apiKey: this.config.apiKey,\n });\n this.time = new TimeUtils(\"UTC\");\n\n this.registerCoreHandlers();\n }\n\n get packageName(): string {\n return this.config.packageName;\n }\n\n get sessionId(): string {\n return this.runtimeSessionId;\n }\n\n get userId(): string | undefined {\n return this.config.userId;\n }\n\n get isConnected(): boolean {\n return this._lifecycleManager.isConnected;\n }\n\n get isParked(): boolean {\n return this._lifecycleManager.isParked;\n }\n\n async connect(): Promise<void> {\n await this._lifecycleManager.connect();\n }\n\n async disconnect(): Promise<void> {\n this._lifecycleManager.disconnect();\n await this.destroyManagers();\n this._router.destroy();\n this._subscriptions.clear();\n }\n\n async releaseOwnership(reason: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\"): Promise<void> {\n this.sendMessage({\n type: AppToCloudMessageType.OWNERSHIP_RELEASE,\n packageName: this.config.packageName,\n sessionId: this.runtimeSessionId,\n reason,\n timestamp: new Date(),\n });\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n updateSettingsForTesting(newSettings: AppSettings): void {\n this.settingsData = newSettings;\n this.permissions.updateFromSettings(newSettings);\n this.emit(\"settings\", this.settingsData);\n }\n\n onConnected(handler: (...args: SessionEventMap[\"connected\"]) => void): () => void {\n this.lifecycle.on(\"connected\", handler);\n return () => this.lifecycle.off(\"connected\", handler);\n }\n\n onDisconnected(handler: (...args: SessionEventMap[\"disconnected\"]) => void): () => void {\n this.lifecycle.on(\"disconnected\", handler);\n return () => this.lifecycle.off(\"disconnected\", handler);\n }\n\n onError(handler: (...args: SessionEventMap[\"error\"]) => void): () => void {\n this.lifecycle.on(\"error\", handler);\n return () => this.lifecycle.off(\"error\", handler);\n }\n\n onStopped(handler: (...args: SessionEventMap[\"stopped\"]) => void): () => void {\n this.lifecycle.on(\"stopped\", handler);\n return () => this.lifecycle.off(\"stopped\", handler);\n }\n\n onSettings(handler: (...args: SessionEventMap[\"settings\"]) => void): () => void {\n this.lifecycle.on(\"settings\", handler);\n return () => this.lifecycle.off(\"settings\", handler);\n }\n\n onReconnected(handler: (...args: SessionEventMap[\"reconnected\"]) => void): () => void {\n this.lifecycle.on(\"reconnected\", handler);\n return () => this.lifecycle.off(\"reconnected\", handler);\n }\n\n sendMessage(message: unknown): void {\n this.transport.send(JSON.stringify(message));\n }\n\n sendBinary(data: ArrayBuffer | Uint8Array): void {\n this.transport.sendBinary(data);\n }\n\n getServerUrl(): string | null {\n return this.config.serverUrl ?? null;\n }\n\n private registerCoreHandlers(): void {\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.DATA_STREAM, (message) => {\n this._router.dataStreamRouter.handle(message);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.CONNECTION_ACK, (message) => {\n this.handleConnectionAck(message, false);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.RECONNECT_ACK, (message) => {\n this.handleConnectionAck(message, true);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.SETTINGS_UPDATE, (message) => {\n this.handleSettingsUpdate(message);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.CAPABILITIES_UPDATE, (message) => {\n this.capabilities = message.capabilities ?? null;\n this.device.handleCapabilitiesUpdate(message);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.DEVICE_STATE_UPDATE, (message) => {\n this.device.handleDeviceStateUpdate(message);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.APP_STOPPED, (message) => {\n const reason = message.reason ?? \"unknown\";\n this.logger.info({ reason }, \"MentraSession received app_stopped\");\n\n // Tell _ConnectionManager NOT to reconnect. The cloud explicitly stopped\n // this session (user closed the app from the phone). Without this, the\n // subsequent WebSocket close triggers scheduleReconnect() because\n // explicitDisconnect is false (the SDK didn't initiate the close).\n // See: cloud/issues/088 — \"app keeps restarting after user stops it\"\n this._lifecycleManager.disconnect();\n\n this.emit(\"stopped\", reason);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.CONNECTION_ERROR, (message) => {\n this.emit(\"error\", new Error(message.message ?? \"MentraSession connection error\"));\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.RECONNECT_REJECTED, (message) => {\n if (message.code === \"NOT_RUNNING\" || message.code === \"BOOT_TIMEOUT\") {\n this.transport.close(1000, message.message ?? \"Reconnect rejected\");\n this.emit(\"disconnected\", {\n code: 4002,\n reason: message.message ?? \"Reconnect rejected\",\n permanent: true,\n });\n return;\n }\n\n this.sendConnectionInit();\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.RECONNECT_DEFERRED, (message) => {\n const timeoutMs = typeof message.timeoutMs === \"number\" ? message.timeoutMs : DEFAULT_PARKED_TIMEOUT_MS;\n this._lifecycleManager.park(timeoutMs, () => {\n this.transport.close(1000, \"Parked timeout\");\n this.emit(\"disconnected\", {\n code: 4001,\n reason: \"Parked reconnect timeout exceeded\",\n permanent: true,\n });\n });\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(\"augmentos_settings_update\", (message) => {\n this.applyMentraosSettings(message.settings ?? {});\n }),\n );\n }\n\n private handleTextMessage(raw: string): void {\n try {\n this._router.handleRawText(raw);\n } catch (error) {\n this.emit(\"error\", error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private handleConnectionAck(message: any, isReconnect: boolean): void {\n this.settingsData = message.settings ?? [];\n this.appConfig = message.config ?? null;\n this.capabilities = message.capabilities ?? null;\n this.runtimeSessionId = message.sessionId ?? this.runtimeSessionId;\n\n this.permissions.updateFromSettings(message.mentraosSettings ?? message.settings ?? {});\n this.applyMentraosSettings(message.mentraosSettings ?? {});\n\n if (message.capabilities) {\n this.device.handleCapabilitiesUpdate({\n type: CloudToAppMessageType.CAPABILITIES_UPDATE,\n capabilities: message.capabilities,\n modelName: message.capabilities.modelName ?? null,\n });\n }\n\n this._lifecycleManager.markConnected();\n this._subscriptions.sync();\n const wasReconnect = isReconnect || this.hasCompletedInitialConnect;\n this.hasCompletedInitialConnect = true;\n\n const transcriptionConfig = this.transcription.config;\n if (transcriptionConfig) {\n this.transcription.configure(transcriptionConfig);\n }\n\n this.emit(\"connected\", this.settingsData);\n this.emit(\"settings\", this.settingsData);\n if (wasReconnect) {\n this.emit(\"reconnected\");\n }\n }\n\n private handleSettingsUpdate(message: any): void {\n this.settingsData = message.settings ?? [];\n this.permissions.updateFromSettings(message.settings ?? {});\n this.emit(\"settings\", this.settingsData);\n }\n\n private applyMentraosSettings(settings: Record<string, any>): void {\n this.mentraosSettings = settings;\n const timezone = settings?.timezone;\n\n if (typeof timezone === \"string\" && timezone.length > 0) {\n try {\n this.time.setTimezone(timezone);\n } catch (error) {\n this.logger.warn({ timezone, error }, \"MentraSession received invalid timezone\");\n }\n }\n }\n\n private sendHandshake(): void {\n if (this.hasCompletedInitialConnect) {\n this.sendMessage({\n type: AppToCloudMessageType.RECONNECT,\n sessionId: this.runtimeSessionId,\n sdkVersion: SDK_VERSION,\n timestamp: new Date(),\n });\n return;\n }\n\n this.sendConnectionInit();\n }\n\n private sendConnectionInit(): void {\n this.sendMessage({\n type: AppToCloudMessageType.CONNECTION_INIT,\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n sdkVersion: SDK_VERSION,\n timestamp: new Date(),\n });\n }\n\n private emit<K extends keyof SessionEventMap>(event: K, ...args: SessionEventMap[K]): void {\n this.lifecycle.emit(event, ...args);\n }\n\n private async destroyManagers(): Promise<void> {\n this._lifecycleManager.destroy();\n\n await this.storage.destroy();\n this.camera.destroy();\n this.dashboard.destroy();\n this.device.destroy();\n this.led.destroy();\n this.location.destroy();\n this.mic.stop();\n this.phone.destroy();\n this.speaker.destroy();\n this.transcription.stop();\n this.translation.stop();\n\n for (const cleanup of this.cleanupTasks.splice(0)) {\n await cleanup();\n }\n }\n}\n",
|
|
24
|
-
"/**\n * CameraManager — v3 SDK Camera API\n *\n * Covers:\n * - photo capture\n * - externally-triggered photo events\n * - unmanaged RTMP streaming\n * - managed stream orchestration/status\n */\n\nimport { EventEmitter } from \"events\";\nimport {\n AppToCloudMessageType,\n CloudToAppMessageType,\n type ManagedStreamStatus,\n type RestreamDestination,\n type StreamStatus,\n StreamType,\n type StreamStatusCheckResponse,\n type AudioConfig,\n type StreamConfig,\n type VideoConfig,\n} from \"../../types\";\n\nexport interface PhotoOptions {\n size?: \"small\" | \"medium\" | \"large\" | \"full\";\n compression?: \"none\" | \"medium\" | \"heavy\";\n saveToGallery?: boolean;\n sound?: boolean;\n timeout?: number;\n}\n\nexport interface PhotoData {\n url: string;\n width: number;\n height: number;\n timestamp: number;\n savedToGallery: boolean;\n}\n\n/**\n * Options for session.camera.startStream().\n *\n * Three modes:\n * - No options → managed relay (default, best for most apps)\n * - `destinations` → managed relay + fan out to external services\n * - `direct` → glasses connect straight to this URL, no relay\n */\nexport interface StreamOptions {\n /** Direct stream URL. Glasses connect to this URL directly, bypassing the cloud relay.\n * Supports srt://, rtmp://, rtmps://, and https:// (WHIP) protocols.\n * When set, the cloud relay is not used. No viewer URLs are returned.\n * Most apps should NOT use this — use the default managed relay instead. */\n direct?: string;\n\n /** Restream destinations. The cloud relay fans out to these URLs.\n * Only works with managed streaming (when `direct` is not set).\n * Each URL is an RTMP or SRT ingest endpoint (YouTube, Twitch, etc.) */\n destinations?: string[];\n\n /** Stream quality. Only applies to managed streaming. */\n quality?: \"720p\" | \"1080p\";\n\n /** Enable WebRTC playback URL. Only applies to managed streaming. Default: true. */\n enableWebRTC?: boolean;\n\n /** Video configuration (resolution, bitrate, fps) */\n video?: VideoConfig;\n\n /** Audio configuration (bitrate, sample rate) */\n audio?: AudioConfig;\n\n /** Stream transport configuration */\n stream?: StreamConfig;\n\n /** Controls stream start/stop sounds on the glasses. Default: true. */\n sound?: boolean;\n}\n\nexport interface StreamResult {\n hlsUrl: string;\n dashUrl: string;\n webrtcUrl?: string;\n previewUrl?: string;\n thumbnailUrl?: string;\n streamId: string;\n}\n\n/** @deprecated Use StreamOptions instead */\nexport interface RtmpStreamOptions {\n rtmpUrl: string;\n video?: VideoConfig;\n audio?: AudioConfig;\n stream?: StreamConfig;\n sound?: boolean;\n}\n\n/** @deprecated Use StreamOptions with destinations instead */\nexport interface ManagedStreamOptions {\n quality?: \"720p\" | \"1080p\";\n enableWebRTC?: boolean;\n video?: VideoConfig;\n audio?: AudioConfig;\n stream?: StreamConfig;\n restreamDestinations?: RestreamDestination[];\n sound?: boolean;\n}\n\n/** @deprecated Use StreamResult instead */\nexport type ManagedStreamResult = StreamResult;\n\nexport interface ExistingStreamInfo {\n hasActiveStream: boolean;\n streamInfo?: {\n type: \"managed\" | \"unmanaged\";\n streamId: string;\n status: string;\n createdAt: Date;\n hlsUrl?: string;\n dashUrl?: string;\n webrtcUrl?: string;\n previewUrl?: string;\n thumbnailUrl?: string;\n activeViewers?: number;\n rtmpUrl?: string;\n requestingAppId?: string;\n };\n}\n\nexport type StreamStatusHandler = (status: StreamStatus) => void;\n\nexport interface CameraManagerDeps {\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n addSubscription: (stream: string) => void;\n removeSubscription: (stream: string) => void;\n sendMessage: (message: any) => void;\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\ninterface PendingPhotoRequest {\n requestId: string;\n resolve: (data: PhotoData) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\ninterface PendingStreamCheck {\n resolve: (response: ExistingStreamInfo) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst STREAM_CHECK_TIMEOUT_MS = 5_000;\nconst MANAGED_STREAM_TIMEOUT_MS = 30_000;\n\nfunction generateRequestId(prefix: string): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `${prefix}_${crypto.randomUUID()}`;\n }\n\n return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport class CameraManager {\n private readonly deps: CameraManagerDeps;\n private readonly events = new EventEmitter();\n private readonly handlerCleanups: Array<() => void> = [];\n\n private pendingRequests = new Map<string, PendingPhotoRequest>();\n private pendingStreamChecks = new Map<string, PendingStreamCheck>();\n private pendingManagedStreamRequest:\n | {\n resolve: (value: ManagedStreamResult) => void;\n reject: (reason?: any) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n }\n | undefined;\n\n private _hasPermission = true;\n private isStreaming = false;\n private currentStreamUrl?: string;\n private currentStreamState?: StreamStatus;\n private isManagedStreaming = false;\n private currentManagedStreamId?: string;\n private currentManagedStreamUrls?: ManagedStreamResult;\n private managedStreamStatus?: ManagedStreamStatus;\n\n constructor(deps: CameraManagerDeps) {\n this.deps = deps;\n\n this.handlerCleanups.push(\n this.deps.messageHandlers.register(CloudToAppMessageType.PHOTO_RESPONSE, (msg: any) =>\n this.handlePhotoResponse(msg),\n ),\n // Register for both old (\"rtmp_stream_status\") and new (\"stream_status\") message types.\n // The cloud currently sends \"rtmp_stream_status\" but the enum maps to \"stream_status\".\n this.deps.messageHandlers.register(CloudToAppMessageType.STREAM_STATUS, (msg: any) =>\n this.handleStreamStatus(msg),\n ),\n this.deps.messageHandlers.register(\"rtmp_stream_status\" as any, (msg: any) =>\n this.handleStreamStatus(msg),\n ),\n this.deps.messageHandlers.register(CloudToAppMessageType.MANAGED_STREAM_STATUS, (msg: any) =>\n this.handleManagedStreamStatus(msg),\n ),\n this.deps.messageHandlers.register(CloudToAppMessageType.STREAM_STATUS_CHECK_RESPONSE, (msg: any) =>\n this.handleStreamCheckResponse(msg),\n ),\n );\n }\n\n takePhoto(opts?: PhotoOptions): Promise<PhotoData> {\n return new Promise<PhotoData>((resolve, reject) => {\n const requestId = generateRequestId(\"photo_req\");\n const timeoutMs = opts?.timeout ?? DEFAULT_TIMEOUT_MS;\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new Error(`Photo request timed out after ${timeoutMs}ms (requestId: ${requestId})`));\n }, timeoutMs);\n\n this.pendingRequests.set(requestId, { requestId, resolve, reject, timer });\n\n const message = {\n type: AppToCloudMessageType.PHOTO_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n saveToGallery: opts?.saveToGallery ?? false,\n size: opts?.size ?? \"medium\",\n compress: opts?.compression ?? \"none\",\n sound: opts?.sound,\n };\n\n try {\n this.deps.sendMessage(message);\n this.deps.logger.info(\n { requestId, size: message.size, compress: message.compress, saveToGallery: message.saveToGallery },\n \"📸 Photo request sent\",\n );\n } catch (err) {\n clearTimeout(timer);\n this.pendingRequests.delete(requestId);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n onPhotoTaken(handler: (photo: PhotoData) => void): () => void {\n const streamKey = StreamType.PHOTO_TAKEN;\n this.deps.addSubscription(streamKey);\n\n const routerCleanup = this.deps.router.on(streamKey, (_streamType, data) => {\n try {\n handler(normalisePhotoData(data));\n } catch (err) {\n this.deps.logger.error(\"[CameraManager] Error in onPhotoTaken handler:\", err);\n }\n });\n\n return () => {\n routerCleanup();\n this.deps.removeSubscription(streamKey);\n };\n }\n\n // ── Unified streaming API ────────────────────────────────────────────────\n\n /**\n * Start a video stream from the glasses.\n *\n * Three modes:\n * - `startStream()` — managed relay (default). Cloud handles quality, reconnection, viewer URLs.\n * - `startStream({ destinations: [...] })` — managed relay + fan out to YouTube/Twitch/etc.\n * - `startStream({ direct: \"srt://...\" })` — glasses connect straight to your URL, no relay.\n *\n * @example\n * ```ts\n * // Default — managed relay\n * const stream = await session.camera.startStream();\n * console.log(stream.hlsUrl, stream.webrtcUrl);\n *\n * // Managed relay + restream to YouTube\n * const stream = await session.camera.startStream({\n * destinations: [\"rtmp://youtube.com/live/your-key\"],\n * });\n *\n * // Direct — glasses → your server, no relay\n * await session.camera.startStream({ direct: \"srt://192.168.1.100:4201\" });\n * ```\n */\n async startStream(options?: StreamOptions): Promise<StreamResult | void> {\n const opts = options ?? {};\n\n if (opts.direct) {\n return this._startDirectStream(opts);\n }\n return this._startManagedStream(opts);\n }\n\n /**\n * Stop any active stream (managed or direct).\n */\n async stopStream(): Promise<void> {\n if (this.isStreaming) {\n // Stop direct stream\n this.deps.sendMessage({\n type: AppToCloudMessageType.STREAM_STOP,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.currentStreamState?.streamId,\n timestamp: new Date(),\n });\n }\n\n if (this.isManagedStreaming) {\n // Stop managed stream\n this.deps.sendMessage({\n type: AppToCloudMessageType.MANAGED_STREAM_STOP,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n timestamp: new Date(),\n });\n\n // Issue 091: Clear local state immediately. Don't wait for the cloud\n // to respond with managed_stream_status: \"stopped\" — the cloud may\n // not respond if the stream was already cleaned up (keep-alive timeout,\n // glasses battery death, etc.). Without this, isManagedStreaming stays\n // true and the next startStream() throws \"Already streaming.\"\n this.isManagedStreaming = false;\n this.currentManagedStreamId = undefined;\n this.currentManagedStreamUrls = undefined;\n }\n }\n\n /**\n * Subscribe to stream status updates (works for both managed and direct).\n */\n onStreamStatus(handler: StreamStatusHandler): () => void {\n // Subscribe to BOTH direct and managed stream status events.\n // Issue 091: the \"unified\" onStreamStatus was only wired to direct\n // stream events. Managed stream events (stopped, error, active from\n // Cloudflare keep-alive timeout, battery death, etc.) went to a\n // separate \"managed_stream_status\" event that this handler never heard.\n this.deps.addSubscription(StreamType.STREAM_STATUS);\n this.deps.addSubscription(StreamType.MANAGED_STREAM_STATUS);\n this.events.on(\"stream_status\", handler);\n this.events.on(\"managed_stream_status\", handler);\n\n return () => {\n this.events.off(\"stream_status\", handler);\n this.events.off(\"managed_stream_status\", handler);\n this.deps.removeSubscription(StreamType.STREAM_STATUS);\n this.deps.removeSubscription(StreamType.MANAGED_STREAM_STATUS);\n };\n }\n\n isCurrentlyStreaming(): boolean {\n return this.isStreaming || this.isManagedStreaming;\n }\n\n getCurrentStreamUrl(): string | undefined {\n return this.currentStreamUrl;\n }\n\n getStreamStatus(): StreamStatus | undefined {\n return this.currentStreamState;\n }\n\n getStreamUrls(): StreamResult | undefined {\n return this.currentManagedStreamUrls;\n }\n\n // ── Direct streaming (glasses → URL, no relay) ───────────────────────────\n\n private async _startDirectStream(opts: StreamOptions): Promise<void> {\n const url = opts.direct!;\n\n if (!url.startsWith(\"rtmp://\") && !url.startsWith(\"rtmps://\") && !url.startsWith(\"srt://\") && !url.startsWith(\"https://\") && !url.startsWith(\"http://\")) {\n throw new Error(\"Invalid stream URL: must start with rtmp://, rtmps://, srt://, https://, or http://\");\n }\n\n // Only check streams WE started, not orphaned streams from a previous session.\n // isStreaming is only set when _startDirectStream sends a STREAM_REQUEST.\n // It's NOT set by incoming status events.\n if (this.isStreaming || this.isManagedStreaming) {\n throw new Error(\"Already streaming. Stop the current stream before starting a new one.\");\n }\n\n this.currentStreamUrl = url;\n this.deps.sendMessage({\n type: AppToCloudMessageType.STREAM_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamUrl: url,\n video: opts.video,\n audio: opts.audio,\n stream: opts.stream,\n sound: opts.sound,\n timestamp: new Date(),\n });\n this.isStreaming = true;\n }\n\n // ── Managed streaming (glasses → cloud relay → viewers/destinations) ─────\n\n private async _startManagedStream(opts: StreamOptions): Promise<StreamResult> {\n // Only check streams WE started, not orphaned streams from a previous session.\n if (this.isStreaming || this.isManagedStreaming) {\n throw new Error(\"Already streaming. Stop the current stream before starting a new one.\");\n }\n\n // Convert destinations to restreamDestinations format\n const restreamDestinations: RestreamDestination[] | undefined = opts.destinations?.map((url) => ({ url }));\n\n this.deps.sendMessage({\n type: AppToCloudMessageType.MANAGED_STREAM_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n quality: opts.quality,\n enableWebRTC: opts.enableWebRTC ?? true,\n video: opts.video,\n audio: opts.audio,\n stream: opts.stream,\n restreamDestinations,\n sound: opts.sound,\n timestamp: new Date(),\n });\n this.isManagedStreaming = true;\n\n return new Promise<StreamResult>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n if (this.pendingManagedStreamRequest?.timeoutId === timeoutId) {\n this.pendingManagedStreamRequest = undefined;\n this.isManagedStreaming = false;\n reject(new Error(\"Managed stream request timeout\"));\n }\n }, MANAGED_STREAM_TIMEOUT_MS);\n\n this.pendingManagedStreamRequest = { resolve, reject, timeoutId };\n });\n }\n\n // ── Deprecated methods (backward compat) ─────────────────────────────────\n\n /** @deprecated Use startStream({ direct: url }) instead */\n async startDirectStream(options: RtmpStreamOptions): Promise<void> {\n return this._startDirectStream({ direct: options.rtmpUrl, video: options.video, audio: options.audio, stream: options.stream, sound: options.sound });\n }\n\n /** @deprecated Use startStream() or startStream({ destinations: [...] }) instead */\n async startManagedStream(options: ManagedStreamOptions = {}): Promise<StreamResult> {\n return this._startManagedStream({\n quality: options.quality,\n enableWebRTC: options.enableWebRTC,\n video: options.video,\n audio: options.audio,\n stream: options.stream,\n destinations: options.restreamDestinations?.map((d) => d.url),\n sound: options.sound,\n });\n }\n\n /** @deprecated Use stopStream() instead */\n async stopManagedStream(): Promise<void> {\n return this.stopStream();\n }\n\n /** @deprecated Use onStreamStatus() instead */\n onManagedStreamStatus(handler: (status: ManagedStreamStatus) => void): () => void {\n this.deps.addSubscription(StreamType.MANAGED_STREAM_STATUS);\n this.events.on(\"managed_stream_status\", handler);\n\n return () => {\n this.events.off(\"managed_stream_status\", handler);\n this.deps.removeSubscription(StreamType.MANAGED_STREAM_STATUS);\n };\n }\n\n /** @deprecated Use isCurrentlyStreaming() instead */\n isManagedStreamActive(): boolean {\n return this.isManagedStreaming;\n }\n\n /** @deprecated Use getStreamUrls() instead */\n getManagedStreamUrls(): StreamResult | undefined {\n return this.currentManagedStreamUrls;\n }\n\n getManagedStreamStatus(): ManagedStreamStatus | undefined {\n return this.managedStreamStatus;\n }\n\n async checkExistingStream(): Promise<ExistingStreamInfo> {\n return new Promise<ExistingStreamInfo>((resolve) => {\n const requestId = generateRequestId(\"stream_check\");\n const timeoutId = setTimeout(() => {\n this.pendingStreamChecks.delete(requestId);\n resolve({ hasActiveStream: false });\n }, STREAM_CHECK_TIMEOUT_MS);\n\n this.pendingStreamChecks.set(requestId, { resolve, timeoutId });\n\n this.deps.sendMessage({\n type: AppToCloudMessageType.STREAM_STATUS_CHECK,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n });\n });\n }\n\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n handlePhotoResponse(message: any): void {\n const requestId: string | undefined = message?.requestId;\n if (!requestId) {\n this.deps.logger.warn(\"[CameraManager] Received PHOTO_RESPONSE without requestId:\", message);\n return;\n }\n\n const pending = this.pendingRequests.get(requestId);\n if (!pending) {\n this.deps.logger.debug(`[CameraManager] No pending request for requestId=\"${requestId}\" — ignoring.`);\n return;\n }\n\n clearTimeout(pending.timer);\n this.pendingRequests.delete(requestId);\n\n if (message.error?.code === \"permission_denied\") {\n this._hasPermission = false;\n }\n\n if (message.success === false) {\n const errorMsg = message.error?.message ?? message.error?.code ?? \"Photo capture failed\";\n pending.reject(new Error(errorMsg));\n return;\n }\n\n pending.resolve({\n url: message.photoUrl ?? \"\",\n width: message.width ?? 0,\n height: message.height ?? 0,\n timestamp: message.timestamp ? new Date(message.timestamp).getTime() : Date.now(),\n savedToGallery: message.savedToGallery ?? false,\n });\n }\n\n private handleStreamStatus(message: StreamStatus): void {\n this.currentStreamState = {\n ...message,\n timestamp: message.timestamp ? new Date(message.timestamp) : new Date(),\n };\n\n // Only update isStreaming for streams WE initiated (isStreaming is set to true\n // in _startDirectStream). Don't let orphaned stream status events from a\n // previous session set isStreaming — that blocks new streams from starting.\n if (this.isStreaming) {\n if (message.status === \"stopped\" || message.status === \"error\" || message.status === \"timeout\") {\n this.isStreaming = false;\n this.currentStreamUrl = undefined;\n }\n }\n\n this.events.emit(\"stream_status\", this.currentStreamState);\n }\n\n private handleManagedStreamStatus(status: ManagedStreamStatus): void {\n this.managedStreamStatus = status;\n\n if (status.status === \"initializing\" && status.streamId) {\n this.isManagedStreaming = true;\n this.currentManagedStreamId = status.streamId;\n }\n\n if (status.status === \"active\") {\n this.isManagedStreaming = true;\n this.currentManagedStreamId = status.streamId;\n\n if (status.hlsUrl && status.dashUrl) {\n const result: ManagedStreamResult = {\n hlsUrl: status.hlsUrl,\n dashUrl: status.dashUrl,\n webrtcUrl: status.webrtcUrl,\n previewUrl: status.previewUrl,\n thumbnailUrl: status.thumbnailUrl,\n streamId: status.streamId ?? \"\",\n };\n\n this.currentManagedStreamUrls = result;\n\n if (this.pendingManagedStreamRequest) {\n clearTimeout(this.pendingManagedStreamRequest.timeoutId);\n this.pendingManagedStreamRequest.resolve(result);\n this.pendingManagedStreamRequest = undefined;\n }\n }\n }\n\n if (status.status === \"error\" || status.status === \"stopped\") {\n if (this.pendingManagedStreamRequest) {\n clearTimeout(this.pendingManagedStreamRequest.timeoutId);\n this.pendingManagedStreamRequest.reject(new Error(status.message || \"Managed stream failed\"));\n this.pendingManagedStreamRequest = undefined;\n }\n\n this.isManagedStreaming = false;\n this.currentManagedStreamId = undefined;\n this.currentManagedStreamUrls = undefined;\n }\n\n this.events.emit(\"managed_stream_status\", status);\n }\n\n private handleStreamCheckResponse(response: StreamStatusCheckResponse): void {\n // Match by requestId from the response — don't blindly pop the first entry.\n // This prevents concurrent checkExistingStream() calls from resolving the wrong promise.\n const requestId = (response as any).requestId;\n const pending = requestId ? this.pendingStreamChecks.get(requestId) : undefined;\n\n // Fallback: if the cloud doesn't include requestId, pop the first entry (v2 behavior)\n if (!pending) {\n const firstEntry = this.pendingStreamChecks.entries().next();\n if (firstEntry.done || !firstEntry.value) {\n return;\n }\n const [fallbackId, fallbackPending] = firstEntry.value;\n clearTimeout(fallbackPending.timeoutId);\n this.pendingStreamChecks.delete(fallbackId);\n fallbackPending.resolve({\n hasActiveStream: response.hasActiveStream,\n streamInfo: response.streamInfo\n ? {\n ...response.streamInfo,\n createdAt: new Date(response.streamInfo.createdAt),\n }\n : undefined,\n });\n return;\n }\n\n clearTimeout(pending.timeoutId);\n this.pendingStreamChecks.delete(requestId!);\n pending.resolve({\n hasActiveStream: response.hasActiveStream,\n streamInfo: response.streamInfo\n ? {\n ...response.streamInfo,\n createdAt: new Date(response.streamInfo.createdAt),\n }\n : undefined,\n });\n }\n\n destroy(): void {\n for (const [requestId, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(`CameraManager destroyed — session disconnected (${requestId})`));\n }\n this.pendingRequests.clear();\n\n for (const [requestId, pending] of this.pendingStreamChecks) {\n clearTimeout(pending.timeoutId);\n pending.resolve({ hasActiveStream: false });\n this.pendingStreamChecks.delete(requestId);\n }\n\n if (this.pendingManagedStreamRequest) {\n clearTimeout(this.pendingManagedStreamRequest.timeoutId);\n this.pendingManagedStreamRequest.reject(new Error(\"CameraManager destroyed — session disconnected\"));\n this.pendingManagedStreamRequest = undefined;\n }\n\n for (const cleanup of this.handlerCleanups) {\n cleanup();\n }\n this.handlerCleanups.length = 0;\n\n this.events.removeAllListeners();\n this.currentStreamState = undefined;\n this.currentStreamUrl = undefined;\n this.isStreaming = false;\n this.managedStreamStatus = undefined;\n this.currentManagedStreamId = undefined;\n this.currentManagedStreamUrls = undefined;\n this.isManagedStreaming = false;\n }\n}\n\nfunction normalisePhotoData(raw: any): PhotoData {\n return {\n url: raw.photoUrl ?? raw.url ?? \"\",\n width: raw.width ?? 0,\n height: raw.height ?? 0,\n timestamp: raw.timestamp ? new Date(raw.timestamp).getTime() : Date.now(),\n savedToGallery: raw.savedToGallery ?? false,\n };\n}\n",
|
|
23
|
+
"import EventEmitter from \"events\";\nimport type { Logger } from \"pino\";\nimport { createLogger, type LoggerConfig } from \"../logging/logger\";\nimport type { AppConfig, AppSettings, Capabilities } from \"../types\";\nimport { AppToCloudMessageType, CloudToAppMessageType } from \"../types/message-types\";\nimport type { Transport } from \"../transport/Transport\";\nimport { CameraManager } from \"./managers/CameraManager\";\nimport { DashboardManager } from \"./managers/DashboardManager\";\nimport { DeviceManager } from \"./managers/DeviceManager\";\nimport { DisplayManager } from \"./managers/DisplayManager\";\nimport { LedManager } from \"./managers/LedManager\";\nimport { LocationManager } from \"./managers/LocationManager\";\nimport { MicManager } from \"./managers/MicManager\";\nimport { PermissionsManager } from \"./managers/PermissionsManager\";\nimport { PhoneManager } from \"./managers/PhoneManager\";\nimport { SpeakerManager } from \"./managers/SpeakerManager\";\nimport { StorageManager } from \"./managers/StorageManager\";\nimport { TimeUtils } from \"./managers/TimeUtils\";\nimport { TranscriptionManager } from \"./managers/TranscriptionManager\";\nimport { TranslationManager } from \"./managers/TranslationManager\";\nimport { _MessageRouter } from \"./internal/_MessageRouter\";\nimport { _ConnectionManager } from \"./internal/_ConnectionManager\";\nimport { _SubscriptionManager } from \"./internal/_SubscriptionManager\";\n\nexport interface MentraSessionConfig extends LoggerConfig {\n packageName: string;\n apiKey: string;\n sessionId: string;\n transport: Transport;\n userId?: string;\n serverUrl?: string;\n autoReconnect?: boolean;\n maxReconnectAttempts?: number;\n reconnectDelay?: number;\n logger?: Logger;\n}\n\ntype SessionEventMap = {\n connected: [AppSettings];\n disconnected: [{ code: number; reason: string; permanent: boolean }];\n error: [Error];\n stopped: [string];\n settings: [AppSettings];\n reconnected: [];\n};\n\nconst DEFAULT_RECONNECT_ATTEMPTS = 3;\nconst DEFAULT_RECONNECT_DELAY_MS = 1_000;\nconst DEFAULT_PARKED_TIMEOUT_MS = 30_000;\nconst SDK_VERSION = \"3.0.0-hono.8\";\n\nexport class MentraSession {\n readonly transport: Transport;\n readonly logger: Logger;\n\n readonly permissions: PermissionsManager;\n readonly transcription: TranscriptionManager;\n readonly translation: TranslationManager;\n readonly display: DisplayManager;\n readonly speaker: SpeakerManager;\n readonly mic: MicManager;\n readonly device: DeviceManager;\n readonly phone: PhoneManager;\n readonly camera: CameraManager;\n readonly led: LedManager;\n readonly location: LocationManager;\n readonly dashboard: DashboardManager;\n readonly storage: StorageManager;\n readonly time: TimeUtils;\n\n settingsData: AppSettings = [];\n mentraosSettings: Record<string, any> = {};\n appConfig: AppConfig | null = null;\n capabilities: Capabilities | null = null;\n private runtimeSessionId: string;\n private hasCompletedInitialConnect = false;\n\n private readonly config: Required<\n Pick<\n MentraSessionConfig,\n \"packageName\" | \"apiKey\" | \"sessionId\" | \"autoReconnect\" | \"maxReconnectAttempts\" | \"reconnectDelay\"\n >\n > &\n Pick<MentraSessionConfig, \"userId\" | \"serverUrl\">;\n private readonly lifecycle = new EventEmitter();\n private readonly cleanupTasks: Array<() => void | Promise<void>> = [];\n private readonly _router: _MessageRouter;\n private readonly _subscriptions: _SubscriptionManager;\n private readonly _lifecycleManager: _ConnectionManager;\n\n constructor(config: MentraSessionConfig) {\n this.transport = config.transport;\n this.runtimeSessionId = config.sessionId;\n this.config = {\n packageName: config.packageName,\n apiKey: config.apiKey,\n sessionId: config.sessionId,\n userId: config.userId,\n serverUrl: config.serverUrl,\n autoReconnect: config.autoReconnect ?? true,\n maxReconnectAttempts: config.maxReconnectAttempts ?? DEFAULT_RECONNECT_ATTEMPTS,\n reconnectDelay: config.reconnectDelay ?? DEFAULT_RECONNECT_DELAY_MS,\n };\n\n this.logger =\n config.logger ??\n createLogger({\n logLevel: config.logLevel,\n verbose: config.verbose,\n }).child({\n packageName: this.config.packageName,\n sessionId: this.config.sessionId,\n service: \"mentra-session\",\n });\n\n // SDK internal logger — tagged with _sdk: true so the clean transport\n // filters it to warn+ in the terminal. BetterStack still gets everything.\n // Developer's session.logger (above) has no _sdk tag → always visible.\n const sdkLogger = this.logger.child({ _sdk: true });\n\n this._router = new _MessageRouter(sdkLogger);\n this._subscriptions = new _SubscriptionManager({\n logger: sdkLogger,\n isConnected: () => this.isConnected,\n sendMessage: this.sendMessage.bind(this),\n getPackageName: () => this.config.packageName,\n getSessionId: () => this.runtimeSessionId,\n });\n this._lifecycleManager = new _ConnectionManager({\n transport: this.transport,\n logger: sdkLogger,\n autoReconnect: this.config.autoReconnect,\n maxReconnectAttempts: this.config.maxReconnectAttempts,\n reconnectDelay: this.config.reconnectDelay,\n onTransportReady: () => this.sendHandshake(),\n onTextMessage: (raw) => this.handleTextMessage(raw),\n onBinaryMessage: (data) => this.mic.handleBinaryAudio(data),\n onClose: (info) => this.emit(\"disconnected\", info),\n onError: (error) => {\n this.emit(\"error\", error);\n this.logger.error(error, \"MentraSession transport error\");\n },\n });\n\n this.permissions = new PermissionsManager({ logger: sdkLogger, messageHandlers: this._router.messageHandlers });\n\n const deps = {\n router: this._router.dataStreamRouter,\n messageHandlers: this._router.messageHandlers,\n addSubscription: (stream: string) => this._subscriptions.add(stream),\n removeSubscription: (stream: string) => this._subscriptions.remove(stream),\n sendMessage: this.sendMessage.bind(this),\n sendBinary: this.sendBinary.bind(this),\n logger: sdkLogger,\n getPackageName: () => this.config.packageName,\n getSessionId: () => this.runtimeSessionId,\n getServerUrl: () => this.getServerUrl(),\n permissions: this.permissions,\n };\n\n this.transcription = new TranscriptionManager(deps);\n this.translation = new TranslationManager(deps);\n this.display = new DisplayManager(deps);\n this.speaker = new SpeakerManager(deps);\n this.mic = new MicManager(deps);\n this.device = new DeviceManager(deps);\n this.phone = new PhoneManager(deps);\n this.camera = new CameraManager(deps);\n this.led = new LedManager(deps);\n this.location = new LocationManager(deps);\n this.dashboard = new DashboardManager(deps);\n this.storage = new StorageManager(deps, {\n userId: this.config.userId ?? \"unknown-user\",\n apiKey: this.config.apiKey,\n });\n this.time = new TimeUtils(\"UTC\");\n\n this.registerCoreHandlers();\n }\n\n get packageName(): string {\n return this.config.packageName;\n }\n\n get sessionId(): string {\n return this.runtimeSessionId;\n }\n\n get userId(): string | undefined {\n return this.config.userId;\n }\n\n get isConnected(): boolean {\n return this._lifecycleManager.isConnected;\n }\n\n get isParked(): boolean {\n return this._lifecycleManager.isParked;\n }\n\n async connect(): Promise<void> {\n await this._lifecycleManager.connect();\n }\n\n async disconnect(): Promise<void> {\n this._lifecycleManager.disconnect();\n await this.destroyManagers();\n this._router.destroy();\n this._subscriptions.clear();\n }\n\n async releaseOwnership(reason: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\"): Promise<void> {\n this.sendMessage({\n type: AppToCloudMessageType.OWNERSHIP_RELEASE,\n packageName: this.config.packageName,\n sessionId: this.runtimeSessionId,\n reason,\n timestamp: new Date(),\n });\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n updateSettingsForTesting(newSettings: AppSettings): void {\n this.settingsData = newSettings;\n this.permissions.updateFromSettings(newSettings);\n this.emit(\"settings\", this.settingsData);\n }\n\n onConnected(handler: (...args: SessionEventMap[\"connected\"]) => void): () => void {\n this.lifecycle.on(\"connected\", handler);\n return () => this.lifecycle.off(\"connected\", handler);\n }\n\n onDisconnected(handler: (...args: SessionEventMap[\"disconnected\"]) => void): () => void {\n this.lifecycle.on(\"disconnected\", handler);\n return () => this.lifecycle.off(\"disconnected\", handler);\n }\n\n onError(handler: (...args: SessionEventMap[\"error\"]) => void): () => void {\n this.lifecycle.on(\"error\", handler);\n return () => this.lifecycle.off(\"error\", handler);\n }\n\n onStopped(handler: (...args: SessionEventMap[\"stopped\"]) => void): () => void {\n this.lifecycle.on(\"stopped\", handler);\n return () => this.lifecycle.off(\"stopped\", handler);\n }\n\n onSettings(handler: (...args: SessionEventMap[\"settings\"]) => void): () => void {\n this.lifecycle.on(\"settings\", handler);\n return () => this.lifecycle.off(\"settings\", handler);\n }\n\n onReconnected(handler: (...args: SessionEventMap[\"reconnected\"]) => void): () => void {\n this.lifecycle.on(\"reconnected\", handler);\n return () => this.lifecycle.off(\"reconnected\", handler);\n }\n\n sendMessage(message: unknown): void {\n this.transport.send(JSON.stringify(message));\n }\n\n sendBinary(data: ArrayBuffer | Uint8Array): void {\n this.transport.sendBinary(data);\n }\n\n getServerUrl(): string | null {\n return this.config.serverUrl ?? null;\n }\n\n private registerCoreHandlers(): void {\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.DATA_STREAM, (message) => {\n this._router.dataStreamRouter.handle(message);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.CONNECTION_ACK, (message) => {\n this.handleConnectionAck(message, false);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.RECONNECT_ACK, (message) => {\n this.handleConnectionAck(message, true);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.SETTINGS_UPDATE, (message) => {\n this.handleSettingsUpdate(message);\n }),\n );\n\n // NOTE: DeviceManager self-registers for both CAPABILITIES_UPDATE and\n // DEVICE_STATE_UPDATE in its constructor. Do NOT register those here\n // too — that causes every handler to fire twice (double logs, double\n // processing). MentraSession only needs to capture the capabilities\n // reference for its own `.capabilities` property.\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.CAPABILITIES_UPDATE, (message) => {\n this.capabilities = message.capabilities ?? null;\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.APP_STOPPED, (message) => {\n const reason = message.reason ?? \"unknown\";\n this.logger.info({ reason }, \"MentraSession received app_stopped\");\n\n // Tell _ConnectionManager NOT to reconnect. The cloud explicitly stopped\n // this session (user closed the app from the phone). Without this, the\n // subsequent WebSocket close triggers scheduleReconnect() because\n // explicitDisconnect is false (the SDK didn't initiate the close).\n // See: cloud/issues/088 — \"app keeps restarting after user stops it\"\n this._lifecycleManager.disconnect();\n\n this.emit(\"stopped\", reason);\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.CONNECTION_ERROR, (message) => {\n this.emit(\"error\", new Error(message.message ?? \"MentraSession connection error\"));\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.RECONNECT_REJECTED, (message) => {\n if (message.code === \"NOT_RUNNING\" || message.code === \"BOOT_TIMEOUT\") {\n this.transport.close(1000, message.message ?? \"Reconnect rejected\");\n this.emit(\"disconnected\", {\n code: 4002,\n reason: message.message ?? \"Reconnect rejected\",\n permanent: true,\n });\n return;\n }\n\n this.sendConnectionInit();\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(CloudToAppMessageType.RECONNECT_DEFERRED, (message) => {\n const timeoutMs = typeof message.timeoutMs === \"number\" ? message.timeoutMs : DEFAULT_PARKED_TIMEOUT_MS;\n this._lifecycleManager.park(timeoutMs, () => {\n this.transport.close(1000, \"Parked timeout\");\n this.emit(\"disconnected\", {\n code: 4001,\n reason: \"Parked reconnect timeout exceeded\",\n permanent: true,\n });\n });\n }),\n );\n\n this.cleanupTasks.push(\n this._router.messageHandlers.register(\"augmentos_settings_update\", (message) => {\n this.applyMentraosSettings(message.settings ?? {});\n }),\n );\n }\n\n private handleTextMessage(raw: string): void {\n try {\n this._router.handleRawText(raw);\n } catch (error) {\n this.emit(\"error\", error instanceof Error ? error : new Error(String(error)));\n }\n }\n\n private handleConnectionAck(message: any, isReconnect: boolean): void {\n this.settingsData = message.settings ?? [];\n this.appConfig = message.config ?? null;\n this.capabilities = message.capabilities ?? null;\n this.runtimeSessionId = message.sessionId ?? this.runtimeSessionId;\n\n this.permissions.updateFromSettings(message.mentraosSettings ?? message.settings ?? {});\n this.applyMentraosSettings(message.mentraosSettings ?? {});\n\n if (message.capabilities) {\n this.device.handleCapabilitiesUpdate({\n type: CloudToAppMessageType.CAPABILITIES_UPDATE,\n capabilities: message.capabilities,\n modelName: message.capabilities.modelName ?? null,\n });\n }\n\n this._lifecycleManager.markConnected();\n this._subscriptions.sync();\n const wasReconnect = isReconnect || this.hasCompletedInitialConnect;\n this.hasCompletedInitialConnect = true;\n\n const transcriptionConfig = this.transcription.config;\n if (transcriptionConfig) {\n this.transcription.configure(transcriptionConfig);\n }\n\n this.emit(\"connected\", this.settingsData);\n this.emit(\"settings\", this.settingsData);\n if (wasReconnect) {\n this.emit(\"reconnected\");\n }\n }\n\n private handleSettingsUpdate(message: any): void {\n this.settingsData = message.settings ?? [];\n this.permissions.updateFromSettings(message.settings ?? {});\n this.emit(\"settings\", this.settingsData);\n }\n\n private applyMentraosSettings(settings: Record<string, any>): void {\n this.mentraosSettings = settings;\n const timezone = settings?.timezone;\n\n if (typeof timezone === \"string\" && timezone.length > 0) {\n try {\n this.time.setTimezone(timezone);\n } catch (error) {\n this.logger.warn({ timezone, error }, \"MentraSession received invalid timezone\");\n }\n }\n }\n\n private sendHandshake(): void {\n if (this.hasCompletedInitialConnect) {\n this.sendMessage({\n type: AppToCloudMessageType.RECONNECT,\n sessionId: this.runtimeSessionId,\n sdkVersion: SDK_VERSION,\n timestamp: new Date(),\n });\n return;\n }\n\n this.sendConnectionInit();\n }\n\n private sendConnectionInit(): void {\n this.sendMessage({\n type: AppToCloudMessageType.CONNECTION_INIT,\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n sdkVersion: SDK_VERSION,\n timestamp: new Date(),\n });\n }\n\n private emit<K extends keyof SessionEventMap>(event: K, ...args: SessionEventMap[K]): void {\n this.lifecycle.emit(event, ...args);\n }\n\n private async destroyManagers(): Promise<void> {\n this._lifecycleManager.destroy();\n\n await this.storage.destroy();\n this.camera.destroy();\n this.dashboard.destroy();\n this.device.destroy();\n this.led.destroy();\n this.location.destroy();\n this.mic.stop();\n this.phone.destroy();\n this.speaker.destroy();\n this.transcription.stop();\n this.translation.stop();\n\n for (const cleanup of this.cleanupTasks.splice(0)) {\n await cleanup();\n }\n }\n}\n",
|
|
24
|
+
"/**\n * CameraManager — v3 SDK Camera API\n *\n * Covers:\n * - photo capture\n * - externally-triggered photo events\n * - unmanaged RTMP streaming\n * - managed stream orchestration/status\n */\n\nimport { EventEmitter } from \"events\";\nimport {\n AppToCloudMessageType,\n CloudToAppMessageType,\n type ManagedStreamStatus,\n type RestreamDestination,\n type StreamStatus,\n StreamType,\n type StreamStatusCheckResponse,\n type AudioConfig,\n type StreamConfig,\n type VideoConfig,\n} from \"../../types\";\n\nexport interface PhotoOptions {\n size?: \"small\" | \"medium\" | \"large\" | \"full\";\n compression?: \"none\" | \"medium\" | \"heavy\";\n saveToGallery?: boolean;\n sound?: boolean;\n timeout?: number;\n}\n\nexport interface PhotoData {\n url: string;\n width: number;\n height: number;\n timestamp: number;\n savedToGallery: boolean;\n}\n\n/**\n * Options for session.camera.startStream().\n *\n * Three modes:\n * - No options → managed relay (default, best for most apps)\n * - `destinations` → managed relay + fan out to external services\n * - `direct` → glasses connect straight to this URL, no relay\n */\nexport interface StreamOptions {\n /** Direct stream URL. Glasses connect to this URL directly, bypassing the cloud relay.\n * Supports srt://, rtmp://, rtmps://, and https:// (WHIP) protocols.\n * When set, the cloud relay is not used. No viewer URLs are returned.\n * Most apps should NOT use this — use the default managed relay instead. */\n direct?: string;\n\n /** Restream destinations. The cloud relay fans out to these URLs.\n * Only works with managed streaming (when `direct` is not set).\n * Each URL is an RTMP or SRT ingest endpoint (YouTube, Twitch, etc.) */\n destinations?: string[];\n\n /** Stream quality. Only applies to managed streaming. */\n quality?: \"720p\" | \"1080p\";\n\n /** Enable WebRTC playback URL. Only applies to managed streaming. Default: true. */\n enableWebRTC?: boolean;\n\n /** Video configuration (resolution, bitrate, fps) */\n video?: VideoConfig;\n\n /** Audio configuration (bitrate, sample rate) */\n audio?: AudioConfig;\n\n /** Stream transport configuration */\n stream?: StreamConfig;\n\n /** Controls stream start/stop sounds on the glasses. Default: true. */\n sound?: boolean;\n}\n\nexport interface StreamResult {\n hlsUrl: string;\n dashUrl: string;\n webrtcUrl?: string;\n previewUrl?: string;\n thumbnailUrl?: string;\n streamId: string;\n}\n\n/** @deprecated Use StreamOptions instead */\nexport interface RtmpStreamOptions {\n rtmpUrl: string;\n video?: VideoConfig;\n audio?: AudioConfig;\n stream?: StreamConfig;\n sound?: boolean;\n}\n\n/** @deprecated Use StreamOptions with destinations instead */\nexport interface ManagedStreamOptions {\n quality?: \"720p\" | \"1080p\";\n enableWebRTC?: boolean;\n video?: VideoConfig;\n audio?: AudioConfig;\n stream?: StreamConfig;\n restreamDestinations?: RestreamDestination[];\n sound?: boolean;\n}\n\n/** @deprecated Use StreamResult instead */\nexport type ManagedStreamResult = StreamResult;\n\nexport interface ExistingStreamInfo {\n hasActiveStream: boolean;\n streamInfo?: {\n type: \"managed\" | \"unmanaged\";\n streamId: string;\n status: string;\n createdAt: Date;\n hlsUrl?: string;\n dashUrl?: string;\n webrtcUrl?: string;\n previewUrl?: string;\n thumbnailUrl?: string;\n activeViewers?: number;\n rtmpUrl?: string;\n requestingAppId?: string;\n };\n}\n\nexport type StreamStatusHandler = (status: StreamStatus) => void;\n\nexport interface CameraManagerDeps {\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n addSubscription: (stream: string) => void;\n removeSubscription: (stream: string) => void;\n sendMessage: (message: any) => void;\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\ninterface PendingPhotoRequest {\n requestId: string;\n resolve: (data: PhotoData) => void;\n reject: (error: Error) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\ninterface PendingStreamCheck {\n resolve: (response: ExistingStreamInfo) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n}\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst STREAM_CHECK_TIMEOUT_MS = 5_000;\nconst MANAGED_STREAM_TIMEOUT_MS = 30_000;\n\nfunction generateRequestId(prefix: string): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `${prefix}_${crypto.randomUUID()}`;\n }\n\n return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport class CameraManager {\n private readonly deps: CameraManagerDeps;\n private readonly events = new EventEmitter();\n private readonly handlerCleanups: Array<() => void> = [];\n\n private pendingRequests = new Map<string, PendingPhotoRequest>();\n private pendingStreamChecks = new Map<string, PendingStreamCheck>();\n private pendingManagedStreamRequest:\n | {\n resolve: (value: ManagedStreamResult) => void;\n reject: (reason?: any) => void;\n timeoutId: ReturnType<typeof setTimeout>;\n }\n | undefined;\n\n private _hasPermission = true;\n private isStreaming = false;\n private currentStreamUrl?: string;\n private currentStreamState?: StreamStatus;\n private isManagedStreaming = false;\n private currentManagedStreamId?: string;\n private currentManagedStreamUrls?: ManagedStreamResult;\n private managedStreamStatus?: ManagedStreamStatus;\n\n constructor(deps: CameraManagerDeps) {\n this.deps = deps;\n\n this.handlerCleanups.push(\n this.deps.messageHandlers.register(CloudToAppMessageType.PHOTO_RESPONSE, (msg: any) =>\n this.handlePhotoResponse(msg),\n ),\n // Register for both old (\"rtmp_stream_status\") and new (\"stream_status\") message types.\n // The cloud currently sends \"rtmp_stream_status\" but the enum maps to \"stream_status\".\n this.deps.messageHandlers.register(CloudToAppMessageType.STREAM_STATUS, (msg: any) =>\n this.handleStreamStatus(msg),\n ),\n this.deps.messageHandlers.register(\"rtmp_stream_status\" as any, (msg: any) => this.handleStreamStatus(msg)),\n this.deps.messageHandlers.register(CloudToAppMessageType.MANAGED_STREAM_STATUS, (msg: any) =>\n this.handleManagedStreamStatus(msg),\n ),\n this.deps.messageHandlers.register(CloudToAppMessageType.STREAM_STATUS_CHECK_RESPONSE, (msg: any) =>\n this.handleStreamCheckResponse(msg),\n ),\n );\n }\n\n takePhoto(opts?: PhotoOptions): Promise<PhotoData> {\n return new Promise<PhotoData>((resolve, reject) => {\n const requestId = generateRequestId(\"photo_req\");\n const timeoutMs = opts?.timeout ?? DEFAULT_TIMEOUT_MS;\n\n const timer = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new Error(`Photo request timed out after ${timeoutMs}ms (requestId: ${requestId})`));\n }, timeoutMs);\n\n this.pendingRequests.set(requestId, { requestId, resolve, reject, timer });\n\n const message = {\n type: AppToCloudMessageType.PHOTO_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n saveToGallery: opts?.saveToGallery ?? false,\n size: opts?.size ?? \"medium\",\n compress: opts?.compression ?? \"none\",\n sound: opts?.sound,\n };\n\n try {\n this.deps.sendMessage(message);\n this.deps.logger.info(\n { requestId, size: message.size, compress: message.compress, saveToGallery: message.saveToGallery },\n \"📸 Photo request sent\",\n );\n } catch (err) {\n clearTimeout(timer);\n this.pendingRequests.delete(requestId);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n // ── Unified streaming API ────────────────────────────────────────────────\n\n /**\n * Start a video stream from the glasses.\n *\n * Three modes:\n * - `startStream()` — managed relay (default). Cloud handles quality, reconnection, viewer URLs.\n * - `startStream({ destinations: [...] })` — managed relay + fan out to YouTube/Twitch/etc.\n * - `startStream({ direct: \"srt://...\" })` — glasses connect straight to your URL, no relay.\n *\n * @example\n * ```ts\n * // Default — managed relay\n * const stream = await session.camera.startStream();\n * console.log(stream.hlsUrl, stream.webrtcUrl);\n *\n * // Managed relay + restream to YouTube\n * const stream = await session.camera.startStream({\n * destinations: [\"rtmp://youtube.com/live/your-key\"],\n * });\n *\n * // Direct — glasses → your server, no relay\n * await session.camera.startStream({ direct: \"srt://192.168.1.100:4201\" });\n * ```\n */\n async startStream(options?: StreamOptions): Promise<StreamResult | void> {\n const opts = options ?? {};\n\n if (opts.direct) {\n return this._startDirectStream(opts);\n }\n return this._startManagedStream(opts);\n }\n\n /**\n * Stop any active stream (managed or direct).\n */\n async stopStream(): Promise<void> {\n if (this.isStreaming) {\n // Stop direct stream\n this.deps.sendMessage({\n type: AppToCloudMessageType.STREAM_STOP,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.currentStreamState?.streamId,\n timestamp: new Date(),\n });\n }\n\n if (this.isManagedStreaming) {\n // Stop managed stream\n this.deps.sendMessage({\n type: AppToCloudMessageType.MANAGED_STREAM_STOP,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n timestamp: new Date(),\n });\n\n // Issue 091: Clear local state immediately. Don't wait for the cloud\n // to respond with managed_stream_status: \"stopped\" — the cloud may\n // not respond if the stream was already cleaned up (keep-alive timeout,\n // glasses battery death, etc.). Without this, isManagedStreaming stays\n // true and the next startStream() throws \"Already streaming.\"\n this.isManagedStreaming = false;\n this.currentManagedStreamId = undefined;\n this.currentManagedStreamUrls = undefined;\n }\n }\n\n /**\n * Subscribe to stream status updates (works for both managed and direct).\n */\n onStreamStatus(handler: StreamStatusHandler): () => void {\n // Subscribe to BOTH direct and managed stream status events.\n // Issue 091: the \"unified\" onStreamStatus was only wired to direct\n // stream events. Managed stream events (stopped, error, active from\n // Cloudflare keep-alive timeout, battery death, etc.) went to a\n // separate \"managed_stream_status\" event that this handler never heard.\n this.deps.addSubscription(StreamType.STREAM_STATUS);\n this.deps.addSubscription(StreamType.MANAGED_STREAM_STATUS);\n this.events.on(\"stream_status\", handler);\n this.events.on(\"managed_stream_status\", handler);\n\n return () => {\n this.events.off(\"stream_status\", handler);\n this.events.off(\"managed_stream_status\", handler);\n this.deps.removeSubscription(StreamType.STREAM_STATUS);\n this.deps.removeSubscription(StreamType.MANAGED_STREAM_STATUS);\n };\n }\n\n isCurrentlyStreaming(): boolean {\n return this.isStreaming || this.isManagedStreaming;\n }\n\n getCurrentStreamUrl(): string | undefined {\n return this.currentStreamUrl;\n }\n\n getStreamStatus(): StreamStatus | undefined {\n return this.currentStreamState;\n }\n\n getStreamUrls(): StreamResult | undefined {\n return this.currentManagedStreamUrls;\n }\n\n // ── Direct streaming (glasses → URL, no relay) ───────────────────────────\n\n private async _startDirectStream(opts: StreamOptions): Promise<void> {\n const url = opts.direct!;\n\n if (\n !url.startsWith(\"rtmp://\") &&\n !url.startsWith(\"rtmps://\") &&\n !url.startsWith(\"srt://\") &&\n !url.startsWith(\"https://\") &&\n !url.startsWith(\"http://\")\n ) {\n throw new Error(\"Invalid stream URL: must start with rtmp://, rtmps://, srt://, https://, or http://\");\n }\n\n // Only check streams WE started, not orphaned streams from a previous session.\n // isStreaming is only set when _startDirectStream sends a STREAM_REQUEST.\n // It's NOT set by incoming status events.\n if (this.isStreaming || this.isManagedStreaming) {\n throw new Error(\"Already streaming. Stop the current stream before starting a new one.\");\n }\n\n this.currentStreamUrl = url;\n this.deps.sendMessage({\n type: AppToCloudMessageType.STREAM_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamUrl: url,\n video: opts.video,\n audio: opts.audio,\n stream: opts.stream,\n sound: opts.sound,\n timestamp: new Date(),\n });\n this.isStreaming = true;\n }\n\n // ── Managed streaming (glasses → cloud relay → viewers/destinations) ─────\n\n private async _startManagedStream(opts: StreamOptions): Promise<StreamResult> {\n // Only check streams WE started, not orphaned streams from a previous session.\n if (this.isStreaming || this.isManagedStreaming) {\n throw new Error(\"Already streaming. Stop the current stream before starting a new one.\");\n }\n\n // Convert destinations to restreamDestinations format\n const restreamDestinations: RestreamDestination[] | undefined = opts.destinations?.map((url) => ({ url }));\n\n this.deps.sendMessage({\n type: AppToCloudMessageType.MANAGED_STREAM_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n quality: opts.quality,\n enableWebRTC: opts.enableWebRTC ?? true,\n video: opts.video,\n audio: opts.audio,\n stream: opts.stream,\n restreamDestinations,\n sound: opts.sound,\n timestamp: new Date(),\n });\n this.isManagedStreaming = true;\n\n return new Promise<StreamResult>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n if (this.pendingManagedStreamRequest?.timeoutId === timeoutId) {\n this.pendingManagedStreamRequest = undefined;\n this.isManagedStreaming = false;\n reject(new Error(\"Managed stream request timeout\"));\n }\n }, MANAGED_STREAM_TIMEOUT_MS);\n\n this.pendingManagedStreamRequest = { resolve, reject, timeoutId };\n });\n }\n\n // ── Deprecated methods (backward compat) ─────────────────────────────────\n\n /** @deprecated Use startStream({ direct: url }) instead */\n async startDirectStream(options: RtmpStreamOptions): Promise<void> {\n return this._startDirectStream({\n direct: options.rtmpUrl,\n video: options.video,\n audio: options.audio,\n stream: options.stream,\n sound: options.sound,\n });\n }\n\n /** @deprecated Use startStream() or startStream({ destinations: [...] }) instead */\n async startManagedStream(options: ManagedStreamOptions = {}): Promise<StreamResult> {\n return this._startManagedStream({\n quality: options.quality,\n enableWebRTC: options.enableWebRTC,\n video: options.video,\n audio: options.audio,\n stream: options.stream,\n destinations: options.restreamDestinations?.map((d) => d.url),\n sound: options.sound,\n });\n }\n\n /** @deprecated Use stopStream() instead */\n async stopManagedStream(): Promise<void> {\n return this.stopStream();\n }\n\n /** @deprecated Use onStreamStatus() instead */\n onManagedStreamStatus(handler: (status: ManagedStreamStatus) => void): () => void {\n this.deps.addSubscription(StreamType.MANAGED_STREAM_STATUS);\n this.events.on(\"managed_stream_status\", handler);\n\n return () => {\n this.events.off(\"managed_stream_status\", handler);\n this.deps.removeSubscription(StreamType.MANAGED_STREAM_STATUS);\n };\n }\n\n /** @deprecated Use isCurrentlyStreaming() instead */\n isManagedStreamActive(): boolean {\n return this.isManagedStreaming;\n }\n\n /** @deprecated Use getStreamUrls() instead */\n getManagedStreamUrls(): StreamResult | undefined {\n return this.currentManagedStreamUrls;\n }\n\n getManagedStreamStatus(): ManagedStreamStatus | undefined {\n return this.managedStreamStatus;\n }\n\n async checkExistingStream(): Promise<ExistingStreamInfo> {\n return new Promise<ExistingStreamInfo>((resolve) => {\n const requestId = generateRequestId(\"stream_check\");\n const timeoutId = setTimeout(() => {\n this.pendingStreamChecks.delete(requestId);\n resolve({ hasActiveStream: false });\n }, STREAM_CHECK_TIMEOUT_MS);\n\n this.pendingStreamChecks.set(requestId, { resolve, timeoutId });\n\n this.deps.sendMessage({\n type: AppToCloudMessageType.STREAM_STATUS_CHECK,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n });\n });\n }\n\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n handlePhotoResponse(message: any): void {\n const requestId: string | undefined = message?.requestId;\n if (!requestId) {\n this.deps.logger.warn(\"[CameraManager] Received PHOTO_RESPONSE without requestId:\", message);\n return;\n }\n\n const pending = this.pendingRequests.get(requestId);\n if (!pending) {\n this.deps.logger.debug(`[CameraManager] No pending request for requestId=\"${requestId}\" — ignoring.`);\n return;\n }\n\n clearTimeout(pending.timer);\n this.pendingRequests.delete(requestId);\n\n if (message.error?.code === \"permission_denied\") {\n this._hasPermission = false;\n }\n\n if (message.success === false) {\n const errorMsg = message.error?.message ?? message.error?.code ?? \"Photo capture failed\";\n pending.reject(new Error(errorMsg));\n return;\n }\n\n pending.resolve({\n url: message.photoUrl ?? \"\",\n width: message.width ?? 0,\n height: message.height ?? 0,\n timestamp: message.timestamp ? new Date(message.timestamp).getTime() : Date.now(),\n savedToGallery: message.savedToGallery ?? false,\n });\n }\n\n private handleStreamStatus(message: StreamStatus): void {\n this.currentStreamState = {\n ...message,\n timestamp: message.timestamp ? new Date(message.timestamp) : new Date(),\n };\n\n // Only update isStreaming for streams WE initiated (isStreaming is set to true\n // in _startDirectStream). Don't let orphaned stream status events from a\n // previous session set isStreaming — that blocks new streams from starting.\n if (this.isStreaming) {\n if (message.status === \"stopped\" || message.status === \"error\" || message.status === \"timeout\") {\n this.isStreaming = false;\n this.currentStreamUrl = undefined;\n }\n }\n\n this.events.emit(\"stream_status\", this.currentStreamState);\n }\n\n private handleManagedStreamStatus(status: ManagedStreamStatus): void {\n this.managedStreamStatus = status;\n\n if (status.status === \"initializing\" && status.streamId) {\n this.isManagedStreaming = true;\n this.currentManagedStreamId = status.streamId;\n }\n\n if (status.status === \"active\") {\n this.isManagedStreaming = true;\n this.currentManagedStreamId = status.streamId;\n\n if (status.hlsUrl && status.dashUrl) {\n const result: ManagedStreamResult = {\n hlsUrl: status.hlsUrl,\n dashUrl: status.dashUrl,\n webrtcUrl: status.webrtcUrl,\n previewUrl: status.previewUrl,\n thumbnailUrl: status.thumbnailUrl,\n streamId: status.streamId ?? \"\",\n };\n\n this.currentManagedStreamUrls = result;\n\n if (this.pendingManagedStreamRequest) {\n clearTimeout(this.pendingManagedStreamRequest.timeoutId);\n this.pendingManagedStreamRequest.resolve(result);\n this.pendingManagedStreamRequest = undefined;\n }\n }\n }\n\n if (status.status === \"error\" || status.status === \"stopped\") {\n if (this.pendingManagedStreamRequest) {\n clearTimeout(this.pendingManagedStreamRequest.timeoutId);\n this.pendingManagedStreamRequest.reject(new Error(status.message || \"Managed stream failed\"));\n this.pendingManagedStreamRequest = undefined;\n }\n\n this.isManagedStreaming = false;\n this.currentManagedStreamId = undefined;\n this.currentManagedStreamUrls = undefined;\n }\n\n this.events.emit(\"managed_stream_status\", status);\n }\n\n private handleStreamCheckResponse(response: StreamStatusCheckResponse): void {\n // Match by requestId from the response — don't blindly pop the first entry.\n // This prevents concurrent checkExistingStream() calls from resolving the wrong promise.\n const requestId = (response as any).requestId;\n const pending = requestId ? this.pendingStreamChecks.get(requestId) : undefined;\n\n // Fallback: if the cloud doesn't include requestId, pop the first entry (v2 behavior)\n if (!pending) {\n const firstEntry = this.pendingStreamChecks.entries().next();\n if (firstEntry.done || !firstEntry.value) {\n return;\n }\n const [fallbackId, fallbackPending] = firstEntry.value;\n clearTimeout(fallbackPending.timeoutId);\n this.pendingStreamChecks.delete(fallbackId);\n fallbackPending.resolve({\n hasActiveStream: response.hasActiveStream,\n streamInfo: response.streamInfo\n ? {\n ...response.streamInfo,\n createdAt: new Date(response.streamInfo.createdAt),\n }\n : undefined,\n });\n return;\n }\n\n clearTimeout(pending.timeoutId);\n this.pendingStreamChecks.delete(requestId!);\n pending.resolve({\n hasActiveStream: response.hasActiveStream,\n streamInfo: response.streamInfo\n ? {\n ...response.streamInfo,\n createdAt: new Date(response.streamInfo.createdAt),\n }\n : undefined,\n });\n }\n\n destroy(): void {\n for (const [requestId, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(`CameraManager destroyed — session disconnected (${requestId})`));\n }\n this.pendingRequests.clear();\n\n for (const [requestId, pending] of this.pendingStreamChecks) {\n clearTimeout(pending.timeoutId);\n pending.resolve({ hasActiveStream: false });\n this.pendingStreamChecks.delete(requestId);\n }\n\n if (this.pendingManagedStreamRequest) {\n clearTimeout(this.pendingManagedStreamRequest.timeoutId);\n this.pendingManagedStreamRequest.reject(new Error(\"CameraManager destroyed — session disconnected\"));\n this.pendingManagedStreamRequest = undefined;\n }\n\n for (const cleanup of this.handlerCleanups) {\n cleanup();\n }\n this.handlerCleanups.length = 0;\n\n this.events.removeAllListeners();\n this.currentStreamState = undefined;\n this.currentStreamUrl = undefined;\n this.isStreaming = false;\n this.managedStreamStatus = undefined;\n this.currentManagedStreamId = undefined;\n this.currentManagedStreamUrls = undefined;\n this.isManagedStreaming = false;\n }\n}\n",
|
|
25
25
|
"/**\n * 📊 DashboardManager — v3 SDK Dashboard Content API\n *\n * Thin wrapper that sends dashboard content updates to the cloud.\n * Provides a simplified two-method API: {@link showText} and {@link clear}.\n *\n * Wire format is identical to v2 DashboardContentManager:\n * ```json\n * {\n * \"type\": \"dashboard_content_update\",\n * \"packageName\": \"<packageName>\",\n * \"sessionId\": \"<sessionId>-<packageName>\",\n * \"content\": \"<text>\",\n * \"modes\": [\"main\"],\n * \"timestamp\": \"<ISO date>\"\n * }\n * ```\n *\n * The `sessionId` field in dashboard messages uses the composite format\n * `\"<sessionId>-<packageName>\"` to match the v2 wire format exactly.\n *\n * @module\n */\n\nimport { AppToCloudMessageType } from \"../../types/message-types\";\nimport { DashboardMode, DashboardContentUpdate } from \"../../types/dashboard\";\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * Structural type — no concrete imports so the manager stays unit-testable\n * with plain stubs.\n */\nexport interface DashboardManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Add a subscription string (triggers SUBSCRIPTION_UPDATE to cloud). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Package name for outgoing messages. */\n getPackageName: () => string;\n /** Current session ID. */\n getSessionId: () => string;\n}\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Controls the dashboard content displayed for this app on the user's glasses.\n *\n * Dashboard content is a text overlay shown in the main dashboard view.\n * The {@link showText} method sends content targeting the `MAIN` dashboard\n * mode by default. Use {@link clear} to remove any displayed content.\n *\n * All methods are fire-and-forget — the messages are sent immediately and\n * no response is awaited.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Show a single line of text\n * session.dashboard.showText(\"Meeting in 5 minutes\");\n *\n * // Show multiple lines\n * session.dashboard.showText([\"Line 1\", \"Line 2\", \"Line 3\"]);\n *\n * // Clear the dashboard\n * session.dashboard.clear();\n * ```\n */\nexport class DashboardManager {\n private readonly deps: DashboardManagerDeps;\n\n constructor(deps: DashboardManagerDeps) {\n this.deps = deps;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Show text content on the dashboard.\n *\n * Sends a `dashboard_content_update` message targeting the `MAIN`\n * dashboard mode. Accepts either a single string or an array of\n * pre-wrapped lines — when an array is provided the lines are joined\n * with newlines before sending.\n *\n * @param text - A string or array of strings to display on the dashboard.\n *\n * @example\n * ```ts\n * // Single string\n * session.dashboard.showText(\"Status: Connected\");\n *\n * // Pre-wrapped lines\n * session.dashboard.showText([\n * \"Temperature: 72°F\",\n * \"Humidity: 45%\",\n * \"Wind: 5 mph\",\n * ]);\n * ```\n */\n showText(text: string | string[]): void {\n const content = Array.isArray(text) ? text.join(\"\\n\") : text;\n\n const message: DashboardContentUpdate = {\n type: AppToCloudMessageType.DASHBOARD_CONTENT_UPDATE,\n packageName: this.deps.getPackageName(),\n sessionId: `${this.deps.getSessionId()}-${this.deps.getPackageName()}`,\n content,\n modes: [DashboardMode.MAIN],\n timestamp: new Date(),\n };\n\n this.deps.sendMessage(message);\n\n this.deps.logger.debug({ contentLength: content.length }, \"📊 Dashboard content update sent\");\n }\n\n /**\n * Clear the dashboard content.\n *\n * Sends an empty `dashboard_content_update` message targeting the\n * `MAIN` dashboard mode, which removes any currently displayed content\n * for this app.\n *\n * @example\n * ```ts\n * session.dashboard.clear();\n * ```\n */\n clear(): void {\n const message: DashboardContentUpdate = {\n type: AppToCloudMessageType.DASHBOARD_CONTENT_UPDATE,\n packageName: this.deps.getPackageName(),\n sessionId: `${this.deps.getSessionId()}-${this.deps.getPackageName()}`,\n content: \"\",\n modes: [DashboardMode.MAIN],\n timestamp: new Date(),\n };\n\n this.deps.sendMessage(message);\n\n this.deps.logger.debug(\"📊 Dashboard content cleared\");\n }\n\n // ─── Cleanup ────────────────────────────────────────────────────────────\n\n /**\n * Clean up resources.\n *\n * Called by MentraSession during disconnect/cleanup. Dashboard commands\n * are fire-and-forget so there is no pending state to drain.\n *\n * @internal\n */\n destroy(): void {\n this.deps.logger.debug(\"[DashboardManager] Destroyed.\");\n }\n}\n",
|
|
26
26
|
"/**\n * Observable<T> - A reactive value wrapper that notifies listeners of changes\n *\n * Provides synchronous value access and reactive subscriptions via onChange().\n * Supports implicit coercion for use in conditionals and comparisons.\n *\n * @example\n * ```typescript\n * const wifiStatus = new Observable(false);\n *\n * // Synchronous read\n * console.log(wifiStatus.value); // false\n *\n * // Implicit coercion\n * if (wifiStatus) { ... } // Works via valueOf()\n *\n * // Reactive subscription\n * const cleanup = wifiStatus.onChange((connected) => {\n * console.log(\"WiFi:\", connected);\n * });\n *\n * // Update (triggers callbacks)\n * wifiStatus.setValue(true);\n *\n * // Cleanup\n * cleanup();\n * ```\n */\nexport class Observable<T> {\n private _value: T;\n private _listeners: Set<(value: T) => void> = new Set();\n private _initialized: boolean = false; // Track if value has been set from WebSocket\n\n constructor(initialValue: T) {\n this._value = initialValue;\n }\n\n /**\n * Get the current value synchronously\n */\n get value(): T {\n return this._value;\n }\n\n /**\n * Implicit coercion to primitive value (for conditionals/comparisons)\n */\n valueOf(): T {\n return this._value;\n }\n\n /**\n * String representation\n */\n toString(): string {\n return String(this._value);\n }\n\n /**\n * Symbol.toPrimitive for implicit type coercion\n * Allows usage in conditionals: if (observable) { ... }\n */\n [Symbol.toPrimitive](hint: string): T | string {\n if (hint === 'string') {\n return String(this._value);\n }\n return this._value;\n }\n\n /**\n * Subscribe to value changes\n *\n * The callback is called immediately with the current value ONLY if\n * the Observable has been initialized (setValue() called at least once).\n * This prevents callbacks from firing with default/uninitialized values.\n *\n * @param callback - Function to call when value changes\n * @returns Cleanup function to unsubscribe\n *\n * @example\n * ```typescript\n * const cleanup = observable.onChange((value) => {\n * console.log(\"New value:\", value);\n * });\n *\n * // Later: unsubscribe\n * cleanup();\n * ```\n */\n onChange(callback: (value: T) => void): () => void {\n this._listeners.add(callback);\n // Call immediately with current value ONLY if initialized\n if (this._initialized) {\n callback(this._value);\n }\n // Return cleanup function\n return () => this._listeners.delete(callback);\n }\n\n /**\n * Update the value and notify listeners\n *\n * Triggers callbacks if:\n * 1. This is the first setValue() call (initialization from WebSocket), OR\n * 2. The new value is different from current value\n *\n * Uses strict equality (===) for comparison.\n *\n * @param value - New value to set\n *\n * @internal This method is called by DeviceState when receiving WebSocket updates\n */\n setValue(value: T): void {\n const isFirstInit = !this._initialized;\n\n // Mark as initialized (first setValue call from WebSocket)\n if (isFirstInit) {\n this._initialized = true;\n }\n\n // Notify listeners if this is initialization OR value changed\n if (isFirstInit || this._value !== value) {\n this._value = value;\n // Notify all listeners\n this._listeners.forEach((cb) => {\n try {\n cb(value);\n } catch (error) {\n console.error('Error in Observable onChange callback:', error);\n }\n });\n }\n }\n\n /**\n * Get the number of active listeners\n * @internal Used for debugging/testing\n */\n get listenerCount(): number {\n return this._listeners.size;\n }\n}\n",
|
|
27
|
-
"/**\n * DeviceManager — Consolidated Device State, Hardware Events & Capabilities\n *\n * Owns all device-related concerns for a MentraSession:\n *\n * - **Reactive state** — Observable properties for connection, battery, WiFi,\n * hotspot, and case status (mirrors the legacy DeviceState pattern).\n * - **Hardware events** — Button presses, head position, touch gestures,\n * battery updates, and VPS coordinates, all routed from the DataStreamRouter.\n * - **Capabilities** — Device capability profile received at connection time\n * and updated mid-session when the glasses model changes.\n * - **Actions** — Outbound commands like `requestWifiSetup`.\n *\n * All handler registrations return a cleanup function. Subscriptions are\n * managed automatically — `addSubscription` is called when the first handler\n * for a stream is registered, and `removeSubscription` when the last is removed.\n *\n * @example\n * ```ts\n * // Reactive state\n * device.state.batteryLevel.onChange((level) => {\n * console.log(\"Battery:\", level, \"%\");\n * });\n *\n * // Hardware events\n * const stop = device.onButtonPress((e) => {\n * console.log(e.buttonId, e.pressType);\n * });\n *\n * // Filtered touch events\n * device.onTouchEvent(\"double_tap\", (e) => {\n * console.log(\"Double tap!\", e);\n * });\n *\n * // Capabilities\n * device.onCapabilitiesChange((caps) => {\n * console.log(\"Device supports camera:\", !!caps?.camera);\n * });\n *\n * // Actions\n * device.requestWifiSetup(\"App needs internet for sync\");\n *\n * // Cleanup\n * stop();\n * ```\n *\n * @module\n */\n\nimport { Observable } from \"../../utils/Observable\";\nimport { StreamType } from \"../../types/streams\";\nimport type { PermissionsManager } from \"./PermissionsManager\";\n\n// ─── Event Types ────────────────────────────────────────────────────────────\n\n/**\n * Button press event from the glasses hardware.\n */\nexport interface ButtonPressEvent {\n /** Identifier of the button that was pressed. */\n buttonId: string;\n /** Whether the press was short or long. */\n pressType: \"short\" | \"long\";\n}\n\n/**\n * Head position event from the IMU.\n */\nexport interface HeadPositionEvent {\n /** Current head position. */\n position: \"up\" | \"down\";\n}\n\n/**\n * Normalised touch/gesture event from the glasses touchpad.\n *\n * Raw wire fields (`gesture_name`, `device_model`) are normalised to\n * `gesture` and `model` for a cleaner developer experience.\n */\nexport interface TouchEventData {\n /** Normalised gesture name (e.g. \"double_tap\", \"forward_swipe\"). */\n gesture: string;\n /** Normalised device model name. */\n model: string;\n /** Timestamp of the gesture. */\n timestamp: Date | string;\n /** The original raw data, preserved for advanced use cases. */\n [key: string]: any;\n}\n\n/**\n * Glasses battery update event.\n */\nexport interface BatteryUpdateEvent {\n /** Battery level 0–100. */\n level: number;\n /** Whether the glasses are currently charging. */\n charging: boolean;\n /** Estimated minutes remaining (if available). */\n timeRemaining?: number;\n}\n\n// ─── Dependency Types ───────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession into the DeviceManager.\n */\nexport interface DeviceManagerDeps {\n /** DataStreamRouter — register for stream-type events. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Subscribe to a data stream (sent to cloud). */\n addSubscription: (stream: string) => void;\n /** Unsubscribe from a data stream. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary message to the cloud. */\n sendMessage: (message: any) => void;\n /** Session-scoped logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Returns the current app's package name. */\n getPackageName: () => string;\n /** Returns the active session ID. */\n getSessionId: () => string;\n /** PermissionsManager for gating protected streams. */\n permissions: PermissionsManager;\n}\n\n// ─── Reactive Device State ──────────────────────────────────────────────────\n\n/**\n * Read-only reactive device state container.\n *\n * Every property is an {@link Observable} — call `.value` for synchronous\n * reads or `.onChange(cb)` for reactive subscriptions.\n */\nexport interface DeviceStateShape {\n readonly connected: Observable<boolean>;\n readonly modelName: Observable<string | null>;\n readonly batteryLevel: Observable<number | null>;\n readonly charging: Observable<boolean | null>;\n readonly caseBatteryLevel: Observable<number | null>;\n readonly caseCharging: Observable<boolean | null>;\n readonly caseOpen: Observable<boolean | null>;\n readonly caseRemoved: Observable<boolean | null>;\n readonly wifiConnected: Observable<boolean>;\n readonly wifiSsid: Observable<string | null>;\n readonly wifiLocalIp: Observable<string | null>;\n readonly hotspotEnabled: Observable<boolean | null>;\n readonly hotspotSsid: Observable<string | null>;\n}\n\n// ─── Internal Helpers ───────────────────────────────────────────────────────\n\n/**\n * Normalise raw touch event data from the wire format.\n *\n * - `gesture_name` → `gesture`\n * - `device_model` → `model`\n */\nfunction normaliseTouchEvent(raw: any): TouchEventData {\n return {\n ...raw,\n gesture: raw.gesture_name ?? raw.gesture ?? \"unknown\",\n model: raw.device_model ?? raw.model ?? \"unknown\",\n timestamp: raw.timestamp ?? new Date().toISOString(),\n };\n}\n\n// ─── DeviceManager ──────────────────────────────────────────────────────────\n\n/**\n * Manages all device-related state, hardware events, capabilities, and actions.\n *\n * Created by MentraSession and exposed as `session.device`.\n */\nexport class DeviceManager {\n // ─── Reactive State ───────────────────────────────────────────────────\n\n /** Reactive device state observables. */\n readonly state: DeviceStateShape;\n\n // ─── Capabilities ─────────────────────────────────────────────────────\n\n /** Current device capabilities (set from CONNECTION_ACK). */\n capabilities: any = null;\n\n // ─── Private ──────────────────────────────────────────────────────────\n\n private deps: DeviceManagerDeps;\n private permissions: PermissionsManager;\n\n /** Internal mutable references to observables (state exposes them read-only). */\n private readonly _connected: Observable<boolean>;\n private readonly _modelName: Observable<string | null>;\n private readonly _batteryLevel: Observable<number | null>;\n private readonly _charging: Observable<boolean | null>;\n private readonly _caseBatteryLevel: Observable<number | null>;\n private readonly _caseCharging: Observable<boolean | null>;\n private readonly _caseOpen: Observable<boolean | null>;\n private readonly _caseRemoved: Observable<boolean | null>;\n private readonly _wifiConnected: Observable<boolean>;\n private readonly _wifiSsid: Observable<string | null>;\n private readonly _wifiLocalIp: Observable<string | null>;\n private readonly _hotspotEnabled: Observable<boolean | null>;\n private readonly _hotspotSsid: Observable<string | null>;\n\n /** Capabilities-change listeners. */\n private capabilitiesListeners: Set<(caps: any) => void> = new Set();\n\n /**\n * Ref-counted handler bookkeeping per stream key.\n *\n * Tracks the number of active handlers for each stream so that\n * `addSubscription` / `removeSubscription` are called exactly once\n * when the first handler is added / last handler is removed.\n */\n private handlerCounts: Map<string, number> = new Map();\n\n /** Cleanup functions returned by router/messageHandlers registrations. */\n private cleanups: Array<() => void> = [];\n\n constructor(deps: DeviceManagerDeps) {\n this.deps = deps;\n this.permissions = deps.permissions;\n\n // ── Initialise Observables ────────────────────────────────────────\n this._connected = new Observable<boolean>(false);\n this._modelName = new Observable<string | null>(null);\n this._batteryLevel = new Observable<number | null>(null);\n this._charging = new Observable<boolean | null>(null);\n this._caseBatteryLevel = new Observable<number | null>(null);\n this._caseCharging = new Observable<boolean | null>(null);\n this._caseOpen = new Observable<boolean | null>(null);\n this._caseRemoved = new Observable<boolean | null>(null);\n this._wifiConnected = new Observable<boolean>(false);\n this._wifiSsid = new Observable<string | null>(null);\n this._wifiLocalIp = new Observable<string | null>(null);\n this._hotspotEnabled = new Observable<boolean | null>(null);\n this._hotspotSsid = new Observable<string | null>(null);\n\n // Expose as read-only shape\n this.state = {\n connected: this._connected,\n modelName: this._modelName,\n batteryLevel: this._batteryLevel,\n charging: this._charging,\n caseBatteryLevel: this._caseBatteryLevel,\n caseCharging: this._caseCharging,\n caseOpen: this._caseOpen,\n caseRemoved: this._caseRemoved,\n wifiConnected: this._wifiConnected,\n wifiSsid: this._wifiSsid,\n wifiLocalIp: this._wifiLocalIp,\n hotspotEnabled: this._hotspotEnabled,\n hotspotSsid: this._hotspotSsid,\n };\n\n // ── Register message handlers ─────────────────────────────────────\n this.cleanups.push(\n deps.messageHandlers.register(\"device_state_update\", (msg: any) => {\n this.handleDeviceStateUpdate(msg);\n }),\n );\n this.cleanups.push(\n deps.messageHandlers.register(\"capabilities_update\", (msg: any) => {\n this.handleCapabilitiesUpdate(msg);\n }),\n );\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Hardware Events\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Listen for physical button press events on the glasses.\n *\n * @param handler - Called with {@link ButtonPressEvent} for every press\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = device.onButtonPress((e) => {\n * if (e.pressType === \"long\") {\n * console.log(\"Long press on\", e.buttonId);\n * }\n * });\n * ```\n */\n onButtonPress(handler: (event: ButtonPressEvent) => void): () => void {\n return this.addStreamHandler(StreamType.BUTTON_PRESS, (_st, data) => {\n handler({\n buttonId: data.buttonId ?? data.button_id ?? \"unknown\",\n pressType: data.pressType ?? data.press_type ?? \"short\",\n });\n });\n }\n\n /**\n * Listen for head position (up/down) events from the IMU.\n *\n * @param handler - Called with {@link HeadPositionEvent} on position change\n * @returns Cleanup function to remove the handler\n */\n onHeadPosition(handler: (event: HeadPositionEvent) => void): () => void {\n return this.addStreamHandler(StreamType.HEAD_POSITION, (_st, data) => {\n handler({\n position: data.position ?? \"down\",\n });\n });\n }\n\n /**\n * Listen for touch/gesture events from the glasses touchpad.\n *\n * Overloaded:\n * - `onTouchEvent(handler)` — all touch events\n * - `onTouchEvent(gesture, handler)` — only events matching the given gesture\n *\n * @param gestureOrHandler - A gesture name string, or a handler for all events\n * @param handler - Handler when the first argument is a gesture name\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * // All gestures\n * device.onTouchEvent((e) => console.log(e.gesture));\n *\n * // Specific gesture\n * device.onTouchEvent(\"double_tap\", (e) => console.log(\"Double tap!\"));\n * ```\n */\n onTouchEvent(handler: (event: TouchEventData) => void): () => void;\n onTouchEvent(gesture: string, handler: (event: TouchEventData) => void): () => void;\n onTouchEvent(\n gestureOrHandler: string | ((event: TouchEventData) => void),\n handler?: (event: TouchEventData) => void,\n ): () => void {\n if (typeof gestureOrHandler === \"function\") {\n // Subscribe to all touch events\n return this.addStreamHandler(StreamType.TOUCH_EVENT, (_st, data) => {\n gestureOrHandler(normaliseTouchEvent(data));\n });\n }\n\n // Subscribe to a specific gesture via \"touch_event:{gesture}\" stream key\n const gesture = gestureOrHandler;\n const gestureStream = `${StreamType.TOUCH_EVENT}:${gesture}`;\n return this.addStreamHandler(gestureStream, (_st, data) => {\n handler!(normaliseTouchEvent(data));\n });\n }\n\n /**\n * Subscribe to multiple touch gestures at once.\n *\n * Registers a handler for each gesture and returns a single cleanup\n * function that removes all of them.\n *\n * @param gestures - Array of gesture names (e.g. `[\"double_tap\", \"forward_swipe\"]`)\n * @returns Cleanup function that removes all gesture subscriptions\n *\n * @example\n * ```ts\n * const stop = device.subscribeToGestures([\"single_tap\", \"double_tap\", \"forward_swipe\"]);\n * // Later:\n * stop();\n * ```\n */\n subscribeToGestures(gestures: string[]): () => void {\n const cleanupFns: Array<() => void> = [];\n\n for (const gesture of gestures) {\n const gestureStream = `${StreamType.TOUCH_EVENT}:${gesture}`;\n\n // Register a no-op handler to establish the subscription.\n // The actual events will be delivered via onTouchEvent handlers.\n const cleanup = this.addStreamHandler(gestureStream, () => {\n // Subscription placeholder — events routed via prefix match\n });\n cleanupFns.push(cleanup);\n }\n\n return () => {\n for (const fn of cleanupFns) {\n fn();\n }\n };\n }\n\n /**\n * Listen for glasses battery update events.\n *\n * Also updates the reactive `state.batteryLevel` and `state.charging` observables.\n *\n * @param handler - Called with {@link BatteryUpdateEvent} on each update\n * @returns Cleanup function to remove the handler\n */\n onBatteryUpdate(handler: (event: BatteryUpdateEvent) => void): () => void {\n return this.addStreamHandler(StreamType.GLASSES_BATTERY_UPDATE, (_st, data) => {\n // Update reactive state from the battery event\n if (data.level !== undefined) {\n this._batteryLevel.setValue(data.level);\n }\n if (data.charging !== undefined) {\n this._charging.setValue(data.charging);\n }\n\n handler({\n level: data.level ?? 0,\n charging: data.charging ?? false,\n timeRemaining: data.timeRemaining ?? data.time_remaining,\n });\n });\n }\n\n /**\n * Listen for VPS (Visual Positioning System) coordinate updates.\n *\n * @param handler - Called with raw VPS coordinate data\n * @returns Cleanup function to remove the handler\n */\n onVpsCoordinates(handler: (event: any) => void): () => void {\n return this.addStreamHandler(StreamType.VPS_COORDINATES, (_st, data) => {\n handler(data);\n });\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Actions\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Request the user to set up WiFi on their glasses.\n *\n * Sends a `request_wifi_setup` message to the cloud, which prompts\n * the companion app to display a WiFi configuration flow.\n *\n * @param reason - Optional human-readable reason shown to the user\n *\n * @example\n * ```ts\n * device.requestWifiSetup(\"This app needs WiFi for real-time sync\");\n * ```\n */\n requestWifiSetup(reason?: string): void {\n this.deps.logger.info(`DeviceManager: Requesting WiFi setup${reason ? ` — ${reason}` : \"\"}`);\n this.deps.sendMessage({\n type: \"request_wifi_setup\",\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n timestamp: new Date().toISOString(),\n ...(reason ? { reason } : {}),\n });\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Capabilities\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Subscribe to device capability changes.\n *\n * Called when capabilities are first received (CONNECTION_ACK) and\n * whenever the device model or capabilities change mid-session.\n *\n * @param handler - Called with the new capabilities object\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * device.onCapabilitiesChange((caps) => {\n * if (caps?.camera?.photo) {\n * console.log(\"Camera supports photos\");\n * }\n * });\n * ```\n */\n onCapabilitiesChange(handler: (caps: any) => void): () => void {\n this.capabilitiesListeners.add(handler);\n return () => {\n this.capabilitiesListeners.delete(handler);\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Internal — Called by MentraSession\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Handle a `device_state_update` message from the cloud.\n *\n * Updates all matching Observable properties. Only fields present in\n * the message are touched — Observables for absent fields keep their\n * current value.\n *\n * @param message - The raw device_state_update message\n * @internal\n */\n handleDeviceStateUpdate(message: any): void {\n const state = message?.state ?? message?.data ?? message;\n if (!state) {\n this.deps.logger.debug(\"DeviceManager: Received empty device_state_update\");\n return;\n }\n\n this.deps.logger.debug(\"DeviceManager: Processing device state update\");\n\n // Connection\n if (state.connected !== undefined) this._connected.setValue(state.connected);\n if (state.modelName !== undefined) this._modelName.setValue(state.modelName);\n\n // WiFi\n if (state.wifiConnected !== undefined) this._wifiConnected.setValue(state.wifiConnected);\n if (state.wifiSsid !== undefined) this._wifiSsid.setValue(state.wifiSsid ?? null);\n if (state.wifiLocalIp !== undefined) this._wifiLocalIp.setValue(state.wifiLocalIp ?? null);\n\n // Battery\n if (state.batteryLevel !== undefined) this._batteryLevel.setValue(state.batteryLevel ?? null);\n if (state.charging !== undefined) this._charging.setValue(state.charging ?? null);\n if (state.caseBatteryLevel !== undefined) this._caseBatteryLevel.setValue(state.caseBatteryLevel ?? null);\n if (state.caseCharging !== undefined) this._caseCharging.setValue(state.caseCharging ?? null);\n if (state.caseOpen !== undefined) this._caseOpen.setValue(state.caseOpen ?? null);\n if (state.caseRemoved !== undefined) this._caseRemoved.setValue(state.caseRemoved ?? null);\n\n // Hotspot\n if (state.hotspotEnabled !== undefined) this._hotspotEnabled.setValue(state.hotspotEnabled ?? null);\n if (state.hotspotSsid !== undefined) this._hotspotSsid.setValue(state.hotspotSsid ?? null);\n }\n\n /**\n * Handle a `capabilities_update` message from the cloud.\n *\n * Extracts the capabilities payload and delegates to {@link setCapabilities}.\n *\n * @param message - The raw capabilities_update message\n * @internal\n */\n handleCapabilitiesUpdate(message: any): void {\n const caps = message?.capabilities ?? message?.data?.capabilities ?? null;\n const modelName = message?.modelName ?? message?.data?.modelName ?? null;\n\n if (modelName) {\n this._modelName.setValue(modelName);\n }\n\n this.setCapabilities(caps);\n }\n\n /**\n * Directly set the device capabilities.\n *\n * Called by MentraSession from the CONNECTION_ACK payload, or by\n * {@link handleCapabilitiesUpdate} for mid-session updates.\n *\n * @param caps - The capabilities object (or null)\n * @internal\n */\n setCapabilities(caps: any): void {\n this.capabilities = caps;\n this.deps.logger.info(`DeviceManager: Capabilities ${caps ? \"updated\" : \"cleared\"}`);\n\n // Notify listeners\n for (const listener of this.capabilitiesListeners) {\n try {\n listener(caps);\n } catch (err) {\n this.deps.logger.error(\n `DeviceManager: Error in capabilities listener: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n /**\n * Remove all tracked handlers and clear listeners.\n *\n * Called by MentraSession during disconnect/cleanup.\n *\n * @internal\n */\n destroy(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n\n this.cleanups.length = 0;\n this.handlerCounts.clear();\n this.capabilitiesListeners.clear();\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Private — Stream Handler Management\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Register a handler on the DataStreamRouter for a given stream key,\n * managing subscription lifecycle automatically.\n *\n * - Calls `deps.addSubscription` when the first handler for a key is added.\n * - Calls `deps.removeSubscription` when the last handler for a key is removed.\n *\n * @param streamKey - The stream type or prefixed stream key\n * @param handler - The stream handler function\n * @returns Cleanup function that unregisters the handler and manages subscription\n */\n private addStreamHandler(\n streamKey: string,\n handler: (streamType: string, data: any, message: any) => void,\n ): () => void {\n const currentCount = this.handlerCounts.get(streamKey) ?? 0;\n\n // First handler for this stream — subscribe\n if (currentCount === 0) {\n this.deps.addSubscription(streamKey);\n }\n this.handlerCounts.set(streamKey, currentCount + 1);\n\n // Register on the router\n const routerCleanup = this.deps.router.on(streamKey, handler);\n\n // Track for bulk cleanup\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n\n // Remove from router\n routerCleanup();\n\n // Decrement handler count\n const count = this.handlerCounts.get(streamKey) ?? 0;\n const newCount = count - 1;\n if (newCount <= 0) {\n this.handlerCounts.delete(streamKey);\n this.deps.removeSubscription(streamKey);\n } else {\n this.handlerCounts.set(streamKey, newCount);\n }\n };\n\n this.cleanups.push(cleanup);\n return cleanup;\n }\n}\n",
|
|
27
|
+
"/**\n * DeviceManager — Consolidated Device State, Hardware Events & Capabilities\n *\n * Owns all device-related concerns for a MentraSession:\n *\n * - **Reactive state** — Observable properties for connection, battery, WiFi,\n * hotspot, and case status (mirrors the legacy DeviceState pattern).\n * - **Hardware events** — Button presses, head position, touch gestures,\n * battery updates, and VPS coordinates, all routed from the DataStreamRouter.\n * - **Capabilities** — Device capability profile received at connection time\n * and updated mid-session when the glasses model changes.\n * - **Actions** — Outbound commands like `requestWifiSetup`.\n *\n * All handler registrations return a cleanup function. Subscriptions are\n * managed automatically — `addSubscription` is called when the first handler\n * for a stream is registered, and `removeSubscription` when the last is removed.\n *\n * @example\n * ```ts\n * // Reactive state\n * device.state.batteryLevel.onChange((level) => {\n * console.log(\"Battery:\", level, \"%\");\n * });\n *\n * // Hardware events\n * const stop = device.onButtonPress((e) => {\n * console.log(e.buttonId, e.pressType);\n * });\n *\n * // Filtered touch events\n * device.onTouchEvent(\"double_tap\", (e) => {\n * console.log(\"Double tap!\", e);\n * });\n *\n * // Capabilities\n * device.onCapabilitiesChange((caps) => {\n * console.log(\"Device supports camera:\", !!caps?.camera);\n * });\n *\n * // Actions\n * device.requestWifiSetup(\"App needs internet for sync\");\n *\n * // Cleanup\n * stop();\n * ```\n *\n * @module\n */\n\nimport { Observable } from \"../../utils/Observable\";\nimport { StreamType } from \"../../types/streams\";\nimport type { PermissionsManager } from \"./PermissionsManager\";\n\n// ─── Event Types ────────────────────────────────────────────────────────────\n\n/**\n * Button press event from the glasses hardware.\n */\nexport interface ButtonPressEvent {\n /** Identifier of the button that was pressed. */\n buttonId: string;\n /** Whether the press was short or long. */\n pressType: \"short\" | \"long\";\n}\n\n/**\n * Head position event from the IMU.\n */\nexport interface HeadPositionEvent {\n /** Current head position. */\n position: \"up\" | \"down\";\n}\n\n/**\n * Normalised touch/gesture event from the glasses touchpad.\n *\n * Raw wire fields (`gesture_name`, `device_model`) are normalised to\n * `gesture` and `model` for a cleaner developer experience.\n */\nexport interface TouchEventData {\n /** Normalised gesture name (e.g. \"double_tap\", \"forward_swipe\"). */\n gesture: string;\n /** Normalised device model name. */\n model: string;\n /** Timestamp of the gesture. */\n timestamp: Date | string;\n /** The original raw data, preserved for advanced use cases. */\n [key: string]: any;\n}\n\n/**\n * Glasses battery update event.\n */\nexport interface BatteryUpdateEvent {\n /** Battery level 0–100. */\n level: number;\n /** Whether the glasses are currently charging. */\n charging: boolean;\n /** Estimated minutes remaining (if available). */\n timeRemaining?: number;\n}\n\n// ─── Dependency Types ───────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession into the DeviceManager.\n */\nexport interface DeviceManagerDeps {\n /** DataStreamRouter — register for stream-type events. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Subscribe to a data stream (sent to cloud). */\n addSubscription: (stream: string) => void;\n /** Unsubscribe from a data stream. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary message to the cloud. */\n sendMessage: (message: any) => void;\n /** Session-scoped logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Returns the current app's package name. */\n getPackageName: () => string;\n /** Returns the active session ID. */\n getSessionId: () => string;\n /** PermissionsManager for gating protected streams. */\n permissions: PermissionsManager;\n}\n\n// ─── Reactive Device State ──────────────────────────────────────────────────\n\n/**\n * Read-only reactive device state container.\n *\n * Every property is an {@link Observable} — call `.value` for synchronous\n * reads or `.onChange(cb)` for reactive subscriptions.\n */\nexport interface DeviceStateShape {\n readonly connected: Observable<boolean>;\n readonly modelName: Observable<string | null>;\n readonly batteryLevel: Observable<number | null>;\n readonly charging: Observable<boolean | null>;\n readonly caseBatteryLevel: Observable<number | null>;\n readonly caseCharging: Observable<boolean | null>;\n readonly caseOpen: Observable<boolean | null>;\n readonly caseRemoved: Observable<boolean | null>;\n readonly wifiConnected: Observable<boolean>;\n readonly wifiSsid: Observable<string | null>;\n readonly wifiLocalIp: Observable<string | null>;\n readonly hotspotEnabled: Observable<boolean | null>;\n readonly hotspotSsid: Observable<string | null>;\n}\n\n// ─── Internal Helpers ───────────────────────────────────────────────────────\n\n/**\n * Normalise raw touch event data from the wire format.\n *\n * - `gesture_name` → `gesture`\n * - `device_model` → `model`\n */\nfunction normaliseTouchEvent(raw: any): TouchEventData {\n return {\n ...raw,\n gesture: raw.gesture_name ?? raw.gesture ?? \"unknown\",\n model: raw.device_model ?? raw.model ?? \"unknown\",\n timestamp: raw.timestamp ?? new Date().toISOString(),\n };\n}\n\n// ─── DeviceManager ──────────────────────────────────────────────────────────\n\n/**\n * Manages all device-related state, hardware events, capabilities, and actions.\n *\n * Created by MentraSession and exposed as `session.device`.\n */\nexport class DeviceManager {\n // ─── Reactive State ───────────────────────────────────────────────────\n\n /** Reactive device state observables. */\n readonly state: DeviceStateShape;\n\n // ─── Capabilities ─────────────────────────────────────────────────────\n\n /** Current device capabilities (set from CONNECTION_ACK). */\n capabilities: any = null;\n\n // ─── Private ──────────────────────────────────────────────────────────\n\n private deps: DeviceManagerDeps;\n private permissions: PermissionsManager;\n\n /** Internal mutable references to observables (state exposes them read-only). */\n private readonly _connected: Observable<boolean>;\n private readonly _modelName: Observable<string | null>;\n private readonly _batteryLevel: Observable<number | null>;\n private readonly _charging: Observable<boolean | null>;\n private readonly _caseBatteryLevel: Observable<number | null>;\n private readonly _caseCharging: Observable<boolean | null>;\n private readonly _caseOpen: Observable<boolean | null>;\n private readonly _caseRemoved: Observable<boolean | null>;\n private readonly _wifiConnected: Observable<boolean>;\n private readonly _wifiSsid: Observable<string | null>;\n private readonly _wifiLocalIp: Observable<string | null>;\n private readonly _hotspotEnabled: Observable<boolean | null>;\n private readonly _hotspotSsid: Observable<string | null>;\n\n /** Capabilities-change listeners. */\n private capabilitiesListeners: Set<(caps: any) => void> = new Set();\n\n /**\n * Ref-counted handler bookkeeping per stream key.\n *\n * Tracks the number of active handlers for each stream so that\n * `addSubscription` / `removeSubscription` are called exactly once\n * when the first handler is added / last handler is removed.\n */\n private handlerCounts: Map<string, number> = new Map();\n\n /** Cleanup functions returned by router/messageHandlers registrations. */\n private cleanups: Array<() => void> = [];\n\n constructor(deps: DeviceManagerDeps) {\n this.deps = deps;\n this.permissions = deps.permissions;\n\n // ── Initialise Observables ────────────────────────────────────────\n this._connected = new Observable<boolean>(false);\n this._modelName = new Observable<string | null>(null);\n this._batteryLevel = new Observable<number | null>(null);\n this._charging = new Observable<boolean | null>(null);\n this._caseBatteryLevel = new Observable<number | null>(null);\n this._caseCharging = new Observable<boolean | null>(null);\n this._caseOpen = new Observable<boolean | null>(null);\n this._caseRemoved = new Observable<boolean | null>(null);\n this._wifiConnected = new Observable<boolean>(false);\n this._wifiSsid = new Observable<string | null>(null);\n this._wifiLocalIp = new Observable<string | null>(null);\n this._hotspotEnabled = new Observable<boolean | null>(null);\n this._hotspotSsid = new Observable<string | null>(null);\n\n // Expose as read-only shape\n this.state = {\n connected: this._connected,\n modelName: this._modelName,\n batteryLevel: this._batteryLevel,\n charging: this._charging,\n caseBatteryLevel: this._caseBatteryLevel,\n caseCharging: this._caseCharging,\n caseOpen: this._caseOpen,\n caseRemoved: this._caseRemoved,\n wifiConnected: this._wifiConnected,\n wifiSsid: this._wifiSsid,\n wifiLocalIp: this._wifiLocalIp,\n hotspotEnabled: this._hotspotEnabled,\n hotspotSsid: this._hotspotSsid,\n };\n\n // ── Register message handlers ─────────────────────────────────────\n this.cleanups.push(\n deps.messageHandlers.register(\"device_state_update\", (msg: any) => {\n this.handleDeviceStateUpdate(msg);\n }),\n );\n this.cleanups.push(\n deps.messageHandlers.register(\"capabilities_update\", (msg: any) => {\n this.handleCapabilitiesUpdate(msg);\n }),\n );\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Hardware Events\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Listen for physical button press events on the glasses.\n *\n * @param handler - Called with {@link ButtonPressEvent} for every press\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = device.onButtonPress((e) => {\n * if (e.pressType === \"long\") {\n * console.log(\"Long press on\", e.buttonId);\n * }\n * });\n * ```\n */\n onButtonPress(handler: (event: ButtonPressEvent) => void): () => void {\n return this.addStreamHandler(StreamType.BUTTON_PRESS, (_st, data) => {\n handler({\n buttonId: data.buttonId ?? data.button_id ?? \"unknown\",\n pressType: data.pressType ?? data.press_type ?? \"short\",\n });\n });\n }\n\n /**\n * Listen for head position (up/down) events from the IMU.\n *\n * @param handler - Called with {@link HeadPositionEvent} on position change\n * @returns Cleanup function to remove the handler\n */\n onHeadPosition(handler: (event: HeadPositionEvent) => void): () => void {\n return this.addStreamHandler(StreamType.HEAD_POSITION, (_st, data) => {\n handler({\n position: data.position ?? \"down\",\n });\n });\n }\n\n /**\n * Listen for touch/gesture events from the glasses touchpad.\n *\n * Overloaded:\n * - `onTouchEvent(handler)` — all touch events\n * - `onTouchEvent(gesture, handler)` — only events matching the given gesture\n *\n * @param gestureOrHandler - A gesture name string, or a handler for all events\n * @param handler - Handler when the first argument is a gesture name\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * // All gestures\n * device.onTouchEvent((e) => console.log(e.gesture));\n *\n * // Specific gesture\n * device.onTouchEvent(\"double_tap\", (e) => console.log(\"Double tap!\"));\n * ```\n */\n onTouchEvent(handler: (event: TouchEventData) => void): () => void;\n onTouchEvent(gesture: string, handler: (event: TouchEventData) => void): () => void;\n onTouchEvent(gestures: string[], handler: (event: TouchEventData) => void): () => void;\n onTouchEvent(\n gestureOrHandler: string | string[] | ((event: TouchEventData) => void),\n handler?: (event: TouchEventData) => void,\n ): () => void {\n if (Array.isArray(gestureOrHandler)) {\n // Subscribe to multiple gestures, single cleanup\n const gestures = gestureOrHandler as string[];\n const cleanups: Array<() => void> = [];\n for (const gesture of gestures) {\n const gestureStream = `${StreamType.TOUCH_EVENT}:${gesture}`;\n cleanups.push(\n this.addStreamHandler(gestureStream, (_st, data) => {\n handler!(normaliseTouchEvent(data));\n }),\n );\n }\n return () => {\n for (const fn of cleanups) fn();\n };\n }\n\n if (typeof gestureOrHandler === \"function\") {\n // Subscribe to all touch events\n return this.addStreamHandler(StreamType.TOUCH_EVENT, (_st, data) => {\n gestureOrHandler(normaliseTouchEvent(data));\n });\n }\n\n // Subscribe to a specific gesture via \"touch_event:{gesture}\" stream key\n const gesture = gestureOrHandler;\n const gestureStream = `${StreamType.TOUCH_EVENT}:${gesture}`;\n return this.addStreamHandler(gestureStream, (_st, data) => {\n handler!(normaliseTouchEvent(data));\n });\n }\n\n /**\n * Listen for glasses battery update events.\n *\n * Also updates the reactive `state.batteryLevel` and `state.charging` observables.\n *\n * @param handler - Called with {@link BatteryUpdateEvent} on each update\n * @returns Cleanup function to remove the handler\n */\n onBatteryUpdate(handler: (event: BatteryUpdateEvent) => void): () => void {\n return this.addStreamHandler(StreamType.GLASSES_BATTERY_UPDATE, (_st, data) => {\n // Update reactive state from the battery event\n if (data.level !== undefined) {\n this._batteryLevel.setValue(data.level);\n }\n if (data.charging !== undefined) {\n this._charging.setValue(data.charging);\n }\n\n handler({\n level: data.level ?? 0,\n charging: data.charging ?? false,\n timeRemaining: data.timeRemaining ?? data.time_remaining,\n });\n });\n }\n\n /**\n * Listen for VPS (Visual Positioning System) coordinate updates.\n *\n * @param handler - Called with raw VPS coordinate data\n * @returns Cleanup function to remove the handler\n */\n onVpsCoordinates(handler: (event: any) => void): () => void {\n return this.addStreamHandler(StreamType.VPS_COORDINATES, (_st, data) => {\n handler(data);\n });\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Actions\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Request the user to set up WiFi on their glasses.\n *\n * Sends a `request_wifi_setup` message to the cloud, which prompts\n * the companion app to display a WiFi configuration flow.\n *\n * @param reason - Optional human-readable reason shown to the user\n *\n * @example\n * ```ts\n * device.requestWifiSetup(\"This app needs WiFi for real-time sync\");\n * ```\n */\n requestWifiSetup(reason?: string): void {\n this.deps.logger.info(`DeviceManager: Requesting WiFi setup${reason ? ` — ${reason}` : \"\"}`);\n this.deps.sendMessage({\n type: \"request_wifi_setup\",\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n timestamp: new Date().toISOString(),\n ...(reason ? { reason } : {}),\n });\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Capabilities\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Subscribe to device capability changes.\n *\n * Called when capabilities are first received (CONNECTION_ACK) and\n * whenever the device model or capabilities change mid-session.\n *\n * @param handler - Called with the new capabilities object\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * device.onCapabilitiesChange((caps) => {\n * if (caps?.camera?.photo) {\n * console.log(\"Camera supports photos\");\n * }\n * });\n * ```\n */\n onCapabilitiesChange(handler: (caps: any) => void): () => void {\n this.capabilitiesListeners.add(handler);\n return () => {\n this.capabilitiesListeners.delete(handler);\n };\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Internal — Called by MentraSession\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Handle a `device_state_update` message from the cloud.\n *\n * Updates all matching Observable properties. Only fields present in\n * the message are touched — Observables for absent fields keep their\n * current value.\n *\n * @param message - The raw device_state_update message\n * @internal\n */\n handleDeviceStateUpdate(message: any): void {\n const state = message?.state ?? message?.data ?? message;\n if (!state) {\n this.deps.logger.debug(\"DeviceManager: Received empty device_state_update\");\n return;\n }\n\n // Intentionally silent — device state updates arrive every ~24s and\n // produce noise in developer logs. The individual Observable.setValue\n // calls below are the real source of truth; consumers subscribe to\n // the specific properties they care about (battery, wifi, etc.).\n\n // Connection\n if (state.connected !== undefined) this._connected.setValue(state.connected);\n if (state.modelName !== undefined) this._modelName.setValue(state.modelName);\n\n // WiFi\n if (state.wifiConnected !== undefined) this._wifiConnected.setValue(state.wifiConnected);\n if (state.wifiSsid !== undefined) this._wifiSsid.setValue(state.wifiSsid ?? null);\n if (state.wifiLocalIp !== undefined) this._wifiLocalIp.setValue(state.wifiLocalIp ?? null);\n\n // Battery\n if (state.batteryLevel !== undefined) this._batteryLevel.setValue(state.batteryLevel ?? null);\n if (state.charging !== undefined) this._charging.setValue(state.charging ?? null);\n if (state.caseBatteryLevel !== undefined) this._caseBatteryLevel.setValue(state.caseBatteryLevel ?? null);\n if (state.caseCharging !== undefined) this._caseCharging.setValue(state.caseCharging ?? null);\n if (state.caseOpen !== undefined) this._caseOpen.setValue(state.caseOpen ?? null);\n if (state.caseRemoved !== undefined) this._caseRemoved.setValue(state.caseRemoved ?? null);\n\n // Hotspot\n if (state.hotspotEnabled !== undefined) this._hotspotEnabled.setValue(state.hotspotEnabled ?? null);\n if (state.hotspotSsid !== undefined) this._hotspotSsid.setValue(state.hotspotSsid ?? null);\n }\n\n /**\n * Handle a `capabilities_update` message from the cloud.\n *\n * Extracts the capabilities payload and delegates to {@link setCapabilities}.\n *\n * @param message - The raw capabilities_update message\n * @internal\n */\n handleCapabilitiesUpdate(message: any): void {\n const caps = message?.capabilities ?? message?.data?.capabilities ?? null;\n const modelName = message?.modelName ?? message?.data?.modelName ?? null;\n\n if (modelName) {\n this._modelName.setValue(modelName);\n }\n\n this.setCapabilities(caps);\n }\n\n /**\n * Directly set the device capabilities.\n *\n * Called by MentraSession from the CONNECTION_ACK payload, or by\n * {@link handleCapabilitiesUpdate} for mid-session updates.\n *\n * @param caps - The capabilities object (or null)\n * @internal\n */\n setCapabilities(caps: any): void {\n this.capabilities = caps;\n const model = this._modelName.value;\n this.deps.logger.info(\n { model: model ?? undefined, hasCamera: !!caps?.camera, hasMicrophone: !!caps?.microphone },\n `Glasses capabilities ${caps ? \"received\" : \"cleared\"}${model ? ` (${model})` : \"\"}`,\n );\n\n // Notify listeners\n for (const listener of this.capabilitiesListeners) {\n try {\n listener(caps);\n } catch (err) {\n this.deps.logger.error(\n `DeviceManager: Error in capabilities listener: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n }\n\n /**\n * Remove all tracked handlers and clear listeners.\n *\n * Called by MentraSession during disconnect/cleanup.\n *\n * @internal\n */\n destroy(): void {\n for (const cleanup of this.cleanups) {\n cleanup();\n }\n\n this.cleanups.length = 0;\n this.handlerCounts.clear();\n this.capabilitiesListeners.clear();\n }\n\n // ═══════════════════════════════════════════════════════════════════════\n // Private — Stream Handler Management\n // ═══════════════════════════════════════════════════════════════════════\n\n /**\n * Register a handler on the DataStreamRouter for a given stream key,\n * managing subscription lifecycle automatically.\n *\n * - Calls `deps.addSubscription` when the first handler for a key is added.\n * - Calls `deps.removeSubscription` when the last handler for a key is removed.\n *\n * @param streamKey - The stream type or prefixed stream key\n * @param handler - The stream handler function\n * @returns Cleanup function that unregisters the handler and manages subscription\n */\n private addStreamHandler(\n streamKey: string,\n handler: (streamType: string, data: any, message: any) => void,\n ): () => void {\n const currentCount = this.handlerCounts.get(streamKey) ?? 0;\n\n // First handler for this stream — subscribe\n if (currentCount === 0) {\n this.deps.addSubscription(streamKey);\n }\n this.handlerCounts.set(streamKey, currentCount + 1);\n\n // Register on the router\n const routerCleanup = this.deps.router.on(streamKey, handler);\n\n // Track for bulk cleanup\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n\n // Remove from router\n routerCleanup();\n\n // Decrement handler count\n const count = this.handlerCounts.get(streamKey) ?? 0;\n const newCount = count - 1;\n if (newCount <= 0) {\n this.handlerCounts.delete(streamKey);\n this.deps.removeSubscription(streamKey);\n } else {\n this.handlerCounts.set(streamKey, newCount);\n }\n };\n\n this.cleanups.push(cleanup);\n return cleanup;\n }\n}\n",
|
|
28
28
|
"/**\n * 🖥️ DisplayManager — AR Display Control\n *\n * v3 manager that wraps the existing LayoutManager display functionality.\n * Sends DisplayRequest messages to the cloud with identical wire format\n * to ensure backward compatibility.\n *\n * @example\n * ```ts\n * const display = new DisplayManager(deps);\n *\n * // Simple text\n * display.showText(\"Hello AR World!\");\n *\n * // Pre-wrapped lines\n * display.showText([\"Line 1\", \"Line 2\"]);\n *\n * // Structured layouts\n * display.showReferenceCard(\"Weather\", \"Sunny and 75°F\");\n * display.showDashboardCard(\"BPM\", \"72\");\n *\n * // Clear the display\n * display.clear();\n * ```\n */\n\nimport {\n DisplayRequest,\n Layout,\n TextWall,\n DoubleTextWall,\n ReferenceCard,\n DashboardCard,\n BitmapView,\n ClearView,\n} from \"../../types/layouts\";\nimport { LayoutType, ViewType } from \"../../types/enums\";\nimport { AppToCloudMessageType } from \"../../types/message-types\";\n\n// ─── Dependencies ────────────────────────────────────────────────────────────\n\n/**\n * Shared dependency bag injected by MentraSession.\n * Keeps managers decoupled from the session implementation.\n */\nexport interface ManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n addSubscription: (stream: string) => void;\n removeSubscription: (stream: string) => void;\n sendMessage: (message: any) => void;\n sendBinary: (data: ArrayBuffer | Uint8Array) => void;\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\n// ─── DisplayManager ─────────────────────────────────────────────────────────\n\n/**\n * Controls the AR display on the user's glasses.\n *\n * Provides high-level methods for showing text, cards, bitmaps, and\n * clearing the display. All methods produce a `DisplayRequest` message\n * with `type: \"display_event\"` — the exact same wire format the cloud\n * and glasses firmware already understand from v2.\n */\nexport class DisplayManager {\n private readonly deps: ManagerDeps;\n\n constructor(deps: ManagerDeps) {\n this.deps = deps;\n }\n\n // ─── High-Level API ──────────────────────────────────────────────────────\n\n /**\n * Show text on the AR display.\n *\n * Accepts a single string or an array of pre-wrapped lines.\n * When an array is provided the lines are joined with newlines\n * and sent as a single TextWall layout.\n *\n * @param text - A string or array of strings to display\n *\n * @example\n * ```ts\n * display.showText(\"Connected to server\");\n * display.showText([\"Line 1\", \"Line 2\", \"Line 3\"]);\n * ```\n */\n showText(text: string | string[]): void {\n const resolved = Array.isArray(text) ? text.join(\"\\n\") : text;\n this.showTextWall(resolved);\n }\n\n /**\n * 📝 Show a single block of text on the main display.\n *\n * Best for simple messages, status updates, and notifications.\n *\n * @param text - Text content to display\n *\n * @example\n * ```ts\n * display.showTextWall(\"Listening…\");\n * ```\n */\n showTextWall(text: string): void {\n if (text === undefined || text === null) {\n text = \"\";\n this.deps.logger.warn(\"showTextWall called with null/undefined text\");\n }\n\n if (typeof text !== \"string\") {\n text = String(text);\n this.deps.logger.warn(\"showTextWall: non-string input converted to string\");\n }\n\n const layout: TextWall = {\n layoutType: LayoutType.TEXT_WALL,\n text,\n };\n\n try {\n this.sendDisplayEvent(layout);\n } catch (err) {\n this.deps.logger.error(\"Failed to display text wall:\", err);\n }\n }\n\n /**\n * ↕️ Show two sections of text, one above the other.\n *\n * Best for before/after content, question/answer, translations,\n * or any two-part message.\n *\n * @param leftText - Text for the top section\n * @param rightText - Text for the bottom section\n *\n * @example\n * ```ts\n * display.showDoubleTextWall(\"Original: Hello\", \"Translated: Bonjour\");\n * ```\n */\n showDoubleTextWall(leftText: string, rightText: string): void {\n const layout: DoubleTextWall = {\n layoutType: LayoutType.DOUBLE_TEXT_WALL,\n topText: leftText,\n bottomText: rightText,\n };\n this.sendDisplayEvent(layout);\n }\n\n /**\n * 📇 Show a card with a title and body text.\n *\n * Best for titled content, important information, and notifications\n * with context.\n *\n * @param title - Card title\n * @param body - Main content text\n *\n * @example\n * ```ts\n * display.showReferenceCard(\"Meeting Reminder\", \"Team standup in 5 minutes\");\n * ```\n */\n showReferenceCard(title: string, body: string): void {\n const layout: ReferenceCard = {\n layoutType: LayoutType.REFERENCE_CARD,\n title,\n text: body,\n };\n this.sendDisplayEvent(layout);\n }\n\n /**\n * 📊 Show a dashboard card with left and right text.\n *\n * Best for key-value pairs, metrics, and dashboard-style displays.\n * Automatically uses the DASHBOARD view type.\n *\n * @param leftText - Left side text (typically label/key)\n * @param rightText - Right side text (typically value)\n *\n * @example\n * ```ts\n * display.showDashboardCard(\"Weather\", \"72°F\");\n * ```\n */\n showDashboardCard(leftText: string, rightText: string): void {\n const layout: DashboardCard = {\n layoutType: LayoutType.DASHBOARD_CARD,\n leftText,\n rightText,\n };\n this.sendDisplayEvent(layout, ViewType.DASHBOARD);\n }\n\n /**\n * 🖼️ Show a bitmap image on the display.\n *\n * @param data - Hex or base64 encoded bitmap data string\n *\n * @example\n * ```ts\n * display.showBitmap(base64EncodedBitmapString);\n * ```\n */\n showBitmap(data: any): void {\n if (typeof data !== \"string\") {\n this.deps.logger.error(\"showBitmap: data must be a string\");\n return;\n }\n\n if (data.length > 1_000_000) {\n this.deps.logger.error(\"showBitmap: data exceeds 1 MB limit\");\n return;\n }\n\n const layout: BitmapView = {\n layoutType: LayoutType.BITMAP_VIEW,\n data,\n };\n this.sendDisplayEvent(layout);\n }\n\n /**\n * 🧹 Clear the AR display.\n *\n * Removes any currently shown content from the main view.\n *\n * @example\n * ```ts\n * display.clear();\n * ```\n */\n clear(): void {\n const layout: ClearView = {\n layoutType: LayoutType.CLEAR_VIEW,\n };\n this.sendDisplayEvent(layout);\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n /**\n * Build and send a DisplayRequest message.\n *\n * Wire format is identical to v2 LayoutManager — the cloud receives\n * the same `{ type: \"display_event\", packageName, view, layout, … }`.\n *\n * @param layout - The layout configuration to display\n * @param view - View type (main or dashboard), defaults to MAIN\n * @param durationMs - Optional display duration in milliseconds\n */\n private sendDisplayEvent(layout: Layout, view: ViewType = ViewType.MAIN, durationMs?: number): void {\n if (!layout || !layout.layoutType) {\n this.deps.logger.error(\"sendDisplayEvent: layout must have a layoutType property\");\n return;\n }\n\n // Validate view type\n if (view !== ViewType.MAIN && view !== ViewType.DASHBOARD) {\n this.deps.logger.warn(`Invalid view type: ${view}, defaulting to MAIN`);\n view = ViewType.MAIN;\n }\n\n // Validate duration\n if (durationMs !== undefined) {\n if (typeof durationMs !== \"number\" || durationMs < 0) {\n this.deps.logger.warn(`Invalid duration: ${durationMs}, ignoring`);\n durationMs = undefined;\n }\n }\n\n const message: DisplayRequest = {\n timestamp: new Date(),\n sessionId: this.deps.getSessionId(),\n type: AppToCloudMessageType.DISPLAY_REQUEST,\n packageName: this.deps.getPackageName(),\n view,\n layout,\n durationMs,\n };\n\n this.deps.sendMessage(message);\n }\n}\n",
|
|
29
|
-
"/**\n * LedManager — v3 SDK LED Control API\n *\n * Thin wrapper around the existing LedModule patterns. Provides a simplified\n * API for controlling RGB LEDs on connected smart glasses.\n *\n * Wire format is identical to v2:\n * ```json\n * {\n * \"type\": \"rgb_led_control\",\n * \"packageName\": \"<packageName>\",\n * \"sessionId\": \"<sessionId>\",\n * \"requestId\": \"<requestId>\",\n * \"action\": \"on\" | \"off\",\n * \"color\": \"<LedColor>\",\n * \"ontime\": <ms>\n * }\n * ```\n *\n * @module\n */\n\nimport { AppToCloudMessageType } from \"../../types\";\nimport type { LedColor } from \"../../types\";\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * Structural type — no concrete imports so the manager stays unit-testable\n * with plain stubs.\n */\nexport interface LedManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Add a subscription string (triggers SUBSCRIPTION_UPDATE to cloud). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Package name for outgoing messages. */\n getPackageName: () => string;\n /** Current session ID. */\n getSessionId: () => string;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/**\n * Generate a unique request ID for LED control requests.\n * Uses `crypto.randomUUID()` when available, falls back to timestamp + random.\n */\nfunction generateRequestId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `led_req_${crypto.randomUUID()}`;\n }\n return `led_req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Controls RGB LEDs on connected smart glasses.\n *\n * LED commands are fire-and-forget — the methods return immediately after\n * sending the control message to the cloud. No response is awaited.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Solid green LED for 2 seconds\n * session.led.setColor(\"green\", 2000);\n *\n * // Turn LED off\n * session.led.off();\n * ```\n */\nexport class LedManager {\n private readonly deps: LedManagerDeps;\n\n constructor(deps: LedManagerDeps) {\n this.deps = deps;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Set the LED to a specific colour.\n *\n * Sends an `rgb_led_control` message with `action: \"on\"` to the cloud.\n *
|
|
30
|
-
"/**\n * LocationManager — v3 SDK Location API\n *\n * Wraps the existing LocationManager patterns from v2 with a cleaner,\n * composable API. Subscribes to location data streams, caches the latest\n * known position, and supports one-shot location polls.\n *\n * Wire format is identical to v2:\n * - Location stream subscription: `\"location_stream\"` added to subscriptions\n * - Location poll: `{ type: \"location_poll_request\", packageName, sessionId, accuracy, correlationId }`\n * - Location updates arrive as DATA_STREAM messages with streamType `\"location_update\"` or `\"location_stream\"`\n *\n * The LocationUpdate payload shape (from glasses-to-cloud):\n * ```json\n * {\n * \"type\": \"location_update\",\n * \"lat\": number,\n * \"lng\": number,\n * \"accuracy\": number,\n * \"correlationId\": string | undefined\n * }\n * ```\n *\n * @module\n */\n\nimport { AppToCloudMessageType, StreamType } from \"../../types\";\n\n// ─── Public Types ───────────────────────────────────────────────────────────\n\n/**\n * Normalised location data delivered to subscriber callbacks.\n */\nexport interface LocationData {\n /** Latitude in decimal degrees. */\n lat: number;\n /** Longitude in decimal degrees. */\n lng: number;\n /** Horizontal accuracy in metres (`undefined` if not available). */\n accuracy?: number;\n /** Unix timestamp (ms) when the location was recorded. */\n timestamp: number;\n /** Correlation ID returned from a one-shot poll (if applicable). */\n correlationId?: string;\n}\n\n/**\n * Accuracy tier for location stream subscriptions.\n * Maps directly to the v2 `LocationStreamRequest.rate` values.\n */\nexport type LocationAccuracy =\n | \"standard\"\n | \"high\"\n | \"realtime\"\n | \"tenMeters\"\n | \"hundredMeters\"\n | \"kilometer\"\n | \"threeKilometers\"\n | \"reduced\";\n\n/** Callback signature for location subscribers. */\nexport type LocationHandler = (location: LocationData) => void;\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * Structural type — no concrete imports so the manager stays unit-testable\n * with plain stubs.\n */\nexport interface LocationManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Add a subscription string (triggers SUBSCRIPTION_UPDATE to cloud). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Package name for outgoing messages. */\n getPackageName: () => string;\n /** Current session ID. */\n getSessionId: () => string;\n}\n\n/**\n * Internal bookkeeping for a single `onUpdate()` registration.\n */\ninterface Registration {\n /** Cleanup function returned by `router.on()` for the primary stream. */\n routerCleanup: () => void;\n /** Cleanup function returned by `router.on()` for the secondary location_update stream. */\n updateCleanup: () => void;\n /** The stream key this registration subscribed to. */\n streamKey: string;\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────\n\n/** Stream type for continuous location updates. */\nconst LOCATION_STREAM = StreamType.LOCATION_STREAM; // \"location_stream\"\n\n/** Stream type for individual location update events. */\nconst LOCATION_UPDATE = StreamType.LOCATION_UPDATE; // \"location_update\"\n\n/** Default timeout for one-shot location polls. */\nconst POLL_TIMEOUT_MS = 15_000;\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/**\n * Generate a unique correlation ID for location poll requests.\n */\nfunction generateCorrelationId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `poll_${crypto.randomUUID()}`;\n }\n return `poll_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Normalise raw location data from a DATA_STREAM event into the public\n * {@link LocationData} shape.\n */\nfunction normalise(raw: any): LocationData {\n return {\n lat: typeof raw.lat === \"number\" ? raw.lat : 0,\n lng: typeof raw.lng === \"number\" ? raw.lng : 0,\n accuracy: typeof raw.accuracy === \"number\" ? raw.accuracy : undefined,\n timestamp: raw.timestamp ? new Date(raw.timestamp).getTime() : Date.now(),\n correlationId: raw.correlationId,\n };\n}\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Manages location subscriptions, caches the latest known position, and\n * supports one-shot location polls.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Subscribe to continuous location updates\n * const stop = session.location.onUpdate((loc) => {\n * console.log(`${loc.lat}, ${loc.lng} (±${loc.accuracy}m)`);\n * });\n *\n * // Read cached values at any time\n * console.log(\"Last known:\", session.location.lat, session.location.lng);\n *\n * // Request a single location update\n * session.location.requestUpdate();\n *\n * // Stop all subscriptions\n * session.location.stop();\n * ```\n */\nexport class LocationManager {\n private readonly deps: LocationManagerDeps;\n\n /**\n * All currently-active registrations. Tracked so that {@link stop}\n * can clean everything up in one shot.\n */\n private registrations = new Set<Registration>();\n\n /**\n * Reference count for the location_stream subscription.\n * We only call `removeSubscription` when ref-count drops to zero.\n */\n private streamRefCount = 0;\n\n // ─── Cached State ───────────────────────────────────────────────────────\n\n /** Latest latitude, or `null` if no update has been received. */\n private _lat: number | null = null;\n\n /** Latest longitude, or `null` if no update has been received. */\n private _lng: number | null = null;\n\n /** Latest horizontal accuracy in metres, or `null` if unknown. */\n private _accuracy: number | null = null;\n\n /** Timestamp of the latest location update, or `null` if none received. */\n private _timestamp: number | null = null;\n\n /**\n * Whether the device has location permission.\n * Optimistically `true`, updated to `false` on permission errors.\n */\n private _hasPermission = true;\n\n /** Cleanup for the internal location_update message handler. */\n private locationUpdateCleanup: (() => void) | null = null;\n\n constructor(deps: LocationManagerDeps) {\n this.deps = deps;\n\n // Register a router handler for \"location_update\" stream type so we always\n // cache the latest position, even if no `onUpdate()` listener is active.\n this.locationUpdateCleanup = this.deps.router.on(LOCATION_UPDATE, (_streamType, data, _message) => {\n this.cacheLocation(data);\n });\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Subscribe to continuous location updates.\n *\n * Registers on the DataStreamRouter for `\"location_stream\"` events and\n * adds the `\"location_stream\"` subscription to the cloud. Multiple\n * independent subscriptions are supported — each returns its own\n * cleanup function.\n *\n * @param handler - Called each time a location update arrives.\n * @param accuracy - Desired accuracy tier. Defaults to `\"standard\"`.\n * @returns A cleanup function that removes this specific subscription.\n *\n * @example\n * ```ts\n * const stop = session.location.onUpdate((loc) => {\n * console.log(`${loc.lat}, ${loc.lng}`);\n * });\n *\n * // Later:\n * stop();\n * ```\n */\n onUpdate(handler: LocationHandler, accuracy?: LocationAccuracy): () => void {\n const streamKey = LOCATION_STREAM;\n\n // Register on the router for location_stream events\n const routerCleanup = this.deps.router.on(streamKey, (_streamType, data, _message) => {\n try {\n const location = normalise(data);\n this.cacheLocation(data);\n handler(location);\n } catch (err) {\n this.deps.logger.error(\"[LocationManager] Error in onUpdate handler:\", err);\n }\n });\n\n // Also listen for location_update events (single updates, poll responses, etc.)\n const updateCleanup = this.deps.router.on(LOCATION_UPDATE, (_streamType, data, _message) => {\n try {\n const location = normalise(data);\n this.cacheLocation(data);\n handler(location);\n } catch (err) {\n this.deps.logger.error(\"[LocationManager] Error in onUpdate handler (location_update):\", err);\n }\n });\n\n const reg: Registration = { routerCleanup, updateCleanup, streamKey };\n\n this.registrations.add(reg);\n\n // Increment ref count and subscribe if first listener\n this.streamRefCount++;\n if (this.streamRefCount === 1) {\n // Add subscription with accuracy rate — v2 uses LocationStreamRequest format\n this.deps.addSubscription(streamKey);\n this.deps.logger.debug({ accuracy: accuracy ?? \"standard\" }, `[LocationManager] Subscribed to \"${streamKey}\".`);\n }\n\n // Return composite cleanup\n return () => {\n if (!this.registrations.has(reg)) return; // Already cleaned up (idempotent)\n\n routerCleanup();\n updateCleanup();\n this.registrations.delete(reg);\n\n // Decrement ref count and unsubscribe if last listener\n this.streamRefCount--;\n if (this.streamRefCount <= 0) {\n this.streamRefCount = 0;\n this.deps.removeSubscription(streamKey);\n this.deps.logger.debug(`[LocationManager] Unsubscribed from \"${streamKey}\".`);\n }\n };\n }\n\n /**\n * Request a single location update (one-shot poll).\n *\n * Sends a `location_poll_request` message to the cloud. The response\n * will arrive as a `location_update` DATA_STREAM event and will be\n * delivered to any active `onUpdate()` listeners as well as updating\n * the cached position.\n *\n * @param accuracy - Desired accuracy tier for the poll. Defaults to `\"standard\"`.\n *\n * @example\n * ```ts\n * session.location.requestUpdate();\n * // The next onUpdate() callback will fire with the fresh position.\n * ```\n */\n requestUpdate(accuracy?: LocationAccuracy): void {\n const correlationId = generateCorrelationId();\n\n const message = {\n type: AppToCloudMessageType.LOCATION_POLL_REQUEST,\n correlationId,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n accuracy: accuracy ?? \"standard\",\n };\n\n this.deps.sendMessage(message);\n\n this.deps.logger.debug({ correlationId, accuracy: message.accuracy }, \"📍 Location poll request sent\");\n }\n\n /**\n * Stop all location subscriptions and remove every handler.\n *\n * After calling this, no location callbacks will fire until new\n * subscriptions are created via {@link onUpdate}.\n *\n * @example\n * ```ts\n * session.location.stop();\n * ```\n */\n stop(): void {\n // Iterate over a snapshot — cleanup mutates the set\n const snapshot = Array.from(this.registrations);\n for (const reg of snapshot) {\n reg.routerCleanup();\n reg.updateCleanup();\n this.registrations.delete(reg);\n }\n\n // Force unsubscribe regardless of ref count\n if (this.streamRefCount > 0) {\n this.deps.removeSubscription(LOCATION_STREAM);\n }\n this.streamRefCount = 0;\n\n this.deps.logger.debug(\"[LocationManager] All subscriptions stopped.\");\n }\n\n // ─── Cached Accessors ──────────────────────────────────────────────────\n\n /**\n * Latest known latitude, or `null` if no location update has been received.\n */\n get lat(): number | null {\n return this._lat;\n }\n\n /**\n * Latest known longitude, or `null` if no location update has been received.\n */\n get lng(): number | null {\n return this._lng;\n }\n\n /**\n * Latest horizontal accuracy in metres, or `null` if unknown.\n */\n get accuracy(): number | null {\n return this._accuracy;\n }\n\n /**\n * Unix timestamp (ms) of the latest location update, or `null` if none received.\n */\n get timestamp(): number | null {\n return this._timestamp;\n }\n\n /**\n * Whether the device has granted location permission.\n *\n * Optimistically `true` — updated to `false` if a permission error\n * is received from the cloud.\n */\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n // ─── Internal ───────────────────────────────────────────────────────────\n\n /**\n * Update cached location values from raw incoming data.\n */\n private cacheLocation(raw: any): void {\n if (typeof raw.lat === \"number\") {\n this._lat = raw.lat;\n }\n if (typeof raw.lng === \"number\") {\n this._lng = raw.lng;\n }\n if (typeof raw.accuracy === \"number\") {\n this._accuracy = raw.accuracy;\n }\n this._timestamp = raw.timestamp ? new Date(raw.timestamp).getTime() : Date.now();\n }\n\n /**\n * Called by MentraSession if a permission error for location is received.\n * @internal\n */\n setPermission(granted: boolean): void {\n this._hasPermission = granted;\n }\n\n // ─── Cleanup ────────────────────────────────────────────────────────────\n\n /**\n * Clean up all resources.\n *\n * Called by MentraSession during disconnect/cleanup.\n * @internal\n */\n destroy(): void {\n this.stop();\n\n if (this.locationUpdateCleanup) {\n this.locationUpdateCleanup();\n this.locationUpdateCleanup = null;\n }\n\n this._lat = null;\n this._lng = null;\n this._accuracy = null;\n this._timestamp = null;\n\n this.deps.logger.debug(\"[LocationManager] Destroyed.\");\n }\n}\n",
|
|
29
|
+
"/**\n * LedManager — v3 SDK LED Control API\n *\n * Thin wrapper around the existing LedModule patterns. Provides a simplified\n * API for controlling RGB LEDs on connected smart glasses.\n *\n * Wire format is identical to v2:\n * ```json\n * {\n * \"type\": \"rgb_led_control\",\n * \"packageName\": \"<packageName>\",\n * \"sessionId\": \"<sessionId>\",\n * \"requestId\": \"<requestId>\",\n * \"action\": \"on\" | \"off\",\n * \"color\": \"<LedColor>\",\n * \"ontime\": <ms>\n * }\n * ```\n *\n * @module\n */\n\nimport { AppToCloudMessageType } from \"../../types\";\nimport type { LedColor } from \"../../types\";\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * Structural type — no concrete imports so the manager stays unit-testable\n * with plain stubs.\n */\nexport interface LedManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Add a subscription string (triggers SUBSCRIPTION_UPDATE to cloud). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Package name for outgoing messages. */\n getPackageName: () => string;\n /** Current session ID. */\n getSessionId: () => string;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/**\n * Generate a unique request ID for LED control requests.\n * Uses `crypto.randomUUID()` when available, falls back to timestamp + random.\n */\nfunction generateRequestId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `led_req_${crypto.randomUUID()}`;\n }\n return `led_req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Controls RGB LEDs on connected smart glasses.\n *\n * LED commands are fire-and-forget — the methods return immediately after\n * sending the control message to the cloud. No response is awaited.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Solid green LED for 2 seconds\n * session.led.setColor(\"green\", 2000);\n *\n * // Turn LED off\n * session.led.off();\n * ```\n */\n/** Options for LED blink patterns. */\nexport interface LedBlinkOptions {\n /** How long the LED stays on per cycle (ms). */\n onTime: number;\n /** How long the LED stays off between cycles (ms). */\n offTime: number;\n /** Number of on/off cycles. */\n count: number;\n}\n\nexport class LedManager {\n private readonly deps: LedManagerDeps;\n\n constructor(deps: LedManagerDeps) {\n this.deps = deps;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Set the LED to a specific colour.\n *\n * Sends an `rgb_led_control` message with `action: \"on\"` to the cloud.\n *\n * Three calling styles:\n * - `setColor(color)` - on for 1000ms (default)\n * - `setColor(color, durationMs)` - on for the specified duration\n * - `setColor(color, { onTime, offTime, count })` - blink pattern\n *\n * @param color - LED colour name. One of `\"red\"`, `\"green\"`, `\"blue\"`, `\"orange\"`, `\"white\"`.\n * @param durationOrOptions - Duration in ms, or an options object for blink patterns.\n *\n * @example\n * ```ts\n * // Red LED for 500ms\n * session.led.setColor(\"red\", 500);\n *\n * // White LED for the default 1s\n * session.led.setColor(\"white\");\n *\n * // Blink green 3 times (500ms on, 500ms off)\n * session.led.setColor(\"green\", { onTime: 500, offTime: 500, count: 3 });\n * ```\n */\n setColor(color: string, durationOrOptions?: number | LedBlinkOptions): void {\n const requestId = generateRequestId();\n\n let ontime: number;\n let offtime: number;\n let count: number;\n\n if (typeof durationOrOptions === \"object\" && durationOrOptions !== null) {\n // Blink pattern: { onTime, offTime, count }\n ontime = durationOrOptions.onTime;\n offtime = durationOrOptions.offTime;\n count = durationOrOptions.count;\n } else {\n // Simple duration (number or undefined)\n ontime = durationOrOptions ?? 1000;\n offtime = 0;\n count = 1;\n }\n\n const message = {\n type: AppToCloudMessageType.RGB_LED_CONTROL,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n action: \"on\" as const,\n color: color as LedColor,\n ontime,\n offtime,\n count,\n };\n\n this.deps.sendMessage(message);\n\n this.deps.logger.debug({ requestId, color, ontime, offtime, count }, \"💡 LED setColor request sent\");\n }\n\n /**\n * Turn the LED off.\n *\n * Sends an `rgb_led_control` message with `action: \"off\"` to the cloud.\n *\n * @example\n * ```ts\n * session.led.off();\n * ```\n */\n off(): void {\n const requestId = generateRequestId();\n\n const message = {\n type: AppToCloudMessageType.RGB_LED_CONTROL,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n action: \"off\" as const,\n };\n\n this.deps.sendMessage(message);\n\n this.deps.logger.debug({ requestId }, \"💡 LED off request sent\");\n }\n\n // ─── Cleanup ────────────────────────────────────────────────────────────\n\n /**\n * Clean up resources.\n *\n * Called by MentraSession during disconnect/cleanup. LED commands are\n * fire-and-forget so there is no pending state to drain.\n *\n * @internal\n */\n destroy(): void {\n this.deps.logger.debug(\"[LedManager] Destroyed.\");\n }\n}\n",
|
|
30
|
+
"/**\n * LocationManager — v3 SDK Location API\n *\n * Wraps the existing LocationManager patterns from v2 with a cleaner,\n * composable API. Subscribes to location data streams, caches the latest\n * known position, and supports one-shot location polls.\n *\n * Wire format is identical to v2:\n * - Location stream subscription: `\"location_stream\"` added to subscriptions\n * - Location poll: `{ type: \"location_poll_request\", packageName, sessionId, accuracy, correlationId }`\n * - Location updates arrive as DATA_STREAM messages with streamType `\"location_update\"` or `\"location_stream\"`\n *\n * The LocationUpdate payload shape (from glasses-to-cloud):\n * ```json\n * {\n * \"type\": \"location_update\",\n * \"lat\": number,\n * \"lng\": number,\n * \"accuracy\": number,\n * \"correlationId\": string | undefined\n * }\n * ```\n *\n * @module\n */\n\nimport { AppToCloudMessageType, StreamType } from \"../../types\";\n\n// ─── Public Types ───────────────────────────────────────────────────────────\n\n/**\n * Normalised location data delivered to subscriber callbacks.\n */\nexport interface LocationData {\n /** Latitude in decimal degrees. */\n lat: number;\n /** Longitude in decimal degrees. */\n lng: number;\n /** Horizontal accuracy in metres (`undefined` if not available). */\n accuracy?: number;\n /** Unix timestamp (ms) when the location was recorded. */\n timestamp: number;\n /** Correlation ID returned from a one-shot poll (if applicable). */\n correlationId?: string;\n}\n\n/**\n * Accuracy tier for location stream subscriptions.\n * Maps directly to the v2 `LocationStreamRequest.rate` values.\n */\nexport type LocationAccuracy =\n | \"standard\"\n | \"high\"\n | \"realtime\"\n | \"tenMeters\"\n | \"hundredMeters\"\n | \"kilometer\"\n | \"threeKilometers\"\n | \"reduced\";\n\n/** Callback signature for location subscribers. */\nexport type LocationHandler = (location: LocationData) => void;\n\n/** Location configuration options. */\nexport interface LocationConfig {\n /** Accuracy level for location updates. Default: \"standard\". */\n accuracy?: LocationAccuracy;\n}\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * Structural type — no concrete imports so the manager stays unit-testable\n * with plain stubs.\n */\nexport interface LocationManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Add a subscription string (triggers SUBSCRIPTION_UPDATE to cloud). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Package name for outgoing messages. */\n getPackageName: () => string;\n /** Current session ID. */\n getSessionId: () => string;\n}\n\n/**\n * Internal bookkeeping for a single `onUpdate()` registration.\n */\ninterface Registration {\n /** Cleanup function returned by `router.on()` for the primary stream. */\n routerCleanup: () => void;\n /** Cleanup function returned by `router.on()` for the secondary location_update stream. */\n updateCleanup: () => void;\n /** The stream key this registration subscribed to. */\n streamKey: string;\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────\n\n/** Stream type for continuous location updates. */\nconst LOCATION_STREAM = StreamType.LOCATION_STREAM; // \"location_stream\"\n\n/** Stream type for individual location update events. */\nconst LOCATION_UPDATE = StreamType.LOCATION_UPDATE; // \"location_update\"\n\n/** Default timeout for one-shot location polls. */\nconst POLL_TIMEOUT_MS = 15_000;\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/**\n * Generate a unique correlation ID for location poll requests.\n */\nfunction generateCorrelationId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `poll_${crypto.randomUUID()}`;\n }\n return `poll_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\n/**\n * Normalise raw location data from a DATA_STREAM event into the public\n * {@link LocationData} shape.\n */\nfunction normalise(raw: any): LocationData {\n return {\n lat: typeof raw.lat === \"number\" ? raw.lat : 0,\n lng: typeof raw.lng === \"number\" ? raw.lng : 0,\n accuracy: typeof raw.accuracy === \"number\" ? raw.accuracy : undefined,\n timestamp: raw.timestamp ? new Date(raw.timestamp).getTime() : Date.now(),\n correlationId: raw.correlationId,\n };\n}\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Manages location subscriptions, caches the latest known position, and\n * supports one-shot location polls.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Subscribe to continuous location updates\n * const stop = session.location.onUpdate((loc) => {\n * console.log(`${loc.lat}, ${loc.lng} (±${loc.accuracy}m)`);\n * });\n *\n * // Read cached values at any time\n * console.log(\"Last known:\", session.location.lat, session.location.lng);\n *\n * // Request a single location update\n * session.location.requestUpdate();\n *\n * // Stop all subscriptions\n * session.location.stop();\n * ```\n */\nexport class LocationManager {\n private readonly deps: LocationManagerDeps;\n\n /**\n * All currently-active registrations. Tracked so that {@link stop}\n * can clean everything up in one shot.\n */\n private registrations = new Set<Registration>();\n\n /**\n * Reference count for the location_stream subscription.\n * We only call `removeSubscription` when ref-count drops to zero.\n */\n private streamRefCount = 0;\n\n // ─── Cached State ───────────────────────────────────────────────────────\n\n /** Latest latitude, or `null` if no update has been received. */\n private _lat: number | null = null;\n\n /** Latest longitude, or `null` if no update has been received. */\n private _lng: number | null = null;\n\n /** Latest horizontal accuracy in metres, or `null` if unknown. */\n private _accuracy: number | null = null;\n\n /** Timestamp of the latest location update, or `null` if none received. */\n private _timestamp: number | null = null;\n\n /**\n * Whether the device has location permission.\n * Optimistically `true`, updated to `false` on permission errors.\n */\n private _hasPermission = true;\n\n /** User-provided configuration (accuracy, etc.). */\n private _config: LocationConfig = {};\n\n /** Pending one-shot poll requests awaiting a correlated response. */\n private pendingPolls = new Map<\n string,\n { resolve: (data: LocationData) => void; reject: (error: Error) => void; timeoutId: ReturnType<typeof setTimeout> }\n >();\n\n /** Cleanup for the internal location_update message handler. */\n private locationUpdateCleanup: (() => void) | null = null;\n\n constructor(deps: LocationManagerDeps) {\n this.deps = deps;\n\n // Register a router handler for \"location_update\" stream type so we always\n // cache the latest position, even if no `onUpdate()` listener is active.\n // Also resolve any pending one-shot polls matched by correlationId.\n this.locationUpdateCleanup = this.deps.router.on(LOCATION_UPDATE, (_streamType, data, _message) => {\n this.cacheLocation(data);\n this.resolvePendingPoll(data);\n });\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Configure location settings.\n *\n * Sets the accuracy level for subsequent `onUpdate()` subscriptions\n * and `requestUpdate()` calls.\n *\n * @example\n * ```ts\n * session.location.configure({ accuracy: \"high\" });\n * ```\n */\n configure(config: LocationConfig): void {\n this._config = { ...this._config, ...config };\n }\n\n /**\n * Subscribe to continuous location updates.\n *\n * Registers on the DataStreamRouter for `\"location_stream\"` events and\n * adds the `\"location_stream\"` subscription to the cloud. Multiple\n * independent subscriptions are supported — each returns its own\n * cleanup function.\n *\n * Uses the accuracy level set via {@link configure}. Defaults to `\"standard\"`.\n *\n * @param handler - Called each time a location update arrives.\n * @returns A cleanup function that removes this specific subscription.\n *\n * @example\n * ```ts\n * session.location.configure({ accuracy: \"high\" });\n * const stop = session.location.onUpdate((loc) => {\n * console.log(`${loc.lat}, ${loc.lng}`);\n * });\n *\n * // Later:\n * stop();\n * ```\n */\n onUpdate(handler: LocationHandler): () => void {\n const streamKey = LOCATION_STREAM;\n\n const accuracy = this._config.accuracy ?? \"standard\";\n\n // Register on the router for location_stream events\n const routerCleanup = this.deps.router.on(streamKey, (_streamType, data, _message) => {\n try {\n const location = normalise(data);\n this.cacheLocation(data);\n this.resolvePendingPoll(data);\n handler(location);\n } catch (err) {\n this.deps.logger.error(\"[LocationManager] Error in onUpdate handler:\", err);\n }\n });\n\n // Also listen for location_update events (single updates, poll responses, etc.)\n const updateCleanup = this.deps.router.on(LOCATION_UPDATE, (_streamType, data, _message) => {\n try {\n const location = normalise(data);\n this.cacheLocation(data);\n this.resolvePendingPoll(data);\n handler(location);\n } catch (err) {\n this.deps.logger.error(\"[LocationManager] Error in onUpdate handler (location_update):\", err);\n }\n });\n\n const reg: Registration = { routerCleanup, updateCleanup, streamKey };\n\n this.registrations.add(reg);\n\n // Increment ref count and subscribe if first listener\n this.streamRefCount++;\n if (this.streamRefCount === 1) {\n // Add subscription with accuracy rate — v2 uses LocationStreamRequest format\n this.deps.addSubscription(streamKey);\n this.deps.logger.debug({ accuracy }, `[LocationManager] Subscribed to \"${streamKey}\".`);\n }\n\n // Return composite cleanup\n return () => {\n if (!this.registrations.has(reg)) return; // Already cleaned up (idempotent)\n\n routerCleanup();\n updateCleanup();\n this.registrations.delete(reg);\n\n // Decrement ref count and unsubscribe if last listener\n this.streamRefCount--;\n if (this.streamRefCount <= 0) {\n this.streamRefCount = 0;\n this.deps.removeSubscription(streamKey);\n this.deps.logger.debug(`[LocationManager] Unsubscribed from \"${streamKey}\".`);\n }\n };\n }\n\n /**\n * Request a single location update (one-shot poll).\n *\n * Sends a `location_poll_request` message to the cloud and returns a\n * Promise that resolves with the {@link LocationData} when the correlated\n * response arrives. The response will also be delivered to any active\n * `onUpdate()` listeners and will update the cached position.\n *\n * Uses the accuracy level set via {@link configure}. Defaults to `\"standard\"`.\n *\n * @returns A promise that resolves with the location data from the poll.\n * @throws If the poll times out (default: 15 seconds).\n *\n * @example\n * ```ts\n * session.location.configure({ accuracy: \"high\" });\n * const loc = await session.location.requestUpdate();\n * console.log(`${loc.lat}, ${loc.lng}`);\n * ```\n */\n requestUpdate(): Promise<LocationData> {\n const correlationId = generateCorrelationId();\n const accuracy = this._config.accuracy ?? \"standard\";\n\n return new Promise<LocationData>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n this.pendingPolls.delete(correlationId);\n reject(new Error(`Location poll timed out after ${POLL_TIMEOUT_MS}ms (correlationId: ${correlationId})`));\n }, POLL_TIMEOUT_MS);\n\n this.pendingPolls.set(correlationId, { resolve, reject, timeoutId });\n\n const message = {\n type: AppToCloudMessageType.LOCATION_POLL_REQUEST,\n correlationId,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n accuracy,\n };\n\n try {\n this.deps.sendMessage(message);\n this.deps.logger.debug({ correlationId, accuracy }, \"📍 Location poll request sent\");\n } catch (err) {\n clearTimeout(timeoutId);\n this.pendingPolls.delete(correlationId);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n /**\n * Stop all location subscriptions and remove every handler.\n *\n * After calling this, no location callbacks will fire until new\n * subscriptions are created via {@link onUpdate}.\n *\n * @example\n * ```ts\n * session.location.stop();\n * ```\n */\n stop(): void {\n // Iterate over a snapshot — cleanup mutates the set\n const snapshot = Array.from(this.registrations);\n for (const reg of snapshot) {\n reg.routerCleanup();\n reg.updateCleanup();\n this.registrations.delete(reg);\n }\n\n // Force unsubscribe regardless of ref count\n if (this.streamRefCount > 0) {\n this.deps.removeSubscription(LOCATION_STREAM);\n }\n this.streamRefCount = 0;\n\n // Reject and clean up any pending polls\n for (const [id, pending] of this.pendingPolls) {\n clearTimeout(pending.timeoutId);\n pending.reject(new Error(\"LocationManager stopped while poll was pending\"));\n this.pendingPolls.delete(id);\n }\n\n this.deps.logger.debug(\"[LocationManager] All subscriptions stopped.\");\n }\n\n // ─── Cached Accessors ──────────────────────────────────────────────────\n\n /**\n * Latest known latitude, or `null` if no location update has been received.\n */\n get lat(): number | null {\n return this._lat;\n }\n\n /**\n * Latest known longitude, or `null` if no location update has been received.\n */\n get lng(): number | null {\n return this._lng;\n }\n\n /**\n * Latest horizontal accuracy in metres, or `null` if unknown.\n */\n get accuracy(): number | null {\n return this._accuracy;\n }\n\n /**\n * Unix timestamp (ms) of the latest location update, or `null` if none received.\n */\n get timestamp(): number | null {\n return this._timestamp;\n }\n\n /**\n * Whether the device has granted location permission.\n *\n * Optimistically `true` — updated to `false` if a permission error\n * is received from the cloud.\n */\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n // ─── Internal ───────────────────────────────────────────────────────────\n\n /**\n * Check if incoming data matches a pending one-shot poll and resolve it.\n */\n private resolvePendingPoll(raw: any): void {\n const correlationId: string | undefined = raw?.correlationId;\n if (!correlationId) return;\n\n const pending = this.pendingPolls.get(correlationId);\n if (!pending) return;\n\n clearTimeout(pending.timeoutId);\n this.pendingPolls.delete(correlationId);\n pending.resolve(normalise(raw));\n }\n\n /**\n * Update cached location values from raw incoming data.\n */\n private cacheLocation(raw: any): void {\n if (typeof raw.lat === \"number\") {\n this._lat = raw.lat;\n }\n if (typeof raw.lng === \"number\") {\n this._lng = raw.lng;\n }\n if (typeof raw.accuracy === \"number\") {\n this._accuracy = raw.accuracy;\n }\n this._timestamp = raw.timestamp ? new Date(raw.timestamp).getTime() : Date.now();\n }\n\n /**\n * Called by MentraSession if a permission error for location is received.\n * @internal\n */\n setPermission(granted: boolean): void {\n this._hasPermission = granted;\n }\n\n // ─── Cleanup ────────────────────────────────────────────────────────────\n\n /**\n * Clean up all resources.\n *\n * Called by MentraSession during disconnect/cleanup.\n * @internal\n */\n destroy(): void {\n this.stop();\n\n if (this.locationUpdateCleanup) {\n this.locationUpdateCleanup();\n this.locationUpdateCleanup = null;\n }\n\n this._lat = null;\n this._lng = null;\n this._accuracy = null;\n this._timestamp = null;\n this._config = {};\n\n this.deps.logger.debug(\"[LocationManager] Destroyed.\");\n }\n}\n",
|
|
31
31
|
"/**\n * 🎤 MicManager — Microphone Input Control\n *\n * v3 manager that handles audio input from the user's glasses microphone.\n * Provides subscriptions for raw PCM audio chunks and voice activity\n * detection (VAD) events.\n *\n * Audio chunks arrive as binary WebSocket frames — MentraSession calls\n * `handleBinaryAudio()` when it receives a binary frame that isn't\n * destined for an output stream. VAD events arrive as JSON DATA_STREAM\n * messages routed through the DataStreamRouter.\n *\n * @example\n * ```ts\n * const mic = new MicManager(deps);\n *\n * // Listen for raw audio\n * const stopChunks = mic.onChunk((chunk) => {\n * console.log(`Got ${chunk.data.byteLength} bytes at ${chunk.sampleRate}Hz`);\n * });\n *\n * // Listen for voice activity\n * const stopVad = mic.onVoiceActivity((vad) => {\n * console.log(vad.isSpeaking ? \"Speech started\" : \"Speech ended\");\n * });\n *\n * // Check state\n * console.log(\"Speaking:\", mic.isSpeaking);\n * console.log(\"Active:\", mic.isActive);\n *\n * // Cleanup\n * mic.stop();\n * ```\n */\n\n// ─── Dependencies ────────────────────────────────────────────────────────────\n\n/**\n * Shared dependency bag injected by MentraSession.\n * Keeps managers decoupled from the session implementation.\n */\nexport interface ManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n addSubscription: (stream: string) => void;\n removeSubscription: (stream: string) => void;\n sendMessage: (message: any) => void;\n sendBinary: (data: ArrayBuffer | Uint8Array) => void;\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\n// ─── Public Types ────────────────────────────────────────────────────────────\n\n/**\n * A chunk of raw PCM audio data from the glasses microphone.\n *\n * Audio is always 16 kHz mono 16-bit signed PCM — the native format\n * of the glasses microphone hardware.\n */\nexport interface AudioChunk {\n /** Raw PCM audio data */\n data: ArrayBuffer;\n /** Sample rate in Hz (always 16000) */\n sampleRate: number;\n /** Number of audio channels (always 1 — mono) */\n channels: number;\n /** Timestamp when this chunk was received (ms since epoch) */\n timestamp: number;\n}\n\n/**\n * Voice activity detection event.\n *\n * Indicates whether the user is currently speaking. The glasses run\n * on-device VAD and send status updates as the speech state changes.\n */\nexport interface VadEvent {\n /** Whether speech is currently detected */\n isSpeaking: boolean;\n /** Timestamp when this event was received (ms since epoch) */\n timestamp: number;\n}\n\n// ─── Stream Type Constants ───────────────────────────────────────────────────\n\n/** Stream type for audio chunk subscriptions (matches StreamType.AUDIO_CHUNK) */\nconst AUDIO_CHUNK_STREAM = \"audio_chunk\";\n\n/** Stream type for VAD subscriptions (matches StreamType.VAD) */\nconst VAD_STREAM = \"VAD\";\n\n// ─── MicManager ─────────────────────────────────────────────────────────────\n\n/**\n * Manages microphone input from the user's glasses.\n *\n * Handles two types of incoming data:\n *\n * 1. **Raw PCM audio chunks** — arrive as binary WebSocket frames.\n * MentraSession calls `handleBinaryAudio()` for each binary frame\n * that isn't part of an output stream. Subscribers receive wrapped\n * `AudioChunk` objects with metadata.\n *\n * 2. **Voice Activity Detection (VAD)** — arrives as JSON DATA_STREAM\n * messages with `streamType: \"VAD\"`. The glasses send `status: true`\n * when speech starts and `status: false` when it stops. The raw\n * `status` field may be a boolean or string (\"true\"/\"false\") — this\n * manager normalizes it to a clean boolean.\n *\n * Subscription lifecycle:\n * - `onChunk()` adds an \"audio_chunk\" subscription when the first handler\n * is registered, and removes it when the last handler unsubscribes.\n * - `onVoiceActivity()` does the same for the \"VAD\" subscription.\n * - `stop()` removes all handlers and unsubscribes from both streams.\n */\nexport class MicManager {\n private readonly deps: ManagerDeps;\n\n /** Registered handlers for audio chunk data */\n private chunkHandlers = new Set<(chunk: AudioChunk) => void>();\n\n /** Registered handlers for VAD events */\n private vadHandlers = new Set<(vad: VadEvent) => void>();\n\n /** Cleanup function for the VAD router subscription */\n private vadRouterCleanup: (() => void) | null = null;\n\n /** Cached latest VAD state — true when speech is detected */\n private _isSpeaking = false;\n\n /** Cached permission state */\n private _hasPermission = true;\n\n constructor(deps: ManagerDeps) {\n this.deps = deps;\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Whether speech is currently detected.\n *\n * This value is cached from the most recent VAD event. It is only\n * updated while there is at least one `onVoiceActivity` subscriber.\n *\n * @example\n * ```ts\n * if (mic.isSpeaking) {\n * // User is talking — maybe pause TTS\n * }\n * ```\n */\n get isSpeaking(): boolean {\n return this._isSpeaking;\n }\n\n /**\n * Whether this app has an active `onChunk` subscription.\n *\n * Returns true when at least one audio chunk handler is registered,\n * meaning the microphone stream is subscribed and binary audio data\n * is being delivered.\n */\n get isActive(): boolean {\n return this.chunkHandlers.size > 0;\n }\n\n /**\n * Whether the app has microphone permission.\n *\n * Updated when the cloud sends permission state changes. Apps that\n * require microphone access should declare `MICROPHONE` in their\n * hardware requirements.\n */\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n /**\n * 🎤 Subscribe to raw PCM audio chunks from the microphone.\n *\n * Audio is always 16 kHz mono 16-bit signed PCM. The first subscriber\n * triggers an \"audio_chunk\" subscription to the cloud; the subscription\n * is removed when the last handler unsubscribes.\n *\n * @param handler - Called with each audio chunk as it arrives\n * @returns Cleanup function that removes this handler\n *\n * @example\n * ```ts\n * const stop = mic.onChunk((chunk) => {\n * // chunk.data is an ArrayBuffer of PCM16 samples\n * const samples = new Int16Array(chunk.data);\n * processAudio(samples);\n * });\n *\n * // Later: unsubscribe\n * stop();\n * ```\n */\n onChunk(handler: (chunk: AudioChunk) => void): () => void {\n const isFirst = this.chunkHandlers.size === 0;\n\n this.chunkHandlers.add(handler);\n\n // Subscribe to the audio_chunk stream when the first handler registers\n if (isFirst) {\n this.deps.addSubscription(AUDIO_CHUNK_STREAM);\n this.deps.logger.debug(\"Subscribed to audio_chunk stream\");\n }\n\n // Return cleanup function\n return () => {\n this.chunkHandlers.delete(handler);\n\n // Unsubscribe when the last handler is removed\n if (this.chunkHandlers.size === 0) {\n this.deps.removeSubscription(AUDIO_CHUNK_STREAM);\n this.deps.logger.debug(\"Unsubscribed from audio_chunk stream\");\n }\n };\n }\n\n /**\n * 🗣️ Subscribe to voice activity detection events.\n *\n * VAD events indicate when the user starts or stops speaking. The\n * `status` field from the glasses may be a boolean or a string\n * (\"true\"/\"false\") — this manager normalizes it to a clean boolean.\n *\n * The first subscriber triggers a \"VAD\" subscription to the cloud and\n * registers a handler on the DataStreamRouter. The subscription is\n * removed when the last handler unsubscribes.\n *\n * @param handler - Called with each VAD event\n * @returns Cleanup function that removes this handler\n *\n * @example\n * ```ts\n * const stop = mic.onVoiceActivity((vad) => {\n * if (vad.isSpeaking) {\n * console.log(\"User started speaking\");\n * } else {\n * console.log(\"User stopped speaking\");\n * }\n * });\n *\n * // Later: unsubscribe\n * stop();\n * ```\n */\n onVoiceActivity(handler: (vad: VadEvent) => void): () => void {\n const isFirst = this.vadHandlers.size === 0;\n\n this.vadHandlers.add(handler);\n\n // Subscribe and register router handler when the first handler registers\n if (isFirst) {\n this.deps.addSubscription(VAD_STREAM);\n\n // Listen for VAD DATA_STREAM messages on the router\n this.vadRouterCleanup = this.deps.router.on(VAD_STREAM, (_streamType: string, data: any, _message: any) => {\n this.handleVadMessage(data);\n });\n\n this.deps.logger.debug(\"Subscribed to VAD stream\");\n }\n\n // Return cleanup function\n return () => {\n this.vadHandlers.delete(handler);\n\n // Unsubscribe and remove router handler when the last handler is removed\n if (this.vadHandlers.size === 0) {\n this.deps.removeSubscription(VAD_STREAM);\n\n if (this.vadRouterCleanup) {\n this.vadRouterCleanup();\n this.vadRouterCleanup = null;\n }\n\n this.deps.logger.debug(\"Unsubscribed from VAD stream\");\n }\n };\n }\n\n /**\n * 🛑 Stop all microphone subscriptions.\n *\n * Removes all registered chunk and VAD handlers, unsubscribes from\n * both streams, and resets internal state. After calling `stop()`,\n * `isActive` will be false and no more callbacks will fire.\n *\n * @example\n * ```ts\n * mic.onChunk(handleChunk);\n * mic.onVoiceActivity(handleVad);\n *\n * // Later: clean up everything\n * mic.stop();\n * ```\n */\n stop(): void {\n // Clean up chunk handlers\n if (this.chunkHandlers.size > 0) {\n this.chunkHandlers.clear();\n this.deps.removeSubscription(AUDIO_CHUNK_STREAM);\n this.deps.logger.debug(\"Stopped audio_chunk subscriptions\");\n }\n\n // Clean up VAD handlers\n if (this.vadHandlers.size > 0) {\n this.vadHandlers.clear();\n this.deps.removeSubscription(VAD_STREAM);\n\n if (this.vadRouterCleanup) {\n this.vadRouterCleanup();\n this.vadRouterCleanup = null;\n }\n\n this.deps.logger.debug(\"Stopped VAD subscriptions\");\n }\n\n // Reset cached state\n this._isSpeaking = false;\n }\n\n // ─── Binary Audio Ingestion ──────────────────────────────────────────────\n\n /**\n * Handle an incoming binary audio frame from the WebSocket transport.\n *\n * MentraSession calls this method when it receives a binary WebSocket\n * frame that is identified as microphone audio (not part of an output\n * stream). The raw bytes are wrapped with metadata and dispatched to\n * all registered `onChunk` handlers.\n *\n * @param data - Raw binary audio data (PCM16, 16 kHz, mono)\n *\n * @remarks\n * This is a public method so MentraSession can call it, but it is not\n * intended to be called by app developers.\n *\n * @internal\n */\n handleBinaryAudio(data: ArrayBuffer): void {\n if (this.chunkHandlers.size === 0) {\n // No subscribers — skip processing\n return;\n }\n\n const chunk: AudioChunk = {\n data,\n sampleRate: 16000,\n channels: 1,\n timestamp: Date.now(),\n };\n\n for (const handler of this.chunkHandlers) {\n try {\n handler(chunk);\n } catch (err) {\n this.deps.logger.error(\"Audio chunk handler error:\", err);\n }\n }\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n /**\n * Process an incoming VAD DATA_STREAM message.\n *\n * The glasses send VAD with `status` that can be:\n * - `true` / `false` (boolean)\n * - `\"true\"` / `\"false\"` (string)\n *\n * This method normalizes the value to a clean boolean and caches it\n * for the `isSpeaking` getter.\n */\n private handleVadMessage(data: any): void {\n if (!data) return;\n\n // Normalize status: boolean | \"true\" | \"false\" → boolean\n const rawStatus = data.status;\n let isSpeaking: boolean;\n\n if (typeof rawStatus === \"boolean\") {\n isSpeaking = rawStatus;\n } else if (typeof rawStatus === \"string\") {\n isSpeaking = rawStatus.toLowerCase() === \"true\";\n } else {\n this.deps.logger.warn(\"Unexpected VAD status type:\", typeof rawStatus, rawStatus);\n return;\n }\n\n // Update cached state\n this._isSpeaking = isSpeaking;\n\n // Build the normalized event\n const event: VadEvent = {\n isSpeaking,\n timestamp: Date.now(),\n };\n\n // Dispatch to all registered handlers\n for (const handler of this.vadHandlers) {\n try {\n handler(event);\n } catch (err) {\n this.deps.logger.error(\"VAD handler error:\", err);\n }\n }\n }\n}\n",
|
|
32
|
-
"/**\n * PermissionsManager — App Permission State\n *\n * Tracks which permissions the current app has been granted based on\n * the app's manifest/registration on the developer console. Permissions\n * are populated when the session connects (from CONNECTION_ACK settings)\n * and can be queried synchronously by other managers.\n *\n * This manager is read-only from the app's perspective — permissions are\n * controlled by the platform, not the app.\n *\n * @example\n * ```ts\n * // Check a single permission\n * if (permissions.has(\"camera\")) {\n * // Safe to use camera APIs\n * }\n *\n * // Get all permissions\n * const all = permissions.getAll();\n * console.log(\"Notifications allowed:\", all.notifications);\n *\n * // React to permission changes\n * const cleanup = permissions.onUpdate((perms) => {\n * console.log(\"Permissions updated:\", perms);\n * });\n * ```\n *\n * @module\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\n/**\n * Permission types supported by the MentraOS platform.\n *\n * These correspond to capabilities and data streams that require\n * explicit opt-in via the developer console app manifest.\n */\nexport type PermissionType = \"location\" | \"microphone\" | \"camera\" | \"notifications\" | \"calendar\";\n\n/**\n * Complete permission record mapping every permission type to its grant status.\n */\nexport type PermissionRecord = Record<PermissionType, boolean>;\n\n/**\n * Dependencies injected by MentraSession.\n */\nexport interface PermissionsManagerDeps {\n /** Logger instance scoped to the session. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────\n\n/** All known permission types, used for iteration and defaults. */\nconst ALL_PERMISSIONS: readonly PermissionType[] = [\n \"location\",\n \"microphone\",\n \"camera\",\n \"notifications\",\n \"calendar\",\n] as const;\n\n/**\n * Returns a fresh default permission record with all permissions denied.\n */\nfunction createDefaultPermissions(): PermissionRecord {\n return {\n location: false,\n microphone: false,\n camera: false,\n notifications: false,\n calendar: false,\n };\n}\n\n// ─── PermissionsManager ─────────────────────────────────────────────────────\n\n/**\n * Manages the permission state for the current app session.\n *\n * Permissions are populated from the CONNECTION_ACK payload when the\n * session is established. Other managers (DeviceManager, PhoneManager)\n * query this manager to gate access to protected streams.\n *\n * The manager emits updates whenever the permission set changes, allowing\n * UI or logic to react to permission grants/revocations in real time.\n */\nexport class PermissionsManager {\n /** Current permission state. */\n private permissions: PermissionRecord;\n\n /** Registered update listeners. */\n private listeners: Set<(permissions: PermissionRecord) => void> = new Set();\n\n /** Logger instance. */\n private logger: PermissionsManagerDeps[\"logger\"];\n\n constructor(deps: PermissionsManagerDeps) {\n this.logger = deps.logger;\n this.permissions = createDefaultPermissions();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Check whether the app has been granted a specific permission.\n *\n * @param permission - The permission type to check\n * @returns `true` if the permission is granted, `false` otherwise\n *\n * @example\n * ```ts\n * if (permissions.has(\"microphone\")) {\n * session.events.onTranscription(handler);\n * }\n * ```\n */\n has(permission: PermissionType): boolean {\n return this.permissions[permission] ?? false;\n }\n\n /**\n * Get a snapshot of all permissions as a record.\n *\n * The returned object is a copy — mutations do not affect internal state.\n *\n * @returns A record mapping every {@link PermissionType} to its grant status\n *\n * @example\n * ```ts\n * const perms = permissions.getAll();\n * console.log(\"Camera:\", perms.camera);\n * console.log(\"Location:\", perms.location);\n * ```\n */\n getAll(): PermissionRecord {\n return { ...this.permissions };\n }\n\n /**\n * Subscribe to permission updates.\n *\n * The handler is called whenever the permission set changes (e.g., on\n * CONNECTION_ACK or a mid-session settings update). It receives a\n * snapshot copy of the full permission record.\n *\n * @param handler - Callback invoked with the updated permission record\n * @returns Cleanup function that removes the listener\n *\n * @example\n * ```ts\n * const cleanup = permissions.onUpdate((perms) => {\n * if (!perms.camera) {\n * console.warn(\"Camera permission revoked\");\n * }\n * });\n *\n * // Later: stop listening\n * cleanup();\n * ```\n */\n onUpdate(handler: (permissions: PermissionRecord) => void): () => void {\n this.listeners.add(handler);\n return () => {\n this.listeners.delete(handler);\n };\n }\n\n // ─── Internal (called by MentraSession) ─────────────────────────────────\n\n /**\n * Update permissions from connection settings or a settings update payload.\n *\n * Called internally by MentraSession when:\n * - A CONNECTION_ACK is received with initial settings/permissions\n * - A mid-session settings update includes permission changes\n *\n * Accepts flexible input — extracts permissions from nested structures\n * commonly found in CONNECTION_ACK and settings_update payloads.\n *\n * @param settings - The raw settings object from the cloud message\n * @internal\n */\n updateFromSettings(settings: any): void {\n if (!settings) {\n this.logger.debug(\"PermissionsManager: No settings provided, skipping update\");\n return;\n }\n\n const previous = { ...this.permissions };\n let updated = false;\n\n // Extract permissions from various possible payload shapes:\n // { permissions: { camera: true, ... } }\n // { appPermissions: { camera: true, ... } }\n // { camera: true, microphone: false, ... } (flat)\n const permissionsSource = settings.permissions ?? settings.appPermissions ?? settings;\n\n for (const perm of ALL_PERMISSIONS) {\n if (perm in permissionsSource) {\n const value = Boolean(permissionsSource[perm]);\n if (this.permissions[perm] !== value) {\n this.permissions[perm] = value;\n updated = true;\n }\n }\n }\n\n if (updated) {\n this.logger.info(\n \"PermissionsManager: Permissions updated — \" +\n ALL_PERMISSIONS.map((p) => `${p}=${this.permissions[p]}`).join(\", \"),\n );\n\n // Log individual changes at debug level\n for (const perm of ALL_PERMISSIONS) {\n if (previous[perm] !== this.permissions[perm]) {\n this.logger.debug(`PermissionsManager: ${perm}: ${previous[perm]} → ${this.permissions[perm]}`);\n }\n }\n\n // Notify listeners with a snapshot copy\n const snapshot = this.getAll();\n for (const listener of this.listeners) {\n try {\n listener(snapshot);\n } catch (err) {\n this.logger.error(\n `PermissionsManager: Error in onUpdate listener: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n } else {\n this.logger.debug(\"PermissionsManager: No permission changes detected\");\n }\n }\n}\n",
|
|
33
|
-
"/**\n * PhoneManager — Phone-Scoped Event Management\n *\n * Consolidates all phone-related data streams into a single manager\n * with purpose-built sub-managers:\n *\n * - **notifications** — Phone notification events and dismissals\n * - **calendar** — Calendar event stream\n * - **battery** — Phone battery level tracking\n *\n * Each sub-manager exposes a `hasPermission` getter that delegates to\n * the {@link PermissionsManager}, giving callers a convenient way to\n * check access before subscribing.\n *\n * All handler registrations return a cleanup function. Subscriptions\n * are managed automatically — `addSubscription` is called when the\n * first handler for a stream is registered, and `removeSubscription`\n * when the last handler is removed.\n *\n * @example\n * ```ts\n * // Phone battery\n * console.log(\"Phone battery:\", phone.battery);\n * phone.onBatteryUpdate((e) => {\n * console.log(\"Phone battery:\", e.level, \"%\");\n * });\n *\n * // Notifications (with permission check)\n * if (phone.notifications.hasPermission) {\n * phone.notifications.on((n) => {\n * console.log(`${n.app}: ${n.title}`);\n * });\n * }\n *\n * // Calendar events\n * if (phone.calendar.hasPermission) {\n * phone.calendar.on((event) => {\n * console.log(event.title, event.start, \"→\", event.end);\n * });\n * }\n * ```\n *\n * @module\n */\n\nimport { StreamType } from \"../../types/streams\";\nimport type { PermissionsManager } from \"./PermissionsManager\";\n\n// ─── Event Types ────────────────────────────────────────────────────────────\n\n/**\n * Phone notification event delivered from the companion app.\n */\nexport interface PhoneNotificationEvent {\n /** Unique identifier for this notification. */\n notificationId: string;\n /** Source application package/name. */\n app: string;\n /** Notification title. */\n title: string;\n /** Notification body content. */\n content: string;\n /** Notification priority level. */\n priority: \"low\" | \"normal\" | \"high\";\n}\n\n/**\n * Event emitted when a phone notification is dismissed by the user.\n */\nexport interface NotificationDismissedEvent {\n /** Unique identifier of the dismissed notification. */\n notificationId: string;\n /** Source application package/name. */\n app: string;\n /** Notification title. */\n title: string;\n /** Notification body content. */\n content: string;\n /** Platform-specific notification key. */\n notificationKey: string;\n}\n\n/**\n * Normalised calendar event data.\n *\n * Raw wire fields are normalised for a cleaner developer experience:\n * - `dtStart` → `start`\n * - `dtEnd` → `end`\n * - `timeStamp` → `timestamp`\n */\nexport interface CalendarEventData {\n /** Calendar event identifier. */\n eventId: string;\n /** Event title/summary. */\n title: string;\n /** Normalised start time (ISO string). */\n start: string;\n /** Normalised end time (ISO string). */\n end: string;\n /** Event timezone. */\n timezone: string;\n /** Normalised timestamp of the event update (ISO string). */\n timestamp: string;\n /** Any additional fields from the raw payload. */\n [key: string]: any;\n}\n\n/**\n * Phone battery update event.\n */\nexport interface PhoneBatteryEvent {\n /** Battery level 0–100. */\n level: number;\n /** Whether the phone is currently charging. */\n charging: boolean;\n /** Estimated minutes remaining (if available). */\n timeRemaining?: number;\n}\n\n// ─── Dependency Types ───────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession into the PhoneManager.\n */\nexport interface PhoneManagerDeps {\n /** DataStreamRouter — register for stream-type events. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Subscribe to a data stream (sent to cloud). */\n addSubscription: (stream: string) => void;\n /** Unsubscribe from a data stream. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary message to the cloud. */\n sendMessage: (message: any) => void;\n /** Session-scoped logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Returns the current app's package name. */\n getPackageName: () => string;\n /** Returns the active session ID. */\n getSessionId: () => string;\n /** PermissionsManager for gating protected streams. */\n permissions: PermissionsManager;\n}\n\n// ─── Internal Helpers ───────────────────────────────────────────────────────\n\n/**\n * Normalise raw calendar event data from the wire format.\n *\n * - `dtStart` → `start`\n * - `dtEnd` → `end`\n * - `timeStamp` → `timestamp`\n */\nfunction normaliseCalendarEvent(raw: any): CalendarEventData {\n return {\n ...raw,\n eventId: raw.eventId ?? raw.event_id ?? \"unknown\",\n title: raw.title ?? \"\",\n start: raw.dtStart ?? raw.start ?? \"\",\n end: raw.dtEnd ?? raw.end ?? \"\",\n timezone: raw.timezone ?? \"\",\n timestamp: raw.timeStamp ?? raw.timestamp ?? new Date().toISOString(),\n };\n}\n\n// ─── Stream Handler Bookkeeping ─────────────────────────────────────────────\n\n/**\n * Shared ref-counting logic for stream subscriptions.\n *\n * Tracks handler counts per stream key and calls `addSubscription` /\n * `removeSubscription` at the appropriate lifecycle boundaries.\n * Identical pattern to the `addStreamHandler` private method in DeviceManager,\n * extracted here so all three PhoneManager sub-concerns can share it.\n */\nclass StreamHandlerTracker {\n /** Ref-counted handler totals keyed by stream string. */\n private handlerCounts: Map<string, number> = new Map();\n\n /** All cleanup functions for bulk teardown. */\n private cleanups: Array<() => void> = [];\n\n constructor(\n private router: PhoneManagerDeps[\"router\"],\n private addSubscription: PhoneManagerDeps[\"addSubscription\"],\n private removeSubscription: PhoneManagerDeps[\"removeSubscription\"],\n ) {}\n\n /**\n * Register a handler on the DataStreamRouter for a given stream key,\n * managing subscription lifecycle automatically.\n *\n * - Calls `addSubscription` when the first handler for a key is added.\n * - Calls `removeSubscription` when the last handler for a key is removed.\n *\n * @param streamKey - The stream type string\n * @param handler - The stream handler function\n * @returns Cleanup function that unregisters the handler and manages subscription\n */\n add(streamKey: string, handler: (streamType: string, data: any, message: any) => void): () => void {\n const currentCount = this.handlerCounts.get(streamKey) ?? 0;\n\n // First handler for this stream — subscribe\n if (currentCount === 0) {\n this.addSubscription(streamKey);\n }\n this.handlerCounts.set(streamKey, currentCount + 1);\n\n // Register on the router\n const routerCleanup = this.router.on(streamKey, handler);\n\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n\n // Remove from router\n routerCleanup();\n\n // Decrement handler count\n const count = this.handlerCounts.get(streamKey) ?? 0;\n const newCount = count - 1;\n if (newCount <= 0) {\n this.handlerCounts.delete(streamKey);\n this.removeSubscription(streamKey);\n } else {\n this.handlerCounts.set(streamKey, newCount);\n }\n };\n\n this.cleanups.push(cleanup);\n return cleanup;\n }\n\n /**\n * Remove all tracked handlers and unsubscribe from all streams.\n * Called during session teardown.\n */\n destroyAll(): void {\n for (const fn of this.cleanups) {\n fn();\n }\n this.cleanups.length = 0;\n this.handlerCounts.clear();\n }\n}\n\n// ─── NotificationSubManager ─────────────────────────────────────────────────\n\n/**\n * Sub-manager for phone notification streams.\n *\n * Provides handlers for incoming notifications and notification dismissals,\n * plus a convenience `hasPermission` check.\n *\n * @example\n * ```ts\n * if (phone.notifications.hasPermission) {\n * phone.notifications.on((n) => {\n * showOnGlasses(`${n.app}: ${n.title}`);\n * });\n *\n * phone.notifications.onDismissed((e) => {\n * removeFromGlasses(e.notificationId);\n * });\n * }\n * ```\n */\nexport class NotificationSubManager {\n private permissions: PermissionsManager;\n private tracker: StreamHandlerTracker;\n private logger: PhoneManagerDeps[\"logger\"];\n\n /** @internal */\n constructor(permissions: PermissionsManager, tracker: StreamHandlerTracker, logger: PhoneManagerDeps[\"logger\"]) {\n this.permissions = permissions;\n this.tracker = tracker;\n this.logger = logger;\n }\n\n /**\n * Whether the app has the `notifications` permission.\n *\n * Reads from the {@link PermissionsManager} — this is a live check,\n * not a cached value.\n */\n get hasPermission(): boolean {\n return this.permissions.has(\"notifications\");\n }\n\n /**\n * Listen for incoming phone notifications.\n *\n * @param handler - Called with {@link PhoneNotificationEvent} for each notification\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = phone.notifications.on((n) => {\n * console.log(`[${n.priority}] ${n.app}: ${n.title} — ${n.content}`);\n * });\n * ```\n */\n on(handler: (notification: PhoneNotificationEvent) => void): () => void {\n return this.tracker.add(StreamType.PHONE_NOTIFICATION, (_streamType, data) => {\n try {\n handler({\n notificationId: data.notificationId ?? data.notification_id ?? \"unknown\",\n app: data.app ?? \"unknown\",\n title: data.title ?? \"\",\n content: data.content ?? \"\",\n priority: data.priority ?? \"normal\",\n });\n } catch (err) {\n this.logger.error(\n `NotificationSubManager: Error in notification handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n\n /**\n * Listen for notification dismissal events.\n *\n * Fired when the user dismisses a notification on their phone.\n *\n * @param handler - Called with {@link NotificationDismissedEvent} for each dismissal\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * phone.notifications.onDismissed((e) => {\n * console.log(\"Dismissed:\", e.notificationId, \"from\", e.app);\n * });\n * ```\n */\n onDismissed(handler: (event: NotificationDismissedEvent) => void): () => void {\n return this.tracker.add(StreamType.PHONE_NOTIFICATION_DISMISSED, (_streamType, data) => {\n try {\n handler({\n notificationId: data.notificationId ?? data.notification_id ?? \"unknown\",\n app: data.app ?? \"unknown\",\n title: data.title ?? \"\",\n content: data.content ?? \"\",\n notificationKey: data.notificationKey ?? data.notification_key ?? \"\",\n });\n } catch (err) {\n this.logger.error(\n `NotificationSubManager: Error in dismissal handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n}\n\n// ─── CalendarSubManager ─────────────────────────────────────────────────────\n\n/**\n * Sub-manager for calendar event streams.\n *\n * Normalises raw calendar data (e.g. `dtStart` → `start`) and provides\n * a convenience `hasPermission` check.\n *\n * @example\n * ```ts\n * if (phone.calendar.hasPermission) {\n * phone.calendar.on((event) => {\n * console.log(`${event.title}: ${event.start} → ${event.end}`);\n * });\n * }\n * ```\n */\nexport class CalendarSubManager {\n private permissions: PermissionsManager;\n private tracker: StreamHandlerTracker;\n private logger: PhoneManagerDeps[\"logger\"];\n\n /** @internal */\n constructor(permissions: PermissionsManager, tracker: StreamHandlerTracker, logger: PhoneManagerDeps[\"logger\"]) {\n this.permissions = permissions;\n this.tracker = tracker;\n this.logger = logger;\n }\n\n /**\n * Whether the app has the `calendar` permission.\n *\n * Reads from the {@link PermissionsManager} — this is a live check,\n * not a cached value.\n */\n get hasPermission(): boolean {\n return this.permissions.has(\"calendar\");\n }\n\n /**\n * Listen for calendar events from the phone.\n *\n * Raw fields are normalised:\n * - `dtStart` → `start`\n * - `dtEnd` → `end`\n * - `timeStamp` → `timestamp`\n *\n * @param handler - Called with {@link CalendarEventData} for each event\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = phone.calendar.on((event) => {\n * console.log(`${event.title} at ${event.start} (${event.timezone})`);\n * });\n * ```\n */\n on(handler: (event: CalendarEventData) => void): () => void {\n return this.tracker.add(StreamType.CALENDAR_EVENT, (_streamType, data) => {\n try {\n handler(normaliseCalendarEvent(data));\n } catch (err) {\n this.logger.error(\n `CalendarSubManager: Error in calendar handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n}\n\n// ─── PhoneManager ───────────────────────────────────────────────────────────\n\n/**\n * Manages all phone-related data streams for a MentraSession.\n *\n * Exposes sub-managers for notifications and calendar, plus direct\n * battery-level tracking. Created by MentraSession and exposed as\n * `session.phone`.\n */\nexport class PhoneManager {\n // ─── Sub-Managers ─────────────────────────────────────────────────────\n\n /** Notification stream sub-manager. */\n readonly notifications: NotificationSubManager;\n\n /** Calendar event stream sub-manager. */\n readonly calendar: CalendarSubManager;\n\n // ─── Private ──────────────────────────────────────────────────────────\n\n private deps: PhoneManagerDeps;\n private permissions: PermissionsManager;\n private tracker: StreamHandlerTracker;\n\n /** Cached phone battery level (null until the first update is received). */\n private _battery: number | null = null;\n\n constructor(deps: PhoneManagerDeps) {\n this.deps = deps;\n this.permissions = deps.permissions;\n\n // Shared subscription tracker for all phone streams\n this.tracker = new StreamHandlerTracker(deps.router, deps.addSubscription, deps.removeSubscription);\n\n // Wire up sub-managers\n this.notifications = new NotificationSubManager(this.permissions, this.tracker, deps.logger);\n this.calendar = new CalendarSubManager(this.permissions, this.tracker, deps.logger);\n }\n\n // ─── Battery ──────────────────────────────────────────────────────────\n\n /**\n * The last-known phone battery level (0–100), or `null` if no update\n * has been received yet.\n *\n * This is a synchronous cached read — subscribe via {@link onBatteryUpdate}\n * to react to changes.\n *\n * @example\n * ```ts\n * const level = phone.battery;\n * if (level !== null && level < 20) {\n * console.warn(\"Phone battery low:\", level, \"%\");\n * }\n * ```\n */\n get battery(): number | null {\n return this._battery;\n }\n\n /**\n * Listen for phone battery update events.\n *\n * Also updates the cached {@link battery} value on every event.\n *\n * @param handler - Called with {@link PhoneBatteryEvent} on each update\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = phone.onBatteryUpdate((e) => {\n * console.log(\"Phone battery:\", e.level, \"%\", e.charging ? \"(charging)\" : \"\");\n * });\n *\n * // Later:\n * stop();\n * ```\n */\n onBatteryUpdate(handler: (event: PhoneBatteryEvent) => void): () => void {\n return this.tracker.add(StreamType.PHONE_BATTERY_UPDATE, (_streamType, data) => {\n // Cache the battery level from every incoming event\n const level = data.level ?? data.batteryLevel ?? data.battery_level;\n if (level !== undefined) {\n this._battery = level;\n }\n\n try {\n handler({\n level: level ?? 0,\n charging: data.charging ?? false,\n timeRemaining: data.timeRemaining ?? data.time_remaining,\n });\n } catch (err) {\n this.deps.logger.error(\n `PhoneManager: Error in battery handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n\n // ─── Cleanup ──────────────────────────────────────────────────────────\n\n /**\n * Remove all registered handlers and unsubscribe from all streams.\n *\n * Called by MentraSession during disconnect/teardown.\n * @internal\n */\n destroy(): void {\n this.tracker.destroyAll();\n this._battery = null;\n this.deps.logger.debug(\"PhoneManager: Destroyed.\");\n }\n}\n",
|
|
34
|
-
"/**\n * 🔊 SpeakerManager — Audio Output Control\n *\n * v3 manager that wraps the existing AudioManager output functionality.\n * Handles audio playback, text-to-speech, and real-time audio streaming\n * to the user's glasses speaker.\n *\n * Wire message formats are identical to v2 so the cloud receives the\n * same AUDIO_PLAY_REQUEST, AUDIO_STOP_REQUEST, AUDIO_STREAM_START,\n * AUDIO_STREAM_END, and binary frame protocol.\n *\n * @example\n * ```ts\n * const speaker = new SpeakerManager(deps);\n *\n * // Play a URL\n * const result = await speaker.play({ url: \"https://example.com/sound.mp3\" });\n *\n * // Text-to-speech\n * await speaker.speak(\"Hello, world!\", { volume: 0.8 });\n *\n * // Real-time streaming\n * const stream = await speaker.createStream({ format: \"mp3\" });\n * stream.write(mp3Chunk);\n * await stream.end();\n * ```\n */\n\nimport { AppToCloudMessageType, CloudToAppMessageType } from \"../../types/message-types\";\n\n// ─── Dependencies ────────────────────────────────────────────────────────────\n\n/**\n * Shared dependency bag injected by MentraSession.\n * Keeps managers decoupled from the session implementation.\n */\nexport interface ManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n addSubscription: (stream: string) => void;\n removeSubscription: (stream: string) => void;\n sendMessage: (message: any) => void;\n sendBinary: (data: ArrayBuffer | Uint8Array) => void;\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\n// ─── Public Types ────────────────────────────────────────────────────────────\n\n/** Audio track identifier. Multiple tracks can play simultaneously (mixing). */\nexport type TrackId = 0 | 1 | 2;\n\n/**\n * Options for playing an audio file from a URL.\n */\nexport interface PlayOptions {\n /** URL of the audio file to play */\n url: string;\n /** Volume level 0.0–1.0. Default: 1.0 */\n volume?: number;\n /**\n * Track ID for playback.\n * - 0: speaker (default audio playback)\n * - 1: app_audio (app-specific audio)\n * - 2: tts (text-to-speech audio)\n * Default: 0\n */\n trackId?: TrackId;\n /** Whether starting playback should stop other audio. Default: false */\n stopOtherAudio?: boolean;\n}\n\n/**\n * Result returned when audio playback completes.\n */\nexport interface PlayResult {\n /** Duration of the audio in milliseconds (when available) */\n duration: number;\n}\n\n/**\n * Options for text-to-speech playback.\n */\nexport interface SpeakOptions {\n /** ElevenLabs voice ID (optional — server picks a default) */\n voiceId?: string;\n /** ElevenLabs model ID (optional — defaults to eleven_flash_v2_5) */\n modelId?: string;\n /** Fine-grained voice settings */\n voiceSettings?: {\n stability?: number;\n similarityBoost?: number;\n style?: number;\n speed?: number;\n };\n /** Volume level 0.0–1.0. Default: 1.0 */\n volume?: number;\n /**\n * Track ID for playback. Default: 2 (tts)\n */\n trackId?: TrackId;\n /** Whether starting playback should stop other audio. Default: false */\n stopOtherAudio?: boolean;\n}\n\n/**\n * Options for creating a real-time audio output stream.\n */\nexport interface StreamOptions {\n /**\n * Format of the audio being written.\n * - \"mp3\": MP3 bytes passed through directly (ElevenLabs, OpenAI TTS, etc.)\n * - \"pcm16\": Raw 16-bit signed PCM samples (SDK encodes to MP3 before sending)\n * Default: \"mp3\"\n */\n format?: \"mp3\" | \"pcm16\";\n /** PCM sample rate in Hz (required when format is \"pcm16\"). Default: 24000 */\n sampleRate?: number;\n /** Number of audio channels. Default: 1 (mono) */\n channels?: 1 | 2;\n /** MP3 bitrate in kbps for PCM encoding. Default: 128 */\n bitrate?: number;\n /** Volume level 0.0–1.0. Default: 1.0 */\n volume?: number;\n /**\n * Track ID for playback. Default: 1 (app_audio)\n */\n trackId?: TrackId;\n /** Whether starting the stream should stop other audio. Default: true */\n stopOtherAudio?: boolean;\n}\n\n/** Lifecycle state of an AudioOutputStream */\nexport type AudioOutputStreamState = \"created\" | \"streaming\" | \"ending\" | \"ended\" | \"error\";\n\n/**\n * A real-time audio output stream.\n *\n * Audio data is sent as binary WebSocket frames with the protocol:\n * [36 bytes: streamId UUID as ASCII] [N bytes: audio data]\n *\n * The cloud pipes those bytes into an HTTP chunked response that the\n * phone's media player consumes like internet radio.\n */\nexport interface AudioOutputStream {\n /** Unique stream identifier (UUID) */\n readonly id: string;\n /** Current lifecycle state */\n readonly state: AudioOutputStreamState;\n /** Write audio data to the stream */\n write(chunk: Uint8Array): void;\n /** Gracefully end the stream — phone finishes buffered audio */\n end(): Promise<void>;\n /** Flush/interrupt — discard buffered audio, silence immediately */\n flush(): void;\n /** Register a callback for state changes */\n onStateChange(handler: (state: AudioOutputStreamState) => void): void;\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\n/** UUID length in ASCII bytes — used as the binary frame header */\nconst STREAM_ID_LENGTH = 36;\n\n/** How long to wait for AUDIO_STREAM_READY from the cloud (ms) */\nconst STREAM_READY_TIMEOUT_MS = 10_000;\n\n/** How long to wait for AUDIO_PLAY_RESPONSE from the cloud (ms) */\nconst PLAY_RESPONSE_TIMEOUT_MS = 60_000;\n\n// ─── AudioOutputStreamImpl ──────────────────────────────────────────────────\n\n/**\n * Internal implementation of the AudioOutputStream interface.\n * Manages the binary frame protocol and lifecycle messages.\n */\nclass AudioOutputStreamImpl implements AudioOutputStream {\n public readonly id: string;\n\n private _state: AudioOutputStreamState = \"created\";\n private readonly deps: ManagerDeps;\n private readonly streamIdBytes: Uint8Array;\n private readonly options: Required<\n Pick<StreamOptions, \"format\" | \"sampleRate\" | \"channels\" | \"bitrate\" | \"volume\" | \"trackId\" | \"stopOtherAudio\">\n >;\n private stateChangeHandlers: Array<(state: AudioOutputStreamState) => void> = [];\n private streamUrl: string | null = null;\n\n constructor(streamId: string, deps: ManagerDeps, opts: StreamOptions = {}) {\n this.id = streamId;\n this.deps = deps;\n\n this.options = {\n format: opts.format ?? \"mp3\",\n sampleRate: opts.sampleRate ?? 24000,\n channels: opts.channels ?? 1,\n bitrate: opts.bitrate ?? 128,\n volume: opts.volume ?? 1.0,\n trackId: opts.trackId ?? 1,\n stopOtherAudio: opts.stopOtherAudio ?? true,\n };\n\n // Pre-encode the streamId as ASCII bytes (reused on every write)\n this.streamIdBytes = new TextEncoder().encode(this.id);\n }\n\n get state(): AudioOutputStreamState {\n return this._state;\n }\n\n /**\n * Initialize the stream — sends AUDIO_STREAM_START and waits for the\n * relay URL from the cloud, then tells the phone to play it.\n * @internal Called by SpeakerManager.createStream()\n */\n async open(): Promise<void> {\n if (this._state !== \"created\") {\n throw new Error(`Cannot open stream in state \"${this._state}\"`);\n }\n\n // Send AUDIO_STREAM_START to the cloud\n const startMessage = {\n type: AppToCloudMessageType.AUDIO_STREAM_START,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.id,\n contentType: \"audio/mpeg\",\n timestamp: new Date(),\n };\n this.deps.sendMessage(startMessage);\n\n // Wait for AUDIO_STREAM_READY response with the relay URL\n this.streamUrl = await this.waitForReady();\n\n this.setState(\"streaming\");\n\n // Tell the phone to play the relay URL using existing audio play path\n const playMessage = {\n type: AppToCloudMessageType.AUDIO_PLAY_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId: `stream_${this.id}`,\n audioUrl: this.streamUrl,\n volume: this.options.volume,\n stopOtherAudio: this.options.stopOtherAudio,\n trackId: this.options.trackId,\n timestamp: new Date(),\n };\n this.deps.sendMessage(playMessage);\n\n this.deps.logger.debug(\"Audio output stream opened\", this.id);\n }\n\n write(chunk: Uint8Array): void {\n if (this._state !== \"streaming\") {\n this.deps.logger.debug(`Write called on non-streaming output (state=${this._state}), ignoring`);\n return;\n }\n\n if (chunk.length === 0) return;\n\n this.sendBinaryFrame(chunk);\n }\n\n async end(): Promise<void> {\n if (this._state !== \"streaming\") return;\n this.setState(\"ending\");\n\n // Tell the cloud to close the relay\n const endMessage = {\n type: AppToCloudMessageType.AUDIO_STREAM_END,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.id,\n timestamp: new Date(),\n };\n this.deps.sendMessage(endMessage);\n\n this.setState(\"ended\");\n this.deps.logger.debug(\"Audio output stream ended\");\n }\n\n flush(): void {\n if (this._state !== \"streaming\") return;\n this.setState(\"ending\");\n\n // End the stream on the cloud side\n const endMessage = {\n type: AppToCloudMessageType.AUDIO_STREAM_END,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.id,\n timestamp: new Date(),\n };\n this.deps.sendMessage(endMessage);\n\n // Also explicitly stop audio playback on the phone\n const stopMessage = {\n type: AppToCloudMessageType.AUDIO_STOP_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n trackId: this.options.trackId,\n timestamp: new Date(),\n };\n this.deps.sendMessage(stopMessage);\n\n this.setState(\"ended\");\n this.deps.logger.debug(\"Audio output stream flushed (interrupted)\");\n }\n\n onStateChange(handler: (state: AudioOutputStreamState) => void): void {\n this.stateChangeHandlers.push(handler);\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n private setState(state: AudioOutputStreamState): void {\n this._state = state;\n for (const handler of this.stateChangeHandlers) {\n try {\n handler(state);\n } catch (err) {\n this.deps.logger.error(\"AudioOutputStream state change handler error:\", err);\n }\n }\n }\n\n /**\n * Send a binary frame over the WebSocket.\n * Frame format: [36 bytes streamId ASCII] [N bytes audio data]\n */\n private sendBinaryFrame(audioData: Uint8Array): void {\n const frame = new Uint8Array(STREAM_ID_LENGTH + audioData.length);\n frame.set(this.streamIdBytes, 0);\n frame.set(audioData, STREAM_ID_LENGTH);\n\n try {\n this.deps.sendBinary(frame);\n } catch (err) {\n this.deps.logger.error(\"Failed to send binary audio frame:\", err);\n this.setState(\"error\");\n }\n }\n\n /**\n * Wait for the cloud to respond with AUDIO_STREAM_READY.\n * Listens on the MessageHandlerRegistry for the top-level response message type.\n */\n private waitForReady(): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n let settled = false;\n\n const timeout = setTimeout(() => {\n if (settled) return;\n settled = true;\n unregister();\n reject(new Error(`Audio stream relay not ready after ${STREAM_READY_TIMEOUT_MS}ms`));\n }, STREAM_READY_TIMEOUT_MS);\n\n // Register on the MessageHandlerRegistry for AUDIO_STREAM_READY.\n // This is a top-level message type, not a DATA_STREAM streamType,\n // so it must go through messageHandlers (not the DataStreamRouter).\n const unregister = this.deps.messageHandlers.register(\n CloudToAppMessageType.AUDIO_STREAM_READY,\n (message: any) => {\n if (message?.streamId === this.id) {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n unregister();\n resolve(message.streamUrl);\n }\n },\n );\n });\n }\n}\n\n// ─── SpeakerManager ─────────────────────────────────────────────────────────\n\n/**\n * Controls audio output on the user's glasses speaker.\n *\n * Provides methods for:\n * - 🎵 Playing audio files from URLs\n * - ⏹️ Stopping audio playback\n * - 🗣️ Text-to-speech via ElevenLabs\n * - 🎙️ Real-time audio streaming\n *\n * All messages use the same wire format as v2 AudioManager — the cloud\n * and phone receive identical AUDIO_PLAY_REQUEST / AUDIO_STOP_REQUEST /\n * AUDIO_STREAM_* messages.\n */\nexport class SpeakerManager {\n private readonly deps: ManagerDeps;\n\n /**\n * Map of pending play requests awaiting AUDIO_PLAY_RESPONSE.\n * Key: requestId, Value: promise resolve/reject pair.\n */\n private pendingRequests = new Map<\n string,\n {\n resolve: (result: PlayResult) => void;\n reject: (reason: any) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n\n /** Currently active output stream (at most one at a time) */\n private activeStream: AudioOutputStreamImpl | null = null;\n\n /** Cached permission state */\n private _hasPermission = true;\n\n /** Cleanup function for the AUDIO_PLAY_RESPONSE message handler registration */\n private responseHandlerCleanup: (() => void) | null = null;\n\n constructor(deps: ManagerDeps) {\n this.deps = deps;\n\n // Register handler for AUDIO_PLAY_RESPONSE messages from the cloud.\n // This is a top-level message type, so it goes through the\n // MessageHandlerRegistry (not the DataStreamRouter).\n this.responseHandlerCleanup = this.deps.messageHandlers.register(\n CloudToAppMessageType.AUDIO_PLAY_RESPONSE,\n (message: any) => {\n this.handleAudioPlayResponse(message);\n },\n );\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Whether the app has speaker permission.\n * Updated when the cloud sends permission state changes.\n */\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n /**\n * 🎵 Play an audio file from a URL on the glasses speaker.\n *\n * If `stopOtherAudio` is false (default), resolves immediately in\n * fire-and-forget mode so multiple tracks can play concurrently.\n * If `stopOtherAudio` is true, waits for the cloud's AUDIO_PLAY_RESPONSE.\n *\n * @param opts - Playback options (url is required)\n * @returns Promise resolving with playback result\n *\n * @example\n * ```ts\n * const result = await speaker.play({\n * url: \"https://example.com/sound.mp3\",\n * volume: 0.8,\n * trackId: 0,\n * });\n * ```\n */\n async play(opts: PlayOptions): Promise<PlayResult> {\n if (!opts.url) {\n throw new Error(\"PlayOptions.url must be provided\");\n }\n\n const requestId = `audio_req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const volume = opts.volume ?? 1.0;\n const trackId = opts.trackId ?? 0;\n const stopOtherAudio = opts.stopOtherAudio ?? false;\n\n // Build wire message — identical to v2 AudioPlayRequest\n const message = {\n type: AppToCloudMessageType.AUDIO_PLAY_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n audioUrl: opts.url,\n volume,\n stopOtherAudio,\n trackId,\n };\n\n // Fire-and-forget for concurrent playback (stopOtherAudio=false)\n if (!stopOtherAudio) {\n this.deps.sendMessage(message);\n this.deps.logger.debug(\"Audio playback started in non-blocking mode\", requestId);\n return { duration: 0 };\n }\n\n // Blocking mode — wait for AUDIO_PLAY_RESPONSE\n return new Promise<PlayResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new Error(\"Audio play request timed out\"));\n this.deps.logger.warn(\"Audio play request timed out\", requestId);\n }, PLAY_RESPONSE_TIMEOUT_MS);\n\n this.pendingRequests.set(requestId, { resolve, reject, timer });\n this.deps.sendMessage(message);\n });\n }\n\n /**\n * ⏹️ Stop audio playback on the glasses.\n *\n * @param trackId - Specific track to stop. If omitted, stops all tracks.\n *\n * @example\n * ```ts\n * // Stop all audio\n * await speaker.stop();\n *\n * // Stop only the TTS track\n * await speaker.stop(2);\n * ```\n */\n async stop(trackId?: TrackId): Promise<void> {\n const message = {\n type: AppToCloudMessageType.AUDIO_STOP_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n trackId,\n timestamp: new Date(),\n };\n\n this.deps.sendMessage(message);\n\n const trackInfo = trackId !== undefined ? ` (track ${trackId})` : \" (all tracks)\";\n this.deps.logger.info(`Audio stop request sent${trackInfo}`);\n }\n\n /**\n * 🗣️ Convert text to speech and play it on the glasses speaker.\n *\n * Uses the server-side TTS endpoint which proxies to ElevenLabs.\n * The generated audio URL is then played via the standard play() path.\n *\n * @param text - Text to speak (required)\n * @param opts - TTS configuration (optional)\n * @returns Promise resolving with playback result\n *\n * @example\n * ```ts\n * await speaker.speak(\"Hello, world!\");\n *\n * await speaker.speak(\"Good morning!\", {\n * voiceId: \"custom_voice_id\",\n * voiceSettings: { stability: 0.5, speed: 1.2 },\n * volume: 0.8,\n * });\n * ```\n */\n async speak(text: string, opts: SpeakOptions = {}): Promise<PlayResult> {\n if (!text) {\n throw new Error(\"text must be provided\");\n }\n\n // Build TTS query parameters — identical to v2 speak() format\n const queryParams = new URLSearchParams();\n queryParams.append(\"text\", text);\n\n if (opts.voiceId) {\n queryParams.append(\"voice_id\", opts.voiceId);\n }\n\n if (opts.modelId) {\n queryParams.append(\"model_id\", opts.modelId);\n }\n\n if (opts.voiceSettings) {\n // Map camelCase API to the snake_case the TTS endpoint expects\n const settings: Record<string, any> = {};\n if (opts.voiceSettings.stability !== undefined) settings.stability = opts.voiceSettings.stability;\n if (opts.voiceSettings.similarityBoost !== undefined)\n settings.similarity_boost = opts.voiceSettings.similarityBoost;\n if (opts.voiceSettings.style !== undefined) settings.style = opts.voiceSettings.style;\n if (opts.voiceSettings.speed !== undefined) settings.speed = opts.voiceSettings.speed;\n queryParams.append(\"voice_settings\", JSON.stringify(settings));\n }\n\n // The TTS URL is constructed the same way as v2 — the cloud resolves it.\n // v2 used session.getHttpsServerUrl() but in v3 we send the query params\n // as part of the play request and let the cloud construct the final URL.\n const ttsUrl = `/api/tts?${queryParams.toString()}`;\n\n this.deps.logger.debug(\"Generating speech from text\", text);\n\n return this.play({\n url: ttsUrl,\n volume: opts.volume,\n stopOtherAudio: opts.stopOtherAudio ?? false,\n trackId: opts.trackId ?? 2, // Default to track 2 (tts)\n });\n }\n\n /**\n * 🎙️ Create a real-time audio output stream.\n *\n * Opens a streaming relay on the cloud and tells the phone to play it.\n * Write audio chunks to the returned stream and they play on the glasses\n * speaker in real-time — like internet radio.\n *\n * Only one stream can be active at a time. Call `end()` or `flush()` on\n * the current stream before creating a new one.\n *\n * @param opts - Stream configuration\n * @returns The AudioOutputStream (already connected and playing)\n *\n * @example\n * ```ts\n * // MP3 pass-through (most common)\n * const stream = await speaker.createStream({ format: \"mp3\" });\n * elevenLabs.on(\"chunk\", (mp3) => stream.write(mp3));\n * elevenLabs.on(\"end\", () => stream.end());\n *\n * // Interrupt on user speech\n * mic.onVoiceActivity((vad) => {\n * if (vad.isSpeaking) stream.flush();\n * });\n * ```\n */\n async createStream(opts: StreamOptions = {}): Promise<AudioOutputStream> {\n // Enforce one-at-a-time — callers must end/flush the current stream first\n if (this.activeStream && this.activeStream.state === \"streaming\") {\n const err = new Error(\n `AUDIO_STREAM_ALREADY_ACTIVE: Stream ${this.activeStream.id} is still active. ` +\n `Call end() or flush() before creating a new output stream.`,\n ) as Error & { code?: string };\n err.code = \"AUDIO_STREAM_ALREADY_ACTIVE\";\n this.deps.logger.warn(\"Refusing to create a second output stream while one is active\");\n throw err;\n }\n\n // Generate a unique stream ID\n const streamId = crypto.randomUUID();\n\n const stream = new AudioOutputStreamImpl(streamId, this.deps, opts);\n\n // Open the stream (sends AUDIO_STREAM_START, waits for relay URL, tells phone to play)\n await stream.open();\n\n this.activeStream = stream;\n\n // Clean up reference when the stream ends\n stream.onStateChange((state) => {\n if ((state === \"ended\" || state === \"error\") && this.activeStream === stream) {\n this.activeStream = null;\n }\n });\n\n return stream;\n }\n\n // ─── Cleanup ─────────────────────────────────────────────────────────────\n\n /**\n * Cancel all pending requests and end any active stream.\n * Called by MentraSession during disconnect/cleanup.\n * @internal\n */\n destroy(): void {\n // Unregister the AUDIO_PLAY_RESPONSE message handler\n if (this.responseHandlerCleanup) {\n this.responseHandlerCleanup();\n this.responseHandlerCleanup = null;\n }\n\n // Cancel all pending play requests\n for (const [requestId, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(\"SpeakerManager destroyed\"));\n this.deps.logger.debug(\"Audio request cancelled during cleanup\", requestId);\n }\n this.pendingRequests.clear();\n\n // End any active output stream\n if (this.activeStream && this.activeStream.state === \"streaming\") {\n this.activeStream.end().catch(() => {});\n this.activeStream = null;\n }\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n /**\n * Handle AUDIO_PLAY_RESPONSE from the cloud.\n * Resolves or rejects the corresponding pending play() promise.\n */\n private handleAudioPlayResponse(response: any): void {\n const requestId: string | undefined = response?.requestId;\n if (!requestId) return;\n\n const pending = this.pendingRequests.get(requestId);\n if (!pending) {\n this.deps.logger.debug(\"Received audio play response for unknown request\", requestId);\n return;\n }\n\n clearTimeout(pending.timer);\n this.pendingRequests.delete(requestId);\n\n if (response.success) {\n pending.resolve({\n duration: response.duration ?? 0,\n });\n this.deps.logger.info(\"Audio play response received\", requestId, \"duration:\", response.duration);\n } else {\n pending.reject(new Error(response.error || \"Audio playback failed\"));\n this.deps.logger.warn(\"Audio play failed\", requestId, response.error);\n }\n }\n}\n",
|
|
32
|
+
"/**\n * PermissionsManager — App Permission State\n *\n * Tracks which permissions the current app has been granted based on\n * the app's manifest/registration on the developer console. Permissions\n * are populated when the session connects (from CONNECTION_ACK settings)\n * and can be queried synchronously by other managers.\n *\n * This manager is read-only from the app's perspective — permissions are\n * controlled by the platform, not the app.\n *\n * @example\n * ```ts\n * // Check a single permission\n * if (permissions.has(\"camera\")) {\n * // Safe to use camera APIs\n * }\n *\n * // Get all permissions\n * const all = permissions.getAll();\n * console.log(\"Notifications allowed:\", all.notifications);\n *\n * // React to permission changes\n * const cleanup = permissions.onUpdate((perms) => {\n * console.log(\"Permissions updated:\", perms);\n * });\n * ```\n *\n * @module\n */\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\n/**\n * Permission types supported by the MentraOS platform.\n *\n * These correspond to capabilities and data streams that require\n * explicit opt-in via the developer console app manifest.\n */\nexport type PermissionType = \"location\" | \"microphone\" | \"camera\" | \"notifications\" | \"calendar\";\n\n/**\n * Complete permission record mapping every permission type to its grant status.\n */\nexport type PermissionRecord = Record<PermissionType, boolean>;\n\n/**\n * Dependencies injected by MentraSession.\n */\nexport interface PermissionsManagerDeps {\n /** Logger instance scoped to the session. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────\n\n/** All known permission types, used for iteration and defaults. */\nconst ALL_PERMISSIONS: readonly PermissionType[] = [\n \"location\",\n \"microphone\",\n \"camera\",\n \"notifications\",\n \"calendar\",\n] as const;\n\n/**\n * Returns a fresh default permission record with all permissions denied.\n */\nfunction createDefaultPermissions(): PermissionRecord {\n return {\n location: false,\n microphone: false,\n camera: false,\n notifications: false,\n calendar: false,\n };\n}\n\n// ─── PermissionsManager ─────────────────────────────────────────────────────\n\n/**\n * Manages the permission state for the current app session.\n *\n * Permissions are populated from the CONNECTION_ACK payload when the\n * session is established. Other managers (DeviceManager, PhoneManager)\n * query this manager to gate access to protected streams.\n *\n * The manager emits updates whenever the permission set changes, allowing\n * UI or logic to react to permission grants/revocations in real time.\n */\nexport class PermissionsManager {\n /** Current permission state. */\n private permissions: PermissionRecord;\n\n /** Registered update listeners. */\n private listeners: Set<(permissions: PermissionRecord) => void> = new Set();\n\n /** Logger instance. */\n private logger: PermissionsManagerDeps[\"logger\"];\n\n /** Message handler registry for cloud message subscriptions. */\n private messageHandlers: PermissionsManagerDeps[\"messageHandlers\"];\n\n constructor(deps: PermissionsManagerDeps) {\n this.logger = deps.logger;\n this.messageHandlers = deps.messageHandlers;\n this.permissions = createDefaultPermissions();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Check whether the app has been granted a specific permission.\n *\n * @param permission - The permission type to check\n * @returns `true` if the permission is granted, `false` otherwise\n *\n * @example\n * ```ts\n * if (permissions.has(\"microphone\")) {\n * session.events.onTranscription(handler);\n * }\n * ```\n */\n has(permission: PermissionType): boolean {\n return this.permissions[permission] ?? false;\n }\n\n /**\n * Get a snapshot of all permissions as a record.\n *\n * The returned object is a copy — mutations do not affect internal state.\n *\n * @returns A record mapping every {@link PermissionType} to its grant status\n *\n * @example\n * ```ts\n * const perms = permissions.getAll();\n * console.log(\"Camera:\", perms.camera);\n * console.log(\"Location:\", perms.location);\n * ```\n */\n getAll(): PermissionRecord {\n return { ...this.permissions };\n }\n\n /**\n * Subscribe to permission updates.\n *\n * The handler is called whenever the permission set changes (e.g., on\n * CONNECTION_ACK or a mid-session settings update). It receives a\n * snapshot copy of the full permission record.\n *\n * @param handler - Callback invoked with the updated permission record\n * @returns Cleanup function that removes the listener\n *\n * @example\n * ```ts\n * const cleanup = permissions.onUpdate((perms) => {\n * if (!perms.camera) {\n * console.warn(\"Camera permission revoked\");\n * }\n * });\n *\n * // Later: stop listening\n * cleanup();\n * ```\n */\n onUpdate(handler: (permissions: PermissionRecord) => void): () => void {\n this.listeners.add(handler);\n return () => {\n this.listeners.delete(handler);\n };\n }\n\n /**\n * Listen for permission error events from the cloud.\n * Fires when a bulk subscription is rejected due to missing permissions.\n *\n * @param handler - Callback invoked with the error details\n * @returns Cleanup function that removes the listener\n *\n * @example\n * ```ts\n * const cleanup = permissions.onPermissionError((err) => {\n * console.error(\"Permission error:\", err.message, err.deniedPermissions);\n * });\n * ```\n */\n onPermissionError(handler: (error: { message: string; deniedPermissions?: string[] }) => void): () => void {\n const cleanup = this.messageHandlers.register(\"permission_error\", (msg: any) => {\n try {\n handler({ message: msg.message ?? \"Permission error\", deniedPermissions: msg.deniedPermissions });\n } catch (err) {\n this.logger.error(\"[PermissionsManager] Error in onPermissionError handler:\", err);\n }\n });\n return cleanup;\n }\n\n /**\n * Listen for permission denied events from the cloud.\n * Fires when an individual stream subscription is rejected.\n *\n * @param handler - Callback invoked with the denial details\n * @returns Cleanup function that removes the listener\n *\n * @example\n * ```ts\n * const cleanup = permissions.onPermissionDenied((err) => {\n * console.warn(\"Denied:\", err.permission, err.streamType);\n * });\n * ```\n */\n onPermissionDenied(handler: (error: { message: string; permission?: string; streamType?: string }) => void): () => void {\n const cleanup = this.messageHandlers.register(\"permission_denied\", (msg: any) => {\n try {\n handler({ message: msg.message ?? \"Permission denied\", permission: msg.permission, streamType: msg.streamType });\n } catch (err) {\n this.logger.error(\"[PermissionsManager] Error in onPermissionDenied handler:\", err);\n }\n });\n return cleanup;\n }\n\n // ─── Internal (called by MentraSession) ─────────────────────────────────\n\n /**\n * Update permissions from connection settings or a settings update payload.\n *\n * Called internally by MentraSession when:\n * - A CONNECTION_ACK is received with initial settings/permissions\n * - A mid-session settings update includes permission changes\n *\n * Accepts flexible input — extracts permissions from nested structures\n * commonly found in CONNECTION_ACK and settings_update payloads.\n *\n * @param settings - The raw settings object from the cloud message\n * @internal\n */\n updateFromSettings(settings: any): void {\n if (!settings) {\n this.logger.debug(\"PermissionsManager: No settings provided, skipping update\");\n return;\n }\n\n const previous = { ...this.permissions };\n let updated = false;\n\n // Extract permissions from various possible payload shapes:\n // { permissions: { camera: true, ... } }\n // { appPermissions: { camera: true, ... } }\n // { camera: true, microphone: false, ... } (flat)\n const permissionsSource = settings.permissions ?? settings.appPermissions ?? settings;\n\n for (const perm of ALL_PERMISSIONS) {\n if (perm in permissionsSource) {\n const value = Boolean(permissionsSource[perm]);\n if (this.permissions[perm] !== value) {\n this.permissions[perm] = value;\n updated = true;\n }\n }\n }\n\n if (updated) {\n this.logger.info(\n \"PermissionsManager: Permissions updated — \" +\n ALL_PERMISSIONS.map((p) => `${p}=${this.permissions[p]}`).join(\", \"),\n );\n\n // Log individual changes at debug level\n for (const perm of ALL_PERMISSIONS) {\n if (previous[perm] !== this.permissions[perm]) {\n this.logger.debug(`PermissionsManager: ${perm}: ${previous[perm]} → ${this.permissions[perm]}`);\n }\n }\n\n // Notify listeners with a snapshot copy\n const snapshot = this.getAll();\n for (const listener of this.listeners) {\n try {\n listener(snapshot);\n } catch (err) {\n this.logger.error(\n `PermissionsManager: Error in onUpdate listener: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n } else {\n this.logger.debug(\"PermissionsManager: No permission changes detected\");\n }\n }\n}\n",
|
|
33
|
+
"/**\n * PhoneManager — Phone-Scoped Event Management\n *\n * Consolidates all phone-related data streams into a single manager\n * with purpose-built sub-managers:\n *\n * - **notifications** — Phone notification events and dismissals\n * - **calendar** — Calendar event stream\n *\n * Each sub-manager exposes a `hasPermission` getter that delegates to\n * the {@link PermissionsManager}, giving callers a convenient way to\n * check access before subscribing.\n *\n * All handler registrations return a cleanup function. Subscriptions\n * are managed automatically — `addSubscription` is called when the\n * first handler for a stream is registered, and `removeSubscription`\n * when the last handler is removed.\n *\n * @example\n * ```ts\n * // Notifications (with permission check)\n * if (phone.notifications.hasPermission) {\n * phone.notifications.on((n) => {\n * console.log(`${n.app}: ${n.title}`);\n * });\n * }\n *\n * // Calendar events\n * if (phone.calendar.hasPermission) {\n * phone.calendar.on((event) => {\n * console.log(event.title, event.start, \"→\", event.end);\n * });\n * }\n * ```\n *\n * @module\n */\n\nimport { StreamType } from \"../../types/streams\";\nimport type { PermissionsManager } from \"./PermissionsManager\";\n\n// ─── Event Types ────────────────────────────────────────────────────────────\n\n/**\n * Phone notification event delivered from the companion app.\n */\nexport interface PhoneNotificationEvent {\n /** Unique identifier for this notification. */\n notificationId: string;\n /** Source application package/name. */\n app: string;\n /** Notification title. */\n title: string;\n /** Notification body content. */\n content: string;\n /** Notification priority level. */\n priority: \"low\" | \"normal\" | \"high\";\n}\n\n/**\n * Event emitted when a phone notification is dismissed by the user.\n */\nexport interface NotificationDismissedEvent {\n /** Unique identifier of the dismissed notification. */\n notificationId: string;\n /** Source application package/name. */\n app: string;\n /** Notification title. */\n title: string;\n /** Notification body content. */\n content: string;\n /** Platform-specific notification key. */\n notificationKey: string;\n}\n\n/**\n * Normalised calendar event data.\n *\n * Raw wire fields are normalised for a cleaner developer experience:\n * - `dtStart` → `start`\n * - `dtEnd` → `end`\n * - `timeStamp` → `timestamp`\n */\nexport interface CalendarEventData {\n /** Calendar event identifier. */\n eventId: string;\n /** Event title/summary. */\n title: string;\n /** Normalised start time (ISO string). */\n start: string;\n /** Normalised end time (ISO string). */\n end: string;\n /** Event timezone. */\n timezone: string;\n /** Normalised timestamp of the event update (ISO string). */\n timestamp: string;\n /** Any additional fields from the raw payload. */\n [key: string]: any;\n}\n\n\n\n// ─── Dependency Types ───────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession into the PhoneManager.\n */\nexport interface PhoneManagerDeps {\n /** DataStreamRouter — register for stream-type events. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Subscribe to a data stream (sent to cloud). */\n addSubscription: (stream: string) => void;\n /** Unsubscribe from a data stream. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary message to the cloud. */\n sendMessage: (message: any) => void;\n /** Session-scoped logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Returns the current app's package name. */\n getPackageName: () => string;\n /** Returns the active session ID. */\n getSessionId: () => string;\n /** PermissionsManager for gating protected streams. */\n permissions: PermissionsManager;\n}\n\n// ─── Internal Helpers ───────────────────────────────────────────────────────\n\n/**\n * Normalise raw calendar event data from the wire format.\n *\n * - `dtStart` → `start`\n * - `dtEnd` → `end`\n * - `timeStamp` → `timestamp`\n */\nfunction normaliseCalendarEvent(raw: any): CalendarEventData {\n return {\n ...raw,\n eventId: raw.eventId ?? raw.event_id ?? \"unknown\",\n title: raw.title ?? \"\",\n start: raw.dtStart ?? raw.start ?? \"\",\n end: raw.dtEnd ?? raw.end ?? \"\",\n timezone: raw.timezone ?? \"\",\n timestamp: raw.timeStamp ?? raw.timestamp ?? new Date().toISOString(),\n };\n}\n\n// ─── Stream Handler Bookkeeping ─────────────────────────────────────────────\n\n/**\n * Shared ref-counting logic for stream subscriptions.\n *\n * Tracks handler counts per stream key and calls `addSubscription` /\n * `removeSubscription` at the appropriate lifecycle boundaries.\n * Identical pattern to the `addStreamHandler` private method in DeviceManager,\n * extracted here so all three PhoneManager sub-concerns can share it.\n */\nclass StreamHandlerTracker {\n /** Ref-counted handler totals keyed by stream string. */\n private handlerCounts: Map<string, number> = new Map();\n\n /** All cleanup functions for bulk teardown. */\n private cleanups: Array<() => void> = [];\n\n constructor(\n private router: PhoneManagerDeps[\"router\"],\n private addSubscription: PhoneManagerDeps[\"addSubscription\"],\n private removeSubscription: PhoneManagerDeps[\"removeSubscription\"],\n ) {}\n\n /**\n * Register a handler on the DataStreamRouter for a given stream key,\n * managing subscription lifecycle automatically.\n *\n * - Calls `addSubscription` when the first handler for a key is added.\n * - Calls `removeSubscription` when the last handler for a key is removed.\n *\n * @param streamKey - The stream type string\n * @param handler - The stream handler function\n * @returns Cleanup function that unregisters the handler and manages subscription\n */\n add(streamKey: string, handler: (streamType: string, data: any, message: any) => void): () => void {\n const currentCount = this.handlerCounts.get(streamKey) ?? 0;\n\n // First handler for this stream — subscribe\n if (currentCount === 0) {\n this.addSubscription(streamKey);\n }\n this.handlerCounts.set(streamKey, currentCount + 1);\n\n // Register on the router\n const routerCleanup = this.router.on(streamKey, handler);\n\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n\n // Remove from router\n routerCleanup();\n\n // Decrement handler count\n const count = this.handlerCounts.get(streamKey) ?? 0;\n const newCount = count - 1;\n if (newCount <= 0) {\n this.handlerCounts.delete(streamKey);\n this.removeSubscription(streamKey);\n } else {\n this.handlerCounts.set(streamKey, newCount);\n }\n };\n\n this.cleanups.push(cleanup);\n return cleanup;\n }\n\n /**\n * Remove all tracked handlers and unsubscribe from all streams.\n * Called during session teardown.\n */\n destroyAll(): void {\n for (const fn of this.cleanups) {\n fn();\n }\n this.cleanups.length = 0;\n this.handlerCounts.clear();\n }\n}\n\n// ─── NotificationSubManager ─────────────────────────────────────────────────\n\n/**\n * Sub-manager for phone notification streams.\n *\n * Provides handlers for incoming notifications and notification dismissals,\n * plus a convenience `hasPermission` check.\n *\n * @example\n * ```ts\n * if (phone.notifications.hasPermission) {\n * phone.notifications.on((n) => {\n * showOnGlasses(`${n.app}: ${n.title}`);\n * });\n *\n * phone.notifications.onDismissed((e) => {\n * removeFromGlasses(e.notificationId);\n * });\n * }\n * ```\n */\nexport class NotificationSubManager {\n private permissions: PermissionsManager;\n private tracker: StreamHandlerTracker;\n private logger: PhoneManagerDeps[\"logger\"];\n\n /** @internal */\n constructor(permissions: PermissionsManager, tracker: StreamHandlerTracker, logger: PhoneManagerDeps[\"logger\"]) {\n this.permissions = permissions;\n this.tracker = tracker;\n this.logger = logger;\n }\n\n /**\n * Whether the app has the `notifications` permission.\n *\n * Reads from the {@link PermissionsManager} — this is a live check,\n * not a cached value.\n */\n get hasPermission(): boolean {\n return this.permissions.has(\"notifications\");\n }\n\n /**\n * Listen for incoming phone notifications.\n *\n * @param handler - Called with {@link PhoneNotificationEvent} for each notification\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = phone.notifications.on((n) => {\n * console.log(`[${n.priority}] ${n.app}: ${n.title} — ${n.content}`);\n * });\n * ```\n */\n on(handler: (notification: PhoneNotificationEvent) => void): () => void {\n return this.tracker.add(StreamType.PHONE_NOTIFICATION, (_streamType, data) => {\n try {\n handler({\n notificationId: data.notificationId ?? data.notification_id ?? \"unknown\",\n app: data.app ?? \"unknown\",\n title: data.title ?? \"\",\n content: data.content ?? \"\",\n priority: data.priority ?? \"normal\",\n });\n } catch (err) {\n this.logger.error(\n `NotificationSubManager: Error in notification handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n\n /**\n * Listen for notification dismissal events.\n *\n * Fired when the user dismisses a notification on their phone.\n *\n * @param handler - Called with {@link NotificationDismissedEvent} for each dismissal\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * phone.notifications.onDismissed((e) => {\n * console.log(\"Dismissed:\", e.notificationId, \"from\", e.app);\n * });\n * ```\n */\n onDismissed(handler: (event: NotificationDismissedEvent) => void): () => void {\n return this.tracker.add(StreamType.PHONE_NOTIFICATION_DISMISSED, (_streamType, data) => {\n try {\n handler({\n notificationId: data.notificationId ?? data.notification_id ?? \"unknown\",\n app: data.app ?? \"unknown\",\n title: data.title ?? \"\",\n content: data.content ?? \"\",\n notificationKey: data.notificationKey ?? data.notification_key ?? \"\",\n });\n } catch (err) {\n this.logger.error(\n `NotificationSubManager: Error in dismissal handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n}\n\n// ─── CalendarSubManager ─────────────────────────────────────────────────────\n\n/**\n * Sub-manager for calendar event streams.\n *\n * Normalises raw calendar data (e.g. `dtStart` → `start`) and provides\n * a convenience `hasPermission` check.\n *\n * @example\n * ```ts\n * if (phone.calendar.hasPermission) {\n * phone.calendar.on((event) => {\n * console.log(`${event.title}: ${event.start} → ${event.end}`);\n * });\n * }\n * ```\n */\nexport class CalendarSubManager {\n private permissions: PermissionsManager;\n private tracker: StreamHandlerTracker;\n private logger: PhoneManagerDeps[\"logger\"];\n\n /** @internal */\n constructor(permissions: PermissionsManager, tracker: StreamHandlerTracker, logger: PhoneManagerDeps[\"logger\"]) {\n this.permissions = permissions;\n this.tracker = tracker;\n this.logger = logger;\n }\n\n /**\n * Whether the app has the `calendar` permission.\n *\n * Reads from the {@link PermissionsManager} — this is a live check,\n * not a cached value.\n */\n get hasPermission(): boolean {\n return this.permissions.has(\"calendar\");\n }\n\n /**\n * Listen for calendar events from the phone.\n *\n * Raw fields are normalised:\n * - `dtStart` → `start`\n * - `dtEnd` → `end`\n * - `timeStamp` → `timestamp`\n *\n * @param handler - Called with {@link CalendarEventData} for each event\n * @returns Cleanup function to remove the handler\n *\n * @example\n * ```ts\n * const stop = phone.calendar.on((event) => {\n * console.log(`${event.title} at ${event.start} (${event.timezone})`);\n * });\n * ```\n */\n on(handler: (event: CalendarEventData) => void): () => void {\n return this.tracker.add(StreamType.CALENDAR_EVENT, (_streamType, data) => {\n try {\n handler(normaliseCalendarEvent(data));\n } catch (err) {\n this.logger.error(\n `CalendarSubManager: Error in calendar handler: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n });\n }\n}\n\n// ─── PhoneManager ───────────────────────────────────────────────────────────\n\n/**\n * Manages all phone-related data streams for a MentraSession.\n *\n * Exposes sub-managers for notifications and calendar. Created by MentraSession and exposed as\n * `session.phone`.\n */\nexport class PhoneManager {\n // ─── Sub-Managers ─────────────────────────────────────────────────────\n\n /** Notification stream sub-manager. */\n readonly notifications: NotificationSubManager;\n\n /** Calendar event stream sub-manager. */\n readonly calendar: CalendarSubManager;\n\n // ─── Private ──────────────────────────────────────────────────────────\n\n private deps: PhoneManagerDeps;\n private permissions: PermissionsManager;\n private tracker: StreamHandlerTracker;\n\n constructor(deps: PhoneManagerDeps) {\n this.deps = deps;\n this.permissions = deps.permissions;\n\n // Shared subscription tracker for all phone streams\n this.tracker = new StreamHandlerTracker(deps.router, deps.addSubscription, deps.removeSubscription);\n\n // Wire up sub-managers\n this.notifications = new NotificationSubManager(this.permissions, this.tracker, deps.logger);\n this.calendar = new CalendarSubManager(this.permissions, this.tracker, deps.logger);\n }\n\n // ─── Cleanup ──────────────────────────────────────────────────────────\n\n /**\n * Remove all registered handlers and unsubscribe from all streams.\n *\n * Called by MentraSession during disconnect/teardown.\n * @internal\n */\n destroy(): void {\n this.tracker.destroyAll();\n this.deps.logger.debug(\"PhoneManager: Destroyed.\");\n }\n}\n",
|
|
34
|
+
"/**\n * 🔊 SpeakerManager — Audio Output Control\n *\n * v3 manager that wraps the existing AudioManager output functionality.\n * Handles audio playback, text-to-speech, and real-time audio streaming\n * to the user's glasses speaker.\n *\n * Wire message formats are identical to v2 so the cloud receives the\n * same AUDIO_PLAY_REQUEST, AUDIO_STOP_REQUEST, AUDIO_STREAM_START,\n * AUDIO_STREAM_END, and binary frame protocol.\n *\n * @example\n * ```ts\n * const speaker = new SpeakerManager(deps);\n *\n * // Play a URL\n * const result = await speaker.play({ url: \"https://example.com/sound.mp3\" });\n *\n * // Text-to-speech\n * await speaker.speak(\"Hello, world!\", { volume: 0.8 });\n *\n * // Real-time streaming\n * const stream = await speaker.createStream({ format: \"mp3\" });\n * stream.write(mp3Chunk);\n * await stream.end();\n * ```\n */\n\nimport { AppToCloudMessageType, CloudToAppMessageType } from \"../../types/message-types\";\n\n// ─── Dependencies ────────────────────────────────────────────────────────────\n\n/**\n * Shared dependency bag injected by MentraSession.\n * Keeps managers decoupled from the session implementation.\n */\nexport interface ManagerDeps {\n /** DataStreamRouter — register for DATA_STREAM messages by streamType key. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — register for top-level message types. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n addSubscription: (stream: string) => void;\n removeSubscription: (stream: string) => void;\n sendMessage: (message: any) => void;\n sendBinary: (data: ArrayBuffer | Uint8Array) => void;\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\n// ─── Public Types ────────────────────────────────────────────────────────────\n\n/** Audio track identifier. Multiple tracks can play simultaneously (mixing). */\nexport type TrackId = 0 | 1 | 2;\n\n/**\n * Options for playing an audio file from a URL.\n */\nexport interface PlayOptions {\n /** URL of the audio file to play */\n url: string;\n /** Volume level 0.0–1.0. Default: 1.0 */\n volume?: number;\n /**\n * Track ID for playback.\n * - 0: speaker (default audio playback)\n * - 1: app_audio (app-specific audio)\n * - 2: tts (text-to-speech audio)\n * Default: 0\n */\n trackId?: TrackId;\n /** Whether starting playback should stop other audio. Default: false */\n stopOtherAudio?: boolean;\n}\n\n/**\n * Result returned when audio playback completes.\n */\nexport interface PlayResult {\n /** Duration of the audio in milliseconds (when available) */\n duration: number;\n}\n\n/**\n * Options for text-to-speech playback.\n */\nexport interface SpeakOptions {\n /** ElevenLabs voice ID (optional — server picks a default) */\n voiceId?: string;\n /** ElevenLabs model ID (optional — defaults to eleven_flash_v2_5) */\n modelId?: string;\n /** Fine-grained voice settings */\n voiceSettings?: {\n stability?: number;\n similarityBoost?: number;\n style?: number;\n speed?: number;\n };\n /** Volume level 0.0–1.0. Default: 1.0 */\n volume?: number;\n /**\n * Track ID for playback. Default: 2 (tts)\n */\n trackId?: TrackId;\n /** Whether starting playback should stop other audio. Default: false */\n stopOtherAudio?: boolean;\n}\n\n/**\n * Options for creating a real-time audio output stream.\n */\nexport interface StreamOptions {\n /**\n * Format of the audio being written.\n * - \"mp3\": MP3 bytes passed through directly (ElevenLabs, OpenAI TTS, etc.)\n * - \"pcm16\": Raw 16-bit signed PCM samples (SDK encodes to MP3 before sending)\n * Default: \"mp3\"\n */\n format?: \"mp3\" | \"pcm16\";\n /** PCM sample rate in Hz (required when format is \"pcm16\"). Default: 24000 */\n sampleRate?: number;\n /** Number of audio channels. Default: 1 (mono) */\n channels?: 1 | 2;\n /** MP3 bitrate in kbps for PCM encoding. Default: 128 */\n bitrate?: number;\n /** Volume level 0.0–1.0. Default: 1.0 */\n volume?: number;\n /**\n * Track ID for playback. Default: 1 (app_audio)\n */\n trackId?: TrackId;\n /** Whether starting the stream should stop other audio. Default: true */\n stopOtherAudio?: boolean;\n}\n\n/** Lifecycle state of an AudioOutputStream */\nexport type AudioOutputStreamState = \"created\" | \"streaming\" | \"ending\" | \"ended\" | \"error\";\n\n/**\n * A real-time audio output stream.\n *\n * Audio data is sent as binary WebSocket frames with the protocol:\n * [36 bytes: streamId UUID as ASCII] [N bytes: audio data]\n *\n * The cloud pipes those bytes into an HTTP chunked response that the\n * phone's media player consumes like internet radio.\n */\nexport interface AudioOutputStream {\n /** Unique stream identifier (UUID) */\n readonly id: string;\n /** Current lifecycle state */\n readonly state: AudioOutputStreamState;\n /** Write audio data to the stream */\n write(chunk: Uint8Array): void;\n /** Gracefully end the stream — phone finishes buffered audio */\n end(): Promise<void>;\n /** Flush/interrupt — discard buffered audio, silence immediately */\n flush(): void;\n /** Register a callback for state changes */\n onStateChange(handler: (state: AudioOutputStreamState) => void): void;\n}\n\n// ─── Constants ───────────────────────────────────────────────────────────────\n\n/** UUID length in ASCII bytes — used as the binary frame header */\nconst STREAM_ID_LENGTH = 36;\n\n/** How long to wait for AUDIO_STREAM_READY from the cloud (ms) */\nconst STREAM_READY_TIMEOUT_MS = 10_000;\n\n/** How long to wait for AUDIO_PLAY_RESPONSE from the cloud (ms) */\nconst PLAY_RESPONSE_TIMEOUT_MS = 60_000;\n\n// ─── AudioOutputStreamImpl ──────────────────────────────────────────────────\n\n/**\n * Internal implementation of the AudioOutputStream interface.\n * Manages the binary frame protocol and lifecycle messages.\n */\n/**\n * Minimal interface for an MP3 encoder (compatible with lamejs).\n */\ninterface Mp3Encoder {\n encodeBuffer(samples: Int16Array): Int32Array | Uint8Array;\n flush(): Int32Array | Uint8Array;\n}\n\n/**\n * Create an MP3 encoder for PCM to MP3 conversion.\n * Used by Gemini Live / OpenAI Realtime which output raw PCM.\n * lamejs is a regular SDK dependency.\n *\n * lamejs has broken CJS modules that reference globals (MPEGMode, Lame,\n * BitStream) only defined when loaded via the concatenated bundle. Bun\n * resolves to src/js/index.js which skips them. We inject manually.\n */\nfunction createMp3Encoder(channels: number, sampleRate: number, bitrate: number): Mp3Encoder {\n (globalThis as any).MPEGMode ??= require(\"lamejs/src/js/MPEGMode.js\");\n (globalThis as any).Lame ??= require(\"lamejs/src/js/Lame.js\");\n (globalThis as any).BitStream ??= require(\"lamejs/src/js/BitStream.js\");\n\n const lamejs = require(\"lamejs\");\n const Encoder = lamejs.Mp3Encoder ?? lamejs.default?.Mp3Encoder;\n return new Encoder(channels, sampleRate, bitrate) as Mp3Encoder;\n}\n\n/** Convert any typed array or ArrayBuffer to Int16Array for PCM encoding. */\nfunction toInt16Array(data: Uint8Array | ArrayBuffer): Int16Array {\n if (data instanceof Int16Array) return data;\n const buffer = data instanceof ArrayBuffer ? data : data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);\n return new Int16Array(buffer);\n}\n\nclass AudioOutputStreamImpl implements AudioOutputStream {\n public readonly id: string;\n\n private _state: AudioOutputStreamState = \"created\";\n private readonly deps: ManagerDeps;\n private readonly streamIdBytes: Uint8Array;\n private readonly options: Required<\n Pick<StreamOptions, \"format\" | \"sampleRate\" | \"channels\" | \"bitrate\" | \"volume\" | \"trackId\" | \"stopOtherAudio\">\n >;\n private stateChangeHandlers: Array<(state: AudioOutputStreamState) => void> = [];\n private streamUrl: string | null = null;\n\n /** MP3 encoder for PCM16 format. Null when format is \"mp3\" (pass-through). */\n private encoder: Mp3Encoder | null = null;\n\n constructor(streamId: string, deps: ManagerDeps, opts: StreamOptions = {}) {\n this.id = streamId;\n this.deps = deps;\n\n this.options = {\n format: opts.format ?? \"mp3\",\n sampleRate: opts.sampleRate ?? 24000,\n channels: opts.channels ?? 1,\n bitrate: opts.bitrate ?? 128,\n volume: opts.volume ?? 1.0,\n trackId: opts.trackId ?? 1,\n stopOtherAudio: opts.stopOtherAudio ?? true,\n };\n\n // Pre-encode the streamId as ASCII bytes (reused on every write)\n this.streamIdBytes = new TextEncoder().encode(this.id);\n }\n\n get state(): AudioOutputStreamState {\n return this._state;\n }\n\n /**\n * Initialize the stream — sends AUDIO_STREAM_START and waits for the\n * relay URL from the cloud, then tells the phone to play it.\n * @internal Called by SpeakerManager.createStream()\n */\n async open(): Promise<void> {\n if (this._state !== \"created\") {\n throw new Error(`Cannot open stream in state \"${this._state}\"`);\n }\n\n // Initialize MP3 encoder for PCM16 format. The phone expects MP3 bytes,\n // so raw PCM must be encoded before sending over the wire.\n if (this.options.format === \"pcm16\") {\n this.encoder = createMp3Encoder(this.options.channels, this.options.sampleRate, this.options.bitrate);\n }\n\n // Send AUDIO_STREAM_START to the cloud\n const startMessage = {\n type: AppToCloudMessageType.AUDIO_STREAM_START,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.id,\n contentType: \"audio/mpeg\",\n timestamp: new Date(),\n };\n this.deps.sendMessage(startMessage);\n\n // Wait for AUDIO_STREAM_READY response with the relay URL\n this.streamUrl = await this.waitForReady();\n\n this.setState(\"streaming\");\n\n // Tell the phone to play the relay URL using existing audio play path\n const playMessage = {\n type: AppToCloudMessageType.AUDIO_PLAY_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId: `stream_${this.id}`,\n audioUrl: this.streamUrl,\n volume: this.options.volume,\n stopOtherAudio: this.options.stopOtherAudio,\n trackId: this.options.trackId,\n timestamp: new Date(),\n };\n this.deps.sendMessage(playMessage);\n\n this.deps.logger.debug(\"Audio output stream opened\", this.id);\n }\n\n write(chunk: Uint8Array): void {\n if (this._state !== \"streaming\") {\n this.deps.logger.debug(`Write called on non-streaming output (state=${this._state}), ignoring`);\n return;\n }\n\n if (chunk.length === 0) return;\n\n if (this.options.format === \"pcm16\" && this.encoder) {\n // Encode PCM to MP3 before sending. The phone expects MP3 bytes.\n const pcm = toInt16Array(chunk);\n const encoded = this.encoder.encodeBuffer(pcm);\n if (encoded.length === 0) return; // Encoder is buffering, no complete frame yet\n this.sendBinaryFrame(new Uint8Array(encoded));\n } else {\n // MP3 pass-through\n this.sendBinaryFrame(chunk);\n }\n }\n\n async end(): Promise<void> {\n if (this._state !== \"streaming\") return;\n this.setState(\"ending\");\n\n // Tell the cloud to close the relay\n const endMessage = {\n type: AppToCloudMessageType.AUDIO_STREAM_END,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.id,\n timestamp: new Date(),\n };\n this.deps.sendMessage(endMessage);\n\n this.setState(\"ended\");\n this.deps.logger.debug(\"Audio output stream ended\");\n }\n\n flush(): void {\n if (this._state !== \"streaming\") return;\n this.setState(\"ending\");\n\n // End the stream on the cloud side\n const endMessage = {\n type: AppToCloudMessageType.AUDIO_STREAM_END,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n streamId: this.id,\n timestamp: new Date(),\n };\n this.deps.sendMessage(endMessage);\n\n // Also explicitly stop audio playback on the phone\n const stopMessage = {\n type: AppToCloudMessageType.AUDIO_STOP_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n trackId: this.options.trackId,\n timestamp: new Date(),\n };\n this.deps.sendMessage(stopMessage);\n\n this.setState(\"ended\");\n this.deps.logger.debug(\"Audio output stream flushed (interrupted)\");\n }\n\n onStateChange(handler: (state: AudioOutputStreamState) => void): void {\n this.stateChangeHandlers.push(handler);\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n private setState(state: AudioOutputStreamState): void {\n this._state = state;\n for (const handler of this.stateChangeHandlers) {\n try {\n handler(state);\n } catch (err) {\n this.deps.logger.error(\"AudioOutputStream state change handler error:\", err);\n }\n }\n }\n\n /**\n * Send a binary frame over the WebSocket.\n * Frame format: [36 bytes streamId ASCII] [N bytes audio data]\n */\n private sendBinaryFrame(audioData: Uint8Array): void {\n const frame = new Uint8Array(STREAM_ID_LENGTH + audioData.length);\n frame.set(this.streamIdBytes, 0);\n frame.set(audioData, STREAM_ID_LENGTH);\n\n try {\n this.deps.sendBinary(frame);\n } catch (err) {\n this.deps.logger.error(\"Failed to send binary audio frame:\", err);\n this.setState(\"error\");\n }\n }\n\n /**\n * Wait for the cloud to respond with AUDIO_STREAM_READY.\n * Listens on the MessageHandlerRegistry for the top-level response message type.\n */\n private waitForReady(): Promise<string> {\n return new Promise<string>((resolve, reject) => {\n let settled = false;\n\n const timeout = setTimeout(() => {\n if (settled) return;\n settled = true;\n unregister();\n reject(new Error(`Audio stream relay not ready after ${STREAM_READY_TIMEOUT_MS}ms`));\n }, STREAM_READY_TIMEOUT_MS);\n\n // Register on the MessageHandlerRegistry for AUDIO_STREAM_READY.\n // This is a top-level message type, not a DATA_STREAM streamType,\n // so it must go through messageHandlers (not the DataStreamRouter).\n const unregister = this.deps.messageHandlers.register(\n CloudToAppMessageType.AUDIO_STREAM_READY,\n (message: any) => {\n if (message?.streamId === this.id) {\n if (settled) return;\n settled = true;\n clearTimeout(timeout);\n unregister();\n resolve(message.streamUrl);\n }\n },\n );\n });\n }\n}\n\n// ─── SpeakerManager ─────────────────────────────────────────────────────────\n\n/**\n * Controls audio output on the user's glasses speaker.\n *\n * Provides methods for:\n * - 🎵 Playing audio files from URLs\n * - ⏹️ Stopping audio playback\n * - 🗣️ Text-to-speech via ElevenLabs\n * - 🎙️ Real-time audio streaming\n *\n * All messages use the same wire format as v2 AudioManager — the cloud\n * and phone receive identical AUDIO_PLAY_REQUEST / AUDIO_STOP_REQUEST /\n * AUDIO_STREAM_* messages.\n */\nexport class SpeakerManager {\n private readonly deps: ManagerDeps;\n\n /**\n * Map of pending play requests awaiting AUDIO_PLAY_RESPONSE.\n * Key: requestId, Value: promise resolve/reject pair.\n */\n private pendingRequests = new Map<\n string,\n {\n resolve: (result: PlayResult) => void;\n reject: (reason: any) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n\n /** Currently active output stream (at most one at a time) */\n private activeStream: AudioOutputStreamImpl | null = null;\n\n /** Cached permission state */\n private _hasPermission = true;\n\n /** Cleanup function for the AUDIO_PLAY_RESPONSE message handler registration */\n private responseHandlerCleanup: (() => void) | null = null;\n\n constructor(deps: ManagerDeps) {\n this.deps = deps;\n\n // Register handler for AUDIO_PLAY_RESPONSE messages from the cloud.\n // This is a top-level message type, so it goes through the\n // MessageHandlerRegistry (not the DataStreamRouter).\n this.responseHandlerCleanup = this.deps.messageHandlers.register(\n CloudToAppMessageType.AUDIO_PLAY_RESPONSE,\n (message: any) => {\n this.handleAudioPlayResponse(message);\n },\n );\n }\n\n // ─── Public API ──────────────────────────────────────────────────────────\n\n /**\n * Whether the app has speaker permission.\n * Updated when the cloud sends permission state changes.\n */\n get hasPermission(): boolean {\n return this._hasPermission;\n }\n\n /**\n * 🎵 Play an audio file from a URL on the glasses speaker.\n *\n * If `stopOtherAudio` is false (default), resolves immediately in\n * fire-and-forget mode so multiple tracks can play concurrently.\n * If `stopOtherAudio` is true, waits for the cloud's AUDIO_PLAY_RESPONSE.\n *\n * @param opts - Playback options (url is required)\n * @returns Promise resolving with playback result\n *\n * @example\n * ```ts\n * const result = await speaker.play({\n * url: \"https://example.com/sound.mp3\",\n * volume: 0.8,\n * trackId: 0,\n * });\n * ```\n */\n async play(opts: PlayOptions): Promise<PlayResult> {\n if (!opts.url) {\n throw new Error(\"PlayOptions.url must be provided\");\n }\n\n const requestId = `audio_req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n const volume = opts.volume ?? 1.0;\n const trackId = opts.trackId ?? 0;\n const stopOtherAudio = opts.stopOtherAudio ?? false;\n\n // Build wire message — identical to v2 AudioPlayRequest\n const message = {\n type: AppToCloudMessageType.AUDIO_PLAY_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n requestId,\n timestamp: new Date(),\n audioUrl: opts.url,\n volume,\n stopOtherAudio,\n trackId,\n };\n\n // Fire-and-forget for concurrent playback (stopOtherAudio=false)\n if (!stopOtherAudio) {\n this.deps.sendMessage(message);\n this.deps.logger.debug(\"Audio playback started in non-blocking mode\", requestId);\n return { duration: 0 };\n }\n\n // Blocking mode — wait for AUDIO_PLAY_RESPONSE\n return new Promise<PlayResult>((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(requestId);\n reject(new Error(\"Audio play request timed out\"));\n this.deps.logger.warn(\"Audio play request timed out\", requestId);\n }, PLAY_RESPONSE_TIMEOUT_MS);\n\n this.pendingRequests.set(requestId, { resolve, reject, timer });\n this.deps.sendMessage(message);\n });\n }\n\n /**\n * ⏹️ Stop audio playback on the glasses.\n *\n * @param trackId - Specific track to stop. If omitted, stops all tracks.\n *\n * @example\n * ```ts\n * // Stop all audio\n * await speaker.stop();\n *\n * // Stop only the TTS track\n * await speaker.stop(2);\n * ```\n */\n async stop(trackId?: TrackId): Promise<void> {\n const message = {\n type: AppToCloudMessageType.AUDIO_STOP_REQUEST,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n trackId,\n timestamp: new Date(),\n };\n\n this.deps.sendMessage(message);\n\n const trackInfo = trackId !== undefined ? ` (track ${trackId})` : \" (all tracks)\";\n this.deps.logger.info(`Audio stop request sent${trackInfo}`);\n }\n\n /**\n * 🗣️ Convert text to speech and play it on the glasses speaker.\n *\n * Uses the server-side TTS endpoint which proxies to ElevenLabs.\n * The generated audio URL is then played via the standard play() path.\n *\n * @param text - Text to speak (required)\n * @param opts - TTS configuration (optional)\n * @returns Promise resolving with playback result\n *\n * @example\n * ```ts\n * await speaker.speak(\"Hello, world!\");\n *\n * await speaker.speak(\"Good morning!\", {\n * voiceId: \"custom_voice_id\",\n * voiceSettings: { stability: 0.5, speed: 1.2 },\n * volume: 0.8,\n * });\n * ```\n */\n async speak(text: string, opts: SpeakOptions = {}): Promise<PlayResult> {\n if (!text) {\n throw new Error(\"text must be provided\");\n }\n\n // Build TTS query parameters — identical to v2 speak() format\n const queryParams = new URLSearchParams();\n queryParams.append(\"text\", text);\n\n if (opts.voiceId) {\n queryParams.append(\"voice_id\", opts.voiceId);\n }\n\n if (opts.modelId) {\n queryParams.append(\"model_id\", opts.modelId);\n }\n\n if (opts.voiceSettings) {\n // Map camelCase API to the snake_case the TTS endpoint expects\n const settings: Record<string, any> = {};\n if (opts.voiceSettings.stability !== undefined) settings.stability = opts.voiceSettings.stability;\n if (opts.voiceSettings.similarityBoost !== undefined)\n settings.similarity_boost = opts.voiceSettings.similarityBoost;\n if (opts.voiceSettings.style !== undefined) settings.style = opts.voiceSettings.style;\n if (opts.voiceSettings.speed !== undefined) settings.speed = opts.voiceSettings.speed;\n queryParams.append(\"voice_settings\", JSON.stringify(settings));\n }\n\n // The TTS URL is constructed the same way as v2 — the cloud resolves it.\n // v2 used session.getHttpsServerUrl() but in v3 we send the query params\n // as part of the play request and let the cloud construct the final URL.\n const ttsUrl = `/api/tts?${queryParams.toString()}`;\n\n this.deps.logger.debug(\"Generating speech from text\", text);\n\n return this.play({\n url: ttsUrl,\n volume: opts.volume,\n stopOtherAudio: opts.stopOtherAudio ?? false,\n trackId: opts.trackId ?? 2, // Default to track 2 (tts)\n });\n }\n\n /**\n * 🎙️ Create a real-time audio output stream.\n *\n * Opens a streaming relay on the cloud and tells the phone to play it.\n * Write audio chunks to the returned stream and they play on the glasses\n * speaker in real-time — like internet radio.\n *\n * Only one stream can be active at a time. Call `end()` or `flush()` on\n * the current stream before creating a new one.\n *\n * @param opts - Stream configuration\n * @returns The AudioOutputStream (already connected and playing)\n *\n * @example\n * ```ts\n * // MP3 pass-through (most common)\n * const stream = await speaker.createStream({ format: \"mp3\" });\n * elevenLabs.on(\"chunk\", (mp3) => stream.write(mp3));\n * elevenLabs.on(\"end\", () => stream.end());\n *\n * // Interrupt on user speech\n * mic.onVoiceActivity((vad) => {\n * if (vad.isSpeaking) stream.flush();\n * });\n * ```\n */\n async createStream(opts: StreamOptions = {}): Promise<AudioOutputStream> {\n // Enforce one-at-a-time — callers must end/flush the current stream first\n if (this.activeStream && this.activeStream.state === \"streaming\") {\n const err = new Error(\n `AUDIO_STREAM_ALREADY_ACTIVE: Stream ${this.activeStream.id} is still active. ` +\n `Call end() or flush() before creating a new output stream.`,\n ) as Error & { code?: string };\n err.code = \"AUDIO_STREAM_ALREADY_ACTIVE\";\n this.deps.logger.warn(\"Refusing to create a second output stream while one is active\");\n throw err;\n }\n\n // Generate a unique stream ID\n const streamId = crypto.randomUUID();\n\n const stream = new AudioOutputStreamImpl(streamId, this.deps, opts);\n\n // Open the stream (sends AUDIO_STREAM_START, waits for relay URL, tells phone to play)\n await stream.open();\n\n this.activeStream = stream;\n\n // Clean up reference when the stream ends\n stream.onStateChange((state) => {\n if ((state === \"ended\" || state === \"error\") && this.activeStream === stream) {\n this.activeStream = null;\n }\n });\n\n return stream;\n }\n\n // ─── Cleanup ─────────────────────────────────────────────────────────────\n\n /**\n * Cancel all pending requests and end any active stream.\n * Called by MentraSession during disconnect/cleanup.\n * @internal\n */\n destroy(): void {\n // Unregister the AUDIO_PLAY_RESPONSE message handler\n if (this.responseHandlerCleanup) {\n this.responseHandlerCleanup();\n this.responseHandlerCleanup = null;\n }\n\n // Cancel all pending play requests\n for (const [requestId, pending] of this.pendingRequests) {\n clearTimeout(pending.timer);\n pending.reject(new Error(\"SpeakerManager destroyed\"));\n this.deps.logger.debug(\"Audio request cancelled during cleanup\", requestId);\n }\n this.pendingRequests.clear();\n\n // End any active output stream\n if (this.activeStream && this.activeStream.state === \"streaming\") {\n this.activeStream.end().catch(() => {});\n this.activeStream = null;\n }\n }\n\n // ─── Internal ────────────────────────────────────────────────────────────\n\n /**\n * Handle AUDIO_PLAY_RESPONSE from the cloud.\n * Resolves or rejects the corresponding pending play() promise.\n */\n private handleAudioPlayResponse(response: any): void {\n const requestId: string | undefined = response?.requestId;\n if (!requestId) return;\n\n const pending = this.pendingRequests.get(requestId);\n if (!pending) {\n this.deps.logger.debug(\"Received audio play response for unknown request\", requestId);\n return;\n }\n\n clearTimeout(pending.timer);\n this.pendingRequests.delete(requestId);\n\n if (response.success) {\n pending.resolve({\n duration: response.duration ?? 0,\n });\n this.deps.logger.info(\"Audio play response received\", requestId, \"duration:\", response.duration);\n } else {\n pending.reject(new Error(response.error || \"Audio playback failed\"));\n this.deps.logger.warn(\"Audio play failed\", requestId, response.error);\n }\n }\n}\n",
|
|
35
35
|
"/**\n * StorageManager — v3 SDK Key-Value Storage API\n *\n * Wraps the existing SimpleStorage patterns from v2 with a cleaner,\n * composable API. Provides localStorage-like semantics with cloud\n * synchronisation via HTTP REST endpoints.\n *\n * **Mental Model:** Local cache (RAM) is the source of truth for reads.\n * Writes are applied to RAM immediately and batched/debounced to the\n * server for persistence. On disconnect, pending writes are flushed.\n *\n * Data is isolated by userId and packageName on the server side.\n * The REST endpoints live on the SDK's own HTTP server (same origin\n * as the WebSocket connection, minus the `/app-ws` path).\n *\n * REST API:\n * - `GET /api/sdk/simple-storage/:userId` → fetch all data\n * - `PUT /api/sdk/simple-storage/:userId` → batch upsert `{ data: { key: value } }`\n * - `DELETE /api/sdk/simple-storage/:userId/:key` → delete single key\n * - `DELETE /api/sdk/simple-storage/:userId` → clear all data\n *\n * @module\n */\n\n// ─── Public Types ───────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * Structural type — no concrete imports so the manager stays unit-testable\n * with plain stubs.\n */\nexport interface StorageManagerDeps {\n /** DataStreamRouter — not used by StorageManager but part of the shared shape. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** MessageHandlerRegistry — not used by StorageManager but part of the shared shape. */\n messageHandlers: {\n register(type: string, handler: (msg: any) => void): () => void;\n };\n /** Add a subscription string (not used by StorageManager). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string (not used by StorageManager). */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n /** Package name — used for auth headers. */\n getPackageName: () => string;\n /** Current session ID. */\n getSessionId: () => string;\n /** Server URL for HTTP API calls (WebSocket URL or HTTP base). */\n getServerUrl?: () => string | null;\n}\n\n/**\n * Configuration options for StorageManager.\n */\nexport interface StorageManagerConfig {\n /** User ID for storage isolation. */\n userId: string;\n /** API key for authentication. */\n apiKey?: string;\n}\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/** Shape of the GET response from the storage API. */\ninterface StorageResponse {\n success: boolean;\n data?: Record<string, string>;\n}\n\n// ─── Constants ──────────────────────────────────────────────────────────────\n\n/** Maximum size for a single value in bytes/characters. */\nconst MAX_VALUE_SIZE = 100_000; // 100 KB\n\n/** Debounce idle time before flushing pending writes to the server. */\nconst DEBOUNCE_MS = 3_000; // 3 seconds\n\n/** Maximum wait time before forcing a flush, regardless of activity. */\nconst MAX_WAIT_MS = 10_000; // 10 seconds\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Key-value storage with local caching and debounced cloud sync.\n *\n * Provides a familiar `get`/`set`/`delete`/`clear` interface backed by\n * an in-memory cache with automatic persistence to the MentraOS cloud.\n * Writes are batched and debounced to minimise network traffic.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Set a value\n * await session.storage.set(\"username\", \"alice\");\n *\n * // Get a value\n * const name = await session.storage.get(\"username\");\n * console.log(name); // \"alice\"\n *\n * // Check existence\n * const exists = await session.storage.has(\"username\");\n *\n * // Delete a key\n * await session.storage.delete(\"username\");\n *\n * // Flush pending writes immediately\n * await session.storage.flush();\n * ```\n */\nexport class StorageManager {\n private readonly deps: StorageManagerDeps;\n private readonly userId: string;\n private readonly apiKey: string;\n\n /** Local cache — `null` means \"not yet loaded from server\". */\n private cache: Record<string, any> | null = null;\n\n /** Base URL for HTTP API calls. */\n private readonly baseUrl: string;\n\n // ─── Debounce / Batching State ──────────────────────────────────────────\n\n /** Pending writes waiting to be flushed. */\n private pendingWrites = new Map<string, any>();\n\n /** Timer for the idle debounce window. */\n private debounceTimer: ReturnType<typeof setTimeout> | undefined;\n\n /** Timer for the maximum wait window. */\n private maxWaitTimer: ReturnType<typeof setTimeout> | undefined;\n\n /** Timestamp of the first write in the current batch. */\n private firstWriteTime: number | undefined;\n\n constructor(deps: StorageManagerDeps, config: StorageManagerConfig) {\n this.deps = deps;\n this.userId = config.userId;\n this.apiKey = config.apiKey ?? \"unknown-api-key\";\n this.baseUrl = this.resolveBaseUrl();\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Get a value by key.\n *\n * Reads from the local cache. If the cache has not been populated yet,\n * it is fetched from the server first.\n *\n * @param key - The storage key to retrieve.\n * @returns The stored value, or `undefined` if the key does not exist.\n *\n * @example\n * ```ts\n * const value = await session.storage.get(\"theme\");\n * ```\n */\n async get(key: string): Promise<any> {\n try {\n await this.ensureCacheLoaded();\n return this.cache?.[key];\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error getting item:\", error);\n return undefined;\n }\n }\n\n /**\n * Set a value for a key.\n *\n * The local cache is updated immediately. The write is batched and\n * debounced — it will be persisted to the server after 3 seconds of\n * idle time or 10 seconds maximum, whichever comes first.\n *\n * @param key - The storage key.\n * @param value - The value to store. Will be serialised as JSON on the server.\n * @throws If the serialised value exceeds the 100 KB size limit.\n *\n * @example\n * ```ts\n * await session.storage.set(\"score\", \"42\");\n * ```\n */\n async set(key: string, value: any): Promise<void> {\n const serialised = typeof value === \"string\" ? value : JSON.stringify(value);\n\n if (serialised.length > MAX_VALUE_SIZE) {\n throw new Error(\n `StorageManager value exceeds 100KB limit (${serialised.length} chars). ` +\n `For large files, use your own S3 bucket storage.`,\n );\n }\n\n await this.ensureCacheLoaded();\n\n // Optimistic update — RAM is source of truth\n if (this.cache) {\n this.cache[key] = serialised;\n }\n\n // Add to pending batch\n this.pendingWrites.set(key, serialised);\n\n // Schedule debounced flush\n this.scheduleFlush();\n }\n\n /**\n * Delete a single key.\n *\n * Removes the key from the local cache immediately and sends a DELETE\n * request to the server. Unlike `set()`, deletes are flushed immediately\n * for consistency.\n *\n * @param key - The storage key to remove.\n *\n * @example\n * ```ts\n * await session.storage.delete(\"old-key\");\n * ```\n */\n async delete(key: string): Promise<void> {\n try {\n await this.ensureCacheLoaded();\n\n // Remove from local cache\n if (this.cache) {\n delete this.cache[key];\n }\n\n // Remove from pending writes if queued\n this.pendingWrites.delete(key);\n\n // Flush delete immediately to server\n const response = await fetch(\n `${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}/${encodeURIComponent(key)}`,\n {\n method: \"DELETE\",\n headers: this.getAuthHeaders(),\n },\n );\n\n if (!response.ok) {\n const errorText = await response.text();\n this.deps.logger.error(\"[StorageManager] Failed to delete key from server:\", errorText);\n }\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error deleting item:\", error);\n }\n }\n\n /**\n * Clear all stored data.\n *\n * Empties the local cache and sends a DELETE request to remove all\n * data from the server.\n *\n * @example\n * ```ts\n * await session.storage.clear();\n * ```\n */\n async clear(): Promise<void> {\n try {\n // Clear local state\n this.cache = {};\n this.pendingWrites.clear();\n this.clearTimers();\n\n // Clear on server\n const response = await fetch(`${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}`, {\n method: \"DELETE\",\n headers: this.getAuthHeaders(),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n this.deps.logger.error(\"[StorageManager] Failed to clear storage on server:\", errorText);\n }\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error clearing storage:\", error);\n }\n }\n\n /**\n * Get all storage keys.\n *\n * @returns An array of all keys currently in storage.\n *\n * @example\n * ```ts\n * const allKeys = await session.storage.keys();\n * console.log(\"Stored keys:\", allKeys);\n * ```\n */\n async keys(): Promise<string[]> {\n try {\n await this.ensureCacheLoaded();\n return Object.keys(this.cache || {});\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error getting keys:\", error);\n return [];\n }\n }\n\n /**\n * Check whether a key exists in storage.\n *\n * @param key - The storage key to check.\n * @returns `true` if the key exists.\n *\n * @example\n * ```ts\n * if (await session.storage.has(\"user-prefs\")) {\n * // load prefs\n * }\n * ```\n */\n async has(key: string): Promise<boolean> {\n try {\n await this.ensureCacheLoaded();\n return key in (this.cache || {});\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error checking key:\", error);\n return false;\n }\n }\n\n /**\n * Get a shallow copy of all stored key-value pairs.\n *\n * @returns A record of all stored data.\n *\n * @example\n * ```ts\n * const allData = await session.storage.getAll();\n * console.log(allData);\n * ```\n */\n async getAll(): Promise<Record<string, any>> {\n try {\n await this.ensureCacheLoaded();\n return { ...(this.cache || {}) };\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error getting all data:\", error);\n return {};\n }\n }\n\n /**\n * Set multiple key-value pairs at once.\n *\n * All values are validated for size before any are applied. The local\n * cache is updated immediately and writes are batched for persistence.\n *\n * @param data - A record of key-value pairs to set.\n * @throws If any value exceeds the 100 KB size limit.\n *\n * @example\n * ```ts\n * await session.storage.setMultiple({\n * theme: \"dark\",\n * language: \"en\",\n * fontSize: \"14\",\n * });\n * ```\n */\n async setMultiple(data: Record<string, any>): Promise<void> {\n // Validate all values first\n for (const [key, value] of Object.entries(data)) {\n const serialised = typeof value === \"string\" ? value : JSON.stringify(value);\n if (serialised.length > MAX_VALUE_SIZE) {\n throw new Error(`StorageManager value for key \"${key}\" exceeds 100KB limit (${serialised.length} chars).`);\n }\n }\n\n await this.ensureCacheLoaded();\n\n // Update cache and pending writes\n for (const [key, value] of Object.entries(data)) {\n const serialised = typeof value === \"string\" ? value : JSON.stringify(value);\n if (this.cache) {\n this.cache[key] = serialised;\n }\n this.pendingWrites.set(key, serialised);\n }\n\n // Schedule debounced flush\n this.scheduleFlush();\n }\n\n /**\n * Flush all pending writes to the server immediately.\n *\n * This is called automatically by the debounce/max-wait timers, but can\n * also be called explicitly (e.g., before disconnect). If there are no\n * pending writes, this is a no-op.\n *\n * @throws If the server returns an error (413 for size limit, 429 for rate limit).\n *\n * @example\n * ```ts\n * await session.storage.flush();\n * ```\n */\n async flush(): Promise<void> {\n if (this.pendingWrites.size === 0) return;\n\n // Clear all timers\n this.clearTimers();\n\n // Snapshot and clear pending writes\n const batch = Object.fromEntries(this.pendingWrites);\n this.pendingWrites.clear();\n\n try {\n const response = await fetch(`${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}`, {\n method: \"PUT\",\n headers: this.getAuthHeaders(),\n body: JSON.stringify({ data: batch }),\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n this.deps.logger.error(\"[StorageManager] Failed to persist writes:\", errorText);\n\n if (response.status === 413) {\n throw new Error(\"StorageManager total size exceeds 1MB limit. Delete unused keys.\");\n }\n if (response.status === 429) {\n throw new Error(\"StorageManager rate limit exceeded.\");\n }\n throw new Error(`StorageManager flush failed: ${errorText}`);\n }\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error flushing writes:\", error);\n throw error;\n }\n }\n\n // ─── Cleanup ────────────────────────────────────────────────────────────\n\n /**\n * Flush pending writes and clean up all resources.\n *\n * Called by MentraSession during disconnect/cleanup.\n * @internal\n */\n async destroy(): Promise<void> {\n // Attempt to flush any pending writes before shutting down\n try {\n await this.flush();\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error flushing on destroy:\", error);\n }\n\n this.clearTimers();\n this.pendingWrites.clear();\n this.cache = null;\n\n this.deps.logger.debug(\"[StorageManager] Destroyed.\");\n }\n\n // ─── Internal: Cache Loading ────────────────────────────────────────────\n\n /**\n * Ensure the local cache is populated from the server.\n * Only fetches once — subsequent calls are no-ops.\n */\n private async ensureCacheLoaded(): Promise<void> {\n if (this.cache !== null) return;\n await this.fetchFromServer();\n }\n\n /**\n * Fetch all stored data from the server and populate the local cache.\n */\n private async fetchFromServer(): Promise<void> {\n try {\n const response = await fetch(`${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}`, {\n headers: this.getAuthHeaders(),\n });\n\n if (response.ok) {\n const result = (await response.json()) as StorageResponse;\n if (result.success && result.data) {\n this.cache = result.data;\n } else {\n this.cache = {};\n }\n } else {\n this.deps.logger.error(\"[StorageManager] Failed to fetch storage from server:\", await response.text());\n this.cache = {};\n }\n } catch (error) {\n this.deps.logger.error(\"[StorageManager] Error fetching storage from server:\", error);\n this.cache = {};\n }\n }\n\n // ─── Internal: Debounce / Batching ──────────────────────────────────────\n\n /**\n * Schedule a debounced flush of pending writes.\n *\n * Uses a two-timer strategy:\n * 1. **Idle timer** — fires after {@link DEBOUNCE_MS} of inactivity (reset on each write).\n * 2. **Max wait timer** — fires after {@link MAX_WAIT_MS} from the first write in the batch,\n * ensuring writes are never delayed indefinitely during continuous activity.\n */\n private scheduleFlush(): void {\n // Track first write time for max-wait calculation\n if (!this.firstWriteTime) {\n this.firstWriteTime = Date.now();\n }\n\n // Clear existing idle debounce timer\n if (this.debounceTimer !== undefined) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n }\n\n // Calculate remaining time until max-wait deadline\n const elapsedMs = Date.now() - this.firstWriteTime;\n const remainingMaxWaitMs = MAX_WAIT_MS - elapsedMs;\n\n // If max wait already exceeded, flush immediately\n if (remainingMaxWaitMs <= 0) {\n this.flush().catch((err) => {\n this.deps.logger.error(\"[StorageManager] Error in scheduled flush:\", err);\n });\n return;\n }\n\n // Set idle debounce timer (capped at remaining max-wait)\n this.debounceTimer = setTimeout(\n () => {\n this.flush().catch((err) => {\n this.deps.logger.error(\"[StorageManager] Error in debounced flush:\", err);\n });\n },\n Math.min(DEBOUNCE_MS, remainingMaxWaitMs),\n );\n\n // Set max-wait timer if not already running\n if (this.maxWaitTimer === undefined && remainingMaxWaitMs > 0) {\n this.maxWaitTimer = setTimeout(() => {\n this.flush().catch((err) => {\n this.deps.logger.error(\"[StorageManager] Error in max-wait flush:\", err);\n });\n }, remainingMaxWaitMs);\n }\n }\n\n /**\n * Clear all flush timers and reset batch tracking state.\n */\n private clearTimers(): void {\n if (this.debounceTimer !== undefined) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = undefined;\n }\n if (this.maxWaitTimer !== undefined) {\n clearTimeout(this.maxWaitTimer);\n this.maxWaitTimer = undefined;\n }\n this.firstWriteTime = undefined;\n }\n\n // ─── Internal: HTTP Helpers ─────────────────────────────────────────────\n\n /**\n * Resolve the base URL for HTTP API calls.\n *\n * Converts the WebSocket URL (e.g., `wss://host/app-ws`) to an HTTP URL\n * (e.g., `https://host`). Falls back to `http://localhost:8002` if no\n * server URL is available.\n */\n private resolveBaseUrl(): string {\n const serverUrl = this.deps.getServerUrl?.() ?? null;\n if (!serverUrl) return \"http://localhost:8002\";\n return serverUrl.replace(/\\/app-ws$/, \"\").replace(/^ws/, \"http\");\n }\n\n /**\n * Generate auth headers for API requests.\n *\n * Uses the `packageName:apiKey` format expected by the SDK server's\n * auth middleware.\n */\n private getAuthHeaders(): Record<string, string> {\n return {\n \"Authorization\": `Bearer ${this.deps.getPackageName()}:${this.apiKey}`,\n \"Content-Type\": \"application/json\",\n };\n }\n}\n",
|
|
36
36
|
"/**\n * ⏰ TimeUtils — Stateless Timezone Utilities\n *\n * Pure utility class for timezone-aware date operations. Uses the built-in\n * `Intl.DateTimeFormat` API for formatting — no external dependencies.\n *\n * This class has **no transport layer**, no subscriptions, and no wire\n * messages. It is a convenience wrapper for apps that need to display\n * or reason about times in the user's local timezone (which may differ\n * from the server's timezone).\n *\n * @example\n * ```ts\n * const time = new TimeUtils(\"America/New_York\");\n *\n * // Current time in the user's timezone\n * const now = time.now();\n *\n * // Format a date for display\n * const formatted = time.format(now, { hour: \"numeric\", minute: \"2-digit\" });\n * // => \"3:45 PM\"\n *\n * // Convert a UTC date to the user's local timezone\n * const local = time.toLocal(new Date(\"2024-01-15T20:00:00Z\"));\n *\n * // Change timezone at runtime (e.g., user travelled)\n * time.setTimezone(\"Europe/London\");\n * ```\n *\n * @module\n */\n\n// ─── TimeUtils ──────────────────────────────────────────────────────────────\n\n/**\n * Timezone-aware date utility class.\n *\n * Wraps the `Intl.DateTimeFormat` API to provide convenient methods for\n * creating, converting, and formatting dates in a specific timezone.\n *\n * The timezone can be changed at runtime via {@link setTimezone}, making\n * this class suitable for long-lived sessions where the user may travel\n * across timezone boundaries.\n */\nexport class TimeUtils {\n /**\n * The current IANA timezone identifier (e.g., `\"America/New_York\"`,\n * `\"Europe/London\"`, `\"Asia/Tokyo\"`).\n */\n private _zone: string;\n\n /**\n * Create a new TimeUtils instance.\n *\n * @param timezone - IANA timezone identifier. Must be a valid timezone\n * string recognised by `Intl.DateTimeFormat` (e.g., `\"America/New_York\"`,\n * `\"UTC\"`, `\"Asia/Tokyo\"`).\n *\n * @throws {RangeError} If the provided timezone string is not a valid\n * IANA timezone identifier.\n *\n * @example\n * ```ts\n * const time = new TimeUtils(\"America/Los_Angeles\");\n * ```\n */\n constructor(timezone: string) {\n // Validate the timezone by attempting to create a formatter with it.\n // Intl.DateTimeFormat will throw a RangeError for invalid timezones.\n TimeUtils.validateTimezone(timezone);\n this._zone = timezone;\n }\n\n // ─── Accessors ──────────────────────────────────────────────────────────\n\n /**\n * The current IANA timezone identifier.\n *\n * @example\n * ```ts\n * console.log(time.zone); // \"America/New_York\"\n * ```\n */\n get zone(): string {\n return this._zone;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Get the current date/time.\n *\n * Returns a standard `Date` object representing the current instant.\n * The `Date` itself is always UTC internally — use {@link format} or\n * {@link toLocal} to interpret it in the configured timezone.\n *\n * @returns A `Date` representing the current moment.\n *\n * @example\n * ```ts\n * const now = time.now();\n * console.log(time.format(now)); // formatted in the configured timezone\n * ```\n */\n now(): Date {\n return new Date();\n }\n\n /**\n * Convert a `Date` to a new `Date` whose UTC fields represent the\n * wall-clock time in the configured timezone.\n *\n * This is useful when you need to extract hours/minutes/seconds that\n * correspond to the local timezone without using `Intl` formatting.\n *\n * **Note:** The returned `Date` is a synthetic object — its\n * `getUTCHours()` etc. return the *local* values, but calling\n * `toISOString()` on it will produce a misleading string. Prefer\n * {@link format} for display purposes.\n *\n * @param date - The date to convert. Defaults to `new Date()` (now).\n * @returns A new `Date` whose UTC methods return local-timezone values.\n *\n * @example\n * ```ts\n * const utcDate = new Date(\"2024-01-15T20:00:00Z\");\n * const local = time.toLocal(utcDate);\n * console.log(local.getUTCHours()); // 15 if timezone is \"America/New_York\" (EST = UTC-5)\n * ```\n */\n toLocal(date: Date = new Date()): Date {\n // Use Intl to get the timezone offset, then shift the date.\n // formatToParts gives us the local components — we reconstruct a Date from them.\n const parts = new Intl.DateTimeFormat(\"en-US\", {\n timeZone: this._zone,\n year: \"numeric\",\n month: \"2-digit\",\n day: \"2-digit\",\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n }).formatToParts(date);\n\n const get = (type: string): string => {\n const part = parts.find((p) => p.type === type);\n return part?.value ?? \"0\";\n };\n\n const year = parseInt(get(\"year\"), 10);\n const month = parseInt(get(\"month\"), 10) - 1; // JS months are 0-indexed\n const day = parseInt(get(\"day\"), 10);\n let hour = parseInt(get(\"hour\"), 10);\n const minute = parseInt(get(\"minute\"), 10);\n const second = parseInt(get(\"second\"), 10);\n\n // hour12: false can yield \"24\" for midnight in some locales — normalise\n if (hour === 24) hour = 0;\n\n // Construct a Date using UTC setters so the UTC fields hold local values\n return new Date(Date.UTC(year, month, day, hour, minute, second));\n }\n\n /**\n * Format a `Date` for display in the configured timezone.\n *\n * Delegates to `Intl.DateTimeFormat` with the configured timezone\n * injected automatically. Any valid `Intl.DateTimeFormatOptions` can\n * be passed through.\n *\n * If no options are provided, a sensible default is used:\n * `\"1/15/2024, 3:45:00 PM\"` (locale-dependent).\n *\n * @param date - The date to format.\n * @param opts - Optional `Intl.DateTimeFormatOptions` to control output.\n * @returns The formatted date string.\n *\n * @example\n * ```ts\n * // Default format\n * time.format(new Date());\n * // => \"1/15/2024, 3:45:00 PM\"\n *\n * // Custom format — time only\n * time.format(new Date(), { hour: \"numeric\", minute: \"2-digit\" });\n * // => \"3:45 PM\"\n *\n * // Custom format — full date\n * time.format(new Date(), {\n * weekday: \"long\",\n * year: \"numeric\",\n * month: \"long\",\n * day: \"numeric\",\n * });\n * // => \"Monday, January 15, 2024\"\n *\n * // With a specific locale\n * time.format(new Date(), { hour: \"numeric\", minute: \"2-digit\" });\n * ```\n */\n format(date: Date, opts?: Intl.DateTimeFormatOptions): string {\n const mergedOpts: Intl.DateTimeFormatOptions = {\n ...opts,\n timeZone: this._zone,\n };\n\n return new Intl.DateTimeFormat(undefined, mergedOpts).format(date);\n }\n\n /**\n * Change the timezone at runtime.\n *\n * Validates the new timezone before applying it. If the timezone is\n * invalid, a `RangeError` is thrown and the previous timezone is retained.\n *\n * @param tz - New IANA timezone identifier.\n * @throws {RangeError} If the timezone string is not valid.\n *\n * @example\n * ```ts\n * time.setTimezone(\"Europe/London\");\n * console.log(time.zone); // \"Europe/London\"\n * ```\n */\n setTimezone(tz: string): void {\n TimeUtils.validateTimezone(tz);\n this._zone = tz;\n }\n\n // ─── Internal ───────────────────────────────────────────────────────────\n\n /**\n * Validate that a timezone string is recognised by the runtime's\n * `Intl.DateTimeFormat` implementation.\n *\n * @param tz - The timezone string to validate.\n * @throws {RangeError} If the timezone is not valid.\n */\n private static validateTimezone(tz: string): void {\n // Intl.DateTimeFormat throws RangeError for unrecognised timeZone values.\n // We intentionally let that error propagate with a clear message.\n try {\n Intl.DateTimeFormat(undefined, { timeZone: tz });\n } catch {\n throw new RangeError(\n `Invalid timezone: \"${tz}\". ` +\n `Must be a valid IANA timezone identifier (e.g., \"America/New_York\", \"UTC\", \"Asia/Tokyo\").`,\n );\n }\n }\n}\n",
|
|
37
37
|
"/**\n * TranscriptionManager — v3 SDK Transcription API\n *\n * Replaces the old `session.events.onTranscription*()` methods with a cleaner,\n * composable API that supports multiple simultaneous subscriptions.\n *\n * @example\n * ```ts\n * const session = await mentra.connect();\n *\n * // Subscribe to all transcription (auto-detect language)\n * const stopAll = session.transcription.on((evt) => {\n * console.log(`[${evt.language}] ${evt.text}`);\n * });\n *\n * // Also subscribe to a specific language — independent of the above\n * const stopEn = session.transcription.forLanguage(\"en\", (evt) => {\n * console.log(`English: ${evt.text}`);\n * });\n *\n * // Multiple languages in one call\n * const stopMulti = session.transcription.forLanguage([\"ja\", \"es\"], (evt) => {\n * console.log(`${evt.language}: ${evt.text}`);\n * });\n *\n * // Configure hints / vocabulary / diarization\n * session.transcription.configure({\n * languageHints: [\"en\", \"ja\"],\n * vocabulary: [\"MentraOS\", \"HIPAA\"],\n * diarization: true,\n * });\n *\n * // Cleanup individual subscriptions\n * stopEn();\n *\n * // Or tear down everything\n * session.transcription.stop();\n * ```\n *\n * @module\n */\n\nimport { StreamType } from \"../../types\";\n\n// ─── Public Types ───────────────────────────────────────────────────────────\n\n/**\n * Configuration options that influence transcription behaviour on the cloud.\n *\n * Passed to {@link TranscriptionManager.configure}. Applies globally to all\n * active subscriptions managed by this instance.\n */\nexport interface TranscriptionConfig {\n /** ISO 639-1 language hints to improve detection accuracy (e.g. `[\"en\", \"ja\", \"es\"]`). */\n languageHints?: string[];\n /** Custom vocabulary / boosted terms (e.g. `[\"MentraOS\", \"HIPAA\"]`). */\n vocabulary?: string[];\n /** Enable speaker diarisation. Defaults to `true`. */\n diarization?: boolean;\n}\n\n/**\n * Normalised transcription event delivered to subscriber callbacks.\n *\n * This is the *public* shape — it is mapped from the raw cloud\n * `TranscriptionData` message inside the manager so consumers never\n * need to think about wire-level details.\n */\nexport interface TranscriptionEvent {\n /** The transcribed text. */\n text: string;\n /** `true` when the cloud considers this utterance segment finalised. */\n isFinal: boolean;\n /** ISO 639-1 detected language code (e.g. `\"en\"`, `\"ja\"`). */\n language: string;\n /** Speaker identifier when diarisation is enabled. */\n speakerId?: string;\n /** Stable identifier for a contiguous utterance. Interim and final events for the same utterance share this ID. */\n utteranceId?: string;\n /** Recognition confidence in the range `[0, 1]`. */\n confidence?: number;\n /** Start time of the utterance segment in milliseconds. */\n startTime: number;\n /** End time of the utterance segment in milliseconds. */\n endTime: number;\n /** Audio duration in milliseconds. */\n duration?: number;\n /** Provider-specific metadata (token-level details, etc.). */\n metadata?: any;\n}\n\n/** Callback signature for transcription subscribers. */\nexport type TranscriptionHandler = (data: TranscriptionEvent) => void;\n\n// ─── Internal Types ─────────────────────────────────────────────────────────\n\n/**\n * Dependencies injected by MentraSession.\n *\n * This is intentionally a *structural* type — we don't import the concrete\n * `DataStreamRouter` class so that the manager remains unit-testable with\n * plain stubs.\n */\nexport interface TranscriptionManagerDeps {\n /** Register for DATA_STREAM messages by streamType key (exact or prefix). Returns a cleanup function. */\n router: {\n on(key: string, handler: (streamType: string, data: any, message: any) => void): () => void;\n };\n /** Add a subscription string (triggers SUBSCRIPTION_UPDATE to cloud). */\n addSubscription: (stream: string) => void;\n /** Remove a subscription string. */\n removeSubscription: (stream: string) => void;\n /** Send an arbitrary JSON message to the cloud. */\n sendMessage: (message: any) => void;\n /** Structured logger. */\n logger: {\n debug(...args: any[]): void;\n info(...args: any[]): void;\n warn(...args: any[]): void;\n error(...args: any[]): void;\n };\n}\n\n/**\n * Internal bookkeeping for a single `on()` / `forLanguage()` registration.\n *\n * Each call to a public subscription method produces one `Registration` per\n * stream key it subscribes to, enabling independent cleanup.\n */\ninterface Registration {\n /** The subscription strings this registration added (e.g. `\"transcription:en\"`). */\n streams: string[];\n /** Cleanup functions returned by `router.on()` for each stream key. */\n routerCleanups: Array<() => void>;\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\n/** Stream prefix used on the wire. */\nconst STREAM_PREFIX = StreamType.TRANSCRIPTION; // \"transcription\"\n\n/** Build the subscription string for a language code. */\nfunction subscriptionKey(lang: string): string {\n return `${STREAM_PREFIX}:${lang}`;\n}\n\n/**\n * Map raw cloud `TranscriptionData` into the public {@link TranscriptionEvent}.\n *\n * The cloud sends fields like `detectedLanguage`, `transcribeLanguage`, and\n * `metadata` that we normalise into a friendlier shape.\n */\nfunction normalise(streamType: string, raw: any): TranscriptionEvent {\n // Derive the language from `detectedLanguage` first, then fall back to the\n // subscription language embedded in the streamType (\"transcription:en\" → \"en\"),\n // and finally to an empty string.\n const language = raw.detectedLanguage ?? raw.transcribeLanguage ?? streamType.replace(`${STREAM_PREFIX}:`, \"\") ?? \"\";\n\n return {\n text: raw.text ?? \"\",\n isFinal: !!raw.isFinal,\n language,\n speakerId: raw.speakerId,\n utteranceId: raw.utteranceId,\n confidence: raw.confidence,\n startTime: raw.startTime ?? 0,\n endTime: raw.endTime ?? 0,\n duration: raw.duration,\n metadata: raw.metadata,\n };\n}\n\n// ─── Manager ────────────────────────────────────────────────────────────────\n\n/**\n * Manages transcription subscriptions and dispatches normalised events to\n * application-level handlers.\n *\n * Every public subscription method (`on`, `forLanguage`) is **independent** —\n * multiple can be active simultaneously and each returns its own cleanup\n * function. Calling {@link stop} tears down *all* active subscriptions.\n */\nexport class TranscriptionManager {\n private readonly deps: TranscriptionManagerDeps;\n\n /**\n * All currently-active registrations. We track them so that {@link stop}\n * can clean everything up in one shot.\n */\n private registrations = new Set<Registration>();\n\n /**\n * Reference count per subscription stream string.\n *\n * Multiple independent registrations may share the same underlying stream\n * key (e.g. two `forLanguage(\"en\", …)` calls). We only call\n * `deps.removeSubscription` when the ref-count drops to zero.\n */\n private refCounts = new Map<string, number>();\n\n /** Latest config applied via {@link configure}. */\n private currentConfig: TranscriptionConfig | null = null;\n\n constructor(deps: TranscriptionManagerDeps) {\n this.deps = deps;\n }\n\n // ─── Public API ─────────────────────────────────────────────────────────\n\n /**\n * Subscribe to **all** transcription events (auto-detect, all languages).\n *\n * Registers a prefix handler on the router for `\"transcription\"` so that\n * events for *any* language are delivered to `handler`. The cloud\n * subscription is `\"transcription:auto\"`.\n *\n * @param handler - Called for every incoming transcription event.\n * @returns A cleanup function that removes this specific subscription.\n */\n on(handler: TranscriptionHandler): () => void {\n const stream = subscriptionKey(\"auto\"); // \"transcription:auto\"\n\n // Register on the router using the bare prefix so we receive\n // transcription:en, transcription:ja, transcription:auto, etc.\n const routerCleanup = this.deps.router.on(STREAM_PREFIX, (_streamType, data, _message) => {\n try {\n handler(normalise(_streamType, data));\n } catch (err) {\n this.deps.logger.error(`[TranscriptionManager] Error in on() handler:`, err);\n }\n });\n\n const reg: Registration = {\n streams: [stream],\n routerCleanups: [routerCleanup],\n };\n\n this.addRegistration(reg);\n\n return () => this.removeRegistration(reg);\n }\n\n /**\n * Subscribe to transcription for one or more specific languages.\n *\n * Each call is **independent** — multiple can be active simultaneously.\n * When an array is provided the handler fires for events in *any* of the\n * listed languages.\n *\n * @param lang - ISO 639-1 language code(s) (e.g. `\"en\"` or `[\"en\", \"ja\"]`).\n * @param handler - Called for every matching transcription event.\n * @returns A cleanup function that removes this specific subscription.\n */\n forLanguage(lang: string | string[], handler: TranscriptionHandler): () => void {\n const langs = Array.isArray(lang) ? lang : [lang];\n\n if (langs.length === 0) {\n this.deps.logger.warn(\"[TranscriptionManager] forLanguage() called with empty language array — no-op.\");\n return () => {};\n }\n\n const streams: string[] = [];\n const routerCleanups: Array<() => void> = [];\n\n for (const l of langs) {\n const stream = subscriptionKey(l); // e.g. \"transcription:en\"\n\n const cleanup = this.deps.router.on(stream, (_streamType, data, _message) => {\n try {\n handler(normalise(_streamType, data));\n } catch (err) {\n this.deps.logger.error(`[TranscriptionManager] Error in forLanguage(\"${l}\") handler:`, err);\n }\n });\n\n streams.push(stream);\n routerCleanups.push(cleanup);\n }\n\n const reg: Registration = { streams, routerCleanups };\n this.addRegistration(reg);\n\n return () => this.removeRegistration(reg);\n }\n\n /**\n * Apply transcription configuration (language hints, custom vocabulary,\n * diarisation toggle).\n *\n * The configuration is sent to the cloud immediately and cached so that\n * it can be re-sent if the session reconnects.\n *\n * @param config - Configuration to apply.\n */\n configure(config: TranscriptionConfig): void {\n this.currentConfig = { ...config };\n\n this.deps.sendMessage({\n type: \"transcription_config\",\n languageHints: config.languageHints,\n vocabulary: config.vocabulary,\n diarization: config.diarization ?? true,\n });\n\n this.deps.logger.debug(\"[TranscriptionManager] Configuration sent:\", config);\n }\n\n /**\n * Stop **all** transcription subscriptions and remove every handler.\n *\n * After calling this, no transcription callbacks will fire until new\n * subscriptions are created via {@link on} or {@link forLanguage}.\n */\n stop(): void {\n // Iterate over a snapshot — removeRegistration mutates the set.\n const snapshot = Array.from(this.registrations);\n for (const reg of snapshot) {\n this.removeRegistration(reg);\n }\n\n this.currentConfig = null;\n this.deps.logger.debug(\"[TranscriptionManager] All subscriptions stopped.\");\n }\n\n // ─── Introspection (useful for testing / debugging) ─────────────────────\n\n /** Returns `true` if there is at least one active subscription. */\n get active(): boolean {\n return this.registrations.size > 0;\n }\n\n /** Returns the current configuration, or `null` if none has been set. */\n get config(): TranscriptionConfig | null {\n return this.currentConfig ? { ...this.currentConfig } : null;\n }\n\n // ─── Internal ───────────────────────────────────────────────────────────\n\n /**\n * Track a new registration: increment ref-counts and call\n * `addSubscription` for any stream that is newly referenced.\n */\n private addRegistration(reg: Registration): void {\n this.registrations.add(reg);\n\n for (const stream of reg.streams) {\n const prev = this.refCounts.get(stream) ?? 0;\n this.refCounts.set(stream, prev + 1);\n\n // Only subscribe on the wire when the first handler for this stream\n // comes online.\n if (prev === 0) {\n this.deps.addSubscription(stream);\n this.deps.logger.debug(`[TranscriptionManager] Subscribed to \"${stream}\".`);\n }\n }\n }\n\n /**\n * Tear down a registration: unregister router handlers, decrement\n * ref-counts, and call `removeSubscription` when a stream drops to zero\n * references.\n */\n private removeRegistration(reg: Registration): void {\n if (!this.registrations.has(reg)) return; // Already removed (idempotent).\n\n // 1. Remove router handlers.\n for (const cleanup of reg.routerCleanups) {\n try {\n cleanup();\n } catch {\n // Best-effort — the router may have already been cleared.\n }\n }\n\n // 2. Decrement ref-counts and unsubscribe when necessary.\n for (const stream of reg.streams) {\n const count = this.refCounts.get(stream) ?? 0;\n const next = count - 1;\n\n if (next <= 0) {\n this.refCounts.delete(stream);\n this.deps.removeSubscription(stream);\n this.deps.logger.debug(`[TranscriptionManager] Unsubscribed from \"${stream}\".`);\n } else {\n this.refCounts.set(stream, next);\n }\n }\n\n // 3. Remove from the active set.\n this.registrations.delete(reg);\n }\n}\n",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"// src/index.ts\nexport * from \"./types/token\";\n\n// Message type enums\nexport * from \"./types/message-types\";\n\n// Base message type\nexport * from \"./types/messages/base\";\n\n// Messages by direction - export everything except the conflicting type guards\nexport * from \"./types/messages/glasses-to-cloud\";\nexport * from \"./types/messages/cloud-to-glasses\";\nexport * from \"./types/messages/app-to-cloud\";\n\n// Utility exports\nexport * from \"./utils/bitmap-utils\";\nexport * from \"./utils/animation-utils\";\n\n// Export cloud-to-app type guards and runtime exports\nexport {\n // Type guards (excluding isPhotoResponse and isStreamStatus which conflict)\n isAppConnectionAck,\n isAppConnectionError,\n isAppStopped,\n isSettingsUpdate,\n isCapabilitiesUpdate,\n isDataStream,\n isAudioChunk,\n isStreamStatusCheckResponse,\n isDashboardModeChanged,\n isDashboardAlwaysOnChanged,\n isManagedStreamStatus,\n isRequestTelemetry,\n isTelemetryResponse,\n // Re-export the cloud-to-app versions of these type guards since they're the ones\n // that should be used when dealing with CloudToAppMessage types\n isPhotoResponse as isPhotoResponseFromCloud,\n isRgbLedControlResponse as isRgbLedControlResponseFromCloud,\n isStreamStatus as isStreamStatusFromCloud,\n} from \"./types\";\n\n// Export cloud-to-app types (type-only exports)\nexport type {\n AppConnectionAck,\n AppConnectionError,\n AppStopped,\n SettingsUpdate as AppSettingsUpdate, // Alias to avoid conflict with cloud-to-glasses SettingsUpdate\n CapabilitiesUpdate,\n DataStream,\n CloudToAppMessage,\n TranslationData,\n ToolCall,\n StandardConnectionError,\n CustomMessage,\n ManagedStreamStatus,\n StreamStatusCheckResponse,\n OutputStatus,\n MentraosSettingsUpdate,\n TranscriptionData,\n TranscriptionMetadata,\n SonioxToken,\n AudioChunk,\n PermissionError,\n PermissionErrorDetail,\n AudioPlayResponse,\n RequestTelemetry,\n TelemetryLogEntry,\n TelemetryResponse,\n} from \"./types\";\n\n// Stream types\nexport * from \"./types/streams\";\n\n// Layout types\nexport * from \"./types/layouts\";\n\n// Dashboard types\nexport * from \"./types/dashboard\";\n\n// RTMP streaming types\nexport * from \"./types/rtmp-stream\";\n\n// Other system enums\nexport { AppType, LayoutType, ViewType, AppSettingType, HardwareType, HardwareRequirementLevel } from \"./types/enums\";\n\n// Core model interfaces\nexport * from \"./types/models\";\n\n// Webhook interfaces\nexport * from \"./types/webhooks\";\n\n// Capability Discovery types\nexport * from \"./types/capabilities\";\n\n// App session and server exports\nexport * from \"./app/index\";\nexport * from \"./MiniAppServer\";\n\n// v3 session — explicit re-exports to avoid name collisions with v2 types\n// The full set of manager types is available via \"@mentra/sdk/session\" entrypoint\nexport { MentraSession } from \"./session/MentraSession\";\nexport type { MentraSessionConfig } from \"./session/MentraSession\";\n\n// Logging exports\nexport * from \"./logging/logger\";\n\n// Error classes\nexport {\n MentraError,\n MentraAuthError,\n MentraConnectionError,\n MentraTimeoutError,\n MentraValidationError,\n MentraPermissionError,\n} from \"./logging/errors\";\n\n// Re-export common types for convenience\n// This allows developers to import commonly used types directly from the package root\n// without having to know exactly which file they come from\n\n// From messages/glasses-to-cloud.ts\nexport type {\n ButtonPress,\n HeadPosition,\n TouchEvent,\n GlassesBatteryUpdate,\n PhoneBatteryUpdate,\n GlassesConnectionState,\n LocationUpdate,\n CalendarEvent,\n Vad,\n PhoneNotification,\n PhoneNotificationDismissed,\n StartApp,\n StopApp,\n ConnectionInit,\n DashboardState,\n OpenDashboard,\n GlassesToCloudMessage,\n PhotoResponse,\n RgbLedControlResponse,\n ConnectionState,\n PhotoErrorDetails,\n} from \"./types/messages/glasses-to-cloud\";\n\n// These are enums (runtime values) — must NOT be re-exported as `export type`\n// or they become unusable as values (TS1362). The `export *` at the top of\n// this file already exports them correctly; these explicit exports are kept\n// here as documentation but as value exports.\nexport { PhotoErrorCode, PhotoStage, StreamStatus, KeepAliveAck } from \"./types/messages/glasses-to-cloud\";\n\n// From messages/cloud-to-glasses.ts\nexport type {\n ConnectionAck,\n ConnectionError,\n AuthError,\n DisplayEvent,\n AppStateChange,\n MicrophoneStateChange,\n CloudToGlassesMessage,\n PhotoRequestToGlasses,\n RgbLedControlToGlasses,\n CameraFovSetToGlasses,\n SettingsUpdate,\n StartStream,\n StopStream,\n KeepStreamAlive,\n LedColor,\n} from \"./types/messages/cloud-to-glasses\";\n\n// From messages/app-to-cloud.ts\nexport type {\n AppConnectionInit,\n AppSubscriptionUpdate,\n StreamRequest,\n StreamStopRequest,\n AppToCloudMessage,\n PhotoRequest,\n RgbLedControlRequest,\n CameraFovSetRequest,\n CameraRoiPosition,\n} from \"./types/messages/app-to-cloud\";\n\n// From layout.ts\nexport type {\n TextWall,\n DoubleTextWall,\n DashboardCard,\n ReferenceCard,\n Layout,\n DisplayRequest,\n BitmapView,\n ClearView,\n} from \"./types/layouts\";\n\n// Type guards - re-export the most commonly used ones for convenience\nexport {\n isButtonPress,\n isHeadPosition,\n isConnectionInit,\n isStartApp,\n isStopApp,\n isPhotoResponse as isPhotoResponseFromGlasses,\n isRgbLedControlResponse as isRgbLedControlResponseFromGlasses,\n isStreamStatus as isStreamStatusFromGlasses,\n isKeepAliveAck,\n isPhoneNotificationDismissed,\n} from \"./types/messages/glasses-to-cloud\";\n\nexport {\n isConnectionAck,\n isDisplayEvent,\n isAppStateChange,\n isPhotoRequest,\n isSettingsUpdate as isSettingsUpdateToGlasses,\n isStartStream,\n isStopStream,\n isKeepStreamAlive,\n isRgbLedControl,\n} from \"./types/messages/cloud-to-glasses\";\n\nexport {\n isAppConnectionInit,\n isAppSubscriptionUpdate,\n isDisplayRequest,\n isStreamRequest,\n isStreamStopRequest,\n isPhotoRequest as isPhotoRequestFromApp,\n isRgbLedControlRequest,\n isCameraFovSetRequest,\n isOwnershipRelease,\n} from \"./types/messages/app-to-cloud\";\n\n// Export setting-related types\nexport { validateAppConfig } from \"./types/models\";\n\nexport type {\n BaseAppSetting,\n AppSetting,\n AppSettings,\n AppConfig,\n ToolSchema,\n ToolParameterSchema,\n HardwareRequirement,\n PreviewImage,\n PhotoOrientation,\n} from \"./types/models\";\n\n// Export RTMP streaming types\nexport type { VideoConfig, AudioConfig, StreamConfig, StreamStatusHandler } from \"./types/rtmp-stream\";\n\n// Export app session modules\nexport * from \"./app/session/modules\";\n\n// Export photo data types\nexport type { PhotoData } from \"./types/photo-data\";\n\n// Export device state types (WebSocket-based observables)\nexport type { DeviceState } from \"./app/session/device-state\";\nexport { Observable } from \"./utils/Observable\";\n\n// Re-export types from @mentra/types so SDK users don't need to install it separately\nexport type { GlassesInfo } from \"@mentra/types\";\n\n/**\n * WebSocket error information\n */\nexport interface WebSocketError {\n code: string;\n message: string;\n details?: unknown;\n}\n\nexport type { AuthenticatedRequest, AuthVariables, MentraAuthContext, MentraAuthHonoContext } from \"./types/index\";\n\n// Frontend authentication helpers for Bun fullstack apps\nexport {\n createAuthMiddleware,\n createMentraAuthRoutes,\n generateFrontendToken,\n getMentraAuth,\n requireMentraAuth,\n} from \"./app/webview/index\";\n",
|
|
46
46
|
"/**\n * 🎨 Bitmap Utilities Module\n *\n * Provides helper functions for working with bitmap images in MentraOS applications.\n * Includes file loading, data validation, and format conversion utilities.\n *\n * @example\n * ```typescript\n * import { BitmapUtils } from '@mentra/sdk';\n *\n * // Load a single BMP file\n * const bmpHex = await BitmapUtils.loadBmpAsHex('./my-image.bmp');\n * session.layouts.showBitmapView(bmpHex);\n *\n * // Load multiple animation frames\n * const frames = await BitmapUtils.loadBmpFrames('./animations', 10);\n * session.layouts.showBitmapAnimation(frames, 1500, true);\n * ```\n */\n\nimport * as fs from \"fs/promises\";\nimport * as path from \"path\";\nimport { Jimp } from \"jimp\";\n\n/**\n * Validation result for bitmap data\n */\nexport interface BitmapValidation {\n /** Whether the bitmap data is valid */\n isValid: boolean;\n /** Total byte count of the bitmap */\n byteCount: number;\n /** Number of black (non-FF) pixels found */\n blackPixels: number;\n /** Array of validation error messages */\n errors: string[];\n /** Additional metadata about the bitmap */\n metadata?: {\n /** Expected bitmap dimensions (if detectable) */\n dimensions?: { width: number; height: number };\n /** Bitmap file format info */\n format?: string;\n };\n}\n\n/**\n * Options for loading bitmap frames\n */\nexport interface LoadFramesOptions {\n /** File name pattern (default: 'animation_10_frame_{i}.bmp') */\n filePattern?: string;\n /** Starting frame number (default: 1) */\n startFrame?: number;\n /** Validate each frame during loading (default: true) */\n validateFrames?: boolean;\n /** Continue loading if a frame is missing (default: false) */\n skipMissingFrames?: boolean;\n}\n\n/**\n * Utility class for working with bitmap images in MentraOS applications\n */\nexport class BitmapUtils {\n static async convert24BitTo1BitBMP(input24BitBmp: Buffer): Promise<Buffer> {\n // Read header information from 24-bit BMP\n const width = input24BitBmp.readUInt32LE(18);\n const height = Math.abs(input24BitBmp.readInt32LE(22)); // Height can be negative (top-down BMP)\n const isTopDown = input24BitBmp.readInt32LE(22) < 0;\n const bitsPerPixel = input24BitBmp.readUInt16LE(28);\n\n if (bitsPerPixel !== 24) {\n throw new Error(\"Input must be a 24-bit BMP\");\n }\n\n // Calculate row sizes (both must be 4-byte aligned)\n const rowSize24 = Math.ceil((width * 3) / 4) * 4;\n const rowSize1 = Math.ceil(width / 32) * 4; // 32 pixels per 4 bytes\n\n // Calculate sizes for 1-bit BMP\n const colorTableSize = 8; // 2 colors * 4 bytes each\n const headerSize = 54 + colorTableSize;\n const pixelDataSize = rowSize1 * height;\n const fileSize = headerSize + pixelDataSize;\n\n // Create new buffer for 1-bit BMP\n const output1BitBmp = Buffer.alloc(fileSize);\n let offset = 0;\n\n // Write BMP file header (14 bytes)\n output1BitBmp.write(\"BM\", offset);\n offset += 2; // Signature\n output1BitBmp.writeUInt32LE(fileSize, offset);\n offset += 4; // File size\n output1BitBmp.writeUInt16LE(0, offset);\n offset += 2; // Reserved 1\n output1BitBmp.writeUInt16LE(0, offset);\n offset += 2; // Reserved 2\n output1BitBmp.writeUInt32LE(headerSize, offset);\n offset += 4; // Pixel data offset\n\n // Write DIB header (40 bytes)\n output1BitBmp.writeUInt32LE(40, offset);\n offset += 4; // DIB header size\n output1BitBmp.writeInt32LE(width, offset);\n offset += 4; // Width\n output1BitBmp.writeInt32LE(height, offset);\n offset += 4; // Height (positive for bottom-up)\n output1BitBmp.writeUInt16LE(1, offset);\n offset += 2; // Planes\n output1BitBmp.writeUInt16LE(1, offset);\n offset += 2; // Bits per pixel (1-bit)\n output1BitBmp.writeUInt32LE(0, offset);\n offset += 4; // Compression (none)\n output1BitBmp.writeUInt32LE(pixelDataSize, offset);\n offset += 4; // Image size\n output1BitBmp.writeInt32LE(2835, offset);\n offset += 4; // X pixels per meter (72 DPI)\n output1BitBmp.writeInt32LE(2835, offset);\n offset += 4; // Y pixels per meter (72 DPI)\n output1BitBmp.writeUInt32LE(2, offset);\n offset += 4; // Colors used\n output1BitBmp.writeUInt32LE(2, offset);\n offset += 4; // Important colors\n\n // Write color table (8 bytes)\n // Black (index 0): B=0, G=0, R=0, Reserved=0\n output1BitBmp.writeUInt32LE(0x00000000, offset);\n offset += 4;\n // White (index 1): B=255, G=255, R=255, Reserved=0\n output1BitBmp.writeUInt8(255, offset++); // Blue\n output1BitBmp.writeUInt8(255, offset++); // Green\n output1BitBmp.writeUInt8(255, offset++); // Red\n output1BitBmp.writeUInt8(0, offset++); // Reserved\n\n // Convert pixel data from 24-bit to 1-bit\n const pixelDataStart24 = 54; // 24-bit BMP has no color table\n\n for (let y = 0; y < height; y++) {\n // BMP files are usually stored bottom-up\n const sourceY = isTopDown ? y : height - 1 - y;\n const destY = height - 1 - y; // Always write bottom-up for compatibility\n\n // Initialize the row with zeros\n const rowData = Buffer.alloc(rowSize1);\n\n for (let x = 0; x < width; x++) {\n // Get pixel from 24-bit BMP\n const offset24 = pixelDataStart24 + sourceY * rowSize24 + x * 3;\n const blue = input24BitBmp[offset24];\n const green = input24BitBmp[offset24 + 1];\n const red = input24BitBmp[offset24 + 2];\n\n // Determine if pixel is white (assuming pure black or white)\n // White = 1, Black = 0\n const isWhite = red > 128 || green > 128 || blue > 128 ? 1 : 0;\n\n // Calculate bit position\n const byteIndex = Math.floor(x / 8);\n const bitPosition = 7 - (x % 8); // MSB first\n\n // Set bit if white\n if (isWhite) {\n rowData[byteIndex] |= 1 << bitPosition;\n }\n }\n\n // Write row to output buffer\n const destOffset = offset + destY * rowSize1;\n rowData.copy(output1BitBmp, destOffset);\n }\n\n return output1BitBmp;\n }\n\n /**\n * Load a BMP file as hex string from filesystem\n *\n * @param filePath - Path to the BMP file\n * @returns Promise resolving to hex-encoded bitmap data\n * @throws Error if file cannot be read or is not a valid BMP\n *\n * @example\n * ```typescript\n * const bmpBase64 = await BitmapUtils.loadBmpFromFileAsBase64('./assets/icon.bmp');\n * session.layouts.showBitmapView(bmpBase64);\n * ```\n */\n static async fileToBase64(filePath: string): Promise<string> {\n try {\n const bmpData = await fs.readFile(filePath);\n\n return this.bufferToBase64(bmpData);\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(\n `Failed to load BMP file ${filePath}: ${error.message}`,\n );\n }\n throw new Error(`Failed to load BMP file ${filePath}: Unknown error`);\n }\n }\n\n static async bufferToBase64(bmpData: Buffer): Promise<string> {\n return bmpData.toString(\"base64\");\n }\n\n static async padBase64Bitmap(\n bmpBase64: string,\n padding?: { left: number; top: number },\n ): Promise<string> {\n const buffer = Buffer.from(bmpBase64, \"base64\");\n const paddedBuffer = await this.padBmpForGlasses(\n buffer,\n padding?.left,\n padding?.top,\n );\n return paddedBuffer.toString(\"base64\");\n }\n\n static async padBmpForGlasses(\n bmpData: Buffer,\n leftPadding: number = 50,\n topPadding: number = 35,\n ): Promise<Buffer> {\n try {\n // Basic BMP validation - check for BMP signature\n if (bmpData.length < 14 || bmpData[0] !== 0x42 || bmpData[1] !== 0x4d) {\n throw new Error(\n `Bmp data is not a valid BMP file (missing BM signature)`,\n );\n }\n\n let finalBmpData = bmpData;\n\n // Load the image with Jimp\n const image = await Jimp.read(bmpData);\n\n // Check if we need to add padding\n if (image.width !== 576 || image.height !== 135) {\n console.log(\n `Adding padding to BMP since it isn't 576x135 (assuming it's 526x100!)(current: ${image.width}x${image.height})`,\n );\n\n // Create a new 576x135 white canvas\n const paddedImage = new Jimp({\n width: 576,\n height: 135,\n color: 0x00000000,\n });\n\n // // Calculate position to place the original image (with padding)\n const leftPadding = 50; // 45px padding on left\n const topPadding = 35; // 35px padding on top\n\n // Composite the original image onto the white canvas\n // paddedImage.composite(image, leftPadding, topPadding);\n paddedImage.composite(image, leftPadding, topPadding);\n\n finalBmpData = await this.convert24BitTo1BitBMP(\n await paddedImage.getBuffer(\"image/bmp\"),\n );\n }\n // No padding needed, just return as hex\n console.log(`finalBmpData: ${finalBmpData.length} bytes`);\n return finalBmpData;\n } catch (error) {\n if (error instanceof Error) {\n throw new Error(`Failed to load BMP data: ${error.message}`);\n }\n throw new Error(`Failed to load BMP data: Unknown error`);\n }\n }\n\n /**\n * Load multiple BMP frames as hex array for animations\n *\n * @param basePath - Directory containing the frame files\n * @param frameCount - Number of frames to load\n * @param options - Loading options and configuration\n * @returns Promise resolving to array of hex-encoded bitmap data\n *\n * @example\n * ```typescript\n * // Load 10 frames with default pattern\n * const frames = await BitmapUtils.loadBmpFrames('./animations', 10);\n *\n * // Load with custom pattern\n * const customFrames = await BitmapUtils.loadBmpFrames('./sprites', 8, {\n * filePattern: 'sprite_{i}.bmp',\n * startFrame: 0\n * });\n * ```\n */\n static async loadBmpFrames(\n basePath: string,\n frameCount: number,\n options: LoadFramesOptions = {},\n ): Promise<string[]> {\n const {\n filePattern = \"animation_10_frame_{i}.bmp\",\n startFrame = 1,\n validateFrames = true,\n skipMissingFrames = false,\n } = options;\n\n const frames: string[] = [];\n const errors: string[] = [];\n\n for (let i = 0; i < frameCount; i++) {\n const frameNumber = startFrame + i;\n const fileName = filePattern.replace(\"{i}\", frameNumber.toString());\n const filePath = path.join(basePath, fileName);\n\n try {\n const frameBase64 = await this.fileToBase64(filePath);\n\n if (validateFrames) {\n const validation = this.validateBase64Bitmap(frameBase64);\n if (!validation.isValid) {\n const errorMsg = `Frame ${frameNumber} validation failed: ${validation.errors.join(\n \", \",\n )}`;\n if (skipMissingFrames) {\n console.warn(`⚠️ ${errorMsg} - skipping`);\n continue;\n } else {\n throw new Error(errorMsg);\n }\n }\n console.log(\n `✅ Frame ${frameNumber} validated (${validation.blackPixels} black pixels)`,\n );\n }\n\n frames.push(frameBase64);\n } catch (error) {\n const errorMsg = `Failed to load frame ${frameNumber} (${fileName}): ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`;\n\n if (skipMissingFrames) {\n console.warn(`⚠️ ${errorMsg} - skipping`);\n continue;\n } else {\n errors.push(errorMsg);\n }\n }\n }\n\n if (errors.length > 0) {\n throw new Error(`Failed to load frames:\\n${errors.join(\"\\n\")}`);\n }\n\n if (frames.length === 0) {\n throw new Error(`No valid frames loaded from ${basePath}`);\n }\n\n console.log(`📚 Loaded ${frames.length} animation frames from ${basePath}`);\n return frames;\n }\n\n /**\n * Validate BMP hex data integrity and extract metadata\n *\n * @param hexString - Hex-encoded bitmap data\n * @returns Validation result with detailed information\n *\n * @example\n * ```typescript\n * const validation = BitmapUtils.validateBmpHex(bmpHex);\n * if (!validation.isValid) {\n * console.error('Invalid bitmap:', validation.errors);\n * } else {\n * console.log(`Valid bitmap: ${validation.blackPixels} black pixels`);\n * }\n * ```\n */\n static validateBase64Bitmap(bmpFrame: string): BitmapValidation {\n const errors: string[] = [];\n let byteCount = 0;\n let blackPixels = 0;\n const metadata: BitmapValidation[\"metadata\"] = {};\n\n try {\n const hexString = Buffer.from(bmpFrame, \"base64\").toString(\"hex\");\n // Basic hex validation\n if (typeof hexString !== \"string\" || hexString.length === 0) {\n errors.push(\"Hex string is empty or invalid\");\n return { isValid: false, byteCount: 0, blackPixels: 0, errors };\n }\n\n if (hexString.length % 2 !== 0) {\n errors.push(\"Hex string length must be even\");\n return { isValid: false, byteCount: 0, blackPixels: 0, errors };\n }\n\n // Convert to buffer\n const buffer = Buffer.from(hexString, \"hex\");\n byteCount = buffer.length;\n\n // BMP signature validation\n if (buffer.length < 14) {\n errors.push(\n \"File too small to be a valid BMP (minimum 14 bytes for header)\",\n );\n } else {\n if (buffer[0] !== 0x42 || buffer[1] !== 0x4d) {\n errors.push('Invalid BMP signature (should start with \"BM\")');\n }\n }\n\n // Size validation for MentraOS (576x135 = ~9782 bytes expected)\n const expectedSize = 9782;\n if (buffer.length < expectedSize - 100) {\n // Allow some tolerance\n errors.push(\n `BMP too small (${buffer.length} bytes, expected ~${expectedSize})`,\n );\n } else if (buffer.length > expectedSize + 1000) {\n // Allow some tolerance\n errors.push(\n `BMP too large (${buffer.length} bytes, expected ~${expectedSize})`,\n );\n }\n\n // Extract BMP metadata if header is valid\n if (buffer.length >= 54) {\n try {\n // BMP width and height are at offsets 18 and 22 (little-endian)\n const width = buffer.readUInt32LE(18);\n const height = buffer.readUInt32LE(22);\n metadata.dimensions = { width, height };\n metadata.format = \"BMP\";\n\n // Validate dimensions for MentraOS glasses\n if (width !== 576 || height !== 135) {\n errors.push(\n `Invalid dimensions (${width}x${height}, expected 576x135 for MentraOS)`,\n );\n }\n } catch (e) {\n errors.push(\"Failed to parse BMP header metadata\");\n }\n }\n\n // Pixel data validation (assumes 54-byte header + pixel data)\n if (buffer.length > 62) {\n const pixelData = buffer.slice(62); // Skip BMP header\n blackPixels = Array.from(pixelData).filter((b) => b !== 0xff).length;\n\n if (blackPixels === 0) {\n errors.push(\"No black pixels found (image appears to be all white)\");\n }\n } else {\n errors.push(\"File too small to contain pixel data\");\n }\n } catch (error) {\n errors.push(\n `Failed to parse hex data: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n );\n }\n\n return {\n isValid: errors.length === 0,\n byteCount,\n blackPixels,\n errors,\n metadata: Object.keys(metadata).length > 0 ? metadata : undefined,\n };\n }\n\n /**\n * Convert bitmap data between different formats\n *\n * @param data - Input bitmap data\n * @param fromFormat - Source format ('hex' | 'base64' | 'buffer')\n * @param toFormat - Target format ('hex' | 'base64' | 'buffer')\n * @returns Converted bitmap data\n *\n * @example\n * ```typescript\n * const base64Data = BitmapUtils.convertFormat(hexData, 'hex', 'base64');\n * const bufferData = BitmapUtils.convertFormat(base64Data, 'base64', 'buffer');\n * ```\n */\n static convertFormat(\n data: string | Buffer,\n fromFormat: \"hex\" | \"base64\" | \"buffer\",\n toFormat: \"hex\" | \"base64\" | \"buffer\",\n ): string | Buffer {\n let buffer: Buffer;\n\n // Convert input to buffer\n switch (fromFormat) {\n case \"hex\":\n buffer = Buffer.from(data as string, \"hex\");\n break;\n case \"base64\":\n buffer = Buffer.from(data as string, \"base64\");\n break;\n case \"buffer\":\n buffer = data as Buffer;\n break;\n default:\n throw new Error(`Unsupported source format: ${fromFormat}`);\n }\n\n // Convert buffer to target format\n switch (toFormat) {\n case \"hex\":\n return buffer.toString(\"hex\");\n case \"base64\":\n return buffer.toString(\"base64\");\n case \"buffer\":\n return buffer;\n default:\n throw new Error(`Unsupported target format: ${toFormat}`);\n }\n }\n\n /**\n * Get bitmap information without full validation\n *\n * @param hexString - Hex-encoded bitmap data\n * @returns Basic bitmap information\n *\n * @example\n * ```typescript\n * const info = BitmapUtils.getBitmapInfo(bmpHex);\n * console.log(`Bitmap: ${info.width}x${info.height}, ${info.blackPixels} black pixels`);\n * ```\n */\n static getBitmapInfo(hexString: string): {\n byteCount: number;\n blackPixels: number;\n width?: number;\n height?: number;\n isValidBmp: boolean;\n } {\n try {\n const buffer = Buffer.from(hexString, \"hex\");\n const isValidBmp =\n buffer.length >= 14 && buffer[0] === 0x42 && buffer[1] === 0x4d;\n\n let width: number | undefined;\n let height: number | undefined;\n\n if (isValidBmp && buffer.length >= 54) {\n try {\n width = buffer.readUInt32LE(18);\n height = buffer.readUInt32LE(22);\n } catch (e) {\n // Ignore metadata parsing errors\n }\n }\n\n const pixelData = buffer.slice(62);\n const blackPixels = Array.from(pixelData).filter(\n (b) => b !== 0xff,\n ).length;\n\n return {\n byteCount: buffer.length,\n blackPixels,\n width,\n height,\n isValidBmp,\n };\n } catch (error) {\n return {\n byteCount: 0,\n blackPixels: 0,\n isValidBmp: false,\n };\n }\n }\n}\n",
|
|
47
47
|
"/**\n * 🎬 Animation Utilities Module\n *\n * Provides helper functions for creating and managing bitmap animations in MentraOS applications.\n * Includes timing utilities, animation factories, and performance optimization helpers.\n *\n * @example\n * ```typescript\n * import { AnimationUtils } from '@mentra/sdk';\n *\n * // Create animation from files\n * const animation = await AnimationUtils.createBitmapAnimation(\n * session, './frames', 10, 1750, true\n * );\n *\n * // Simple delay utility\n * await AnimationUtils.delay(2000);\n *\n * // Stop animation\n * animation.stop();\n * ```\n */\n\nimport { AppSession } from \"../app/session\";\nimport { BitmapUtils, LoadFramesOptions } from \"./bitmap-utils\";\n\n/**\n * Configuration options for bitmap animations\n */\nexport interface AnimationConfig {\n /** Time between frames in milliseconds (default: 1750ms - optimized for MentraOS) */\n intervalMs?: number;\n /** Whether to loop the animation continuously (default: false) */\n repeat?: boolean;\n /** Validate frames before starting animation (default: true) */\n validateFrames?: boolean;\n /** Options for loading frames from files */\n loadOptions?: LoadFramesOptions;\n /** Callback fired when animation starts */\n onStart?: () => void;\n /** Callback fired when animation stops/completes */\n onStop?: () => void;\n /** Callback fired on each frame display */\n onFrame?: (frameIndex: number, totalFrames: number) => void;\n /** Callback fired if animation encounters an error */\n onError?: (error: string) => void;\n}\n\n/**\n * Animation controller interface\n */\nexport interface AnimationController {\n /** Stop the animation */\n stop: () => void;\n /** Check if animation is currently running */\n isRunning: () => boolean;\n /** Get current frame index */\n getCurrentFrame: () => number;\n /** Get total frame count */\n getTotalFrames: () => number;\n}\n\n/**\n * Performance timing information\n */\nexport interface TimingInfo {\n /** Target interval between frames */\n targetInterval: number;\n /** Actual measured interval between frames */\n actualInterval: number;\n /** Timing drift (difference between target and actual) */\n drift: number;\n /** Frame rate (frames per second) */\n fps: number;\n}\n\n/**\n * Utility class for creating and managing animations in MentraOS applications\n */\nexport class AnimationUtils {\n /**\n * Simple async delay helper\n *\n * @param ms - Milliseconds to delay\n * @returns Promise that resolves after the specified delay\n *\n * @example\n * ```typescript\n * console.log('Starting...');\n * await AnimationUtils.delay(2000);\n * console.log('2 seconds later!');\n * ```\n */\n static delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n /**\n * Create bitmap animation from files with advanced configuration\n *\n * @param session - MentraOS app session\n * @param basePath - Directory containing animation frames\n * @param frameCount - Number of frames to load\n * @param config - Animation configuration options\n * @returns Promise resolving to animation controller\n *\n * @example\n * ```typescript\n * // Simple animation\n * const animation = await AnimationUtils.createBitmapAnimation(\n * session, './animations', 10\n * );\n *\n * // Advanced configuration\n * const advancedAnimation = await AnimationUtils.createBitmapAnimation(\n * session, './sprites', 8, {\n * intervalMs: 1000,\n * repeat: true,\n * loadOptions: { filePattern: 'sprite_{i}.bmp', startFrame: 0 },\n * onFrame: (frame, total) => console.log(`Frame ${frame}/${total}`),\n * onError: (error) => console.error('Animation error:', error)\n * }\n * );\n * ```\n */\n static async createBitmapAnimation(\n session: AppSession,\n basePath: string,\n frameCount: number,\n config: AnimationConfig = {},\n ): Promise<AnimationController> {\n const {\n intervalMs = 1750, // Optimized for MentraOS hardware\n repeat = false,\n validateFrames = true,\n loadOptions = {},\n onStart,\n onStop,\n onFrame,\n onError,\n } = config;\n\n try {\n console.log(\n `🎬 Loading ${frameCount} animation frames from ${basePath}...`,\n );\n\n // Load frames with validation\n const frames = await BitmapUtils.loadBmpFrames(basePath, frameCount, {\n validateFrames,\n ...loadOptions,\n });\n\n if (frames.length === 0) {\n throw new Error(\"No frames loaded for animation\");\n }\n\n console.log(\n `📚 Animation ready: ${frames.length} frames at ${intervalMs}ms intervals`,\n );\n\n // Create enhanced animation with the loaded frames\n return this.createBitmapAnimationFromFrames(session, frames, {\n intervalMs,\n repeat,\n onStart,\n onStop,\n onFrame,\n onError,\n });\n } catch (error) {\n const errorMsg = `Failed to create animation: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n console.error(`❌ ${errorMsg}`);\n if (onError) {\n onError(errorMsg);\n }\n throw new Error(errorMsg);\n }\n }\n\n /**\n * Create bitmap animation from pre-loaded frame data\n *\n * @param session - MentraOS app session\n * @param frames - Array of hex-encoded bitmap data\n * @param config - Animation configuration options\n * @returns Animation controller\n *\n * @example\n * ```typescript\n * const frames = ['424d461a...', '424d461b...', '424d461c...'];\n * const animation = AnimationUtils.createBitmapAnimationFromFrames(\n * session, frames, { intervalMs: 1500, repeat: true }\n * );\n * ```\n */\n static createBitmapAnimationFromFrames(\n session: AppSession,\n frames: string[],\n config: Omit<AnimationConfig, \"loadOptions\" | \"validateFrames\"> = {},\n ): AnimationController {\n const {\n intervalMs = 1750,\n repeat = false,\n onStart,\n onStop,\n onFrame,\n onError,\n } = config;\n\n let isRunning = false;\n const currentFrame = 0;\n let animationController: { stop: () => void } | null = null;\n\n const controller: AnimationController = {\n stop: () => {\n if (animationController) {\n animationController.stop();\n animationController = null;\n }\n isRunning = false;\n if (onStop) {\n onStop();\n }\n console.log(\"🛑 Animation stopped\");\n },\n\n isRunning: () => isRunning,\n\n getCurrentFrame: () => currentFrame,\n\n getTotalFrames: () => frames.length,\n };\n\n try {\n // Start the animation using the session's built-in method\n animationController = session.layouts.showBitmapAnimation(\n frames,\n intervalMs,\n repeat,\n );\n isRunning = true;\n\n if (onStart) {\n onStart();\n }\n\n console.log(\n `🎬 Animation started: ${frames.length} frames at ${intervalMs}ms${repeat ? \" (repeating)\" : \"\"}`,\n );\n\n // If we have frame callbacks, we need to track timing manually\n // This is a limitation of the current SDK - we can't hook into individual frame displays\n if (onFrame) {\n let frameTracker = 0;\n\n // Call onFrame for the first frame immediately\n onFrame(frameTracker, frames.length);\n\n const frameInterval = setInterval(() => {\n if (!isRunning) {\n clearInterval(frameInterval);\n return;\n }\n\n frameTracker = (frameTracker + 1) % frames.length;\n onFrame(frameTracker, frames.length);\n\n // If not repeating and we've shown all frames, stop tracking\n if (!repeat && frameTracker === frames.length - 1) {\n clearInterval(frameInterval);\n }\n }, intervalMs);\n\n // Override stop to also clear frame tracking\n const originalStop = controller.stop;\n controller.stop = () => {\n clearInterval(frameInterval);\n originalStop();\n };\n }\n } catch (error) {\n const errorMsg = `Failed to start animation: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n console.error(`❌ ${errorMsg}`);\n if (onError) {\n onError(errorMsg);\n }\n throw new Error(errorMsg);\n }\n\n return controller;\n }\n\n /**\n * Create a sequence of bitmap displays with custom timing\n *\n * @param session - MentraOS app session\n * @param sequence - Array of frame data with individual timing\n * @returns Promise that resolves when sequence completes\n *\n * @example\n * ```typescript\n * await AnimationUtils.createBitmapSequence(session, [\n * { frame: frame1Hex, duration: 1000 },\n * { frame: frame2Hex, duration: 500 },\n * { frame: frame3Hex, duration: 2000 }\n * ]);\n * ```\n */\n static async createBitmapSequence(\n session: AppSession,\n sequence: Array<{ frame: string; duration: number }>,\n ): Promise<void> {\n console.log(\n `🎭 Starting bitmap sequence: ${sequence.length} frames with custom timing`,\n );\n\n for (let i = 0; i < sequence.length; i++) {\n const { frame, duration } = sequence[i];\n\n try {\n console.log(\n `📽️ Sequence frame ${i + 1}/${sequence.length} (${duration}ms)`,\n );\n session.layouts.showBitmapView(frame);\n\n if (i < sequence.length - 1) {\n // Don't delay after the last frame\n await this.delay(duration);\n }\n } catch (error) {\n console.error(`❌ Error in sequence frame ${i + 1}:`, error);\n throw error;\n }\n }\n\n console.log(\"✅ Bitmap sequence completed\");\n }\n\n /**\n * Measure animation timing performance\n *\n * @param targetInterval - Expected interval between frames in ms\n * @param measureDuration - How long to measure in ms (default: 10 seconds)\n * @returns Promise resolving to timing performance data\n *\n * @example\n * ```typescript\n * const timing = await AnimationUtils.measureTiming(1750, 10000);\n * console.log(`Target: ${timing.targetInterval}ms, Actual: ${timing.actualInterval}ms`);\n * console.log(`Drift: ${timing.drift}ms, FPS: ${timing.fps.toFixed(1)}`);\n * ```\n */\n static async measureTiming(\n targetInterval: number,\n measureDuration: number = 10000,\n ): Promise<TimingInfo> {\n return new Promise((resolve) => {\n const timestamps: number[] = [];\n const startTime = Date.now();\n\n const measureInterval = setInterval(() => {\n timestamps.push(Date.now());\n }, targetInterval);\n\n setTimeout(() => {\n clearInterval(measureInterval);\n\n if (timestamps.length < 2) {\n resolve({\n targetInterval,\n actualInterval: targetInterval,\n drift: 0,\n fps: 1000 / targetInterval,\n });\n return;\n }\n\n // Calculate actual interval\n const intervals = [];\n for (let i = 1; i < timestamps.length; i++) {\n intervals.push(timestamps[i] - timestamps[i - 1]);\n }\n\n const actualInterval =\n intervals.reduce((a, b) => a + b, 0) / intervals.length;\n const drift = actualInterval - targetInterval;\n const fps = 1000 / actualInterval;\n\n resolve({\n targetInterval,\n actualInterval,\n drift,\n fps,\n });\n }, measureDuration);\n });\n }\n\n /**\n * Create optimized animation settings for different hardware\n *\n * @param deviceType - Target device type\n * @returns Recommended animation configuration\n *\n * @example\n * ```typescript\n * const config = AnimationUtils.getOptimizedConfig('even-realities-g1');\n * const animation = await AnimationUtils.createBitmapAnimation(\n * session, './frames', 10, config\n * );\n * ```\n */\n static getOptimizedConfig(\n deviceType: \"even-realities-g1\" | \"generic\",\n ): AnimationConfig {\n switch (deviceType) {\n case \"even-realities-g1\":\n return {\n intervalMs: 1650, // Tested optimal timing for Even Realities G1\n repeat: false,\n validateFrames: true,\n loadOptions: {\n validateFrames: true,\n skipMissingFrames: false,\n },\n };\n\n case \"generic\":\n default:\n return {\n intervalMs: 1000,\n repeat: false,\n validateFrames: true,\n loadOptions: {\n validateFrames: true,\n skipMissingFrames: false,\n },\n };\n }\n }\n\n /**\n * Preload and cache animation frames for better performance\n *\n * @param basePath - Directory containing frames\n * @param frameCount - Number of frames to preload\n * @param options - Loading options\n * @returns Promise resolving to cached frame data\n *\n * @example\n * ```typescript\n * // Preload frames\n * const cachedFrames = await AnimationUtils.preloadFrames('./animations', 10);\n *\n * // Use cached frames multiple times\n * const animation1 = AnimationUtils.createBitmapAnimationFromFrames(session, cachedFrames);\n * const animation2 = AnimationUtils.createBitmapAnimationFromFrames(session, cachedFrames);\n * ```\n */\n static async preloadFrames(\n basePath: string,\n frameCount: number,\n options: LoadFramesOptions = {},\n ): Promise<string[]> {\n console.log(`📦 Preloading ${frameCount} frames from ${basePath}...`);\n\n const frames = await BitmapUtils.loadBmpFrames(basePath, frameCount, {\n validateFrames: true,\n ...options,\n });\n\n console.log(\n `✅ Preloaded ${frames.length} frames (${frames.reduce((total: number, frame: string) => total + frame.length, 0)} total characters)`,\n );\n\n return frames;\n }\n}\n",
|
|
48
|
-
"/**\n * App Server Module\n *\n * Creates and manages a server for Apps in the MentraOS ecosystem.\n * Handles webhook endpoints, session management, and cleanup.\n *\n * Now built on Hono + Bun for better performance and developer experience.\n */\nimport fs from \"fs\";\nimport path from \"path\";\n\nimport { Hono } from \"hono\";\nimport type { Context, MiddlewareHandler } from \"hono\";\nimport { serveStatic } from \"hono/bun\";\nimport { Logger } from \"pino\";\n\nimport { getDistTag } from \"../../constants/log-messages/updates\";\nimport { createLogger } from \"../../logging/logger\";\nimport {\n WebhookRequest,\n WebhookResponse,\n SessionWebhookRequest,\n StopWebhookRequest,\n ToolCall,\n WebhookRequestType,\n AuthVariables,\n} from \"../../types\";\n\nimport { AppSession } from \"../session/index\";\nimport { createAuthMiddleware, createMentraAuthRoutes } from \"../webview\";\n\n// Import PhotoData type for pending photo requests\nimport type { PhotoData } from \"../../types/photo-data\";\n\nexport const GIVE_APP_CONTROL_OF_TOOL_RESPONSE: string = \"GIVE_APP_CONTROL_OF_TOOL_RESPONSE\";\nconst SDK_ROUTE_PREFIX = \"/api/_mentraos\";\nconst LEGACY_MENTRA_AUTH_ROUTE_PREFIX = \"/api/mentra/auth\";\n\n/**\n * Pending photo request stored at AppServer level for reconnection resilience.\n * This allows O(1) lookup when photo uploads arrive via HTTP,\n * and survives session reconnections.\n * See: cloud/issues/019-sdk-photo-request-architecture\n */\ninterface PendingPhotoRequest {\n userId: string;\n sessionId: string;\n session: AppSession;\n resolve: (photo: PhotoData) => void;\n reject: (error: Error) => void;\n timestamp: number;\n timeoutId?: ReturnType<typeof setTimeout>;\n}\n\n/**\n * 🔧 Configuration options for App Server\n *\n * @example\n * ```typescript\n * const config: AppServerConfig = {\n * packageName: 'org.example.myapp',\n * apiKey: 'your_api_key',\n * port: 7010,\n * publicDir: './public'\n * };\n * ```\n */\nexport interface AppServerConfig {\n /** 📦 Unique identifier for your App (e.g., 'org.company.appname') must match what you specified at https://console.mentra.glass */\n packageName: string;\n /** 🔑 API key for authentication with MentraOS Cloud */\n apiKey: string;\n /** 🌐 Port number for the server (default: 7010) */\n port?: number;\n\n /** Cloud API URL (default: 'api.mentra.glass') */\n cloudApiUrl?: string;\n\n /** 🛣️ [DEPRECATED] do not set: The SDK will automatically expose an endpoint at '/webhook' */\n webhookPath?: string;\n /**\n * 📂 Directory for serving static files (e.g., images, logos)\n * Set to false to disable static file serving\n */\n publicDir?: string | false;\n\n /** ❤️ Enable health check endpoint at /health (default: true) */\n healthCheck?: boolean;\n /**\n * 🔐 Secret key used to sign session cookies\n * This must be a strong, unique secret\n */\n cookieSecret?: string;\n /** App instructions string shown to the user */\n appInstructions?: string;\n\n /**\n * Enable verbose SDK logging. Shows all internal SDK messages in the terminal\n * (WebSocket lifecycle, subscription updates, message routing, etc.).\n * Useful for debugging connection and streaming issues.\n *\n * Can also be enabled with the MENTRA_VERBOSE=true environment variable.\n * This config option takes priority over the env var.\n */\n verbose?: boolean;\n\n /**\n * SDK log level. Controls which log messages appear in the terminal.\n * - 'error': Only errors\n * - 'warn': Errors and warnings\n * - 'info': Normal operation (default)\n * - 'debug': Everything including SDK internals (implies verbose)\n *\n * Can also be set with the MENTRA_LOG_LEVEL environment variable.\n * This config option takes priority over the env var.\n */\n logLevel?: \"error\" | \"warn\" | \"info\" | \"debug\";\n}\n\n// Type for Hono app with auth variables\ntype AppHono = Hono<{ Variables: AuthVariables }>;\n\n/**\n * 🎯 App Server Implementation\n *\n * Base class for creating App servers, now extending Hono for a modern API.\n * Handles:\n * - 🔄 Session lifecycle management\n * - 📡 Webhook endpoints for MentraOS Cloud\n * - 📂 Static file serving\n * - ❤️ Health checks\n * - 🧹 Cleanup on shutdown\n *\n * @example\n * ```typescript\n * class MyAppServer extends AppServer {\n * constructor(config: AppServerConfig) {\n * super(config)\n *\n * // Add custom API routes (Hono syntax)\n * this.get(\"/api/custom\", (c) => c.json({ message: \"Hello!\" }))\n * }\n *\n * protected async onSession(session: AppSession, sessionId: string, userId: string) {\n * // Handle new user sessions here\n * session.events.onTranscription((data) => {\n * session.layouts.showTextWall(data.text);\n * });\n * }\n * }\n *\n * const server = new MyAppServer({\n * packageName: 'org.example.myapp',\n * apiKey: 'your_api_key',\n * });\n *\n * await server.start();\n * ```\n */\nexport class AppServer extends Hono<{ Variables: AuthVariables }> {\n /** Server configuration */\n protected config: AppServerConfig;\n /** Map of active user sessions by sessionId */\n private activeSessions = new Map<string, AppSession>();\n /** Map of active user sessions by userId */\n private activeSessionsByUserId = new Map<string, AppSession>();\n /** Guards against running cleanup twice (double Ctrl-C, SIGINT+SIGTERM, etc.) */\n private _cleanupPromise: Promise<void> | null = null;\n /**\n * Pending photo requests by requestId - owned by AppServer for HTTP endpoint access.\n * This is the single source of truth for pending photo requests.\n * Stored here (not on CameraModule) because:\n * 1. Photo uploads arrive via HTTP to AppServer, not via WebSocket to session\n * 2. Allows O(1) lookup by requestId instead of iterating all sessions\n * 3. Survives session reconnections (session may be removed from activeSessions temporarily)\n * See: cloud/issues/019-sdk-photo-request-architecture\n */\n private pendingPhotoRequests = new Map<string, PendingPhotoRequest>();\n /** Array of cleanup handlers to run on shutdown */\n private cleanupHandlers: Array<() => void> = [];\n /** App instructions string shown to the user */\n private appInstructions: string | null = null;\n\n public readonly logger: Logger;\n\n constructor(config: AppServerConfig) {\n super(); // Initialize Hono\n\n // Set defaults and merge with provided config\n this.config = {\n port: 7010,\n webhookPath: \"/webhook\",\n publicDir: false,\n healthCheck: true,\n ...config,\n };\n\n // Apply config-level log settings to environment before logger creation.\n // Config takes priority over env vars.\n if (config.verbose !== undefined) {\n process.env.MENTRA_VERBOSE = config.verbose ? \"true\" : \"false\";\n }\n if (config.logLevel !== undefined) {\n process.env.MENTRA_LOG_LEVEL = config.logLevel;\n }\n\n this.logger = createLogger({\n verbose: config.verbose,\n logLevel: config.logLevel as any,\n }).child({\n app: this.config.packageName,\n packageName: this.config.packageName,\n service: \"app-server\",\n });\n\n // Apply authentication middleware\n this.use(\n \"*\",\n createAuthMiddleware({\n apiKey: this.config.apiKey,\n packageName: this.config.packageName,\n getAppSessionForUser: (userId: string) => {\n return this.activeSessionsByUserId.get(userId) || null;\n },\n cookieSecret: this.config.cookieSecret || this.config.apiKey, // Default to apiKey for simplicity\n }),\n );\n\n this.appInstructions = (config as any).appInstructions || null;\n\n // Setup server features\n this.setupWebhook();\n this.setupSettingsEndpoint();\n this.setupHealthCheck();\n this.setupToolCallEndpoint();\n this.setupPhotoUploadEndpoint();\n this.setupMentraWebviewAuth();\n this.setupMentraAuthRedirect();\n this.setupPublicDir();\n this.setupShutdown();\n }\n\n /**\n * @deprecated Use `this.get()`, `this.post()`, etc. directly since AppServer now extends Hono\n * This method is kept for backward compatibility during migration.\n */\n public getExpressApp(): AppHono {\n console.warn(\n \"DEPRECATION: getExpressApp() is deprecated. AppServer now extends Hono - use this.get(), this.post(), etc. directly.\",\n );\n return this as AppHono;\n }\n\n /**\n * Get the Hono app instance (returns this since AppServer extends Hono)\n */\n public getHonoApp(): AppHono {\n return this as AppHono;\n }\n\n /**\n * 👥 Session Handler\n * Override this method to handle new App sessions.\n * This is where you implement your app's core functionality.\n *\n * @param session - App session instance for the user\n * @param sessionId - Unique identifier for this session\n * @param userId - User's identifier\n */\n protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {\n this.logger.debug({ sessionId, userId }, \"Session handler started\");\n }\n\n /**\n * 👥 Stop Handler\n * Override this method to handle stop requests.\n * This is where you can clean up resources when a session is stopped.\n *\n * @param sessionId - Unique identifier for this session\n * @param userId - User's identifier\n * @param reason - Reason for stopping\n */\n protected async onStop(sessionId: string, userId: string, reason: string): Promise<void> {\n this.logger.debug(`Session ${sessionId} stopped for user ${userId}. Reason: ${reason}`);\n\n // Default implementation: close the session if it exists\n const session = this.activeSessions.get(sessionId);\n if (session) {\n session.disconnect();\n this.activeSessions.delete(sessionId);\n this.activeSessionsByUserId.delete(userId);\n }\n }\n\n /**\n * 🛠️ Tool Call Handler\n * Override this method to handle tool calls from MentraOS Cloud.\n * This is where you implement your app's tool functionality.\n *\n * @param toolCall - The tool call request containing tool details and parameters\n * @returns Optional string response that will be sent back to MentraOS Cloud\n */\n protected async onToolCall(toolCall: ToolCall): Promise<string | undefined> {\n this.logger.debug(`Tool call received: ${toolCall.toolId}`);\n this.logger.debug(`Parameters: ${JSON.stringify(toolCall.toolParameters)}`);\n return undefined;\n }\n\n protected getActiveSessionById(sessionId: string): AppSession | null {\n return this.activeSessions.get(sessionId) || null;\n }\n\n protected getActiveSessionForUser(userId: string): AppSession | null {\n return this.activeSessionsByUserId.get(userId) || null;\n }\n\n protected setActiveSession(sessionId: string, userId: string, session: AppSession): void {\n this.activeSessions.set(sessionId, session);\n this.activeSessionsByUserId.set(userId, session);\n }\n\n protected removeActiveSession(sessionId: string, userId: string): void {\n this.activeSessions.delete(sessionId);\n this.activeSessionsByUserId.delete(userId);\n }\n\n /**\n * 🚀 Initialize the App\n * Sets up logging and checks SDK version.\n * After calling this, use Bun.serve() with app.fetch to start the server.\n *\n * @example\n * ```typescript\n * const app = new MyAppServer({ ... })\n * await app.start()\n *\n * Bun.serve({\n * port: 3333,\n * routes: { \"/*\": indexHtml },\n * fetch: app.fetch,\n * })\n * ```\n *\n * @returns Promise that resolves when initialization is complete\n */\n public async start(): Promise<void> {\n this.logger.info(`App server running on port ${this.config.port}`);\n\n // Check for SDK updates (non-blocking)\n await this.checkSDKVersion();\n }\n\n /**\n * Check and log SDK version (dist-tag aware).\n * Hits npm registry directly — no dependency on our backend.\n */\n private async checkSDKVersion(): Promise<void> {\n try {\n const sdkPkgPath = path.resolve(process.cwd(), \"node_modules/@mentra/sdk/package.json\");\n\n let currentVersion = \"unknown\";\n\n if (fs.existsSync(sdkPkgPath)) {\n const sdkPkg = JSON.parse(fs.readFileSync(sdkPkgPath, \"utf-8\"));\n currentVersion = sdkPkg.version || \"not-found\";\n } else {\n this.logger.debug({ sdkPkgPath }, \"No @mentra/sdk package.json found at path\");\n }\n\n // Determine which dist-tag (release track) the dev is on\n const distTag = getDistTag(currentVersion);\n\n // Fetch latest version for this track directly from npm registry\n let latest: string | null = null;\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 3000);\n const response = await fetch(`https://registry.npmjs.org/@mentra/sdk/${distTag}`, {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n if (response.ok) {\n const data = (await response.json()) as { version: string };\n latest = data.version;\n }\n } catch {\n this.logger.debug(\"Failed to check npm for SDK updates — skipping (offline or timeout)\");\n }\n\n if (currentVersion === \"not-found\") {\n this.logger.warn(\n \"@mentra/sdk not found in your project dependencies. Install it with: bun install @mentra/sdk\",\n );\n } else if (latest && latest !== currentVersion) {\n this.logger.warn(`SDK update available: ${currentVersion} → ${latest} — bun install @mentra/sdk@${distTag}`);\n }\n } catch (err) {\n this.logger.debug(err, \"Version check failed\");\n }\n }\n\n /**\n * Stop the Server\n * Gracefully shuts down the server and cleans up all sessions.\n */\n public async stop(): Promise<void> {\n // Prevent double-cleanup from concurrent signals or multiple stop() calls\n if (this._cleanupPromise) return this._cleanupPromise;\n this.logger.info(\"Shutting down...\");\n this._cleanupPromise = this.cleanup();\n return this._cleanupPromise;\n }\n\n /**\n * 🔐 Generate a App token for a user\n * This should be called when handling a session webhook request.\n *\n * @param userId - User identifier\n * @param sessionId - Session identifier\n * @param secretKey - Secret key for signing the token\n * @returns JWT token string\n */\n protected generateToken(userId: string, sessionId: string, secretKey: string): string {\n const { createToken } = require(\"../token/utils\");\n return createToken(\n {\n userId,\n packageName: this.config.packageName,\n sessionId,\n },\n { secretKey },\n );\n }\n\n /**\n * Add Cleanup Handler\n * Register a function to be called during server shutdown.\n *\n * @param handler - Function to call during cleanup\n */\n protected addCleanupHandler(handler: () => void): void {\n this.cleanupHandlers.push(handler);\n }\n\n // =====================================\n // 📸 Photo Request Management APIs\n // =====================================\n\n /**\n * Register a pending photo request.\n * Called by CameraModule when a photo is requested.\n * Stores the request at AppServer level for O(1) lookup when HTTP response arrives.\n *\n * @param requestId - Unique identifier for this photo request\n * @param request - Request details including session, resolve/reject callbacks\n */\n registerPhotoRequest(requestId: string, request: Omit<PendingPhotoRequest, \"timeoutId\">): void {\n // Set timeout at AppServer level (single source of truth)\n const timeoutMs = 30000; // 30 seconds\n const timeoutId = setTimeout(() => {\n const pending = this.pendingPhotoRequests.get(requestId);\n if (pending) {\n pending.reject(new Error(\"Photo request timed out\"));\n this.pendingPhotoRequests.delete(requestId);\n this.logger.warn({ requestId }, \"Photo request timed out\");\n }\n }, timeoutMs);\n\n this.pendingPhotoRequests.set(requestId, {\n ...request,\n timeoutId,\n });\n\n this.logger.debug({ requestId, userId: request.userId, sessionId: request.sessionId }, \"Photo request registered\");\n }\n\n /**\n * Get a pending photo request by ID.\n *\n * @param requestId - The request ID to look up\n * @returns The pending request, or undefined if not found\n */\n getPhotoRequest(requestId: string): PendingPhotoRequest | undefined {\n return this.pendingPhotoRequests.get(requestId);\n }\n\n /**\n * Complete a photo request (success or error).\n * Clears the timeout and removes from the pending map.\n *\n * @param requestId - The request ID to complete\n * @returns The pending request that was completed, or undefined if not found\n */\n completePhotoRequest(requestId: string): PendingPhotoRequest | undefined {\n const pending = this.pendingPhotoRequests.get(requestId);\n if (pending) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n this.pendingPhotoRequests.delete(requestId);\n this.logger.debug({ requestId }, \"Photo request completed\");\n }\n return pending;\n }\n\n /**\n * Clean up all pending photo requests for a session.\n * Called when a session permanently disconnects.\n *\n * @param sessionId - The session ID to clean up requests for\n */\n cleanupPhotoRequestsForSession(sessionId: string): void {\n let cleanedCount = 0;\n for (const [requestId, pending] of this.pendingPhotoRequests) {\n if (pending.sessionId === sessionId) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.reject(new Error(\"Session ended\"));\n this.pendingPhotoRequests.delete(requestId);\n cleanedCount++;\n this.logger.debug({ requestId, sessionId }, \"Photo request cleaned up (session ended)\");\n }\n }\n if (cleanedCount > 0) {\n this.logger.debug({ sessionId, cleanedCount }, \"Cleaned up photo requests for ended session\");\n }\n }\n\n /**\n * Setup Webhook Endpoint\n * Creates the webhook endpoint that MentraOS Cloud calls to start new sessions.\n */\n private setupWebhook(): void {\n const webhookPaths = [this.config.webhookPath || \"/webhook\", `${SDK_ROUTE_PREFIX}/webhook`];\n\n const handler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n const webhookRequest = (await c.req.json()) as WebhookRequest;\n\n // Handle session request\n if (webhookRequest.type === WebhookRequestType.SESSION_REQUEST) {\n return this.handleSessionWebhookRequest(webhookRequest as SessionWebhookRequest, c);\n }\n // Handle stop request\n else if (webhookRequest.type === WebhookRequestType.STOP_REQUEST) {\n return this.handleStopWebhookRequest(webhookRequest as StopWebhookRequest, c);\n }\n // Unknown webhook type\n else {\n this.logger.error(\"Unknown webhook request type\");\n return c.json(\n {\n status: \"error\",\n message: \"Unknown webhook request type\",\n } as WebhookResponse,\n 400,\n );\n }\n } catch (error) {\n this.logger.error(error, \"Error handling webhook\");\n return c.json(\n {\n status: \"error\",\n message: \"Error handling webhook: \" + (error as Error).message,\n } as WebhookResponse,\n 500,\n );\n }\n };\n\n for (const path of webhookPaths) {\n this.post(path, handler);\n }\n }\n\n /**\n * Setup Tool Call Endpoint\n * Creates a /tool endpoint for handling tool calls from MentraOS Cloud.\n */\n private setupToolCallEndpoint(): void {\n const postHandler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n const toolCall = (await c.req.json()) as ToolCall;\n toolCall.activeSession = this.getActiveSessionForUser(toolCall.userId);\n this.logger.debug({ toolId: toolCall.toolId }, \"Tool call received\");\n\n // Call the onToolCall handler and get the response\n const response = await this.onToolCall(toolCall);\n\n // Send back the response if one was provided\n if (response !== undefined) {\n return c.json({ status: \"success\", reply: response });\n } else {\n return c.json({ status: \"success\", reply: null });\n }\n } catch (error) {\n this.logger.error(error, \"Error handling tool call\");\n return c.json(\n {\n status: \"error\",\n message: error instanceof Error ? error.message : \"Unknown error occurred calling tool\",\n },\n 500,\n );\n }\n };\n\n const getHandler = async (c: Context<{ Variables: AuthVariables }>) => {\n return c.json({ status: \"success\", reply: \"Hello, world!\" });\n };\n\n for (const path of [\"/tool\", `${SDK_ROUTE_PREFIX}/tool`]) {\n this.post(path, postHandler);\n this.get(path, getHandler);\n }\n }\n\n /**\n * Handle a session request webhook\n */\n protected async handleSessionWebhookRequest(\n request: SessionWebhookRequest,\n c: Context<{ Variables: AuthVariables }>,\n ): Promise<Response> {\n const { sessionId, userId, websocketUrl, mentraOSWebsocketUrl, augmentOSWebsocketUrl } = request;\n this.logger.debug({ userId, sessionId }, \"Session request received\");\n\n // Check for existing session (user might be switching clouds)\n // If an existing session exists, we need to clean it up properly to avoid:\n // 1. Orphaned sessions with open WebSockets\n // 2. Cleanup handlers that corrupt the new session's map entries\n // See: cloud/issues/018-app-disconnect-resurrection\n const existingSession = this.getActiveSessionById(sessionId);\n if (existingSession) {\n this.logger.debug({ sessionId, userId }, \"Existing session found — releasing ownership before reconnect\");\n\n try {\n // Send OWNERSHIP_RELEASE to tell the old cloud not to resurrect this app\n // The old cloud will mark the app as DORMANT instead of trying to restart it\n await existingSession.releaseOwnership(\"switching_clouds\");\n } catch (error) {\n this.logger.warn({ error, sessionId }, \"Failed to release ownership on old session — continuing\");\n }\n\n try {\n // Disconnect the old session explicitly\n existingSession.disconnect();\n } catch (error) {\n this.logger.warn({ error, sessionId }, \"Failed to disconnect old session — continuing\");\n }\n\n // Remove from maps immediately (don't wait for cleanup handler)\n this.removeActiveSession(sessionId, userId);\n\n this.logger.debug({ sessionId, userId }, \"Old session cleaned up, proceeding with new connection\");\n }\n\n // Create new App session\n const session = new AppSession({\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n mentraOSWebsocketUrl: websocketUrl || mentraOSWebsocketUrl || augmentOSWebsocketUrl,\n appServer: this,\n userId,\n });\n\n // Setup session event handlers\n const cleanupDisconnect = session.events.onDisconnected((info) => {\n // Determine if this is a permanent disconnect\n // Permanent disconnects happen when:\n // 1. User session ends (sessionEnded === true)\n // 2. Reconnection attempts exhausted (permanent === true)\n // 3. Clean WebSocket closure (1000/1001) - no reconnection will be attempted\n // Temporary disconnects (abnormal closures like 1006 that trigger reconnection) should NOT remove session from maps\n // See: cloud/issues/019-sdk-photo-request-architecture\n let isPermanent = false;\n let reason = \"unknown\";\n\n // Handle different disconnect info formats (string or object)\n if (typeof info === \"string\") {\n this.logger.debug({ sessionId }, `Session disconnected: ${info}`);\n reason = info;\n // String-only disconnects are typically temporary (e.g., \"WebSocket closed\")\n isPermanent = false;\n } else {\n this.logger.debug({ sessionId, code: info.code }, `Session disconnected: ${info.message}`);\n reason = info.reason || info.message;\n\n if (info.sessionEnded === true) {\n this.logger.debug({ sessionId }, \"User session ended, calling onStop\");\n isPermanent = true;\n\n this.onStop(sessionId, userId, \"User session ended\").catch((error) => {\n this.logger.error(error, \"Error in onStop handler for session end\");\n });\n }\n // Check if this is a permanent disconnection after exhausted reconnection attempts\n else if (info.permanent === true) {\n this.logger.debug({ sessionId }, \"Permanent disconnection, calling onStop\");\n isPermanent = true;\n\n this.onStop(sessionId, userId, `Connection permanently lost: ${info.reason}`).catch((error) => {\n this.logger.error(error, \"Error in onStop handler for permanent disconnection\");\n });\n }\n // Check if this is a clean WebSocket closure (1000/1001) that won't trigger reconnection\n // These are intentional disconnects (app shutdown, manual stop, etc.)\n // AppSession skips reconnection for these codes, so we must treat them as permanent\n // to avoid zombie sessions in activeSessions map\n else if (info.wasClean === true || info.code === 1000 || info.code === 1001) {\n this.logger.debug({ sessionId, code: info.code }, \"Clean WebSocket closure, treating as permanent\");\n isPermanent = true;\n\n // Call onStop for clean disconnects too\n this.onStop(sessionId, userId, `Clean disconnect: ${reason}`).catch((error) => {\n this.logger.error(error, \"Error in onStop handler for clean disconnect\");\n });\n }\n }\n\n // Only remove session and clean up photo requests on PERMANENT disconnects\n // Temporary disconnects should leave the session in place so:\n // 1. Photo uploads can still find the pending request\n // 2. The session can be reused after reconnection\n // See: cloud/issues/019-sdk-photo-request-architecture\n if (isPermanent) {\n // Remove the session from active sessions ONLY if this session is still the active one.\n // This prevents a bug where an old session's cleanup handler deletes a newer session:\n // 1. User switches from Cloud A to Cloud B\n // 2. SDK creates sessionB, overwrites activeSessions[sessionId]\n // 3. sessionA is orphaned but its cleanup handler still references sessionId\n // 4. When Cloud A disposes, sessionA's cleanup fires and would delete sessionB\n // By checking identity (===), we only delete if we're still the current session.\n // See: cloud/issues/018-app-disconnect-resurrection\n if (this.getActiveSessionById(sessionId) === session) {\n this.removeActiveSession(sessionId, userId);\n } else {\n this.logger.debug({ sessionId }, \"Session cleanup skipped — a newer session has taken over\");\n }\n\n // Clean up any pending photo requests for this session\n this.cleanupPhotoRequestsForSession(sessionId);\n } else {\n // Temporary disconnect - session stays in maps for reconnection\n // Photo requests remain pending and can still be fulfilled\n this.logger.debug({ sessionId, reason }, \"Temporary disconnect, keeping session for reconnection\");\n }\n });\n\n const cleanupError = session.events.onError((error) => {\n this.logger.error(error, \"Session error\");\n });\n\n // Start the session\n try {\n await session.connect(sessionId);\n this.setActiveSession(sessionId, userId, session);\n await this.onSession(session, sessionId, userId);\n return c.json({ status: \"success\" } as WebhookResponse);\n } catch (error) {\n this.logger.error(error, \"Failed to connect session\");\n cleanupDisconnect();\n cleanupError();\n return c.json(\n {\n status: \"error\",\n message: \"Failed to connect\",\n } as WebhookResponse,\n 500,\n );\n }\n }\n\n /**\n * Handle a stop request webhook\n */\n protected async handleStopWebhookRequest(\n request: StopWebhookRequest,\n c: Context<{ Variables: AuthVariables }>,\n ): Promise<Response> {\n const { sessionId, userId, reason } = request;\n this.logger.debug({ sessionId, userId, reason }, \"Stop request received\");\n\n try {\n await this.onStop(sessionId, userId, reason);\n return c.json({ status: \"success\" } as WebhookResponse);\n } catch (error) {\n this.logger.error(error, \"Error handling stop request\");\n return c.json(\n {\n status: \"error\",\n message: \"Failed to process stop request\",\n } as WebhookResponse,\n 500,\n );\n }\n }\n\n /**\n * Setup Health Check Endpoint\n * Creates a /health endpoint for monitoring server status.\n */\n private setupHealthCheck(): void {\n if (this.config.healthCheck) {\n const handler = (c: Context<{ Variables: AuthVariables }>) => {\n return c.json({\n status: \"healthy\",\n app: this.config.packageName,\n activeSessions: this.activeSessions.size,\n });\n };\n\n for (const path of [\"/health\", `${SDK_ROUTE_PREFIX}/health`]) {\n this.get(path, handler);\n }\n }\n }\n\n /**\n * Setup Settings Endpoint\n * Creates a /settings endpoint that the MentraOS Cloud can use to update settings.\n */\n private setupSettingsEndpoint(): void {\n const handler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n const { userIdForSettings, settings } = await c.req.json();\n\n if (!userIdForSettings || !Array.isArray(settings)) {\n return c.json(\n {\n status: \"error\",\n message: \"Missing userId or settings array in request body\",\n },\n 400,\n );\n }\n\n this.logger.debug({ userId: userIdForSettings }, \"Settings update received\");\n\n // Find all active sessions for this user\n const userSessions: AppSession[] = [];\n\n this.activeSessions.forEach((session, _sessionId) => {\n if (session.userId === userIdForSettings) {\n userSessions.push(session);\n }\n });\n\n if (userSessions.length === 0) {\n this.logger.debug({ userId: userIdForSettings }, \"No active sessions for settings update\");\n }\n\n // Update settings for all of the user's sessions\n for (const session of userSessions) {\n session.updateSettingsForTesting(settings);\n }\n\n // Allow subclasses to handle settings updates if they implement the method\n if (typeof (this as any).onSettingsUpdate === \"function\") {\n await (this as any).onSettingsUpdate(userIdForSettings, settings);\n }\n\n return c.json({\n status: \"success\",\n message: \"Settings updated successfully\",\n sessionsUpdated: userSessions.length,\n });\n } catch (error) {\n this.logger.error(error, \"Error handling settings update\");\n return c.json(\n {\n status: \"error\",\n message: \"Internal server error processing settings update\",\n },\n 500,\n );\n }\n };\n\n for (const path of [\"/settings\", `${SDK_ROUTE_PREFIX}/settings`]) {\n this.post(path, handler);\n }\n }\n\n /**\n * Setup Static File Serving\n * Configures Hono to serve static files from the specified directory.\n */\n private setupPublicDir(): void {\n if (this.config.publicDir) {\n const publicPath = path.resolve(this.config.publicDir);\n this.use(\"/*\", serveStatic({ root: publicPath }));\n this.logger.debug({ publicPath }, \"Serving static files\");\n }\n }\n\n /**\n * Setup Shutdown Handlers\n *\n * Both SIGINT (Ctrl+C) and SIGTERM (Kubernetes) → fast exit.\n *\n * We never release ownership on shutdown (cloud will resurrect), so\n * there is nothing useful to clean up. The only thing worth doing is\n * a best-effort SimpleStorage flush, which we fire-and-forget.\n *\n * process.exit() does NOT work reliably under `bun --watch` — it\n * intercepts the call. Instead we remove all JS signal handlers and\n * re-raise the signal so the OS default handler terminates us.\n *\n * See: cloud/issues/086-sdk-fast-shutdown\n */\n private setupShutdown(): void {\n const die = (signal: \"SIGINT\" | \"SIGTERM\") => {\n this.logger.info(\"Shutting down...\");\n\n // Best-effort flush of SimpleStorage (fire-and-forget, don't await).\n for (const [, session] of this.activeSessions) {\n try {\n (session as any).simpleStorage?.flush?.()?.catch?.(() => {});\n } catch {\n // ignore\n }\n }\n\n // Remove ALL handlers for BOTH signals so the re-raised signal\n // hits the OS default handler and actually kills the process.\n process.removeAllListeners(\"SIGINT\");\n process.removeAllListeners(\"SIGTERM\");\n\n // Re-raise the original signal. OS kills us immediately.\n process.kill(process.pid, signal);\n };\n\n process.on(\"SIGINT\", () => die(\"SIGINT\"));\n process.on(\"SIGTERM\", () => die(\"SIGTERM\"));\n }\n\n /**\n * 🧹 Cleanup\n * Closes all active sessions and runs cleanup handlers.\n * Does NOT release ownership - we want the cloud to resurrect when we come back up.\n *\n * OWNERSHIP_RELEASE should only be sent for:\n * - switching_clouds: User moved to another cloud, don't compete\n * - user_logout: User explicitly logged out\n *\n * NOT for clean_shutdown, because:\n * - Server is restarting/redeploying\n * - Cloud should resurrect the app (trigger webhook)\n * - User expects their app to keep running\n *\n * See: cloud/issues/023-disposed-appsession-resurrection-bug\n */\n private async cleanup(): Promise<void> {\n this.logger.debug(\"Cleanup started — not releasing ownership (cloud will resurrect)\");\n // Close all active sessions WITHOUT releasing ownership\n // This allows the cloud to resurrect apps when we come back up\n for (const [sessionId, session] of this.activeSessions) {\n this.logger.debug({ sessionId }, \"Closing session\");\n try {\n // Just disconnect, don't release ownership\n // The cloud will enter grace period and then resurrect via webhook\n await session.disconnect({\n releaseOwnership: false,\n });\n } catch (error) {\n this.logger.error(error, `Error during cleanup of session ${sessionId}`);\n // Still try to disconnect even if release fails\n try {\n await session.disconnect();\n } catch {\n // Ignore secondary errors\n }\n }\n }\n this.activeSessions.clear();\n this.activeSessionsByUserId.clear();\n\n // Run cleanup handlers\n this.cleanupHandlers.forEach((handler) => handler());\n }\n\n /**\n * 🎯 Setup Photo Upload Endpoint\n * Creates a /photo-upload endpoint for receiving photos directly from ASG glasses\n */\n private setupPhotoUploadEndpoint(): void {\n const handler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n // Parse multipart form data\n const body = await c.req.parseBody();\n const requestId = body.requestId as string;\n const type = body.type as string;\n const errorCode = body.errorCode as string;\n const errorMessage = body.errorMessage as string;\n const photoFile = body.photo as File | undefined;\n\n // Defensive parsing: photo file presence is the primary success indicator\n // The success field may be undefined/missing from some clients\n const hasPhotoFile = !!photoFile;\n const successValue = typeof body.success === \"string\" ? body.success : undefined;\n const isExplicitError = type === \"photo_error\" || successValue === \"false\";\n\n this.logger.debug({ requestId, type, hasPhotoFile, isExplicitError }, \"Photo response received\");\n\n if (!requestId) {\n this.logger.error(\"No requestId in photo response\");\n return c.json({ success: false, error: \"No requestId provided\" }, 400);\n }\n\n // Complete the request (O(1) lookup and cleanup)\n const pending = this.completePhotoRequest(requestId);\n if (!pending) {\n this.logger.debug(\n { requestId, pendingCount: this.pendingPhotoRequests.size },\n \"No pending request found for photo (may have timed out or session ended)\",\n );\n return c.json(\n { success: false, error: \"No pending request found for this photo (may have timed out or session ended)\" },\n 404,\n );\n }\n\n // Handle error response: only if explicitly marked as error AND no photo file\n if (isExplicitError && !hasPhotoFile) {\n this.logger.warn(\n { requestId, errorCode, errorMessage },\n `Photo capture failed: ${errorCode} - ${errorMessage}`,\n );\n pending.reject(new Error(`${errorCode || \"UNKNOWN_ERROR\"}: ${errorMessage || \"Unknown error\"}`));\n\n return c.json({\n success: true,\n requestId,\n message: \"Photo error received successfully\",\n });\n }\n\n // Handle successful photo upload\n if (!photoFile) {\n const errorMsg = \"No photo file in upload (and no explicit error reported)\";\n this.logger.error({ requestId, bodyKeys: Object.keys(body) }, errorMsg);\n pending.reject(new Error(errorMsg));\n return c.json({ success: false, error: errorMsg }, 400);\n }\n\n // Read file buffer\n const buffer = Buffer.from(await photoFile.arrayBuffer());\n\n this.logger.debug({ requestId, size: photoFile.size }, \"Photo received\");\n\n // Deliver photo data to the original requester\n pending.resolve({\n buffer,\n mimeType: photoFile.type,\n filename: photoFile.name || \"photo.jpg\",\n requestId,\n size: photoFile.size,\n timestamp: new Date(),\n });\n\n return c.json({\n success: true,\n requestId,\n message: \"Photo received successfully\",\n });\n } catch (error) {\n this.logger.error(error, \"Error handling photo response\");\n return c.json({ success: false, error: \"Internal server error processing photo response\" }, 500);\n }\n };\n\n for (const path of [\"/photo-upload\", `${SDK_ROUTE_PREFIX}/photo-upload`]) {\n this.post(path, handler);\n }\n }\n\n /**\n * Setup Mentra Auth Redirect Endpoint\n * Creates a /mentra-auth endpoint that redirects to the MentraOS OAuth flow.\n */\n private setupMentraAuthRedirect(): void {\n const handler = (c: Context<{ Variables: AuthVariables }>) => {\n const authUrl = `https://account.mentra.glass/auth?packagename=${encodeURIComponent(this.config.packageName)}`;\n return c.redirect(authUrl, 302);\n };\n\n for (const path of [\"/mentra-auth\", `${SDK_ROUTE_PREFIX}/auth`]) {\n this.get(path, handler);\n }\n }\n\n /**\n * Setup SDK-owned webview auth routes.\n *\n * Canonical v3 path is under the internal SDK namespace. The legacy\n * `/api/mentra/auth` path remains as a compatibility alias during the\n * transition so older Hono examples and early adopters keep working.\n */\n private setupMentraWebviewAuth(): void {\n const authApp = createMentraAuthRoutes({\n apiKey: this.config.apiKey,\n packageName: this.config.packageName,\n cookieSecret: this.config.cookieSecret || this.config.apiKey,\n });\n\n for (const path of [`${SDK_ROUTE_PREFIX}/auth`, LEGACY_MENTRA_AUTH_ROUTE_PREFIX]) {\n this.route(path, authApp);\n }\n }\n}\n\n/**\n * @deprecated Use `AppServerConfig` instead. `TpaServerConfig` is deprecated and will be removed in a future version.\n * This is an alias for backward compatibility only.\n */\nexport type TpaServerConfig = AppServerConfig;\n\n/**\n * @deprecated Use `AppServer` instead. `TpaServer` is deprecated and will be removed in a future version.\n * This is an alias for backward compatibility only.\n */\nexport class TpaServer extends AppServer {\n constructor(config: TpaServerConfig) {\n super(config);\n console.warn(\n \"⚠️ DEPRECATION WARNING: TpaServer is deprecated and will be removed in a future version. \" +\n \"Please use AppServer instead. \" +\n 'Simply replace \"TpaServer\" with \"AppServer\" in your code.',\n );\n }\n}\n",
|
|
48
|
+
"/**\n * App Server Module\n *\n * Creates and manages a server for Apps in the MentraOS ecosystem.\n * Handles webhook endpoints, session management, and cleanup.\n *\n * Now built on Hono + Bun for better performance and developer experience.\n */\nimport fs from \"fs\";\nimport path from \"path\";\n\nimport { Hono } from \"hono\";\nimport type { Context, MiddlewareHandler } from \"hono\";\nimport { serveStatic } from \"hono/bun\";\nimport { Logger } from \"pino\";\n\nimport { getDistTag } from \"../../constants/log-messages/updates\";\nimport { createLogger } from \"../../logging/logger\";\nimport {\n WebhookRequest,\n WebhookResponse,\n SessionWebhookRequest,\n StopWebhookRequest,\n ToolCall,\n WebhookRequestType,\n AuthVariables,\n} from \"../../types\";\n\nimport { AppSession } from \"../session/index\";\nimport { createAuthMiddleware, createMentraAuthRoutes } from \"../webview\";\n\n// Import PhotoData type for pending photo requests\nimport type { PhotoData } from \"../../types/photo-data\";\n\nexport const GIVE_APP_CONTROL_OF_TOOL_RESPONSE: string = \"GIVE_APP_CONTROL_OF_TOOL_RESPONSE\";\nconst SDK_ROUTE_PREFIX = \"/api/_mentraos\";\nconst LEGACY_MENTRA_AUTH_ROUTE_PREFIX = \"/api/mentra/auth\";\n\n/**\n * Pending photo request stored at AppServer level for reconnection resilience.\n * This allows O(1) lookup when photo uploads arrive via HTTP,\n * and survives session reconnections.\n * See: cloud/issues/019-sdk-photo-request-architecture\n */\ninterface PendingPhotoRequest {\n userId: string;\n sessionId: string;\n session: AppSession;\n resolve: (photo: PhotoData) => void;\n reject: (error: Error) => void;\n timestamp: number;\n timeoutId?: ReturnType<typeof setTimeout>;\n}\n\n/**\n * 🔧 Configuration options for App Server\n *\n * @example\n * ```typescript\n * const config: AppServerConfig = {\n * packageName: 'org.example.myapp',\n * apiKey: 'your_api_key',\n * port: 7010,\n * publicDir: './public'\n * };\n * ```\n */\nexport interface AppServerConfig {\n /** 📦 Unique identifier for your App (e.g., 'org.company.appname') must match what you specified at https://console.mentra.glass */\n packageName: string;\n /** 🔑 API key for authentication with MentraOS Cloud */\n apiKey: string;\n /** 🌐 Port number for the server (default: 7010) */\n port?: number;\n\n /** Cloud API URL (default: 'api.mentra.glass') */\n cloudApiUrl?: string;\n\n /** 🛣️ [DEPRECATED] do not set: The SDK will automatically expose an endpoint at '/webhook' */\n webhookPath?: string;\n /**\n * 📂 Directory for serving static files (e.g., images, logos)\n * Set to false to disable static file serving\n */\n publicDir?: string | false;\n\n /** ❤️ Enable health check endpoint at /health (default: true) */\n healthCheck?: boolean;\n /**\n * 🔐 Secret key used to sign session cookies\n * This must be a strong, unique secret\n */\n cookieSecret?: string;\n /** App instructions string shown to the user */\n appInstructions?: string;\n\n /**\n * SDK log level. Controls which log messages appear in the terminal.\n * - 'error': Only errors\n * - 'warn': Errors and warnings (default)\n * - 'info': Normal operation\n * - 'debug': Everything including SDK internals\n *\n * Can also be set with the MENTRA_LOG_LEVEL environment variable.\n * This config option takes priority over the env var.\n */\n logLevel?: \"error\" | \"warn\" | \"info\" | \"debug\";\n}\n\n// Type for Hono app with auth variables\ntype AppHono = Hono<{ Variables: AuthVariables }>;\n\n/**\n * 🎯 App Server Implementation\n *\n * Base class for creating App servers, now extending Hono for a modern API.\n * Handles:\n * - 🔄 Session lifecycle management\n * - 📡 Webhook endpoints for MentraOS Cloud\n * - 📂 Static file serving\n * - ❤️ Health checks\n * - 🧹 Cleanup on shutdown\n *\n * @example\n * ```typescript\n * class MyAppServer extends AppServer {\n * constructor(config: AppServerConfig) {\n * super(config)\n *\n * // Add custom API routes (Hono syntax)\n * this.get(\"/api/custom\", (c) => c.json({ message: \"Hello!\" }))\n * }\n *\n * protected async onSession(session: AppSession, sessionId: string, userId: string) {\n * // Handle new user sessions here\n * session.events.onTranscription((data) => {\n * session.layouts.showTextWall(data.text);\n * });\n * }\n * }\n *\n * const server = new MyAppServer({\n * packageName: 'org.example.myapp',\n * apiKey: 'your_api_key',\n * });\n *\n * await server.start();\n * ```\n */\nexport class AppServer extends Hono<{ Variables: AuthVariables }> {\n /** Server configuration */\n protected config: AppServerConfig;\n /** Map of active user sessions by sessionId */\n private activeSessions = new Map<string, AppSession>();\n /** Map of active user sessions by userId */\n private activeSessionsByUserId = new Map<string, AppSession>();\n /** Guards against running cleanup twice (double Ctrl-C, SIGINT+SIGTERM, etc.) */\n private _cleanupPromise: Promise<void> | null = null;\n /**\n * Pending photo requests by requestId - owned by AppServer for HTTP endpoint access.\n * This is the single source of truth for pending photo requests.\n * Stored here (not on CameraModule) because:\n * 1. Photo uploads arrive via HTTP to AppServer, not via WebSocket to session\n * 2. Allows O(1) lookup by requestId instead of iterating all sessions\n * 3. Survives session reconnections (session may be removed from activeSessions temporarily)\n * See: cloud/issues/019-sdk-photo-request-architecture\n */\n private pendingPhotoRequests = new Map<string, PendingPhotoRequest>();\n /** Array of cleanup handlers to run on shutdown */\n private cleanupHandlers: Array<() => void> = [];\n /** App instructions string shown to the user */\n private appInstructions: string | null = null;\n\n public readonly logger: Logger;\n\n constructor(config: AppServerConfig) {\n super(); // Initialize Hono\n\n // Set defaults and merge with provided config\n this.config = {\n port: 7010,\n webhookPath: \"/webhook\",\n publicDir: false,\n healthCheck: true,\n ...config,\n };\n\n // Apply config-level log settings to environment before logger creation.\n // Config takes priority over env vars.\n if (config.logLevel !== undefined) {\n process.env.MENTRA_LOG_LEVEL = config.logLevel;\n }\n\n this.logger = createLogger({\n logLevel: (config.logLevel ?? \"warn\") as any,\n }).child({\n app: this.config.packageName,\n packageName: this.config.packageName,\n service: \"app-server\",\n });\n\n // Apply authentication middleware\n this.use(\n \"*\",\n createAuthMiddleware({\n apiKey: this.config.apiKey,\n packageName: this.config.packageName,\n getAppSessionForUser: (userId: string) => {\n return this.activeSessionsByUserId.get(userId) || null;\n },\n cookieSecret: this.config.cookieSecret || this.config.apiKey, // Default to apiKey for simplicity\n }),\n );\n\n this.appInstructions = (config as any).appInstructions || null;\n\n // Setup server features\n this.setupWebhook();\n this.setupSettingsEndpoint();\n this.setupHealthCheck();\n this.setupToolCallEndpoint();\n this.setupPhotoUploadEndpoint();\n this.setupMentraWebviewAuth();\n this.setupMentraAuthRedirect();\n this.setupPublicDir();\n this.setupShutdown();\n }\n\n /**\n * @deprecated Use `this.get()`, `this.post()`, etc. directly since AppServer now extends Hono\n * This method is kept for backward compatibility during migration.\n */\n public getExpressApp(): AppHono {\n console.warn(\n \"DEPRECATION: getExpressApp() is deprecated. AppServer now extends Hono - use this.get(), this.post(), etc. directly.\",\n );\n return this as AppHono;\n }\n\n /**\n * Get the Hono app instance (returns this since AppServer extends Hono)\n */\n public getHonoApp(): AppHono {\n return this as AppHono;\n }\n\n /**\n * 👥 Session Handler\n * Override this method to handle new App sessions.\n * This is where you implement your app's core functionality.\n *\n * @param session - App session instance for the user\n * @param sessionId - Unique identifier for this session\n * @param userId - User's identifier\n */\n protected async onSession(session: AppSession, sessionId: string, userId: string): Promise<void> {\n this.logger.debug({ sessionId, userId }, \"Session handler started\");\n }\n\n /**\n * 👥 Stop Handler\n * Override this method to handle stop requests.\n * This is where you can clean up resources when a session is stopped.\n *\n * @param sessionId - Unique identifier for this session\n * @param userId - User's identifier\n * @param reason - Reason for stopping\n */\n protected async onStop(sessionId: string, userId: string, reason: string): Promise<void> {\n this.logger.debug(`Session ${sessionId} stopped for user ${userId}. Reason: ${reason}`);\n\n // Default implementation: close the session if it exists\n const session = this.activeSessions.get(sessionId);\n if (session) {\n session.disconnect();\n this.activeSessions.delete(sessionId);\n this.activeSessionsByUserId.delete(userId);\n }\n }\n\n /**\n * 🛠️ Tool Call Handler\n * Override this method to handle tool calls from MentraOS Cloud.\n * This is where you implement your app's tool functionality.\n *\n * @param toolCall - The tool call request containing tool details and parameters\n * @returns Optional string response that will be sent back to MentraOS Cloud\n */\n protected async onToolCall(toolCall: ToolCall): Promise<string | undefined> {\n this.logger.debug(`Tool call received: ${toolCall.toolId}`);\n this.logger.debug(`Parameters: ${JSON.stringify(toolCall.toolParameters)}`);\n return undefined;\n }\n\n protected getActiveSessionById(sessionId: string): AppSession | null {\n return this.activeSessions.get(sessionId) || null;\n }\n\n protected getActiveSessionForUser(userId: string): AppSession | null {\n return this.activeSessionsByUserId.get(userId) || null;\n }\n\n protected setActiveSession(sessionId: string, userId: string, session: AppSession): void {\n this.activeSessions.set(sessionId, session);\n this.activeSessionsByUserId.set(userId, session);\n }\n\n protected removeActiveSession(sessionId: string, userId: string): void {\n this.activeSessions.delete(sessionId);\n this.activeSessionsByUserId.delete(userId);\n }\n\n /**\n * 🚀 Initialize the App\n * Sets up logging and checks SDK version.\n * After calling this, use Bun.serve() with app.fetch to start the server.\n *\n * @example\n * ```typescript\n * const app = new MyAppServer({ ... })\n * await app.start()\n *\n * Bun.serve({\n * port: 3333,\n * routes: { \"/*\": indexHtml },\n * fetch: app.fetch,\n * })\n * ```\n *\n * @returns Promise that resolves when initialization is complete\n */\n public async start(): Promise<void> {\n this.logger.info(`App server running on port ${this.config.port}`);\n\n // Check for SDK updates (non-blocking)\n await this.checkSDKVersion();\n }\n\n /**\n * Check and log SDK version (dist-tag aware).\n * Hits npm registry directly — no dependency on our backend.\n */\n private async checkSDKVersion(): Promise<void> {\n try {\n const sdkPkgPath = path.resolve(process.cwd(), \"node_modules/@mentra/sdk/package.json\");\n\n let currentVersion = \"unknown\";\n\n if (fs.existsSync(sdkPkgPath)) {\n const sdkPkg = JSON.parse(fs.readFileSync(sdkPkgPath, \"utf-8\"));\n currentVersion = sdkPkg.version || \"not-found\";\n } else {\n this.logger.debug({ sdkPkgPath }, \"No @mentra/sdk package.json found at path\");\n }\n\n // Determine which dist-tag (release track) the dev is on\n const distTag = getDistTag(currentVersion);\n\n // Fetch latest version for this track directly from npm registry\n let latest: string | null = null;\n try {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), 3000);\n const response = await fetch(`https://registry.npmjs.org/@mentra/sdk/${distTag}`, {\n signal: controller.signal,\n });\n clearTimeout(timeout);\n if (response.ok) {\n const data = (await response.json()) as { version: string };\n latest = data.version;\n }\n } catch {\n this.logger.debug(\"Failed to check npm for SDK updates — skipping (offline or timeout)\");\n }\n\n if (currentVersion === \"not-found\") {\n this.logger.warn(\n \"@mentra/sdk not found in your project dependencies. Install it with: bun install @mentra/sdk\",\n );\n } else if (latest && latest !== currentVersion) {\n this.logger.warn(`SDK update available: ${currentVersion} → ${latest} — bun install @mentra/sdk@${distTag}`);\n }\n } catch (err) {\n this.logger.debug(err, \"Version check failed\");\n }\n }\n\n /**\n * Stop the Server\n * Gracefully shuts down the server and cleans up all sessions.\n */\n public async stop(): Promise<void> {\n // Prevent double-cleanup from concurrent signals or multiple stop() calls\n if (this._cleanupPromise) return this._cleanupPromise;\n this.logger.info(\"Shutting down...\");\n this._cleanupPromise = this.cleanup();\n return this._cleanupPromise;\n }\n\n /**\n * 🔐 Generate a App token for a user\n * This should be called when handling a session webhook request.\n *\n * @param userId - User identifier\n * @param sessionId - Session identifier\n * @param secretKey - Secret key for signing the token\n * @returns JWT token string\n */\n protected generateToken(userId: string, sessionId: string, secretKey: string): string {\n const { createToken } = require(\"../token/utils\");\n return createToken(\n {\n userId,\n packageName: this.config.packageName,\n sessionId,\n },\n { secretKey },\n );\n }\n\n /**\n * Add Cleanup Handler\n * Register a function to be called during server shutdown.\n *\n * @param handler - Function to call during cleanup\n */\n protected addCleanupHandler(handler: () => void): void {\n this.cleanupHandlers.push(handler);\n }\n\n // =====================================\n // 📸 Photo Request Management APIs\n // =====================================\n\n /**\n * Register a pending photo request.\n * Called by CameraModule when a photo is requested.\n * Stores the request at AppServer level for O(1) lookup when HTTP response arrives.\n *\n * @param requestId - Unique identifier for this photo request\n * @param request - Request details including session, resolve/reject callbacks\n */\n registerPhotoRequest(requestId: string, request: Omit<PendingPhotoRequest, \"timeoutId\">): void {\n // Set timeout at AppServer level (single source of truth)\n const timeoutMs = 30000; // 30 seconds\n const timeoutId = setTimeout(() => {\n const pending = this.pendingPhotoRequests.get(requestId);\n if (pending) {\n pending.reject(new Error(\"Photo request timed out\"));\n this.pendingPhotoRequests.delete(requestId);\n this.logger.warn({ requestId }, \"Photo request timed out\");\n }\n }, timeoutMs);\n\n this.pendingPhotoRequests.set(requestId, {\n ...request,\n timeoutId,\n });\n\n this.logger.debug({ requestId, userId: request.userId, sessionId: request.sessionId }, \"Photo request registered\");\n }\n\n /**\n * Get a pending photo request by ID.\n *\n * @param requestId - The request ID to look up\n * @returns The pending request, or undefined if not found\n */\n getPhotoRequest(requestId: string): PendingPhotoRequest | undefined {\n return this.pendingPhotoRequests.get(requestId);\n }\n\n /**\n * Complete a photo request (success or error).\n * Clears the timeout and removes from the pending map.\n *\n * @param requestId - The request ID to complete\n * @returns The pending request that was completed, or undefined if not found\n */\n completePhotoRequest(requestId: string): PendingPhotoRequest | undefined {\n const pending = this.pendingPhotoRequests.get(requestId);\n if (pending) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n this.pendingPhotoRequests.delete(requestId);\n this.logger.debug({ requestId }, \"Photo request completed\");\n }\n return pending;\n }\n\n /**\n * Clean up all pending photo requests for a session.\n * Called when a session permanently disconnects.\n *\n * @param sessionId - The session ID to clean up requests for\n */\n cleanupPhotoRequestsForSession(sessionId: string): void {\n let cleanedCount = 0;\n for (const [requestId, pending] of this.pendingPhotoRequests) {\n if (pending.sessionId === sessionId) {\n if (pending.timeoutId) {\n clearTimeout(pending.timeoutId);\n }\n pending.reject(new Error(\"Session ended\"));\n this.pendingPhotoRequests.delete(requestId);\n cleanedCount++;\n this.logger.debug({ requestId, sessionId }, \"Photo request cleaned up (session ended)\");\n }\n }\n if (cleanedCount > 0) {\n this.logger.debug({ sessionId, cleanedCount }, \"Cleaned up photo requests for ended session\");\n }\n }\n\n /**\n * Setup Webhook Endpoint\n * Creates the webhook endpoint that MentraOS Cloud calls to start new sessions.\n */\n private setupWebhook(): void {\n const webhookPaths = [this.config.webhookPath || \"/webhook\", `${SDK_ROUTE_PREFIX}/webhook`];\n\n const handler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n const webhookRequest = (await c.req.json()) as WebhookRequest;\n\n // Handle session request\n if (webhookRequest.type === WebhookRequestType.SESSION_REQUEST) {\n return this.handleSessionWebhookRequest(webhookRequest as SessionWebhookRequest, c);\n }\n // Handle stop request\n else if (webhookRequest.type === WebhookRequestType.STOP_REQUEST) {\n return this.handleStopWebhookRequest(webhookRequest as StopWebhookRequest, c);\n }\n // Unknown webhook type\n else {\n this.logger.error(\"Unknown webhook request type\");\n return c.json(\n {\n status: \"error\",\n message: \"Unknown webhook request type\",\n } as WebhookResponse,\n 400,\n );\n }\n } catch (error) {\n this.logger.error(error, \"Error handling webhook\");\n return c.json(\n {\n status: \"error\",\n message: \"Error handling webhook: \" + (error as Error).message,\n } as WebhookResponse,\n 500,\n );\n }\n };\n\n for (const path of webhookPaths) {\n this.post(path, handler);\n }\n }\n\n /**\n * Setup Tool Call Endpoint\n * Creates a /tool endpoint for handling tool calls from MentraOS Cloud.\n */\n private setupToolCallEndpoint(): void {\n const postHandler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n const toolCall = (await c.req.json()) as ToolCall;\n toolCall.activeSession = this.getActiveSessionForUser(toolCall.userId);\n this.logger.debug({ toolId: toolCall.toolId }, \"Tool call received\");\n\n // Call the onToolCall handler and get the response\n const response = await this.onToolCall(toolCall);\n\n // Send back the response if one was provided\n if (response !== undefined) {\n return c.json({ status: \"success\", reply: response });\n } else {\n return c.json({ status: \"success\", reply: null });\n }\n } catch (error) {\n this.logger.error(error, \"Error handling tool call\");\n return c.json(\n {\n status: \"error\",\n message: error instanceof Error ? error.message : \"Unknown error occurred calling tool\",\n },\n 500,\n );\n }\n };\n\n const getHandler = async (c: Context<{ Variables: AuthVariables }>) => {\n return c.json({ status: \"success\", reply: \"Hello, world!\" });\n };\n\n for (const path of [\"/tool\", `${SDK_ROUTE_PREFIX}/tool`]) {\n this.post(path, postHandler);\n this.get(path, getHandler);\n }\n }\n\n /**\n * Handle a session request webhook\n */\n protected async handleSessionWebhookRequest(\n request: SessionWebhookRequest,\n c: Context<{ Variables: AuthVariables }>,\n ): Promise<Response> {\n const { sessionId, userId, websocketUrl, mentraOSWebsocketUrl, augmentOSWebsocketUrl } = request;\n this.logger.debug({ userId, sessionId }, \"Session request received\");\n\n // Check for existing session (user might be switching clouds)\n // If an existing session exists, we need to clean it up properly to avoid:\n // 1. Orphaned sessions with open WebSockets\n // 2. Cleanup handlers that corrupt the new session's map entries\n // See: cloud/issues/018-app-disconnect-resurrection\n const existingSession = this.getActiveSessionById(sessionId);\n if (existingSession) {\n this.logger.debug({ sessionId, userId }, \"Existing session found — releasing ownership before reconnect\");\n\n try {\n // Send OWNERSHIP_RELEASE to tell the old cloud not to resurrect this app\n // The old cloud will mark the app as DORMANT instead of trying to restart it\n await existingSession.releaseOwnership(\"switching_clouds\");\n } catch (error) {\n this.logger.warn({ error, sessionId }, \"Failed to release ownership on old session — continuing\");\n }\n\n try {\n // Disconnect the old session explicitly\n existingSession.disconnect();\n } catch (error) {\n this.logger.warn({ error, sessionId }, \"Failed to disconnect old session — continuing\");\n }\n\n // Remove from maps immediately (don't wait for cleanup handler)\n this.removeActiveSession(sessionId, userId);\n\n this.logger.debug({ sessionId, userId }, \"Old session cleaned up, proceeding with new connection\");\n }\n\n // Create new App session\n const session = new AppSession({\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n mentraOSWebsocketUrl: websocketUrl || mentraOSWebsocketUrl || augmentOSWebsocketUrl,\n appServer: this,\n userId,\n });\n\n // Setup session event handlers\n const cleanupDisconnect = session.events.onDisconnected((info) => {\n // Determine if this is a permanent disconnect\n // Permanent disconnects happen when:\n // 1. User session ends (sessionEnded === true)\n // 2. Reconnection attempts exhausted (permanent === true)\n // 3. Clean WebSocket closure (1000/1001) - no reconnection will be attempted\n // Temporary disconnects (abnormal closures like 1006 that trigger reconnection) should NOT remove session from maps\n // See: cloud/issues/019-sdk-photo-request-architecture\n let isPermanent = false;\n let reason = \"unknown\";\n\n // Handle different disconnect info formats (string or object)\n if (typeof info === \"string\") {\n this.logger.debug({ sessionId }, `Session disconnected: ${info}`);\n reason = info;\n // String-only disconnects are typically temporary (e.g., \"WebSocket closed\")\n isPermanent = false;\n } else {\n this.logger.debug({ sessionId, code: info.code }, `Session disconnected: ${info.message}`);\n reason = info.reason || info.message;\n\n if (info.sessionEnded === true) {\n this.logger.debug({ sessionId }, \"User session ended, calling onStop\");\n isPermanent = true;\n\n this.onStop(sessionId, userId, \"User session ended\").catch((error) => {\n this.logger.error(error, \"Error in onStop handler for session end\");\n });\n }\n // Check if this is a permanent disconnection after exhausted reconnection attempts\n else if (info.permanent === true) {\n this.logger.debug({ sessionId }, \"Permanent disconnection, calling onStop\");\n isPermanent = true;\n\n this.onStop(sessionId, userId, `Connection permanently lost: ${info.reason}`).catch((error) => {\n this.logger.error(error, \"Error in onStop handler for permanent disconnection\");\n });\n }\n // Check if this is a clean WebSocket closure (1000/1001) that won't trigger reconnection\n // These are intentional disconnects (app shutdown, manual stop, etc.)\n // AppSession skips reconnection for these codes, so we must treat them as permanent\n // to avoid zombie sessions in activeSessions map\n else if (info.wasClean === true || info.code === 1000 || info.code === 1001) {\n this.logger.debug({ sessionId, code: info.code }, \"Clean WebSocket closure, treating as permanent\");\n isPermanent = true;\n\n // Call onStop for clean disconnects too\n this.onStop(sessionId, userId, `Clean disconnect: ${reason}`).catch((error) => {\n this.logger.error(error, \"Error in onStop handler for clean disconnect\");\n });\n }\n }\n\n // Only remove session and clean up photo requests on PERMANENT disconnects\n // Temporary disconnects should leave the session in place so:\n // 1. Photo uploads can still find the pending request\n // 2. The session can be reused after reconnection\n // See: cloud/issues/019-sdk-photo-request-architecture\n if (isPermanent) {\n // Remove the session from active sessions ONLY if this session is still the active one.\n // This prevents a bug where an old session's cleanup handler deletes a newer session:\n // 1. User switches from Cloud A to Cloud B\n // 2. SDK creates sessionB, overwrites activeSessions[sessionId]\n // 3. sessionA is orphaned but its cleanup handler still references sessionId\n // 4. When Cloud A disposes, sessionA's cleanup fires and would delete sessionB\n // By checking identity (===), we only delete if we're still the current session.\n // See: cloud/issues/018-app-disconnect-resurrection\n if (this.getActiveSessionById(sessionId) === session) {\n this.removeActiveSession(sessionId, userId);\n } else {\n this.logger.debug({ sessionId }, \"Session cleanup skipped — a newer session has taken over\");\n }\n\n // Clean up any pending photo requests for this session\n this.cleanupPhotoRequestsForSession(sessionId);\n } else {\n // Temporary disconnect - session stays in maps for reconnection\n // Photo requests remain pending and can still be fulfilled\n this.logger.debug({ sessionId, reason }, \"Temporary disconnect, keeping session for reconnection\");\n }\n });\n\n const cleanupError = session.events.onError((error) => {\n this.logger.error(error, \"Session error\");\n });\n\n // Start the session\n try {\n await session.connect(sessionId);\n this.setActiveSession(sessionId, userId, session);\n // Respond to webhook immediately — session is connected.\n // Run onSession in background so slow developer setup doesn't timeout the webhook.\n const response = c.json({ status: \"success\" } as WebhookResponse);\n\n // Fire-and-forget: run developer's onSession handler\n this.onSession(session, sessionId, userId).catch((error) => {\n this.logger.error({ error, sessionId, userId }, \"Error in onSession handler\");\n });\n\n return response;\n } catch (error) {\n this.logger.error(error, \"Failed to connect session\");\n cleanupDisconnect();\n cleanupError();\n return c.json(\n {\n status: \"error\",\n message: \"Failed to connect\",\n } as WebhookResponse,\n 500,\n );\n }\n }\n\n /**\n * Handle a stop request webhook\n */\n protected async handleStopWebhookRequest(\n request: StopWebhookRequest,\n c: Context<{ Variables: AuthVariables }>,\n ): Promise<Response> {\n const { sessionId, userId, reason } = request;\n this.logger.debug({ sessionId, userId, reason }, \"Stop request received\");\n\n try {\n await this.onStop(sessionId, userId, reason);\n return c.json({ status: \"success\" } as WebhookResponse);\n } catch (error) {\n this.logger.error(error, \"Error handling stop request\");\n return c.json(\n {\n status: \"error\",\n message: \"Failed to process stop request\",\n } as WebhookResponse,\n 500,\n );\n }\n }\n\n /**\n * Setup Health Check Endpoint\n * Creates a /health endpoint for monitoring server status.\n */\n private setupHealthCheck(): void {\n if (this.config.healthCheck) {\n const handler = (c: Context<{ Variables: AuthVariables }>) => {\n return c.json({\n status: \"healthy\",\n app: this.config.packageName,\n activeSessions: this.activeSessions.size,\n });\n };\n\n for (const path of [\"/health\", `${SDK_ROUTE_PREFIX}/health`]) {\n this.get(path, handler);\n }\n }\n }\n\n /**\n * Setup Settings Endpoint\n * Creates a /settings endpoint that the MentraOS Cloud can use to update settings.\n */\n private setupSettingsEndpoint(): void {\n const handler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n const { userIdForSettings, settings } = await c.req.json();\n\n if (!userIdForSettings || !Array.isArray(settings)) {\n return c.json(\n {\n status: \"error\",\n message: \"Missing userId or settings array in request body\",\n },\n 400,\n );\n }\n\n this.logger.debug({ userId: userIdForSettings }, \"Settings update received\");\n\n // Find all active sessions for this user\n const userSessions: AppSession[] = [];\n\n this.activeSessions.forEach((session, _sessionId) => {\n if (session.userId === userIdForSettings) {\n userSessions.push(session);\n }\n });\n\n if (userSessions.length === 0) {\n this.logger.debug({ userId: userIdForSettings }, \"No active sessions for settings update\");\n }\n\n // Update settings for all of the user's sessions\n for (const session of userSessions) {\n session.updateSettingsForTesting(settings);\n }\n\n // Allow subclasses to handle settings updates if they implement the method\n if (typeof (this as any).onSettingsUpdate === \"function\") {\n await (this as any).onSettingsUpdate(userIdForSettings, settings);\n }\n\n return c.json({\n status: \"success\",\n message: \"Settings updated successfully\",\n sessionsUpdated: userSessions.length,\n });\n } catch (error) {\n this.logger.error(error, \"Error handling settings update\");\n return c.json(\n {\n status: \"error\",\n message: \"Internal server error processing settings update\",\n },\n 500,\n );\n }\n };\n\n for (const path of [\"/settings\", `${SDK_ROUTE_PREFIX}/settings`]) {\n this.post(path, handler);\n }\n }\n\n /**\n * Setup Static File Serving\n * Configures Hono to serve static files from the specified directory.\n */\n private setupPublicDir(): void {\n if (this.config.publicDir) {\n const publicPath = path.resolve(this.config.publicDir);\n this.use(\"/*\", serveStatic({ root: publicPath }));\n this.logger.debug({ publicPath }, \"Serving static files\");\n }\n }\n\n /**\n * Setup Shutdown Handlers\n *\n * Both SIGINT (Ctrl+C) and SIGTERM (Kubernetes) → fast exit.\n *\n * We never release ownership on shutdown (cloud will resurrect), so\n * there is nothing useful to clean up. The only thing worth doing is\n * a best-effort SimpleStorage flush, which we fire-and-forget.\n *\n * process.exit() does NOT work reliably under `bun --watch` — it\n * intercepts the call. Instead we remove all JS signal handlers and\n * re-raise the signal so the OS default handler terminates us.\n *\n * See: cloud/issues/086-sdk-fast-shutdown\n */\n private setupShutdown(): void {\n const die = (signal: \"SIGINT\" | \"SIGTERM\") => {\n this.logger.info(\"Shutting down...\");\n\n // Best-effort flush of SimpleStorage (fire-and-forget, don't await).\n for (const [, session] of this.activeSessions) {\n try {\n (session as any).simpleStorage?.flush?.()?.catch?.(() => {});\n } catch {\n // ignore\n }\n }\n\n // Remove ALL handlers for BOTH signals so the re-raised signal\n // hits the OS default handler and actually kills the process.\n process.removeAllListeners(\"SIGINT\");\n process.removeAllListeners(\"SIGTERM\");\n\n // Re-raise the original signal. OS kills us immediately.\n process.kill(process.pid, signal);\n };\n\n process.on(\"SIGINT\", () => die(\"SIGINT\"));\n process.on(\"SIGTERM\", () => die(\"SIGTERM\"));\n }\n\n /**\n * 🧹 Cleanup\n * Closes all active sessions and runs cleanup handlers.\n * Does NOT release ownership - we want the cloud to resurrect when we come back up.\n *\n * OWNERSHIP_RELEASE should only be sent for:\n * - switching_clouds: User moved to another cloud, don't compete\n * - user_logout: User explicitly logged out\n *\n * NOT for clean_shutdown, because:\n * - Server is restarting/redeploying\n * - Cloud should resurrect the app (trigger webhook)\n * - User expects their app to keep running\n *\n * See: cloud/issues/023-disposed-appsession-resurrection-bug\n */\n private async cleanup(): Promise<void> {\n this.logger.debug(\"Cleanup started — not releasing ownership (cloud will resurrect)\");\n // Close all active sessions WITHOUT releasing ownership\n // This allows the cloud to resurrect apps when we come back up\n for (const [sessionId, session] of this.activeSessions) {\n this.logger.debug({ sessionId }, \"Closing session\");\n try {\n // Just disconnect, don't release ownership\n // The cloud will enter grace period and then resurrect via webhook\n await session.disconnect({\n releaseOwnership: false,\n });\n } catch (error) {\n this.logger.error(error, `Error during cleanup of session ${sessionId}`);\n // Still try to disconnect even if release fails\n try {\n await session.disconnect();\n } catch {\n // Ignore secondary errors\n }\n }\n }\n this.activeSessions.clear();\n this.activeSessionsByUserId.clear();\n\n // Run cleanup handlers\n this.cleanupHandlers.forEach((handler) => handler());\n }\n\n /**\n * 🎯 Setup Photo Upload Endpoint\n * Creates a /photo-upload endpoint for receiving photos directly from ASG glasses\n */\n private setupPhotoUploadEndpoint(): void {\n const handler = async (c: Context<{ Variables: AuthVariables }>) => {\n try {\n // Parse multipart form data\n const body = await c.req.parseBody();\n const requestId = body.requestId as string;\n const type = body.type as string;\n const errorCode = body.errorCode as string;\n const errorMessage = body.errorMessage as string;\n const photoFile = body.photo as File | undefined;\n\n // Defensive parsing: photo file presence is the primary success indicator\n // The success field may be undefined/missing from some clients\n const hasPhotoFile = !!photoFile;\n const successValue = typeof body.success === \"string\" ? body.success : undefined;\n const isExplicitError = type === \"photo_error\" || successValue === \"false\";\n\n this.logger.debug({ requestId, type, hasPhotoFile, isExplicitError }, \"Photo response received\");\n\n if (!requestId) {\n this.logger.error(\"No requestId in photo response\");\n return c.json({ success: false, error: \"No requestId provided\" }, 400);\n }\n\n // Complete the request (O(1) lookup and cleanup)\n const pending = this.completePhotoRequest(requestId);\n if (!pending) {\n this.logger.debug(\n { requestId, pendingCount: this.pendingPhotoRequests.size },\n \"No pending request found for photo (may have timed out or session ended)\",\n );\n return c.json(\n { success: false, error: \"No pending request found for this photo (may have timed out or session ended)\" },\n 404,\n );\n }\n\n // Handle error response: only if explicitly marked as error AND no photo file\n if (isExplicitError && !hasPhotoFile) {\n this.logger.warn(\n { requestId, errorCode, errorMessage },\n `Photo capture failed: ${errorCode} - ${errorMessage}`,\n );\n pending.reject(new Error(`${errorCode || \"UNKNOWN_ERROR\"}: ${errorMessage || \"Unknown error\"}`));\n\n return c.json({\n success: true,\n requestId,\n message: \"Photo error received successfully\",\n });\n }\n\n // Handle successful photo upload\n if (!photoFile) {\n const errorMsg = \"No photo file in upload (and no explicit error reported)\";\n this.logger.error({ requestId, bodyKeys: Object.keys(body) }, errorMsg);\n pending.reject(new Error(errorMsg));\n return c.json({ success: false, error: errorMsg }, 400);\n }\n\n // Read file buffer\n const buffer = Buffer.from(await photoFile.arrayBuffer());\n\n this.logger.debug({ requestId, size: photoFile.size }, \"Photo received\");\n\n // Deliver photo data to the original requester\n pending.resolve({\n buffer,\n mimeType: photoFile.type,\n filename: photoFile.name || \"photo.jpg\",\n requestId,\n size: photoFile.size,\n timestamp: new Date(),\n });\n\n return c.json({\n success: true,\n requestId,\n message: \"Photo received successfully\",\n });\n } catch (error) {\n this.logger.error(error, \"Error handling photo response\");\n return c.json({ success: false, error: \"Internal server error processing photo response\" }, 500);\n }\n };\n\n for (const path of [\"/photo-upload\", `${SDK_ROUTE_PREFIX}/photo-upload`]) {\n this.post(path, handler);\n }\n }\n\n /**\n * Setup Mentra Auth Redirect Endpoint\n * Creates a /mentra-auth endpoint that redirects to the MentraOS OAuth flow.\n */\n private setupMentraAuthRedirect(): void {\n const handler = (c: Context<{ Variables: AuthVariables }>) => {\n const authUrl = `https://account.mentra.glass/auth?packagename=${encodeURIComponent(this.config.packageName)}`;\n return c.redirect(authUrl, 302);\n };\n\n for (const path of [\"/mentra-auth\", `${SDK_ROUTE_PREFIX}/auth`]) {\n this.get(path, handler);\n }\n }\n\n /**\n * Setup SDK-owned webview auth routes.\n *\n * Canonical v3 path is under the internal SDK namespace. The legacy\n * `/api/mentra/auth` path remains as a compatibility alias during the\n * transition so older Hono examples and early adopters keep working.\n */\n private setupMentraWebviewAuth(): void {\n const authApp = createMentraAuthRoutes({\n apiKey: this.config.apiKey,\n packageName: this.config.packageName,\n cookieSecret: this.config.cookieSecret || this.config.apiKey,\n });\n\n for (const path of [`${SDK_ROUTE_PREFIX}/auth`, LEGACY_MENTRA_AUTH_ROUTE_PREFIX]) {\n this.route(path, authApp);\n }\n }\n}\n\n/**\n * @deprecated Use `AppServerConfig` instead. `TpaServerConfig` is deprecated and will be removed in a future version.\n * This is an alias for backward compatibility only.\n */\nexport type TpaServerConfig = AppServerConfig;\n\n/**\n * @deprecated Use `AppServer` instead. `TpaServer` is deprecated and will be removed in a future version.\n * This is an alias for backward compatibility only.\n */\nexport class TpaServer extends AppServer {\n constructor(config: TpaServerConfig) {\n super(config);\n console.warn(\n \"⚠️ DEPRECATION WARNING: TpaServer is deprecated and will be removed in a future version. \" +\n \"Please use AppServer instead. \" +\n 'Simply replace \"TpaServer\" with \"AppServer\" in your code.',\n );\n }\n}\n",
|
|
49
49
|
"/**\n * updates.ts\n *\n * SDK update notification messages and dist-tag utilities.\n *\n * Previously used boxen-bordered ASCII art banners. Now returns plain\n * single-line strings that the clean transport formats with color/prefix.\n *\n * The clean logger renders this as:\n * MentraOS ⚠ SDK update available: 2.1.29 → 2.1.30 — bun install @mentra/sdk@latest\n * MentraOS ⚠ SDK update available: 3.0.0-hono.4 → 3.0.0-hono.5 — bun install @mentra/sdk@hono\n */\n\n/**\n * Known npm dist-tags for @mentra/sdk.\n * Used to parse the current version's prerelease identifier into a dist-tag,\n * and to validate the tag before sending it to the cloud API.\n */\nconst KNOWN_DIST_TAGS = [\"alpha\", \"beta\", \"hono\", \"rc\", \"canary\", \"next\"] as const;\n\n/**\n * Determine the npm dist-tag (release track) from a semver version string.\n *\n * Parses the prerelease identifier:\n * \"2.1.29\" → \"latest\" (no prerelease)\n * \"2.1.31-beta.5\" → \"beta\"\n * \"3.0.0-hono.4\" → \"hono\"\n * \"2.1.2-alpha.0\" → \"alpha\"\n * \"4.0.0-rc.1\" → \"rc\"\n * \"1.0.0-unknown.1\" → \"latest\" (unrecognized prerelease falls back to latest)\n *\n * @param version - The installed SDK version string\n * @returns The dist-tag name (e.g., \"latest\", \"beta\", \"hono\")\n */\nexport function getDistTag(version: string): string {\n const pattern = new RegExp(`-(${KNOWN_DIST_TAGS.join(\"|\")})`);\n const match = version.match(pattern);\n return match ? match[1] : \"latest\";\n}\n\n/**\n * Generate a single-line SDK update notification message.\n *\n * The install command uses the correct dist-tag so developers on non-latest\n * tracks (beta, hono, etc.) aren't told to install @latest which would\n * downgrade/brick their app.\n *\n * @param currentVersion - The currently installed SDK version\n * @param latestVersion - The latest available SDK version for this track\n * @param tag - The npm dist-tag for the install command (default: \"latest\")\n * @returns A plain string suitable for `logger.warn()`\n */\nexport const newSDKUpdate = (currentVersion: string, latestVersion: string, tag: string = \"latest\"): string => {\n return `SDK update available: ${currentVersion} → ${latestVersion} — bun install @mentra/sdk@${tag}`;\n};\n",
|
|
50
50
|
"/**\n * 🎯 App Session Module\n *\n * Manages an active Third Party App session with MentraOS Cloud.\n * Handles real-time communication, event subscriptions, and display management.\n */\n\n// Patch version for tracking Bug 007 fix (subscriptions derived from handlers)\n// v1: Derive subscriptions from handlers (single source of truth)\n// v2: Add 'terminated' flag to prevent reconnection after \"User session ended\"\n// This helps verify the correct SDK version is running in production\nconst SDK_SUBSCRIPTION_PATCH = \"bug007-fix-v2\";\nimport pino from \"pino\";\nimport { WebSocket } from \"ws\";\nimport { EventManager, EventData } from \"./events\";\nimport { LayoutManager } from \"./layouts\";\nimport { SettingsManager } from \"./settings\";\nimport { LocationManager } from \"./modules/location\";\nimport { CameraModule } from \"./modules/camera\";\nimport { LedModule } from \"./modules/led\";\nimport { AudioManager } from \"./modules/audio\";\nimport { ResourceTracker } from \"../../utils/resource-tracker\";\nimport { MentraAuthError, MentraConnectionError, MentraTimeoutError, MentraError } from \"../../logging/errors\";\nimport { createTelemetryStream } from \"../../logging/telemetry-transport\";\nimport type { TelemetryLogEntry } from \"../../types/messages/app-to-cloud\";\nimport type { RequestWifiSetup, OwnershipReleaseMessage } from \"../../types/messages/app-to-cloud\";\nimport {\n // Message types\n AppToCloudMessage,\n CloudToAppMessage,\n AppConnectionInit,\n AppSubscriptionUpdate,\n AudioPlayResponse,\n AppToCloudMessageType,\n CloudToAppMessageType,\n TelemetryResponse,\n\n // Event data types\n StreamType,\n ExtendedStreamType,\n ButtonPress,\n HeadPosition,\n TouchEvent,\n PhoneNotification,\n PhoneNotificationDismissed,\n TranscriptionData,\n TranslationData,\n createTouchEventStream,\n\n // Type guards\n isAppConnectionAck,\n isAppConnectionError,\n isDataStream,\n isAppStopped,\n isSettingsUpdate,\n isDashboardModeChanged,\n isDashboardAlwaysOnChanged,\n isAudioPlayResponse,\n isCapabilitiesUpdate,\n\n // Other types\n AppSettings,\n AppSetting,\n AppConfig,\n validateAppConfig,\n AudioChunk,\n VpsCoordinates,\n PhotoTaken,\n SubscriptionRequest,\n Capabilities,\n CapabilitiesUpdate,\n} from \"../../types\";\nimport { DashboardAPI } from \"../../types/dashboard\";\nimport { MentraosSettingsUpdate } from \"../../types/messages/cloud-to-app\";\nimport { Logger } from \"pino\";\nimport { AppServer } from \"../server\";\nimport axios from \"axios\";\nimport EventEmitter from \"events\";\n\n// Import the cloud-to-app specific type guards\nimport {\n isPhotoResponse,\n isRgbLedControlResponse,\n isStreamStatus,\n isManagedStreamStatus,\n isStreamStatusCheckResponse,\n isDeviceStateUpdate,\n isRequestTelemetry,\n} from \"../../types/messages/cloud-to-app\";\nimport type { RequestTelemetry } from \"../../types/messages/cloud-to-app\";\nimport type { PhotoResponse } from \"../../types/messages/glasses-to-cloud\";\nimport { SimpleStorage } from \"./modules/simple-storage\";\nimport { DeviceState } from \"./device-state\";\nimport { readNotificationWarnLog } from \"../../utils/permissions-utils\";\n\n/**\n * ⚙️ Configuration options for App Session\n *\n * @example\n * ```typescript\n * const config: AppSessionConfig = {\n * packageName: 'org.example.myapp',\n * apiKey: 'your_api_key',\n * // Auto-reconnection is enabled by default\n * // autoReconnect: true\n * };\n * ```\n */\nexport interface AppSessionConfig {\n /** 📦 Unique identifier for your App (e.g., 'org.company.appname') */\n packageName: string;\n /** 🔑 API key for authentication with MentraOS Cloud */\n apiKey: string;\n /** 🔌 WebSocket server URL (default: 'ws://localhost:7002/app-ws') */\n mentraOSWebsocketUrl?: string;\n /** 🔄 Automatically attempt to reconnect on disconnect (default: true) */\n autoReconnect?: boolean;\n /** 🔁 Maximum number of reconnection attempts (default: 3) */\n maxReconnectAttempts?: number;\n /** ⏱️ Base delay between reconnection attempts in ms (default: 1000) */\n reconnectDelay?: number;\n\n userId: string; // user ID for tracking sessions (email of the user).\n appServer: AppServer; // Optional App server instance for advanced features\n}\n\n// List of event types that should never be subscribed to as streams\nconst APP_TO_APP_EVENT_TYPES = [\n \"app_message_received\",\n \"app_user_joined\",\n \"app_user_left\",\n \"app_room_updated\",\n \"app_direct_message_response\",\n];\n\n/**\n * 🚀 App Session Implementation\n *\n * Manages a live connection between your App and MentraOS Cloud.\n * Provides interfaces for:\n * - 🎮 Event handling (transcription, head position, etc.)\n * - 📱 Display management in AR view\n * - 🔌 Connection lifecycle\n * - 🔄 Automatic reconnection\n *\n * @example\n * ```typescript\n * const session = new AppSession({\n * packageName: 'org.example.myapp',\n * apiKey: 'your_api_key'\n * });\n *\n * // Handle events\n * session.onTranscription((data) => {\n * session.layouts.showTextWall(data.text);\n * });\n *\n * // Connect to cloud\n * await session.connect('session_123');\n * ```\n */\nexport class AppSession {\n /** WebSocket connection to MentraOS Cloud */\n private ws: WebSocket | null = null;\n /** Current session identifier */\n private sessionId: string | null = null;\n /** Number of reconnection attempts made */\n private reconnectAttempts = 0;\n /** Flag to prevent reconnection after session termination (e.g., \"User session ended\") */\n private terminated = false;\n // REMOVED: private subscriptions = new Set<ExtendedStreamType>()\n // Subscriptions are now derived from EventManager.handlers (single source of truth)\n // This prevents drift between handlers and subscriptions that caused Bug 007\n // See: cloud/issues/006-captions-and-apps-stopping/011-sdk-subscription-architecture-mismatch.md\n /** Map to store rate options for streams */\n private streamRates = new Map<ExtendedStreamType, string>();\n /** Resource tracker for automatic cleanup */\n private resources = new ResourceTracker();\n /** Internal settings storage - use public settings API instead */\n private settingsData: AppSettings = [];\n /** App configuration loaded from app_config.json */\n private appConfig: AppConfig | null = null;\n /** Whether to update subscriptions when settings change */\n private shouldUpdateSubscriptionsOnSettingsChange = false;\n /** Custom subscription handler for settings-based subscriptions */\n private subscriptionSettingsHandler?: (settings: AppSettings) => ExtendedStreamType[];\n /** Settings that should trigger subscription updates when changed */\n private subscriptionUpdateTriggers: string[] = [];\n /** Pending user discovery requests waiting for responses */\n private pendingUserDiscoveryRequests = new Map<\n string,\n {\n resolve: (userList: any) => void;\n reject: (reason: any) => void;\n }\n >();\n /** Pending direct message requests waiting for responses */\n private pendingDirectMessages = new Map<\n string,\n {\n resolve: (success: boolean) => void;\n reject: (reason: any) => void;\n }\n >();\n\n /** 🎮 Event management interface */\n public readonly events: EventManager;\n /** 📱 Layout management interface */\n public readonly layouts: LayoutManager;\n /** ⚙️ Settings management interface */\n public readonly settings: SettingsManager;\n /** 📊 Dashboard management interface */\n public readonly dashboard: DashboardAPI;\n /** 📍 Location management interface */\n public readonly location: LocationManager;\n /** 📷 Camera interface for photos and streaming */\n public readonly camera: CameraModule;\n /** 💡 LED interface for RGB LED control */\n public readonly led: LedModule;\n /** 🔊 Audio interface for audio playback */\n public readonly audio: AudioManager;\n /** 🔐 Simple key-value storage interface */\n public readonly simpleStorage: SimpleStorage;\n /** 📱 Reactive device state (WebSocket-based observables) */\n public readonly device: { state: DeviceState };\n\n public readonly appServer: AppServer;\n public readonly logger: Logger;\n public readonly userId: string;\n\n /** 🔧 Device capabilities available for this session */\n public capabilities: Capabilities | null = null;\n\n /** 📡 Latest glasses connection state (includes WiFi status) */\n private glassesConnectionState: any = null; // Using any for now since GlassesConnectionState is in glasses-to-cloud types\n\n /** Dedicated emitter for App-to-App events */\n private appEvents = new EventEmitter();\n\n /**\n * Pending handlers waiting for AUDIO_STREAM_READY responses from the cloud.\n * Key: streamId, Value: handler function that receives the raw message.\n * Used by AudioOutputStream.waitForReady() to resolve the relay URL.\n * @internal\n */\n public _audioStreamReadyHandlers = new Map<string, (msg: any) => void>();\n\n /** Per-session ring buffer of recent log entries for incident telemetry uploads */\n private telemetryBuffer: TelemetryLogEntry[] = [];\n /** Interval that sends app-level pings to keep the app-ws connection alive.\n * Bidirectional traffic (ping → cloud, pong ← cloud) prevents load balancer\n * idle timeouts from killing the WebSocket. See: cloud/issues/046-sdk-app-ws-liveness */\n private pingInterval: ReturnType<typeof setInterval> | null = null;\n private static readonly PING_INTERVAL_MS = 15_000;\n\n constructor(private config: AppSessionConfig) {\n // Set defaults and merge with provided config\n this.config = {\n mentraOSWebsocketUrl: `ws://localhost:8002/app-ws`, // Use localhost as default\n autoReconnect: true, // Enable auto-reconnection by default for better reliability\n maxReconnectAttempts: 3, // Default to 3 reconnection attempts for better resilience\n reconnectDelay: 1000, // Start with 1 second delay (uses exponential backoff)\n ...config,\n };\n\n this.appServer = this.config.appServer;\n this.userId = this.config.userId;\n\n // Build session logger: child of appServer.logger (for BetterStack + console)\n // PLUS a telemetry stream that captures info+ entries into this session's\n // ring buffer. Because pino child loggers share the parent transport, we\n // instead create a fresh pino instance that:\n // 1. Forwards all writes to the parent (preserving BetterStack + console)\n // 2. Also tees into the per-session telemetry buffer\n // This means every session.logger.info/warn/error call — including all\n // module child loggers — is automatically captured for incident debugging.\n const parentLogger = this.appServer.logger.child({\n userId: this.config.userId,\n service: \"app-session\",\n });\n const telemetryStream = createTelemetryStream(this.telemetryBuffer, 500);\n // pino multistream: parent at debug (so BetterStack/console still control their own levels)\n // + telemetry stream at info (debug is too noisy for incident bundles)\n this.logger = pino(\n { level: \"debug\", base: null },\n pino.multistream([\n { stream: (parentLogger as any)[pino.symbols.streamSym] ?? process.stderr, level: \"debug\" },\n { stream: telemetryStream, level: \"info\" },\n ]),\n );\n\n // Make sure the URL is correctly formatted to prevent double protocol issues\n if (this.config.mentraOSWebsocketUrl) {\n try {\n const url = new URL(this.config.mentraOSWebsocketUrl);\n if (![\"ws:\", \"wss:\"].includes(url.protocol)) {\n // Fix URLs with incorrect protocol (e.g., 'ws://http://host')\n const fixedUrl = this.config.mentraOSWebsocketUrl.replace(/^ws:\\/\\/http:\\/\\//, \"ws://\");\n this.config.mentraOSWebsocketUrl = fixedUrl;\n this.logger.warn(`Fixed malformed WebSocket URL: ${fixedUrl}`);\n }\n } catch (error) {\n this.logger.error(error, `Invalid WebSocket URL format: ${this.config.mentraOSWebsocketUrl}`);\n }\n }\n\n this.logger.debug(\"App session initialized\");\n\n // Validate URL format - give early warning for obvious issues\n // Check URL format but handle undefined case\n if (this.config.mentraOSWebsocketUrl) {\n try {\n const url = new URL(this.config.mentraOSWebsocketUrl);\n if (![\"ws:\", \"wss:\"].includes(url.protocol)) {\n this.logger.error(\n { config: this.config },\n `Invalid WebSocket URL protocol: ${url.protocol}. Should be ws: or wss:`,\n );\n }\n } catch (error) {\n this.logger.error(\n error,\n `⚠️ [${this.config.packageName}] Invalid WebSocket URL format: ${this.config.mentraOSWebsocketUrl}`,\n );\n }\n }\n\n this.events = new EventManager(\n this.subscribe.bind(this),\n this.unsubscribe.bind(this),\n this.config.packageName,\n this.getHttpsServerUrl() || \"\",\n this.logger,\n );\n this.layouts = new LayoutManager(config.packageName, this.send.bind(this));\n\n // Initialize settings manager with all necessary parameters, including subscribeFn for MentraOS settings\n this.settings = new SettingsManager(\n this.settingsData,\n this.config.packageName,\n this.config.mentraOSWebsocketUrl,\n this.sessionId ?? undefined,\n async (streams: string[]) => {\n // NOTE: With Bug 007 fix, subscriptions are derived from EventManager.handlers\n // This subscribeFn is called by SettingsManager to auto-subscribe to streams for MentraOS settings\n // The actual subscription intent should be tracked via handlers, not a separate Set\n this.logger.debug({ streams: JSON.stringify(streams) }, `[AppSession] subscribeFn called for streams`);\n\n // Log current handler-based subscriptions for debugging\n const currentHandlerStreams = this.events.getRegisteredStreams();\n this.logger.debug(\n {\n requestedStreams: JSON.stringify(streams),\n currentHandlerStreams: JSON.stringify(currentHandlerStreams),\n },\n `[AppSession] subscribeFn: requested streams vs current handler streams`,\n );\n\n // Send subscription update if connected\n // Note: The actual subscriptions sent are derived from handlers\n if (this.ws?.readyState === 1) {\n this.updateSubscriptions();\n this.logger.debug(`[AppSession] Sent updated subscriptions to cloud (derived from handlers).`);\n } else {\n this.logger.debug(`[AppSession] WebSocket not open, will send subscriptions when connected.`);\n }\n },\n );\n\n // Initialize dashboard API with this session instance\n // Import DashboardManager dynamically to avoid circular dependency\n const { DashboardManager } = require(\"./dashboard\");\n this.dashboard = new DashboardManager(this);\n\n // Initialize camera module with session reference\n this.camera = new CameraModule(\n this,\n this.config.packageName,\n this.sessionId || \"unknown-session-id\",\n this.logger.child({ module: \"camera\" }),\n );\n\n // Initialize LED control module\n this.led = new LedModule(\n this,\n this.config.packageName,\n this.sessionId || \"unknown-session-id\",\n this.logger.child({ module: \"led\" }),\n );\n\n // Initialize audio module with session reference\n this.audio = new AudioManager(\n this,\n this.config.packageName,\n this.sessionId || \"unknown-session-id\",\n this.logger.child({ module: \"audio\" }),\n );\n\n this.simpleStorage = new SimpleStorage(this);\n this.device = { state: new DeviceState(this) };\n\n this.location = new LocationManager(this);\n }\n\n /**\n * Get the current session ID\n * @returns The current session ID or 'unknown-session-id' if not connected\n */\n getSessionId(): string {\n return this.sessionId || \"unknown-session-id\";\n }\n\n /**\n * Get the package name for this App\n * @returns The package name\n */\n getPackageName(): string {\n return this.config.packageName;\n }\n\n // =====================================\n // 🎮 Direct Event Handling Interface\n // =====================================\n\n /**\n * @deprecated Use session.events.onTranscription() instead\n */\n onTranscription(handler: (data: TranscriptionData) => void): () => void {\n return this.events.onTranscription(handler);\n }\n\n /**\n * 🌐 Listen for speech transcription events in a specific language\n * @param language - Language code (e.g., \"en-US\")\n * @param handler - Function to handle transcription data\n * @returns Cleanup function to remove the handler\n * @throws Error if language code is invalid\n * @deprecated Use session.events.onTranscriptionForLanguage() instead\n */\n onTranscriptionForLanguage(\n language: string,\n handler: (data: TranscriptionData) => void,\n disableLanguageIdentification = false,\n ): () => void {\n return this.events.onTranscriptionForLanguage(language, handler, disableLanguageIdentification);\n }\n\n /**\n * 🌐 Listen for speech translation events for a specific language pair\n * @param sourceLanguage - Source language code (e.g., \"es-ES\")\n * @param targetLanguage - Target language code (e.g., \"en-US\")\n * @param handler - Function to handle translation data\n * @returns Cleanup function to remove the handler\n * @throws Error if language codes are invalid\n * @deprecated Use session.events.onTranslationForLanguage() instead\n */\n onTranslationForLanguage(\n sourceLanguage: string,\n targetLanguage: string,\n handler: (data: TranslationData) => void,\n ): () => void {\n return this.events.ontranslationForLanguage(sourceLanguage, targetLanguage, handler);\n }\n\n /**\n * 👤 Listen for head position changes\n * @param handler - Function to handle head position updates\n * @returns Cleanup function to remove the handler\n * @deprecated Use session.events.onHeadPosition() instead\n */\n onHeadPosition(handler: (data: HeadPosition) => void): () => void {\n return this.events.onHeadPosition(handler);\n }\n\n /**\n * 🔘 Listen for hardware button press events\n * @param handler - Function to handle button events\n * @returns Cleanup function to remove the handler\n * @deprecated Use session.events.onButtonPress() instead\n */\n onButtonPress(handler: (data: ButtonPress) => void): () => void {\n return this.events.onButtonPress(handler);\n }\n\n /**\n * 👆 Listen for touch gesture events\n * @param gestureOrHandler - Gesture name or handler function\n * @param handler - Handler function (if first param is gesture name)\n * @returns Cleanup function\n *\n * @example\n * // Subscribe to all touch events\n * session.onTouchEvent((event) => console.log(event.gesture_name));\n *\n * // Subscribe to specific gesture\n * session.onTouchEvent(\"forward_swipe\", (event) => console.log(\"Forward swipe!\"));\n */\n onTouchEvent(\n gestureOrHandler: string | ((data: TouchEvent) => void),\n handler?: (data: TouchEvent) => void,\n ): () => void {\n return this.events.onTouchEvent(gestureOrHandler as any, handler as any);\n }\n\n /**\n * 👆 Subscribe to multiple touch gestures\n * @param gestures - Array of gesture names\n * @returns Cleanup function that unsubscribes from all\n *\n * @example\n * session.subscribeToGestures([\"forward_swipe\", \"backward_swipe\"]);\n */\n subscribeToGestures(gestures: string[]): () => void {\n gestures.forEach((gesture) => {\n const stream = createTouchEventStream(gesture);\n this.subscribe(stream);\n });\n\n return () => {\n gestures.forEach((gesture) => {\n const stream = createTouchEventStream(gesture);\n this.unsubscribe(stream);\n });\n };\n }\n\n /**\n * 📱 Listen for phone notification events\n * @param handler - Function to handle notifications\n * @returns Cleanup function to remove the handler\n * @deprecated Use session.events.onPhoneNotifications() instead\n */\n onPhoneNotifications(handler: (data: PhoneNotification) => void): () => void {\n readNotificationWarnLog(this.getHttpsServerUrl() || \"\", this.getPackageName(), \"onPhoneNotifications\");\n return this.events.onPhoneNotifications(handler);\n }\n\n /**\n * 📱 Listen for phone notification dismissed events\n * @param handler - Function to handle notification dismissal data\n * @returns Cleanup function to remove the handler\n * @deprecated Use session.events.onPhoneNotificationDismissed() instead\n */\n onPhoneNotificationDismissed(handler: (data: PhoneNotificationDismissed) => void): () => void {\n return this.events.onPhoneNotificationDismissed(handler);\n }\n\n /**\n * 📡 Listen for VPS coordinates updates\n * @param handler - Function to handle VPS coordinates\n * @returns Cleanup function to remove the handler\n * @deprecated Use session.events.onVpsCoordinates() instead\n */\n onVpsCoordinates(handler: (data: VpsCoordinates) => void): () => void {\n this.subscribe(StreamType.VPS_COORDINATES);\n return this.events.onVpsCoordinates(handler);\n }\n\n /**\n * 📸 Listen for photo responses\n * @param handler - Function to handle photo response data\n * @returns Cleanup function to remove the handler\n * @deprecated Use session.events.onPhotoTaken() instead\n */\n onPhotoTaken(handler: (data: PhotoTaken) => void): () => void {\n this.subscribe(StreamType.PHOTO_TAKEN);\n return this.events.onPhotoTaken(handler);\n }\n\n // =====================================\n // 📡 Pub/Sub Interface\n // =====================================\n\n /**\n * 📬 Subscribe to a specific event stream\n * @param sub - A string or a rich subscription object\n */\n subscribe(sub: SubscriptionRequest): void {\n let type: ExtendedStreamType;\n let rate: string | undefined;\n\n if (typeof sub === \"string\") {\n type = sub;\n } else {\n // it's a LocationStreamRequest object\n type = sub.stream;\n rate = sub.rate;\n }\n\n if (APP_TO_APP_EVENT_TYPES.includes(type as string)) {\n this.logger.warn(\n `[AppSession] Attempted to subscribe to App-to-App event type '${type}', which is not a valid stream. Use the event handler (e.g., onAppMessage) instead.`,\n );\n return;\n }\n\n // NOTE: We no longer maintain this.subscriptions - subscriptions are derived from handlers\n // This prevents drift between handlers and subscriptions (Bug 007 fix)\n // The EventManager.addHandler() already tracks the subscription intent via handlers\n\n if (rate) {\n this.streamRates.set(type, rate);\n }\n\n if (this.ws?.readyState === 1) {\n this.updateSubscriptions();\n }\n }\n\n /**\n * 📭 Unsubscribe from a specific event stream\n * @param sub - The subscription to remove\n */\n unsubscribe(sub: SubscriptionRequest): void {\n let type: ExtendedStreamType;\n if (typeof sub === \"string\") {\n type = sub;\n } else {\n type = sub.stream;\n }\n\n if (APP_TO_APP_EVENT_TYPES.includes(type as string)) {\n this.logger.warn(\n `[AppSession] Attempted to unsubscribe from App-to-App event type '${type}', which is not a valid stream.`,\n );\n return;\n }\n // NOTE: We no longer maintain this.subscriptions - subscriptions are derived from handlers\n // The EventManager.removeHandler() already tracks the unsubscription intent\n\n this.streamRates.delete(type); // also remove from our rate map\n if (this.ws?.readyState === 1) {\n this.updateSubscriptions();\n }\n }\n\n /**\n * 🎯 Generic event listener (pub/sub style)\n * @param event - Event name to listen for\n * @param handler - Event handler function\n */\n on<T extends ExtendedStreamType>(event: T, handler: (data: EventData<T>) => void): () => void {\n return this.events.on(event, handler);\n }\n\n // =====================================\n // 🔌 Connection Management\n // =====================================\n\n /**\n * 🚀 Connect to MentraOS Cloud\n * @param sessionId - Unique session identifier\n * @returns Promise that resolves when connected\n */\n async connect(sessionId: string): Promise<void> {\n this.sessionId = sessionId;\n\n // Configure settings API client with the WebSocket URL and session ID\n // This allows settings to be fetched from the correct server\n this.settings.configureApiClient(this.config.packageName, this.config.mentraOSWebsocketUrl || \"\", sessionId);\n\n // Update the sessionId in the camera module\n if (this.camera) {\n this.camera.updateSessionId(sessionId);\n }\n\n // Update the sessionId in the audio module\n if (this.audio) {\n this.audio.updateSessionId(sessionId);\n }\n\n return new Promise((resolve, reject) => {\n try {\n // Stop ping interval before replacing the WebSocket.\n // This prevents a stale interval from a previous connection running\n // during the reconnect window. startPingInterval() also calls this,\n // but clearing here means no pings fire on a dead socket at all.\n this.stopPingInterval();\n\n // Clear previous resources if reconnecting\n if (this.ws) {\n // Don't call full dispose() as that would clear subscriptions\n if (this.ws.readyState !== 3) {\n // 3 = CLOSED\n this.ws.close();\n }\n this.ws = null;\n }\n\n // Validate WebSocket URL before attempting connection\n if (!this.config.mentraOSWebsocketUrl) {\n this.logger.error(\"WebSocket URL is missing or undefined\");\n reject(new MentraConnectionError(\"WebSocket URL is required\"));\n return;\n }\n\n this.logger.debug(`Connecting to ${this.config.mentraOSWebsocketUrl}`);\n\n // Create connection with error handling\n this.ws = new WebSocket(this.config.mentraOSWebsocketUrl);\n\n // Track WebSocket for automatic cleanup\n this.resources.track(() => {\n if (this.ws && this.ws.readyState !== 3) {\n // 3 = CLOSED\n this.ws.close();\n }\n });\n\n this.ws.on(\"open\", () => {\n try {\n this.sendConnectionInit();\n } catch (error: unknown) {\n this.logger.error(error, \"Error during connection initialization\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\"error\", new MentraConnectionError(`Connection initialization failed: ${errorMessage}`));\n reject(error instanceof Error ? error : new MentraConnectionError(String(error)));\n }\n });\n\n // Message handler with comprehensive error recovery\n const messageHandler = async (data: Buffer | string, isBinary: boolean) => {\n try {\n // Handle binary messages (typically audio data)\n if (isBinary && Buffer.isBuffer(data)) {\n try {\n // Validate buffer before processing\n if (data.length === 0) {\n this.events.emit(\"error\", new MentraError(\"Received empty binary data\", \"EMPTY_DATA\"));\n return;\n }\n\n // Convert Node.js Buffer to ArrayBuffer safely\n const arrayBuf: ArrayBufferLike = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);\n\n // Create AUDIO_CHUNK event message with validation\n const audioChunk: AudioChunk = {\n type: StreamType.AUDIO_CHUNK,\n arrayBuffer: arrayBuf,\n timestamp: new Date(), // Ensure timestamp is present\n };\n\n this.handleMessage(audioChunk);\n return;\n } catch (error: unknown) {\n this.logger.error(error, \"Error processing binary message:\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\n \"error\",\n new MentraError(`Failed to process binary message: ${errorMessage}`, \"PARSE_ERROR\"),\n );\n return;\n }\n }\n\n // Handle ArrayBuffer data type directly\n if (data instanceof ArrayBuffer) {\n return;\n }\n\n // Handle JSON messages with validation\n try {\n // Convert string data to JSON safely\n let jsonData: string;\n if (typeof data === \"string\") {\n jsonData = data;\n } else if (Buffer.isBuffer(data)) {\n jsonData = data.toString(\"utf8\");\n } else {\n throw new Error(\"Unknown message format\");\n }\n\n // Validate JSON before parsing\n if (!jsonData || jsonData.trim() === \"\") {\n this.events.emit(\"error\", new MentraError(\"Received empty JSON message\", \"PARSE_ERROR\"));\n return;\n }\n\n // Parse JSON with error handling\n const message = JSON.parse(jsonData) as CloudToAppMessage;\n\n // Basic schema validation\n if (!message || typeof message !== \"object\" || !(\"type\" in message)) {\n this.events.emit(\"error\", new MentraError(\"Malformed message: missing type property\", \"PARSE_ERROR\"));\n return;\n }\n\n // Process the validated message\n this.handleMessage(message);\n } catch (error: unknown) {\n this.logger.error(error, \"JSON parsing error\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\"error\", new MentraError(`Failed to parse message: ${errorMessage}`, \"PARSE_ERROR\"));\n }\n } catch (error: unknown) {\n // Final catch - should never reach here if individual handlers work correctly\n this.logger.error({ error }, \"Unhandled message processing error\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\"error\", new MentraError(`Unhandled message error: ${errorMessage}`, \"INTERNAL_ERROR\"));\n }\n };\n\n this.ws.on(\"message\", messageHandler);\n\n // Track event handler removal for automatic cleanup\n this.resources.track(() => {\n if (this.ws) {\n this.ws.off(\"message\", messageHandler);\n }\n });\n\n // Connection closure handler\n const closeHandler = (code: number, reason: string) => {\n const reasonStr = reason ? `: ${reason}` : \"\";\n const closeInfo = `Connection closed (code: ${code})${reasonStr}`;\n\n // Emit the disconnected event with structured data for better handling\n this.events.emit(\"disconnected\", {\n message: closeInfo,\n code: code,\n reason: reason || \"\",\n wasClean: code === 1000 || code === 1001,\n });\n\n // Only attempt reconnection for abnormal closures\n // https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code\n // 1000 (Normal Closure) and 1001 (Going Away) are normal\n // 1002-1015 are abnormal, and reason \"App stopped\" means intentional closure\n // 1008 usually when the userSession no longer exists on server. i.e user disconnected from cloud.\n const isNormalClosure = code === 1000 || code === 1001 || code === 1008;\n const isManualStop = reason && reason.includes(\"App stopped\");\n const isUserSessionEnded = reason && reason.includes(\"User session ended\");\n\n this.logger.debug(`WebSocket closed (code: ${code}${reasonStr})`);\n\n // Stop ping interval immediately — the socket is closed so pings are pointless.\n // connect() will restart it on reconnect; disconnect() would also clear it,\n // but stopping here prevents an orphaned interval if neither is called.\n this.stopPingInterval();\n\n // If user session ended, mark as terminated to prevent any future reconnection\n if (isUserSessionEnded) {\n this.terminated = true;\n this.logger.debug(\"User session ended — marked as terminated, no reconnection\");\n }\n\n if (!isNormalClosure && !isManualStop && !this.terminated) {\n this.logger.debug(\"Abnormal closure detected, attempting reconnection\");\n this.handleReconnection();\n } else {\n this.logger.debug(\"Normal closure, not reconnecting\");\n }\n\n // if user session ended, then trigger onStop.\n if (isUserSessionEnded) {\n this.logger.debug(\"User session ended — emitting disconnected event\");\n // Emit a disconnected event with a special flag to indicate session end\n // This will be caught by AppServer which will call the onStop callback\n const disconnectInfo = {\n message: \"User session ended\",\n code: 1000, // Normal closure\n reason: \"User session ended\",\n wasClean: true,\n permanent: true, // This is permanent - no reconnection\n sessionEnded: true, // Special flag to indicate session disposal\n };\n this.events.emit(\"disconnected\", disconnectInfo);\n }\n };\n\n this.ws.on(\"close\", closeHandler);\n\n // Track event handler removal\n this.resources.track(() => {\n if (this.ws) {\n this.ws.off(\"close\", closeHandler);\n }\n });\n\n // Connection error handler\n const errorHandler = (error: Error) => {\n this.logger.error(error, \"WebSocket error\");\n this.events.emit(\"error\", new MentraConnectionError(error.message));\n };\n\n this.ws.on(\"error\", (error: Error) => {\n errorHandler(error);\n });\n\n // Track event handler removal\n this.resources.track(() => {\n if (this.ws) {\n this.ws.off(\"error\", errorHandler);\n }\n });\n\n // Set up connection success handler\n const connectedCleanup = this.events.onConnected(() => resolve());\n\n // Track event handler removal\n this.resources.track(connectedCleanup);\n\n // Connection timeout with configurable duration\n const timeoutMs = 5000; // 5 seconds default\n const connectionTimeout = this.resources.setTimeout(() => {\n // Use tracked timeout that will be auto-cleared\n this.logger.error(\n {\n config: this.config,\n sessionId: this.sessionId,\n timeoutMs,\n },\n `Connection timeout after ${timeoutMs}ms`,\n );\n\n const err = new MentraTimeoutError(`Connection timeout after ${timeoutMs}ms`);\n this.events.emit(\"error\", err);\n reject(err);\n }, timeoutMs);\n\n // Clear timeout on successful connection\n const timeoutCleanup = this.events.onConnected(() => {\n clearTimeout(connectionTimeout);\n resolve();\n });\n\n // Track event handler removal\n this.resources.track(timeoutCleanup);\n } catch (error: unknown) {\n this.logger.error(error, \"Connection setup error\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new MentraConnectionError(`Failed to setup connection: ${errorMessage}`));\n }\n });\n }\n\n /**\n * 🔄 Release ownership of this session to allow clean handoff\n * Call this before connecting to a different cloud instance or shutting down cleanly.\n * This signals to the cloud that no resurrection is needed.\n *\n * @param reason - Why ownership is being released\n */\n async releaseOwnership(reason: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\"): Promise<void> {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n this.logger.debug(`[${this.config.packageName}] Cannot release ownership - WebSocket not open`);\n return;\n }\n\n const message: OwnershipReleaseMessage = {\n type: AppToCloudMessageType.OWNERSHIP_RELEASE,\n packageName: this.config.packageName,\n sessionId: this.sessionId || \"\",\n reason,\n timestamp: new Date(),\n };\n\n this.logger.info(\n { reason, sessionId: this.sessionId },\n `🔄 [${this.config.packageName}] Releasing ownership: ${reason}`,\n );\n\n this.send(message);\n\n // Small delay to ensure message is sent before any subsequent disconnect\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n /**\n * 👋 Disconnect from MentraOS Cloud\n * Flushes any pending SimpleStorage writes before closing\n *\n * @param options - Optional disconnect options\n * @param options.releaseOwnership - If true, send OWNERSHIP_RELEASE before disconnecting (enables clean handoff)\n * @param options.reason - Reason for ownership release (required if releaseOwnership is true)\n */\n async disconnect(options?: {\n releaseOwnership?: boolean;\n reason?: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\";\n }): Promise<void> {\n // Release ownership if requested (for clean handoffs)\n if (options?.releaseOwnership && options?.reason) {\n await this.releaseOwnership(options.reason);\n }\n\n // Flush any pending SimpleStorage writes before closing\n try {\n await this.simpleStorage.flush();\n console.log(\"SimpleStorage flushed on disconnect\");\n } catch (error) {\n console.error(\"Error flushing SimpleStorage on disconnect:\", error);\n // Continue with disconnect even if flush fails\n }\n\n // Clean up camera module first\n if (this.camera) {\n this.camera.cancelAllRequests();\n }\n\n // Clean up audio module\n if (this.audio) {\n this.audio.cancelAllRequests();\n }\n\n // Stop ping interval before disposing resources\n this.stopPingInterval();\n\n // Use the resource tracker to clean up everything\n this.resources.dispose();\n\n // Clean up additional resources not handled by the tracker\n this.ws = null;\n this.sessionId = null;\n // REMOVED: this.subscriptions.clear()\n // We no longer clear subscriptions here - they are derived from handlers\n // This is the key fix for Bug 007: clearing subscriptions here caused\n // empty subscription updates on reconnect when handlers still existed\n // See: cloud/issues/006-captions-and-apps-stopping/011-sdk-subscription-architecture-mismatch.md\n this.reconnectAttempts = 0;\n }\n\n /**\n * 🛠️ Get all current user settings\n * @returns A copy of the current settings array\n * @deprecated Use session.settings.getAll() instead\n */\n getSettings(): AppSettings {\n return this.settings.getAll();\n }\n\n /**\n * 🔍 Get a specific setting value by key\n * @param key The setting key to look for\n * @returns The setting's value, or undefined if not found\n * @deprecated Use session.settings.get(key) instead\n */\n getSetting<T>(key: string): T | undefined {\n return this.settings.get<T>(key);\n }\n\n /**\n * ⚙️ Configure settings-based subscription updates\n * This allows Apps to automatically update their subscriptions when certain settings change\n * @param options Configuration options for settings-based subscriptions\n */\n setSubscriptionSettings(options: {\n updateOnChange: string[]; // Setting keys that should trigger subscription updates\n handler: (settings: AppSettings) => ExtendedStreamType[]; // Handler that returns new subscriptions\n }): void {\n this.shouldUpdateSubscriptionsOnSettingsChange = true;\n this.subscriptionUpdateTriggers = options.updateOnChange;\n this.subscriptionSettingsHandler = options.handler;\n\n // If we already have settings, update subscriptions immediately\n if (this.settingsData.length > 0) {\n this.updateSubscriptionsFromSettings();\n }\n }\n\n /**\n * 🔄 Update subscriptions based on current settings\n * Called automatically when relevant settings change\n */\n private updateSubscriptionsFromSettings(): void {\n if (!this.subscriptionSettingsHandler) return;\n\n try {\n // Get desired subscriptions from settings handler\n const settingsSubscriptions = this.subscriptionSettingsHandler(this.settingsData);\n\n // NOTE: Settings-based subscriptions work differently from handler-based subscriptions\n // With the Bug 007 fix, subscriptions are now derived from EventManager.handlers\n // Apps using setSubscriptionSettings() should ensure their settings correspond to\n // registered handlers for the subscriptions to take effect.\n //\n // Log if there's a mismatch (for debugging during migration)\n const handlerStreams = this.events.getRegisteredStreams();\n if (settingsSubscriptions.length !== handlerStreams.length) {\n this.logger.warn(\n {\n settingsSubscriptions: JSON.stringify(settingsSubscriptions),\n handlerStreams: JSON.stringify(handlerStreams),\n },\n `[AppSession] Settings-based subscriptions (${settingsSubscriptions.length}) differ from handler-based subscriptions (${handlerStreams.length}). ` +\n `Subscriptions are now derived from handlers. Ensure handlers are registered for desired streams.`,\n );\n }\n\n // Send subscription update to cloud if connected\n // Note: updateSubscriptions() derives from handlers, so settings-based apps\n // should ensure their settings correspond to registered handlers\n if (this.ws && this.ws.readyState === 1) {\n this.updateSubscriptions();\n }\n } catch (error: unknown) {\n this.logger.error(error, \"Error updating subscriptions from settings\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\n \"error\",\n new MentraError(`Failed to update subscriptions: ${errorMessage}`, \"SUBSCRIPTION_ERROR\"),\n );\n }\n }\n\n /**\n * 🧪 For testing: Update settings locally\n * In normal operation, settings come from the cloud\n * @param newSettings The new settings to apply\n */\n updateSettingsForTesting(newSettings: AppSettings): void {\n this.settingsData = newSettings;\n\n // Update the settings manager with the new settings\n this.settings.updateSettings(newSettings);\n\n // Emit update event for backwards compatibility\n this.events.emit(\"settings_update\", this.settingsData);\n\n // Check if we should update subscriptions\n if (this.shouldUpdateSubscriptionsOnSettingsChange) {\n this.updateSubscriptionsFromSettings();\n }\n }\n\n /**\n * 📝 Load configuration from a JSON file\n * @param jsonData JSON string containing App configuration\n * @returns The loaded configuration\n * @throws Error if the configuration is invalid\n */\n loadConfigFromJson(jsonData: string): AppConfig {\n try {\n const parsedConfig = JSON.parse(jsonData);\n\n if (validateAppConfig(parsedConfig)) {\n this.appConfig = parsedConfig;\n return parsedConfig;\n } else {\n throw new Error(\"Invalid App configuration format\");\n }\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load App configuration: ${errorMessage}`);\n }\n }\n\n /**\n * 📋 Get the loaded App configuration\n * @returns The current App configuration or null if not loaded\n */\n getConfig(): AppConfig | null {\n return this.appConfig;\n }\n\n /**\n * 🔌 Get the WebSocket server URL for this session\n * @returns The WebSocket server URL used by this session\n */\n getServerUrl(): string | undefined {\n return this.config.mentraOSWebsocketUrl;\n }\n\n public getHttpsServerUrl(): string | undefined {\n if (!this.config.mentraOSWebsocketUrl) {\n return undefined;\n }\n return AppSession.convertToHttps(this.config.mentraOSWebsocketUrl);\n }\n\n private static convertToHttps(rawUrl: string | undefined): string {\n if (!rawUrl) return \"\";\n // Remove ws:// or wss://\n let url = rawUrl.replace(/^wss?:\\/\\//, \"\");\n // Remove trailing /app-ws\n url = url.replace(/\\/app-ws$/, \"\");\n // Prepend https://\n return `https://${url}`;\n }\n\n /**\n * 🔍 Get default settings from the App configuration\n * @returns Array of settings with default values\n * @throws Error if configuration is not loaded\n */\n getDefaultSettings(): AppSettings {\n if (!this.appConfig) {\n throw new Error(\"App configuration not loaded. Call loadConfigFromJson first.\");\n }\n\n return this.appConfig.settings\n .filter((s: AppSetting | { type: \"group\"; title: string }): s is AppSetting => s.type !== \"group\")\n .map((s: AppSetting) => ({\n ...s,\n value: s.defaultValue, // Set value to defaultValue\n }));\n }\n\n /**\n * 🔍 Get setting schema from configuration\n * @param key Setting key to look up\n * @returns The setting schema or undefined if not found\n */\n getSettingSchema(key: string): AppSetting | undefined {\n if (!this.appConfig) return undefined;\n\n const setting = this.appConfig.settings.find(\n (s: AppSetting | { type: \"group\"; title: string }) => s.type !== \"group\" && \"key\" in s && s.key === key,\n );\n\n return setting as AppSetting | undefined;\n }\n\n /**\n * 📡 Get WiFi connection status of glasses\n * @returns WiFi status object or null if glasses don't support WiFi or status not available\n */\n getWifiStatus(): { connected: boolean; ssid?: string | null } | null {\n if (!this.capabilities?.hasWifi) {\n return null;\n }\n return this.glassesConnectionState?.wifi || null;\n }\n\n /**\n * ✅ Check if glasses are connected to WiFi\n * @returns true if connected to WiFi, false otherwise\n */\n isWifiConnected(): boolean {\n return this.getWifiStatus()?.connected === true;\n }\n\n /**\n * 🌐 Request WiFi setup from mobile app\n * Triggers a popup on the mobile app that allows user to set up WiFi on glasses\n * @param reason Optional reason message to display to the user\n */\n requestWifiSetup(reason?: string): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n throw new Error(\"Not connected to MentraOS Cloud\");\n }\n\n const message: RequestWifiSetup = {\n type: AppToCloudMessageType.REQUEST_WIFI_SETUP,\n packageName: this.config.packageName,\n sessionId: this.sessionId || \"\",\n reason,\n timestamp: new Date(),\n };\n\n this.send(message);\n }\n\n /**\n * 👂 Listen for glasses connection state changes (includes WiFi status)\n * @param handler Callback function to handle connection state updates\n * @returns Cleanup function to remove the listener\n */\n onGlassesConnectionState(handler: (state: any) => void): () => void {\n return this.events.on(StreamType.GLASSES_CONNECTION_STATE, handler);\n }\n\n // =====================================\n // 🔧 Private Methods\n // =====================================\n\n /**\n * 📨 Handle incoming messages from cloud\n */\n private handleMessage(message: CloudToAppMessage): void {\n try {\n // Validate message before processing\n if (!this.validateMessage(message)) {\n this.events.emit(\"error\", new MentraError(\"Invalid message format received\", \"PARSE_ERROR\"));\n return;\n }\n\n // Handle binary data (audio or video)\n if (message instanceof ArrayBuffer) {\n this.handleBinaryMessage(message);\n return;\n }\n\n // Using type guards to determine message type and safely handle each case\n try {\n if (isAppConnectionAck(message)) {\n // Get settings from connection acknowledgment\n const receivedSettings = message.settings || [];\n this.settingsData = receivedSettings;\n\n // Store config if provided\n if (message.config && validateAppConfig(message.config)) {\n this.appConfig = message.config;\n }\n\n // Use default settings from config if no settings were provided\n if (receivedSettings.length === 0 && this.appConfig) {\n try {\n this.settingsData = this.getDefaultSettings();\n } catch (error) {\n this.logger.warn(error, \"Failed to load default settings from config:\");\n }\n }\n\n // Update the settings manager with the new settings\n this.settings.updateSettings(this.settingsData);\n\n // Handle MentraOS system settings if provided\n this.logger.debug(\n { mentraosSettings: JSON.stringify(message.mentraosSettings) },\n `[AppSession] CONNECTION_ACK mentraosSettings}`,\n );\n if (message.mentraosSettings) {\n this.logger.info(\n { mentraosSettings: JSON.stringify(message.mentraosSettings) },\n `[AppSession] Calling updatementraosSettings with`,\n );\n this.settings.updateMentraosSettings(message.mentraosSettings);\n } else {\n this.logger.warn(`[AppSession] CONNECTION_ACK message missing mentraosSettings field`);\n }\n\n // Handle device capabilities if provided\n if (message.capabilities) {\n this.capabilities = message.capabilities;\n this.logger.info(`[AppSession] Device capabilities loaded for model: ${message.capabilities.modelName}`);\n } else {\n this.logger.debug(`[AppSession] No capabilities provided in CONNECTION_ACK`);\n }\n\n // Emit connected event with settings\n this.events.emit(\"connected\", this.settingsData);\n\n // Start app-level ping interval to keep the app-ws connection alive.\n // The SDK sends {type:\"ping\"} every 15s; the cloud responds {type:\"pong\"}.\n // Both directions produce traffic, satisfying infra bidirectional-traffic\n // requirements that prevent load balancer idle timeouts.\n // Only new-SDK apps send pings — old 2.x apps are unaffected.\n // See: cloud/issues/046-sdk-app-ws-liveness\n this.startPingInterval();\n\n // Log once to confirm Bug 007 fix is active (subscriptions derived from handlers)\n const handlerCount = this.events.getRegisteredStreams().length;\n this.logger.info(\n { patch: SDK_SUBSCRIPTION_PATCH, handlerCount },\n `[AppSession] 🔧 SDK Patch Active: ${SDK_SUBSCRIPTION_PATCH} - Subscriptions derived from ${handlerCount} handler(s)`,\n );\n\n // Update subscriptions (normal flow)\n this.updateSubscriptions();\n\n // If settings-based subscriptions are enabled, update those too\n if (this.shouldUpdateSubscriptionsOnSettingsChange && this.settingsData.length > 0) {\n this.updateSubscriptionsFromSettings();\n }\n } else if (isAppConnectionError(message) || message.type === \"connection_error\") {\n // Handle both App-specific connection_error and standard connection_error\n const errorMessage = message.message || \"Unknown connection error\";\n this.events.emit(\"error\", new MentraAuthError(errorMessage));\n } else if (message.type === StreamType.AUDIO_CHUNK) {\n // Check if we have a handler registered for AUDIO_CHUNK (derived from handlers)\n const hasAudioHandler = this.events.getRegisteredStreams().includes(StreamType.AUDIO_CHUNK);\n if (hasAudioHandler) {\n // Only process if we're subscribed to avoid unnecessary processing\n this.events.emit(StreamType.AUDIO_CHUNK, message);\n }\n } else if (isDataStream(message) && message.streamType === StreamType.GLASSES_CONNECTION_STATE) {\n // Store latest glasses connection state (includes WiFi info)\n this.glassesConnectionState = message.data;\n\n // Emit to subscribed listeners (check derived from handlers)\n const hasGlassesStateHandler = this.events\n .getRegisteredStreams()\n .includes(StreamType.GLASSES_CONNECTION_STATE);\n if (hasGlassesStateHandler) {\n const sanitizedData = this.sanitizeEventData(\n StreamType.GLASSES_CONNECTION_STATE,\n message.data,\n ) as EventData<typeof StreamType.GLASSES_CONNECTION_STATE>;\n this.events.emit(StreamType.GLASSES_CONNECTION_STATE, sanitizedData);\n }\n } else if (isDataStream(message)) {\n // Ensure streamType exists before emitting the event\n const messageStreamType = message.streamType as ExtendedStreamType;\n // if (message.streamType === StreamType.TRANSCRIPTION) {\n // const transcriptionData = message.data as TranscriptionData;\n // if (transcriptionData.transcribeLanguage) {\n // messageStreamType = createTranscriptionStream(transcriptionData.transcribeLanguage) as ExtendedStreamType;\n // }\n // } else if (message.streamType === StreamType.TRANSLATION) {\n // const translationData = message.data as TranslationData;\n // if (translationData.transcribeLanguage && translationData.translateLanguage) {\n // messageStreamType = createTranslationStream(translationData.transcribeLanguage, translationData.translateLanguage) as ExtendedStreamType;\n // }\n // }\n\n // Check if we have a handler registered for this stream type (derived from handlers)\n const hasHandler = this.events.getRegisteredStreams().includes(messageStreamType);\n if (messageStreamType && hasHandler) {\n const sanitizedData = this.sanitizeEventData(messageStreamType, message.data) as EventData<\n typeof messageStreamType\n >;\n this.events.emit(messageStreamType, sanitizedData);\n }\n } else if (isStreamStatus(message)) {\n // Emit as a standard stream event if subscribed (check derived from handlers)\n const hasStreamHandler = this.events.getRegisteredStreams().includes(StreamType.STREAM_STATUS);\n if (hasStreamHandler) {\n this.events.emit(StreamType.STREAM_STATUS, message);\n }\n\n // Update camera module's internal stream state\n this.camera.updateStreamState(message);\n } else if (isManagedStreamStatus(message)) {\n // Emit as a standard stream event if subscribed (check derived from handlers)\n const hasManagedStreamHandler = this.events.getRegisteredStreams().includes(StreamType.MANAGED_STREAM_STATUS);\n if (hasManagedStreamHandler) {\n this.events.emit(StreamType.MANAGED_STREAM_STATUS, message);\n }\n\n // Update camera module's managed stream state\n this.camera.handleManagedStreamStatus(message);\n } else if (isStreamStatusCheckResponse(message)) {\n // Handle stream status check response\n // This is a direct response, not a subscription-based event\n this.camera.handleStreamCheckResponse(message);\n } else if (isSettingsUpdate(message)) {\n // Store previous settings to check for changes\n const _prevSettings = [...this.settingsData];\n\n // Update internal settings storage\n this.settingsData = message.settings || [];\n\n // Update the settings manager with the new settings\n const changes = this.settings.updateSettings(this.settingsData);\n\n // Emit settings update event (for backwards compatibility)\n this.events.emit(\"settings_update\", this.settingsData);\n\n // --- MentraOS settings update logic ---\n // If the message.settings looks like MentraOS settings (object with known keys), update mentraosSettings\n if (message.settings && typeof message.settings === \"object\") {\n this.settings.updateMentraosSettings(message.settings);\n }\n\n // Check if we should update subscriptions\n if (this.shouldUpdateSubscriptionsOnSettingsChange) {\n // Check if any subscription trigger settings changed\n const shouldUpdateSubs = this.subscriptionUpdateTriggers.some((key) => {\n return key in changes;\n });\n\n if (shouldUpdateSubs) {\n this.updateSubscriptionsFromSettings();\n }\n }\n } else if (isCapabilitiesUpdate(message)) {\n // Update device capabilities\n const capabilitiesMessage = message as CapabilitiesUpdate;\n this.capabilities = capabilitiesMessage.capabilities;\n this.logger.info(\n capabilitiesMessage.capabilities,\n `[AppSession] Capabilities updated for model: ${capabilitiesMessage.modelName}`,\n );\n\n // Emit capabilities update event for applications to handle\n this.events.emit(\"capabilities_update\", {\n capabilities: capabilitiesMessage.capabilities,\n modelName: capabilitiesMessage.modelName,\n timestamp: capabilitiesMessage.timestamp,\n });\n } else if (isDeviceStateUpdate(message)) {\n // Update device state observables\n this.device.state.updateFromMessage(message.state);\n\n this.logger.debug(\n {\n changedFields: Object.keys(message.state),\n fullSnapshot: message.fullSnapshot,\n },\n `[AppSession] Device state updated via WebSocket`,\n );\n } else if (isAppStopped(message)) {\n const reason = message.reason || \"unknown\";\n const displayReason = `App stopped: ${reason}`;\n\n // Don't emit disconnected event here - let the WebSocket close handler do it\n // This prevents duplicate disconnected events when the session is disposed\n this.logger.info(`📤 [${this.config.packageName}] Received APP_STOPPED message: ${displayReason}`);\n\n // Clear reconnection state\n this.reconnectAttempts = 0;\n }\n // Handle dashboard mode changes\n else if (isDashboardModeChanged(message)) {\n try {\n // Use proper type\n const mode = message.mode || \"none\";\n\n // Update dashboard state in the API\n if (this.dashboard && \"content\" in this.dashboard) {\n (this.dashboard.content as any).setCurrentMode(mode);\n }\n } catch (error) {\n this.logger.error(error, \"Error handling dashboard mode change\");\n }\n }\n // Handle always-on dashboard state changes\n else if (isDashboardAlwaysOnChanged(message)) {\n try {\n // Use proper type\n const enabled = !!message.enabled;\n\n // Update dashboard state in the API\n if (this.dashboard && \"content\" in this.dashboard) {\n (this.dashboard.content as any).setAlwaysOnEnabled(enabled);\n }\n } catch (error) {\n this.logger.error(error, \"Error handling dashboard always-on change\");\n }\n }\n // Handle custom messages\n else if (message.type === CloudToAppMessageType.CUSTOM_MESSAGE) {\n this.events.emit(\"custom_message\", message);\n return;\n }\n // Handle App-to-App communication messages\n else if ((message as any).type === \"app_message_received\") {\n this.appEvents.emit(\"app_message_received\", message as any);\n } else if ((message as any).type === \"app_user_joined\") {\n this.appEvents.emit(\"app_user_joined\", message as any);\n } else if ((message as any).type === \"app_user_left\") {\n this.appEvents.emit(\"app_user_left\", message as any);\n } else if ((message as any).type === \"app_room_updated\") {\n this.appEvents.emit(\"app_room_updated\", message as any);\n } else if ((message as any).type === \"app_direct_message_response\") {\n const response = message as any;\n if (response.messageId && this.pendingDirectMessages.has(response.messageId)) {\n const { resolve } = this.pendingDirectMessages.get(response.messageId)!;\n resolve(response.success);\n this.pendingDirectMessages.delete(response.messageId);\n }\n } else if (message.type === \"augmentos_settings_update\") {\n const mentraosMsg = message as MentraosSettingsUpdate;\n if (mentraosMsg.settings && typeof mentraosMsg.settings === \"object\") {\n this.settings.updateMentraosSettings(mentraosMsg.settings);\n }\n }\n // Handle 'connection_error' as a specific case if cloud sends this string literal\n else if ((message as any).type === \"connection_error\") {\n // Treat 'connection_error' (string literal) like AppConnectionError\n // This handles cases where the cloud might send the type as a direct string\n // instead of the enum's 'tpa_connection_error' value.\n const errorMessage = (message as any).message || \"Unknown connection error (type: connection_error)\";\n this.logger.warn(\n `Received 'connection_error' type directly. Consider aligning cloud to send 'tpa_connection_error'. Message: ${errorMessage}`,\n );\n this.events.emit(\"error\", new MentraConnectionError(errorMessage));\n } else if (message.type === \"permission_error\") {\n // Handle permission errors from cloud\n this.logger.warn(\n {\n message: message.message,\n details: message.details,\n detailsCount: message.details?.length || 0,\n rejectedStreams: message.details?.map((d) => d.stream) || [],\n },\n \"Permission error received:\",\n );\n\n // Emit permission error event for application handling\n this.events.emit(\"permission_error\", {\n message: message.message,\n details: message.details,\n timestamp: message.timestamp,\n });\n\n // Optionally emit individual permission denied events for each stream\n message.details?.forEach((detail) => {\n this.events.emit(\"permission_denied\", {\n stream: detail.stream,\n requiredPermission: detail.requiredPermission,\n message: detail.message,\n });\n });\n } else if (message.type === \"audio_stream_ready\") {\n // Route AUDIO_STREAM_READY to the pending handler for this streamId\n const streamId = (message as any).streamId;\n const handler = this._audioStreamReadyHandlers.get(streamId);\n if (handler) {\n handler(message);\n this._audioStreamReadyHandlers.delete(streamId);\n } else {\n this.logger.debug({ streamId }, \"Received audio_stream_ready with no pending handler\");\n }\n } else if (isAudioPlayResponse(message)) {\n // Delegate audio play response handling to the audio module\n if (this.audio) {\n this.audio.handleAudioPlayResponse(message as AudioPlayResponse);\n }\n } else if (isPhotoResponse(message)) {\n // Photo responses can arrive via WebSocket when the cloud forwards error/success\n // from the phone's REST endpoint (POST /api/client/photo/response).\n // Success photos normally arrive via HTTP to /photo-upload, but errors always\n // come through WebSocket because the phone reports them to cloud, not directly\n // to the SDK. We MUST handle errors here to reject the pending promise immediately\n // instead of letting the developer wait 30s for a generic timeout.\n // See: OS-947, OS-951\n const photoResponse = message as PhotoResponse;\n const { requestId, success } = photoResponse;\n\n if (requestId && this.appServer) {\n const pending = this.appServer.completePhotoRequest(requestId);\n if (pending) {\n if (success) {\n // Success via WebSocket (legacy path — normally comes via /photo-upload HTTP)\n this.logger.info({ requestId }, \"📸 Photo success received via WebSocket (legacy path)\");\n pending.resolve({\n buffer: Buffer.from([]),\n mimeType: \"image/jpeg\",\n filename: \"photo.jpg\",\n requestId,\n size: 0,\n timestamp: new Date(),\n photoUrl: photoResponse.photoUrl,\n } as any);\n } else {\n // Error response — this is the critical path for OS-947/OS-951\n const errorCode = photoResponse.error?.code || \"UNKNOWN_ERROR\";\n const errorMessage = photoResponse.error?.message || \"Photo capture failed\";\n this.logger.warn(\n { requestId, errorCode, errorMessage },\n `📸 Photo error received via WebSocket: ${errorCode} - ${errorMessage}`,\n );\n pending.reject(new Error(`${errorCode}: ${errorMessage}`));\n }\n } else {\n this.logger.debug(\n { requestId, success },\n \"Photo response received via WebSocket but no pending request found (may have timed out or been completed via /photo-upload)\",\n );\n }\n } else {\n this.logger.warn(\n { requestId, hasAppServer: !!this.appServer },\n \"Photo response received via WebSocket but missing requestId or appServer\",\n );\n }\n } else if (isRgbLedControlResponse(message)) {\n // LED control responses are no longer handled - fire-and-forget mode\n this.logger.debug({ message }, \"Received LED control response (ignored - fire-and-forget mode)\");\n } else if (isRequestTelemetry(message)) {\n // Cloud is asking us to upload recent telemetry logs for incident debugging\n this.handleTelemetryRequest(message as RequestTelemetry).catch((err) => {\n this.logger.warn(err, \"handleTelemetryRequest failed\");\n });\n } else if ((message as any).type === \"pong\") {\n // Cloud responded to our app-level ping — bidirectional traffic maintained.\n // No action needed: the response itself satisfies the egress requirement.\n // See: cloud/issues/046-sdk-app-ws-liveness\n }\n // Handle unrecognized message types gracefully\n else {\n this.logger.warn(`Unrecognized message type: ${(message as any).type}`);\n this.events.emit(\n \"error\",\n new MentraError(`Unrecognized message type: ${(message as any).type}`, \"UNKNOWN_TYPE\"),\n );\n }\n } catch (processingError: unknown) {\n // Catch any errors during message processing to prevent App crashes\n this.logger.error(processingError, \"Error processing message:\");\n const errorMessage = processingError instanceof Error ? processingError.message : String(processingError);\n this.events.emit(\"error\", new MentraError(`Error processing message: ${errorMessage}`, \"INTERNAL_ERROR\"));\n }\n } catch (error: unknown) {\n // Final safety net to ensure the App doesn't crash on any unexpected errors\n this.logger.error(error, \"Unexpected error in message handler\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\"error\", new Error(`Unexpected error in message handler: ${errorMessage}`));\n }\n }\n\n /**\n * 🏓 Start the app-level ping interval.\n * Clears any existing interval first so reconnects don't double-up.\n */\n private startPingInterval(): void {\n this.stopPingInterval();\n this.pingInterval = setInterval(() => {\n if (!this.ws || this.ws.readyState !== 1) return;\n try {\n this.ws.send(JSON.stringify({ type: \"ping\" }));\n } catch {\n // If send fails the WebSocket is already dead; the close handler\n // will fire and trigger reconnection — nothing to do here.\n }\n }, AppSession.PING_INTERVAL_MS);\n }\n\n /**\n * 🏓 Stop the app-level ping interval.\n */\n private stopPingInterval(): void {\n if (this.pingInterval !== null) {\n clearInterval(this.pingInterval);\n this.pingInterval = null;\n }\n }\n\n /**\n * 📤 Handle a REQUEST_TELEMETRY message from cloud.\n * Collects recent log entries from the AppServer's telemetry buffer and\n * POSTs them back to the cloud's incident endpoint so the support team\n * can diagnose production issues.\n *\n * @param request - The REQUEST_TELEMETRY message from cloud\n */\n private async handleTelemetryRequest(request: RequestTelemetry): Promise<void> {\n const { incidentId, uploadToken, windowMs } = request;\n\n // Read from this session's own buffer — already scoped to this user\n const cutoff = windowMs ? Date.now() - windowMs : 0;\n const logs = cutoff > 0 ? this.telemetryBuffer.filter((e) => e.timestamp >= cutoff) : [...this.telemetryBuffer];\n\n this.logger.debug({ incidentId, logCount: logs.length, windowMs }, \"Collecting telemetry for incident upload\");\n\n const payload: TelemetryResponse = {\n type: AppToCloudMessageType.TELEMETRY_RESPONSE,\n incidentId,\n packageName: this.config.packageName,\n logs,\n metadata: {\n bufferSize: logs.length,\n oldestEntryMs: logs.length > 0 ? logs[0].timestamp : undefined,\n newestEntryMs: logs.length > 0 ? logs[logs.length - 1].timestamp : undefined,\n },\n };\n\n const baseUrl = this.getHttpsServerUrl();\n if (!baseUrl) {\n this.logger.warn({ incidentId }, \"Cannot upload telemetry — no server URL available\");\n return;\n }\n\n try {\n // Strip any path suffix (e.g. /app-ws) to get the cloud root URL\n const cloudBase = baseUrl.replace(/\\/app-ws.*$/, \"\");\n const url = `${cloudBase}/api/incidents/${incidentId}/logs`;\n\n await axios.post(url, payload, {\n headers: {\n \"Authorization\": `Bearer ${uploadToken}`,\n \"Content-Type\": \"application/json\",\n },\n timeout: 10_000,\n });\n\n this.logger.info({ incidentId, logCount: logs.length }, \"Telemetry uploaded successfully\");\n } catch (err) {\n this.logger.error(err, `Failed to upload telemetry for incident ${incidentId}`);\n }\n }\n\n /**\n * 🧪 Validate incoming message structure\n * @param message - Message to validate\n * @returns boolean indicating if the message is valid\n */\n private validateMessage(message: CloudToAppMessage): boolean {\n // Handle ArrayBuffer case separately\n if (message instanceof ArrayBuffer) {\n return true; // ArrayBuffers are always considered valid at this level\n }\n\n // Check if message is null or undefined\n if (!message) {\n return false;\n }\n\n // Check if message has a type property\n if (!(\"type\" in message)) {\n return false;\n }\n\n // All other message types should be objects with a type property\n return true;\n }\n\n /**\n * 📦 Handle binary message data (audio or video)\n * @param buffer - Binary data as ArrayBuffer\n */\n private handleBinaryMessage(buffer: ArrayBuffer): void {\n try {\n // Safety check - only process if we have a handler registered (derived from handlers)\n const hasAudioHandler = this.events.getRegisteredStreams().includes(StreamType.AUDIO_CHUNK);\n if (!hasAudioHandler) {\n return;\n }\n\n // Validate buffer has content before processing\n if (!buffer || buffer.byteLength === 0) {\n this.events.emit(\"error\", new Error(\"Received empty binary message\"));\n return;\n }\n\n // Create a safety wrapped audio chunk with proper defaults\n const audioChunk: AudioChunk = {\n type: StreamType.AUDIO_CHUNK,\n timestamp: new Date(),\n arrayBuffer: buffer,\n sampleRate: 16000, // Default sample rate\n };\n\n // Emit to subscribers\n this.events.emit(StreamType.AUDIO_CHUNK, audioChunk);\n } catch (error: unknown) {\n this.logger.error(error, \"Error processing binary message\");\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.events.emit(\"error\", new Error(`Error processing binary message: ${errorMessage}`));\n }\n }\n\n /**\n * 🧹 Sanitize event data to prevent crashes from malformed data\n * @param streamType - The type of stream data\n * @param data - The potentially unsafe data to sanitize\n * @returns Sanitized data safe for processing\n */\n private sanitizeEventData(streamType: ExtendedStreamType, data: unknown): any {\n try {\n // If data is null or undefined, return an empty object to prevent crashes\n if (data === null || data === undefined) {\n return {};\n }\n\n // For specific stream types, perform targeted sanitization\n switch (streamType) {\n case StreamType.TRANSCRIPTION: {\n // Ensure text field exists and is a string\n if (typeof (data as TranscriptionData).text !== \"string\") {\n return {\n text: \"\",\n isFinal: true,\n startTime: Date.now(),\n endTime: Date.now(),\n };\n }\n break;\n }\n\n case StreamType.HEAD_POSITION: {\n // Ensure position data has required numeric fields\n // Handle HeadPosition - Note the property position instead of x,y,z\n const pos = data as any;\n if (typeof pos?.position !== \"string\") {\n return { position: \"up\", timestamp: new Date() };\n }\n break;\n }\n\n case StreamType.BUTTON_PRESS: {\n // Ensure button type is valid\n const btn = data as any;\n if (!btn.buttonId || !btn.pressType) {\n return {\n buttonId: \"unknown\",\n pressType: \"short\",\n timestamp: new Date(),\n };\n }\n break;\n }\n }\n\n return data;\n } catch (error: unknown) {\n this.logger.error(error, `Error sanitizing ${streamType} data`);\n // Return a safe empty object if something goes wrong\n return {};\n }\n }\n\n /**\n * 🔐 Send connection initialization message\n */\n private sendConnectionInit(): void {\n const message: AppConnectionInit = {\n type: AppToCloudMessageType.CONNECTION_INIT,\n sessionId: this.sessionId!,\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n timestamp: new Date(),\n };\n this.send(message);\n }\n\n /**\n * 📝 Update subscription list with cloud\n */\n private updateSubscriptions(): void {\n // CRITICAL FIX (Bug 007): Derive subscriptions from EventManager.handlers\n // This ensures subscriptions can NEVER be empty if handlers exist\n // Previously, this.subscriptions could drift out of sync with handlers\n // See: cloud/issues/006-captions-and-apps-stopping/011-sdk-subscription-architecture-mismatch.md\n const derivedSubscriptions = this.events.getRegisteredStreams();\n\n this.logger.info(\n { subscriptions: JSON.stringify(derivedSubscriptions) },\n `[AppSession] updateSubscriptions: sending ${derivedSubscriptions.length} subscriptions to cloud (derived from handlers)`,\n );\n\n // Build the array of SubscriptionRequest objects to send to the cloud\n const subscriptionPayload: SubscriptionRequest[] = derivedSubscriptions.map((stream) => {\n const rate = this.streamRates.get(stream);\n if (rate && stream === StreamType.LOCATION_STREAM) {\n return { stream: \"location_stream\", rate: rate as any };\n }\n return stream;\n });\n\n const message: AppSubscriptionUpdate = {\n type: AppToCloudMessageType.SUBSCRIPTION_UPDATE,\n packageName: this.config.packageName,\n subscriptions: subscriptionPayload,\n sessionId: this.sessionId!,\n timestamp: new Date(),\n };\n this.send(message);\n }\n\n /**\n * 🔄 Handle reconnection with exponential backoff\n */\n private async handleReconnection(): Promise<void> {\n // Check if session was terminated (e.g., \"User session ended\")\n if (this.terminated) {\n this.logger.info(\n `🔄 Reconnection skipped: session was terminated (User session ended). ` +\n `If cloud restarts app, onSession will be called with fresh handlers.`,\n );\n return;\n }\n\n // Check if reconnection is allowed\n if (!this.config.autoReconnect || !this.sessionId) {\n this.logger.debug(\n `🔄 Reconnection skipped: autoReconnect=${this.config.autoReconnect}, sessionId=${\n this.sessionId ? \"valid\" : \"invalid\"\n }`,\n );\n return;\n }\n\n // Check if we've exceeded the maximum attempts\n const maxAttempts = this.config.maxReconnectAttempts || 3;\n if (this.reconnectAttempts >= maxAttempts) {\n this.logger.warn(`Reconnection failed after ${maxAttempts} attempts, giving up`);\n\n // Emit a permanent disconnection event to trigger onStop in the App server\n this.events.emit(\"disconnected\", {\n message: `Connection permanently lost after ${maxAttempts} failed reconnection attempts`,\n code: 4000, // Custom code for max reconnection attempts exhausted\n reason: \"Maximum reconnection attempts exceeded\",\n wasClean: false,\n permanent: true, // Flag this as a permanent disconnection\n });\n\n return;\n }\n\n // Calculate delay with exponential backoff\n const baseDelay = this.config.reconnectDelay || 1000;\n const delay = baseDelay * Math.pow(2, this.reconnectAttempts);\n this.reconnectAttempts++;\n\n this.logger.warn(`Connection lost, reconnecting (${this.reconnectAttempts}/${maxAttempts})...`);\n\n // Use the resource tracker for the timeout\n await new Promise<void>((resolve) => {\n this.resources.setTimeout(() => resolve(), delay);\n });\n\n try {\n await this.connect(this.sessionId);\n this.logger.info(\"Reconnected successfully\");\n this.reconnectAttempts = 0;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.logger.debug(error, \"Reconnection attempt failed\");\n this.events.emit(\"error\", new Error(`Reconnection failed: ${errorMessage}`));\n\n // Check if this was the last attempt\n if (this.reconnectAttempts >= maxAttempts) {\n this.logger.debug(\"Final reconnection attempt failed, emitting permanent disconnection\");\n\n // Emit permanent disconnection event after the last failed attempt\n this.events.emit(\"disconnected\", {\n message: `Connection permanently lost after ${maxAttempts} failed reconnection attempts`,\n code: 4000, // Custom code for max reconnection attempts exhausted\n reason: \"Maximum reconnection attempts exceeded\",\n wasClean: false,\n permanent: true, // Flag this as a permanent disconnection\n });\n }\n }\n }\n\n /**\n * 📤 Public API for modules to send messages\n * Always uses current WebSocket connection\n */\n public sendMessage(message: AppToCloudMessage): void {\n return this.send(message);\n }\n\n /**\n * 📤 Send raw binary data over the WebSocket.\n * Used by AudioOutputStream to push audio frames to the cloud relay.\n *\n * Binary frame format for audio streaming:\n * [36 bytes: streamId UUID as ASCII] [N bytes: audio data]\n *\n * @param data - Binary data to send\n * @throws {Error} If WebSocket is not connected\n * @internal\n */\n public sendBinary(data: Uint8Array | Buffer): void {\n if (!this.ws) {\n throw new Error(\"WebSocket connection not established\");\n }\n if (this.ws.readyState !== 1) {\n throw new Error(\"WebSocket not connected\");\n }\n try {\n this.ws.send(data);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n this.logger.debug({ err }, \"Failed to send binary frame\");\n throw new Error(`Failed to send binary data: ${errorMessage}`);\n }\n }\n\n /**\n * 📤 Send message to cloud with validation and error handling\n * @throws {Error} If WebSocket is not connected\n */\n private send(message: AppToCloudMessage): void {\n try {\n // Verify WebSocket connection is valid\n if (!this.ws) {\n throw new Error(\"WebSocket connection not established\");\n }\n\n if (this.ws.readyState !== 1) {\n const stateMap: Record<number, string> = {\n 0: \"CONNECTING\",\n 1: \"OPEN\",\n 2: \"CLOSING\",\n 3: \"CLOSED\",\n };\n const stateName = stateMap[this.ws.readyState] || \"UNKNOWN\";\n throw new Error(`WebSocket not connected (current state: ${stateName})`);\n }\n\n // Validate message before sending\n if (!message || typeof message !== \"object\") {\n throw new Error(\"Invalid message: must be an object\");\n }\n\n if (!(\"type\" in message)) {\n throw new Error('Invalid message: missing \"type\" property');\n }\n\n // Ensure message format is consistent\n if (!(\"timestamp\" in message) || !(message.timestamp instanceof Date)) {\n message.timestamp = new Date();\n }\n\n // Try to send with error handling\n try {\n const serializedMessage = JSON.stringify(message);\n this.ws.send(serializedMessage);\n } catch (sendError: unknown) {\n const errorMessage = sendError instanceof Error ? sendError.message : String(sendError);\n throw new Error(`Failed to send message: ${errorMessage}`);\n }\n } catch (error: unknown) {\n // Check if this is an expected disconnection error (not a real error)\n const isDisconnectError =\n error instanceof Error &&\n (error.message.includes(\"WebSocket not connected\") ||\n error.message.includes(\"CLOSED\") ||\n error.message.includes(\"CLOSING\"));\n\n if (isDisconnectError) {\n // Don't log as error - this is expected when user disconnects\n // Apps should handle this gracefully by checking session.isConnected\n this.logger.debug(error, \"Message send skipped - session disconnected\");\n } else {\n // This is an actual error that needs attention\n this.logger.error(error, \"Message send error\");\n }\n\n // Ensure we always emit an Error object\n if (error instanceof Error) {\n this.events.emit(\"error\", error);\n } else {\n this.events.emit(\"error\", new Error(String(error)));\n }\n\n // Re-throw to maintain the original function behavior\n throw error;\n }\n }\n\n /**\n * Fetch the onboarding instructions for this session from the backend.\n * @returns Promise resolving to the instructions string or null\n */\n public async getInstructions(): Promise<string | null> {\n try {\n const baseUrl = this.getServerUrl();\n const response = await axios.get(`${baseUrl}/api/instructions`, {\n params: { userId: this.userId },\n });\n return response.data.instructions || null;\n } catch (err) {\n this.logger.error(err, `Error fetching instructions from backend`);\n return null;\n }\n }\n // =====================================\n // 👥 App-to-App Communication Interface\n // =====================================\n\n /**\n * 👥 Discover other users currently using the same App\n * @param includeProfiles - Whether to include user profile information\n * @returns Promise that resolves with list of active users\n */\n async discoverAppUsers(domain: string, includeProfiles = false): Promise<any> {\n // Use the domain argument as the base URL if provided\n if (!domain) {\n throw new Error(\"Domain (API base URL) is required for user discovery\");\n }\n const url = `${domain}/api/app-communication/discover-users`;\n // Use the user's core token for authentication\n const appApiKey = this.config.apiKey; // This may need to be updated if you store the core token elsewhere\n\n if (!appApiKey) {\n throw new Error(\"Core token (apiKey) is required for user discovery\");\n }\n const body = {\n packageName: this.config.packageName,\n userId: this.userId,\n includeUserProfiles: includeProfiles,\n };\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Authorization\": `Bearer ${appApiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(body),\n });\n if (!response.ok) {\n const errorText = await response.text();\n throw new Error(`Failed to discover users: ${response.status} ${response.statusText} - ${errorText}`);\n }\n return await response.json();\n }\n\n /**\n * 🔍 Check if a specific user is currently active\n * @param userId - User ID to check for\n * @returns Promise that resolves with boolean indicating if user is active\n */\n async isUserActive(userId: string): Promise<boolean> {\n try {\n const userList = await this.discoverAppUsers(\"\", false);\n return userList.users.some((user: any) => user.userId === userId);\n } catch (error) {\n this.logger.error({ error, userId }, \"Error checking if user is active\");\n return false;\n }\n }\n\n /**\n * 📊 Get user count for this App\n * @returns Promise that resolves with number of active users\n */\n async getUserCount(domain: string): Promise<number> {\n try {\n const userList = await this.discoverAppUsers(domain, false);\n return userList.totalUsers;\n } catch (error) {\n this.logger.error(error, \"Error getting user count\");\n return 0;\n }\n }\n\n /**\n * 📢 Send broadcast message to all users with same App active\n * @param payload - Message payload to send\n * @param roomId - Optional room ID for room-based messaging\n * @returns Promise that resolves when message is sent\n */\n async broadcastToAppUsers(payload: any, _roomId?: string): Promise<void> {\n try {\n const messageId = this.generateMessageId();\n\n const message = {\n type: \"app_broadcast_message\",\n packageName: this.config.packageName,\n sessionId: this.sessionId!,\n payload,\n messageId,\n senderUserId: this.userId,\n timestamp: new Date(),\n };\n\n this.send(message as any);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to broadcast message: ${errorMessage}`);\n }\n }\n\n /**\n * 📤 Send direct message to specific user\n * @param targetUserId - User ID to send message to\n * @param payload - Message payload to send\n * @returns Promise that resolves with success status\n */\n async sendDirectMessage(targetUserId: string, payload: any): Promise<boolean> {\n return new Promise((resolve, reject) => {\n try {\n const messageId = this.generateMessageId();\n\n // Store promise resolver\n this.pendingDirectMessages.set(messageId, { resolve, reject });\n\n const message = {\n type: \"app_direct_message\",\n packageName: this.config.packageName,\n sessionId: this.sessionId!,\n targetUserId,\n payload,\n messageId,\n senderUserId: this.userId,\n timestamp: new Date(),\n };\n\n this.send(message as any);\n\n // Set timeout to avoid hanging promises\n const timeoutMs = 15000; // 15 seconds\n this.resources.setTimeout(() => {\n if (this.pendingDirectMessages.has(messageId)) {\n this.pendingDirectMessages.get(messageId)!.reject(new Error(\"Direct message timed out\"));\n this.pendingDirectMessages.delete(messageId);\n }\n }, timeoutMs);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n reject(new Error(`Failed to send direct message: ${errorMessage}`));\n }\n });\n }\n\n /**\n * 🏠 Join a communication room for group messaging\n * @param roomId - Room ID to join\n * @param roomConfig - Optional room configuration\n * @returns Promise that resolves when room is joined\n */\n async joinAppRoom(\n roomId: string,\n roomConfig?: {\n maxUsers?: number;\n isPrivate?: boolean;\n metadata?: any;\n },\n ): Promise<void> {\n try {\n const message = {\n type: \"app_room_join\",\n packageName: this.config.packageName,\n sessionId: this.sessionId!,\n roomId,\n roomConfig,\n timestamp: new Date(),\n };\n\n this.send(message as any);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to join room: ${errorMessage}`);\n }\n }\n\n /**\n * 🚪 Leave a communication room\n * @param roomId - Room ID to leave\n * @returns Promise that resolves when room is left\n */\n async leaveAppRoom(roomId: string): Promise<void> {\n try {\n const message = {\n type: \"app_room_leave\",\n packageName: this.config.packageName,\n sessionId: this.sessionId!,\n roomId,\n timestamp: new Date(),\n };\n\n this.send(message as any);\n } catch (error: unknown) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to leave room: ${errorMessage}`);\n }\n }\n\n /**\n * 📨 Listen for messages from other App users\n * @param handler - Function to handle incoming messages\n * @returns Cleanup function to remove the handler\n */\n onAppMessage(handler: (message: any) => void): () => void {\n this.appEvents.on(\"app_message_received\", handler);\n return () => this.appEvents.off(\"app_message_received\", handler);\n }\n\n /**\n * 👋 Listen for user join events\n * @param handler - Function to handle user join events\n * @returns Cleanup function to remove the handler\n */\n onAppUserJoined(handler: (data: any) => void): () => void {\n this.appEvents.on(\"app_user_joined\", handler);\n return () => this.appEvents.off(\"app_user_joined\", handler);\n }\n\n /**\n * 🚪 Listen for user leave events\n * @param handler - Function to handle user leave events\n * @returns Cleanup function to remove the handler\n */\n onAppUserLeft(handler: (data: any) => void): () => void {\n this.appEvents.on(\"app_user_left\", handler);\n return () => this.appEvents.off(\"app_user_left\", handler);\n }\n\n /**\n * 🏠 Listen for room update events\n * @param handler - Function to handle room updates\n * @returns Cleanup function to remove the handler\n */\n onAppRoomUpdated(handler: (data: any) => void): () => void {\n this.appEvents.on(\"app_room_updated\", handler);\n return () => this.appEvents.off(\"app_room_updated\", handler);\n }\n\n /**\n * 🔧 Generate unique message ID\n * @returns Unique message identifier\n */\n private generateMessageId(): string {\n return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;\n }\n}\n\n/**\n * @deprecated Use `AppSessionConfig` instead. `TpaSessionConfig` is deprecated and will be removed in a future version.\n * This is an alias for backward compatibility only.\n *\n * @example\n * ```typescript\n * // ❌ Deprecated - Don't use this\n * const config: TpaSessionConfig = { ... };\n *\n * // ✅ Use this instead\n * const config: AppSessionConfig = { ... };\n * ```\n */\nexport type TpaSessionConfig = AppSessionConfig;\n\n/**\n * @deprecated Use `AppSession` instead. `TpaSession` is deprecated and will be removed in a future version.\n * This is an alias for backward compatibility only.\n *\n * @example\n * ```typescript\n * // ❌ Deprecated - Don't use this\n * const session = new TpaSession(config);\n *\n * // ✅ Use this instead\n * const session = new AppSession(config);\n * ```\n */\nexport class TpaSession extends AppSession {\n constructor(config: TpaSessionConfig) {\n super(config);\n // Emit a deprecation warning to help developers migrate\n console.warn(\n \"⚠️ DEPRECATION WARNING: TpaSession is deprecated and will be removed in a future version. \" +\n \"Please use AppSession instead. \" +\n 'Simply replace \"TpaSession\" with \"AppSession\" in your code.',\n );\n }\n}\n\n// Export module classes for developers\nexport { CameraModule } from \"./modules/camera\";\nexport { LedModule } from \"./modules/led\";\nexport { AudioManager } from \"./modules/audio\";\nexport { SimpleStorage } from \"./modules/simple-storage\";\n\n// Export module types for developers\nexport type { PhotoRequestOptions, StreamOptions } from \"./modules/camera\";\nexport type { LedControlOptions } from \"./modules/led\";\nexport type { AudioPlayOptions, AudioPlayResult, SpeakOptions } from \"./modules/audio\";\n",
|
|
51
51
|
"/**\n * 🎨 Layout Manager Module\n *\n * Manages AR display layouts for Apps. This class provides an easy-to-use interface\n * for showing different types of content in the user's AR view.\n *\n * @example\n * ```typescript\n * const layouts = new LayoutManager('org.example.myapp', sendMessage);\n *\n * // Show a simple message\n * layouts.showTextWall('Hello AR World!');\n *\n * // Show a card with title\n * layouts.showReferenceCard('Weather', 'Sunny and 75°F');\n * ```\n */\nimport { BitmapUtils } from \"../../utils/bitmap-utils\";\nimport {\n DisplayRequest,\n Layout,\n TextWall,\n DoubleTextWall,\n ReferenceCard,\n DashboardCard,\n LayoutType,\n ViewType,\n AppToCloudMessageType,\n BitmapView,\n BitmapAnimation,\n ClearView,\n} from \"../../types\";\n\nexport class LayoutManager {\n /**\n * 🎯 Creates a new LayoutManager instance\n *\n * @param packageName - App package identifier\n * @param sendMessage - Function to send display requests to MentraOS\n */\n constructor(\n private packageName: string,\n private sendMessage: (message: DisplayRequest) => void,\n ) {}\n\n /**\n * 📦 Creates a display event request with validation\n *\n * @param layout - Layout configuration to display\n * @param view - View type (main or dashboard)\n * @param durationMs - How long to show the layout (optional)\n * @returns Formatted display request\n * @throws Error if layout is invalid\n */\n private createDisplayEvent(\n layout: Layout,\n view: ViewType = ViewType.MAIN,\n durationMs?: number,\n ): DisplayRequest {\n try {\n // Validate layout data before sending\n if (!layout) {\n throw new Error(\"Layout cannot be null or undefined\");\n }\n\n if (!layout.layoutType) {\n throw new Error(\"Layout must have a layoutType property\");\n }\n\n // Layout-specific validations\n switch (layout.layoutType) {\n case LayoutType.TEXT_WALL:\n if (typeof (layout as TextWall).text !== \"string\") {\n throw new Error(\"TextWall layout must have a text property\");\n }\n // Ensure text is not too long (prevent performance issues)\n if ((layout as TextWall).text.length > 1000) {\n console.warn(\n \"TextWall text is very long, this may cause performance issues\",\n );\n }\n break;\n\n case LayoutType.DOUBLE_TEXT_WALL:\n const doubleText = layout as DoubleTextWall;\n if (typeof doubleText.topText !== \"string\") {\n throw new Error(\n \"DoubleTextWall layout must have a topText property\",\n );\n }\n if (typeof doubleText.bottomText !== \"string\") {\n throw new Error(\n \"DoubleTextWall layout must have a bottomText property\",\n );\n }\n break;\n\n case LayoutType.REFERENCE_CARD:\n const refCard = layout as ReferenceCard;\n if (typeof refCard.title !== \"string\") {\n throw new Error(\"ReferenceCard layout must have a title property\");\n }\n if (typeof refCard.text !== \"string\") {\n throw new Error(\"ReferenceCard layout must have a text property\");\n }\n break;\n\n case LayoutType.DASHBOARD_CARD:\n const dashCard = layout as DashboardCard;\n if (typeof dashCard.leftText !== \"string\") {\n throw new Error(\n \"DashboardCard layout must have a leftText property\",\n );\n }\n if (typeof dashCard.rightText !== \"string\") {\n throw new Error(\n \"DashboardCard layout must have a rightText property\",\n );\n }\n break;\n\n case LayoutType.BITMAP_VIEW:\n const bitmapView = layout as BitmapView;\n if (typeof bitmapView.data !== \"string\") {\n throw new Error(\"BitmapView layout must have a data property\");\n }\n // Check if data is too large (prevent OOM errors)\n if (bitmapView.data.length > 1000000) {\n // 1MB limit\n throw new Error(\n \"Bitmap data is too large (>1MB), please reduce size\",\n );\n }\n break;\n\n case LayoutType.CLEAR_VIEW:\n // ClearView has no additional validation needed\n break;\n }\n\n // Validate view type\n if (view !== ViewType.MAIN && view !== ViewType.DASHBOARD) {\n console.warn(`Invalid view type: ${view}, defaulting to MAIN`);\n view = ViewType.MAIN;\n }\n\n // Validate duration if provided\n if (durationMs !== undefined) {\n if (typeof durationMs !== \"number\" || durationMs < 0) {\n console.warn(`Invalid duration: ${durationMs}, ignoring`);\n durationMs = undefined;\n }\n }\n\n // Create the display request with validated data\n return {\n timestamp: new Date(),\n sessionId: \"\", // Will be filled by session\n type: AppToCloudMessageType.DISPLAY_REQUEST,\n packageName: this.packageName,\n view,\n layout,\n durationMs,\n };\n } catch (error) {\n console.error(\"Error creating display event:\", error);\n throw error; // Re-throw to notify caller\n }\n }\n\n /**\n * 📝 Shows a single block of text\n *\n * Best for:\n * - Simple messages\n * - Status updates\n * - Notifications\n *\n * @param text - Text content to display\n * @param options - Optional parameters (view, duration, priority)\n * - priority: If true, this display will not be overridden by other requests (default: false)\n *\n * @example\n * ```typescript\n * layouts.showTextWall('Connected to server');\n * layouts.showTextWall('Onboarding!', { priority: true });\n * ```\n */\n showTextWall(\n text: string,\n options?: { view?: ViewType; durationMs?: number },\n ) {\n try {\n // Validate input before processing\n if (text === undefined || text === null) {\n text = \"\"; // Default to empty string instead of crashing\n console.warn(\"showTextWall called with null/undefined text\");\n }\n\n // Ensure text is a string\n if (typeof text !== \"string\") {\n text = String(text); // Convert to string\n console.warn(\"showTextWall: Non-string input converted to string\");\n }\n\n // Create layout with validated text\n const layout: TextWall = {\n layoutType: LayoutType.TEXT_WALL,\n text,\n };\n\n // Create and send display event with error handling\n try {\n const displayEvent = this.createDisplayEvent(\n layout,\n options?.view,\n options?.durationMs,\n );\n this.sendMessage(displayEvent);\n } catch (error) {\n console.error(\"Failed to display text wall:\", error);\n // Don't re-throw - prevent app crashes\n }\n } catch (error) {\n console.error(\"Error in showTextWall:\", error);\n // Don't crash the App - fail gracefully\n }\n }\n\n /**\n * ↕️ Shows two sections of text, one above the other\n *\n * Best for:\n * - Before/After content\n * - Question/Answer displays\n * - Two-part messages\n * - Comparisons\n *\n * @param topText - Text to show in top section\n * @param bottomText - Text to show in bottom section\n * @param options - Optional parameters (view, duration)\n *\n * @example\n * ```typescript\n * layouts.showDoubleTextWall(\n * 'Original: Hello',\n * 'Translated: Bonjour'\n * );\n * ```\n */\n showDoubleTextWall(\n topText: string,\n bottomText: string,\n options?: { view?: ViewType; durationMs?: number },\n ) {\n const layout: DoubleTextWall = {\n layoutType: LayoutType.DOUBLE_TEXT_WALL,\n topText,\n bottomText,\n };\n this.sendMessage(\n this.createDisplayEvent(layout, options?.view, options?.durationMs),\n );\n }\n\n /**\n * 📇 Shows a card with a title and content\n *\n * Best for:\n * - Titled content\n * - Important information\n * - Structured data\n * - Notifications with context\n *\n * @param title - Card title\n * @param text - Main content text\n * @param options - Optional parameters (view, duration)\n *\n * @example\n * ```typescript\n * layouts.showReferenceCard(\n * 'Meeting Reminder',\n * 'Team standup in 5 minutes'\n * );\n * ```\n */\n showReferenceCard(\n title: string,\n text: string,\n options?: { view?: ViewType; durationMs?: number },\n ) {\n const layout: ReferenceCard = {\n layoutType: LayoutType.REFERENCE_CARD,\n title,\n text,\n };\n this.sendMessage(\n this.createDisplayEvent(layout, options?.view, options?.durationMs),\n );\n }\n\n /**\n * 📇 Shows a bitmap\n *\n * Uses the proven animation system internally for proper L/R eye synchronization.\n * This ensures single bitmap displays work consistently with the same\n * hardware-optimized timing as animations.\n *\n * @param data - hex or base64 encoded bitmap data\n * @param options - Optional parameters (view, duration)\n *\n * @example\n * ```typescript\n * layouts.showBitmapView(\n * yourHexOrBase64EncodedBitmapDataString\n * );\n * ```\n */\n async showBitmapView(\n base64Bitmap: string,\n options?: { view?: ViewType; padding?: { left: number; top: number } },\n ) {\n const padding = options?.padding ?? { left: 50, top: 35 };\n const bitmapFrame = await BitmapUtils.padBase64Bitmap(\n base64Bitmap,\n padding,\n );\n const validation = BitmapUtils.validateBase64Bitmap(bitmapFrame);\n if (!validation.isValid) {\n throw new Error(\n `❌ Frame validation failed: ${validation.errors.join(\", \")}`,\n );\n }\n const layout: BitmapView = {\n layoutType: LayoutType.BITMAP_VIEW,\n data: bitmapFrame,\n };\n this.sendMessage(this.createDisplayEvent(layout, options?.view));\n }\n\n /**\n * 📊 Shows a dashboard card with left and right text\n *\n * Best for:\n * - Key-value pairs\n * - Dashboard displays\n * - Metrics\n *\n * @param leftText - Left side text (typically label/key)\n * @param rightText - Right side text (typically value)\n * @param options - Optional parameters (view, duration)\n *\n * @example\n * ```typescript\n * layouts.showDashboardCard('Weather', '72°F');\n * ```\n */\n showDashboardCard(\n leftText: string,\n rightText: string,\n options?: { view?: ViewType; durationMs?: number },\n ) {\n const layout: DashboardCard = {\n layoutType: LayoutType.DASHBOARD_CARD,\n leftText,\n rightText,\n };\n this.sendMessage(\n this.createDisplayEvent(\n layout,\n options?.view || ViewType.DASHBOARD,\n options?.durationMs,\n ),\n );\n }\n\n /**\n * 🧹 Clears the display\n *\n * Best for:\n * - Clearing previous content\n * - Resetting display state\n * - Starting fresh\n *\n * @param options - Optional parameters (view)\n *\n * @example\n * ```typescript\n * layouts.clearView();\n * layouts.clearView({ view: ViewType.DASHBOARD });\n * ```\n */\n clearView(options?: { view?: ViewType }) {\n const layout: ClearView = {\n layoutType: LayoutType.CLEAR_VIEW,\n };\n this.sendMessage(this.createDisplayEvent(layout, options?.view));\n }\n\n /**\n * 🎬 Shows an animated sequence of bitmap images (iOS-controlled timing)\n *\n * Sends complete animation package to iOS for device-controlled timing.\n * This provides superior performance and synchronization by letting\n * the device control the display timing directly.\n *\n * Best for:\n * - Smooth high-performance animations\n * - Precise timing control\n * - Synchronized left/right display\n * - EvenDemo-quality performance\n *\n * @param bitmapDataArray - Array of bitmap data strings (hex or base64 encoded)\n * @param intervalMs - Time between frames in milliseconds (default: 1650ms)\n * @param repeat - Whether to loop the animation continuously (default: false)\n * @param options - Optional parameters (view)\n *\n * @example\n * ```typescript\n * // Device-controlled animation (recommended)\n * const frames = ['hexdata1', 'hexdata2', 'hexdata3'];\n * layouts.showBitmapAnimation(frames, 1650, true);\n *\n * // Single-cycle animation\n * layouts.showBitmapAnimation(loadingFrames, 1650, false);\n * ```\n *\n * @returns Animation controller object with stop() method\n */\n showBitmapAnimation(\n bitmapDataArray: string[],\n intervalMs: number = 1650,\n repeat: boolean = false,\n options?: { view?: ViewType },\n ): { stop: () => void } {\n // Validation\n if (!Array.isArray(bitmapDataArray) || bitmapDataArray.length === 0) {\n throw new Error(\n \"showBitmapAnimation requires a non-empty array of bitmap data\",\n );\n }\n\n // Send complete animation package to iOS for device-controlled timing\n const layout: BitmapAnimation = {\n layoutType: LayoutType.BITMAP_ANIMATION,\n frames: bitmapDataArray,\n interval: intervalMs,\n repeat: repeat,\n };\n\n this.sendMessage(this.createDisplayEvent(layout, options?.view));\n\n console.log(\n `🎬 Sent batched animation to iOS: ${\n bitmapDataArray.length\n } frames at ${intervalMs}ms${repeat ? \" (repeating)\" : \"\"}`,\n );\n\n // Return controller for compatibility\n return {\n stop: () => {\n // Send stop command to iOS\n this.clearView();\n console.log(\"🛑 Animation stop requested\");\n },\n };\n }\n}\n",
|
|
@@ -62,18 +62,18 @@
|
|
|
62
62
|
"/**\n * Telemetry Transport for MentraOS SDK\n *\n * A pino-compatible Writable stream that intercepts log entries and pushes\n * them into a session-scoped ring buffer for incident debugging.\n *\n * This transport is added to the session logger (not the server logger), so\n * the buffer is automatically scoped to one user's session. Every log line\n * written via session.logger — including all module child loggers (camera,\n * audio, led, etc.) — is captured here with zero effort from app developers.\n *\n * Design notes:\n * - Only captures info+ entries. Debug is too noisy for incident bundles;\n * BetterStack captures debug separately.\n * - Ring buffer: oldest entries are dropped when full. This is intentional —\n * the most recent logs before a bug report are the most useful.\n * - The buffer is an external array passed in by reference, so AppSession\n * owns the lifetime and can clear it on disconnect simply by reassigning.\n * - This transport does NOT forward to BetterStack or console — those run\n * via the parent appServer.logger streams independently.\n */\n\nimport { Writable } from \"stream\";\nimport type { TelemetryLogEntry } from \"../types/messages/app-to-cloud\";\n\n// Pino level numbers → our TelemetryLogEntry level strings\n// https://getpino.io/#/docs/api?id=loggerlevel-string-gettersetter\nconst PINO_LEVEL_MAP: Record<number, TelemetryLogEntry[\"level\"]> = {\n 10: \"debug\", // trace → debug (we filter these out anyway)\n 20: \"debug\",\n 30: \"info\",\n 40: \"warn\",\n 50: \"error\",\n 60: \"error\", // fatal → error\n};\n\n// Minimum pino level number to capture. 30 = info.\n// Debug (20) and trace (10) are excluded — too noisy for incident bundles.\nconst MIN_CAPTURE_LEVEL = 30;\n\n/**\n * Creates a pino-compatible Writable stream that pushes log entries into\n * a caller-owned ring buffer.\n *\n * @param buffer - The array to push entries into. Owned by the caller\n * (AppSession). Passed by reference so the caller can\n * clear it by splicing or reassigning.\n * @param bufferSize - Maximum number of entries to keep. When the buffer\n * exceeds this, the oldest entries are dropped.\n * Default: 500.\n * @returns A Node.js Writable stream compatible with pino's multistream.\n *\n * @example\n * ```typescript\n * const telemetryBuffer: TelemetryLogEntry[] = []\n * const stream = createTelemetryStream(telemetryBuffer, 500)\n *\n * const logger = pino(\n * { level: \"debug\" },\n * pino.multistream([\n * { stream: parentStream, level: \"warn\" },\n * { stream: stream, level: \"info\" },\n * ])\n * )\n * ```\n */\nexport function createTelemetryStream(buffer: TelemetryLogEntry[], bufferSize = 500): Writable {\n return new Writable({\n write(chunk: Buffer, _encoding: string, callback: () => void) {\n try {\n const line = chunk.toString().trim();\n if (!line) {\n callback();\n return;\n }\n\n const obj = JSON.parse(line);\n\n // Filter out below-info entries\n const pinoLevel: number = obj.level ?? 30;\n if (pinoLevel < MIN_CAPTURE_LEVEL) {\n callback();\n return;\n }\n\n const level: TelemetryLogEntry[\"level\"] = PINO_LEVEL_MAP[pinoLevel] ?? \"info\";\n const msg: string = obj.msg ?? \"\";\n\n // Skip empty messages — pino internal events or structured-only logs\n if (!msg) {\n callback();\n return;\n }\n\n // Build the entry. We capture the structured context fields (everything\n // except the pino internals) as `data` so the incident viewer can see\n // userId, module, requestId, etc. alongside the message.\n const { level: _l, msg: _m, time, pid: _pid, hostname: _hostname, ...rest } = obj;\n const entry: TelemetryLogEntry = {\n timestamp: typeof time === \"number\" ? time : Date.now(),\n level,\n message: msg,\n // Preserve source tagging from pino child logger bindings\n source: obj.service ?? obj.module ?? undefined,\n // Attach remaining structured fields only if there's anything useful\n data: Object.keys(rest).length > 0 ? rest : undefined,\n };\n\n buffer.push(entry);\n\n // Trim to keep only the most recent entries\n if (buffer.length > bufferSize) {\n buffer.splice(0, buffer.length - bufferSize);\n }\n } catch {\n // Silently ignore parse errors — a broken telemetry stream should\n // never crash the app or interfere with other log transports.\n }\n\n callback();\n },\n });\n}\n",
|
|
63
63
|
"/**\n * Simple Storage SDK Module for MentraOS Apps\n * Provides localStorage-like API with cloud synchronization\n *\n * Mental Model: App server RAM = source of truth, MongoDB = crash recovery backup\n * - User interactions read/write to RAM instantly\n * - Changes are debounced and batched to MongoDB (3s idle / 10s max)\n * - On disconnect, pending writes are flushed automatically\n */\n\nimport {AppSession} from \"..\"\n\n/**\n * Response types for Simple Storage API\n */\ninterface StorageResponse {\n success: boolean\n data?: Record<string, string>\n}\n\ninterface StorageOperationResponse {\n success: boolean\n}\n\n/**\n * Key-value storage with local caching and debounced cloud sync\n * Data is isolated by userId and packageName\n */\nexport class SimpleStorage {\n private storage: Record<string, string> | null = null\n private appSession: AppSession\n private userId: string\n private packageName: string\n private baseUrl: string\n\n // Debounce batching state\n private pendingWrites = new Map<string, string>()\n private debounceTimer?: NodeJS.Timeout\n private maxWaitTimer?: NodeJS.Timeout\n private firstWriteTime?: number\n\n // Constants\n private static readonly MAX_VALUE_SIZE = 100_000 // 100KB\n private static readonly DEBOUNCE_MS = 3_000 // 3 seconds idle\n private static readonly MAX_WAIT_MS = 10_000 // 10 seconds max\n\n constructor(appSession: AppSession) {\n this.appSession = appSession\n this.userId = appSession.userId\n this.packageName = appSession.getPackageName()\n this.baseUrl = this.getBaseUrl()\n }\n\n // Convert WebSocket URL to HTTP for API calls\n private getBaseUrl(): string {\n const serverUrl = this.appSession.getServerUrl()\n if (!serverUrl) return \"http://localhost:8002\"\n return serverUrl.replace(/\\/app-ws$/, \"\").replace(/^ws/, \"http\")\n }\n\n // Generate auth headers for API requests\n private getAuthHeaders() {\n const apiKey = (this.appSession as any).config?.apiKey || \"unknown-api-key\"\n return {\n \"Authorization\": `Bearer ${this.packageName}:${apiKey}`,\n \"Content-Type\": \"application/json\",\n }\n }\n\n // Fetch all data from cloud and cache locally\n private async fetchStorageFromCloud(): Promise<void> {\n try {\n const response = await fetch(`${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}`, {\n headers: this.getAuthHeaders(),\n })\n\n if (response.ok) {\n const result = (await response.json()) as StorageResponse\n if (result.success && result.data) {\n this.storage = result.data\n } else {\n this.storage = {}\n }\n } else {\n console.error(\"Failed to fetch storage from cloud:\", await response.text())\n this.storage = {}\n }\n } catch (error) {\n console.error(\"Error fetching storage from cloud:\", error)\n this.storage = {}\n }\n }\n\n // Get item from cache or cloud\n public async get(key: string): Promise<string | undefined> {\n try {\n if (this.storage !== null && this.storage !== undefined) {\n return this.storage[key]\n }\n\n await this.fetchStorageFromCloud()\n return this.storage?.[key]\n } catch (error) {\n console.error(\"Error getting item:\", error)\n return undefined\n }\n }\n\n // Set item with size validation and debounced batching\n // RAM updated immediately, MongoDB synced after 3s idle or 10s max\n public async set(key: string, value: string): Promise<void> {\n try {\n // Validate value size\n if (value.length > SimpleStorage.MAX_VALUE_SIZE) {\n throw new Error(\n `SimpleStorage value exceeds 100KB limit (${value.length} bytes). ` +\n `For large files, use your own S3 bucket storage.`,\n )\n }\n\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n\n // Optimistic update - RAM is source of truth (instant)\n if (this.storage) {\n this.storage[key] = value\n }\n\n // Add to pending batch for MongoDB persistence\n this.pendingWrites.set(key, value)\n\n // Schedule debounced flush\n this.scheduleFlush()\n } catch (error) {\n console.error(\"Error setting item:\", error)\n throw error\n }\n }\n\n /**\n * Schedule flush with debounce (3s idle) and max wait (10s)\n */\n private scheduleFlush(): void {\n // Track first write time for max wait\n if (!this.firstWriteTime) {\n this.firstWriteTime = Date.now()\n }\n\n // Clear existing debounce timer\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer)\n }\n\n // Calculate time until max wait\n const elapsedMs = Date.now() - this.firstWriteTime\n const remainingMaxWaitMs = SimpleStorage.MAX_WAIT_MS - elapsedMs\n\n // If we've hit max wait, flush immediately\n if (remainingMaxWaitMs <= 0) {\n this.flush().catch((err) => {\n console.error(\"Error flushing SimpleStorage:\", err)\n })\n return\n }\n\n // Set debounce timer (3s idle)\n this.debounceTimer = setTimeout(\n () => {\n this.flush().catch((err) => {\n console.error(\"Error flushing SimpleStorage:\", err)\n })\n },\n Math.min(SimpleStorage.DEBOUNCE_MS, remainingMaxWaitMs),\n )\n\n // Set max wait timer if not already set\n if (!this.maxWaitTimer && remainingMaxWaitMs > 0) {\n this.maxWaitTimer = setTimeout(() => {\n this.flush().catch((err) => {\n console.error(\"Error flushing SimpleStorage (max wait):\", err)\n })\n }, remainingMaxWaitMs)\n }\n }\n\n /**\n * Flush pending writes immediately\n * Called by: debounce timeout, max wait timeout, disconnect, or explicit flush()\n */\n public async flush(): Promise<void> {\n if (this.pendingWrites.size === 0) return\n\n // Clear all timers\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer)\n this.debounceTimer = undefined\n }\n if (this.maxWaitTimer) {\n clearTimeout(this.maxWaitTimer)\n this.maxWaitTimer = undefined\n }\n this.firstWriteTime = undefined\n\n const batch = Object.fromEntries(this.pendingWrites)\n this.pendingWrites.clear()\n\n try {\n // Persist to MongoDB (backup for crash recovery)\n const response = await fetch(`${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}`, {\n method: \"PUT\",\n headers: this.getAuthHeaders(),\n body: JSON.stringify({data: batch}),\n })\n\n if (!response.ok) {\n const error = await response.text()\n console.error(\"Failed to persist SimpleStorage to MongoDB:\", error)\n\n // Re-throw with helpful message\n if (response.status === 413) {\n throw new Error(\"SimpleStorage total size exceeds 1MB limit. Delete unused keys.\")\n }\n if (response.status === 429) {\n throw new Error(\"SimpleStorage rate limit exceeded.\")\n }\n throw new Error(`SimpleStorage flush failed: ${error}`)\n }\n } catch (error) {\n console.error(\"Error flushing SimpleStorage:\", error)\n throw error\n }\n }\n\n // Delete item from cache and debounced sync to cloud\n public async delete(key: string): Promise<boolean> {\n try {\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n\n // Remove from cache (RAM = source of truth)\n if (this.storage) {\n delete this.storage[key]\n }\n\n // Remove from pending writes if exists\n this.pendingWrites.delete(key)\n\n // For deletes, we flush immediately to ensure consistency\n // (could batch this too, but deletes are rare)\n const response = await fetch(\n `${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}/${encodeURIComponent(key)}`,\n {\n method: \"DELETE\",\n headers: this.getAuthHeaders(),\n },\n )\n\n if (response.ok) {\n const result = (await response.json()) as StorageOperationResponse\n return result.success\n } else {\n console.error(\"Failed to delete item from cloud:\", await response.text())\n return false\n }\n } catch (error) {\n console.error(\"Error deleting item:\", error)\n return false\n }\n }\n\n // Clear all data from cache and cloud\n public async clear(): Promise<boolean> {\n try {\n this.storage = {}\n\n const response = await fetch(`${this.baseUrl}/api/sdk/simple-storage/${encodeURIComponent(this.userId)}`, {\n method: \"DELETE\",\n headers: this.getAuthHeaders(),\n })\n\n if (response.ok) {\n const result = (await response.json()) as StorageOperationResponse\n return result.success\n } else {\n console.error(\"Failed to clear storage from cloud:\", await response.text())\n return false\n }\n } catch (error) {\n console.error(\"Error clearing storage:\", error)\n return false\n }\n }\n\n // Get all storage keys\n public async keys(): Promise<string[]> {\n try {\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n return Object.keys(this.storage || {})\n } catch (error) {\n console.error(\"Error getting keys:\", error)\n return []\n }\n }\n\n // Get number of stored items\n public async size(): Promise<number> {\n try {\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n return Object.keys(this.storage || {}).length\n } catch (error) {\n console.error(\"Error getting storage size:\", error)\n return 0\n }\n }\n\n // Check if key exists\n public async hasKey(key: string): Promise<boolean> {\n try {\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n return key in (this.storage || {})\n } catch (error) {\n console.error(\"Error checking key:\", error)\n return false\n }\n }\n\n // Get copy of all stored data\n public async getAllData(): Promise<Record<string, string>> {\n try {\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n return {...(this.storage || {})}\n } catch (error) {\n console.error(\"Error getting all data:\", error)\n return {}\n }\n }\n\n // Set multiple items at once with validation\n public async setMultiple(data: Record<string, string>): Promise<void> {\n try {\n // Validate all values first\n for (const [key, value] of Object.entries(data)) {\n if (value.length > SimpleStorage.MAX_VALUE_SIZE) {\n throw new Error(`SimpleStorage value for key \"${key}\" exceeds 100KB limit (${value.length} bytes)`)\n }\n }\n\n if (this.storage === null || this.storage === undefined) {\n await this.fetchStorageFromCloud()\n }\n\n // Update cache (RAM = source of truth)\n if (this.storage) {\n Object.assign(this.storage, data)\n }\n\n // Add all to pending batch\n for (const [key, value] of Object.entries(data)) {\n this.pendingWrites.set(key, value)\n }\n\n // Schedule debounced flush\n this.scheduleFlush()\n } catch (error) {\n console.error(\"Error setting multiple items:\", error)\n throw error\n }\n }\n}\n",
|
|
64
64
|
"/**\n * DeviceState - Reactive device state management via WebSocket\n *\n * Provides real-time Observable properties for device state (WiFi, battery, hotspot, etc.)\n * Uses flat structure matching GlassesInfo field names exactly.\n *\n * @example\n * ```typescript\n * // Synchronous read\n * if (session.device.state.wifiConnected) {\n * console.log(\"Connected to:\", session.device.state.wifiSsid.value);\n * }\n *\n * // Reactive subscription\n * session.device.state.wifiConnected.onChange((connected) => {\n * console.log(\"WiFi status:\", connected);\n * });\n *\n * session.device.state.batteryLevel.onChange((level) => {\n * console.log(\"Battery:\", level, \"%\");\n * });\n * ```\n */\n\nimport {Observable} from '../../utils/Observable';\nimport type {GlassesInfo} from '@mentra/types';\nimport type {AppSession} from './index';\n\nexport class DeviceState {\n // ============================================================================\n // WiFi Status Observables\n // ============================================================================\n\n /** WiFi connection status */\n public readonly wifiConnected: Observable<boolean>;\n\n /** WiFi network SSID (null if not connected) */\n public readonly wifiSsid: Observable<string | null>;\n\n /** WiFi local IP address (null if not connected) */\n public readonly wifiLocalIp: Observable<string | null>;\n\n // ============================================================================\n // Battery Status Observables\n // ============================================================================\n\n /** Glasses battery level (0-100, null if unknown) */\n public readonly batteryLevel: Observable<number | null>;\n\n /** Glasses charging status (null if unknown) */\n public readonly charging: Observable<boolean | null>;\n\n /** Case battery level (0-100, null if no case or unknown) */\n public readonly caseBatteryLevel: Observable<number | null>;\n\n /** Case charging status (null if no case or unknown) */\n public readonly caseCharging: Observable<boolean | null>;\n\n /** Case open/closed status (true = open, null if no case or unknown) */\n public readonly caseOpen: Observable<boolean | null>;\n\n /** Case removed status (true = glasses not in case, null if no case or unknown) */\n public readonly caseRemoved: Observable<boolean | null>;\n\n // ============================================================================\n // Hotspot Status Observables\n // ============================================================================\n\n /** Hotspot enabled status (null if not supported or unknown) */\n public readonly hotspotEnabled: Observable<boolean | null>;\n\n /** Hotspot SSID (null if disabled or unknown) */\n public readonly hotspotSsid: Observable<string | null>;\n\n // ============================================================================\n // Connection & Device Info Observables\n // ============================================================================\n\n /** Glasses connected to phone/cloud (true = connected) */\n public readonly connected: Observable<boolean>;\n\n /** Glasses model name (e.g., \"even_g1\", \"xreal_air_2_pro\") */\n public readonly modelName: Observable<string | null>;\n\n // ============================================================================\n // Internal State\n // ============================================================================\n\n private appSession: AppSession;\n\n constructor(appSession: AppSession) {\n this.appSession = appSession;\n\n // Initialize all observables with default/safe values\n // These will be updated when cloud sends DEVICE_STATE_UPDATE\n\n // WiFi (default: disconnected)\n this.wifiConnected = new Observable<boolean>(false);\n this.wifiSsid = new Observable<string | null>(null);\n this.wifiLocalIp = new Observable<string | null>(null);\n\n // Battery (default: unknown)\n this.batteryLevel = new Observable<number | null>(null);\n this.charging = new Observable<boolean | null>(null);\n this.caseBatteryLevel = new Observable<number | null>(null);\n this.caseCharging = new Observable<boolean | null>(null);\n this.caseOpen = new Observable<boolean | null>(null);\n this.caseRemoved = new Observable<boolean | null>(null);\n\n // Hotspot (default: disabled/unknown)\n this.hotspotEnabled = new Observable<boolean | null>(null);\n this.hotspotSsid = new Observable<string | null>(null);\n\n // Connection (default: disconnected)\n this.connected = new Observable<boolean>(false);\n this.modelName = new Observable<string | null>(null);\n }\n\n /**\n * Update device state from WebSocket message\n *\n * Called internally by AppSession when DEVICE_STATE_UPDATE message is received.\n * Only updates Observables for fields present in the state object.\n * Observables automatically notify listeners only if value changed.\n *\n * @param state - Partial device state (only changed fields, or full snapshot)\n * @internal\n */\n updateFromMessage(state: Partial<GlassesInfo>): void {\n // Connection state\n if (state.connected !== undefined) {\n this.connected.setValue(state.connected);\n }\n if (state.modelName !== undefined) {\n this.modelName.setValue(state.modelName);\n }\n\n // WiFi state\n if (state.wifiConnected !== undefined) {\n this.wifiConnected.setValue(state.wifiConnected);\n }\n if (state.wifiSsid !== undefined) {\n this.wifiSsid.setValue(state.wifiSsid ?? null);\n }\n if (state.wifiLocalIp !== undefined) {\n this.wifiLocalIp.setValue(state.wifiLocalIp ?? null);\n }\n\n // Battery state\n if (state.batteryLevel !== undefined) {\n this.batteryLevel.setValue(state.batteryLevel ?? null);\n }\n if (state.charging !== undefined) {\n this.charging.setValue(state.charging ?? null);\n }\n if (state.caseBatteryLevel !== undefined) {\n this.caseBatteryLevel.setValue(state.caseBatteryLevel ?? null);\n }\n if (state.caseCharging !== undefined) {\n this.caseCharging.setValue(state.caseCharging ?? null);\n }\n if (state.caseOpen !== undefined) {\n this.caseOpen.setValue(state.caseOpen ?? null);\n }\n if (state.caseRemoved !== undefined) {\n this.caseRemoved.setValue(state.caseRemoved ?? null);\n }\n\n // Hotspot state\n if (state.hotspotEnabled !== undefined) {\n this.hotspotEnabled.setValue(state.hotspotEnabled ?? null);\n }\n if (state.hotspotSsid !== undefined) {\n this.hotspotSsid.setValue(state.hotspotSsid ?? null);\n }\n }\n\n /**\n * Get snapshot of current device state\n *\n * Returns a plain object with current values of all Observables.\n * Useful for compatibility with REST-style code or debugging.\n *\n * @returns Current device state as GlassesInfo partial object\n *\n * @example\n * ```typescript\n * const currentState = session.device.state.getSnapshot();\n * console.log(\"Current state:\", currentState);\n * ```\n */\n getSnapshot(): Partial<GlassesInfo> {\n return {\n // Connection\n connected: this.connected.value,\n modelName: this.modelName.value ?? undefined,\n\n // WiFi\n wifiConnected: this.wifiConnected.value,\n wifiSsid: this.wifiSsid.value ?? undefined,\n wifiLocalIp: this.wifiLocalIp.value ?? undefined,\n\n // Battery\n batteryLevel: this.batteryLevel.value ?? undefined,\n charging: this.charging.value ?? undefined,\n caseBatteryLevel: this.caseBatteryLevel.value ?? undefined,\n caseCharging: this.caseCharging.value ?? undefined,\n caseOpen: this.caseOpen.value ?? undefined,\n caseRemoved: this.caseRemoved.value ?? undefined,\n\n // Hotspot\n hotspotEnabled: this.hotspotEnabled.value ?? undefined,\n hotspotSsid: this.hotspotSsid.value ?? undefined,\n };\n }\n}\n",
|
|
65
|
-
"// src/app/webview/index.ts\nimport * as crypto from \"crypto\";\n\nimport axios from \"axios\";\nimport { Hono } from \"hono\";\nimport type { Context, Next, MiddlewareHandler } from \"hono\";\nimport { getCookie, setCookie, deleteCookie } from \"hono/cookie\";\nimport type { CookieOptions } from \"hono/utils/cookie\";\nimport { KEYUTIL, KJUR, RSAKey } from \"jsrsasign\";\n\nimport { AuthVariables, AuthenticatedRequest, MentraAuthContext, MentraAuthHonoContext } from \"../../types\";\nimport { AppSession } from \"../session\";\n\nconst userTokenPublicKey =\n process.env.MENTRAOS_CLOUD_USER_TOKEN_PUBLIC_KEY ||\n \"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Yt2RtNOdeKQxWMY0c84\\nADpY1Jy58YWZhaEgP2A5tBwFUKgy/TH9gQLWZjQ3dQ/6XXO8qq0kluoYFqM7ZDRF\\nzJ0E4Yi0WQncioLRcCx4q8pDmqY9vPKgv6PruJdFWca0l0s3gZ3BqSeWum/C23xK\\nFPHPwi8gvRdc6ALrkcHeciM+7NykU8c0EY8PSitNL+Tchti95kGu+j6APr5vNewi\\nzRpQGOdqaLWe+ahHmtj6KtUZjm8o6lan4f/o08C6litizguZXuw2Nn/Kd9fFI1xF\\nIVNJYMy9jgGaOi71+LpGw+vIpwAawp/7IvULDppvY3DdX5nt05P1+jvVJXPxMKzD\\nTQIDAQAB\\n-----END PUBLIC KEY-----\";\n\n/**\n * Extracts the temporary token from a URL string.\n * @param url The URL string, typically window.location.href.\n * @returns The token string or null if not found.\n */\nexport function extractTempToken(url: string): string | null {\n try {\n const parsedUrl = new URL(url);\n return parsedUrl.searchParams.get(\"aos_temp_token\");\n } catch (e) {\n console.error(\"Error parsing URL for temp token:\", e);\n return null;\n }\n}\n\n/**\n * Exchanges a temporary token for a user ID with the MentraOS Cloud.\n * This should be called from the App's backend server.\n * @param cloudApiUrl The base URL of the MentraOS Cloud API.\n * @param tempToken The temporary token obtained from the webview URL.\n * @param apiKey Your App's secret API key.\n * @returns A Promise that resolves with an object containing the userId.\n * @throws Throws an error if the exchange fails (e.g., invalid token, expired, network error).\n */\nexport async function exchangeToken(\n cloudApiUrl: string,\n tempToken: string,\n apiKey: string,\n packageName: string,\n): Promise<{ userId: string }> {\n const endpoint = `${cloudApiUrl}/api/auth/exchange-user-token`;\n console.log(`Exchanging token for user at ${endpoint}`);\n try {\n const response = await axios.post(\n endpoint,\n { aos_temp_token: tempToken, packageName: packageName },\n {\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${apiKey}`,\n },\n timeout: 10000, // 10 second timeout\n },\n );\n\n if (response.status === 200 && response.data.success && response.data.userId) {\n return { userId: response.data.userId };\n } else {\n // Handle specific error messages from the server if available\n const errorMessage = response.data?.error || `Failed with status ${response.status}`;\n throw new Error(errorMessage);\n }\n } catch (error) {\n if (axios.isAxiosError(error)) {\n const status = error.response?.status;\n const data = error.response?.data;\n const message = data?.error || error.message || \"Unknown error during token exchange\";\n console.error(`Token exchange failed with status ${status}: ${message}`);\n throw new Error(`Token exchange failed: ${message}`);\n } else {\n console.error(\"Unexpected error during token exchange:\", error);\n throw new Error(\"An unexpected error occurred during token exchange.\");\n }\n }\n}\n\n/**\n * Signs a user ID to create a secure session token.\n * @param userId The user ID to sign\n * @param secret The secret key used for signing\n * @returns A signed session token string\n */\nfunction signSession(userId: string, secret: string): string {\n // Format: userId.timestamp.signature\n const timestamp = Date.now();\n const data = `${userId}|${timestamp}`;\n const signature = crypto.createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n\n return `${data}|${signature}`;\n}\n\n/**\n * Verifies and extracts the user ID from a signed session token.\n * @param token The signed session token\n * @param secret The secret key used for verification\n * @param maxAge The maximum age of the token in milliseconds\n * @returns The extracted user ID if valid, or null if invalid\n */\nfunction verifySession(token: string, secret: string, maxAge?: number): string | null {\n try {\n const parts = token.split(\"|\");\n if (parts.length !== 3) return null;\n\n const [userId, timestampStr, signature] = parts;\n const timestamp = parseInt(timestampStr, 10);\n\n // Check if token has expired\n if (maxAge && Date.now() - timestamp > maxAge) {\n console.log(\n `Session token expired: ${token}. Parsed date is ${timestamp}, meaning age is ${Date.now() - timestamp}, but maxAge is ${maxAge}`,\n );\n return null;\n }\n\n // Verify signature\n const data = `${userId}|${timestamp}`;\n const expectedSignature = crypto.createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n\n if (signature !== expectedSignature) {\n console.log(`Session token signature mismatch: ${signature} !== ${expectedSignature}`);\n return null;\n }\n\n return userId;\n } catch (error) {\n console.error(\"Session verification failed:\", error);\n return null;\n }\n}\n\n/**\n * Verifies a signed user token and extracts the user ID from it\n * @param signedUserToken The JWT token to verify\n * @returns The user ID (subject) from the token, or null if invalid\n */\nasync function verifySignedUserToken(signedUserToken: string): Promise<string | null> {\n try {\n // 1. Parse the PEM public key into a jsrsasign key object\n const publicKeyObj = KEYUTIL.getKey(userTokenPublicKey) as RSAKey;\n // 2. Verify JWT signature + claims (issuer, exp, iat) with 2-min tolerance\n const isValid = KJUR.jws.JWS.verifyJWT(signedUserToken, publicKeyObj, {\n alg: [\"RS256\"],\n iss: [\"https://prod.augmentos.cloud\"],\n verifyAt: KJUR.jws.IntDate.get(\"now\"),\n gracePeriod: 120,\n });\n if (!isValid) return null;\n\n // 3. Decode payload and return the subject (user ID)\n const parsed = KJUR.jws.JWS.parse(signedUserToken);\n return (parsed.payloadObj as { sub: string }).sub || null;\n } catch (e) {\n console.error(\"[verifySignedUserToken] Error verifying token:\", e);\n return null;\n }\n}\n\n/**\n * Verifies a frontend token by comparing it to a secure hash of the API key\n * @param frontendToken The token to verify (should be a hash of the API key)\n * @param apiKey The API key to hash and compare against\n * @param userId Optional user ID that may be embedded in the token format\n * @returns The user ID if the token is valid, or null if invalid\n */\nfunction verifyFrontendToken(frontendToken: string, apiKey: string): string | null {\n try {\n // Check if the token contains a user ID and hash separated by a colon\n const tokenParts = frontendToken.split(\":\");\n\n if (tokenParts.length === 2) {\n // Format: userId:hash\n const [tokenUserId, tokenHash] = tokenParts;\n\n // Align the hashing algorithm with server-side `hashWithApiKey`\n // 1. Hash the API key first (server only stores the hashed version)\n const hashedApiKey = crypto.createHash(\"sha256\").update(apiKey).digest(\"hex\");\n // 2. Create the expected hash using userId + hashedApiKey (same order & update calls)\n const expectedHash = crypto.createHash(\"sha256\").update(tokenUserId).update(hashedApiKey).digest(\"hex\");\n\n if (tokenHash === expectedHash) {\n return tokenUserId;\n }\n } else {\n throw new Error(\"Invalid frontend token format\");\n }\n\n return null;\n } catch (error) {\n console.error(\"Frontend token verification failed:\", error);\n return null;\n }\n}\n\nfunction validateCloudApiUrlChecksum(checksum: string, cloudApiUrl: string, apiKey: string): boolean {\n const hashedApiKey = crypto.createHash(\"sha256\").update(apiKey).digest(\"hex\");\n const expectedChecksum = crypto.createHash(\"sha256\").update(cloudApiUrl).update(hashedApiKey).digest(\"hex\");\n\n return expectedChecksum === checksum;\n}\n/**\n * Hono middleware for automatically handling the token exchange.\n * Assumes API key and Cloud URL are available (e.g., via environment variables).\n * Sets context variables `authUserId` and `activeSession` if successful.\n *\n * @param options Configuration options.\n * @param options.apiKey Your App's secret API key.\n * @param options.packageName Your App's package name.\n * @param options.cookieName The name of the cookie to store the session token (default: 'aos_session').\n * @param options.cookieSecret Secret key used to sign the session cookie. MUST be provided and kept secure.\n * @param options.cookieOptions Options for the session cookie.\n */\nexport function createAuthMiddleware(options: {\n apiKey: string;\n packageName: string;\n cookieName?: string;\n cookieSecret: string;\n getAppSessionForUser?: (userId: string) => AppSession | null;\n cookieOptions?: {\n httpOnly?: boolean;\n secure?: boolean;\n maxAge?: number;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n path?: string;\n };\n}): MiddlewareHandler<{ Variables: AuthVariables }> {\n const {\n apiKey,\n packageName,\n // Default to packageName-session to match createMentraAuthRoutes.\n // \"aos_session\" was the old default — we fall back to it below for\n // backwards compatibility with 2.x apps that may have existing cookies.\n cookieName = `${packageName}-session`,\n cookieSecret,\n getAppSessionForUser,\n cookieOptions = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n maxAge: 30 * 24 * 60 * 60, // 30 days in seconds for Hono\n sameSite: process.env.NODE_ENV === \"production\" ? \"None\" : \"Lax\",\n path: \"/\",\n },\n } = options;\n\n // Legacy cookie name used by 2.x Express SDK and early Hono SDK versions.\n // We check this as a fallback and silently migrate the user to the new name.\n const legacyCookieName = \"aos_session\";\n\n if (!apiKey) {\n throw new Error(\"API Key is required for the auth middleware.\");\n }\n\n if (!cookieSecret || typeof cookieSecret !== \"string\" || cookieSecret.length < 8) {\n throw new Error(\"A strong cookieSecret (at least 8 characters) is required for secure session management.\");\n }\n\n return async (c: Context<{ Variables: AuthVariables }>, next: Next) => {\n // Helper to set auth and continue\n const setAuthAndContinue = async (userId: string) => {\n c.set(\"authUserId\", userId);\n if (getAppSessionForUser) {\n const appSession = getAppSessionForUser(userId);\n c.set(\"activeSession\", appSession);\n } else {\n c.set(\"activeSession\", null);\n }\n\n // Create and set session cookie\n const signedSession = signSession(userId, cookieSecret);\n setCookie(c, cookieName, signedSession, cookieOptions as CookieOptions);\n await next();\n };\n\n // Get query params and headers\n const tempToken = c.req.query(\"aos_temp_token\");\n const signedUserToken = c.req.query(\"aos_signed_user_token\");\n const authHeader = c.req.header(\"authorization\");\n const frontendToken = authHeader?.replace(\"Bearer \", \"\") || c.req.query(\"aos_frontend_token\");\n\n // First check for signed user token\n if (signedUserToken) {\n const userId = await verifySignedUserToken(signedUserToken);\n if (userId) {\n console.log(\"[auth.middleware] User ID verified from signed user token:\", userId);\n return setAuthAndContinue(userId);\n } else {\n console.log(\"[auth.middleware] Signed user token invalid\");\n }\n }\n\n // If temporary token exists, authenticate with it\n if (tempToken) {\n try {\n let cloudApiUrl = `https://api.mentra.glass`;\n const cloudApiUrlFromQuery = c.req.query(\"cloudApiUrl\");\n if (cloudApiUrlFromQuery) {\n const cloudApiUrlChecksum = c.req.query(\"cloudApiUrlChecksum\");\n\n if (cloudApiUrlChecksum && validateCloudApiUrlChecksum(cloudApiUrlChecksum, cloudApiUrlFromQuery, apiKey)) {\n console.log(`Cloud API is being routed to alternate url at request of the server: ${cloudApiUrlFromQuery}`);\n cloudApiUrl = cloudApiUrlFromQuery;\n } else {\n console.error(\n `Server requested alternate cloud url of ${cloudApiUrlFromQuery} but the checksum is invalid. Using default cloud url.`,\n );\n }\n }\n\n const { userId } = await exchangeToken(cloudApiUrl, tempToken, apiKey, packageName);\n\n console.log(\"[auth.middleware] User ID verified from temporary token:\", userId);\n return setAuthAndContinue(userId);\n } catch (error) {\n console.error(\"Webview token exchange failed:\", error);\n // Continue to check other auth methods\n }\n }\n\n // Check frontend token\n if (frontendToken) {\n const userId = verifyFrontendToken(frontendToken, apiKey);\n\n if (userId) {\n console.log(\"[auth.middleware] User ID verified from frontend user token:\", userId);\n return setAuthAndContinue(userId);\n } else {\n console.log(\"[auth.middleware] Frontend token invalid\");\n }\n }\n\n // No valid temporary token, check for existing session cookie.\n // Check the current cookie name first, then fall back to the legacy\n // \"aos_session\" name used by 2.x apps and early Hono SDK versions.\n const sessionCookie =\n getCookie(c, cookieName) ?? (cookieName !== legacyCookieName ? getCookie(c, legacyCookieName) : undefined);\n\n if (sessionCookie) {\n try {\n // Verify the signed session cookie and extract the user ID\n // Convert maxAge from seconds to milliseconds for verifySession\n const userId = verifySession(\n sessionCookie,\n cookieSecret,\n cookieOptions.maxAge ? cookieOptions.maxAge * 1000 : undefined,\n );\n if (userId) {\n c.set(\"authUserId\", userId);\n if (getAppSessionForUser) {\n const appSession = getAppSessionForUser(userId);\n c.set(\"activeSession\", appSession);\n } else {\n c.set(\"activeSession\", null);\n }\n // If the cookie was found under the legacy name, silently migrate\n // it to the current name so future requests use the new cookie.\n if (!getCookie(c, cookieName)) {\n setCookie(c, cookieName, sessionCookie, cookieOptions as CookieOptions);\n deleteCookie(c, legacyCookieName, { path: cookieOptions.path });\n }\n return next();\n }\n\n // Invalid or expired session, clear both cookie names\n deleteCookie(c, cookieName, { path: cookieOptions.path });\n deleteCookie(c, legacyCookieName, { path: cookieOptions.path });\n } catch (error) {\n console.error(\"Invalid session cookie:\", error);\n // Clear the invalid cookie under both names\n deleteCookie(c, cookieName, { path: cookieOptions.path });\n deleteCookie(c, legacyCookieName, { path: cookieOptions.path });\n }\n }\n\n // No valid authentication method found, proceed without setting authUserId\n c.set(\"activeSession\", null);\n await next();\n };\n}\n\n/**\n * Read the authenticated Mentra context from a Hono request context.\n *\n * This helper intentionally hides the underlying context variable names so\n * app code does not depend on implementation details like `authUserId`.\n */\nexport function getMentraAuth(c: MentraAuthHonoContext): MentraAuthContext {\n return {\n userId: c.get(\"authUserId\") ?? null,\n session: c.get(\"activeSession\") ?? null,\n };\n}\n\n/**\n * Read the authenticated Mentra context and throw if no authenticated user\n * is present. Intended for SDK-owned middleware / helpers that want a strict\n * contract after authentication has been enforced.\n */\nexport function requireMentraAuth(c: MentraAuthHonoContext): {\n userId: string;\n session: AppSession | null;\n} {\n const auth = getMentraAuth(c);\n if (!auth.userId) {\n throw new Error(\"Unauthenticated Mentra request\");\n }\n\n return {\n userId: auth.userId,\n session: auth.session,\n };\n}\n\n/**\n * Generates a frontend token for client-side authentication.\n * The token format is userId:hash where hash = sha256(userId + sha256(apiKey))\n * @param userId The user ID to embed in the token\n * @param apiKey The app's API key\n * @returns A frontend token string\n */\nexport function generateFrontendToken(userId: string, apiKey: string): string {\n const hashedApiKey = crypto.createHash(\"sha256\").update(apiKey).digest(\"hex\");\n const hash = crypto.createHash(\"sha256\").update(userId).update(hashedApiKey).digest(\"hex\");\n return `${userId}:${hash}`;\n}\n\n/**\n * Creates a Hono sub-app with authentication routes for frontend token exchange.\n * Mount this at /api/mentra/auth to enable frontend-initiated authentication.\n *\n * This is required for apps using Bun's fullstack dev server where the HTML\n * is served directly by Bun's routes (bypassing Hono middleware).\n *\n * @example\n * ```typescript\n * import { createMentraAuthRoutes } from \"@mentra/sdk\";\n *\n * const app = new MyAppServer({...});\n *\n * app.route(\"/api/mentra/auth\", createMentraAuthRoutes({\n * apiKey: API_KEY,\n * packageName: PACKAGE_NAME,\n * cookieSecret: COOKIE_SECRET,\n * }));\n * ```\n */\nexport function createMentraAuthRoutes(options: {\n apiKey: string;\n packageName: string;\n cookieSecret: string;\n cookieOptions?: {\n httpOnly?: boolean;\n secure?: boolean;\n maxAge?: number;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n path?: string;\n };\n}): Hono {\n const {\n apiKey,\n packageName,\n cookieSecret,\n cookieOptions = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n maxAge: 30 * 24 * 60 * 60, // 30 days in seconds\n sameSite: process.env.NODE_ENV === \"production\" ? \"None\" : \"Lax\",\n path: \"/\",\n },\n } = options;\n\n if (!apiKey) {\n throw new Error(\"API Key is required for Mentra auth routes.\");\n }\n\n if (!cookieSecret || typeof cookieSecret !== \"string\" || cookieSecret.length < 8) {\n throw new Error(\"A strong cookieSecret (at least 8 characters) is required.\");\n }\n\n const authRouter = new Hono();\n const cookieName = `${packageName}-session`; // Must match createAuthMiddleware\n\n /**\n * GET /init - Exchange aos_temp_token for session\n * Query params:\n * - aos_temp_token: The temporary token from MentraOS Cloud\n * - cloudApiUrl: (optional) Custom cloud API URL\n * - cloudApiUrlChecksum: (optional) Checksum for custom cloud URL\n */\n authRouter.get(\"/init\", async (c) => {\n const tempToken = c.req.query(\"aos_temp_token\");\n const signedUserToken = c.req.query(\"aos_signed_user_token\");\n\n // First try signed user token (JWT)\n if (signedUserToken) {\n const userId = await verifySignedUserToken(signedUserToken);\n if (userId) {\n const frontendToken = generateFrontendToken(userId, apiKey);\n const signedSession = signSession(userId, cookieSecret);\n setCookie(c, cookieName, signedSession, cookieOptions as CookieOptions);\n\n console.log(\"[mentra/auth/init] User authenticated via signed user token:\", userId);\n return c.json({ success: true, userId, frontendToken });\n }\n return c.json({ success: false, error: \"Invalid signed user token\" }, 401);\n }\n\n // Try temp token exchange\n if (tempToken) {\n try {\n let cloudApiUrl = \"https://api.mentra.glass\";\n const cloudApiUrlFromQuery = c.req.query(\"cloudApiUrl\");\n if (cloudApiUrlFromQuery) {\n const checksum = c.req.query(\"cloudApiUrlChecksum\");\n if (checksum && validateCloudApiUrlChecksum(checksum, cloudApiUrlFromQuery, apiKey)) {\n cloudApiUrl = cloudApiUrlFromQuery;\n }\n }\n\n const { userId } = await exchangeToken(cloudApiUrl, tempToken, apiKey, packageName);\n const frontendToken = generateFrontendToken(userId, apiKey);\n const signedSession = signSession(userId, cookieSecret);\n setCookie(c, cookieName, signedSession, cookieOptions as CookieOptions);\n\n console.log(\"[mentra/auth/init] User authenticated via temp token:\", userId);\n return c.json({ success: true, userId, frontendToken });\n } catch (error) {\n console.error(\"[mentra/auth/init] Token exchange failed:\", error);\n return c.json({ success: false, error: \"Token exchange failed\" }, 401);\n }\n }\n\n return c.json({ success: false, error: \"No token provided\" }, 400);\n });\n\n return authRouter;\n}\n",
|
|
65
|
+
"// src/app/webview/index.ts\nimport * as crypto from \"crypto\";\n\nimport axios from \"axios\";\nimport { Hono } from \"hono\";\nimport type { Context, Next, MiddlewareHandler } from \"hono\";\nimport { getCookie, setCookie, deleteCookie } from \"hono/cookie\";\nimport type { CookieOptions } from \"hono/utils/cookie\";\nimport { KEYUTIL, KJUR, RSAKey } from \"jsrsasign\";\n\nimport { AuthVariables, AuthenticatedRequest, MentraAuthContext, MentraAuthHonoContext } from \"../../types\";\nimport { AppSession } from \"../session\";\n\nconst userTokenPublicKey =\n process.env.MENTRAOS_CLOUD_USER_TOKEN_PUBLIC_KEY ||\n \"-----BEGIN PUBLIC KEY-----\\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0Yt2RtNOdeKQxWMY0c84\\nADpY1Jy58YWZhaEgP2A5tBwFUKgy/TH9gQLWZjQ3dQ/6XXO8qq0kluoYFqM7ZDRF\\nzJ0E4Yi0WQncioLRcCx4q8pDmqY9vPKgv6PruJdFWca0l0s3gZ3BqSeWum/C23xK\\nFPHPwi8gvRdc6ALrkcHeciM+7NykU8c0EY8PSitNL+Tchti95kGu+j6APr5vNewi\\nzRpQGOdqaLWe+ahHmtj6KtUZjm8o6lan4f/o08C6litizguZXuw2Nn/Kd9fFI1xF\\nIVNJYMy9jgGaOi71+LpGw+vIpwAawp/7IvULDppvY3DdX5nt05P1+jvVJXPxMKzD\\nTQIDAQAB\\n-----END PUBLIC KEY-----\";\n\n/**\n * Extracts the temporary token from a URL string.\n * @param url The URL string, typically window.location.href.\n * @returns The token string or null if not found.\n */\nexport function extractTempToken(url: string): string | null {\n try {\n const parsedUrl = new URL(url);\n return parsedUrl.searchParams.get(\"aos_temp_token\");\n } catch (e) {\n console.error(\"Error parsing URL for temp token:\", e);\n return null;\n }\n}\n\n/**\n * Exchanges a temporary token for a user ID with the MentraOS Cloud.\n * This should be called from the App's backend server.\n * @param cloudApiUrl The base URL of the MentraOS Cloud API.\n * @param tempToken The temporary token obtained from the webview URL.\n * @param apiKey Your App's secret API key.\n * @returns A Promise that resolves with an object containing the userId.\n * @throws Throws an error if the exchange fails (e.g., invalid token, expired, network error).\n */\nexport async function exchangeToken(\n cloudApiUrl: string,\n tempToken: string,\n apiKey: string,\n packageName: string,\n): Promise<{ userId: string }> {\n const endpoint = `${cloudApiUrl}/api/auth/exchange-user-token`;\n console.log(`Exchanging token for user at ${endpoint}`);\n try {\n const response = await axios.post(\n endpoint,\n { aos_temp_token: tempToken, packageName: packageName },\n {\n headers: {\n \"Content-Type\": \"application/json\",\n \"Authorization\": `Bearer ${apiKey}`,\n },\n timeout: 10000, // 10 second timeout\n },\n );\n\n if (response.status === 200 && response.data.success && response.data.userId) {\n return { userId: response.data.userId };\n } else {\n // Handle specific error messages from the server if available\n const errorMessage = response.data?.error || `Failed with status ${response.status}`;\n throw new Error(errorMessage);\n }\n } catch (error) {\n if (axios.isAxiosError(error)) {\n const status = error.response?.status;\n const data = error.response?.data;\n const message = data?.error || error.message || \"Unknown error during token exchange\";\n console.error(`Token exchange failed with status ${status}: ${message}`);\n throw new Error(`Token exchange failed: ${message}`);\n } else {\n console.error(\"Unexpected error during token exchange:\", error);\n throw new Error(\"An unexpected error occurred during token exchange.\");\n }\n }\n}\n\n/**\n * Signs a user ID to create a secure session token.\n * @param userId The user ID to sign\n * @param secret The secret key used for signing\n * @returns A signed session token string\n */\nfunction signSession(userId: string, secret: string): string {\n // Format: userId.timestamp.signature\n const timestamp = Date.now();\n const data = `${userId}|${timestamp}`;\n const signature = crypto.createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n\n return `${data}|${signature}`;\n}\n\n/**\n * Verifies and extracts the user ID from a signed session token.\n * @param token The signed session token\n * @param secret The secret key used for verification\n * @param maxAge The maximum age of the token in milliseconds\n * @returns The extracted user ID if valid, or null if invalid\n */\nfunction verifySession(token: string, secret: string, maxAge?: number): string | null {\n try {\n const parts = token.split(\"|\");\n if (parts.length !== 3) return null;\n\n const [userId, timestampStr, signature] = parts;\n const timestamp = parseInt(timestampStr, 10);\n\n // Check if token has expired\n if (maxAge && Date.now() - timestamp > maxAge) {\n console.log(\n `Session token expired: ${token}. Parsed date is ${timestamp}, meaning age is ${Date.now() - timestamp}, but maxAge is ${maxAge}`,\n );\n return null;\n }\n\n // Verify signature\n const data = `${userId}|${timestamp}`;\n const expectedSignature = crypto.createHmac(\"sha256\", secret).update(data).digest(\"hex\");\n\n if (signature !== expectedSignature) {\n console.log(`Session token signature mismatch: ${signature} !== ${expectedSignature}`);\n return null;\n }\n\n return userId;\n } catch (error) {\n console.error(\"Session verification failed:\", error);\n return null;\n }\n}\n\n/**\n * Verifies a signed user token and extracts the user ID from it\n * @param signedUserToken The JWT token to verify\n * @returns The user ID (subject) from the token, or null if invalid\n */\nasync function verifySignedUserToken(signedUserToken: string): Promise<string | null> {\n try {\n // 1. Parse the PEM public key into a jsrsasign key object\n const publicKeyObj = KEYUTIL.getKey(userTokenPublicKey) as RSAKey;\n // 2. Verify JWT signature + claims (issuer, exp, iat) with 2-min tolerance\n const isValid = KJUR.jws.JWS.verifyJWT(signedUserToken, publicKeyObj, {\n alg: [\"RS256\"],\n iss: [\"https://prod.augmentos.cloud\"],\n verifyAt: KJUR.jws.IntDate.get(\"now\"),\n gracePeriod: 120,\n });\n if (!isValid) return null;\n\n // 3. Decode payload and return the subject (user ID)\n const parsed = KJUR.jws.JWS.parse(signedUserToken);\n return (parsed.payloadObj as { sub: string }).sub || null;\n } catch (e) {\n console.error(\"[verifySignedUserToken] Error verifying token:\", e);\n return null;\n }\n}\n\n/**\n * Verifies a frontend token by comparing it to a secure hash of the API key\n * @param frontendToken The token to verify (should be a hash of the API key)\n * @param apiKey The API key to hash and compare against\n * @param userId Optional user ID that may be embedded in the token format\n * @returns The user ID if the token is valid, or null if invalid\n */\nfunction verifyFrontendToken(frontendToken: string, apiKey: string): string | null {\n try {\n // Check if the token contains a user ID and hash separated by a colon\n const tokenParts = frontendToken.split(\":\");\n\n if (tokenParts.length === 2) {\n // Format: userId:hash\n const [tokenUserId, tokenHash] = tokenParts;\n\n // Align the hashing algorithm with server-side `hashWithApiKey`\n // 1. Hash the API key first (server only stores the hashed version)\n const hashedApiKey = crypto.createHash(\"sha256\").update(apiKey).digest(\"hex\");\n // 2. Create the expected hash using userId + hashedApiKey (same order & update calls)\n const expectedHash = crypto.createHash(\"sha256\").update(tokenUserId).update(hashedApiKey).digest(\"hex\");\n\n if (tokenHash === expectedHash) {\n return tokenUserId;\n }\n } else {\n throw new Error(\"Invalid frontend token format\");\n }\n\n return null;\n } catch (error) {\n console.error(\"Frontend token verification failed:\", error);\n return null;\n }\n}\n\nfunction validateCloudApiUrlChecksum(checksum: string, cloudApiUrl: string, apiKey: string): boolean {\n const hashedApiKey = crypto.createHash(\"sha256\").update(apiKey).digest(\"hex\");\n const expectedChecksum = crypto.createHash(\"sha256\").update(cloudApiUrl).update(hashedApiKey).digest(\"hex\");\n\n return expectedChecksum === checksum;\n}\n/**\n * Hono middleware for automatically handling the token exchange.\n * Assumes API key and Cloud URL are available (e.g., via environment variables).\n * Sets context variables `authUserId` and `activeSession` if successful.\n *\n * @param options Configuration options.\n * @param options.apiKey Your App's secret API key.\n * @param options.packageName Your App's package name.\n * @param options.cookieName The name of the cookie to store the session token (default: 'aos_session').\n * @param options.cookieSecret Secret key used to sign the session cookie. MUST be provided and kept secure.\n * @param options.cookieOptions Options for the session cookie.\n */\nexport function createAuthMiddleware(options: {\n apiKey: string;\n packageName: string;\n cookieName?: string;\n cookieSecret: string;\n getAppSessionForUser?: (userId: string) => AppSession | null;\n cookieOptions?: {\n httpOnly?: boolean;\n secure?: boolean;\n maxAge?: number;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n path?: string;\n };\n}): MiddlewareHandler<{ Variables: AuthVariables }> {\n const {\n apiKey,\n packageName,\n // Default to packageName-session to match createMentraAuthRoutes.\n // \"aos_session\" was the old default — we fall back to it below for\n // backwards compatibility with 2.x apps that may have existing cookies.\n cookieName = `${packageName}-session`,\n cookieSecret,\n getAppSessionForUser,\n cookieOptions = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n maxAge: 30 * 24 * 60 * 60, // 30 days in seconds for Hono\n sameSite: process.env.NODE_ENV === \"production\" ? \"None\" : \"Lax\",\n path: \"/\",\n },\n } = options;\n\n // Legacy cookie name used by 2.x Express SDK and early Hono SDK versions.\n // We check this as a fallback and silently migrate the user to the new name.\n const legacyCookieName = \"aos_session\";\n\n if (!apiKey) {\n throw new Error(\"API Key is required for the auth middleware.\");\n }\n\n if (!cookieSecret || typeof cookieSecret !== \"string\" || cookieSecret.length < 8) {\n throw new Error(\"A strong cookieSecret (at least 8 characters) is required for secure session management.\");\n }\n\n return async (c: Context<{ Variables: AuthVariables }>, next: Next) => {\n // Helper to set auth and continue\n const setAuthAndContinue = async (userId: string) => {\n c.set(\"authUserId\", userId);\n if (getAppSessionForUser) {\n const appSession = getAppSessionForUser(userId);\n c.set(\"activeSession\", appSession);\n } else {\n c.set(\"activeSession\", null);\n }\n\n // Create and set session cookie\n const signedSession = signSession(userId, cookieSecret);\n setCookie(c, cookieName, signedSession, cookieOptions as CookieOptions);\n await next();\n };\n\n // Get query params and headers\n const tempToken = c.req.query(\"aos_temp_token\");\n const signedUserToken = c.req.query(\"aos_signed_user_token\");\n const authHeader = c.req.header(\"authorization\");\n const frontendToken = authHeader?.replace(\"Bearer \", \"\") || c.req.query(\"aos_frontend_token\");\n\n // First check for signed user token\n if (signedUserToken) {\n const userId = await verifySignedUserToken(signedUserToken);\n if (userId) {\n console.debug(\"[auth.middleware] Authenticated via signed user token\");\n return setAuthAndContinue(userId);\n } else {\n console.log(\"[auth.middleware] Signed user token invalid\");\n }\n }\n\n // If temporary token exists, authenticate with it\n if (tempToken) {\n try {\n let cloudApiUrl = `https://api.mentra.glass`;\n const cloudApiUrlFromQuery = c.req.query(\"cloudApiUrl\");\n if (cloudApiUrlFromQuery) {\n const cloudApiUrlChecksum = c.req.query(\"cloudApiUrlChecksum\");\n\n if (cloudApiUrlChecksum && validateCloudApiUrlChecksum(cloudApiUrlChecksum, cloudApiUrlFromQuery, apiKey)) {\n console.log(`Cloud API is being routed to alternate url at request of the server: ${cloudApiUrlFromQuery}`);\n cloudApiUrl = cloudApiUrlFromQuery;\n } else {\n console.error(\n `Server requested alternate cloud url of ${cloudApiUrlFromQuery} but the checksum is invalid. Using default cloud url.`,\n );\n }\n }\n\n const { userId } = await exchangeToken(cloudApiUrl, tempToken, apiKey, packageName);\n\n console.debug(\"[auth.middleware] Authenticated via temporary token\");\n return setAuthAndContinue(userId);\n } catch (error) {\n console.error(\"Webview token exchange failed:\", error);\n // Continue to check other auth methods\n }\n }\n\n // Check frontend token\n if (frontendToken) {\n const userId = verifyFrontendToken(frontendToken, apiKey);\n\n if (userId) {\n console.debug(\"[auth.middleware] Authenticated via frontend token\");\n return setAuthAndContinue(userId);\n } else {\n console.log(\"[auth.middleware] Frontend token invalid\");\n }\n }\n\n // No valid temporary token, check for existing session cookie.\n // Check the current cookie name first, then fall back to the legacy\n // \"aos_session\" name used by 2.x apps and early Hono SDK versions.\n const sessionCookie =\n getCookie(c, cookieName) ?? (cookieName !== legacyCookieName ? getCookie(c, legacyCookieName) : undefined);\n\n if (sessionCookie) {\n try {\n // Verify the signed session cookie and extract the user ID\n // Convert maxAge from seconds to milliseconds for verifySession\n const userId = verifySession(\n sessionCookie,\n cookieSecret,\n cookieOptions.maxAge ? cookieOptions.maxAge * 1000 : undefined,\n );\n if (userId) {\n c.set(\"authUserId\", userId);\n if (getAppSessionForUser) {\n const appSession = getAppSessionForUser(userId);\n c.set(\"activeSession\", appSession);\n } else {\n c.set(\"activeSession\", null);\n }\n // If the cookie was found under the legacy name, silently migrate\n // it to the current name so future requests use the new cookie.\n if (!getCookie(c, cookieName)) {\n setCookie(c, cookieName, sessionCookie, cookieOptions as CookieOptions);\n deleteCookie(c, legacyCookieName, { path: cookieOptions.path });\n }\n return next();\n }\n\n // Invalid or expired session, clear both cookie names\n deleteCookie(c, cookieName, { path: cookieOptions.path });\n deleteCookie(c, legacyCookieName, { path: cookieOptions.path });\n } catch (error) {\n console.error(\"Invalid session cookie:\", error);\n // Clear the invalid cookie under both names\n deleteCookie(c, cookieName, { path: cookieOptions.path });\n deleteCookie(c, legacyCookieName, { path: cookieOptions.path });\n }\n }\n\n // No valid authentication method found, proceed without setting authUserId\n c.set(\"activeSession\", null);\n await next();\n };\n}\n\n/**\n * Read the authenticated Mentra context from a Hono request context.\n *\n * This helper intentionally hides the underlying context variable names so\n * app code does not depend on implementation details like `authUserId`.\n */\nexport function getMentraAuth(c: MentraAuthHonoContext): MentraAuthContext {\n return {\n userId: c.get(\"authUserId\") ?? null,\n session: c.get(\"activeSession\") ?? null,\n };\n}\n\n/**\n * Read the authenticated Mentra context and throw if no authenticated user\n * is present. Intended for SDK-owned middleware / helpers that want a strict\n * contract after authentication has been enforced.\n */\nexport function requireMentraAuth(c: MentraAuthHonoContext): {\n userId: string;\n session: AppSession | null;\n} {\n const auth = getMentraAuth(c);\n if (!auth.userId) {\n throw new Error(\"Unauthenticated Mentra request\");\n }\n\n return {\n userId: auth.userId,\n session: auth.session,\n };\n}\n\n/**\n * Generates a frontend token for client-side authentication.\n * The token format is userId:hash where hash = sha256(userId + sha256(apiKey))\n * @param userId The user ID to embed in the token\n * @param apiKey The app's API key\n * @returns A frontend token string\n */\nexport function generateFrontendToken(userId: string, apiKey: string): string {\n const hashedApiKey = crypto.createHash(\"sha256\").update(apiKey).digest(\"hex\");\n const hash = crypto.createHash(\"sha256\").update(userId).update(hashedApiKey).digest(\"hex\");\n return `${userId}:${hash}`;\n}\n\n/**\n * Creates a Hono sub-app with authentication routes for frontend token exchange.\n * Mount this at /api/mentra/auth to enable frontend-initiated authentication.\n *\n * This is required for apps using Bun's fullstack dev server where the HTML\n * is served directly by Bun's routes (bypassing Hono middleware).\n *\n * @example\n * ```typescript\n * import { createMentraAuthRoutes } from \"@mentra/sdk\";\n *\n * const app = new MyAppServer({...});\n *\n * app.route(\"/api/mentra/auth\", createMentraAuthRoutes({\n * apiKey: API_KEY,\n * packageName: PACKAGE_NAME,\n * cookieSecret: COOKIE_SECRET,\n * }));\n * ```\n */\nexport function createMentraAuthRoutes(options: {\n apiKey: string;\n packageName: string;\n cookieSecret: string;\n cookieOptions?: {\n httpOnly?: boolean;\n secure?: boolean;\n maxAge?: number;\n sameSite?: \"Lax\" | \"Strict\" | \"None\";\n path?: string;\n };\n}): Hono {\n const {\n apiKey,\n packageName,\n cookieSecret,\n cookieOptions = {\n httpOnly: true,\n secure: process.env.NODE_ENV === \"production\",\n maxAge: 30 * 24 * 60 * 60, // 30 days in seconds\n sameSite: process.env.NODE_ENV === \"production\" ? \"None\" : \"Lax\",\n path: \"/\",\n },\n } = options;\n\n if (!apiKey) {\n throw new Error(\"API Key is required for Mentra auth routes.\");\n }\n\n if (!cookieSecret || typeof cookieSecret !== \"string\" || cookieSecret.length < 8) {\n throw new Error(\"A strong cookieSecret (at least 8 characters) is required.\");\n }\n\n const authRouter = new Hono();\n const cookieName = `${packageName}-session`; // Must match createAuthMiddleware\n\n /**\n * GET /init - Exchange aos_temp_token for session\n * Query params:\n * - aos_temp_token: The temporary token from MentraOS Cloud\n * - cloudApiUrl: (optional) Custom cloud API URL\n * - cloudApiUrlChecksum: (optional) Checksum for custom cloud URL\n */\n authRouter.get(\"/init\", async (c) => {\n const tempToken = c.req.query(\"aos_temp_token\");\n const signedUserToken = c.req.query(\"aos_signed_user_token\");\n\n // First try signed user token (JWT)\n if (signedUserToken) {\n const userId = await verifySignedUserToken(signedUserToken);\n if (userId) {\n const frontendToken = generateFrontendToken(userId, apiKey);\n const signedSession = signSession(userId, cookieSecret);\n setCookie(c, cookieName, signedSession, cookieOptions as CookieOptions);\n\n console.log(\"[mentra/auth/init] User authenticated via signed user token:\", userId);\n return c.json({ success: true, userId, frontendToken });\n }\n return c.json({ success: false, error: \"Invalid signed user token\" }, 401);\n }\n\n // Try temp token exchange\n if (tempToken) {\n try {\n let cloudApiUrl = \"https://api.mentra.glass\";\n const cloudApiUrlFromQuery = c.req.query(\"cloudApiUrl\");\n if (cloudApiUrlFromQuery) {\n const checksum = c.req.query(\"cloudApiUrlChecksum\");\n if (checksum && validateCloudApiUrlChecksum(checksum, cloudApiUrlFromQuery, apiKey)) {\n cloudApiUrl = cloudApiUrlFromQuery;\n }\n }\n\n const { userId } = await exchangeToken(cloudApiUrl, tempToken, apiKey, packageName);\n const frontendToken = generateFrontendToken(userId, apiKey);\n const signedSession = signSession(userId, cookieSecret);\n setCookie(c, cookieName, signedSession, cookieOptions as CookieOptions);\n\n console.log(\"[mentra/auth/init] User authenticated via temp token:\", userId);\n return c.json({ success: true, userId, frontendToken });\n } catch (error) {\n console.error(\"[mentra/auth/init] Token exchange failed:\", error);\n return c.json({ success: false, error: \"Token exchange failed\" }, 401);\n }\n }\n\n return c.json({ success: false, error: \"No token provided\" }, 400);\n });\n\n return authRouter;\n}\n",
|
|
66
66
|
"/**\n * 🔐 App Token Module\n *\n * Provides utilities for working with App tokens.\n */\nexport * from './utils';",
|
|
67
67
|
"/**\n * WebSocketTransport\n *\n * Transport implementation that wraps the `ws` library for cloud/server apps.\n * Used by MentraApp to connect MentraSession instances to the cloud.\n *\n * This is the ONLY file in the SDK that imports `ws` — the session layer\n * and all managers are transport-agnostic and never touch WebSocket directly.\n *\n * @example\n * ```ts\n * const transport = new WebSocketTransport(\"wss://cloud.mentra.glass/ws/miniapp\", {\n * headers: { Authorization: `Bearer ${jwt}` },\n * timeoutMs: 10000,\n * });\n *\n * transport.onMessage((data) => console.log(\"received:\", data));\n * transport.onClose((code, reason) => console.log(\"closed:\", code, reason));\n *\n * await transport.connect();\n * transport.send(JSON.stringify({ type: \"connection_init\", ... }));\n * ```\n */\n\nimport { WebSocket } from \"ws\";\nimport { Transport, TransportState, TransportOptions } from \"./Transport\";\n\n// ─── Configuration ──────────────────────────────────────────────────────────\n\nexport interface WebSocketTransportOptions extends TransportOptions {\n /** WebSocket URL to connect to (wss:// or ws://) */\n url: string;\n\n /** Headers sent during the WebSocket upgrade request */\n headers?: Record<string, string>;\n\n /** Connection timeout in milliseconds (default: 10000) */\n timeoutMs?: number;\n\n /**\n * If true, the transport will attempt to connect immediately on construction.\n * If false (default), call connect() manually.\n */\n connectOnCreate?: boolean;\n}\n\n// ─── Implementation ─────────────────────────────────────────────────────────\n\nexport class WebSocketTransport implements Transport {\n private ws: WebSocket | null = null;\n private _readyState: TransportState = TransportState.CLOSED;\n\n // Handler slots — only one handler per event type (last registration wins)\n private _onMessage: ((data: string) => void) | null = null;\n private _onBinary: ((data: ArrayBuffer) => void) | null = null;\n private _onClose: ((code: number, reason: string) => void) | null = null;\n private _onError: ((error: Error) => void) | null = null;\n\n private readonly url: string;\n private readonly headers: Record<string, string>;\n private readonly timeoutMs: number;\n\n constructor(options: WebSocketTransportOptions) {\n this.url = options.url;\n this.headers = options.headers ?? {};\n this.timeoutMs = options.timeoutMs ?? 10000;\n\n if (options.connectOnCreate) {\n this.connect();\n }\n }\n\n // ─── Transport Interface ────────────────────────────────────────────────\n\n get readyState(): TransportState {\n // Prefer the real WebSocket readyState if available\n if (this.ws) {\n return this.ws.readyState as TransportState;\n }\n return this._readyState;\n }\n\n send(data: string): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n // Silently drop — callers should check readyState if they care\n return;\n }\n try {\n this.ws.send(data);\n } catch {\n // Send failures on a closing socket are expected; swallow them\n }\n }\n\n sendBinary(data: ArrayBuffer | Uint8Array): void {\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\n return;\n }\n try {\n this.ws.send(data);\n } catch {\n // Swallow send errors on closing sockets\n }\n }\n\n onMessage(handler: (data: string) => void): void {\n this._onMessage = handler;\n }\n\n onBinary(handler: (data: ArrayBuffer) => void): void {\n this._onBinary = handler;\n }\n\n onClose(handler: (code: number, reason: string) => void): void {\n this._onClose = handler;\n }\n\n onError(handler: (error: Error) => void): void {\n this._onError = handler;\n }\n\n close(code?: number, reason?: string): void {\n if (!this.ws) {\n this._readyState = TransportState.CLOSED;\n return;\n }\n\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n this._readyState = TransportState.CLOSING;\n try {\n this.ws.close(code ?? 1000, reason ?? \"\");\n } catch {\n // Already closing or closed\n this._readyState = TransportState.CLOSED;\n }\n }\n }\n\n // ─── Connection Management ──────────────────────────────────────────────\n\n /**\n * Establish the WebSocket connection.\n * Resolves when the connection is open, rejects on error or timeout.\n */\n connect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n if (this.ws) {\n // Clean up previous connection\n this.detachListeners();\n if (this.ws.readyState === WebSocket.OPEN || this.ws.readyState === WebSocket.CONNECTING) {\n try {\n this.ws.close();\n } catch {\n // Ignore\n }\n }\n this.ws = null;\n }\n\n this._readyState = TransportState.CONNECTING;\n\n // Connection timeout\n let settled = false;\n const timeout = setTimeout(() => {\n if (!settled) {\n settled = true;\n this._readyState = TransportState.CLOSED;\n if (this.ws) {\n try {\n this.ws.close();\n } catch {\n // Ignore\n }\n }\n reject(new Error(`WebSocket connection timed out after ${this.timeoutMs}ms`));\n }\n }, this.timeoutMs);\n\n try {\n this.ws = new WebSocket(this.url, {\n headers: this.headers,\n });\n\n // Handle binary data as ArrayBuffer (not Buffer)\n this.ws.binaryType = \"arraybuffer\";\n\n this.ws.addEventListener(\"open\", () => {\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n this._readyState = TransportState.OPEN;\n resolve();\n }\n });\n\n this.ws.addEventListener(\"message\", (event) => {\n this.handleIncomingMessage(event.data);\n });\n\n this.ws.addEventListener(\"close\", (event) => {\n this._readyState = TransportState.CLOSED;\n\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n reject(new Error(`WebSocket closed before open: code=${event.code} reason=${event.reason}`));\n }\n\n if (this._onClose) {\n try {\n this._onClose(event.code, event.reason || \"\");\n } catch {\n // Don't let handler errors propagate\n }\n }\n });\n\n this.ws.addEventListener(\"error\", (event) => {\n const error = event instanceof Error ? event : new Error(\"WebSocket error\");\n\n if (!settled) {\n settled = true;\n clearTimeout(timeout);\n this._readyState = TransportState.CLOSED;\n reject(error);\n }\n\n if (this._onError) {\n try {\n this._onError(error);\n } catch {\n // Don't let handler errors propagate\n }\n }\n });\n } catch (err) {\n settled = true;\n clearTimeout(timeout);\n this._readyState = TransportState.CLOSED;\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n /**\n * Whether the transport is currently connected and ready to send.\n */\n get isOpen(): boolean {\n return this.readyState === TransportState.OPEN;\n }\n\n // ─── Internal ───────────────────────────────────────────────────────────\n\n private handleIncomingMessage(data: unknown): void {\n // Binary message (ArrayBuffer from binaryType: \"arraybuffer\")\n if (data instanceof ArrayBuffer) {\n if (this._onBinary) {\n try {\n this._onBinary(data);\n } catch {\n // Don't let handler errors kill the transport\n }\n }\n return;\n }\n\n // Node Buffer (ws may deliver Buffer even with binaryType: \"arraybuffer\" in some paths)\n if (Buffer.isBuffer(data)) {\n if (this._onBinary) {\n const ab = new Uint8Array(data).slice().buffer;\n try {\n this._onBinary(ab);\n } catch {\n // Swallow handler errors\n }\n }\n return;\n }\n\n // Text message\n if (typeof data === \"string\") {\n if (this._onMessage) {\n try {\n this._onMessage(data);\n } catch {\n // Swallow handler errors\n }\n }\n return;\n }\n\n // Blob (unlikely in Node/Bun, but handle defensively)\n if (typeof Blob !== \"undefined\" && data instanceof Blob) {\n // Convert Blob to text — async but necessary\n data.text().then((text) => {\n if (this._onMessage) {\n try {\n this._onMessage(text);\n } catch {\n // Swallow handler errors\n }\n }\n });\n return;\n }\n\n // Unknown type — try to stringify\n if (this._onMessage) {\n try {\n this._onMessage(String(data));\n } catch {\n // Swallow handler errors\n }\n }\n }\n\n /**\n * Remove all event listeners from the current WebSocket instance.\n * Called before replacing the socket on reconnect.\n */\n private detachListeners(): void {\n if (this.ws) {\n // Remove all listeners to prevent memory leaks.\n // The `ws` library supports removeAllListeners().\n try {\n this.ws.removeAllListeners();\n } catch {\n // Some environments may not support removeAllListeners\n }\n }\n }\n}\n",
|
|
68
68
|
"import { EventEmitter } from \"events\";\nimport type { AudioOutputStream } from \"../managers/SpeakerManager\";\n\nexport class _V2AudioStreamShim extends EventEmitter {\n readonly streamId: string;\n\n constructor(private readonly stream: AudioOutputStream) {\n super();\n this.streamId = stream.id;\n\n this.stream.onStateChange((state) => {\n if (state === \"ended\") {\n this.emit(\"close\");\n }\n\n if (state === \"error\") {\n this.emit(\"error\", new Error(\"Audio output stream entered error state\"));\n }\n });\n }\n\n get state(): string {\n return this.stream.state;\n }\n\n write(chunk: Uint8Array): void {\n this.stream.write(chunk);\n }\n\n async end(): Promise<void> {\n await this.stream.end();\n }\n\n async flush(): Promise<void> {\n this.stream.flush();\n }\n}\n",
|
|
69
|
-
"import type { PhotoData as LegacyPhotoData } from \"../../types/photo-data\";\nimport { AppToCloudMessageType } from \"../../types\";\nimport type { MentraSession } from \"../MentraSession\";\nimport type {\n ExistingStreamInfo,\n ManagedStreamOptions,\n ManagedStreamResult,\n PhotoOptions,\n RtmpStreamOptions,\n} from \"../managers/CameraManager\";\n\nexport interface _V2PhotoRequestOptions {\n saveToGallery?: boolean;\n customWebhookUrl?: string;\n authToken?: string;\n size?: \"small\" | \"medium\" | \"large\" | \"full\";\n compress?: \"none\" | \"medium\" | \"heavy\";\n sound?: boolean;\n}\n\nexport interface _V2PhotoRequestBridge {\n registerPhotoRequest(\n requestId: string,\n request: {\n userId: string;\n sessionId: string;\n session: unknown;\n resolve: (photo: LegacyPhotoData) => void;\n reject: (error: Error) => void;\n timestamp: number;\n },\n ): void;\n completePhotoRequest(requestId: string):\n | {\n resolve: (photo: LegacyPhotoData) => void;\n reject: (error: Error) => void;\n }\n | undefined;\n}\n\ninterface _V2CameraShimConfig {\n photoRequestBridge?: _V2PhotoRequestBridge;\n getV2Session?: () => unknown;\n}\n\nfunction generateRequestId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `photo_req_${crypto.randomUUID()}`;\n }\n\n return `photo_req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport class _V2CameraShim {\n private readonly session: MentraSession;\n private readonly config: _V2CameraShimConfig;\n\n constructor(session: MentraSession, config: _V2CameraShimConfig = {}) {\n this.session = session;\n this.config = config;\n }\n\n get hasPermission(): boolean {\n return this.session.camera.hasPermission;\n }\n\n takePhoto(options?: PhotoOptions) {\n return this.session.camera.takePhoto(options);\n }\n\n
|
|
70
|
-
"import { MentraSession } from \"../MentraSession\";\n\ntype LegacyEventName =\n | \"transcription\"\n | \"head_position\"\n | \"button_press\"\n | \"touch_event\"\n | \"phone_notification\"\n | \"phone_notification_dismissed\"\n | \"vps_coordinates\"\n | \"photo_taken\";\n\n/**\n * V2 Event Manager Shim\n *\n * Maps every `session.events.*` method from the v2 API to the\n * corresponding v3 manager method. This is the compatibility layer\n * for code that does `session.events.onTranscription(handler)` etc.\n *\n * Note on `ontranslationForLanguage` (lowercase 'on'):\n * The v2 EventManager had this as a lowercase method name — it was a bug\n * in the original codebase that shipped and became part of the public API.\n * We preserve the lowercase version for backward compat AND add a\n * correctly-cased `onTranslationForLanguage` alias so both work.\n *\n * Removed in v3.1.\n *\n * @internal\n */\nexport class _V2EventManagerShim {\n private readonly session: MentraSession;\n\n constructor(session: MentraSession) {\n this.session = session;\n }\n\n onTranscription(handler: (data: any) => void): () => void {\n return this.session.transcription.on(handler);\n }\n\n onTranscriptionForLanguage(language: string, handler: (data: any) => void): () => void {\n return this.session.transcription.forLanguage(language, handler);\n }\n\n /**\n * Original v2 method name (lowercase 'on' — was a bug, shipped as public API).\n * Preserved for backward compat with code that calls `events.ontranslationForLanguage()`.\n */\n ontranslationForLanguage(source: string, target: string, handler: (data: any) => void): () => void {\n return this.session.translation.fromTo(source, target, handler);\n }\n\n /**\n * Correctly-cased alias. Both `onTranslationForLanguage` and `ontranslationForLanguage` work.\n */\n onTranslationForLanguage(source: string, target: string, handler: (data: any) => void): () => void {\n return this.session.translation.fromTo(source, target, handler);\n }\n\n onHeadPosition(handler: (data: any) => void): () => void {\n return this.session.device.onHeadPosition(handler);\n }\n\n onButtonPress(handler: (data: any) => void): () => void {\n return this.session.device.onButtonPress(handler);\n }\n\n onTouchEvent(gestureOrHandler: string | ((data: any) => void), handler?: (data: any) => void): () => void {\n if (typeof gestureOrHandler === \"string\") {\n return this.session.device.onTouchEvent(gestureOrHandler, handler!);\n }\n\n return this.session.device.onTouchEvent(gestureOrHandler);\n }\n\n onPhoneNotifications(handler: (data: any) => void): () => void {\n return this.session.phone.notifications.on(handler);\n }\n\n onPhoneNotificationDismissed(handler: (data: any) => void): () => void {\n return this.session.phone.notifications.onDismissed(handler);\n }\n\n onVpsCoordinates(handler: (data: any) => void): () => void {\n return this.session.device.onVpsCoordinates(handler);\n }\n\n
|
|
69
|
+
"import type { PhotoData as LegacyPhotoData } from \"../../types/photo-data\";\nimport { AppToCloudMessageType } from \"../../types\";\nimport type { MentraSession } from \"../MentraSession\";\nimport type {\n ExistingStreamInfo,\n ManagedStreamOptions,\n ManagedStreamResult,\n PhotoOptions,\n RtmpStreamOptions,\n} from \"../managers/CameraManager\";\n\nexport interface _V2PhotoRequestOptions {\n saveToGallery?: boolean;\n customWebhookUrl?: string;\n authToken?: string;\n size?: \"small\" | \"medium\" | \"large\" | \"full\";\n compress?: \"none\" | \"medium\" | \"heavy\";\n sound?: boolean;\n}\n\nexport interface _V2PhotoRequestBridge {\n registerPhotoRequest(\n requestId: string,\n request: {\n userId: string;\n sessionId: string;\n session: unknown;\n resolve: (photo: LegacyPhotoData) => void;\n reject: (error: Error) => void;\n timestamp: number;\n },\n ): void;\n completePhotoRequest(requestId: string):\n | {\n resolve: (photo: LegacyPhotoData) => void;\n reject: (error: Error) => void;\n }\n | undefined;\n}\n\ninterface _V2CameraShimConfig {\n photoRequestBridge?: _V2PhotoRequestBridge;\n getV2Session?: () => unknown;\n}\n\nfunction generateRequestId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return `photo_req_${crypto.randomUUID()}`;\n }\n\n return `photo_req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;\n}\n\nexport class _V2CameraShim {\n private readonly session: MentraSession;\n private readonly config: _V2CameraShimConfig;\n\n constructor(session: MentraSession, config: _V2CameraShimConfig = {}) {\n this.session = session;\n this.config = config;\n }\n\n get hasPermission(): boolean {\n return this.session.camera.hasPermission;\n }\n\n takePhoto(options?: PhotoOptions) {\n return this.session.camera.takePhoto(options);\n }\n\n\n\n async requestPhoto(options?: _V2PhotoRequestOptions): Promise<LegacyPhotoData> {\n const bridge = this.config.photoRequestBridge;\n const userId = this.session.userId;\n\n if (!bridge || !userId) {\n throw new Error(\"requestPhoto() requires the MiniAppServer photo upload bridge\");\n }\n\n return new Promise<LegacyPhotoData>((resolve, reject) => {\n const requestId = generateRequestId();\n\n bridge.registerPhotoRequest(requestId, {\n userId,\n sessionId: this.session.sessionId,\n session: this.config.getV2Session?.() ?? this.session,\n resolve,\n reject,\n timestamp: Date.now(),\n });\n\n this.session.sendMessage({\n type: AppToCloudMessageType.PHOTO_REQUEST,\n packageName: this.session.packageName,\n sessionId: this.session.sessionId,\n requestId,\n timestamp: new Date(),\n saveToGallery: options?.saveToGallery ?? false,\n customWebhookUrl: options?.customWebhookUrl,\n authToken: options?.authToken,\n size: options?.size ?? \"medium\",\n compress: options?.compress ?? \"none\",\n sound: options?.sound,\n });\n\n if (options?.customWebhookUrl) {\n const pending = bridge.completePhotoRequest(requestId);\n pending?.resolve({\n buffer: Buffer.from([]),\n mimeType: \"image/jpeg\",\n filename: \"photo.jpg\",\n requestId,\n size: 0,\n timestamp: new Date(),\n });\n }\n });\n }\n\n startStream(options: RtmpStreamOptions): Promise<void> {\n return this.session.camera.startDirectStream(options);\n }\n\n stopStream(): Promise<void> {\n return this.session.camera.stopStream();\n }\n\n onStreamStatus(handler: (status: any) => void): () => void {\n return this.session.camera.onStreamStatus(handler);\n }\n\n isCurrentlyStreaming(): boolean {\n return this.session.camera.isCurrentlyStreaming();\n }\n\n getCurrentStreamUrl(): string | undefined {\n return this.session.camera.getCurrentStreamUrl();\n }\n\n getStreamStatus() {\n return this.session.camera.getStreamStatus();\n }\n\n startManagedStream(options?: ManagedStreamOptions): Promise<ManagedStreamResult> {\n return this.session.camera.startManagedStream(options);\n }\n\n stopManagedStream(): Promise<void> {\n return this.session.camera.stopManagedStream();\n }\n\n onManagedStreamStatus(handler: (status: any) => void): () => void {\n return this.session.camera.onManagedStreamStatus(handler);\n }\n\n isManagedStreamActive(): boolean {\n return this.session.camera.isManagedStreamActive();\n }\n\n getManagedStreamUrls(): ManagedStreamResult | undefined {\n return this.session.camera.getManagedStreamUrls();\n }\n\n checkExistingStream(): Promise<ExistingStreamInfo> {\n return this.session.camera.checkExistingStream();\n }\n}\n",
|
|
70
|
+
"import { MentraSession } from \"../MentraSession\";\n\ntype LegacyEventName =\n | \"transcription\"\n | \"head_position\"\n | \"button_press\"\n | \"touch_event\"\n | \"phone_notification\"\n | \"phone_notification_dismissed\"\n | \"vps_coordinates\"\n | \"photo_taken\";\n\n/**\n * V2 Event Manager Shim\n *\n * Maps every `session.events.*` method from the v2 API to the\n * corresponding v3 manager method. This is the compatibility layer\n * for code that does `session.events.onTranscription(handler)` etc.\n *\n * Note on `ontranslationForLanguage` (lowercase 'on'):\n * The v2 EventManager had this as a lowercase method name — it was a bug\n * in the original codebase that shipped and became part of the public API.\n * We preserve the lowercase version for backward compat AND add a\n * correctly-cased `onTranslationForLanguage` alias so both work.\n *\n * Removed in v3.1.\n *\n * @internal\n */\nexport class _V2EventManagerShim {\n private readonly session: MentraSession;\n\n constructor(session: MentraSession) {\n this.session = session;\n }\n\n onTranscription(handler: (data: any) => void): () => void {\n return this.session.transcription.on(handler);\n }\n\n onTranscriptionForLanguage(language: string, handler: (data: any) => void): () => void {\n return this.session.transcription.forLanguage(language, handler);\n }\n\n /**\n * Original v2 method name (lowercase 'on' — was a bug, shipped as public API).\n * Preserved for backward compat with code that calls `events.ontranslationForLanguage()`.\n */\n ontranslationForLanguage(source: string, target: string, handler: (data: any) => void): () => void {\n return this.session.translation.fromTo(source, target, handler);\n }\n\n /**\n * Correctly-cased alias. Both `onTranslationForLanguage` and `ontranslationForLanguage` work.\n */\n onTranslationForLanguage(source: string, target: string, handler: (data: any) => void): () => void {\n return this.session.translation.fromTo(source, target, handler);\n }\n\n onHeadPosition(handler: (data: any) => void): () => void {\n return this.session.device.onHeadPosition(handler);\n }\n\n onButtonPress(handler: (data: any) => void): () => void {\n return this.session.device.onButtonPress(handler);\n }\n\n onTouchEvent(gestureOrHandler: string | ((data: any) => void), handler?: (data: any) => void): () => void {\n if (typeof gestureOrHandler === \"string\") {\n return this.session.device.onTouchEvent(gestureOrHandler, handler!);\n }\n\n return this.session.device.onTouchEvent(gestureOrHandler);\n }\n\n onPhoneNotifications(handler: (data: any) => void): () => void {\n return this.session.phone.notifications.on(handler);\n }\n\n onPhoneNotificationDismissed(handler: (data: any) => void): () => void {\n return this.session.phone.notifications.onDismissed(handler);\n }\n\n onVpsCoordinates(handler: (data: any) => void): () => void {\n return this.session.device.onVpsCoordinates(handler);\n }\n\n\n\n onAudioChunk(handler: (data: any) => void): () => void {\n return this.session.mic.onChunk((chunk) => {\n handler({\n type: \"audio_chunk\",\n arrayBuffer: chunk.data,\n sampleRate: chunk.sampleRate,\n timestamp: new Date(chunk.timestamp),\n });\n });\n }\n\n onLocation(handler: (data: any) => void): () => void {\n return this.session.location.onUpdate(handler);\n }\n\n onCalendarEvent(handler: (data: any) => void): () => void {\n return this.session.phone.calendar.on(handler);\n }\n\n onConnected(handler: (data: any) => void): () => void {\n return this.session.onConnected(handler);\n }\n\n onDisconnected(handler: (data: any) => void): () => void {\n return this.session.onDisconnected(handler);\n }\n\n onError(handler: (data: any) => void): () => void {\n return this.session.onError(handler);\n }\n\n onSettingsUpdate(handler: (data: any) => void): () => void {\n return this.session.onSettings(handler);\n }\n\n onCapabilitiesUpdate(handler: (data: any) => void): () => void {\n return this.session.device.onCapabilitiesChange((capabilities) => {\n handler({\n capabilities,\n modelName: capabilities?.modelName ?? null,\n });\n });\n }\n\n on(event: LegacyEventName, handler: (data: any) => void): () => void {\n switch (event) {\n case \"transcription\":\n return this.onTranscription(handler);\n case \"head_position\":\n return this.onHeadPosition(handler);\n case \"button_press\":\n return this.onButtonPress(handler);\n case \"touch_event\":\n return this.onTouchEvent(handler);\n case \"phone_notification\":\n return this.onPhoneNotifications(handler);\n case \"phone_notification_dismissed\":\n return this.onPhoneNotificationDismissed(handler);\n case \"vps_coordinates\":\n return this.onVpsCoordinates(handler);\n\n default:\n return () => {};\n }\n }\n}\n",
|
|
71
71
|
"import type { AppSettings } from \"../../types\";\nimport { MentraSession } from \"../MentraSession\";\n\ntype SettingsChangeMap = Record<\n string,\n {\n oldValue: any;\n newValue: any;\n }\n>;\n\nexport class _V2SettingsShim {\n private readonly session: MentraSession;\n\n constructor(session: MentraSession) {\n this.session = session;\n }\n\n has(key: string): boolean {\n return this.session.settingsData.some((setting) => setting.key === key);\n }\n\n getAll(): AppSettings {\n return [...this.session.settingsData];\n }\n\n get<T = any>(key: string, defaultValue?: T): T {\n const setting = this.session.settingsData.find((candidate) => candidate.key === key);\n if (setting && setting.value !== undefined) {\n return setting.value as T;\n }\n\n return defaultValue as T;\n }\n\n onChange(handler: (changes: SettingsChangeMap) => void): () => void {\n let previous = this.getAll();\n\n return this.session.onSettings((settings) => {\n const changes: SettingsChangeMap = {};\n\n for (const nextSetting of settings) {\n const oldSetting = previous.find((candidate) => candidate.key === nextSetting.key);\n if (oldSetting?.value !== nextSetting.value) {\n changes[nextSetting.key] = {\n oldValue: oldSetting?.value,\n newValue: nextSetting.value,\n };\n }\n }\n\n for (const oldSetting of previous) {\n if (!settings.some((candidate) => candidate.key === oldSetting.key)) {\n changes[oldSetting.key] = {\n oldValue: oldSetting.value,\n newValue: undefined,\n };\n }\n }\n\n previous = [...settings];\n\n if (Object.keys(changes).length > 0) {\n handler(changes);\n }\n });\n }\n\n onValueChange<T = any>(key: string, handler: (newValue: T, oldValue: T) => void): () => void {\n let previous = this.get<T>(key);\n\n return this.session.onSettings(() => {\n const next = this.get<T>(key);\n if (next !== previous) {\n const oldValue = previous;\n previous = next;\n handler(next, oldValue as T);\n }\n });\n }\n}\n",
|
|
72
|
-
"import type { AppSettings, AppConfig, AppSetting, Capabilities, ExtendedStreamType } from \"../../types\";\nimport { MentraSession } from \"../MentraSession\";\nimport { _V2AudioStreamShim } from \"./_V2AudioStreamShim\";\nimport { _V2CameraShim, type _V2PhotoRequestBridge } from \"./_V2CameraShim\";\nimport { _V2EventManagerShim } from \"./_V2EventManagerShim\";\nimport { _V2SettingsShim } from \"./_V2SettingsShim\";\n\n/**\n * V2 Session Shim\n *\n * Wraps a v3 MentraSession in the v2 AppSession-shaped API so that\n * existing mini apps continue to work without code changes.\n *\n * This is the primary backward-compatibility surface. It exposes:\n * - session.layouts.* → delegates to session.display\n * - session.audio.* → delegates to session.speaker\n * - session.simpleStorage → delegates to session.storage\n * - session.camera.* → delegates via _V2CameraShim\n * - session.events.* → delegates via _V2EventManagerShim\n * - session.settings.* → delegates via _V2SettingsShim\n * - All deprecated top-level on*() convenience methods\n * - All v2 utility methods (getSettings, getWifiStatus, subscribe, etc.)\n *\n * Removed in v3.1.\n *\n * @internal\n */\nexport class _V2SessionShim {\n readonly session: MentraSession;\n\n // ─── V2 Module Surfaces ─────────────────────────────────────────────────\n\n readonly layouts: {\n showText: MentraSession[\"display\"][\"showText\"];\n showTextWall: MentraSession[\"display\"][\"showTextWall\"];\n showDoubleTextWall: MentraSession[\"display\"][\"showDoubleTextWall\"];\n showReferenceCard: MentraSession[\"display\"][\"showReferenceCard\"];\n showDashboardCard: MentraSession[\"display\"][\"showDashboardCard\"];\n showBitmap: MentraSession[\"display\"][\"showBitmap\"];\n clear: MentraSession[\"display\"][\"clear\"];\n updateText: (payload: { text: string }) => void;\n };\n readonly simpleStorage: MentraSession[\"storage\"];\n readonly audio: {\n speak: MentraSession[\"speaker\"][\"speak\"];\n playAudio: (options: {\n url: string;\n volume?: number;\n trackId?: 0 | 1 | 2;\n stopOtherAudio?: boolean;\n }) => Promise<any>;\n stopAudio: (trackId?: 0 | 1 | 2) => Promise<void>;\n createOutputStream: (options?: Record<string, any>) => Promise<_V2AudioStreamShim>;\n };\n readonly camera: _V2CameraShim;\n readonly led: MentraSession[\"led\"];\n readonly location: MentraSession[\"location\"];\n readonly device: MentraSession[\"device\"];\n readonly dashboard: MentraSession[\"dashboard\"];\n readonly settings: _V2SettingsShim;\n readonly events: _V2EventManagerShim;\n\n constructor(\n session: MentraSession,\n options?: {\n photoRequestBridge?: _V2PhotoRequestBridge;\n },\n ) {\n this.session = session;\n this.layouts = {\n showText: session.display.showText.bind(session.display),\n showTextWall: session.display.showTextWall.bind(session.display),\n showDoubleTextWall: session.display.showDoubleTextWall.bind(session.display),\n showReferenceCard: session.display.showReferenceCard.bind(session.display),\n showDashboardCard: session.display.showDashboardCard.bind(session.display),\n showBitmap: session.display.showBitmap.bind(session.display),\n clear: session.display.clear.bind(session.display),\n updateText: ({ text }) => session.display.showTextWall(text),\n };\n this.simpleStorage = session.storage;\n this.audio = {\n speak: session.speaker.speak.bind(session.speaker),\n playAudio: (options) =>\n session.speaker.play({\n url: options.url,\n volume: options.volume,\n trackId: options.trackId,\n stopOtherAudio: options.stopOtherAudio,\n }),\n stopAudio: (trackId) => session.speaker.stop(trackId),\n createOutputStream: async (options?: Record<string, any>) =>\n new _V2AudioStreamShim(await session.speaker.createStream(options)),\n };\n this.camera = new _V2CameraShim(session, {\n photoRequestBridge: options?.photoRequestBridge,\n getV2Session: () => this,\n });\n this.led = session.led;\n this.location = session.location;\n this.device = session.device;\n this.dashboard = session.dashboard;\n this.settings = new _V2SettingsShim(session);\n this.events = new _V2EventManagerShim(session);\n }\n\n // ─── Identity ───────────────────────────────────────────────────────────\n\n get userId(): string | undefined {\n return this.session.userId;\n }\n\n get packageName(): string {\n return this.session.packageName;\n }\n\n getSessionId(): string {\n return this.session.sessionId;\n }\n\n getPackageName(): string {\n return this.session.packageName;\n }\n\n // ─── Capabilities ───────────────────────────────────────────────────────\n\n get capabilities(): Capabilities | null {\n return this.session.capabilities;\n }\n\n // ─── Settings Utility Methods ───────────────────────────────────────────\n\n /** @deprecated Use session.settings or session.settingsData */\n getSettings(): AppSettings {\n return this.session.settingsData;\n }\n\n /** @deprecated Use session.settings.get(key) */\n getSetting<T>(key: string): T | undefined {\n return this.settings.get<T>(key);\n }\n\n /** @deprecated Use session.appConfig */\n getConfig(): AppConfig | null {\n return this.session.appConfig;\n }\n\n /** @deprecated Use session.getServerUrl() */\n getServerUrl(): string | null {\n return this.session.getServerUrl();\n }\n\n /** @deprecated Convert WS URL to HTTPS */\n getHttpsServerUrl(): string | null {\n const serverUrl = this.session.getServerUrl();\n if (!serverUrl) return null;\n // Remove ws:// or wss://\n let url = serverUrl.replace(/^wss?:\\/\\//, \"\");\n // Remove trailing /app-ws\n url = url.replace(/\\/app-ws$/, \"\");\n return `https://${url}`;\n }\n\n // ─── WiFi ───────────────────────────────────────────────────────────────\n\n /** @deprecated Use session.device.state.wifiConnected */\n getWifiStatus(): { connected: boolean; ssid?: string | null } | null {\n return {\n connected: this.session.device.state.wifiConnected.value,\n ssid: this.session.device.state.wifiSsid.value,\n };\n }\n\n /** @deprecated Use session.device.state.wifiConnected.value */\n isWifiConnected(): boolean {\n return this.session.device.state.wifiConnected.value === true;\n }\n\n /** @deprecated Use session.device.requestWifiSetup() */\n requestWifiSetup(reason?: string): void {\n this.session.device.requestWifiSetup(reason);\n }\n\n // ─── Subscription Methods ───────────────────────────────────────────────\n\n /**\n * @deprecated Subscriptions are now derived from handler registrations.\n * Prefer using manager methods (e.g., session.transcription.on()) which\n * handle subscriptions automatically.\n */\n subscribe(sub: string | { stream: string; rate?: string }): void {\n const stream = typeof sub === \"string\" ? sub : sub.stream;\n // Delegate to the internal subscription manager via MentraSession.\n // This is a manual override — the developer is explicitly asking to subscribe.\n (this.session as any)._subscriptions?.add(stream);\n }\n\n /**\n * @deprecated Subscriptions are now derived from handler registrations.\n */\n unsubscribe(sub: string | { stream: string }): void {\n const stream = typeof sub === \"string\" ? sub : sub.stream;\n (this.session as any)._subscriptions?.remove(stream);\n }\n\n // ─── Generic Event Listener ─────────────────────────────────────────────\n\n /** @deprecated Use the specific manager methods instead. */\n on(event: string, handler: (data: any) => void): () => void {\n return this.events.on(event as any, handler);\n }\n\n // ─── Gesture Subscription ───────────────────────────────────────────────\n\n /** @deprecated Use session.device.subscribeToGestures() */\n subscribeToGestures(gestures: string[]): () => void {\n return this.session.device.subscribeToGestures(gestures);\n }\n\n // ─── Connection State ───────────────────────────────────────────────────\n\n /** @deprecated Use session.device.state.connected.onChange() */\n onGlassesConnectionState(handler: (state: any) => void): () => void {\n return this.session.device.state.connected.onChange((connected) => {\n handler({\n connected,\n modelName: this.session.device.state.modelName.value,\n wifi: {\n connected: this.session.device.state.wifiConnected.value,\n ssid: this.session.device.state.wifiSsid.value,\n },\n });\n });\n }\n\n // ─── Direct Event Handling (deprecated on* methods) ─────────────────────\n\n /** @deprecated Use session.transcription.on() */\n onTranscription(handler: (data: any) => void): () => void {\n return this.events.onTranscription(handler);\n }\n\n /** @deprecated Use session.transcription.forLanguage() */\n onTranscriptionForLanguage(language: string, handler: (data: any) => void): () => void {\n return this.events.onTranscriptionForLanguage(language, handler);\n }\n\n /** @deprecated Use session.translation.fromTo() */\n onTranslationForLanguage(source: string, target: string, handler: (data: any) => void): () => void {\n return this.session.translation.fromTo(source, target, handler);\n }\n\n /** @deprecated Use session.device.onHeadPosition() */\n onHeadPosition(handler: (data: any) => void): () => void {\n return this.events.onHeadPosition(handler);\n }\n\n /** @deprecated Use session.device.onButtonPress() */\n onButtonPress(handler: (data: any) => void): () => void {\n return this.events.onButtonPress(handler);\n }\n\n /** @deprecated Use session.device.onTouchEvent() */\n onTouchEvent(gestureOrHandler: string | ((data: any) => void), handler?: (data: any) => void): () => void {\n return this.events.onTouchEvent(gestureOrHandler, handler);\n }\n\n /** @deprecated Use session.phone.notifications.on() */\n onPhoneNotifications(handler: (data: any) => void): () => void {\n return this.events.onPhoneNotifications(handler);\n }\n\n /** @deprecated Use session.phone.notifications.onDismissed() */\n onPhoneNotificationDismissed(handler: (data: any) => void): () => void {\n return this.events.onPhoneNotificationDismissed(handler);\n }\n\n /** @deprecated Use session.device.onVpsCoordinates() */\n onVpsCoordinates(handler: (data: any) => void): () => void {\n return this.events.onVpsCoordinates(handler);\n }\n\n /** @deprecated Use session.camera.onPhotoTaken() */\n onPhotoTaken(handler: (data: any) => void): () => void {\n return this.events.onPhotoTaken(handler);\n }\n\n // ─── Low-Level Message Sending ──────────────────────────────────────────\n\n // ─── Settings-Based Subscriptions ───────────────────────────────────────\n\n /**\n * @deprecated Use v3 manager-based subscriptions instead.\n *\n * Configure automatic subscription updates when settings change.\n * The handler function receives the current settings and returns\n * the desired subscription list. When any of the `updateOnChange`\n * keys change, the handler is re-evaluated and subscriptions updated.\n */\n private _subscriptionSettingsHandler?: (settings: AppSettings) => ExtendedStreamType[];\n private _subscriptionUpdateTriggers: string[] = [];\n\n setSubscriptionSettings(options: {\n updateOnChange: string[];\n handler: (settings: AppSettings) => ExtendedStreamType[];\n }): void {\n this._subscriptionUpdateTriggers = options.updateOnChange;\n this._subscriptionSettingsHandler = options.handler;\n\n // If we already have settings, evaluate immediately\n if (this.session.settingsData.length > 0) {\n this._updateSubscriptionsFromSettings();\n }\n\n // Listen for settings changes to re-evaluate\n this.session.onSettings((settings) => {\n const shouldUpdate = this._subscriptionUpdateTriggers.some((key) => {\n return settings.some((s: any) => s.key === key);\n });\n if (shouldUpdate) {\n this._updateSubscriptionsFromSettings();\n }\n });\n }\n\n private _updateSubscriptionsFromSettings(): void {\n if (!this._subscriptionSettingsHandler) return;\n try {\n this._subscriptionSettingsHandler(this.session.settingsData);\n // Note: with Bug 007 fix, subscriptions are derived from handlers.\n // The handler should register event handlers that correspond to the\n // desired subscriptions. This call just triggers the re-evaluation.\n } catch (error) {\n this.session.logger.error(error, \"Error updating subscriptions from settings\");\n }\n }\n\n // ─── Config Loading ─────────────────────────────────────────────────────\n\n /**\n * @deprecated Use appConfig property directly.\n * Load app configuration from a JSON string.\n */\n loadConfigFromJson(jsonData: string): AppConfig {\n try {\n const parsed = JSON.parse(jsonData);\n // Basic validation\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Invalid App configuration format\");\n }\n this.session.appConfig = parsed as AppConfig;\n return parsed as AppConfig;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load App configuration: ${msg}`);\n }\n }\n\n /**\n * @deprecated Read from appConfig.settings directly.\n * Get default settings from the loaded app configuration.\n */\n getDefaultSettings(): AppSettings {\n if (!this.session.appConfig) {\n throw new Error(\"App configuration not loaded. Call loadConfigFromJson first.\");\n }\n return (this.session.appConfig.settings || [])\n .filter((s: any) => s.type !== \"group\" && \"key\" in s)\n .map((s: any) => ({ ...s, value: s.defaultValue }));\n }\n\n /**\n * @deprecated Read from appConfig.settings directly.\n * Get the schema for a specific setting key.\n */\n getSettingSchema(key: string): AppSetting | undefined {\n if (!this.session.appConfig) return undefined;\n return (this.session.appConfig.settings || []).find(\n (s: any) => s.type !== \"group\" && \"key\" in s && s.key === key,\n ) as AppSetting | undefined;\n }\n\n // ─── Messaging ──────────────────────────────────────────────────────────\n\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage(message: unknown): void {\n this.session.sendMessage(message);\n }\n\n /** Send binary data over the WebSocket (e.g., audio stream frames). */\n sendBinary(data: ArrayBuffer | Uint8Array): void {\n this.session.sendBinary(data);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n async releaseOwnership(reason: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\"): Promise<void> {\n await this.session.releaseOwnership(reason);\n }\n\n async disconnect(_options?: {\n releaseOwnership?: boolean;\n reason?: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\";\n }): Promise<void> {\n if (_options?.releaseOwnership && _options.reason) {\n await this.releaseOwnership(_options.reason);\n }\n\n await this.session.disconnect();\n }\n\n updateSettingsForTesting(newSettings: AppSettings): void {\n this.session.updateSettingsForTesting(newSettings);\n }\n}\n",
|
|
73
|
-
"/**\n * _SessionManager\n *\n * Consolidated server-level session orchestrator. Merges the responsibilities\n * of the previous four separate classes into one:\n *\n * _MentraSessionServerFactory → createSession()\n * _MiniAppSessionRegistry → session tracking (bySessionId, byUserId maps)\n * _MiniAppServerCallbackBridge → callback storage (onSession, onStop, onToolCall)\n * _MiniAppServerRuntime → webhook handling (handleSessionRequest, handleStopRequest)\n *\n * This is an internal class — never exported to developers.\n * MiniAppServer is the only consumer.\n *\n * See decisions.md D-007 for rationale on the consolidation.\n *\n * @internal\n */\n\nimport type { Logger } from \"pino\";\nimport type { WebhookResponse, SessionWebhookRequest, StopWebhookRequest, ToolCall } from \"../types\";\nimport type { MentraSessionConfig } from \"../session\";\nimport { MentraSession } from \"../session\";\nimport { WebSocketTransport } from \"../transport/WebSocketTransport\";\nimport { _V2SessionShim } from \"../session/internal/_V2SessionShim\";\nimport type { _V2PhotoRequestBridge } from \"../session/internal/_V2CameraShim\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface _SessionManagerConfig {\n packageName: string;\n apiKey: string;\n logger: Logger;\n serverUrl?: string;\n logLevel?: MentraSessionConfig[\"logLevel\"];\n verbose?: MentraSessionConfig[\"verbose\"];\n photoRequestBridge?: _V2PhotoRequestBridge;\n}\n\nexport type _SessionHandler = (session: _V2SessionShim) => void | Promise<void>;\nexport type _StopHandler = (session: _V2SessionShim | null, reason: string) => void | Promise<void>;\nexport type _ToolCallHandler = (toolCall: ToolCall) => string | undefined | Promise<string | undefined>;\n\ninterface SessionRecord {\n session: MentraSession;\n compatSession: _V2SessionShim;\n userId: string;\n sessionId: string;\n}\n\n// ─── _SessionManager ────────────────────────────────────────────────────────\n\nexport class _SessionManager {\n private readonly config: _SessionManagerConfig;\n private readonly logger: Logger;\n\n // ─── Registry (was _MiniAppSessionRegistry) ───────────────────────────\n private readonly bySessionId = new Map<string, SessionRecord>();\n private readonly byUserId = new Map<string, SessionRecord>();\n\n // ─── Callbacks (was _MiniAppServerCallbackBridge) ─────────────────────\n private sessionHandler?: _SessionHandler;\n private stopHandler?: _StopHandler;\n private toolCallHandler?: _ToolCallHandler;\n private readonly callbackSessionCache = new Map<string, _V2SessionShim>();\n\n // ─── Lifecycle ────────────────────────────────────────────────────────\n private readonly stopSuppression = new Set<string>();\n\n constructor(config: _SessionManagerConfig) {\n this.config = config;\n this.logger = config.logger;\n }\n\n // ─── Callback Registration ────────────────────────────────────────────\n\n onSession(handler: _SessionHandler): void {\n this.sessionHandler = handler;\n }\n\n onStop(handler: _StopHandler): void {\n this.stopHandler = handler;\n }\n\n onToolCall(handler: _ToolCallHandler): void {\n this.toolCallHandler = handler;\n }\n\n // ─── Registry Queries ─────────────────────────────────────────────────\n\n getBySessionId(sessionId: string): SessionRecord | null {\n return this.bySessionId.get(sessionId) ?? null;\n }\n\n getByUserId(userId: string): SessionRecord | null {\n return this.byUserId.get(userId) ?? null;\n }\n\n get size(): number {\n return this.bySessionId.size;\n }\n\n // ─── Webhook Handlers ─────────────────────────────────────────────────\n\n async handleSessionRequest(request: SessionWebhookRequest): Promise<WebhookResponse> {\n // Tear down any existing session for this sessionId\n const existing = this.bySessionId.get(request.sessionId);\n if (existing) {\n this.stopSuppression.add(request.sessionId);\n try {\n await existing.compatSession.releaseOwnership(\"switching_clouds\");\n } catch (error) {\n this.logger.warn({ error, sessionId: request.sessionId }, \"Failed to release ownership on existing session\");\n }\n\n await existing.session.disconnect();\n this.deleteIfSameSession(request.sessionId, existing.session);\n this.stopSuppression.delete(request.sessionId);\n }\n\n // Create new session (was _MentraSessionServerFactory.create)\n const created = this.createSession(request);\n\n // Register in maps\n this.registrySet({\n session: created.session,\n compatSession: created.compatSession,\n userId: request.userId,\n sessionId: request.sessionId,\n });\n\n // Wire up permanent-disconnect → stop handler\n created.compatSession.events.onDisconnected(async (info) => {\n if (!info?.permanent) return;\n\n const removed = this.deleteIfSameSession(request.sessionId, created.session);\n if (!removed) return;\n if (this.stopSuppression.has(request.sessionId)) return;\n\n try {\n await this.invokeStopHandler(request.sessionId, info.reason || \"Session disconnected\");\n } catch (error) {\n this.logger.error(error, \"Stop handler failed after permanent disconnect\");\n }\n });\n\n // Wire up error logging\n created.compatSession.events.onError((error) => {\n this.logger.error(error, \"Session runtime error\");\n });\n\n // Connect the WebSocket\n try {\n await created.session.connect();\n } catch (error) {\n this.deleteIfSameSession(request.sessionId, created.session);\n throw error;\n }\n\n // Invoke the developer's onSession callback\n await this.invokeSessionHandler(created.compatSession, request.sessionId);\n\n return { status: \"success\" };\n }\n\n async handleStopRequest(request: StopWebhookRequest): Promise<WebhookResponse> {\n this.stopSuppression.add(request.sessionId);\n const existing = this.registryDeleteBySessionId(request.sessionId);\n if (existing) {\n await existing.session.disconnect();\n }\n\n try {\n await this.invokeStopHandler(request.sessionId, request.reason);\n } finally {\n this.stopSuppression.delete(request.sessionId);\n }\n return { status: \"success\" };\n }\n\n async handleToolCall(toolCall: ToolCall): Promise<{ status: \"success\"; reply: string | null }> {\n const activeSession = this.byUserId.get(toolCall.userId)?.compatSession ?? null;\n const response = await this.invokeToolCallHandler({\n ...toolCall,\n activeSession: activeSession as any,\n });\n\n return {\n status: \"success\",\n reply: response ?? null,\n };\n }\n\n async shutdown(): Promise<void> {\n for (const record of Array.from(this.bySessionId.values())) {\n this.stopSuppression.add(record.sessionId);\n await record.session.disconnect();\n }\n this.bySessionId.clear();\n this.byUserId.clear();\n this.callbackSessionCache.clear();\n this.stopSuppression.clear();\n }\n\n // ─── Session Factory (was _MentraSessionServerFactory) ────────────────\n\n private createSession(request: SessionWebhookRequest): {\n session: MentraSession;\n compatSession: _V2SessionShim;\n } {\n const websocketUrl = request.websocketUrl || request.mentraOSWebsocketUrl || request.augmentOSWebsocketUrl;\n if (!websocketUrl) {\n throw new Error(\"Session webhook is missing websocketUrl/mentraOSWebsocketUrl/augmentOSWebsocketUrl\");\n }\n\n const transport = new WebSocketTransport({\n url: websocketUrl,\n headers: {\n \"x-user-id\": request.userId,\n \"x-session-id\": request.sessionId,\n \"x-package-name\": this.config.packageName,\n \"x-api-key\": this.config.apiKey,\n },\n });\n\n const session = new MentraSession({\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n sessionId: request.sessionId,\n userId: request.userId,\n serverUrl: this.config.serverUrl,\n transport,\n logLevel: this.config.logLevel,\n verbose: this.config.verbose,\n });\n\n const compatSession = new _V2SessionShim(session, {\n photoRequestBridge: this.config.photoRequestBridge,\n });\n\n return { session, compatSession };\n }\n\n // ─── Registry Operations (was _MiniAppSessionRegistry) ────────────────\n\n private registrySet(record: SessionRecord): void {\n this.bySessionId.set(record.sessionId, record);\n this.byUserId.set(record.userId, record);\n }\n\n private registryDeleteBySessionId(sessionId: string): SessionRecord | null {\n const record = this.bySessionId.get(sessionId) ?? null;\n if (!record) return null;\n\n this.bySessionId.delete(sessionId);\n if (this.byUserId.get(record.userId)?.sessionId === sessionId) {\n this.byUserId.delete(record.userId);\n }\n\n return record;\n }\n\n private deleteIfSameSession(sessionId: string, session: MentraSession): SessionRecord | null {\n const record = this.bySessionId.get(sessionId) ?? null;\n if (!record || record.session !== session) return null;\n return this.registryDeleteBySessionId(sessionId);\n }\n\n // ─── Callback Invocation (was _MiniAppServerCallbackBridge) ───────────\n\n private async invokeSessionHandler(session: _V2SessionShim, sessionId: string): Promise<void> {\n this.callbackSessionCache.set(sessionId, session);\n\n if (this.sessionHandler) {\n await this.sessionHandler(session);\n }\n }\n\n private async invokeStopHandler(sessionId: string, reason: string): Promise<void> {\n const session = this.callbackSessionCache.get(sessionId) ?? null;\n this.callbackSessionCache.delete(sessionId);\n\n if (this.stopHandler) {\n await this.stopHandler(session, reason);\n }\n }\n\n private async invokeToolCallHandler(toolCall: ToolCall): Promise<string | undefined> {\n if (this.toolCallHandler) {\n return this.toolCallHandler(toolCall);\n }\n return undefined;\n }\n}\n",
|
|
72
|
+
"import type { AppSettings, AppConfig, AppSetting, Capabilities, ExtendedStreamType } from \"../../types\";\nimport { MentraSession } from \"../MentraSession\";\nimport { _V2AudioStreamShim } from \"./_V2AudioStreamShim\";\nimport { _V2CameraShim, type _V2PhotoRequestBridge } from \"./_V2CameraShim\";\nimport { _V2EventManagerShim } from \"./_V2EventManagerShim\";\nimport { _V2SettingsShim } from \"./_V2SettingsShim\";\n\n/**\n * V2 Session Shim\n *\n * Wraps a v3 MentraSession in the v2 AppSession-shaped API so that\n * existing mini apps continue to work without code changes.\n *\n * This is the primary backward-compatibility surface. It exposes:\n * - session.layouts.* → delegates to session.display\n * - session.audio.* → delegates to session.speaker\n * - session.simpleStorage → delegates to session.storage\n * - session.camera.* → delegates via _V2CameraShim\n * - session.events.* → delegates via _V2EventManagerShim\n * - session.settings.* → delegates via _V2SettingsShim\n * - All deprecated top-level on*() convenience methods\n * - All v2 utility methods (getSettings, getWifiStatus, subscribe, etc.)\n *\n * Removed in v3.1.\n *\n * @internal\n */\nexport class _V2SessionShim {\n readonly session: MentraSession;\n\n // ─── V2 Module Surfaces ─────────────────────────────────────────────────\n\n readonly layouts: {\n showText: MentraSession[\"display\"][\"showText\"];\n showTextWall: MentraSession[\"display\"][\"showTextWall\"];\n showDoubleTextWall: MentraSession[\"display\"][\"showDoubleTextWall\"];\n showReferenceCard: MentraSession[\"display\"][\"showReferenceCard\"];\n showDashboardCard: MentraSession[\"display\"][\"showDashboardCard\"];\n showBitmap: MentraSession[\"display\"][\"showBitmap\"];\n clear: MentraSession[\"display\"][\"clear\"];\n updateText: (payload: { text: string }) => void;\n };\n readonly simpleStorage: MentraSession[\"storage\"];\n readonly audio: {\n speak: MentraSession[\"speaker\"][\"speak\"];\n playAudio: (options: {\n url: string;\n volume?: number;\n trackId?: 0 | 1 | 2;\n stopOtherAudio?: boolean;\n }) => Promise<any>;\n stopAudio: (trackId?: 0 | 1 | 2) => Promise<void>;\n createOutputStream: (options?: Record<string, any>) => Promise<_V2AudioStreamShim>;\n };\n readonly camera: _V2CameraShim;\n readonly led: MentraSession[\"led\"];\n readonly location: MentraSession[\"location\"];\n readonly device: MentraSession[\"device\"];\n readonly dashboard: MentraSession[\"dashboard\"];\n readonly settings: _V2SettingsShim;\n readonly events: _V2EventManagerShim;\n\n constructor(\n session: MentraSession,\n options?: {\n photoRequestBridge?: _V2PhotoRequestBridge;\n },\n ) {\n this.session = session;\n this.layouts = {\n showText: session.display.showText.bind(session.display),\n showTextWall: session.display.showTextWall.bind(session.display),\n showDoubleTextWall: session.display.showDoubleTextWall.bind(session.display),\n showReferenceCard: session.display.showReferenceCard.bind(session.display),\n showDashboardCard: session.display.showDashboardCard.bind(session.display),\n showBitmap: session.display.showBitmap.bind(session.display),\n clear: session.display.clear.bind(session.display),\n updateText: ({ text }) => session.display.showTextWall(text),\n };\n this.simpleStorage = session.storage;\n this.audio = {\n speak: session.speaker.speak.bind(session.speaker),\n playAudio: (options) =>\n session.speaker.play({\n url: options.url,\n volume: options.volume,\n trackId: options.trackId,\n stopOtherAudio: options.stopOtherAudio,\n }),\n stopAudio: (trackId) => session.speaker.stop(trackId),\n createOutputStream: async (options?: Record<string, any>) =>\n new _V2AudioStreamShim(await session.speaker.createStream(options)),\n };\n this.camera = new _V2CameraShim(session, {\n photoRequestBridge: options?.photoRequestBridge,\n getV2Session: () => this,\n });\n this.led = session.led;\n this.location = session.location;\n this.device = session.device;\n this.dashboard = session.dashboard;\n this.settings = new _V2SettingsShim(session);\n this.events = new _V2EventManagerShim(session);\n }\n\n // ─── Identity ───────────────────────────────────────────────────────────\n\n get userId(): string | undefined {\n return this.session.userId;\n }\n\n get packageName(): string {\n return this.session.packageName;\n }\n\n getSessionId(): string {\n return this.session.sessionId;\n }\n\n getPackageName(): string {\n return this.session.packageName;\n }\n\n // ─── Capabilities ───────────────────────────────────────────────────────\n\n get capabilities(): Capabilities | null {\n return this.session.capabilities;\n }\n\n // ─── Settings Utility Methods ───────────────────────────────────────────\n\n /** @deprecated Use session.settings or session.settingsData */\n getSettings(): AppSettings {\n return this.session.settingsData;\n }\n\n /** @deprecated Use session.settings.get(key) */\n getSetting<T>(key: string): T | undefined {\n return this.settings.get<T>(key);\n }\n\n /** @deprecated Use session.appConfig */\n getConfig(): AppConfig | null {\n return this.session.appConfig;\n }\n\n /** @deprecated Use session.getServerUrl() */\n getServerUrl(): string | null {\n return this.session.getServerUrl();\n }\n\n /** @deprecated Convert WS URL to HTTPS */\n getHttpsServerUrl(): string | null {\n const serverUrl = this.session.getServerUrl();\n if (!serverUrl) return null;\n // Remove ws:// or wss://\n let url = serverUrl.replace(/^wss?:\\/\\//, \"\");\n // Remove trailing /app-ws\n url = url.replace(/\\/app-ws$/, \"\");\n return `https://${url}`;\n }\n\n // ─── WiFi ───────────────────────────────────────────────────────────────\n\n /** @deprecated Use session.device.state.wifiConnected */\n getWifiStatus(): { connected: boolean; ssid?: string | null } | null {\n return {\n connected: this.session.device.state.wifiConnected.value,\n ssid: this.session.device.state.wifiSsid.value,\n };\n }\n\n /** @deprecated Use session.device.state.wifiConnected.value */\n isWifiConnected(): boolean {\n return this.session.device.state.wifiConnected.value === true;\n }\n\n /** @deprecated Use session.device.requestWifiSetup() */\n requestWifiSetup(reason?: string): void {\n this.session.device.requestWifiSetup(reason);\n }\n\n // ─── Subscription Methods ───────────────────────────────────────────────\n\n /**\n * @deprecated Subscriptions are now derived from handler registrations.\n * Prefer using manager methods (e.g., session.transcription.on()) which\n * handle subscriptions automatically.\n */\n subscribe(sub: string | { stream: string; rate?: string }): void {\n const stream = typeof sub === \"string\" ? sub : sub.stream;\n // Delegate to the internal subscription manager via MentraSession.\n // This is a manual override — the developer is explicitly asking to subscribe.\n (this.session as any)._subscriptions?.add(stream);\n }\n\n /**\n * @deprecated Subscriptions are now derived from handler registrations.\n */\n unsubscribe(sub: string | { stream: string }): void {\n const stream = typeof sub === \"string\" ? sub : sub.stream;\n (this.session as any)._subscriptions?.remove(stream);\n }\n\n // ─── Generic Event Listener ─────────────────────────────────────────────\n\n /** @deprecated Use the specific manager methods instead. */\n on(event: string, handler: (data: any) => void): () => void {\n return this.events.on(event as any, handler);\n }\n\n // ─── Connection State ───────────────────────────────────────────────────\n\n /** @deprecated Use session.device.state.connected.onChange() */\n onGlassesConnectionState(handler: (state: any) => void): () => void {\n return this.session.device.state.connected.onChange((connected) => {\n handler({\n connected,\n modelName: this.session.device.state.modelName.value,\n wifi: {\n connected: this.session.device.state.wifiConnected.value,\n ssid: this.session.device.state.wifiSsid.value,\n },\n });\n });\n }\n\n // ─── Direct Event Handling (deprecated on* methods) ─────────────────────\n\n /** @deprecated Use session.transcription.on() */\n onTranscription(handler: (data: any) => void): () => void {\n return this.events.onTranscription(handler);\n }\n\n /** @deprecated Use session.transcription.forLanguage() */\n onTranscriptionForLanguage(language: string, handler: (data: any) => void): () => void {\n return this.events.onTranscriptionForLanguage(language, handler);\n }\n\n /** @deprecated Use session.translation.fromTo() */\n onTranslationForLanguage(source: string, target: string, handler: (data: any) => void): () => void {\n return this.session.translation.fromTo(source, target, handler);\n }\n\n /** @deprecated Use session.device.onHeadPosition() */\n onHeadPosition(handler: (data: any) => void): () => void {\n return this.events.onHeadPosition(handler);\n }\n\n /** @deprecated Use session.device.onButtonPress() */\n onButtonPress(handler: (data: any) => void): () => void {\n return this.events.onButtonPress(handler);\n }\n\n /** @deprecated Use session.device.onTouchEvent() */\n onTouchEvent(gestureOrHandler: string | ((data: any) => void), handler?: (data: any) => void): () => void {\n return this.events.onTouchEvent(gestureOrHandler, handler);\n }\n\n /** @deprecated Use session.phone.notifications.on() */\n onPhoneNotifications(handler: (data: any) => void): () => void {\n return this.events.onPhoneNotifications(handler);\n }\n\n /** @deprecated Use session.phone.notifications.onDismissed() */\n onPhoneNotificationDismissed(handler: (data: any) => void): () => void {\n return this.events.onPhoneNotificationDismissed(handler);\n }\n\n /** @deprecated Use session.device.onVpsCoordinates() */\n onVpsCoordinates(handler: (data: any) => void): () => void {\n return this.events.onVpsCoordinates(handler);\n }\n\n // ─── Low-Level Message Sending ──────────────────────────────────────────\n\n // ─── Settings-Based Subscriptions ───────────────────────────────────────\n\n /**\n * @deprecated Use v3 manager-based subscriptions instead.\n *\n * Configure automatic subscription updates when settings change.\n * The handler function receives the current settings and returns\n * the desired subscription list. When any of the `updateOnChange`\n * keys change, the handler is re-evaluated and subscriptions updated.\n */\n private _subscriptionSettingsHandler?: (settings: AppSettings) => ExtendedStreamType[];\n private _subscriptionUpdateTriggers: string[] = [];\n\n setSubscriptionSettings(options: {\n updateOnChange: string[];\n handler: (settings: AppSettings) => ExtendedStreamType[];\n }): void {\n this._subscriptionUpdateTriggers = options.updateOnChange;\n this._subscriptionSettingsHandler = options.handler;\n\n // If we already have settings, evaluate immediately\n if (this.session.settingsData.length > 0) {\n this._updateSubscriptionsFromSettings();\n }\n\n // Listen for settings changes to re-evaluate\n this.session.onSettings((settings) => {\n const shouldUpdate = this._subscriptionUpdateTriggers.some((key) => {\n return settings.some((s: any) => s.key === key);\n });\n if (shouldUpdate) {\n this._updateSubscriptionsFromSettings();\n }\n });\n }\n\n private _updateSubscriptionsFromSettings(): void {\n if (!this._subscriptionSettingsHandler) return;\n try {\n this._subscriptionSettingsHandler(this.session.settingsData);\n // Note: with Bug 007 fix, subscriptions are derived from handlers.\n // The handler should register event handlers that correspond to the\n // desired subscriptions. This call just triggers the re-evaluation.\n } catch (error) {\n this.session.logger.error(error, \"Error updating subscriptions from settings\");\n }\n }\n\n // ─── Config Loading ─────────────────────────────────────────────────────\n\n /**\n * @deprecated Use appConfig property directly.\n * Load app configuration from a JSON string.\n */\n loadConfigFromJson(jsonData: string): AppConfig {\n try {\n const parsed = JSON.parse(jsonData);\n // Basic validation\n if (!parsed || typeof parsed !== \"object\") {\n throw new Error(\"Invalid App configuration format\");\n }\n this.session.appConfig = parsed as AppConfig;\n return parsed as AppConfig;\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to load App configuration: ${msg}`);\n }\n }\n\n /**\n * @deprecated Read from appConfig.settings directly.\n * Get default settings from the loaded app configuration.\n */\n getDefaultSettings(): AppSettings {\n if (!this.session.appConfig) {\n throw new Error(\"App configuration not loaded. Call loadConfigFromJson first.\");\n }\n return (this.session.appConfig.settings || [])\n .filter((s: any) => s.type !== \"group\" && \"key\" in s)\n .map((s: any) => ({ ...s, value: s.defaultValue }));\n }\n\n /**\n * @deprecated Read from appConfig.settings directly.\n * Get the schema for a specific setting key.\n */\n getSettingSchema(key: string): AppSetting | undefined {\n if (!this.session.appConfig) return undefined;\n return (this.session.appConfig.settings || []).find(\n (s: any) => s.type !== \"group\" && \"key\" in s && s.key === key,\n ) as AppSetting | undefined;\n }\n\n // ─── Messaging ──────────────────────────────────────────────────────────\n\n /** Send an arbitrary JSON message over the WebSocket. */\n sendMessage(message: unknown): void {\n this.session.sendMessage(message);\n }\n\n /** Send binary data over the WebSocket (e.g., audio stream frames). */\n sendBinary(data: ArrayBuffer | Uint8Array): void {\n this.session.sendBinary(data);\n }\n\n // ─── Lifecycle ──────────────────────────────────────────────────────────\n\n async releaseOwnership(reason: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\"): Promise<void> {\n await this.session.releaseOwnership(reason);\n }\n\n async disconnect(_options?: {\n releaseOwnership?: boolean;\n reason?: \"switching_clouds\" | \"clean_shutdown\" | \"user_logout\";\n }): Promise<void> {\n if (_options?.releaseOwnership && _options.reason) {\n await this.releaseOwnership(_options.reason);\n }\n\n await this.session.disconnect();\n }\n\n updateSettingsForTesting(newSettings: AppSettings): void {\n this.session.updateSettingsForTesting(newSettings);\n }\n}\n",
|
|
73
|
+
"/**\n * _SessionManager\n *\n * Consolidated server-level session orchestrator. Merges the responsibilities\n * of the previous four separate classes into one:\n *\n * _MentraSessionServerFactory → createSession()\n * _MiniAppSessionRegistry → session tracking (bySessionId, byUserId maps)\n * _MiniAppServerCallbackBridge → callback storage (onSession, onStop, onToolCall)\n * _MiniAppServerRuntime → webhook handling (handleSessionRequest, handleStopRequest)\n *\n * This is an internal class — never exported to developers.\n * MiniAppServer is the only consumer.\n *\n * See decisions.md D-007 for rationale on the consolidation.\n *\n * @internal\n */\n\nimport type { Logger } from \"pino\";\nimport type { WebhookResponse, SessionWebhookRequest, StopWebhookRequest, ToolCall } from \"../types\";\nimport type { MentraSessionConfig } from \"../session\";\nimport { MentraSession } from \"../session\";\nimport { WebSocketTransport } from \"../transport/WebSocketTransport\";\nimport { _V2SessionShim } from \"../session/internal/_V2SessionShim\";\nimport type { _V2PhotoRequestBridge } from \"../session/internal/_V2CameraShim\";\n\n// ─── Types ──────────────────────────────────────────────────────────────────\n\nexport interface _SessionManagerConfig {\n packageName: string;\n apiKey: string;\n logger: Logger;\n serverUrl?: string;\n logLevel?: MentraSessionConfig[\"logLevel\"];\n verbose?: MentraSessionConfig[\"verbose\"];\n photoRequestBridge?: _V2PhotoRequestBridge;\n}\n\nexport type _SessionHandler = (session: _V2SessionShim) => void | Promise<void>;\nexport type _StopHandler = (session: _V2SessionShim | null, reason: string) => void | Promise<void>;\nexport type _ToolCallHandler = (toolCall: ToolCall) => string | undefined | Promise<string | undefined>;\n\ninterface SessionRecord {\n session: MentraSession;\n compatSession: _V2SessionShim;\n userId: string;\n sessionId: string;\n}\n\n// ─── _SessionManager ────────────────────────────────────────────────────────\n\nexport class _SessionManager {\n private readonly config: _SessionManagerConfig;\n private readonly logger: Logger;\n\n // ─── Registry (was _MiniAppSessionRegistry) ───────────────────────────\n private readonly bySessionId = new Map<string, SessionRecord>();\n private readonly byUserId = new Map<string, SessionRecord>();\n\n // ─── Callbacks (was _MiniAppServerCallbackBridge) ─────────────────────\n private sessionHandler?: _SessionHandler;\n private stopHandler?: _StopHandler;\n private toolCallHandler?: _ToolCallHandler;\n private readonly callbackSessionCache = new Map<string, _V2SessionShim>();\n\n // ─── Lifecycle ────────────────────────────────────────────────────────\n private readonly stopSuppression = new Set<string>();\n\n constructor(config: _SessionManagerConfig) {\n this.config = config;\n this.logger = config.logger;\n }\n\n // ─── Callback Registration ────────────────────────────────────────────\n\n onSession(handler: _SessionHandler): void {\n this.sessionHandler = handler;\n }\n\n onStop(handler: _StopHandler): void {\n this.stopHandler = handler;\n }\n\n onToolCall(handler: _ToolCallHandler): void {\n this.toolCallHandler = handler;\n }\n\n // ─── Registry Queries ─────────────────────────────────────────────────\n\n getBySessionId(sessionId: string): SessionRecord | null {\n return this.bySessionId.get(sessionId) ?? null;\n }\n\n getByUserId(userId: string): SessionRecord | null {\n return this.byUserId.get(userId) ?? null;\n }\n\n get size(): number {\n return this.bySessionId.size;\n }\n\n // ─── Webhook Handlers ─────────────────────────────────────────────────\n\n async handleSessionRequest(request: SessionWebhookRequest): Promise<WebhookResponse> {\n // Tear down any existing session for this sessionId\n const existing = this.bySessionId.get(request.sessionId);\n if (existing) {\n this.stopSuppression.add(request.sessionId);\n try {\n await existing.compatSession.releaseOwnership(\"switching_clouds\");\n } catch (error) {\n this.logger.warn({ error, sessionId: request.sessionId }, \"Failed to release ownership on existing session\");\n }\n\n await existing.session.disconnect();\n this.deleteIfSameSession(request.sessionId, existing.session);\n this.stopSuppression.delete(request.sessionId);\n }\n\n // Create new session (was _MentraSessionServerFactory.create)\n const created = this.createSession(request);\n\n // Register in maps\n this.registrySet({\n session: created.session,\n compatSession: created.compatSession,\n userId: request.userId,\n sessionId: request.sessionId,\n });\n\n // Wire up permanent-disconnect → stop handler\n created.compatSession.events.onDisconnected(async (info) => {\n if (!info?.permanent) return;\n\n const removed = this.deleteIfSameSession(request.sessionId, created.session);\n if (!removed) return;\n if (this.stopSuppression.has(request.sessionId)) return;\n\n try {\n await this.invokeStopHandler(request.sessionId, info.reason || \"Session disconnected\");\n } catch (error) {\n this.logger.error(error, \"Stop handler failed after permanent disconnect\");\n }\n });\n\n // Wire up error logging\n created.compatSession.events.onError((error) => {\n this.logger.error(error, \"Session runtime error\");\n });\n\n // Connect the WebSocket\n try {\n await created.session.connect();\n } catch (error) {\n this.deleteIfSameSession(request.sessionId, created.session);\n throw error;\n }\n\n // Respond to webhook immediately — session is connected.\n // Run onSession in background so slow developer setup doesn't timeout the webhook.\n const response: WebhookResponse = { status: \"success\" };\n\n // Fire-and-forget: run developer's onSession handler\n this.invokeSessionHandler(created.compatSession, request.sessionId).catch((error) => {\n this.logger.error({ error, sessionId: request.sessionId }, \"Error in onSession handler\");\n });\n\n return response;\n }\n\n async handleStopRequest(request: StopWebhookRequest): Promise<WebhookResponse> {\n this.stopSuppression.add(request.sessionId);\n const existing = this.registryDeleteBySessionId(request.sessionId);\n if (existing) {\n await existing.session.disconnect();\n }\n\n try {\n await this.invokeStopHandler(request.sessionId, request.reason);\n } finally {\n this.stopSuppression.delete(request.sessionId);\n }\n return { status: \"success\" };\n }\n\n async handleToolCall(toolCall: ToolCall): Promise<{ status: \"success\"; reply: string | null }> {\n const activeSession = this.byUserId.get(toolCall.userId)?.compatSession ?? null;\n const response = await this.invokeToolCallHandler({\n ...toolCall,\n activeSession: activeSession as any,\n });\n\n return {\n status: \"success\",\n reply: response ?? null,\n };\n }\n\n async shutdown(): Promise<void> {\n for (const record of Array.from(this.bySessionId.values())) {\n this.stopSuppression.add(record.sessionId);\n await record.session.disconnect();\n }\n this.bySessionId.clear();\n this.byUserId.clear();\n this.callbackSessionCache.clear();\n this.stopSuppression.clear();\n }\n\n // ─── Session Factory (was _MentraSessionServerFactory) ────────────────\n\n private createSession(request: SessionWebhookRequest): {\n session: MentraSession;\n compatSession: _V2SessionShim;\n } {\n const websocketUrl = request.websocketUrl || request.mentraOSWebsocketUrl || request.augmentOSWebsocketUrl;\n if (!websocketUrl) {\n throw new Error(\"Session webhook is missing websocketUrl/mentraOSWebsocketUrl/augmentOSWebsocketUrl\");\n }\n\n const transport = new WebSocketTransport({\n url: websocketUrl,\n headers: {\n \"x-user-id\": request.userId,\n \"x-session-id\": request.sessionId,\n \"x-package-name\": this.config.packageName,\n \"x-api-key\": this.config.apiKey,\n },\n });\n\n const session = new MentraSession({\n packageName: this.config.packageName,\n apiKey: this.config.apiKey,\n sessionId: request.sessionId,\n userId: request.userId,\n serverUrl: this.config.serverUrl,\n transport,\n logLevel: this.config.logLevel,\n verbose: this.config.verbose,\n });\n\n const compatSession = new _V2SessionShim(session, {\n photoRequestBridge: this.config.photoRequestBridge,\n });\n\n return { session, compatSession };\n }\n\n // ─── Registry Operations (was _MiniAppSessionRegistry) ────────────────\n\n private registrySet(record: SessionRecord): void {\n this.bySessionId.set(record.sessionId, record);\n this.byUserId.set(record.userId, record);\n }\n\n private registryDeleteBySessionId(sessionId: string): SessionRecord | null {\n const record = this.bySessionId.get(sessionId) ?? null;\n if (!record) return null;\n\n this.bySessionId.delete(sessionId);\n if (this.byUserId.get(record.userId)?.sessionId === sessionId) {\n this.byUserId.delete(record.userId);\n }\n\n return record;\n }\n\n private deleteIfSameSession(sessionId: string, session: MentraSession): SessionRecord | null {\n const record = this.bySessionId.get(sessionId) ?? null;\n if (!record || record.session !== session) return null;\n return this.registryDeleteBySessionId(sessionId);\n }\n\n // ─── Callback Invocation (was _MiniAppServerCallbackBridge) ───────────\n\n private async invokeSessionHandler(session: _V2SessionShim, sessionId: string): Promise<void> {\n this.callbackSessionCache.set(sessionId, session);\n\n if (this.sessionHandler) {\n await this.sessionHandler(session);\n }\n }\n\n private async invokeStopHandler(sessionId: string, reason: string): Promise<void> {\n const session = this.callbackSessionCache.get(sessionId) ?? null;\n this.callbackSessionCache.delete(sessionId);\n\n if (this.stopHandler) {\n await this.stopHandler(session, reason);\n }\n }\n\n private async invokeToolCallHandler(toolCall: ToolCall): Promise<string | undefined> {\n if (this.toolCallHandler) {\n return this.toolCallHandler(toolCall);\n }\n return undefined;\n }\n}\n",
|
|
74
74
|
"import type { Context } from \"hono\";\nimport type { ToolCall } from \"./types\";\nimport type { AuthVariables, SessionWebhookRequest, StopWebhookRequest, WebhookResponse } from \"./types\";\nimport { AppServer, type AppServerConfig } from \"./app/server\";\nimport { AppSession } from \"./app/session\";\nimport { MentraSession } from \"./session\";\nimport { _SessionManager, type _ToolCallHandler } from \"./internal/_SessionManager\";\n\n/**\n * Internal bridge session type used by the v2 override path.\n * When a developer subclasses MiniAppServer and overrides onSession(session, sessionId, userId),\n * the call goes through the old AppServer path which needs an AppSession instance.\n */\nclass V2BridgeSession extends AppSession {}\n\nexport type MiniAppServerConfig = AppServerConfig;\n\nexport type SessionHandler = (session: MentraSession) => void | Promise<void>;\nexport type StopHandler = (session: MentraSession | null, reason: string) => void | Promise<void>;\nexport type ToolCallHandler = _ToolCallHandler;\n\n/**\n * v3 cloud/server host for Mentra mini apps.\n *\n * `MiniAppServer` is the cloud-only entry point. It handles HTTP endpoints\n * (webhooks, tools, settings, health, photo-upload) and creates MentraSession\n * instances for each connected user.\n *\n * Naming:\n * - `MiniAppServer` is cloud/server-specific (not needed for local apps).\n * - `MentraSession` is the per-user session abstraction (same everywhere).\n *\n * This class extends the v2 `AppServer` during the transition period.\n * When a v3-style callback is registered via `app.onSession((session) => {...})`,\n * webhook lifecycle flows through `_SessionManager` → `MentraSession` → v3 runtime.\n * When a v2-style subclass overrides `onSession(session, sessionId, userId)`,\n * it goes through the old `AppServer` path entirely.\n *\n * @example\n * ```ts\n * const app = new MiniAppServer({ packageName: \"com.example.myapp\", apiKey: \"...\" })\n *\n * app.onSession((session) => {\n * session.transcription.on((data) => {\n * session.display.showText(data.text)\n * })\n * })\n *\n * await app.start()\n * ```\n */\nexport class MiniAppServer extends AppServer {\n private readonly _sessions: _SessionManager;\n\n constructor(config: MiniAppServerConfig) {\n super(config);\n this._sessions = new _SessionManager({\n packageName: config.packageName,\n apiKey: config.apiKey,\n logger: this.logger,\n serverUrl: config.cloudApiUrl,\n photoRequestBridge: {\n registerPhotoRequest: this.registerPhotoRequest.bind(this),\n completePhotoRequest: this.completePhotoRequest.bind(this),\n },\n });\n }\n\n // ─── Callback Registration (v3 pattern) ─────────────────────────────────\n\n public onSession(handler: SessionHandler): this;\n public override onSession(session: AppSession, sessionId: string, userId: string): Promise<void>;\n public override onSession(\n arg1: SessionHandler | AppSession,\n sessionId?: string,\n userId?: string,\n ): this | Promise<void> {\n if (typeof arg1 === \"function\") {\n // v3 path: developer passes a callback, we route through _SessionManager\n this._sessions.onSession((compatSession) => arg1(compatSession.session));\n return this;\n }\n\n // v2 path: developer subclassed and overrode onSession(session, sessionId, userId)\n const mentraSession = arg1 as V2BridgeSession;\n return super.onSession(mentraSession, sessionId!, userId!);\n }\n\n public onStop(handler: StopHandler): this;\n public override onStop(sessionId: string, userId: string, reason: string): Promise<void>;\n public override onStop(arg1: StopHandler | string, userId?: string, reason?: string): this | Promise<void> {\n if (typeof arg1 === \"function\") {\n this._sessions.onStop((session, stopReason) => arg1(session?.session ?? null, stopReason));\n return this;\n }\n\n return super.onStop(arg1, userId!, reason!);\n }\n\n public onToolCall(handler: ToolCallHandler): this;\n public override onToolCall(toolCall: ToolCall): Promise<string | undefined>;\n public override onToolCall(arg1: ToolCallHandler | ToolCall): this | Promise<string | undefined> {\n if (typeof arg1 === \"function\") {\n this._sessions.onToolCall(arg1);\n return this;\n }\n\n return super.onToolCall(arg1);\n }\n\n // ─── Webhook Handlers (override AppServer) ──────────────────────────────\n\n protected override async handleSessionWebhookRequest(\n request: SessionWebhookRequest,\n c: Context<{ Variables: AuthVariables }>,\n ): Promise<Response> {\n try {\n const response = await this._sessions.handleSessionRequest(request);\n const record = this._sessions.getBySessionId(request.sessionId);\n if (record) {\n // Register in AppServer's active session tracking (for photo upload correlation, etc.)\n this.setActiveSession(request.sessionId, request.userId, record.compatSession as unknown as AppSession);\n\n record.compatSession.events.onDisconnected((info) => {\n if (!info?.permanent) return;\n\n if (this.getActiveSessionById(request.sessionId) === (record.compatSession as unknown as AppSession)) {\n this.removeActiveSession(request.sessionId, request.userId);\n }\n\n this.cleanupPhotoRequestsForSession(request.sessionId);\n });\n }\n\n return c.json(response as WebhookResponse);\n } catch (error) {\n this.logger.error(error, \"Failed to connect MiniAppServer runtime session\");\n return c.json(\n {\n status: \"error\",\n message: \"Failed to connect\",\n } as WebhookResponse,\n 500,\n );\n }\n }\n\n protected override async handleStopWebhookRequest(\n request: StopWebhookRequest,\n c: Context<{ Variables: AuthVariables }>,\n ): Promise<Response> {\n try {\n const response = await this._sessions.handleStopRequest(request);\n this.removeActiveSession(request.sessionId, request.userId);\n return c.json(response as WebhookResponse);\n } catch (error) {\n this.logger.error(error, \"Failed to stop MiniAppServer runtime session\");\n return c.json(\n {\n status: \"error\",\n message: \"Failed to process stop request\",\n } as WebhookResponse,\n 500,\n );\n }\n }\n}\n"
|
|
75
75
|
],
|
|
76
|
-
"mappings": "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",
|
|
77
|
-
"debugId": "
|
|
76
|
+
"mappings": "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",
|
|
77
|
+
"debugId": "8B8711F9E2BD9BA564756E2164756E21",
|
|
78
78
|
"names": []
|
|
79
79
|
}
|