@mentra/sdk 3.0.0-alpha.1 → 3.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/app/server/index.d.ts +3 -12
  2. package/dist/app/server/index.d.ts.map +1 -1
  3. package/dist/display-utils.js +102 -102
  4. package/dist/display-utils.js.map +3 -3
  5. package/dist/index.js +163 -117
  6. package/dist/index.js.map +16 -16
  7. package/dist/internal/_SessionManager.d.ts.map +1 -1
  8. package/dist/session/MentraSession.d.ts.map +1 -1
  9. package/dist/session/internal/_V2CameraShim.d.ts +0 -1
  10. package/dist/session/internal/_V2CameraShim.d.ts.map +1 -1
  11. package/dist/session/internal/_V2EventManagerShim.d.ts +0 -1
  12. package/dist/session/internal/_V2EventManagerShim.d.ts.map +1 -1
  13. package/dist/session/internal/_V2SessionShim.d.ts +0 -4
  14. package/dist/session/internal/_V2SessionShim.d.ts.map +1 -1
  15. package/dist/session/managers/CameraManager.d.ts +0 -1
  16. package/dist/session/managers/CameraManager.d.ts.map +1 -1
  17. package/dist/session/managers/DeviceManager.d.ts +1 -17
  18. package/dist/session/managers/DeviceManager.d.ts.map +1 -1
  19. package/dist/session/managers/LedManager.d.ts +19 -4
  20. package/dist/session/managers/LedManager.d.ts.map +1 -1
  21. package/dist/session/managers/LocationManager.d.ts +41 -10
  22. package/dist/session/managers/LocationManager.d.ts.map +1 -1
  23. package/dist/session/managers/PermissionsManager.d.ts +43 -0
  24. package/dist/session/managers/PermissionsManager.d.ts.map +1 -1
  25. package/dist/session/managers/PhoneManager.d.ts +1 -57
  26. package/dist/session/managers/PhoneManager.d.ts.map +1 -1
  27. package/dist/session/managers/SpeakerManager.d.ts.map +1 -1
  28. package/dist/session.js +145 -87
  29. package/dist/session.js.map +10 -10
  30. package/node_modules/@mentra/types/src/applet.ts +55 -0
  31. package/node_modules/@mentra/types/src/capabilities/even-realities-g1.ts +63 -0
  32. package/node_modules/@mentra/types/src/capabilities/even-realities-g2.ts +70 -0
  33. package/node_modules/@mentra/types/src/capabilities/mentra-display.ts +63 -0
  34. package/node_modules/@mentra/types/src/capabilities/mentra-live.ts +103 -0
  35. package/node_modules/@mentra/types/src/capabilities/none.ts +76 -0
  36. package/node_modules/@mentra/types/src/capabilities/simulated-glasses.ts +76 -0
  37. package/node_modules/@mentra/types/src/capabilities/vuzix-z100.ts +60 -0
  38. package/node_modules/@mentra/types/src/cli.ts +169 -0
  39. package/node_modules/@mentra/types/src/device.ts +43 -0
  40. package/node_modules/@mentra/types/src/enums.ts +43 -0
  41. package/node_modules/@mentra/types/src/hardware.ts +179 -0
  42. package/node_modules/@mentra/types/src/index.ts +64 -0
  43. package/node_modules/@mentra/types/tsconfig.json +22 -0
  44. package/node_modules/@mentra/types/tsconfig.tsbuildinfo +1 -0
  45. package/package.json +1 -1
