@mentra/sdk 1.1.20 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{tpa → app}/index.d.ts.map +1 -1
- package/dist/{tpa → app}/index.js +2 -2
- package/dist/{tpa → app}/server/index.d.ts +21 -21
- package/dist/app/server/index.d.ts.map +1 -0
- package/dist/{tpa → app}/server/index.js +21 -21
- package/dist/{tpa → app}/session/api-client.d.ts +1 -1
- package/dist/{tpa → app}/session/api-client.d.ts.map +1 -1
- package/dist/{tpa → app}/session/api-client.js +2 -2
- package/dist/{tpa → app}/session/dashboard.d.ts +9 -9
- package/dist/{tpa → app}/session/dashboard.d.ts.map +1 -1
- package/dist/{tpa → app}/session/dashboard.js +10 -10
- package/dist/{tpa → app}/session/events.d.ts +1 -1
- package/dist/{tpa → app}/session/events.d.ts.map +1 -1
- package/dist/{tpa → app}/session/events.js +1 -1
- package/dist/{tpa → app}/session/index.d.ts +38 -38
- package/dist/{tpa → app}/session/index.d.ts.map +1 -1
- package/dist/{tpa → app}/session/index.js +116 -116
- package/dist/{tpa → app}/session/layouts.d.ts +2 -2
- package/dist/{tpa → app}/session/layouts.d.ts.map +1 -1
- package/dist/{tpa → app}/session/layouts.js +4 -4
- package/dist/{tpa → app}/session/modules/streaming.d.ts +5 -5
- package/dist/{tpa → app}/session/modules/streaming.d.ts.map +1 -1
- package/dist/{tpa → app}/session/modules/streaming.js +7 -7
- package/dist/{tpa → app}/session/settings.d.ts +3 -3
- package/dist/{tpa → app}/session/settings.d.ts.map +1 -1
- package/dist/{tpa → app}/session/settings.js +5 -7
- package/dist/app/token/index.d.ts +7 -0
- package/dist/app/token/index.d.ts.map +1 -0
- package/dist/{tpa → app}/token/index.js +2 -2
- package/dist/{tpa → app}/token/utils.d.ts +6 -6
- package/dist/{tpa → app}/token/utils.d.ts.map +1 -1
- package/dist/{tpa → app}/token/utils.js +6 -6
- package/dist/{tpa → app}/webview/index.d.ts +3 -3
- package/dist/{tpa → app}/webview/index.d.ts.map +1 -1
- package/dist/{tpa → app}/webview/index.js +4 -4
- package/dist/examples/rtmp-streaming-example.js +6 -6
- package/dist/index.d.ts +39 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -16
- package/dist/types/capabilities.d.ts +1 -1
- package/dist/types/capabilities.js +1 -1
- package/dist/types/dashboard/index.d.ts +9 -9
- package/dist/types/enums.d.ts +2 -2
- package/dist/types/enums.js +8 -8
- package/dist/types/index.d.ts +6 -6
- package/dist/types/index.js +24 -24
- package/dist/types/layouts.d.ts +2 -2
- package/dist/types/message-types.d.ts +15 -15
- package/dist/types/message-types.js +47 -47
- package/dist/types/messages/app-to-cloud.d.ts +146 -0
- package/dist/types/messages/{tpa-to-cloud.d.ts.map → app-to-cloud.d.ts.map} +1 -1
- package/dist/types/messages/{tpa-to-cloud.js → app-to-cloud.js} +18 -18
- package/dist/types/messages/{cloud-to-tpa.d.ts → cloud-to-app.d.ts} +52 -52
- package/dist/types/messages/{cloud-to-tpa.d.ts.map → cloud-to-app.d.ts.map} +1 -1
- package/dist/types/messages/{cloud-to-tpa.js → cloud-to-app.js} +22 -22
- package/dist/types/models.d.ts +7 -7
- package/dist/types/models.js +3 -3
- package/dist/types/streams.d.ts +2 -2
- package/dist/types/streams.js +2 -2
- package/dist/types/token.d.ts +7 -7
- package/dist/types/token.js +2 -2
- package/dist/types/webhooks.d.ts +8 -8
- package/dist/types/webhooks.js +3 -3
- package/package.json +1 -1
- package/dist/tpa/server/index.d.ts.map +0 -1
- package/dist/tpa/token/index.d.ts +0 -7
- package/dist/tpa/token/index.d.ts.map +0 -1
- package/dist/types/messages/tpa-to-cloud.d.ts +0 -146
- /package/dist/{tpa → app}/index.d.ts +0 -0
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.
|
6
|
+
exports.AppSession = void 0;
|
7
7
|
/**
|
8
|
-
* 🎯
|
8
|
+
* 🎯 App Session Module
|
9
9
|
*
|
10
10
|
* Manages an active Third Party App session with AugmentOS Cloud.
|
11
11
|
* Handles real-time communication, event subscriptions, and display management.
|
@@ -19,20 +19,20 @@ const resource_tracker_1 = require("../../utils/resource-tracker");
|
|
19
19
|
const types_1 = require("../../types");
|
20
20
|
const axios_1 = __importDefault(require("axios"));
|
21
21
|
const events_2 = __importDefault(require("events"));
|
22
|
-
// Import the cloud-to-
|
23
|
-
const
|
22
|
+
// Import the cloud-to-app specific type guards
|
23
|
+
const cloud_to_app_1 = require("../../types/messages/cloud-to-app");
|
24
24
|
// List of event types that should never be subscribed to as streams
|
25
|
-
const
|
26
|
-
'
|
27
|
-
'
|
28
|
-
'
|
29
|
-
'
|
30
|
-
'
|
25
|
+
const APP_TO_APP_EVENT_TYPES = [
|
26
|
+
'app_message_received',
|
27
|
+
'app_user_joined',
|
28
|
+
'app_user_left',
|
29
|
+
'app_room_updated',
|
30
|
+
'app_direct_message_response'
|
31
31
|
];
|
32
32
|
/**
|
33
|
-
* 🚀
|
33
|
+
* 🚀 App Session Implementation
|
34
34
|
*
|
35
|
-
* Manages a live connection between your
|
35
|
+
* Manages a live connection between your App and AugmentOS Cloud.
|
36
36
|
* Provides interfaces for:
|
37
37
|
* - 🎮 Event handling (transcription, head position, etc.)
|
38
38
|
* - 📱 Display management in AR view
|
@@ -41,7 +41,7 @@ const TPA_TO_TPA_EVENT_TYPES = [
|
|
41
41
|
*
|
42
42
|
* @example
|
43
43
|
* ```typescript
|
44
|
-
* const session = new
|
44
|
+
* const session = new AppSession({
|
45
45
|
* packageName: 'org.example.myapp',
|
46
46
|
* apiKey: 'your_api_key'
|
47
47
|
* });
|
@@ -55,7 +55,7 @@ const TPA_TO_TPA_EVENT_TYPES = [
|
|
55
55
|
* await session.connect('session_123');
|
56
56
|
* ```
|
57
57
|
*/
|
58
|
-
class
|
58
|
+
class AppSession {
|
59
59
|
constructor(config) {
|
60
60
|
this.config = config;
|
61
61
|
/** WebSocket connection to AugmentOS Cloud */
|
@@ -70,8 +70,8 @@ class TpaSession {
|
|
70
70
|
this.resources = new resource_tracker_1.ResourceTracker();
|
71
71
|
/** Internal settings storage - use public settings API instead */
|
72
72
|
this.settingsData = [];
|
73
|
-
/**
|
74
|
-
this.
|
73
|
+
/** App configuration loaded from app_config.json */
|
74
|
+
this.appConfig = null;
|
75
75
|
/** Whether to update subscriptions when settings change */
|
76
76
|
this.shouldUpdateSubscriptionsOnSettingsChange = false;
|
77
77
|
/** Settings that should trigger subscription updates when changed */
|
@@ -84,18 +84,18 @@ class TpaSession {
|
|
84
84
|
this.pendingDirectMessages = new Map();
|
85
85
|
/** 🔧 Device capabilities available for this session */
|
86
86
|
this.capabilities = null;
|
87
|
-
/** Dedicated emitter for
|
88
|
-
this.
|
87
|
+
/** Dedicated emitter for App-to-App events */
|
88
|
+
this.appEvents = new events_2.default();
|
89
89
|
// Set defaults and merge with provided config
|
90
90
|
this.config = {
|
91
|
-
augmentOSWebsocketUrl: `ws://localhost:8002/
|
91
|
+
augmentOSWebsocketUrl: `ws://localhost:8002/app-ws`, // Use localhost as default
|
92
92
|
autoReconnect: true, // Enable auto-reconnection by default for better reliability
|
93
93
|
maxReconnectAttempts: 3, // Default to 3 reconnection attempts for better resilience
|
94
94
|
reconnectDelay: 1000, // Start with 1 second delay (uses exponential backoff)
|
95
95
|
...config
|
96
96
|
};
|
97
|
-
this.
|
98
|
-
this.logger = this.
|
97
|
+
this.appServer = this.config.appServer;
|
98
|
+
this.logger = this.appServer.logger.child({ userId: this.config.userId, service: 'app-session' });
|
99
99
|
this.userId = this.config.userId;
|
100
100
|
// Make sure the URL is correctly formatted to prevent double protocol issues
|
101
101
|
if (this.config.augmentOSWebsocketUrl) {
|
@@ -113,7 +113,7 @@ class TpaSession {
|
|
113
113
|
}
|
114
114
|
}
|
115
115
|
// Log initialization
|
116
|
-
this.logger.debug(`🚀 [${this.config.packageName}]
|
116
|
+
this.logger.debug(`🚀 [${this.config.packageName}] App Session initialized`);
|
117
117
|
this.logger.debug(`🚀 [${this.config.packageName}] WebSocket URL: ${this.config.augmentOSWebsocketUrl}`);
|
118
118
|
// Validate URL format - give early warning for obvious issues
|
119
119
|
// Check URL format but handle undefined case
|
@@ -132,23 +132,23 @@ class TpaSession {
|
|
132
132
|
this.layouts = new layouts_1.LayoutManager(config.packageName, this.send.bind(this));
|
133
133
|
// Initialize settings manager with all necessary parameters, including subscribeFn for AugmentOS settings
|
134
134
|
this.settings = new settings_1.SettingsManager(this.settingsData, this.config.packageName, this.config.augmentOSWebsocketUrl, this.sessionId ?? undefined, async (streams) => {
|
135
|
-
this.logger.debug(`[
|
135
|
+
this.logger.debug(`[AppSession] subscribeFn called for streams:`, streams);
|
136
136
|
streams.forEach((stream) => {
|
137
137
|
if (!this.subscriptions.has(stream)) {
|
138
138
|
this.subscriptions.add(stream);
|
139
|
-
this.logger.debug(`[
|
139
|
+
this.logger.debug(`[AppSession] Auto-subscribed to stream '${stream}' for AugmentOS setting.`);
|
140
140
|
}
|
141
141
|
else {
|
142
|
-
this.logger.debug(`[
|
142
|
+
this.logger.debug(`[AppSession] Already subscribed to stream '${stream}'.`);
|
143
143
|
}
|
144
144
|
});
|
145
|
-
this.logger.debug(`[
|
145
|
+
this.logger.debug(`[AppSession] Current subscriptions after subscribeFn:`, Array.from(this.subscriptions));
|
146
146
|
if (this.ws?.readyState === 1) {
|
147
147
|
this.updateSubscriptions();
|
148
|
-
this.logger.debug(`[
|
148
|
+
this.logger.debug(`[AppSession] Sent updated subscriptions to cloud after auto-subscribing to AugmentOS setting.`);
|
149
149
|
}
|
150
150
|
else {
|
151
|
-
this.logger.debug(`[
|
151
|
+
this.logger.debug(`[AppSession] WebSocket not open, will send subscriptions when connected.`);
|
152
152
|
}
|
153
153
|
});
|
154
154
|
// Initialize dashboard API with this session instance
|
@@ -167,7 +167,7 @@ class TpaSession {
|
|
167
167
|
return this.sessionId || 'unknown-session-id';
|
168
168
|
}
|
169
169
|
/**
|
170
|
-
* Get the package name for this
|
170
|
+
* Get the package name for this App
|
171
171
|
* @returns The package name
|
172
172
|
*/
|
173
173
|
getPackageName() {
|
@@ -255,8 +255,8 @@ class TpaSession {
|
|
255
255
|
* @param type - Type of event to subscribe to
|
256
256
|
*/
|
257
257
|
subscribe(type) {
|
258
|
-
if (
|
259
|
-
this.logger.warn(`[
|
258
|
+
if (APP_TO_APP_EVENT_TYPES.includes(type)) {
|
259
|
+
this.logger.warn(`[AppSession] Attempted to subscribe to App-to-App event type '${type}', which is not a valid stream. Use the event handler (e.g., onAppMessage) instead.`);
|
260
260
|
return;
|
261
261
|
}
|
262
262
|
this.subscriptions.add(type);
|
@@ -269,8 +269,8 @@ class TpaSession {
|
|
269
269
|
* @param type - Type of event to unsubscribe from
|
270
270
|
*/
|
271
271
|
unsubscribe(type) {
|
272
|
-
if (
|
273
|
-
this.logger.warn(`[
|
272
|
+
if (APP_TO_APP_EVENT_TYPES.includes(type)) {
|
273
|
+
this.logger.warn(`[AppSession] Attempted to unsubscribe from App-to-App event type '${type}', which is not a valid stream.`);
|
274
274
|
return;
|
275
275
|
}
|
276
276
|
this.subscriptions.delete(type);
|
@@ -538,7 +538,7 @@ class TpaSession {
|
|
538
538
|
this.pendingPhotoRequests.set(requestId, { resolve, reject });
|
539
539
|
// Create photo request message
|
540
540
|
const message = {
|
541
|
-
type: types_1.
|
541
|
+
type: types_1.AppToCloudMessageType.PHOTO_REQUEST,
|
542
542
|
packageName: this.config.packageName,
|
543
543
|
sessionId: this.sessionId,
|
544
544
|
timestamp: new Date(),
|
@@ -580,7 +580,7 @@ class TpaSession {
|
|
580
580
|
}
|
581
581
|
/**
|
582
582
|
* ⚙️ Configure settings-based subscription updates
|
583
|
-
* This allows
|
583
|
+
* This allows Apps to automatically update their subscriptions when certain settings change
|
584
584
|
* @param options Configuration options for settings-based subscriptions
|
585
585
|
*/
|
586
586
|
setSubscriptionSettings(options) {
|
@@ -636,32 +636,32 @@ class TpaSession {
|
|
636
636
|
}
|
637
637
|
/**
|
638
638
|
* 📝 Load configuration from a JSON file
|
639
|
-
* @param jsonData JSON string containing
|
639
|
+
* @param jsonData JSON string containing App configuration
|
640
640
|
* @returns The loaded configuration
|
641
641
|
* @throws Error if the configuration is invalid
|
642
642
|
*/
|
643
643
|
loadConfigFromJson(jsonData) {
|
644
644
|
try {
|
645
645
|
const parsedConfig = JSON.parse(jsonData);
|
646
|
-
if ((0, types_1.
|
647
|
-
this.
|
646
|
+
if ((0, types_1.validateAppConfig)(parsedConfig)) {
|
647
|
+
this.appConfig = parsedConfig;
|
648
648
|
return parsedConfig;
|
649
649
|
}
|
650
650
|
else {
|
651
|
-
throw new Error('Invalid
|
651
|
+
throw new Error('Invalid App configuration format');
|
652
652
|
}
|
653
653
|
}
|
654
654
|
catch (error) {
|
655
655
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
656
|
-
throw new Error(`Failed to load
|
656
|
+
throw new Error(`Failed to load App configuration: ${errorMessage}`);
|
657
657
|
}
|
658
658
|
}
|
659
659
|
/**
|
660
|
-
* 📋 Get the loaded
|
661
|
-
* @returns The current
|
660
|
+
* 📋 Get the loaded App configuration
|
661
|
+
* @returns The current App configuration or null if not loaded
|
662
662
|
*/
|
663
663
|
getConfig() {
|
664
|
-
return this.
|
664
|
+
return this.appConfig;
|
665
665
|
}
|
666
666
|
/**
|
667
667
|
* 🔌 Get the WebSocket server URL for this session
|
@@ -674,28 +674,28 @@ class TpaSession {
|
|
674
674
|
if (!this.config.augmentOSWebsocketUrl) {
|
675
675
|
return undefined;
|
676
676
|
}
|
677
|
-
return
|
677
|
+
return AppSession.convertToHttps(this.config.augmentOSWebsocketUrl);
|
678
678
|
}
|
679
679
|
static convertToHttps(rawUrl) {
|
680
680
|
if (!rawUrl)
|
681
681
|
return '';
|
682
682
|
// Remove ws:// or wss://
|
683
683
|
let url = rawUrl.replace(/^wss?:\/\//, '');
|
684
|
-
// Remove trailing /
|
685
|
-
url = url.replace(/\/
|
684
|
+
// Remove trailing /app-ws
|
685
|
+
url = url.replace(/\/app-ws$/, '');
|
686
686
|
// Prepend https://
|
687
687
|
return `https://${url}`;
|
688
688
|
}
|
689
689
|
/**
|
690
|
-
* 🔍 Get default settings from the
|
690
|
+
* 🔍 Get default settings from the App configuration
|
691
691
|
* @returns Array of settings with default values
|
692
692
|
* @throws Error if configuration is not loaded
|
693
693
|
*/
|
694
694
|
getDefaultSettings() {
|
695
|
-
if (!this.
|
696
|
-
throw new Error('
|
695
|
+
if (!this.appConfig) {
|
696
|
+
throw new Error('App configuration not loaded. Call loadConfigFromJson first.');
|
697
697
|
}
|
698
|
-
return this.
|
698
|
+
return this.appConfig.settings
|
699
699
|
.filter((s) => s.type !== 'group')
|
700
700
|
.map((s) => ({
|
701
701
|
...s,
|
@@ -708,9 +708,9 @@ class TpaSession {
|
|
708
708
|
* @returns The setting schema or undefined if not found
|
709
709
|
*/
|
710
710
|
getSettingSchema(key) {
|
711
|
-
if (!this.
|
711
|
+
if (!this.appConfig)
|
712
712
|
return undefined;
|
713
|
-
const setting = this.
|
713
|
+
const setting = this.appConfig.settings.find((s) => s.type !== 'group' && 'key' in s && s.key === key);
|
714
714
|
return setting;
|
715
715
|
}
|
716
716
|
// =====================================
|
@@ -733,16 +733,16 @@ class TpaSession {
|
|
733
733
|
}
|
734
734
|
// Using type guards to determine message type and safely handle each case
|
735
735
|
try {
|
736
|
-
if ((0, types_1.
|
736
|
+
if ((0, types_1.isAppConnectionAck)(message)) {
|
737
737
|
// Get settings from connection acknowledgment
|
738
738
|
const receivedSettings = message.settings || [];
|
739
739
|
this.settingsData = receivedSettings;
|
740
740
|
// Store config if provided
|
741
|
-
if (message.config && (0, types_1.
|
742
|
-
this.
|
741
|
+
if (message.config && (0, types_1.validateAppConfig)(message.config)) {
|
742
|
+
this.appConfig = message.config;
|
743
743
|
}
|
744
744
|
// Use default settings from config if no settings were provided
|
745
|
-
if (receivedSettings.length === 0 && this.
|
745
|
+
if (receivedSettings.length === 0 && this.appConfig) {
|
746
746
|
try {
|
747
747
|
this.settingsData = this.getDefaultSettings();
|
748
748
|
}
|
@@ -753,21 +753,21 @@ class TpaSession {
|
|
753
753
|
// Update the settings manager with the new settings
|
754
754
|
this.settings.updateSettings(this.settingsData);
|
755
755
|
// Handle AugmentOS system settings if provided
|
756
|
-
this.logger.debug(`[
|
756
|
+
this.logger.debug(`[AppSession] CONNECTION_ACK augmentosSettings:`, message.augmentosSettings);
|
757
757
|
if (message.augmentosSettings) {
|
758
|
-
this.logger.info(`[
|
758
|
+
this.logger.info(`[AppSession] Calling updateAugmentosSettings with:`, message.augmentosSettings);
|
759
759
|
this.settings.updateAugmentosSettings(message.augmentosSettings);
|
760
760
|
}
|
761
761
|
else {
|
762
|
-
this.logger.warn(`[
|
762
|
+
this.logger.warn(`[AppSession] CONNECTION_ACK message missing augmentosSettings field`);
|
763
763
|
}
|
764
764
|
// Handle device capabilities if provided
|
765
765
|
if (message.capabilities) {
|
766
766
|
this.capabilities = message.capabilities;
|
767
|
-
this.logger.info(`[
|
767
|
+
this.logger.info(`[AppSession] Device capabilities loaded for model: ${message.capabilities.modelName}`);
|
768
768
|
}
|
769
769
|
else {
|
770
|
-
this.logger.debug(`[
|
770
|
+
this.logger.debug(`[AppSession] No capabilities provided in CONNECTION_ACK`);
|
771
771
|
}
|
772
772
|
// Emit connected event with settings
|
773
773
|
this.events.emit('connected', this.settingsData);
|
@@ -778,8 +778,8 @@ class TpaSession {
|
|
778
778
|
this.updateSubscriptionsFromSettings();
|
779
779
|
}
|
780
780
|
}
|
781
|
-
else if ((0, types_1.
|
782
|
-
// Handle both
|
781
|
+
else if ((0, types_1.isAppConnectionError)(message) || message.type === 'connection_error') {
|
782
|
+
// Handle both App-specific connection_error and standard connection_error
|
783
783
|
const errorMessage = message.message || 'Unknown connection error';
|
784
784
|
this.events.emit('error', new Error(errorMessage));
|
785
785
|
}
|
@@ -809,7 +809,7 @@ class TpaSession {
|
|
809
809
|
this.events.emit(messageStreamType, sanitizedData);
|
810
810
|
}
|
811
811
|
}
|
812
|
-
else if ((0,
|
812
|
+
else if ((0, cloud_to_app_1.isPhotoResponse)(message)) {
|
813
813
|
// Handle photo response by resolving the pending promise
|
814
814
|
if (this.pendingPhotoRequests.has(message.requestId)) {
|
815
815
|
const { resolve } = this.pendingPhotoRequests.get(message.requestId);
|
@@ -817,7 +817,7 @@ class TpaSession {
|
|
817
817
|
this.pendingPhotoRequests.delete(message.requestId);
|
818
818
|
}
|
819
819
|
}
|
820
|
-
else if ((0,
|
820
|
+
else if ((0, cloud_to_app_1.isRtmpStreamStatus)(message)) {
|
821
821
|
// Emit as a standard stream event if subscribed
|
822
822
|
if (this.subscriptions.has(types_1.StreamType.RTMP_STREAM_STATUS)) {
|
823
823
|
this.events.emit(types_1.StreamType.RTMP_STREAM_STATUS, message);
|
@@ -892,24 +892,24 @@ class TpaSession {
|
|
892
892
|
}
|
893
893
|
}
|
894
894
|
// Handle custom messages
|
895
|
-
else if (message.type === types_1.
|
895
|
+
else if (message.type === types_1.CloudToAppMessageType.CUSTOM_MESSAGE) {
|
896
896
|
this.events.emit('custom_message', message);
|
897
897
|
return;
|
898
898
|
}
|
899
|
-
// Handle
|
900
|
-
else if (message.type === '
|
901
|
-
this.
|
899
|
+
// Handle App-to-App communication messages
|
900
|
+
else if (message.type === 'app_message_received') {
|
901
|
+
this.appEvents.emit('app_message_received', message);
|
902
902
|
}
|
903
|
-
else if (message.type === '
|
904
|
-
this.
|
903
|
+
else if (message.type === 'app_user_joined') {
|
904
|
+
this.appEvents.emit('app_user_joined', message);
|
905
905
|
}
|
906
|
-
else if (message.type === '
|
907
|
-
this.
|
906
|
+
else if (message.type === 'app_user_left') {
|
907
|
+
this.appEvents.emit('app_user_left', message);
|
908
908
|
}
|
909
|
-
else if (message.type === '
|
910
|
-
this.
|
909
|
+
else if (message.type === 'app_room_updated') {
|
910
|
+
this.appEvents.emit('app_room_updated', message);
|
911
911
|
}
|
912
|
-
else if (message.type === '
|
912
|
+
else if (message.type === 'app_direct_message_response') {
|
913
913
|
const response = message;
|
914
914
|
if (response.messageId && this.pendingDirectMessages.has(response.messageId)) {
|
915
915
|
const { resolve } = this.pendingDirectMessages.get(response.messageId);
|
@@ -925,7 +925,7 @@ class TpaSession {
|
|
925
925
|
}
|
926
926
|
// Handle 'connection_error' as a specific case if cloud sends this string literal
|
927
927
|
else if (message.type === 'connection_error') {
|
928
|
-
// Treat 'connection_error' (string literal) like
|
928
|
+
// Treat 'connection_error' (string literal) like AppConnectionError
|
929
929
|
// This handles cases where the cloud might send the type as a direct string
|
930
930
|
// instead of the enum's 'tpa_connection_error' value.
|
931
931
|
const errorMessage = message.message || 'Unknown connection error (type: connection_error)';
|
@@ -974,14 +974,14 @@ class TpaSession {
|
|
974
974
|
}
|
975
975
|
}
|
976
976
|
catch (processingError) {
|
977
|
-
// Catch any errors during message processing to prevent
|
977
|
+
// Catch any errors during message processing to prevent App crashes
|
978
978
|
this.logger.error(processingError, 'Error processing message:');
|
979
979
|
const errorMessage = processingError instanceof Error ? processingError.message : String(processingError);
|
980
980
|
this.events.emit('error', new Error(`Error processing message: ${errorMessage}`));
|
981
981
|
}
|
982
982
|
}
|
983
983
|
catch (error) {
|
984
|
-
// Final safety net to ensure the
|
984
|
+
// Final safety net to ensure the App doesn't crash on any unexpected errors
|
985
985
|
this.logger.error(error, 'Unexpected error in message handler');
|
986
986
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
987
987
|
this.events.emit('error', new Error(`Unexpected error in message handler: ${errorMessage}`));
|
@@ -1093,7 +1093,7 @@ class TpaSession {
|
|
1093
1093
|
*/
|
1094
1094
|
sendConnectionInit() {
|
1095
1095
|
const message = {
|
1096
|
-
type: types_1.
|
1096
|
+
type: types_1.AppToCloudMessageType.CONNECTION_INIT,
|
1097
1097
|
sessionId: this.sessionId,
|
1098
1098
|
packageName: this.config.packageName,
|
1099
1099
|
apiKey: this.config.apiKey,
|
@@ -1105,9 +1105,9 @@ class TpaSession {
|
|
1105
1105
|
* 📝 Update subscription list with cloud
|
1106
1106
|
*/
|
1107
1107
|
updateSubscriptions() {
|
1108
|
-
this.logger.info(`[
|
1108
|
+
this.logger.info(`[AppSession] updateSubscriptions: sending subscriptions to cloud:`, Array.from(this.subscriptions));
|
1109
1109
|
const message = {
|
1110
|
-
type: types_1.
|
1110
|
+
type: types_1.AppToCloudMessageType.SUBSCRIPTION_UPDATE,
|
1111
1111
|
packageName: this.config.packageName,
|
1112
1112
|
subscriptions: Array.from(this.subscriptions),
|
1113
1113
|
sessionId: this.sessionId,
|
@@ -1128,7 +1128,7 @@ class TpaSession {
|
|
1128
1128
|
const maxAttempts = this.config.maxReconnectAttempts || 3;
|
1129
1129
|
if (this.reconnectAttempts >= maxAttempts) {
|
1130
1130
|
this.logger.info(`🔄 Maximum reconnection attempts (${maxAttempts}) reached, giving up`);
|
1131
|
-
// Emit a permanent disconnection event to trigger onStop in the
|
1131
|
+
// Emit a permanent disconnection event to trigger onStop in the App server
|
1132
1132
|
this.events.emit('disconnected', {
|
1133
1133
|
message: `Connection permanently lost after ${maxAttempts} failed reconnection attempts`,
|
1134
1134
|
code: 4000, // Custom code for max reconnection attempts exhausted
|
@@ -1213,7 +1213,7 @@ class TpaSession {
|
|
1213
1213
|
}
|
1214
1214
|
}
|
1215
1215
|
catch (error) {
|
1216
|
-
// Log the error and emit an event so
|
1216
|
+
// Log the error and emit an event so App developers are aware
|
1217
1217
|
this.logger.error(error, 'Message send error');
|
1218
1218
|
// Ensure we always emit an Error object
|
1219
1219
|
if (error instanceof Error) {
|
@@ -1242,22 +1242,22 @@ class TpaSession {
|
|
1242
1242
|
}
|
1243
1243
|
}
|
1244
1244
|
// =====================================
|
1245
|
-
// 👥
|
1245
|
+
// 👥 App-to-App Communication Interface
|
1246
1246
|
// =====================================
|
1247
1247
|
/**
|
1248
|
-
* 👥 Discover other users currently using the same
|
1248
|
+
* 👥 Discover other users currently using the same App
|
1249
1249
|
* @param includeProfiles - Whether to include user profile information
|
1250
1250
|
* @returns Promise that resolves with list of active users
|
1251
1251
|
*/
|
1252
|
-
async
|
1252
|
+
async discoverAppUsers(domain, includeProfiles = false) {
|
1253
1253
|
// Use the domain argument as the base URL if provided
|
1254
1254
|
if (!domain) {
|
1255
1255
|
throw new Error('Domain (API base URL) is required for user discovery');
|
1256
1256
|
}
|
1257
|
-
const url = `${domain}/api/
|
1257
|
+
const url = `${domain}/api/app-communication/discover-users`;
|
1258
1258
|
// Use the user's core token for authentication
|
1259
|
-
const
|
1260
|
-
if (!
|
1259
|
+
const appApiKey = this.config.apiKey; // This may need to be updated if you store the core token elsewhere
|
1260
|
+
if (!appApiKey) {
|
1261
1261
|
throw new Error('Core token (apiKey) is required for user discovery');
|
1262
1262
|
}
|
1263
1263
|
const body = {
|
@@ -1268,7 +1268,7 @@ class TpaSession {
|
|
1268
1268
|
const response = await fetch(url, {
|
1269
1269
|
method: 'POST',
|
1270
1270
|
headers: {
|
1271
|
-
'Authorization': `Bearer ${
|
1271
|
+
'Authorization': `Bearer ${appApiKey}`,
|
1272
1272
|
'Content-Type': 'application/json'
|
1273
1273
|
},
|
1274
1274
|
body: JSON.stringify(body)
|
@@ -1286,7 +1286,7 @@ class TpaSession {
|
|
1286
1286
|
*/
|
1287
1287
|
async isUserActive(userId) {
|
1288
1288
|
try {
|
1289
|
-
const userList = await this.
|
1289
|
+
const userList = await this.discoverAppUsers('', false);
|
1290
1290
|
return userList.users.some((user) => user.userId === userId);
|
1291
1291
|
}
|
1292
1292
|
catch (error) {
|
@@ -1295,12 +1295,12 @@ class TpaSession {
|
|
1295
1295
|
}
|
1296
1296
|
}
|
1297
1297
|
/**
|
1298
|
-
* 📊 Get user count for this
|
1298
|
+
* 📊 Get user count for this App
|
1299
1299
|
* @returns Promise that resolves with number of active users
|
1300
1300
|
*/
|
1301
1301
|
async getUserCount(domain) {
|
1302
1302
|
try {
|
1303
|
-
const userList = await this.
|
1303
|
+
const userList = await this.discoverAppUsers(domain, false);
|
1304
1304
|
return userList.totalUsers;
|
1305
1305
|
}
|
1306
1306
|
catch (error) {
|
@@ -1309,16 +1309,16 @@ class TpaSession {
|
|
1309
1309
|
}
|
1310
1310
|
}
|
1311
1311
|
/**
|
1312
|
-
* 📢 Send broadcast message to all users with same
|
1312
|
+
* 📢 Send broadcast message to all users with same App active
|
1313
1313
|
* @param payload - Message payload to send
|
1314
1314
|
* @param roomId - Optional room ID for room-based messaging
|
1315
1315
|
* @returns Promise that resolves when message is sent
|
1316
1316
|
*/
|
1317
|
-
async
|
1317
|
+
async broadcastToAppUsers(payload, roomId) {
|
1318
1318
|
try {
|
1319
1319
|
const messageId = this.generateMessageId();
|
1320
1320
|
const message = {
|
1321
|
-
type: '
|
1321
|
+
type: 'app_broadcast_message',
|
1322
1322
|
packageName: this.config.packageName,
|
1323
1323
|
sessionId: this.sessionId,
|
1324
1324
|
payload,
|
@@ -1346,7 +1346,7 @@ class TpaSession {
|
|
1346
1346
|
// Store promise resolver
|
1347
1347
|
this.pendingDirectMessages.set(messageId, { resolve, reject });
|
1348
1348
|
const message = {
|
1349
|
-
type: '
|
1349
|
+
type: 'app_direct_message',
|
1350
1350
|
packageName: this.config.packageName,
|
1351
1351
|
sessionId: this.sessionId,
|
1352
1352
|
targetUserId,
|
@@ -1377,10 +1377,10 @@ class TpaSession {
|
|
1377
1377
|
* @param roomConfig - Optional room configuration
|
1378
1378
|
* @returns Promise that resolves when room is joined
|
1379
1379
|
*/
|
1380
|
-
async
|
1380
|
+
async joinAppRoom(roomId, roomConfig) {
|
1381
1381
|
try {
|
1382
1382
|
const message = {
|
1383
|
-
type: '
|
1383
|
+
type: 'app_room_join',
|
1384
1384
|
packageName: this.config.packageName,
|
1385
1385
|
sessionId: this.sessionId,
|
1386
1386
|
roomId,
|
@@ -1399,10 +1399,10 @@ class TpaSession {
|
|
1399
1399
|
* @param roomId - Room ID to leave
|
1400
1400
|
* @returns Promise that resolves when room is left
|
1401
1401
|
*/
|
1402
|
-
async
|
1402
|
+
async leaveAppRoom(roomId) {
|
1403
1403
|
try {
|
1404
1404
|
const message = {
|
1405
|
-
type: '
|
1405
|
+
type: 'app_room_leave',
|
1406
1406
|
packageName: this.config.packageName,
|
1407
1407
|
sessionId: this.sessionId,
|
1408
1408
|
roomId,
|
@@ -1416,40 +1416,40 @@ class TpaSession {
|
|
1416
1416
|
}
|
1417
1417
|
}
|
1418
1418
|
/**
|
1419
|
-
* 📨 Listen for messages from other
|
1419
|
+
* 📨 Listen for messages from other App users
|
1420
1420
|
* @param handler - Function to handle incoming messages
|
1421
1421
|
* @returns Cleanup function to remove the handler
|
1422
1422
|
*/
|
1423
|
-
|
1424
|
-
this.
|
1425
|
-
return () => this.
|
1423
|
+
onAppMessage(handler) {
|
1424
|
+
this.appEvents.on('app_message_received', handler);
|
1425
|
+
return () => this.appEvents.off('app_message_received', handler);
|
1426
1426
|
}
|
1427
1427
|
/**
|
1428
1428
|
* 👋 Listen for user join events
|
1429
1429
|
* @param handler - Function to handle user join events
|
1430
1430
|
* @returns Cleanup function to remove the handler
|
1431
1431
|
*/
|
1432
|
-
|
1433
|
-
this.
|
1434
|
-
return () => this.
|
1432
|
+
onAppUserJoined(handler) {
|
1433
|
+
this.appEvents.on('app_user_joined', handler);
|
1434
|
+
return () => this.appEvents.off('app_user_joined', handler);
|
1435
1435
|
}
|
1436
1436
|
/**
|
1437
1437
|
* 🚪 Listen for user leave events
|
1438
1438
|
* @param handler - Function to handle user leave events
|
1439
1439
|
* @returns Cleanup function to remove the handler
|
1440
1440
|
*/
|
1441
|
-
|
1442
|
-
this.
|
1443
|
-
return () => this.
|
1441
|
+
onAppUserLeft(handler) {
|
1442
|
+
this.appEvents.on('app_user_left', handler);
|
1443
|
+
return () => this.appEvents.off('app_user_left', handler);
|
1444
1444
|
}
|
1445
1445
|
/**
|
1446
1446
|
* 🏠 Listen for room update events
|
1447
1447
|
* @param handler - Function to handle room updates
|
1448
1448
|
* @returns Cleanup function to remove the handler
|
1449
1449
|
*/
|
1450
|
-
|
1451
|
-
this.
|
1452
|
-
return () => this.
|
1450
|
+
onAppRoomUpdated(handler) {
|
1451
|
+
this.appEvents.on('app_room_updated', handler);
|
1452
|
+
return () => this.appEvents.off('app_room_updated', handler);
|
1453
1453
|
}
|
1454
1454
|
/**
|
1455
1455
|
* 🔧 Generate unique message ID
|
@@ -1459,4 +1459,4 @@ class TpaSession {
|
|
1459
1459
|
return `msg_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
1460
1460
|
}
|
1461
1461
|
}
|
1462
|
-
exports.
|
1462
|
+
exports.AppSession = AppSession;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* 🎨 Layout Manager Module
|
3
3
|
*
|
4
|
-
* Manages AR display layouts for
|
4
|
+
* Manages AR display layouts for Apps. This class provides an easy-to-use interface
|
5
5
|
* for showing different types of content in the user's AR view.
|
6
6
|
*
|
7
7
|
* @example
|
@@ -22,7 +22,7 @@ export declare class LayoutManager {
|
|
22
22
|
/**
|
23
23
|
* 🎯 Creates a new LayoutManager instance
|
24
24
|
*
|
25
|
-
* @param packageName -
|
25
|
+
* @param packageName - App package identifier
|
26
26
|
* @param sendMessage - Function to send display requests to AugmentOS
|
27
27
|
*/
|
28
28
|
constructor(packageName: string, sendMessage: (message: DisplayRequest) => void);
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"layouts.d.ts","sourceRoot":"","sources":["../../../src/
|
1
|
+
{"version":3,"file":"layouts.d.ts","sourceRoot":"","sources":["../../../src/app/session/layouts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EACL,cAAc,EAOd,QAAQ,EAGT,MAAM,aAAa,CAAC;AAErB,qBAAa,aAAa;IAQtB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,WAAW;IARrB;;;;;OAKG;gBAEO,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI;IAGxD;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB;IAmG1B;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CACV,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAC;IAuCnD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAcpD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,iBAAiB,CACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAclD;;;;;;;;;;;;KAYC;IACH,cAAc,CACZ,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAapD;;;;;;;;;;;;;;;;OAgBG;IACH,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,QAAQ,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;CAarD"}
|