@mentra/sdk 2.1.2 → 2.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/app/session/events.d.ts +3 -2
  2. package/dist/app/session/events.d.ts.map +1 -1
  3. package/dist/app/session/events.js +3 -0
  4. package/dist/app/session/index.d.ts +8 -1
  5. package/dist/app/session/index.d.ts.map +1 -1
  6. package/dist/app/session/index.js +9 -0
  7. package/dist/app/session/layouts.d.ts +63 -3
  8. package/dist/app/session/layouts.d.ts.map +1 -1
  9. package/dist/app/session/layouts.js +101 -7
  10. package/dist/app/session/modules/camera-managed-extension.d.ts +3 -1
  11. package/dist/app/session/modules/camera-managed-extension.d.ts.map +1 -1
  12. package/dist/app/session/modules/camera-managed-extension.js +26 -18
  13. package/dist/examples/managed-rtmp-streaming-example.js +3 -0
  14. package/dist/examples/managed-rtmp-streaming-with-restream-example.d.ts +11 -0
  15. package/dist/examples/managed-rtmp-streaming-with-restream-example.d.ts.map +1 -0
  16. package/dist/examples/managed-rtmp-streaming-with-restream-example.js +124 -0
  17. package/dist/index.d.ts +6 -4
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +5 -1
  20. package/dist/types/enums.d.ts +3 -1
  21. package/dist/types/enums.d.ts.map +1 -1
  22. package/dist/types/enums.js +2 -0
  23. package/dist/types/index.d.ts +2 -2
  24. package/dist/types/index.d.ts.map +1 -1
  25. package/dist/types/layouts.d.ts +16 -1
  26. package/dist/types/layouts.d.ts.map +1 -1
  27. package/dist/types/message-types.d.ts +2 -2
  28. package/dist/types/message-types.d.ts.map +1 -1
  29. package/dist/types/message-types.js +3 -3
  30. package/dist/types/messages/app-to-cloud.d.ts +11 -0
  31. package/dist/types/messages/app-to-cloud.d.ts.map +1 -1
  32. package/dist/types/messages/cloud-to-app.d.ts +19 -0
  33. package/dist/types/messages/cloud-to-app.d.ts.map +1 -1
  34. package/dist/types/messages/glasses-to-cloud.d.ts +8 -4
  35. package/dist/types/messages/glasses-to-cloud.d.ts.map +1 -1
  36. package/dist/types/messages/glasses-to-cloud.js +3 -3
  37. package/dist/types/models.d.ts +1 -0
  38. package/dist/types/models.d.ts.map +1 -1
  39. package/dist/types/models.js +1 -0
  40. package/dist/types/streams.d.ts +1 -1
  41. package/dist/types/streams.d.ts.map +1 -1
  42. package/dist/types/streams.js +2 -2
  43. package/dist/utils/animation-utils.d.ts +206 -0
  44. package/dist/utils/animation-utils.d.ts.map +1 -0
  45. package/dist/utils/animation-utils.js +339 -0
  46. package/dist/utils/bitmap-utils.d.ts +147 -0
  47. package/dist/utils/bitmap-utils.d.ts.map +1 -0
  48. package/dist/utils/bitmap-utils.js +338 -0
  49. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitmap-utils.d.ts","sourceRoot":"","sources":["../../src/utils/bitmap-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE;QACT,iDAAiD;QACjD,UAAU,CAAC,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;QAC/C,8BAA8B;QAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,8DAA8D;IAC9D,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,WAAW;IAEtB;;;;;;;;;;;;OAYG;WACU,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAqB5D;;;;;;;;;;;;;;;;;;;OAmBG;WACU,aAAa,CACxB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,MAAM,EAAE,CAAC;IA0DpB;;;;;;;;;;;;;;;OAeG;IACH,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB;IAkF1D;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,aAAa,CAClB,IAAI,EAAE,MAAM,GAAG,MAAM,EACrB,UAAU,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,EACvC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GACpC,MAAM,GAAG,MAAM;IA+BlB;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG;QACvC,SAAS,EAAE,MAAM,CAAC;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,OAAO,CAAC;KACrB;CAmCF"}
