@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.
- package/README.md +102 -0
- package/dist/constants/index.d.ts +14 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +16 -0
- package/dist/examples/rtmp-streaming-example.d.ts +2 -0
- package/dist/examples/rtmp-streaming-example.d.ts.map +1 -0
- package/dist/examples/rtmp-streaming-example.js +102 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/logging/logger.d.ts +3 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +79 -0
- package/dist/tpa/index.d.ts +6 -0
- package/dist/tpa/index.d.ts.map +1 -0
- package/dist/tpa/index.js +24 -0
- package/dist/tpa/server/index.d.ts +193 -0
- package/dist/tpa/server/index.d.ts.map +1 -0
- package/dist/tpa/server/index.js +436 -0
- package/dist/tpa/session/api-client.d.ts +49 -0
- package/dist/tpa/session/api-client.d.ts.map +1 -0
- package/dist/tpa/session/api-client.js +101 -0
- package/dist/tpa/session/dashboard.d.ts +52 -0
- package/dist/tpa/session/dashboard.d.ts.map +1 -0
- package/dist/tpa/session/dashboard.js +149 -0
- package/dist/tpa/session/events.d.ts +178 -0
- package/dist/tpa/session/events.d.ts.map +1 -0
- package/dist/tpa/session/events.js +294 -0
- package/dist/tpa/session/index.d.ts +391 -0
- package/dist/tpa/session/index.d.ts.map +1 -0
- package/dist/tpa/session/index.js +1452 -0
- package/dist/tpa/session/layouts.d.ts +150 -0
- package/dist/tpa/session/layouts.d.ts.map +1 -0
- package/dist/tpa/session/layouts.js +282 -0
- package/dist/tpa/session/modules/streaming.d.ts +100 -0
- package/dist/tpa/session/modules/streaming.d.ts.map +1 -0
- package/dist/tpa/session/modules/streaming.js +270 -0
- package/dist/tpa/session/settings.d.ts +202 -0
- package/dist/tpa/session/settings.d.ts.map +1 -0
- package/dist/tpa/session/settings.js +361 -0
- package/dist/tpa/token/index.d.ts +7 -0
- package/dist/tpa/token/index.d.ts.map +1 -0
- package/dist/tpa/token/index.js +22 -0
- package/dist/tpa/token/utils.d.ts +69 -0
- package/dist/tpa/token/utils.d.ts.map +1 -0
- package/dist/tpa/token/utils.js +144 -0
- package/dist/tpa/webview/index.d.ts +47 -0
- package/dist/tpa/webview/index.d.ts.map +1 -0
- package/dist/tpa/webview/index.js +344 -0
- package/dist/types/dashboard/index.d.ts +128 -0
- package/dist/types/dashboard/index.d.ts.map +1 -0
- package/dist/types/dashboard/index.js +12 -0
- package/dist/types/enums.d.ts +57 -0
- package/dist/types/enums.d.ts.map +1 -0
- package/dist/types/enums.js +72 -0
- package/dist/types/index.d.ts +38 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +87 -0
- package/dist/types/layouts.d.ts +51 -0
- package/dist/types/layouts.d.ts.map +1 -0
- package/dist/types/layouts.js +3 -0
- package/dist/types/message-types.d.ts +109 -0
- package/dist/types/message-types.d.ts.map +1 -0
- package/dist/types/message-types.js +189 -0
- package/dist/types/messages/base.d.ts +12 -0
- package/dist/types/messages/base.d.ts.map +1 -0
- package/dist/types/messages/base.js +3 -0
- package/dist/types/messages/cloud-to-glasses.d.ts +126 -0
- package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -0
- package/dist/types/messages/cloud-to-glasses.js +60 -0
- package/dist/types/messages/cloud-to-tpa.d.ts +228 -0
- package/dist/types/messages/cloud-to-tpa.d.ts.map +1 -0
- package/dist/types/messages/cloud-to-tpa.js +61 -0
- package/dist/types/messages/glasses-to-cloud.d.ts +219 -0
- package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -0
- package/dist/types/messages/glasses-to-cloud.js +88 -0
- package/dist/types/messages/tpa-to-cloud.d.ts +146 -0
- package/dist/types/messages/tpa-to-cloud.d.ts.map +1 -0
- package/dist/types/messages/tpa-to-cloud.js +67 -0
- package/dist/types/models.d.ts +165 -0
- package/dist/types/models.d.ts.map +1 -0
- package/dist/types/models.js +84 -0
- package/dist/types/rtmp-stream.d.ts +68 -0
- package/dist/types/rtmp-stream.d.ts.map +1 -0
- package/dist/types/rtmp-stream.js +3 -0
- package/dist/types/streams.d.ts +138 -0
- package/dist/types/streams.d.ts.map +1 -0
- package/dist/types/streams.js +251 -0
- package/dist/types/token.d.ts +41 -0
- package/dist/types/token.d.ts.map +1 -0
- package/dist/types/token.js +7 -0
- package/dist/types/user-session.d.ts +73 -0
- package/dist/types/user-session.d.ts.map +1 -0
- package/dist/types/user-session.js +17 -0
- package/dist/types/webhooks.d.ts +107 -0
- package/dist/types/webhooks.d.ts.map +1 -0
- package/dist/types/webhooks.js +55 -0
- package/dist/utils/resource-tracker.d.ts +94 -0
- package/dist/utils/resource-tracker.d.ts.map +1 -0
- package/dist/utils/resource-tracker.js +153 -0
- 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;
|