@@ -15,18 +15,18 @@
15
15
  "// @mentra/sdk\n// packages/sdk/types/src/models.ts - Core models\n\nimport { AppSettingType, AppType, HardwareType, HardwareRequirementLevel } from \"./enums\";\n\n// Tool parameter type definition\nexport interface ToolParameterSchema {\n type: \"string\" | \"number\" | \"boolean\";\n description: string;\n enum?: string[];\n required?: boolean;\n}\n\n// Tool schema definition for Apps\nexport interface ToolSchema {\n id: string;\n description: string;\n activationPhrases?: string[];\n parameters?: Record<string, ToolParameterSchema>;\n}\n\n/**\n * Developer profile information\n */\nexport interface DeveloperProfile {\n company?: string;\n website?: string;\n contactEmail?: string;\n description?: string;\n logo?: string;\n}\n\n// Define PermissionType enum with legacy support\nexport enum PermissionType {\n MICROPHONE = \"MICROPHONE\",\n LOCATION = \"LOCATION\",\n BACKGROUND_LOCATION = \"BACKGROUND_LOCATION\",\n CALENDAR = \"CALENDAR\",\n CAMERA = \"CAMERA\",\n\n // Legacy notification permission (backward compatibility)\n NOTIFICATIONS = \"NOTIFICATIONS\",\n\n // New granular notification permissions\n READ_NOTIFICATIONS = \"READ_NOTIFICATIONS\",\n POST_NOTIFICATIONS = \"POST_NOTIFICATIONS\",\n\n ALL = \"ALL\",\n}\n\n// Legacy permission mapping for backward compatibility\nexport const LEGACY_PERMISSION_MAP = new Map<PermissionType, PermissionType[]>([\n [PermissionType.NOTIFICATIONS, [PermissionType.READ_NOTIFICATIONS]],\n]);\n\n// Permission interface\nexport interface Permission {\n type: PermissionType;\n description?: string;\n}\n\n/**\n * Hardware requirement for an app\n */\nexport interface HardwareRequirement {\n type: HardwareType;\n level: HardwareRequirementLevel;\n description?: string; // Why this hardware is needed\n}\n\n/**\n * Preview image orientation\n */\nexport type PhotoOrientation = \"landscape\" | \"portrait\";\n\n/**\n * Preview image for an app in the app store\n */\nexport interface PreviewImage {\n url: string;\n imageId: string;\n orientation: PhotoOrientation;\n order: number;\n}\n\n/**\n * Base interface for applications\n */\nexport interface AppI {\n packageName: string;\n name: string;\n publicUrl: string; // Base URL of the app server\n isSystemApp?: boolean; // Is this a system app?\n uninstallable?: boolean; // Can the app be uninstalled?\n\n webviewURL?: string; // URL for phone UI\n logoURL: string;\n appType: AppType; // Type of app\n appStoreId?: string; // Which app store registered this app\n\n /**\n * @deprecated Use organizationId instead. Will be removed after migration.\n */\n developerId?: string; // ID of the developer who created the app\n organizationId?: any; // ID of the organization that owns this app\n\n // Auth\n hashedEndpointSecret?: string;\n hashedApiKey?: string;\n\n // App details\n permissions?: Permission[];\n description?: string;\n version?: string;\n settings?: AppSettings;\n tools?: ToolSchema[];\n\n /**\n * Hardware requirements for the app\n * If not specified, app is assumed to work with any hardware\n */\n hardwareRequirements?: HardwareRequirement[];\n\n /**\n * Preview images for the app store\n */\n previewImages?: PreviewImage[];\n\n isPublic?: boolean;\n appStoreStatus?: \"DEVELOPMENT\" | \"SUBMITTED\" | \"REJECTED\" | \"PUBLISHED\";\n}\n\n/**\n * Base interface for all app settings\n */\nexport interface BaseAppSetting {\n key: string;\n label: string;\n value?: any; // User's selected value\n defaultValue?: any; // System default\n}\n\n/**\n * Setting types for applications\n */\nexport type AppSetting =\n | (BaseAppSetting & {\n type: AppSettingType.TOGGLE;\n defaultValue: boolean;\n value?: boolean;\n })\n | (BaseAppSetting & {\n type: AppSettingType.TEXT;\n defaultValue?: string;\n value?: string;\n })\n | (BaseAppSetting & {\n type: AppSettingType.TEXT_NO_SAVE_BUTTON;\n defaultValue?: string;\n value?: string;\n maxLines?: number;\n })\n | (BaseAppSetting & {\n type: AppSettingType.SELECT;\n options: { label: string; value: any }[];\n defaultValue?: any;\n value?: any;\n })\n | (BaseAppSetting & {\n type: AppSettingType.SELECT_WITH_SEARCH;\n options: { label: string; value: any }[];\n defaultValue?: any;\n value?: any;\n })\n | (BaseAppSetting & {\n type: AppSettingType.MULTISELECT;\n options: { label: string; value: any }[];\n defaultValue?: any[];\n value?: any[];\n })\n | (BaseAppSetting & {\n type: AppSettingType.SLIDER;\n min: number;\n max: number;\n defaultValue: number;\n value?: number;\n })\n | (BaseAppSetting & {\n type: AppSettingType.NUMERIC_INPUT;\n min?: number;\n max?: number;\n step?: number;\n placeholder?: string;\n defaultValue?: number;\n value?: number;\n })\n | (BaseAppSetting & {\n type: AppSettingType.TIME_PICKER;\n showSeconds?: boolean;\n defaultValue?: number; // Total seconds\n value?: number; // Total seconds\n })\n | (BaseAppSetting & {\n type: AppSettingType.GROUP;\n title: string;\n })\n | (BaseAppSetting & {\n type: AppSettingType.TITLE_VALUE;\n label: string;\n value: any;\n key?: never; // TITLE_VALUE settings don't need keys since they're display-only\n });\n\nexport type AppSettings = AppSetting[];\n\n/**\n * App configuration file structure\n * Represents the schema in app_config.json\n */\nexport interface AppConfig {\n name: string;\n description: string;\n version: string;\n settings: AppSetting[];\n tools: ToolSchema[];\n}\n\n/**\n * Validate a App configuration object\n * @param config Object to validate\n * @returns True if the config is valid\n */\nexport function validateAppConfig(config: any): config is AppConfig {\n if (!config || typeof config !== \"object\") return false;\n\n // Check required string properties\n if (typeof config.name !== \"string\" || typeof config.description !== \"string\" || typeof config.version !== \"string\") {\n return false;\n }\n\n // Check settings array\n if (!Array.isArray(config.settings)) return false;\n\n // Validate each setting\n return config.settings.every((setting: any) => {\n // Group settings just need a title\n if (setting.type === \"group\") {\n return typeof setting.title === \"string\";\n }\n\n // TITLE_VALUE settings just need label and value\n if (setting.type === \"titleValue\") {\n return typeof setting.label === \"string\" && \"value\" in setting;\n }\n\n // Regular settings need key and label\n if (typeof setting.key !== \"string\" || typeof setting.label !== \"string\") {\n return false;\n }\n\n // Type-specific validation\n switch (setting.type) {\n case AppSettingType.TOGGLE:\n return typeof setting.defaultValue === \"boolean\";\n\n case AppSettingType.TEXT:\n case AppSettingType.TEXT_NO_SAVE_BUTTON:\n return setting.defaultValue === undefined || typeof setting.defaultValue === \"string\";\n\n case AppSettingType.SELECT:\n case AppSettingType.SELECT_WITH_SEARCH:\n return (\n Array.isArray(setting.options) &&\n setting.options.every((opt: any) => typeof opt.label === \"string\" && \"value\" in opt)\n );\n\n case AppSettingType.MULTISELECT:\n return (\n Array.isArray(setting.options) &&\n setting.options.every((opt: any) => typeof opt.label === \"string\" && \"value\" in opt) &&\n (setting.defaultValue === undefined || Array.isArray(setting.defaultValue))\n );\n\n case AppSettingType.SLIDER:\n return (\n typeof setting.defaultValue === \"number\" &&\n typeof setting.min === \"number\" &&\n typeof setting.max === \"number\" &&\n setting.min <= setting.max\n );\n\n case AppSettingType.NUMERIC_INPUT:\n return (\n (setting.defaultValue === undefined || typeof setting.defaultValue === \"number\") &&\n (setting.min === undefined || typeof setting.min === \"number\") &&\n (setting.max === undefined || typeof setting.max === \"number\") &&\n (setting.step === undefined || typeof setting.step === \"number\") &&\n (setting.placeholder === undefined || typeof setting.placeholder === \"string\")\n );\n\n case AppSettingType.TIME_PICKER:\n return (\n (setting.defaultValue === undefined || typeof setting.defaultValue === \"number\") &&\n (setting.showSeconds === undefined || typeof setting.showSeconds === \"boolean\")\n );\n\n case AppSettingType.GROUP:\n return typeof setting.title === \"string\";\n\n case AppSettingType.TITLE_VALUE:\n return typeof setting.label === \"string\" && \"value\" in setting;\n\n default:\n return false;\n }\n });\n}\n\n/**\n * Transcript segment for speech processing\n */\nexport interface TranscriptSegment {\n speakerId?: string;\n resultId: string;\n text: string;\n timestamp: Date;\n isFinal: boolean;\n}\n\n/**\n * Complete transcript\n */\nexport interface TranscriptI {\n segments: TranscriptSegment[];\n languageSegments?: Map<string, TranscriptSegment[]>; // Language-indexed map for multi-language support\n}\n",
