@mentra/sdk 2.1.1 → 2.1.2
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/session/events.d.ts +2 -1
- package/dist/app/session/events.d.ts.map +1 -1
- package/dist/app/session/index.d.ts +14 -5
- package/dist/app/session/index.d.ts.map +1 -1
- package/dist/app/session/index.js +71 -21
- package/dist/app/session/modules/audio.d.ts +190 -0
- package/dist/app/session/modules/audio.d.ts.map +1 -0
- package/dist/app/session/modules/audio.js +317 -0
- package/dist/app/session/modules/camera-managed-extension.d.ts +152 -0
- package/dist/app/session/modules/camera-managed-extension.d.ts.map +1 -0
- package/dist/app/session/modules/camera-managed-extension.js +231 -0
- package/dist/app/session/modules/camera.d.ts +55 -1
- package/dist/app/session/modules/camera.d.ts.map +1 -1
- package/dist/app/session/modules/camera.js +72 -0
- package/dist/app/session/modules/index.d.ts +4 -0
- package/dist/app/session/modules/index.d.ts.map +1 -0
- package/dist/app/session/modules/index.js +19 -0
- package/dist/app/session/modules/location.d.ts +16 -0
- package/dist/app/session/modules/location.d.ts.map +1 -0
- package/dist/app/session/modules/location.js +55 -0
- package/dist/app/webview/index.d.ts.map +1 -1
- package/dist/app/webview/index.js +0 -1
- package/dist/examples/managed-rtmp-streaming-example.d.ts +2 -0
- package/dist/examples/managed-rtmp-streaming-example.d.ts.map +1 -0
- package/dist/examples/managed-rtmp-streaming-example.js +155 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/types/enums.d.ts +3 -1
- package/dist/types/enums.d.ts.map +1 -1
- package/dist/types/enums.js +2 -0
- package/dist/types/index.d.ts +5 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +7 -1
- package/dist/types/message-types.d.ts +14 -2
- package/dist/types/message-types.d.ts.map +1 -1
- package/dist/types/message-types.js +16 -0
- package/dist/types/messages/app-to-cloud.d.ts +65 -3
- package/dist/types/messages/app-to-cloud.d.ts.map +1 -1
- package/dist/types/messages/app-to-cloud.js +28 -0
- package/dist/types/messages/cloud-to-app.d.ts +26 -1
- package/dist/types/messages/cloud-to-app.d.ts.map +1 -1
- package/dist/types/messages/cloud-to-app.js +8 -0
- package/dist/types/messages/cloud-to-glasses.d.ts +38 -1
- package/dist/types/messages/cloud-to-glasses.d.ts.map +1 -1
- package/dist/types/messages/cloud-to-glasses.js +8 -0
- package/dist/types/messages/glasses-to-cloud.d.ts +14 -1
- package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
- package/dist/types/messages/glasses-to-cloud.js +4 -0
- package/dist/types/models.d.ts +13 -0
- package/dist/types/models.d.ts.map +1 -1
- package/dist/types/models.js +9 -0
- package/dist/types/streams.d.ts +6 -0
- package/dist/types/streams.d.ts.map +1 -1
- package/dist/types/streams.js +4 -0
- package/package.json +1 -1
@@ -0,0 +1,231 @@
|
|
1
|
+
"use strict";
|
2
|
+
/**
|
3
|
+
* 📷 Camera Module Managed Streaming Extension
|
4
|
+
*
|
5
|
+
* Extends the camera module with managed streaming capabilities.
|
6
|
+
* Apps can request managed streams and receive HLS/DASH URLs without managing RTMP endpoints.
|
7
|
+
*/
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
9
|
+
exports.CameraManagedExtension = void 0;
|
10
|
+
const types_1 = require("../../../types");
|
11
|
+
/**
|
12
|
+
* 📹 Managed Streaming Extension for Camera Module
|
13
|
+
*
|
14
|
+
* Provides managed streaming capabilities where the cloud handles
|
15
|
+
* RTMP endpoints and returns HLS/DASH URLs for viewing.
|
16
|
+
*
|
17
|
+
* @example
|
18
|
+
* ```typescript
|
19
|
+
* // Start a managed stream
|
20
|
+
* const urls = await session.camera.startManagedStream({
|
21
|
+
* quality: '720p',
|
22
|
+
* enableWebRTC: true
|
23
|
+
* });
|
24
|
+
* console.log('HLS URL:', urls.hlsUrl);
|
25
|
+
* console.log('DASH URL:', urls.dashUrl);
|
26
|
+
*
|
27
|
+
* // Monitor managed stream status
|
28
|
+
* session.camera.onManagedStreamStatus((status) => {
|
29
|
+
* console.log('Managed stream status:', status.status);
|
30
|
+
* });
|
31
|
+
*
|
32
|
+
* // Stop managed stream
|
33
|
+
* await session.camera.stopManagedStream();
|
34
|
+
* ```
|
35
|
+
*/
|
36
|
+
class CameraManagedExtension {
|
37
|
+
constructor(packageName, sessionId, send, logger, session) {
|
38
|
+
// Managed streaming state
|
39
|
+
this.isManagedStreaming = false;
|
40
|
+
this.packageName = packageName;
|
41
|
+
this.sessionId = sessionId;
|
42
|
+
this.send = send;
|
43
|
+
this.logger = logger.child({ module: 'CameraManagedExtension' });
|
44
|
+
this.session = session;
|
45
|
+
}
|
46
|
+
/**
|
47
|
+
* 📹 Start a managed stream
|
48
|
+
*
|
49
|
+
* The cloud will handle the RTMP endpoint and return HLS/DASH URLs for viewing.
|
50
|
+
* Multiple apps can consume the same managed stream simultaneously.
|
51
|
+
*
|
52
|
+
* @param options - Configuration options for the managed stream
|
53
|
+
* @returns Promise that resolves with viewing URLs when the stream is ready
|
54
|
+
*
|
55
|
+
* @example
|
56
|
+
* ```typescript
|
57
|
+
* const urls = await session.camera.startManagedStream({
|
58
|
+
* quality: '1080p',
|
59
|
+
* enableWebRTC: true,
|
60
|
+
* video: { fps: 30 },
|
61
|
+
* audio: { sampleRate: 48000 }
|
62
|
+
* });
|
63
|
+
* ```
|
64
|
+
*/
|
65
|
+
async startManagedStream(options = {}) {
|
66
|
+
this.logger.info({ options }, '📹 Managed stream request starting');
|
67
|
+
if (this.isManagedStreaming) {
|
68
|
+
this.logger.error({
|
69
|
+
currentStreamId: this.currentManagedStreamId
|
70
|
+
}, '📹 Already managed streaming error');
|
71
|
+
throw new Error('Already streaming. Stop the current managed stream before starting a new one.');
|
72
|
+
}
|
73
|
+
// Create the request message
|
74
|
+
const request = {
|
75
|
+
type: types_1.AppToCloudMessageType.MANAGED_STREAM_REQUEST,
|
76
|
+
packageName: this.packageName,
|
77
|
+
quality: options.quality,
|
78
|
+
enableWebRTC: options.enableWebRTC,
|
79
|
+
video: options.video,
|
80
|
+
audio: options.audio,
|
81
|
+
stream: options.stream
|
82
|
+
};
|
83
|
+
// Send the request
|
84
|
+
this.send(request);
|
85
|
+
this.isManagedStreaming = true;
|
86
|
+
// Create promise to wait for URLs
|
87
|
+
return new Promise((resolve, reject) => {
|
88
|
+
this.pendingManagedStreamRequest = { resolve, reject };
|
89
|
+
// Set a timeout
|
90
|
+
setTimeout(() => {
|
91
|
+
if (this.pendingManagedStreamRequest) {
|
92
|
+
this.pendingManagedStreamRequest = undefined;
|
93
|
+
this.isManagedStreaming = false;
|
94
|
+
reject(new Error('Managed stream request timeout'));
|
95
|
+
}
|
96
|
+
}, 30000); // 30 second timeout
|
97
|
+
});
|
98
|
+
}
|
99
|
+
/**
|
100
|
+
* 🛑 Stop the current managed stream
|
101
|
+
*
|
102
|
+
* This will stop streaming for this app only. If other apps are consuming
|
103
|
+
* the same managed stream, it will continue for them.
|
104
|
+
*
|
105
|
+
* @returns Promise that resolves when the stop request is sent
|
106
|
+
*/
|
107
|
+
async stopManagedStream() {
|
108
|
+
if (!this.isManagedStreaming) {
|
109
|
+
this.logger.warn('📹 No managed stream to stop');
|
110
|
+
return;
|
111
|
+
}
|
112
|
+
this.logger.info({ streamId: this.currentManagedStreamId }, '📹 Stopping managed stream');
|
113
|
+
const request = {
|
114
|
+
type: types_1.AppToCloudMessageType.MANAGED_STREAM_STOP,
|
115
|
+
packageName: this.packageName
|
116
|
+
};
|
117
|
+
this.send(request);
|
118
|
+
// Clean up state
|
119
|
+
this.isManagedStreaming = false;
|
120
|
+
this.currentManagedStreamId = undefined;
|
121
|
+
this.currentManagedStreamUrls = undefined;
|
122
|
+
this.managedStreamStatus = undefined;
|
123
|
+
this.pendingManagedStreamRequest = undefined;
|
124
|
+
}
|
125
|
+
/**
|
126
|
+
* 📊 Check if currently managed streaming
|
127
|
+
*
|
128
|
+
* @returns true if a managed stream is active
|
129
|
+
*/
|
130
|
+
isManagedStreamActive() {
|
131
|
+
return this.isManagedStreaming;
|
132
|
+
}
|
133
|
+
/**
|
134
|
+
* 🔗 Get current managed stream URLs
|
135
|
+
*
|
136
|
+
* @returns Current stream URLs or undefined if not streaming
|
137
|
+
*/
|
138
|
+
getManagedStreamUrls() {
|
139
|
+
return this.currentManagedStreamUrls;
|
140
|
+
}
|
141
|
+
/**
|
142
|
+
* 📊 Get current managed stream status
|
143
|
+
*
|
144
|
+
* @returns Current stream status or undefined
|
145
|
+
*/
|
146
|
+
getManagedStreamStatus() {
|
147
|
+
return this.managedStreamStatus;
|
148
|
+
}
|
149
|
+
/**
|
150
|
+
* 🔔 Register a handler for managed stream status updates
|
151
|
+
*
|
152
|
+
* @param handler - Function to call when stream status changes
|
153
|
+
* @returns Cleanup function to unregister the handler
|
154
|
+
*
|
155
|
+
* @example
|
156
|
+
* ```typescript
|
157
|
+
* const cleanup = session.camera.onManagedStreamStatus((status) => {
|
158
|
+
* console.log('Status:', status.status);
|
159
|
+
* if (status.status === 'active') {
|
160
|
+
* console.log('Stream is live!');
|
161
|
+
* }
|
162
|
+
* });
|
163
|
+
*
|
164
|
+
* // Later, unregister the handler
|
165
|
+
* cleanup();
|
166
|
+
* ```
|
167
|
+
*/
|
168
|
+
onManagedStreamStatus(handler) {
|
169
|
+
if (!this.session) {
|
170
|
+
this.logger.error('Cannot listen for managed status updates: session reference not available');
|
171
|
+
return () => { };
|
172
|
+
}
|
173
|
+
this.session.subscribe(types_1.StreamType.MANAGED_STREAM_STATUS);
|
174
|
+
// Register the handler using the session's event system
|
175
|
+
return this.session.on(types_1.StreamType.MANAGED_STREAM_STATUS, handler);
|
176
|
+
}
|
177
|
+
/**
|
178
|
+
* Handle incoming managed stream status messages
|
179
|
+
* Called by the parent AppSession when messages are received
|
180
|
+
*/
|
181
|
+
handleManagedStreamStatus(status) {
|
182
|
+
this.logger.info({
|
183
|
+
status: status.status,
|
184
|
+
streamId: status.streamId
|
185
|
+
}, '📹 Received managed stream status');
|
186
|
+
this.managedStreamStatus = status;
|
187
|
+
// Handle initial stream ready status
|
188
|
+
if (status.status === 'active' && this.pendingManagedStreamRequest && status.hlsUrl && status.dashUrl) {
|
189
|
+
const result = {
|
190
|
+
hlsUrl: status.hlsUrl,
|
191
|
+
dashUrl: status.dashUrl,
|
192
|
+
webrtcUrl: status.webrtcUrl,
|
193
|
+
streamId: status.streamId || ''
|
194
|
+
};
|
195
|
+
this.currentManagedStreamId = status.streamId;
|
196
|
+
this.currentManagedStreamUrls = result;
|
197
|
+
// Resolve the pending promise
|
198
|
+
this.pendingManagedStreamRequest.resolve(result);
|
199
|
+
this.pendingManagedStreamRequest = undefined;
|
200
|
+
}
|
201
|
+
// Handle error status
|
202
|
+
if ((status.status === 'error' || status.status === 'stopped') && this.pendingManagedStreamRequest) {
|
203
|
+
this.pendingManagedStreamRequest.reject(new Error(status.message || 'Managed stream failed'));
|
204
|
+
this.pendingManagedStreamRequest = undefined;
|
205
|
+
this.isManagedStreaming = false;
|
206
|
+
}
|
207
|
+
// Clean up on stopped status
|
208
|
+
if (status.status === 'stopped') {
|
209
|
+
this.isManagedStreaming = false;
|
210
|
+
this.currentManagedStreamId = undefined;
|
211
|
+
this.currentManagedStreamUrls = undefined;
|
212
|
+
}
|
213
|
+
// Notify handlers (would use event emitter in real implementation)
|
214
|
+
// this.emit('managedStreamStatus', status);
|
215
|
+
}
|
216
|
+
/**
|
217
|
+
* 🧹 Clean up all managed streaming state
|
218
|
+
*/
|
219
|
+
cleanup() {
|
220
|
+
if (this.pendingManagedStreamRequest) {
|
221
|
+
this.pendingManagedStreamRequest.reject(new Error('Camera module cleanup'));
|
222
|
+
this.pendingManagedStreamRequest = undefined;
|
223
|
+
}
|
224
|
+
this.isManagedStreaming = false;
|
225
|
+
this.currentManagedStreamId = undefined;
|
226
|
+
this.currentManagedStreamUrls = undefined;
|
227
|
+
this.managedStreamStatus = undefined;
|
228
|
+
this.logger.info('📹 Managed streaming extension cleaned up');
|
229
|
+
}
|
230
|
+
}
|
231
|
+
exports.CameraManagedExtension = CameraManagedExtension;
|
@@ -4,9 +4,10 @@
|
|
4
4
|
* Unified camera functionality for App Sessions.
|
5
5
|
* Handles both photo requests and RTMP streaming from connected glasses.
|
6
6
|
*/
|
7
|
-
import { PhotoData, RtmpStreamStatus } from '../../../types';
|
7
|
+
import { PhotoData, RtmpStreamStatus, ManagedStreamStatus } from '../../../types';
|
8
8
|
import { VideoConfig, AudioConfig, StreamConfig, StreamStatusHandler } from '../../../types/rtmp-stream';
|
9
9
|
import { Logger } from 'pino';
|
10
|
+
import { ManagedStreamOptions, ManagedStreamResult } from './camera-managed-extension';
|
10
11
|
/**
|
11
12
|
* Options for photo requests
|
12
13
|
*/
|
@@ -65,6 +66,7 @@ export declare class CameraModule {
|
|
65
66
|
private isStreaming;
|
66
67
|
private currentStreamUrl?;
|
67
68
|
private currentStreamState?;
|
69
|
+
private managedExtension;
|
68
70
|
/**
|
69
71
|
* Create a new CameraModule
|
70
72
|
*
|
@@ -210,6 +212,58 @@ export declare class CameraModule {
|
|
210
212
|
* @internal This method is used internally by AppSession
|
211
213
|
*/
|
212
214
|
updateStreamState(message: any): void;
|
215
|
+
/**
|
216
|
+
* 📹 Start a managed stream
|
217
|
+
*
|
218
|
+
* The cloud handles the RTMP endpoint and returns HLS/DASH URLs for viewing.
|
219
|
+
* Multiple apps can consume the same managed stream simultaneously.
|
220
|
+
*
|
221
|
+
* @param options - Configuration options for the managed stream
|
222
|
+
* @returns Promise that resolves with viewing URLs when the stream is ready
|
223
|
+
*
|
224
|
+
* @example
|
225
|
+
* ```typescript
|
226
|
+
* const urls = await session.camera.startManagedStream({
|
227
|
+
* quality: '720p',
|
228
|
+
* enableWebRTC: true
|
229
|
+
* });
|
230
|
+
* console.log('HLS URL:', urls.hlsUrl);
|
231
|
+
* ```
|
232
|
+
*/
|
233
|
+
startManagedStream(options?: ManagedStreamOptions): Promise<ManagedStreamResult>;
|
234
|
+
/**
|
235
|
+
* 🛑 Stop the current managed stream
|
236
|
+
*
|
237
|
+
* This will stop streaming for this app only. If other apps are consuming
|
238
|
+
* the same managed stream, it will continue for them.
|
239
|
+
*
|
240
|
+
* @returns Promise that resolves when the stop request is sent
|
241
|
+
*/
|
242
|
+
stopManagedStream(): Promise<void>;
|
243
|
+
/**
|
244
|
+
* 🔔 Register a handler for managed stream status updates
|
245
|
+
*
|
246
|
+
* @param handler - Function to call when stream status changes
|
247
|
+
* @returns Cleanup function to unregister the handler
|
248
|
+
*/
|
249
|
+
onManagedStreamStatus(handler: (status: ManagedStreamStatus) => void): () => void;
|
250
|
+
/**
|
251
|
+
* 📊 Check if currently managed streaming
|
252
|
+
*
|
253
|
+
* @returns true if a managed stream is active
|
254
|
+
*/
|
255
|
+
isManagedStreamActive(): boolean;
|
256
|
+
/**
|
257
|
+
* 🔗 Get current managed stream URLs
|
258
|
+
*
|
259
|
+
* @returns Current stream URLs or undefined if not streaming
|
260
|
+
*/
|
261
|
+
getManagedStreamUrls(): ManagedStreamResult | undefined;
|
262
|
+
/**
|
263
|
+
* Handle incoming managed stream status messages
|
264
|
+
* @internal
|
265
|
+
*/
|
266
|
+
handleManagedStreamStatus(message: ManagedStreamStatus): void;
|
213
267
|
/**
|
214
268
|
* 🔧 Update the session ID (used when reconnecting)
|
215
269
|
*
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAEL,SAAS,EAIT,gBAAgB,
|
1
|
+
{"version":3,"file":"camera.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/camera.ts"],"names":[],"mappings":"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"}
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.CameraModule = void 0;
|
10
10
|
const types_1 = require("../../../types");
|
11
11
|
const streams_1 = require("../../../types/streams");
|
12
|
+
const camera_managed_extension_1 = require("./camera-managed-extension");
|
12
13
|
/**
|
13
14
|
* 📷 Camera Module Implementation
|
14
15
|
*
|
@@ -57,6 +58,8 @@ class CameraModule {
|
|
57
58
|
this.send = send;
|
58
59
|
this.session = session;
|
59
60
|
this.logger = logger || console;
|
61
|
+
// Initialize managed extension
|
62
|
+
this.managedExtension = new camera_managed_extension_1.CameraManagedExtension(packageName, sessionId, send, this.logger, session);
|
60
63
|
}
|
61
64
|
// =====================================
|
62
65
|
// 📸 Photo Functionality
|
@@ -409,6 +412,73 @@ class CameraModule {
|
|
409
412
|
this.currentStreamState = status;
|
410
413
|
}
|
411
414
|
// =====================================
|
415
|
+
// 📹 Managed Streaming Functionality
|
416
|
+
// =====================================
|
417
|
+
/**
|
418
|
+
* 📹 Start a managed stream
|
419
|
+
*
|
420
|
+
* The cloud handles the RTMP endpoint and returns HLS/DASH URLs for viewing.
|
421
|
+
* Multiple apps can consume the same managed stream simultaneously.
|
422
|
+
*
|
423
|
+
* @param options - Configuration options for the managed stream
|
424
|
+
* @returns Promise that resolves with viewing URLs when the stream is ready
|
425
|
+
*
|
426
|
+
* @example
|
427
|
+
* ```typescript
|
428
|
+
* const urls = await session.camera.startManagedStream({
|
429
|
+
* quality: '720p',
|
430
|
+
* enableWebRTC: true
|
431
|
+
* });
|
432
|
+
* console.log('HLS URL:', urls.hlsUrl);
|
433
|
+
* ```
|
434
|
+
*/
|
435
|
+
async startManagedStream(options) {
|
436
|
+
return this.managedExtension.startManagedStream(options);
|
437
|
+
}
|
438
|
+
/**
|
439
|
+
* 🛑 Stop the current managed stream
|
440
|
+
*
|
441
|
+
* This will stop streaming for this app only. If other apps are consuming
|
442
|
+
* the same managed stream, it will continue for them.
|
443
|
+
*
|
444
|
+
* @returns Promise that resolves when the stop request is sent
|
445
|
+
*/
|
446
|
+
async stopManagedStream() {
|
447
|
+
return this.managedExtension.stopManagedStream();
|
448
|
+
}
|
449
|
+
/**
|
450
|
+
* 🔔 Register a handler for managed stream status updates
|
451
|
+
*
|
452
|
+
* @param handler - Function to call when stream status changes
|
453
|
+
* @returns Cleanup function to unregister the handler
|
454
|
+
*/
|
455
|
+
onManagedStreamStatus(handler) {
|
456
|
+
return this.managedExtension.onManagedStreamStatus(handler);
|
457
|
+
}
|
458
|
+
/**
|
459
|
+
* 📊 Check if currently managed streaming
|
460
|
+
*
|
461
|
+
* @returns true if a managed stream is active
|
462
|
+
*/
|
463
|
+
isManagedStreamActive() {
|
464
|
+
return this.managedExtension.isManagedStreamActive();
|
465
|
+
}
|
466
|
+
/**
|
467
|
+
* 🔗 Get current managed stream URLs
|
468
|
+
*
|
469
|
+
* @returns Current stream URLs or undefined if not streaming
|
470
|
+
*/
|
471
|
+
getManagedStreamUrls() {
|
472
|
+
return this.managedExtension.getManagedStreamUrls();
|
473
|
+
}
|
474
|
+
/**
|
475
|
+
* Handle incoming managed stream status messages
|
476
|
+
* @internal
|
477
|
+
*/
|
478
|
+
handleManagedStreamStatus(message) {
|
479
|
+
this.managedExtension.handleManagedStreamStatus(message);
|
480
|
+
}
|
481
|
+
// =====================================
|
412
482
|
// 🔧 General Utilities
|
413
483
|
// =====================================
|
414
484
|
/**
|
@@ -433,6 +503,8 @@ class CameraModule {
|
|
433
503
|
this.logger.error({ error }, 'Error stopping stream during cleanup');
|
434
504
|
});
|
435
505
|
}
|
506
|
+
// Clean up managed extension
|
507
|
+
this.managedExtension.cleanup();
|
436
508
|
return { photoRequests };
|
437
509
|
}
|
438
510
|
}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,4BAA4B,CAAC"}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
15
|
+
};
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
17
|
+
__exportStar(require("./audio"), exports);
|
18
|
+
__exportStar(require("./camera"), exports);
|
19
|
+
__exportStar(require("./camera-managed-extension"), exports);
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { AppSession } from '..';
|
2
|
+
import { LocationUpdate } from '../../../types';
|
3
|
+
export declare class LocationManager {
|
4
|
+
private session;
|
5
|
+
private send;
|
6
|
+
private lastLocationCleanupHandler;
|
7
|
+
constructor(session: AppSession, send: (message: any) => void);
|
8
|
+
subscribeToStream(options: {
|
9
|
+
accuracy: 'standard' | 'high' | 'realtime' | 'tenMeters' | 'hundredMeters' | 'kilometer' | 'threeKilometers' | 'reduced';
|
10
|
+
}, handler: (data: LocationUpdate) => void): () => void;
|
11
|
+
unsubscribeFromStream(): void;
|
12
|
+
getLatestLocation(options: {
|
13
|
+
accuracy: string;
|
14
|
+
}): Promise<LocationUpdate>;
|
15
|
+
}
|
16
|
+
//# sourceMappingURL=location.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"location.d.ts","sourceRoot":"","sources":["../../../../src/app/session/modules/location.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAqC,cAAc,EAAyB,MAAM,gBAAgB,CAAC;AAE1G,qBAAa,eAAe;IAGd,OAAO,CAAC,OAAO;IAAc,OAAO,CAAC,IAAI;IAFrD,OAAO,CAAC,0BAA0B,CAAwB;gBAEtC,OAAO,EAAE,UAAU,EAAU,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI;IAGtE,iBAAiB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,eAAe,GAAG,WAAW,GAAG,iBAAiB,GAAG,SAAS,CAAA;KAAE,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAQ7M,qBAAqB,IAAI,IAAI;IAUvB,iBAAiB,CAAC,OAAO,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;CA4BvF"}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.LocationManager = void 0;
|
4
|
+
const types_1 = require("../../../types");
|
5
|
+
class LocationManager {
|
6
|
+
constructor(session, send) {
|
7
|
+
this.session = session;
|
8
|
+
this.send = send;
|
9
|
+
this.lastLocationCleanupHandler = () => { };
|
10
|
+
}
|
11
|
+
// subscribes to the continuous location stream with a specified accuracy tier
|
12
|
+
subscribeToStream(options, handler) {
|
13
|
+
const subscription = { stream: 'location_stream', rate: options.accuracy };
|
14
|
+
this.session.subscribe(subscription);
|
15
|
+
this.lastLocationCleanupHandler = this.session.events.onLocation(handler);
|
16
|
+
return this.lastLocationCleanupHandler;
|
17
|
+
}
|
18
|
+
// unsubscribes from the continuous location stream
|
19
|
+
unsubscribeFromStream() {
|
20
|
+
if (this.lastLocationCleanupHandler) {
|
21
|
+
this.lastLocationCleanupHandler();
|
22
|
+
this.lastLocationCleanupHandler = () => { };
|
23
|
+
}
|
24
|
+
else {
|
25
|
+
this.session.unsubscribe('location_stream');
|
26
|
+
}
|
27
|
+
}
|
28
|
+
// performs a one-time, intelligent poll for a location fix
|
29
|
+
async getLatestLocation(options) {
|
30
|
+
return new Promise((resolve, reject) => {
|
31
|
+
const requestId = `poll_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
32
|
+
// listens for a location update with a matching correlationId
|
33
|
+
const unsubscribe = this.session.events.on('location_update', (data) => {
|
34
|
+
if (data.correlationId === requestId) {
|
35
|
+
unsubscribe(); // clean up the listener
|
36
|
+
resolve(data);
|
37
|
+
}
|
38
|
+
});
|
39
|
+
// sends the poll request message to the cloud
|
40
|
+
this.send({
|
41
|
+
type: types_1.AppToCloudMessageType.LOCATION_POLL_REQUEST,
|
42
|
+
correlationId: requestId,
|
43
|
+
packageName: this.session.getPackageName(),
|
44
|
+
sessionId: this.session.getSessionId(),
|
45
|
+
accuracy: options.accuracy
|
46
|
+
});
|
47
|
+
// sets a timeout to prevent the promise from hanging indefinitely
|
48
|
+
setTimeout(() => {
|
49
|
+
unsubscribe();
|
50
|
+
reject(new Error('Location poll request timed out'));
|
51
|
+
}, 15000); // 15 second timeout
|
52
|
+
});
|
53
|
+
}
|
54
|
+
}
|
55
|
+
exports.LocationManager = LocationManager;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/app/webview/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAUnD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ3D;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAmC7B;AAsID;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,IAuBe,KAAK,oBAAoB,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/app/webview/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAUnD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ3D;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAmC7B;AAsID;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE;QACd,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;QAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,IAuBe,KAAK,oBAAoB,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,mBAiG3E"}
|
@@ -324,7 +324,6 @@ function createAuthMiddleware(options) {
|
|
324
324
|
try {
|
325
325
|
// Verify the signed session cookie and extract the user ID
|
326
326
|
const userId = verifySession(sessionCookie, cookieSecret, cookieOptions.maxAge);
|
327
|
-
console.log(`User ID verified from session cookie: ${userId}`);
|
328
327
|
if (userId) {
|
329
328
|
req.authUserId = userId;
|
330
329
|
return next();
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"managed-rtmp-streaming-example.d.ts","sourceRoot":"","sources":["../../src/examples/managed-rtmp-streaming-example.ts"],"names":[],"mappings":""}
|