@mentra/sdk 1.1.19

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 (101) hide show
  1. package/README.md +102 -0
  2. package/dist/constants/index.d.ts +14 -0
  3. package/dist/constants/index.d.ts.map +1 -0
  4. package/dist/constants/index.js +16 -0
  5. package/dist/examples/rtmp-streaming-example.d.ts +2 -0
  6. package/dist/examples/rtmp-streaming-example.d.ts.map +1 -0
  7. package/dist/examples/rtmp-streaming-example.js +102 -0
  8. package/dist/index.d.ts +4 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +33 -0
  11. package/dist/logging/logger.d.ts +3 -0
  12. package/dist/logging/logger.d.ts.map +1 -0
  13. package/dist/logging/logger.js +79 -0
  14. package/dist/tpa/index.d.ts +6 -0
  15. package/dist/tpa/index.d.ts.map +1 -0
  16. package/dist/tpa/index.js +24 -0
  17. package/dist/tpa/server/index.d.ts +193 -0
  18. package/dist/tpa/server/index.d.ts.map +1 -0
  19. package/dist/tpa/server/index.js +436 -0
  20. package/dist/tpa/session/api-client.d.ts +49 -0
  21. package/dist/tpa/session/api-client.d.ts.map +1 -0
  22. package/dist/tpa/session/api-client.js +101 -0
  23. package/dist/tpa/session/dashboard.d.ts +52 -0
  24. package/dist/tpa/session/dashboard.d.ts.map +1 -0
  25. package/dist/tpa/session/dashboard.js +149 -0
  26. package/dist/tpa/session/events.d.ts +178 -0
  27. package/dist/tpa/session/events.d.ts.map +1 -0
  28. package/dist/tpa/session/events.js +294 -0
  29. package/dist/tpa/session/index.d.ts +391 -0
  30. package/dist/tpa/session/index.d.ts.map +1 -0
  31. package/dist/tpa/session/index.js +1452 -0
  32. package/dist/tpa/session/layouts.d.ts +150 -0
  33. package/dist/tpa/session/layouts.d.ts.map +1 -0
  34. package/dist/tpa/session/layouts.js +282 -0
  35. package/dist/tpa/session/modules/streaming.d.ts +100 -0
  36. package/dist/tpa/session/modules/streaming.d.ts.map +1 -0
  37. package/dist/tpa/session/modules/streaming.js +270 -0
  38. package/dist/tpa/session/settings.d.ts +202 -0
  39. package/dist/tpa/session/settings.d.ts.map +1 -0
  40. package/dist/tpa/session/settings.js +361 -0
  41. package/dist/tpa/token/index.d.ts +7 -0
  42. package/dist/tpa/token/index.d.ts.map +1 -0
  43. package/dist/tpa/token/index.js +22 -0
  44. package/dist/tpa/token/utils.d.ts +69 -0
  45. package/dist/tpa/token/utils.d.ts.map +1 -0
  46. package/dist/tpa/token/utils.js +144 -0
  47. package/dist/tpa/webview/index.d.ts +47 -0
  48. package/dist/tpa/webview/index.d.ts.map +1 -0
  49. package/dist/tpa/webview/index.js +344 -0
  50. package/dist/types/dashboard/index.d.ts +128 -0
  51. package/dist/types/dashboard/index.d.ts.map +1 -0
  52. package/dist/types/dashboard/index.js +12 -0
  53. package/dist/types/enums.d.ts +57 -0
  54. package/dist/types/enums.d.ts.map +1 -0
  55. package/dist/types/enums.js +72 -0
  56. package/dist/types/index.d.ts +38 -0
  57. package/dist/types/index.d.ts.map +1 -0
  58. package/dist/types/index.js +87 -0
  59. package/dist/types/layouts.d.ts +51 -0
  60. package/dist/types/layouts.d.ts.map +1 -0
  61. package/dist/types/layouts.js +3 -0
  62. package/dist/types/message-types.d.ts +109 -0
  63. package/dist/types/message-types.d.ts.map +1 -0
  64. package/dist/types/message-types.js +189 -0
  65. package/dist/types/messages/base.d.ts +12 -0
  66. package/dist/types/messages/base.d.ts.map +1 -0
  67. package/dist/types/messages/base.js +3 -0
  68. package/dist/types/messages/cloud-to-glasses.d.ts +126 -0
  69. package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -0
  70. package/dist/types/messages/cloud-to-glasses.js +60 -0
  71. package/dist/types/messages/cloud-to-tpa.d.ts +228 -0
  72. package/dist/types/messages/cloud-to-tpa.d.ts.map +1 -0
  73. package/dist/types/messages/cloud-to-tpa.js +61 -0
  74. package/dist/types/messages/glasses-to-cloud.d.ts +219 -0
  75. package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -0
  76. package/dist/types/messages/glasses-to-cloud.js +88 -0
  77. package/dist/types/messages/tpa-to-cloud.d.ts +146 -0
  78. package/dist/types/messages/tpa-to-cloud.d.ts.map +1 -0
  79. package/dist/types/messages/tpa-to-cloud.js +67 -0
  80. package/dist/types/models.d.ts +165 -0
  81. package/dist/types/models.d.ts.map +1 -0
  82. package/dist/types/models.js +84 -0
  83. package/dist/types/rtmp-stream.d.ts +68 -0
  84. package/dist/types/rtmp-stream.d.ts.map +1 -0
  85. package/dist/types/rtmp-stream.js +3 -0
  86. package/dist/types/streams.d.ts +138 -0
  87. package/dist/types/streams.d.ts.map +1 -0
  88. package/dist/types/streams.js +251 -0
  89. package/dist/types/token.d.ts +41 -0
  90. package/dist/types/token.d.ts.map +1 -0
  91. package/dist/types/token.js +7 -0
  92. package/dist/types/user-session.d.ts +73 -0
  93. package/dist/types/user-session.d.ts.map +1 -0
  94. package/dist/types/user-session.js +17 -0
  95. package/dist/types/webhooks.d.ts +107 -0
  96. package/dist/types/webhooks.d.ts.map +1 -0
  97. package/dist/types/webhooks.js +55 -0
  98. package/dist/utils/resource-tracker.d.ts +94 -0
  99. package/dist/utils/resource-tracker.d.ts.map +1 -0
  100. package/dist/utils/resource-tracker.js +153 -0
  101. package/package.json +50 -0
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DashboardManager = exports.DashboardContentManager = exports.DashboardSystemManager = void 0;
7
+ /**
8
+ * Dashboard API Implementation
9
+ *
10
+ * Provides dashboard functionality for TPAs, allowing them to write content
11
+ * to the dashboard and respond to dashboard mode changes.
12
+ */
13
+ // import { systemApps } from '../../constants';
14
+ const dashboard_1 = require("../../types/dashboard");
15
+ const message_types_1 = require("../../types/message-types");
16
+ const dotenv_1 = __importDefault(require("dotenv"));
17
+ // Load environment variables from .env file
18
+ dotenv_1.default.config();
19
+ const SYSTEM_DASHBOARD_PACKAGE_NAME = process.env.SYSTEM_DASHBOARD_PACKAGE_NAME || 'system.augmentos.dashboard';
20
+ /**
21
+ * Implementation of DashboardSystemAPI interface for system dashboard TPA
22
+ */
23
+ class DashboardSystemManager {
24
+ constructor(session, packageName, send) {
25
+ this.session = session;
26
+ this.packageName = packageName;
27
+ this.send = send;
28
+ }
29
+ setTopLeft(content) {
30
+ this.updateSystemSection('topLeft', content);
31
+ }
32
+ setTopRight(content) {
33
+ this.updateSystemSection('topRight', content);
34
+ }
35
+ setBottomLeft(content) {
36
+ this.updateSystemSection('bottomLeft', content);
37
+ }
38
+ setBottomRight(content) {
39
+ this.updateSystemSection('bottomRight', content);
40
+ }
41
+ setViewMode(mode) {
42
+ const message = {
43
+ type: message_types_1.TpaToCloudMessageType.DASHBOARD_MODE_CHANGE,
44
+ packageName: this.packageName,
45
+ sessionId: `${this.session.getSessionId()}-${this.packageName}`,
46
+ mode,
47
+ timestamp: new Date()
48
+ };
49
+ this.send(message);
50
+ }
51
+ updateSystemSection(section, content) {
52
+ const message = {
53
+ type: message_types_1.TpaToCloudMessageType.DASHBOARD_SYSTEM_UPDATE,
54
+ packageName: this.packageName,
55
+ sessionId: `${this.session.getSessionId()}-${this.packageName}`,
56
+ section,
57
+ content,
58
+ timestamp: new Date()
59
+ };
60
+ this.send(message);
61
+ }
62
+ }
63
+ exports.DashboardSystemManager = DashboardSystemManager;
64
+ /**
65
+ * Implementation of DashboardContentAPI interface for all TPAs
66
+ */
67
+ class DashboardContentManager {
68
+ // private alwaysOnEnabled: boolean = false;
69
+ constructor(session, packageName, send, events) {
70
+ this.session = session;
71
+ this.packageName = packageName;
72
+ this.send = send;
73
+ this.events = events;
74
+ this.currentMode = 'none';
75
+ }
76
+ write(content, targets = [dashboard_1.DashboardMode.MAIN]) {
77
+ const message = {
78
+ type: message_types_1.TpaToCloudMessageType.DASHBOARD_CONTENT_UPDATE,
79
+ packageName: this.packageName,
80
+ sessionId: `${this.session.getSessionId()}-${this.packageName}`,
81
+ content,
82
+ modes: targets,
83
+ timestamp: new Date()
84
+ };
85
+ this.send(message);
86
+ }
87
+ writeToMain(content) {
88
+ this.write(content, [dashboard_1.DashboardMode.MAIN]);
89
+ }
90
+ writeToExpanded(content) {
91
+ const message = {
92
+ type: message_types_1.TpaToCloudMessageType.DASHBOARD_CONTENT_UPDATE,
93
+ packageName: this.packageName,
94
+ sessionId: `${this.session.getSessionId()}-${this.packageName}`,
95
+ content,
96
+ modes: [dashboard_1.DashboardMode.EXPANDED],
97
+ timestamp: new Date()
98
+ };
99
+ this.send(message);
100
+ }
101
+ // writeToAlwaysOn(content: string): void {
102
+ // this.write(content, [DashboardMode.ALWAYS_ON]);
103
+ // }
104
+ async getCurrentMode() {
105
+ return this.currentMode;
106
+ }
107
+ // async isAlwaysOnEnabled(): Promise<boolean> {
108
+ // return this.alwaysOnEnabled;
109
+ // }
110
+ onModeChange(callback) {
111
+ return this.events.onDashboardModeChange((data) => {
112
+ this.currentMode = data.mode;
113
+ callback(data.mode);
114
+ });
115
+ }
116
+ // onAlwaysOnChange(callback: (enabled: boolean) => void): () => void {
117
+ // return this.events.onDashboardAlwaysOnChange((data) => {
118
+ // this.alwaysOnEnabled = data.enabled;
119
+ // callback(data.enabled);
120
+ // });
121
+ // }
122
+ // Internal methods to update state
123
+ setCurrentMode(mode) {
124
+ this.currentMode = mode;
125
+ this.events.emit('dashboard_mode_change', { mode });
126
+ }
127
+ }
128
+ exports.DashboardContentManager = DashboardContentManager;
129
+ /**
130
+ * Dashboard Manager - Main class that manages dashboard functionality
131
+ * Each TpaSession instance gets its own DashboardManager instance
132
+ */
133
+ class DashboardManager {
134
+ constructor(session, send) {
135
+ const packageName = session.getPackageName();
136
+ const events = session.events;
137
+ // Create content API (available to all TPAs)
138
+ this.content = new DashboardContentManager(session, packageName, send, events);
139
+ // Add system API if this is the system dashboard TPA
140
+ if (packageName === SYSTEM_DASHBOARD_PACKAGE_NAME) {
141
+ session.logger.info({ service: "SDK:DashboardManager" }, 'Initializing system dashboard manager');
142
+ this.system = new DashboardSystemManager(session, packageName, send);
143
+ }
144
+ else {
145
+ session.logger.info({ service: "SDK:DashboardManager" }, `Not the system dashboard: ${packageName}`);
146
+ }
147
+ }
148
+ }
149
+ exports.DashboardManager = DashboardManager;
@@ -0,0 +1,178 @@
1
+ /**
2
+ * 🎮 Event Manager Module
3
+ */
4
+ import EventEmitter from 'events';
5
+ import { StreamType, ExtendedStreamType, AppSettings, WebSocketError, ButtonPress, HeadPosition, PhoneNotification, TranscriptionData, TranslationData, GlassesBatteryUpdate, PhoneBatteryUpdate, GlassesConnectionState, LocationUpdate, Vad, NotificationDismissed, AudioChunk, CalendarEvent, VpsCoordinates, CustomMessage, RtmpStreamStatus, PhotoTaken } from '../../types';
6
+ import { DashboardMode } from '../../types/dashboard';
7
+ import { PermissionErrorDetail } from '../../types/messages/cloud-to-tpa';
8
+ /** 🎯 Type-safe event handler function */
9
+ type Handler<T> = (data: T) => void;
10
+ /** 🔄 System events not tied to streams */
11
+ interface SystemEvents {
12
+ 'connected': AppSettings | undefined;
13
+ 'disconnected': string | {
14
+ message: string;
15
+ code: number;
16
+ reason: string;
17
+ wasClean: boolean;
18
+ permanent?: boolean;
19
+ };
20
+ 'error': WebSocketError | Error;
21
+ 'settings_update': AppSettings;
22
+ 'dashboard_mode_change': {
23
+ mode: DashboardMode | 'none';
24
+ };
25
+ 'dashboard_always_on_change': {
26
+ enabled: boolean;
27
+ };
28
+ 'custom_message': CustomMessage;
29
+ 'permission_error': {
30
+ message: string;
31
+ details: PermissionErrorDetail[];
32
+ timestamp?: Date;
33
+ };
34
+ 'permission_denied': {
35
+ stream: string;
36
+ requiredPermission: string;
37
+ message: string;
38
+ };
39
+ }
40
+ /** 📡 All possible event types */
41
+ type EventType = ExtendedStreamType | keyof SystemEvents;
42
+ /** 📦 Map of stream types to their data types */
43
+ export interface StreamDataTypes {
44
+ [StreamType.BUTTON_PRESS]: ButtonPress;
45
+ [StreamType.HEAD_POSITION]: HeadPosition;
46
+ [StreamType.PHONE_NOTIFICATION]: PhoneNotification;
47
+ [StreamType.TRANSCRIPTION]: TranscriptionData;
48
+ [StreamType.TRANSLATION]: TranslationData;
49
+ [StreamType.GLASSES_BATTERY_UPDATE]: GlassesBatteryUpdate;
50
+ [StreamType.PHONE_BATTERY_UPDATE]: PhoneBatteryUpdate;
51
+ [StreamType.GLASSES_CONNECTION_STATE]: GlassesConnectionState;
52
+ [StreamType.LOCATION_UPDATE]: LocationUpdate;
53
+ [StreamType.CALENDAR_EVENT]: CalendarEvent;
54
+ [StreamType.VAD]: Vad;
55
+ [StreamType.NOTIFICATION_DISMISSED]: NotificationDismissed;
56
+ [StreamType.AUDIO_CHUNK]: AudioChunk;
57
+ [StreamType.VIDEO]: ArrayBuffer;
58
+ [StreamType.RTMP_STREAM_STATUS]: RtmpStreamStatus;
59
+ [StreamType.VPS_COORDINATES]: VpsCoordinates;
60
+ [StreamType.PHOTO_TAKEN]: PhotoTaken;
61
+ [StreamType.OPEN_DASHBOARD]: never;
62
+ [StreamType.START_APP]: never;
63
+ [StreamType.STOP_APP]: never;
64
+ [StreamType.ALL]: never;
65
+ [StreamType.WILDCARD]: never;
66
+ }
67
+ /** 📦 Data type for an event */
68
+ export type EventData<T extends EventType> = T extends keyof StreamDataTypes ? StreamDataTypes[T] : T extends keyof SystemEvents ? SystemEvents[T] : T extends string ? T extends `${StreamType.TRANSCRIPTION}:${string}` ? TranscriptionData : T extends `${StreamType.TRANSLATION}:${string}` ? TranslationData : never : never;
69
+ export declare class EventManager {
70
+ private subscribe;
71
+ private unsubscribe;
72
+ private emitter;
73
+ private handlers;
74
+ private lastLanguageTranscriptioCleanupHandler;
75
+ private lastLanguageTranslationCleanupHandler;
76
+ constructor(subscribe: (type: ExtendedStreamType) => void, unsubscribe: (type: ExtendedStreamType) => void);
77
+ onTranscription(handler: Handler<TranscriptionData>): () => void;
78
+ /**
79
+ * 🎤 Listen for transcription events in a specific language
80
+ * @param language - Language code (e.g., "en-US")
81
+ * @param handler - Function to handle transcription data
82
+ * @returns Cleanup function to remove the handler
83
+ * @throws Error if language code is invalid
84
+ */
85
+ onTranscriptionForLanguage(language: string, handler: Handler<TranscriptionData>): () => void;
86
+ /**
87
+ * 🌐 Listen for translation events for a specific language pair
88
+ * @param sourceLanguage - Source language code (e.g., "es-ES")
89
+ * @param targetLanguage - Target language code (e.g., "en-US")
90
+ * @param handler - Function to handle translation data
91
+ * @returns Cleanup function to remove the handler
92
+ * @throws Error if language codes are invalid
93
+ */
94
+ ontranslationForLanguage(sourceLanguage: string, targetLanguage: string, handler: Handler<TranslationData>): () => void;
95
+ onHeadPosition(handler: Handler<HeadPosition>): () => void;
96
+ onButtonPress(handler: Handler<ButtonPress>): () => void;
97
+ onPhoneNotifications(handler: Handler<PhoneNotification>): () => void;
98
+ onGlassesBattery(handler: Handler<GlassesBatteryUpdate>): () => void;
99
+ onPhoneBattery(handler: Handler<PhoneBatteryUpdate>): () => void;
100
+ onVoiceActivity(handler: Handler<Vad>): () => void;
101
+ onLocation(handler: Handler<LocationUpdate>): () => void;
102
+ onCalendarEvent(handler: Handler<CalendarEvent>): () => void;
103
+ /**
104
+ * 🎤 Listen for audio chunk data
105
+ * @param handler - Function to handle audio chunks
106
+ * @returns Cleanup function to remove the handler
107
+ */
108
+ onAudioChunk(handler: Handler<AudioChunk>): () => void;
109
+ onConnected(handler: Handler<SystemEvents['connected']>): () => EventEmitter<[never]>;
110
+ onDisconnected(handler: Handler<SystemEvents['disconnected']>): () => EventEmitter<[never]>;
111
+ onError(handler: Handler<SystemEvents['error']>): () => EventEmitter<[never]>;
112
+ onSettingsUpdate(handler: Handler<SystemEvents['settings_update']>): () => EventEmitter<[never]>;
113
+ /**
114
+ * 🌐 Listen for dashboard mode changes
115
+ * @param handler - Function to handle dashboard mode changes
116
+ * @returns Cleanup function to remove the handler
117
+ */
118
+ onDashboardModeChange(handler: Handler<SystemEvents['dashboard_mode_change']>): () => EventEmitter<[never]>;
119
+ /**
120
+ * 🌐 Listen for dashboard always-on mode changes
121
+ * @param handler - Function to handle dashboard always-on mode changes
122
+ * @returns Cleanup function to remove the handler
123
+ */
124
+ onDashboardAlwaysOnChange(handler: Handler<SystemEvents['dashboard_always_on_change']>): () => EventEmitter<[never]>;
125
+ /**
126
+ * 🚫 Listen for permission errors when subscriptions are rejected
127
+ * @param handler - Function to handle permission errors
128
+ * @returns Cleanup function to remove the handler
129
+ */
130
+ onPermissionError(handler: Handler<SystemEvents['permission_error']>): () => EventEmitter<[never]>;
131
+ /**
132
+ * 🚫 Listen for individual permission denied events for specific streams
133
+ * @param handler - Function to handle permission denied events
134
+ * @returns Cleanup function to remove the handler
135
+ */
136
+ onPermissionDenied(handler: Handler<SystemEvents['permission_denied']>): () => EventEmitter<[never]>;
137
+ /**
138
+ * 🔄 Listen for changes to a specific setting
139
+ * @param key - Setting key to monitor
140
+ * @param handler - Function to handle setting value changes
141
+ * @returns Cleanup function to remove the handler
142
+ */
143
+ onSettingChange<T>(key: string, handler: (value: T, previousValue: T | undefined) => void): () => void;
144
+ /**
145
+ * 🔄 Generic event handler
146
+ *
147
+ * Use this for stream types without specific handler methods
148
+ */
149
+ on<T extends ExtendedStreamType>(type: T, handler: Handler<EventData<T>>): () => void;
150
+ /**
151
+ * ➕ Add an event handler and subscribe if needed
152
+ */
153
+ private addHandler;
154
+ /**
155
+ * ➖ Remove an event handler
156
+ */
157
+ private removeHandler;
158
+ /**
159
+ * 📡 Emit an event to all registered handlers with error isolation
160
+ */
161
+ emit<T extends EventType>(event: T, data: EventData<T>): void;
162
+ /**
163
+ * 📨 Listen for custom messages with a specific action
164
+ * @param action - The action identifier to filter by
165
+ * @param handler - Function to handle the message
166
+ * @returns Cleanup function to remove the handler
167
+ */
168
+ onCustomMessage(action: string, handler: (payload: any) => void): () => void;
169
+ onVpsCoordinates(handler: Handler<VpsCoordinates>): () => void;
170
+ /**
171
+ * 📸 Listen for photo responses
172
+ * @param handler - Function to handle photo response data
173
+ * @returns Cleanup function to remove the handler
174
+ */
175
+ onPhotoTaken(handler: Handler<PhotoTaken>): () => void;
176
+ }
177
+ export {};
178
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../../src/tpa/session/events.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,294 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EventManager = void 0;
7
+ /**
8
+ * 🎮 Event Manager Module
9
+ */
10
+ const events_1 = __importDefault(require("events"));
11
+ const types_1 = require("../../types");
12
+ class EventManager {
13
+ constructor(subscribe, unsubscribe) {
14
+ this.subscribe = subscribe;
15
+ this.unsubscribe = unsubscribe;
16
+ this.emitter = new events_1.default();
17
+ this.handlers = new Map();
18
+ this.lastLanguageTranscriptioCleanupHandler = () => { };
19
+ this.lastLanguageTranslationCleanupHandler = () => { };
20
+ }
21
+ // Convenience handlers for common event types
22
+ onTranscription(handler) {
23
+ // Default to en-US when using the generic transcription handler
24
+ return this.addHandler((0, types_1.createTranscriptionStream)('en-US'), handler);
25
+ }
26
+ /**
27
+ * 🎤 Listen for transcription events in a specific language
28
+ * @param language - Language code (e.g., "en-US")
29
+ * @param handler - Function to handle transcription data
30
+ * @returns Cleanup function to remove the handler
31
+ * @throws Error if language code is invalid
32
+ */
33
+ onTranscriptionForLanguage(language, handler) {
34
+ if (!(0, types_1.isValidLanguageCode)(language)) {
35
+ throw new Error(`Invalid language code: ${language}`);
36
+ }
37
+ this.lastLanguageTranscriptioCleanupHandler();
38
+ // console.log(`((())) onTranscriptionForLanguage: ${language}`);
39
+ const streamType = (0, types_1.createTranscriptionStream)(language);
40
+ // console.log(`((())) streamType: ${streamType}`);
41
+ // console.log(`^^^^^^^ handler: ${handler.toString()}`);
42
+ this.lastLanguageTranscriptioCleanupHandler = this.addHandler(streamType, handler);
43
+ return this.lastLanguageTranscriptioCleanupHandler;
44
+ }
45
+ /**
46
+ * 🌐 Listen for translation events for a specific language pair
47
+ * @param sourceLanguage - Source language code (e.g., "es-ES")
48
+ * @param targetLanguage - Target language code (e.g., "en-US")
49
+ * @param handler - Function to handle translation data
50
+ * @returns Cleanup function to remove the handler
51
+ * @throws Error if language codes are invalid
52
+ */
53
+ ontranslationForLanguage(sourceLanguage, targetLanguage, handler) {
54
+ if (!(0, types_1.isValidLanguageCode)(sourceLanguage)) {
55
+ throw new Error(`Invalid source language code: ${sourceLanguage}`);
56
+ }
57
+ if (!(0, types_1.isValidLanguageCode)(targetLanguage)) {
58
+ throw new Error(`Invalid target language code: ${targetLanguage}`);
59
+ }
60
+ this.lastLanguageTranslationCleanupHandler();
61
+ const streamType = (0, types_1.createTranslationStream)(sourceLanguage, targetLanguage);
62
+ this.lastLanguageTranslationCleanupHandler = this.addHandler(streamType, handler);
63
+ return this.lastLanguageTranslationCleanupHandler;
64
+ }
65
+ onHeadPosition(handler) {
66
+ return this.addHandler(types_1.StreamType.HEAD_POSITION, handler);
67
+ }
68
+ onButtonPress(handler) {
69
+ return this.addHandler(types_1.StreamType.BUTTON_PRESS, handler);
70
+ }
71
+ onPhoneNotifications(handler) {
72
+ return this.addHandler(types_1.StreamType.PHONE_NOTIFICATION, handler);
73
+ }
74
+ onGlassesBattery(handler) {
75
+ return this.addHandler(types_1.StreamType.GLASSES_BATTERY_UPDATE, handler);
76
+ }
77
+ onPhoneBattery(handler) {
78
+ return this.addHandler(types_1.StreamType.PHONE_BATTERY_UPDATE, handler);
79
+ }
80
+ onVoiceActivity(handler) {
81
+ return this.addHandler(types_1.StreamType.VAD, handler);
82
+ }
83
+ onLocation(handler) {
84
+ return this.addHandler(types_1.StreamType.LOCATION_UPDATE, handler);
85
+ }
86
+ onCalendarEvent(handler) {
87
+ return this.addHandler(types_1.StreamType.CALENDAR_EVENT, handler);
88
+ }
89
+ /**
90
+ * 🎤 Listen for audio chunk data
91
+ * @param handler - Function to handle audio chunks
92
+ * @returns Cleanup function to remove the handler
93
+ */
94
+ onAudioChunk(handler) {
95
+ return this.addHandler(types_1.StreamType.AUDIO_CHUNK, handler);
96
+ }
97
+ // System event handlers
98
+ onConnected(handler) {
99
+ this.emitter.on('connected', handler);
100
+ return () => this.emitter.off('connected', handler);
101
+ }
102
+ onDisconnected(handler) {
103
+ this.emitter.on('disconnected', handler);
104
+ return () => this.emitter.off('disconnected', handler);
105
+ }
106
+ onError(handler) {
107
+ this.emitter.on('error', handler);
108
+ return () => this.emitter.off('error', handler);
109
+ }
110
+ onSettingsUpdate(handler) {
111
+ this.emitter.on('settings_update', handler);
112
+ return () => this.emitter.off('settings_update', handler);
113
+ }
114
+ /**
115
+ * 🌐 Listen for dashboard mode changes
116
+ * @param handler - Function to handle dashboard mode changes
117
+ * @returns Cleanup function to remove the handler
118
+ */
119
+ onDashboardModeChange(handler) {
120
+ this.emitter.on('dashboard_mode_change', handler);
121
+ return () => this.emitter.off('dashboard_mode_change', handler);
122
+ }
123
+ /**
124
+ * 🌐 Listen for dashboard always-on mode changes
125
+ * @param handler - Function to handle dashboard always-on mode changes
126
+ * @returns Cleanup function to remove the handler
127
+ */
128
+ onDashboardAlwaysOnChange(handler) {
129
+ this.emitter.on('dashboard_always_on_change', handler);
130
+ return () => this.emitter.off('dashboard_always_on_change', handler);
131
+ }
132
+ /**
133
+ * 🚫 Listen for permission errors when subscriptions are rejected
134
+ * @param handler - Function to handle permission errors
135
+ * @returns Cleanup function to remove the handler
136
+ */
137
+ onPermissionError(handler) {
138
+ this.emitter.on('permission_error', handler);
139
+ return () => this.emitter.off('permission_error', handler);
140
+ }
141
+ /**
142
+ * 🚫 Listen for individual permission denied events for specific streams
143
+ * @param handler - Function to handle permission denied events
144
+ * @returns Cleanup function to remove the handler
145
+ */
146
+ onPermissionDenied(handler) {
147
+ this.emitter.on('permission_denied', handler);
148
+ return () => this.emitter.off('permission_denied', handler);
149
+ }
150
+ /**
151
+ * 🔄 Listen for changes to a specific setting
152
+ * @param key - Setting key to monitor
153
+ * @param handler - Function to handle setting value changes
154
+ * @returns Cleanup function to remove the handler
155
+ */
156
+ onSettingChange(key, handler) {
157
+ let previousValue = undefined;
158
+ const settingsHandler = (settings) => {
159
+ try {
160
+ const setting = settings.find(s => s.key === key);
161
+ if (setting) {
162
+ // Only call handler if value has changed
163
+ if (setting.value !== previousValue) {
164
+ const newValue = setting.value;
165
+ handler(newValue, previousValue);
166
+ previousValue = newValue;
167
+ }
168
+ }
169
+ }
170
+ catch (error) {
171
+ console.error(`Error in onSettingChange handler for key "${key}":`, error);
172
+ }
173
+ };
174
+ this.emitter.on('settings_update', settingsHandler);
175
+ this.emitter.on('connected', settingsHandler); // Also check when first connected
176
+ return () => {
177
+ this.emitter.off('settings_update', settingsHandler);
178
+ this.emitter.off('connected', settingsHandler);
179
+ };
180
+ }
181
+ /**
182
+ * 🔄 Generic event handler
183
+ *
184
+ * Use this for stream types without specific handler methods
185
+ */
186
+ on(type, handler) {
187
+ return this.addHandler(type, handler);
188
+ }
189
+ /**
190
+ * ➕ Add an event handler and subscribe if needed
191
+ */
192
+ addHandler(type, handler) {
193
+ const handlers = this.handlers.get(type) ?? new Set();
194
+ if (handlers.size === 0) {
195
+ this.handlers.set(type, handlers);
196
+ this.subscribe(type);
197
+ }
198
+ handlers.add(handler);
199
+ return () => this.removeHandler(type, handler);
200
+ }
201
+ /**
202
+ * ➖ Remove an event handler
203
+ */
204
+ removeHandler(type, handler) {
205
+ const handlers = this.handlers.get(type);
206
+ if (!handlers)
207
+ return;
208
+ handlers.delete(handler);
209
+ if (handlers.size === 0) {
210
+ this.handlers.delete(type);
211
+ this.unsubscribe(type);
212
+ }
213
+ }
214
+ /**
215
+ * 📡 Emit an event to all registered handlers with error isolation
216
+ */
217
+ emit(event, data) {
218
+ try {
219
+ // Emit to EventEmitter handlers (system events)
220
+ // console.log(`#### Emitting to ${event}`);
221
+ this.emitter.emit(event, data);
222
+ // Emit to stream handlers if applicable
223
+ const handlers = this.handlers.get(event);
224
+ // console.log(`#### Handlers: ${JSON.stringify(handlers)}`);
225
+ if (handlers) {
226
+ // Create array of handlers to prevent modification during iteration
227
+ const handlersArray = Array.from(handlers);
228
+ // console.log(`((())) HandlersArray: ${JSON.stringify(handlersArray)}`);
229
+ // Execute each handler in isolated try/catch to prevent one handler
230
+ // from crashing the entire TPA
231
+ handlersArray.forEach(handler => {
232
+ try {
233
+ handler(data);
234
+ }
235
+ catch (handlerError) {
236
+ // Log the error but don't let it propagate
237
+ console.error(`Error in handler for event '${String(event)}':`, handlerError);
238
+ // Emit an error event for tracking purposes
239
+ if (event !== 'error') { // Prevent infinite recursion
240
+ const errorMessage = handlerError instanceof Error
241
+ ? handlerError.message
242
+ : String(handlerError);
243
+ this.emitter.emit('error', new Error(`Handler error for event '${String(event)}': ${errorMessage}`));
244
+ }
245
+ }
246
+ });
247
+ }
248
+ }
249
+ catch (emitError) {
250
+ // Catch any errors in the emission process itself
251
+ console.error(`Fatal error emitting event '${String(event)}':`, emitError);
252
+ // Try to emit an error event if we're not already handling an error
253
+ if (event !== 'error') {
254
+ try {
255
+ const errorMessage = emitError instanceof Error
256
+ ? emitError.message
257
+ : String(emitError);
258
+ this.emitter.emit('error', new Error(`Event emission error for '${String(event)}': ${errorMessage}`));
259
+ }
260
+ catch (nestedError) {
261
+ // If even this fails, just log it - nothing more we can do
262
+ console.error('Failed to emit error event:', nestedError);
263
+ }
264
+ }
265
+ }
266
+ }
267
+ /**
268
+ * 📨 Listen for custom messages with a specific action
269
+ * @param action - The action identifier to filter by
270
+ * @param handler - Function to handle the message
271
+ * @returns Cleanup function to remove the handler
272
+ */
273
+ onCustomMessage(action, handler) {
274
+ const messageHandler = (message) => {
275
+ if (message.action === action) {
276
+ handler(message.payload);
277
+ }
278
+ };
279
+ this.emitter.on('custom_message', messageHandler);
280
+ return () => this.emitter.off('custom_message', messageHandler);
281
+ }
282
+ onVpsCoordinates(handler) {
283
+ return this.addHandler(types_1.StreamType.VPS_COORDINATES, handler);
284
+ }
285
+ /**
286
+ * 📸 Listen for photo responses
287
+ * @param handler - Function to handle photo response data
288
+ * @returns Cleanup function to remove the handler
289
+ */
290
+ onPhotoTaken(handler) {
291
+ return this.addHandler(types_1.StreamType.PHOTO_TAKEN, handler);
292
+ }
293
+ }
294
+ exports.EventManager = EventManager;