16
16
  "// src/webhook.ts\n\n/**\n * Types of webhook requests that can be sent to Apps\n */\nexport enum WebhookRequestType {\n /** Request to start a App session */\n SESSION_REQUEST = \"session_request\",\n\n /** Request to stop a App session */\n STOP_REQUEST = \"stop_request\",\n}\n\n/**\n * Base interface for all webhook requests\n */\nexport interface BaseWebhookRequest {\n /** Type of webhook request */\n type: WebhookRequestType;\n\n /** Session ID for the request */\n sessionId: string;\n\n /** User ID associated with the session */\n userId: string;\n\n /** Timestamp of the request */\n timestamp: string;\n}\n\n/**\n * Session request webhook\n *\n * Sent to a App when a user starts the App\n */\nexport interface SessionWebhookRequest extends BaseWebhookRequest {\n type: WebhookRequestType.SESSION_REQUEST;\n /**\n * Canonical mini app websocket URL for this app session.\n * New SDK/server paths should prefer this field.\n */\n websocketUrl?: string;\n /**\n * @deprecated Prefer `websocketUrl`.\n */\n mentraOSWebsocketUrl?: string;\n /**\n * @deprecated Prefer `websocketUrl`.\n */\n augmentOSWebsocketUrl?: string;\n}\n\n/**\n * Stop request webhook\n *\n * Sent to a App when a user or the system stops the App\n */\nexport interface StopWebhookRequest extends BaseWebhookRequest {\n type: WebhookRequestType.STOP_REQUEST;\n reason: \"user_disabled\" | \"system_stop\" | \"error\";\n}\n\n/**\n * Union type for all webhook requests\n */\nexport type WebhookRequest = SessionWebhookRequest | StopWebhookRequest;\n\n/**\n * Response to a webhook request\n */\nexport interface WebhookResponse {\n status: \"success\" | \"error\";\n message?: string;\n}\n\n/**\n * Type guard to check if a webhook request is a session request\n */\nexport function isSessionWebhookRequest(request: WebhookRequest): request is SessionWebhookRequest {\n return request.type === WebhookRequestType.SESSION_REQUEST;\n}\n\n/**\n * Type guard to check if a webhook request is a stop request\n */\nexport function isStopWebhookRequest(request: WebhookRequest): request is StopWebhookRequest {\n return request.type === WebhookRequestType.STOP_REQUEST;\n}\n",