@@ -0,0 +1,338 @@
1
+ "use strict";
2
+ /**
3
+ * 🎨 Bitmap Utilities Module
4
+ *
5
+ * Provides helper functions for working with bitmap images in MentraOS applications.
6
+ * Includes file loading, data validation, and format conversion utilities.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { BitmapUtils } from '@mentra/sdk';
11
+ *
12
+ * // Load a single BMP file
13
+ * const bmpHex = await BitmapUtils.loadBmpAsHex('./my-image.bmp');
14
+ * session.layouts.showBitmapView(bmpHex);
15
+ *
16
+ * // Load multiple animation frames
17
+ * const frames = await BitmapUtils.loadBmpFrames('./animations', 10);
18
+ * session.layouts.showBitmapAnimation(frames, 1500, true);
19
+ * ```
20
+ */
21
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
22
+ if (k2 === undefined) k2 = k;
23
+ var desc = Object.getOwnPropertyDescriptor(m, k);
24
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
25
+ desc = { enumerable: true, get: function() { return m[k]; } };
26
+ }
27
+ Object.defineProperty(o, k2, desc);
28
+ }) : (function(o, m, k, k2) {
29
+ if (k2 === undefined) k2 = k;
30
+ o[k2] = m[k];
31
+ }));
32
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
33
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
34
+ }) : function(o, v) {
35
+ o["default"] = v;
36
+ });
37
+ var __importStar = (this && this.__importStar) || (function () {
38
+ var ownKeys = function(o) {
39
+ ownKeys = Object.getOwnPropertyNames || function (o) {
40
+ var ar = [];
41
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
42
+ return ar;
43
+ };
44
+ return ownKeys(o);
45
+ };
46
+ return function (mod) {
47
+ if (mod && mod.__esModule) return mod;
48
+ var result = {};
49
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
50
+ __setModuleDefault(result, mod);
51
+ return result;
52
+ };
53
+ })();
54
+ Object.defineProperty(exports, "__esModule", { value: true });
55
+ exports.BitmapUtils = void 0;
56
+ const fs = __importStar(require("fs/promises"));
57
+ const path = __importStar(require("path"));
58
+ /**
59
+ * Utility class for working with bitmap images in MentraOS applications
60
+ */
61
+ class BitmapUtils {
62
+ /**
63
+ * Load a BMP file as hex string from filesystem
64
+ *
65
+ * @param filePath - Path to the BMP file
66
+ * @returns Promise resolving to hex-encoded bitmap data
67
+ * @throws Error if file cannot be read or is not a valid BMP
68
+ *
69
+ * @example
70
+ * ```typescript
71
+ * const bmpHex = await BitmapUtils.loadBmpAsHex('./assets/icon.bmp');
72
+ * session.layouts.showBitmapView(bmpHex);
73
+ * ```
74
+ */
75
+ static async loadBmpAsHex(filePath) {
76
+ try {
77
+ const bmpData = await fs.readFile(filePath);
78
+ // Basic BMP validation - check for BMP signature
79
+ if (bmpData.length < 14 || bmpData[0] !== 0x42 || bmpData[1] !== 0x4D) {
80
+ throw new Error(`File ${filePath} is not a valid BMP file (missing BM signature)`);
81
+ }
82
+ const hexString = bmpData.toString('hex');
83
+ console.log(`📁 Loaded BMP: ${path.basename(filePath)} (${bmpData.length} bytes)`);
84
+ return hexString;
85
+ }
86
+ catch (error) {
87
+ if (error instanceof Error) {
88
+ throw new Error(`Failed to load BMP file ${filePath}: ${error.message}`);
89
+ }
90
+ throw new Error(`Failed to load BMP file ${filePath}: Unknown error`);
91
+ }
92
+ }
93
+ /**
94
+ * Load multiple BMP frames as hex array for animations
95
+ *
96
+ * @param basePath - Directory containing the frame files
97
+ * @param frameCount - Number of frames to load
98
+ * @param options - Loading options and configuration
99
+ * @returns Promise resolving to array of hex-encoded bitmap data
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * // Load 10 frames with default pattern
104
+ * const frames = await BitmapUtils.loadBmpFrames('./animations', 10);
105
+ *
106
+ * // Load with custom pattern
107
+ * const customFrames = await BitmapUtils.loadBmpFrames('./sprites', 8, {
108
+ * filePattern: 'sprite_{i}.bmp',
109
+ * startFrame: 0
110
+ * });
111
+ * ```
112
+ */
113
+ static async loadBmpFrames(basePath, frameCount, options = {}) {
114
+ const { filePattern = 'animation_10_frame_{i}.bmp', startFrame = 1, validateFrames = true, skipMissingFrames = false } = options;
115
+ const frames = [];
116
+ const errors = [];
117
+ for (let i = 0; i < frameCount; i++) {
118
+ const frameNumber = startFrame + i;
119
+ const fileName = filePattern.replace('{i}', frameNumber.toString());
120
+ const filePath = path.join(basePath, fileName);
121
+ try {
122
+ const frameHex = await this.loadBmpAsHex(filePath);
123
+ if (validateFrames) {
124
+ const validation = this.validateBmpHex(frameHex);
125
+ if (!validation.isValid) {
126
+ const errorMsg = `Frame ${frameNumber} validation failed: ${validation.errors.join(', ')}`;
127
+ if (skipMissingFrames) {
128
+ console.warn(`⚠️ ${errorMsg} - skipping`);
129
+ continue;
130
+ }
131
+ else {
132
+ throw new Error(errorMsg);
133
+ }
134
+ }
135
+ console.log(`✅ Frame ${frameNumber} validated (${validation.blackPixels} black pixels)`);
136
+ }
137
+ frames.push(frameHex);
138
+ }
139
+ catch (error) {
140
+ const errorMsg = `Failed to load frame ${frameNumber} (${fileName}): ${error instanceof Error ? error.message : 'Unknown error'}`;
141
+ if (skipMissingFrames) {
142
+ console.warn(`⚠️ ${errorMsg} - skipping`);
143
+ continue;
144
+ }
145
+ else {
146
+ errors.push(errorMsg);
147
+ }
148
+ }
149
+ }
150
+ if (errors.length > 0) {
151
+ throw new Error(`Failed to load frames:\n${errors.join('\n')}`);
152
+ }
153
+ if (frames.length === 0) {
154
+ throw new Error(`No valid frames loaded from ${basePath}`);
155
+ }
156
+ console.log(`📚 Loaded ${frames.length} animation frames from ${basePath}`);
157
+ return frames;
158
+ }
159
+ /**
160
+ * Validate BMP hex data integrity and extract metadata
161
+ *
162
+ * @param hexString - Hex-encoded bitmap data
163
+ * @returns Validation result with detailed information
164
+ *
165
+ * @example
166
+ * ```typescript
167
+ * const validation = BitmapUtils.validateBmpHex(bmpHex);
168
+ * if (!validation.isValid) {
169
+ * console.error('Invalid bitmap:', validation.errors);
170
+ * } else {
171
+ * console.log(`Valid bitmap: ${validation.blackPixels} black pixels`);
172
+ * }
173
+ * ```
174
+ */
175
+ static validateBmpHex(hexString) {
176
+ const errors = [];
177
+ let byteCount = 0;
178
+ let blackPixels = 0;
179
+ let metadata = {};
180
+ try {
181
+ // Basic hex validation
182
+ if (typeof hexString !== 'string' || hexString.length === 0) {
183
+ errors.push('Hex string is empty or invalid');
184
+ return { isValid: false, byteCount: 0, blackPixels: 0, errors };
185
+ }
186
+ if (hexString.length % 2 !== 0) {
187
+ errors.push('Hex string length must be even');
188
+ return { isValid: false, byteCount: 0, blackPixels: 0, errors };
189
+ }
190
+ // Convert to buffer
191
+ const buffer = Buffer.from(hexString, 'hex');
192
+ byteCount = buffer.length;
193
+ // BMP signature validation
194
+ if (buffer.length < 14) {
195
+ errors.push('File too small to be a valid BMP (minimum 14 bytes for header)');
196
+ }
197
+ else {
198
+ if (buffer[0] !== 0x42 || buffer[1] !== 0x4D) {
199
+ errors.push('Invalid BMP signature (should start with "BM")');
200
+ }
201
+ }
202
+ // Size validation for MentraOS (576x135 = ~9782 bytes expected)
203
+ const expectedSize = 9782;
204
+ if (buffer.length < expectedSize - 100) { // Allow some tolerance
205
+ errors.push(`BMP too small (${buffer.length} bytes, expected ~${expectedSize})`);
206
+ }
207
+ else if (buffer.length > expectedSize + 1000) { // Allow some tolerance
208
+ errors.push(`BMP too large (${buffer.length} bytes, expected ~${expectedSize})`);
209
+ }
210
+ // Extract BMP metadata if header is valid
211
+ if (buffer.length >= 54) {
212
+ try {
213
+ // BMP width and height are at offsets 18 and 22 (little-endian)
214
+ const width = buffer.readUInt32LE(18);
215
+ const height = buffer.readUInt32LE(22);
216
+ metadata.dimensions = { width, height };
217
+ metadata.format = 'BMP';
218
+ // Validate dimensions for MentraOS glasses
219
+ if (width !== 576 || height !== 135) {
220
+ errors.push(`Invalid dimensions (${width}x${height}, expected 576x135 for MentraOS)`);
221
+ }
222
+ }
223
+ catch (e) {
224
+ errors.push('Failed to parse BMP header metadata');
225
+ }
226
+ }
227
+ // Pixel data validation (assumes 54-byte header + pixel data)
228
+ if (buffer.length > 62) {
229
+ const pixelData = buffer.slice(62); // Skip BMP header
230
+ blackPixels = Array.from(pixelData).filter(b => b !== 0xFF).length;
231
+ if (blackPixels === 0) {
232
+ errors.push('No black pixels found (image appears to be all white)');
233
+ }
234
+ }
235
+ else {
236
+ errors.push('File too small to contain pixel data');
237
+ }
238
+ }
239
+ catch (error) {
240
+ errors.push(`Failed to parse hex data: ${error instanceof Error ? error.message : 'Unknown error'}`);
241
+ }
242
+ return {
243
+ isValid: errors.length === 0,
244
+ byteCount,
245
+ blackPixels,
246
+ errors,
247
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined
248
+ };
249
+ }
250
+ /**
251
+ * Convert bitmap data between different formats
252
+ *
253
+ * @param data - Input bitmap data
254
+ * @param fromFormat - Source format ('hex' | 'base64' | 'buffer')
255
+ * @param toFormat - Target format ('hex' | 'base64' | 'buffer')
256
+ * @returns Converted bitmap data
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * const base64Data = BitmapUtils.convertFormat(hexData, 'hex', 'base64');
261
+ * const bufferData = BitmapUtils.convertFormat(base64Data, 'base64', 'buffer');
262
+ * ```
263
+ */
264
+ static convertFormat(data, fromFormat, toFormat) {
265
+ let buffer;
266
+ // Convert input to buffer
267
+ switch (fromFormat) {
268
+ case 'hex':
269
+ buffer = Buffer.from(data, 'hex');
270
+ break;
271
+ case 'base64':
272
+ buffer = Buffer.from(data, 'base64');
273
+ break;
274
+ case 'buffer':
275
+ buffer = data;
276
+ break;
277
+ default:
278
+ throw new Error(`Unsupported source format: ${fromFormat}`);
279
+ }
280
+ // Convert buffer to target format
281
+ switch (toFormat) {
282
+ case 'hex':
283
+ return buffer.toString('hex');
284
+ case 'base64':
285
+ return buffer.toString('base64');
286
+ case 'buffer':
287
+ return buffer;
288
+ default:
289
+ throw new Error(`Unsupported target format: ${toFormat}`);
290
+ }
291
+ }
292
+ /**
293
+ * Get bitmap information without full validation
294
+ *
295
+ * @param hexString - Hex-encoded bitmap data
296
+ * @returns Basic bitmap information
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * const info = BitmapUtils.getBitmapInfo(bmpHex);
301
+ * console.log(`Bitmap: ${info.width}x${info.height}, ${info.blackPixels} black pixels`);
302
+ * ```
303
+ */
304
+ static getBitmapInfo(hexString) {
305
+ try {
306
+ const buffer = Buffer.from(hexString, 'hex');
307
+ const isValidBmp = buffer.length >= 14 && buffer[0] === 0x42 && buffer[1] === 0x4D;
308
+ let width;
309
+ let height;
310
+ if (isValidBmp && buffer.length >= 54) {
311
+ try {
312
+ width = buffer.readUInt32LE(18);
313
+ height = buffer.readUInt32LE(22);
314
+ }
315
+ catch (e) {
316
+ // Ignore metadata parsing errors
317
+ }
318
+ }
319
+ const pixelData = buffer.slice(62);
320
+ const blackPixels = Array.from(pixelData).filter(b => b !== 0xFF).length;
321
+ return {
322
+ byteCount: buffer.length,
323
+ blackPixels,
324
+ width,
325
+ height,
326
+ isValidBmp
327
+ };
328
+ }
329
+ catch (error) {
330
+ return {
331
+ byteCount: 0,
332
+ blackPixels: 0,
333
+ isValidBmp: false
334
+ };
335
+ }
336
+ }
337
+ }
338
+ exports.BitmapUtils = BitmapUtils;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mentra/sdk",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Build apps for MentraOS smartglasses. This SDK provides everything you need to create real-time smartglasses applications.",
5
5
  "source": "src/index.ts",
6
6
  "main": "dist/index.js",