@mentra/sdk 2.0.3 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app/server/index.d.ts +40 -1
- package/dist/app/server/index.d.ts.map +1 -1
- package/dist/app/server/index.js +114 -2
- package/dist/app/session/index.d.ts +34 -13
- package/dist/app/session/index.d.ts.map +1 -1
- package/dist/app/session/index.js +45 -57
- package/dist/app/session/modules/camera.d.ts +230 -0
- package/dist/app/session/modules/camera.d.ts.map +1 -0
- package/dist/app/session/modules/camera.js +439 -0
- package/dist/examples/rtmp-streaming-example.js +3 -3
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/messages/app-to-cloud.d.ts +1 -0
- package/dist/types/messages/app-to-cloud.d.ts.map +1 -1
- package/dist/types/messages/cloud-to-glasses.d.ts +1 -0
- package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -1
- package/dist/types/messages/glasses-to-cloud.d.ts +3 -0
- package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
- package/dist/types/photo-data.d.ts +18 -0
- package/dist/types/photo-data.d.ts.map +1 -0
- package/dist/types/photo-data.js +2 -0
- package/dist/types/rtmp-stream.d.ts +2 -2
- package/package.json +2 -2
- package/dist/app/session/modules/streaming.d.ts +0 -100
- package/dist/app/session/modules/streaming.d.ts.map +0 -1
- package/dist/app/session/modules/streaming.js +0 -270
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* 🚀 App Server Module
|
3
3
|
*
|
4
|
-
* Creates and manages a server for
|
4
|
+
* Creates and manages a server for Apps in the MentraOS ecosystem.
|
5
5
|
* Handles webhook endpoints, session management, and cleanup.
|
6
6
|
*/
|
7
7
|
import { type Express } from 'express';
|
@@ -189,5 +189,44 @@ export declare class AppServer {
|
|
189
189
|
* Closes all active sessions and runs cleanup handlers.
|
190
190
|
*/
|
191
191
|
private cleanup;
|
192
|
+
/**
|
193
|
+
* 🎯 Setup Photo Upload Endpoint
|
194
|
+
* Creates a /photo-upload endpoint for receiving photos directly from ASG glasses
|
195
|
+
*/
|
196
|
+
private setupPhotoUploadEndpoint;
|
197
|
+
/**
|
198
|
+
* Find session that has a pending photo request for the given requestId
|
199
|
+
*/
|
200
|
+
private findSessionByPhotoRequestId;
|
201
|
+
}
|
202
|
+
/**
|
203
|
+
* @deprecated Use `AppServerConfig` instead. `TpaServerConfig` is deprecated and will be removed in a future version.
|
204
|
+
* This is an alias for backward compatibility only.
|
205
|
+
*
|
206
|
+
* @example
|
207
|
+
* ```typescript
|
208
|
+
* // ❌ Deprecated - Don't use this
|
209
|
+
* const config: TpaServerConfig = { ... };
|
210
|
+
*
|
211
|
+
* // ✅ Use this instead
|
212
|
+
* const config: AppServerConfig = { ... };
|
213
|
+
* ```
|
214
|
+
*/
|
215
|
+
export type TpaServerConfig = AppServerConfig;
|
216
|
+
/**
|
217
|
+
* @deprecated Use `AppServer` instead. `TpaServer` is deprecated and will be removed in a future version.
|
218
|
+
* This is an alias for backward compatibility only.
|
219
|
+
*
|
220
|
+
* @example
|
221
|
+
* ```typescript
|
222
|
+
* // ❌ Deprecated - Don't use this
|
223
|
+
* class MyServer extends TpaServer { ... }
|
224
|
+
*
|
225
|
+
* // ✅ Use this instead
|
226
|
+
* class MyServer extends AppServer { ... }
|
227
|
+
* ```
|
228
|
+
*/
|
229
|
+
export declare class TpaServer extends AppServer {
|
230
|
+
constructor(config: TpaServerConfig);
|
192
231
|
}
|
193
232
|
//# sourceMappingURL=index.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/app/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAQL,QAAQ,EACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAI9B;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAe;IAC9B,oIAAoI;IACpI,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAE3B,iEAAiE;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,SAAS;IAYR,OAAO,CAAC,MAAM;IAX1B,2BAA2B;IAC3B,OAAO,CAAC,GAAG,CAAU;IACrB,+CAA+C;IAC/C,OAAO,CAAC,cAAc,CAAiC;IACvD,mDAAmD;IACnD,OAAO,CAAC,eAAe,CAAyB;IAChD,gDAAgD;IAChD,OAAO,CAAC,eAAe,CAAuB;IAE9C,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEX,MAAM,EAAE,eAAe;
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/app/server/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAgB,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EAQL,QAAQ,EACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAI9B;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAe;IAC9B,oIAAoI;IACpI,WAAW,EAAE,MAAM,CAAC;IACpB,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,+FAA+F;IAC/F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAE3B,iEAAiE;IACjE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gDAAgD;IAChD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,SAAS;IAYR,OAAO,CAAC,MAAM;IAX1B,2BAA2B;IAC3B,OAAO,CAAC,GAAG,CAAU;IACrB,+CAA+C;IAC/C,OAAO,CAAC,cAAc,CAAiC;IACvD,mDAAmD;IACnD,OAAO,CAAC,eAAe,CAAyB;IAChD,gDAAgD;IAChD,OAAO,CAAC,eAAe,CAAuB;IAE9C,SAAgB,MAAM,EAAE,MAAM,CAAC;gBAEX,MAAM,EAAE,eAAe;IAwCpC,aAAa,IAAI,OAAO;IAI/B;;;;;;;;OAQG;cACa,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhG;;;;;;;;OAQG;cACa,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWxF;;;;;;;OAOG;cACa,UAAU,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAM3E;;;;;OAKG;IACI,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAY7B;;;OAGG;IACI,IAAI,IAAI,IAAI;IAMnB;;;;;;;;KAQC;IACD,SAAS,CAAC,aAAa,CACrB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,MAAM;IAYT;;;;;OAKG;IACH,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,IAAI,GAAG,IAAI;IAItD;;;OAGG;IACH,OAAO,CAAC,YAAY;IAoCpB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IA2B7B;;OAEG;YACW,oBAAoB;IA6DlC;;OAEG;YACW,iBAAiB;IAgB/B;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;;OAGG;IACH,OAAO,CAAC,qBAAqB;IAyD7B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAQtB;;;OAGG;IACH,OAAO,CAAC,aAAa;IAKrB;;;OAGG;IACH,OAAO,CAAC,OAAO;IAYf;;;OAGG;IACH,OAAO,CAAC,wBAAwB;IAkFhC;;OAEG;IACH,OAAO,CAAC,2BAA2B;CAQpC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC;AAE9C;;;;;;;;;;;;GAYG;AACH,qBAAa,SAAU,SAAQ,SAAS;gBAC1B,MAAM,EAAE,eAAe;CASpC"}
|
package/dist/app/server/index.js
CHANGED
@@ -3,11 +3,11 @@ 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.AppServer = void 0;
|
6
|
+
exports.TpaServer = exports.AppServer = void 0;
|
7
7
|
/**
|
8
8
|
* 🚀 App Server Module
|
9
9
|
*
|
10
|
-
* Creates and manages a server for
|
10
|
+
* Creates and manages a server for Apps in the MentraOS ecosystem.
|
11
11
|
* Handles webhook endpoints, session management, and cleanup.
|
12
12
|
*/
|
13
13
|
const express_1 = __importDefault(require("express"));
|
@@ -81,6 +81,7 @@ class AppServer {
|
|
81
81
|
this.setupSettingsEndpoint();
|
82
82
|
this.setupHealthCheck();
|
83
83
|
this.setupToolCallEndpoint();
|
84
|
+
this.setupPhotoUploadEndpoint();
|
84
85
|
this.setupPublicDir();
|
85
86
|
this.setupShutdown();
|
86
87
|
}
|
@@ -432,5 +433,116 @@ class AppServer {
|
|
432
433
|
// Run cleanup handlers
|
433
434
|
this.cleanupHandlers.forEach(handler => handler());
|
434
435
|
}
|
436
|
+
/**
|
437
|
+
* 🎯 Setup Photo Upload Endpoint
|
438
|
+
* Creates a /photo-upload endpoint for receiving photos directly from ASG glasses
|
439
|
+
*/
|
440
|
+
setupPhotoUploadEndpoint() {
|
441
|
+
const multer = require('multer');
|
442
|
+
// Configure multer for handling multipart form data
|
443
|
+
const upload = multer({
|
444
|
+
storage: multer.memoryStorage(),
|
445
|
+
limits: {
|
446
|
+
fileSize: 10 * 1024 * 1024, // 10MB limit
|
447
|
+
},
|
448
|
+
fileFilter: (req, file, cb) => {
|
449
|
+
// Accept image files only
|
450
|
+
if (file.mimetype && file.mimetype.startsWith('image/')) {
|
451
|
+
cb(null, true);
|
452
|
+
}
|
453
|
+
else {
|
454
|
+
cb(new Error('Only image files are allowed'), false);
|
455
|
+
}
|
456
|
+
}
|
457
|
+
});
|
458
|
+
this.app.post('/photo-upload', upload.single('photo'), async (req, res) => {
|
459
|
+
try {
|
460
|
+
const { requestId, type } = req.body;
|
461
|
+
const photoFile = req.file;
|
462
|
+
this.logger.info({ requestId, type }, `📸 Received photo upload: ${requestId}`);
|
463
|
+
if (!photoFile) {
|
464
|
+
this.logger.error({ requestId }, 'No photo file in upload');
|
465
|
+
return res.status(400).json({
|
466
|
+
success: false,
|
467
|
+
error: 'No photo file provided'
|
468
|
+
});
|
469
|
+
}
|
470
|
+
if (!requestId) {
|
471
|
+
this.logger.error('No requestId in photo upload');
|
472
|
+
return res.status(400).json({
|
473
|
+
success: false,
|
474
|
+
error: 'No requestId provided'
|
475
|
+
});
|
476
|
+
}
|
477
|
+
// Find the corresponding session that made this photo request
|
478
|
+
const session = this.findSessionByPhotoRequestId(requestId);
|
479
|
+
if (!session) {
|
480
|
+
this.logger.warn({ requestId }, 'No active session found for photo request');
|
481
|
+
return res.status(404).json({
|
482
|
+
success: false,
|
483
|
+
error: 'No active session found for this photo request'
|
484
|
+
});
|
485
|
+
}
|
486
|
+
// Create photo data object
|
487
|
+
const photoData = {
|
488
|
+
buffer: photoFile.buffer,
|
489
|
+
mimeType: photoFile.mimetype,
|
490
|
+
filename: photoFile.originalname || 'photo.jpg',
|
491
|
+
requestId,
|
492
|
+
size: photoFile.size,
|
493
|
+
timestamp: new Date()
|
494
|
+
};
|
495
|
+
// Deliver photo to the session
|
496
|
+
session.camera.handlePhotoReceived(photoData);
|
497
|
+
// Respond to ASG client
|
498
|
+
res.json({
|
499
|
+
success: true,
|
500
|
+
requestId,
|
501
|
+
message: 'Photo received successfully'
|
502
|
+
});
|
503
|
+
}
|
504
|
+
catch (error) {
|
505
|
+
this.logger.error(error, '❌ Error handling photo upload');
|
506
|
+
res.status(500).json({
|
507
|
+
success: false,
|
508
|
+
error: 'Internal server error processing photo upload'
|
509
|
+
});
|
510
|
+
}
|
511
|
+
});
|
512
|
+
}
|
513
|
+
/**
|
514
|
+
* Find session that has a pending photo request for the given requestId
|
515
|
+
*/
|
516
|
+
findSessionByPhotoRequestId(requestId) {
|
517
|
+
for (const [sessionId, session] of this.activeSessions) {
|
518
|
+
if (session.camera.hasPhotoPendingRequest(requestId)) {
|
519
|
+
return session;
|
520
|
+
}
|
521
|
+
}
|
522
|
+
return undefined;
|
523
|
+
}
|
435
524
|
}
|
436
525
|
exports.AppServer = AppServer;
|
526
|
+
/**
|
527
|
+
* @deprecated Use `AppServer` instead. `TpaServer` is deprecated and will be removed in a future version.
|
528
|
+
* This is an alias for backward compatibility only.
|
529
|
+
*
|
530
|
+
* @example
|
531
|
+
* ```typescript
|
532
|
+
* // ❌ Deprecated - Don't use this
|
533
|
+
* class MyServer extends TpaServer { ... }
|
534
|
+
*
|
535
|
+
* // ✅ Use this instead
|
536
|
+
* class MyServer extends AppServer { ... }
|
537
|
+
* ```
|
538
|
+
*/
|
539
|
+
class TpaServer extends AppServer {
|
540
|
+
constructor(config) {
|
541
|
+
super(config);
|
542
|
+
// Emit a deprecation warning to help developers migrate
|
543
|
+
console.warn('⚠️ DEPRECATION WARNING: TpaServer is deprecated and will be removed in a future version. ' +
|
544
|
+
'Please use AppServer instead. ' +
|
545
|
+
'Simply replace "TpaServer" with "AppServer" in your code.');
|
546
|
+
}
|
547
|
+
}
|
548
|
+
exports.TpaServer = TpaServer;
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { EventManager, EventData } from './events';
|
2
2
|
import { LayoutManager } from './layouts';
|
3
3
|
import { SettingsManager } from './settings';
|
4
|
-
import {
|
4
|
+
import { CameraModule } from './modules/camera';
|
5
5
|
import { ExtendedStreamType, ButtonPress, HeadPosition, PhoneNotification, TranscriptionData, TranslationData, AppSettings, AppSetting, AppConfig, VpsCoordinates, PhotoTaken, Capabilities } from '../../types';
|
6
6
|
import { DashboardAPI } from '../../types/dashboard';
|
7
7
|
import { Logger } from 'pino';
|
@@ -83,8 +83,6 @@ export declare class AppSession {
|
|
83
83
|
private subscriptionSettingsHandler?;
|
84
84
|
/** Settings that should trigger subscription updates when changed */
|
85
85
|
private subscriptionUpdateTriggers;
|
86
|
-
/** Pending photo requests waiting for responses */
|
87
|
-
private pendingPhotoRequests;
|
88
86
|
/** Pending user discovery requests waiting for responses */
|
89
87
|
private pendingUserDiscoveryRequests;
|
90
88
|
/** Pending direct message requests waiting for responses */
|
@@ -97,8 +95,8 @@ export declare class AppSession {
|
|
97
95
|
readonly settings: SettingsManager;
|
98
96
|
/** 📊 Dashboard management interface */
|
99
97
|
readonly dashboard: DashboardAPI;
|
100
|
-
/**
|
101
|
-
readonly
|
98
|
+
/** 📷 Camera interface for photos and streaming */
|
99
|
+
readonly camera: CameraModule;
|
102
100
|
readonly appServer: AppServer;
|
103
101
|
readonly logger: Logger;
|
104
102
|
readonly userId: string;
|
@@ -201,14 +199,6 @@ export declare class AppSession {
|
|
201
199
|
* 👋 Disconnect from MentraOS Cloud
|
202
200
|
*/
|
203
201
|
disconnect(): void;
|
204
|
-
/**
|
205
|
-
* 📸 Request a photo from the connected glasses
|
206
|
-
* @param options - Optional configuration for the photo request
|
207
|
-
* @returns Promise that resolves with the URL to the captured photo
|
208
|
-
*/
|
209
|
-
requestPhoto(options?: {
|
210
|
-
saveToGallery?: boolean;
|
211
|
-
}): Promise<string>;
|
212
202
|
/**
|
213
203
|
* 🛠️ Get all current user settings
|
214
204
|
* @returns A copy of the current settings array
|
@@ -395,4 +385,35 @@ export declare class AppSession {
|
|
395
385
|
*/
|
396
386
|
private generateMessageId;
|
397
387
|
}
|
388
|
+
/**
|
389
|
+
* @deprecated Use `AppSessionConfig` instead. `TpaSessionConfig` is deprecated and will be removed in a future version.
|
390
|
+
* This is an alias for backward compatibility only.
|
391
|
+
*
|
392
|
+
* @example
|
393
|
+
* ```typescript
|
394
|
+
* // ❌ Deprecated - Don't use this
|
395
|
+
* const config: TpaSessionConfig = { ... };
|
396
|
+
*
|
397
|
+
* // ✅ Use this instead
|
398
|
+
* const config: AppSessionConfig = { ... };
|
399
|
+
* ```
|
400
|
+
*/
|
401
|
+
export type TpaSessionConfig = AppSessionConfig;
|
402
|
+
/**
|
403
|
+
* @deprecated Use `AppSession` instead. `TpaSession` is deprecated and will be removed in a future version.
|
404
|
+
* This is an alias for backward compatibility only.
|
405
|
+
*
|
406
|
+
* @example
|
407
|
+
* ```typescript
|
408
|
+
* // ❌ Deprecated - Don't use this
|
409
|
+
* const session = new TpaSession(config);
|
410
|
+
*
|
411
|
+
* // ✅ Use this instead
|
412
|
+
* const session = new AppSession(config);
|
413
|
+
* ```
|
414
|
+
*/
|
415
|
+
export declare class TpaSession extends AppSession {
|
416
|
+
constructor(config: TpaSessionConfig);
|
417
|
+
}
|
418
|
+
export { CameraModule, PhotoRequestOptions, RtmpStreamOptions } from './modules/camera';
|
398
419
|
//# sourceMappingURL=index.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/app/session/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/app/session/index.ts"],"names":[],"mappings":"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"}
|
@@ -3,7 +3,7 @@ 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.AppSession = void 0;
|
6
|
+
exports.CameraModule = exports.TpaSession = exports.AppSession = void 0;
|
7
7
|
/**
|
8
8
|
* 🎯 App Session Module
|
9
9
|
*
|
@@ -14,7 +14,7 @@ const ws_1 = require("ws");
|
|
14
14
|
const events_1 = require("./events");
|
15
15
|
const layouts_1 = require("./layouts");
|
16
16
|
const settings_1 = require("./settings");
|
17
|
-
const
|
17
|
+
const camera_1 = require("./modules/camera");
|
18
18
|
const resource_tracker_1 = require("../../utils/resource-tracker");
|
19
19
|
const types_1 = require("../../types");
|
20
20
|
const axios_1 = __importDefault(require("axios"));
|
@@ -76,8 +76,6 @@ class AppSession {
|
|
76
76
|
this.shouldUpdateSubscriptionsOnSettingsChange = false;
|
77
77
|
/** Settings that should trigger subscription updates when changed */
|
78
78
|
this.subscriptionUpdateTriggers = [];
|
79
|
-
/** Pending photo requests waiting for responses */
|
80
|
-
this.pendingPhotoRequests = new Map();
|
81
79
|
/** Pending user discovery requests waiting for responses */
|
82
80
|
this.pendingUserDiscoveryRequests = new Map();
|
83
81
|
/** Pending direct message requests waiting for responses */
|
@@ -155,9 +153,9 @@ class AppSession {
|
|
155
153
|
// Import DashboardManager dynamically to avoid circular dependency
|
156
154
|
const { DashboardManager } = require('./dashboard');
|
157
155
|
this.dashboard = new DashboardManager(this, this.send.bind(this));
|
158
|
-
// Initialize
|
159
|
-
this.
|
160
|
-
);
|
156
|
+
// Initialize camera module with session reference
|
157
|
+
this.camera = new camera_1.CameraModule(this.config.packageName, this.sessionId || 'unknown-session-id', this.send.bind(this), this, // Pass session reference
|
158
|
+
this.logger.child({ module: 'camera' }));
|
161
159
|
}
|
162
160
|
/**
|
163
161
|
* Get the current session ID
|
@@ -304,9 +302,9 @@ class AppSession {
|
|
304
302
|
// Configure settings API client with the WebSocket URL and session ID
|
305
303
|
// This allows settings to be fetched from the correct server
|
306
304
|
this.settings.configureApiClient(this.config.packageName, this.config.mentraOSWebsocketUrl || '', sessionId);
|
307
|
-
// Update the sessionId in the
|
308
|
-
if (this.
|
309
|
-
|
305
|
+
// Update the sessionId in the camera module
|
306
|
+
if (this.camera) {
|
307
|
+
this.camera.updateSessionId(sessionId);
|
310
308
|
}
|
311
309
|
return new Promise((resolve, reject) => {
|
312
310
|
try {
|
@@ -521,6 +519,10 @@ class AppSession {
|
|
521
519
|
* 👋 Disconnect from MentraOS Cloud
|
522
520
|
*/
|
523
521
|
disconnect() {
|
522
|
+
// Clean up camera module first
|
523
|
+
if (this.camera) {
|
524
|
+
this.camera.cancelAllRequests();
|
525
|
+
}
|
524
526
|
// Use the resource tracker to clean up everything
|
525
527
|
this.resources.dispose();
|
526
528
|
// Clean up additional resources not handled by the tracker
|
@@ -529,43 +531,6 @@ class AppSession {
|
|
529
531
|
this.subscriptions.clear();
|
530
532
|
this.reconnectAttempts = 0;
|
531
533
|
}
|
532
|
-
/**
|
533
|
-
* 📸 Request a photo from the connected glasses
|
534
|
-
* @param options - Optional configuration for the photo request
|
535
|
-
* @returns Promise that resolves with the URL to the captured photo
|
536
|
-
*/
|
537
|
-
requestPhoto(options) {
|
538
|
-
return new Promise((resolve, reject) => {
|
539
|
-
try {
|
540
|
-
// Generate unique request ID
|
541
|
-
const requestId = `photo_req_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
542
|
-
// Store promise resolvers for when we get the response
|
543
|
-
this.pendingPhotoRequests.set(requestId, { resolve, reject });
|
544
|
-
// Create photo request message
|
545
|
-
const message = {
|
546
|
-
type: types_1.AppToCloudMessageType.PHOTO_REQUEST,
|
547
|
-
packageName: this.config.packageName,
|
548
|
-
sessionId: this.sessionId,
|
549
|
-
timestamp: new Date(),
|
550
|
-
saveToGallery: options?.saveToGallery || false
|
551
|
-
};
|
552
|
-
// Send request to cloud
|
553
|
-
this.send(message);
|
554
|
-
// Set timeout to avoid hanging promises
|
555
|
-
const timeoutMs = 30000; // 30 seconds
|
556
|
-
this.resources.setTimeout(() => {
|
557
|
-
if (this.pendingPhotoRequests.has(requestId)) {
|
558
|
-
this.pendingPhotoRequests.get(requestId).reject(new Error('Photo request timed out'));
|
559
|
-
this.pendingPhotoRequests.delete(requestId);
|
560
|
-
}
|
561
|
-
}, timeoutMs);
|
562
|
-
}
|
563
|
-
catch (error) {
|
564
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
565
|
-
reject(new Error(`Failed to request photo: ${errorMessage}`));
|
566
|
-
}
|
567
|
-
});
|
568
|
-
}
|
569
534
|
/**
|
570
535
|
* 🛠️ Get all current user settings
|
571
536
|
* @returns A copy of the current settings array
|
@@ -814,21 +779,13 @@ class AppSession {
|
|
814
779
|
this.events.emit(messageStreamType, sanitizedData);
|
815
780
|
}
|
816
781
|
}
|
817
|
-
else if ((0, cloud_to_app_1.isPhotoResponse)(message)) {
|
818
|
-
// Handle photo response by resolving the pending promise
|
819
|
-
if (this.pendingPhotoRequests.has(message.requestId)) {
|
820
|
-
const { resolve } = this.pendingPhotoRequests.get(message.requestId);
|
821
|
-
resolve(message.photoUrl);
|
822
|
-
this.pendingPhotoRequests.delete(message.requestId);
|
823
|
-
}
|
824
|
-
}
|
825
782
|
else if ((0, cloud_to_app_1.isRtmpStreamStatus)(message)) {
|
826
783
|
// Emit as a standard stream event if subscribed
|
827
784
|
if (this.subscriptions.has(types_1.StreamType.RTMP_STREAM_STATUS)) {
|
828
785
|
this.events.emit(types_1.StreamType.RTMP_STREAM_STATUS, message);
|
829
786
|
}
|
830
|
-
// Update
|
831
|
-
this.
|
787
|
+
// Update camera module's internal stream state
|
788
|
+
this.camera.updateStreamState(message);
|
832
789
|
}
|
833
790
|
else if ((0, types_1.isSettingsUpdate)(message)) {
|
834
791
|
// Store previous settings to check for changes
|
@@ -960,6 +917,11 @@ class AppSession {
|
|
960
917
|
});
|
961
918
|
});
|
962
919
|
}
|
920
|
+
else if ((0, cloud_to_app_1.isPhotoResponse)(message)) {
|
921
|
+
// Legacy photo response handling - now photos come directly via webhook
|
922
|
+
// This branch can be removed in the future as all photos now go through /photo-upload
|
923
|
+
this.logger.warn('Received legacy photo response - photos should now come via /photo-upload webhook');
|
924
|
+
}
|
963
925
|
// Handle unrecognized message types gracefully
|
964
926
|
else {
|
965
927
|
console.log(`Unrecognized message type: ${message.type}. Full message details:`, {
|
@@ -1465,3 +1427,29 @@ class AppSession {
|
|
1465
1427
|
}
|
1466
1428
|
}
|
1467
1429
|
exports.AppSession = AppSession;
|
1430
|
+
/**
|
1431
|
+
* @deprecated Use `AppSession` instead. `TpaSession` is deprecated and will be removed in a future version.
|
1432
|
+
* This is an alias for backward compatibility only.
|
1433
|
+
*
|
1434
|
+
* @example
|
1435
|
+
* ```typescript
|
1436
|
+
* // ❌ Deprecated - Don't use this
|
1437
|
+
* const session = new TpaSession(config);
|
1438
|
+
*
|
1439
|
+
* // ✅ Use this instead
|
1440
|
+
* const session = new AppSession(config);
|
1441
|
+
* ```
|
1442
|
+
*/
|
1443
|
+
class TpaSession extends AppSession {
|
1444
|
+
constructor(config) {
|
1445
|
+
super(config);
|
1446
|
+
// Emit a deprecation warning to help developers migrate
|
1447
|
+
console.warn('⚠️ DEPRECATION WARNING: TpaSession is deprecated and will be removed in a future version. ' +
|
1448
|
+
'Please use AppSession instead. ' +
|
1449
|
+
'Simply replace "TpaSession" with "AppSession" in your code.');
|
1450
|
+
}
|
1451
|
+
}
|
1452
|
+
exports.TpaSession = TpaSession;
|
1453
|
+
// Export camera module types for developers
|
1454
|
+
var camera_2 = require("./modules/camera");
|
1455
|
+
Object.defineProperty(exports, "CameraModule", { enumerable: true, get: function () { return camera_2.CameraModule; } });
|