17
17
  "// src/index.ts\n\nexport * from \"./token\";\n\n// Message type enums\nexport * from \"./message-types\";\n\n// Base message type\nexport * from \"./messages/base\";\n\n// Messages by direction - export everything except the conflicting type guards\nexport * from \"./messages/glasses-to-cloud\";\nexport * from \"./messages/cloud-to-glasses\";\n\n// Export from app-to-cloud excluding isPhotoRequest which conflicts with cloud-to-glasses\nexport {\n // Type guards - all except isPhotoRequest\n isAppConnectionInit,\n isAppReconnect,\n isAppSubscriptionUpdate,\n isDisplayRequest,\n isRgbLedControlRequest,\n isCameraFovSetRequest,\n isAudioPlayRequest,\n isAudioStopRequest,\n isDashboardContentUpdate,\n isDashboardModeChange,\n isDashboardSystemUpdate,\n isManagedStreamRequest,\n isManagedStreamStopRequest,\n isStreamRequest,\n isStreamStopRequest,\n isOwnershipRelease,\n isTelemetryResponse,\n // Export with alias to avoid conflict\n isPhotoRequest as isPhotoRequestFromApp,\n} from \"./messages/app-to-cloud\";\n\n// Type-only exports from app-to-cloud (all interfaces)\nexport type {\n SubscriptionRequest,\n AppConnectionInit,\n AppReconnect,\n AppSubscriptionUpdate,\n PhotoRequest,\n RgbLedControlRequest,\n CameraFovSetRequest,\n CameraRoiPosition,\n StreamRequest,\n StreamStopRequest,\n AppLocationPollRequest,\n RestreamDestination,\n ManagedStreamRequest,\n ManagedStreamStopRequest,\n StreamStatusCheckRequest,\n AudioPlayRequest,\n AudioStopRequest,\n AudioStreamStart,\n AudioStreamEnd,\n AppToCloudMessage,\n AppBroadcastMessage,\n AppDirectMessage,\n AppUserDiscovery,\n AppRoomJoin,\n AppRoomLeave,\n RequestWifiSetup,\n OwnershipReleaseMessage,\n TelemetryLogEntry,\n TelemetryResponse,\n} from \"./messages/app-to-cloud\";\n\n// Export cloud-to-app but exclude the conflicting type guards\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 isAudioPlayResponse,\n isDashboardModeChanged,\n isDashboardAlwaysOnChanged,\n isManagedStreamStatus,\n isStreamStatusCheckResponse,\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 isStreamStatus as isStreamStatusFromCloud,\n isRgbLedControlResponse as isRgbLedControlResponseFromCloud,\n isRequestTelemetry,\n} from \"./messages/cloud-to-app\";\n\n// Type-only exports from cloud-to-app (all interfaces)\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 AudioPlayResponse,\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 AudioStreamReady,\n RequestTelemetry,\n} from \"./messages/cloud-to-app\";\n\n// Stream types\nexport * from \"./streams\";\n\n// Layout types\nexport * from \"./layouts\";\n\n// Dashboard types\nexport * from \"./dashboard\";\n\n// RTMP streaming types\nexport * from \"./rtmp-stream\";\n\n// Other system enums\nexport * from \"./enums\";\n\n// Core model interfaces\nexport * from \"./models\";\n\n// Webhook interfaces\nexport * from \"./webhooks\";\n\n// Capability Discovery types\nexport * from \"./capabilities\";\n\n// Photo data types\nexport * from \"./photo-data\";\n\n/**\n * WebSocket error information\n */\nexport interface WebSocketError {\n code: string;\n message: string;\n details?: unknown;\n}\n\nimport type { Context } from \"hono\";\n\nimport type { AppSession } from \"../app/session\";\n\n/**\n * Hono Context variables for authenticated requests.\n * Apps should prefer the public auth helpers instead of reading these\n * variables directly from the context.\n */\nexport interface AuthVariables {\n authUserId?: string;\n activeSession: AppSession | null;\n}\n\nexport interface MentraAuthContext {\n userId: string | null;\n session: AppSession | null;\n}\n\nexport type MentraAuthHonoContext = Context<{ Variables: AuthVariables }>;\n\n/**\n * @deprecated Use AuthVariables with Hono context instead\n * This type is kept for backward compatibility during migration\n */\nexport interface AuthenticatedRequest {\n authUserId?: string;\n activeSession: AppSession | null;\n query: Record<string, string | undefined>;\n headers: Record<string, string | undefined>;\n cookies?: Record<string, string>;\n body?: unknown;\n}\n",
18
- "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",
19
- "/**\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",
18
+ "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",
19
+ "/**\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",
20
20
  "/**\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",
21
21
  "/**\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",
22
- "/**\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",
22
+ "/**\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",
23
23
  "/**\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",
24
- "/**\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 * The LED will remain on for `onTimeMs` milliseconds (defaults to 1000ms)\n * then turn off automatically on the device.\n *\n * @param color - LED colour name. One of `\"red\"`, `\"green\"`, `\"blue\"`, `\"orange\"`, `\"white\"`.\n * @param onTimeMs - Duration in milliseconds the LED stays on. Defaults to `1000`.\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 */\n setColor(color: string, onTimeMs?: number): 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: \"on\" as const,\n color: color as LedColor,\n ontime: onTimeMs ?? 1000,\n offtime: 0,\n count: 1,\n };\n\n this.deps.sendMessage(message);\n\n this.deps.logger.debug({ requestId, color, ontime: message.ontime }, \"💡 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",
25
- "/**\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",
24
+ "/**\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",
25
+ "/**\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",
26
26
  "/**\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",
27
- "/**\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",
28
- "/**\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",
29
- "/**\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",
27
+ "/**\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",
28
+ "/**\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",
29
+ "/**\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",
30
30
  "/**\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",
31
31
  "/**\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",
32
32
  "/**\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",
@@ -38,7 +38,7 @@
38
38
  "import type { Logger } from \"pino\";\nimport { AppToCloudMessageType } from \"../../types/message-types\";\n\nexport interface _SubscriptionManagerDeps {\n logger: Logger;\n isConnected: () => boolean;\n sendMessage: (message: unknown) => void;\n getPackageName: () => string;\n getSessionId: () => string;\n}\n\nexport class _SubscriptionManager {\n private readonly deps: _SubscriptionManagerDeps;\n private readonly subscriptions = new Set<string>();\n private syncScheduled = false;\n\n constructor(deps: _SubscriptionManagerDeps) {\n this.deps = deps;\n }\n\n add(stream: string): void {\n if (this.subscriptions.has(stream)) return;\n this.subscriptions.add(stream);\n this.scheduleSync();\n }\n\n remove(stream: string): void {\n if (!this.subscriptions.has(stream)) return;\n this.subscriptions.delete(stream);\n this.scheduleSync();\n }\n\n /**\n * Send the full subscription set to the cloud immediately.\n * Called directly after CONNECTION_ACK / RECONNECT_ACK to ensure\n * the cloud and SDK are in sync. Bypasses the microtask batch.\n */\n sync(): void {\n this.syncScheduled = false;\n this.deps.sendMessage({\n type: AppToCloudMessageType.SUBSCRIPTION_UPDATE,\n packageName: this.deps.getPackageName(),\n sessionId: this.deps.getSessionId(),\n subscriptions: this.snapshot(),\n timestamp: new Date(),\n });\n }\n\n snapshot(): string[] {\n return Array.from(this.subscriptions);\n }\n\n clear(): void {\n this.subscriptions.clear();\n this.syncScheduled = false;\n }\n\n /**\n * Batch multiple add/remove calls within the same microtask into a\n * single SUBSCRIPTION_UPDATE message. If onSession registers 5\n * subscriptions synchronously, only one message is sent at the end\n * of the current tick instead of 5.\n */\n private scheduleSync(): void {\n if (!this.deps.isConnected() || this.syncScheduled) return;\n this.syncScheduled = true;\n queueMicrotask(() => {\n if (!this.syncScheduled) return;\n this.syncScheduled = false;\n if (this.deps.isConnected()) {\n this.sync();\n }\n });\n }\n}\n",
39
39
  "/**\n * Error Utilities\n *\n * Shared error handling utilities to replace the ~20 copy-pasted\n * error wrapping patterns throughout the old AppSession.\n *\n * Before (scattered across AppSession):\n * } catch (error) {\n * const errorMessage = error instanceof Error ? error.message : String(error);\n * this.logger.error({ error: errorMessage }, \"Something failed\");\n * }\n *\n * After:\n * } catch (error) {\n * this.logger.error({ error: toErrorMessage(error) }, \"Something failed\");\n * }\n */\n\n// ─── Error Message Extraction ───────────────────────────────────────────────\n\n/**\n * Safely extract a human-readable error message from any thrown value.\n *\n * JavaScript allows throwing anything — Error objects, strings, numbers,\n * null, undefined, objects, etc. This function normalizes all of them\n * into a string suitable for logging.\n *\n * @param error - Any value that was thrown or caught\n * @returns A string error message\n *\n * @example\n * ```ts\n * try {\n * await doSomething();\n * } catch (error) {\n * logger.error({ error: toErrorMessage(error) }, \"doSomething failed\");\n * }\n * ```\n */\nexport function toErrorMessage(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === \"string\") {\n return error;\n }\n if (error === null) {\n return \"null\";\n }\n if (error === undefined) {\n return \"undefined\";\n }\n if (typeof error === \"object\") {\n // Some libraries throw plain objects with a message field\n const obj = error as Record<string, unknown>;\n if (typeof obj.message === \"string\") {\n return obj.message;\n }\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n }\n return String(error);\n}\n\n// ─── Error Wrapping ─────────────────────────────────────────────────────────\n\n/**\n * Wrap an unknown caught value into a proper Error instance.\n * If it's already an Error, returns it as-is.\n * Otherwise, creates a new Error with the extracted message.\n *\n * Useful when you need to re-throw or pass an Error object\n * but the catch block might have received a non-Error value.\n *\n * @param error - Any value that was thrown or caught\n * @param fallbackMessage - Optional message to use if the error has no message\n * @returns An Error instance\n *\n * @example\n * ```ts\n * try {\n * await riskyOperation();\n * } catch (error) {\n * throw toError(error, \"riskyOperation failed\");\n * }\n * ```\n */\nexport function toError(error: unknown, fallbackMessage?: string): Error {\n if (error instanceof Error) {\n return error;\n }\n const message = toErrorMessage(error);\n return new Error(message || fallbackMessage || \"Unknown error\");\n}\n\n// ─── Safe Execution ─────────────────────────────────────────────────────────\n\n/**\n * Execute a function and swallow any errors, optionally logging them.\n * Used for fire-and-forget operations where failure is acceptable\n * (e.g., cleanup handlers, optional notifications, analytics).\n *\n * @param fn - The function to execute\n * @param onError - Optional error handler (e.g., logger.warn)\n *\n * @example\n * ```ts\n * // Cleanup that shouldn't throw\n * safeExec(() => transport.close(), (err) => logger.warn({ err }, \"close failed\"));\n *\n * // Fire-and-forget analytics\n * safeExec(() => trackEvent(\"session_start\"));\n * ```\n */\nexport function safeExec(fn: () => void, onError?: (error: Error) => void): void {\n try {\n fn();\n } catch (err) {\n if (onError) {\n onError(toError(err));\n }\n }\n}\n\n/**\n * Execute an async function and swallow any errors, optionally logging them.\n * Async version of safeExec.\n *\n * @param fn - The async function to execute\n * @param onError - Optional error handler\n *\n * @example\n * ```ts\n * await safeExecAsync(\n * () => session.storage.set(\"lastActive\", Date.now()),\n * (err) => logger.warn({ err }, \"Failed to persist lastActive\")\n * );\n * ```\n */\nexport async function safeExecAsync(fn: () => Promise<void>, onError?: (error: Error) => void): Promise<void> {\n try {\n await fn();\n } catch (err) {\n if (onError) {\n onError(toError(err));\n }\n }\n}\n\n// ─── Deprecation Warnings ───────────────────────────────────────────────────\n\n/**\n * Set of deprecation keys that have already been warned about.\n * Prevents spamming the console with the same deprecation warning\n * on every access — warns once per session, not once per call.\n */\nconst _deprecationWarnings = new Set<string>();\n\n/**\n * Log a deprecation warning once per key per process lifetime.\n * Subsequent calls with the same key are silently ignored.\n *\n * @param key - Unique identifier for this deprecation (e.g., \"session.layouts\")\n * @param message - The deprecation message to log\n * @param logger - Optional structured logger; falls back to console.warn\n *\n * @example\n * ```ts\n * get layouts() {\n * warnOnce(\n * \"session.layouts\",\n * \"session.layouts is deprecated. Use session.display instead.\",\n * this.logger\n * );\n * return this.display;\n * }\n * ```\n */\nexport function warnOnce(key: string, message: string, logger?: { warn: (msg: string) => void }): void {\n if (_deprecationWarnings.has(key)) return;\n _deprecationWarnings.add(key);\n\n const formatted = `⚠️ DEPRECATION: ${message}`;\n if (logger) {\n logger.warn(formatted);\n } else {\n console.warn(formatted);\n }\n}\n\n/**\n * Reset all deprecation warning state.\n * Only useful in tests to ensure warnings fire again.\n */\nexport function resetDeprecationWarnings(): void {\n _deprecationWarnings.clear();\n}\n\n// ─── Timeout Utility ────────────────────────────────────────────────────────\n\n/**\n * Create a promise that rejects after a timeout.\n * Useful for racing against operations that might hang.\n *\n * @param ms - Timeout in milliseconds\n * @param message - Error message on timeout\n * @returns A promise that rejects after `ms` milliseconds\n *\n * @example\n * ```ts\n * const result = await Promise.race([\n * doSlowThing(),\n * timeout(5000, \"doSlowThing timed out after 5s\"),\n * ]);\n * ```\n */\nexport function timeout(ms: number, message?: string): Promise<never> {\n return new Promise<never>((_, reject) => {\n setTimeout(() => {\n reject(new Error(message ?? `Operation timed out after ${ms}ms`));\n }, ms);\n });\n}\n"
40
40
  ],
41
- "mappings": "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",
42
- "debugId": "8AE847F1727E65C164756E2164756E21",
41
+ "mappings": "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",
42
+ "debugId": "CD897D9F35B061EF64756E2164756E21",
43
43
  "names": []
44
44
  }