@mentra/engine 3.2.0-dev.116 → 3.2.0-dev.120

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 (64) hide show
  1. package/build/engine.d.ts.map +1 -1
  2. package/build/engine.js +7 -2
  3. package/build/engine.js.map +1 -1
  4. package/build/generated/releaseMetadata.js +5 -5
  5. package/build/generated/releaseMetadata.js.map +1 -1
  6. package/build/runtime/streamConfig.d.ts +7 -0
  7. package/build/runtime/streamConfig.d.ts.map +1 -1
  8. package/build/runtime/streamConfig.js +7 -0
  9. package/build/runtime/streamConfig.js.map +1 -1
  10. package/build/services/AcsMeetingService.d.ts +154 -0
  11. package/build/services/AcsMeetingService.d.ts.map +1 -0
  12. package/build/services/AcsMeetingService.js +477 -0
  13. package/build/services/AcsMeetingService.js.map +1 -0
  14. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  15. package/build/services/DeviceEventRouter.js +12 -3
  16. package/build/services/DeviceEventRouter.js.map +1 -1
  17. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  18. package/build/services/GlassesSettingsSync.js +11 -1
  19. package/build/services/GlassesSettingsSync.js.map +1 -1
  20. package/build/services/GlassesStatusProjection.d.ts +12 -0
  21. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  22. package/build/services/GlassesStatusProjection.js +23 -0
  23. package/build/services/GlassesStatusProjection.js.map +1 -1
  24. package/build/services/LocalMiniappRuntime.d.ts +6 -0
  25. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  26. package/build/services/LocalMiniappRuntime.js +130 -1
  27. package/build/services/LocalMiniappRuntime.js.map +1 -1
  28. package/build/services/MentraJSRouter.d.ts.map +1 -1
  29. package/build/services/MentraJSRouter.js +8 -1
  30. package/build/services/MentraJSRouter.js.map +1 -1
  31. package/build/services/PhoneCameraFovCoordinator.d.ts +18 -0
  32. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  33. package/build/services/PhoneCameraFovCoordinator.js +36 -0
  34. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  35. package/build/services/PhoneStreamCoordinator.d.ts +67 -1
  36. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  37. package/build/services/PhoneStreamCoordinator.js +204 -15
  38. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  39. package/build/services/StreamLifecycleController.d.ts +23 -5
  40. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  41. package/build/services/StreamLifecycleController.js +31 -10
  42. package/build/services/StreamLifecycleController.js.map +1 -1
  43. package/build/services/acsAudioSource.d.ts +24 -0
  44. package/build/services/acsAudioSource.d.ts.map +1 -0
  45. package/build/services/acsAudioSource.js +37 -0
  46. package/build/services/acsAudioSource.js.map +1 -0
  47. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  48. package/build/utils/devMiniappLaunch.js +4 -0
  49. package/build/utils/devMiniappLaunch.js.map +1 -1
  50. package/package.json +7 -6
  51. package/src/engine.ts +10 -2
  52. package/src/generated/releaseMetadata.ts +5 -5
  53. package/src/runtime/streamConfig.ts +13 -0
  54. package/src/services/AcsMeetingService.ts +570 -0
  55. package/src/services/DeviceEventRouter.ts +12 -3
  56. package/src/services/GlassesSettingsSync.ts +13 -3
  57. package/src/services/GlassesStatusProjection.ts +28 -0
  58. package/src/services/LocalMiniappRuntime.ts +142 -1
  59. package/src/services/MentraJSRouter.ts +7 -1
  60. package/src/services/PhoneCameraFovCoordinator.ts +34 -0
  61. package/src/services/PhoneStreamCoordinator.ts +232 -19
  62. package/src/services/StreamLifecycleController.ts +42 -12
  63. package/src/services/acsAudioSource.ts +53 -0
  64. package/src/utils/devMiniappLaunch.ts +4 -0
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,SAAS,EAAkD,aAAa,EAAC,MAAM,qBAAqB,CAAA;AAmC5G,eAAO,MAAM,MAAM;IACjB,2EAA2E;;IAE3E,8EAA8E;;IAE9E;iDAC6C;;IA0E7C;;yCAEqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BrC,mFAAmF;;;;;;;;IAEnF,sEAAsE;;;;;;;;;;;;IAEtE,qFAAqF;;;gBA7FlC,CAAC;mBAAiB,CAAC;;;gBAKhD,CAAC;mBAAiB,CAAC;;;;;;;;;;;;;;;;IA0FzC,qEAAqE;;;;IAErE,sFAAsF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEtF,6EAA6E;;;;;;;;;;;;IAE7E,iFAAiF;;;;;;;;;;;;;;;;;;;IAEjF,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAE9C,uDAAuD;;;;;;;;;;;;IAEvD,8EAA8E;;;;;;;IAE9E,qFAAqF;;;;;;;;;;;;;;CAGtF,CAAA"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,SAAS,EAAkD,aAAa,EAAC,MAAM,qBAAqB,CAAA;AAuC5G,eAAO,MAAM,MAAM;IACjB,2EAA2E;;IAE3E,8EAA8E;;IAE9E;iDAC6C;;IA8E7C;;yCAEqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BrC,mFAAmF;;;;;;;;IAEnF,sEAAsE;;;;;;;;;;;;IAEtE,qFAAqF;;;gBA/FjF,CAAL;mBAAiB,CAAC;;;gBAImB,CAAC;mBAAiB,CAAC;;;;;;;;;;;;;;;;IA6FvD,qEAAqE;;;;IAErE,sFAAsF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAEtF,6EAA6E;;;;;;;;;;;;IAE7E,iFAAiF;;;;;;;;;;;;;;;;;;;IAEjF,8CAA8C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAE9C,uDAAuD;;;;;;;;;;;;IAEvD,8EAA8E;;;;;;;IAE9E,qFAAqF;;;;;;;;;;;;;;CAGtF,CAAA"}
package/build/engine.js CHANGED
@@ -12,7 +12,7 @@ import { configure, start as bootstrapStart, stop as bootstrapStop, updateUiSeam
12
12
  import { cloudClientService } from "./services/CloudClientService";
13
13
  import { hydrateDeviceStore, demoteOrphanedDefaultWearable } from "./services/DeviceStoreHydration";
14
14
  import { startGlassesSettingsSync, stopGlassesSettingsSync } from "./services/GlassesSettingsSync";
15
- import { startGlassesStatusProjection, stopGlassesStatusProjection } from "./services/GlassesStatusProjection";
15
+ import { startGlassesStatusProjection, stopGlassesStatusProjection, toMiniappConnectionData, } from "./services/GlassesStatusProjection";
16
16
  import { startOtaService, stopOtaService } from "./services/OtaService";
17
17
  import { startAudioCloudUplink, stopAudioCloudUplink } from "./services/AudioCloudUplink";
18
18
  import { startSupportProfileSync, stopSupportProfileSync } from "./services/SupportProfileSync";
@@ -58,7 +58,12 @@ export const engine = {
58
58
  // Project native device status -> the engine stores (the inbound feed the rest
59
59
  // of the runtime reads). Established first so the stores are live before the
60
60
  // syncs below react to them.
61
- startGlassesStatusProjection((changed) => localMiniappRuntime.forwardEvent("glasses_connection_state", changed));
61
+ startGlassesStatusProjection((changed) => {
62
+ const connection = toMiniappConnectionData(changed);
63
+ if (!connection)
64
+ return;
65
+ localMiniappRuntime.forwardEvent("glasses_connection_state", connection);
66
+ });
62
67
  // Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,
63
68
  // photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->
64
69
  // store, miniapp_selected -> launcher) so a bare OEM gets device data, not just the
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAC,SAAS,EAAE,KAAK,IAAI,cAAc,EAAE,IAAI,IAAI,aAAa,EAAE,aAAa,EAAC,MAAM,qBAAqB,CAAA;AAC5G,OAAO,EAAC,kBAAkB,EAAC,MAAM,+BAA+B,CAAA;AAChE,OAAO,EAAC,kBAAkB,EAAE,6BAA6B,EAAC,MAAM,iCAAiC,CAAA;AACjG,OAAO,EAAC,wBAAwB,EAAE,uBAAuB,EAAC,MAAM,gCAAgC,CAAA;AAChG,OAAO,EAAC,4BAA4B,EAAE,2BAA2B,EAAC,MAAM,oCAAoC,CAAA;AAC5G,OAAO,EAAC,eAAe,EAAE,cAAc,EAAC,MAAM,uBAAuB,CAAA;AACrE,OAAO,EAAC,qBAAqB,EAAE,oBAAoB,EAAC,MAAM,6BAA6B,CAAA;AACvF,OAAO,EAAC,uBAAuB,EAAE,sBAAsB,EAAC,MAAM,+BAA+B,CAAA;AAC7F,OAAO,EAAC,sBAAsB,EAAE,qBAAqB,EAAC,MAAM,8BAA8B,CAAA;AAC1F,OAAO,EAAC,2BAA2B,EAAE,0BAA0B,EAAC,MAAM,mCAAmC,CAAA;AACzG,OAAO,EAAC,gCAAgC,EAAE,+BAA+B,EAAC,MAAM,wCAAwC,CAAA;AACxH,OAAO,EACL,mCAAmC,EACnC,kCAAkC,GACnC,MAAM,2CAA2C,CAAA;AAClD,OAAO,EAAC,mBAAmB,EAAE,iBAAiB,EAAC,MAAM,0BAA0B,CAAA;AAC/E,OAAO,mBAAmB,MAAM,gCAAgC,CAAA;AAChE,OAAO,gBAAgB,MAAM,6BAA6B,CAAA;AAC1D,OAAO,EAAC,kBAAkB,EAAC,MAAM,mCAAmC,CAAA;AACpE,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,MAAM,EAAC,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,GAAG,EAAC,MAAM,eAAe,CAAA;AACjC,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,QAAQ,EAAC,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAC,OAAO,EAAC,MAAM,mBAAmB,CAAA;AACzC,OAAO,EAAC,kBAAkB,EAAC,MAAM,8BAA8B,CAAA;AAC/D,OAAO,EAAC,WAAW,EAAC,MAAM,uBAAuB,CAAA;AACjD,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAA;AAE5C,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,2EAA2E;IAC3E,SAAS;IACT,8EAA8E;IAC9E,aAAa;IACb;iDAC6C;IAC7C,KAAK,CAAC,KAAK;QACT,4EAA4E;QAC5E,mEAAmE;QACnE,SAAS,CAAC,wBAAwB,EAAE,CAAA;QACpC,MAAM,cAAc,EAAE,CAAA;QACtB,6EAA6E;QAC7E,2EAA2E;QAC3E,iBAAiB;QACjB,kBAAkB,CAAC,IAAI,EAAE,CAAA;QACzB,+EAA+E;QAC/E,6EAA6E;QAC7E,6BAA6B;QAC7B,4BAA4B,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,mBAAmB,CAAC,YAAY,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC,CAAA;QAChH,mFAAmF;QACnF,qFAAqF;QACrF,oFAAoF;QACpF,8BAA8B;QAC9B,sBAAsB,EAAE,CAAA;QACxB,2EAA2E;QAC3E,4EAA4E;QAC5E,yEAAyE;QACzE,uEAAuE;QACvE,qEAAqE;QACrE,2EAA2E;QAC3E,oEAAoE;QACpE,sDAAsD;QACtD,IAAI,CAAC;YACH,MAAM,kBAAkB,EAAE,CAAA;YAC1B,qEAAqE;YACrE,yEAAyE;YACzE,wEAAwE;YACxE,+DAA+D;YAC/D,MAAM,6BAA6B,EAAE,CAAA;QACvC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QAC9G,CAAC;QACD,kFAAkF;QAClF,eAAe,EAAE,CAAA;QACjB,gFAAgF;QAChF,+EAA+E;QAC/E,qBAAqB,EAAE,CAAA;QACvB,IAAI,CAAC;YACH,MAAM,kBAAkB,CAAC,wBAAwB,EAAE,CAAA;QACrD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CACV,wDAAwD,EACxD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAC/C,CAAA;QACH,CAAC;QACD,uBAAuB,EAAE,CAAA;QACzB,8DAA8D;QAC9D,8EAA8E;QAC9E,wBAAwB,EAAE,CAAA;QAC1B,uEAAuE;QACvE,2BAA2B,EAAE,CAAA;QAC7B,+EAA+E;QAC/E,mDAAmD;QACnD,gCAAgC,EAAE,CAAA;QAClC,uEAAuE;QACvE,yEAAyE;QACzE,mCAAmC,EAAE,CAAA;QACrC,6EAA6E;QAC7E,2EAA2E;QAC3E,4EAA4E;QAC5E,6EAA6E;QAC7E,8EAA8E;QAC9E,oEAAoE;QACpE,gCAAgC;QAChC,mBAAmB,CAAC,UAAU,EAAE,CAAA;QAChC,mBAAmB,EAAE,CAAA;QACrB,gBAAgB,CAAC,eAAe,EAAE,CAAA;QAClC,kBAAkB,CAAC,UAAU,EAAE,CAAA;IACjC,CAAC;IACD;;yCAEqC;IACrC,KAAK,CAAC,IAAI;QACR,MAAM,MAAM,GAAG,KAAK,EAAE,KAAa,EAAE,IAAmB,EAAiB,EAAE;YACzE,IAAI,CAAC;gBACH,MAAM,IAAI,EAAE,CAAA;YACd,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,gBAAgB,KAAK,UAAU,EAAE,KAAK,CAAC,CAAA;YACtD,CAAC;QACH,CAAC,CAAA;QACD,MAAM,MAAM,CAAC,uBAAuB,EAAE,uBAAuB,CAAC,CAAA;QAC9D,MAAM,MAAM,CAAC,2BAA2B,EAAE,2BAA2B,CAAC,CAAA;QACtE,MAAM,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC,CAAA;QAC1D,MAAM,MAAM,CAAC,aAAa,EAAE,cAAc,CAAC,CAAA;QAC3C,MAAM,MAAM,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAA;QACxD,MAAM,MAAM,CAAC,sBAAsB,EAAE,sBAAsB,CAAC,CAAA;QAC5D,MAAM,MAAM,CAAC,0BAA0B,EAAE,0BAA0B,CAAC,CAAA;QACpE,MAAM,MAAM,CAAC,gCAAgC,EAAE,+BAA+B,CAAC,CAAA;QAC/E,MAAM,MAAM,CAAC,mCAAmC,EAAE,kCAAkC,CAAC,CAAA;QACrF,MAAM,MAAM,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAA;QACjD,MAAM,MAAM,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,OAAO,EAAE,CAAC,CAAA;QAC1E,MAAM,MAAM,CAAC,mBAAmB,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,CAAC,CAAA;QAC7E,MAAM,MAAM,CAAC,sBAAsB,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,OAAO,EAAE,CAAC,CAAA;QACxE,MAAM,MAAM,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAA;QAC7D,MAAM,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,CAAA;IAC1C,CAAC;IACD,OAAO;IACP,MAAM;IACN,mFAAmF;IACnF,OAAO;IACP,sEAAsE;IACtE,QAAQ;IACR,qFAAqF;IACrF,GAAG;IACH,qEAAqE;IACrE,OAAO;IACP,sFAAsF;IACtF,GAAG;IACH,6EAA6E;IAC7E,OAAO;IACP,iFAAiF;IACjF,QAAQ;IACR,8CAA8C;IAC9C,OAAO;IACP,uDAAuD;IACvD,kBAAkB;IAClB,8EAA8E;IAC9E,WAAW;IACX,qFAAqF;IACrF,aAAa;IACb,OAAO;CACR,CAAA","sourcesContent":["/**\n * `engine` — the namespaced OEM-facing engine API (the \"(A) host API\" from the\n * Phase-1 contract). Host UI calls `engine.<domain>.<method>()`; each domain is a\n * typed facade over the runtime. (Exported from the `@mentra/engine` module, whose\n * name stays `engine` in code; the public API surface is `engine`.)\n *\n * It grows one facade at a time. The migration-era flat store/service exports\n * remain in a private MentraOS host package; they shrink as screens move onto\n * `engine.*`.\n */\nimport {configure, start as bootstrapStart, stop as bootstrapStop, updateUiSeams} from \"./runtime/bootstrap\"\nimport {cloudClientService} from \"./services/CloudClientService\"\nimport {hydrateDeviceStore, demoteOrphanedDefaultWearable} from \"./services/DeviceStoreHydration\"\nimport {startGlassesSettingsSync, stopGlassesSettingsSync} from \"./services/GlassesSettingsSync\"\nimport {startGlassesStatusProjection, stopGlassesStatusProjection} from \"./services/GlassesStatusProjection\"\nimport {startOtaService, stopOtaService} from \"./services/OtaService\"\nimport {startAudioCloudUplink, stopAudioCloudUplink} from \"./services/AudioCloudUplink\"\nimport {startSupportProfileSync, stopSupportProfileSync} from \"./services/SupportProfileSync\"\nimport {startDeviceEventRouter, stopDeviceEventRouter} from \"./services/DeviceEventRouter\"\nimport {startPhoneNotificationsSync, stopPhoneNotificationsSync} from \"./services/PhoneNotificationsSync\"\nimport {startCaptionsTesterReportService, stopCaptionsTesterReportService} from \"./services/CaptionsTesterReportService\"\nimport {\n startMentraJSCrashloopReportService,\n stopMentraJSCrashloopReportService,\n} from \"./services/MentraJSCrashloopReportService\"\nimport {ensureMiniappEngine, stopMiniappEngine} from \"./services/MiniappEngine\"\nimport localMiniappRuntime from \"./services/LocalMiniappRuntime\"\nimport displayProcessor from \"./services/DisplayProcessor\"\nimport {gallerySyncService} from \"./services/asg/gallerySyncService\"\nimport {glasses} from \"./facades/glasses\"\nimport {display} from \"./facades/display\"\nimport {speech} from \"./facades/speech\"\nimport {session} from \"./facades/session\"\nimport {settings} from \"./facades/settings\"\nimport {dev} from \"./facades/dev\"\nimport {reports} from \"./facades/reports\"\nimport {ota} from \"./facades/ota\"\nimport {gallery} from \"./facades/gallery\"\nimport {miniapps} from \"./facades/miniapps\"\nimport {pairing} from \"./facades/pairing\"\nimport {phoneNotifications} from \"./facades/phoneNotifications\"\nimport {permissions} from \"./facades/permissions\"\nimport {notifications} from \"./facades/notifications\"\nimport {logBuffer} from \"./utils/devLogging\"\n\nexport const engine = {\n /** Front door — hand engine auth + config, then start/stop the runtime. */\n configure,\n /** Merge host-UI seams on a running runtime (scan overlay, wifi setup, …). */\n updateUiSeams,\n /** Start the runtime: mark started + construct/connect the cloud client + begin\n * syncing device settings to the glasses. */\n async start() {\n // Reports attach recent phone logs, so engine owns console interception for\n // OEM hosts too. Idempotent; the Mentra host may start it earlier.\n logBuffer.startConsoleInterception()\n await bootstrapStart()\n // Construct + connect the cloud client so the documented configure()+start()\n // lifecycle yields a live engine.session for OEMs. Idempotent for repeated\n // start() calls.\n cloudClientService.init()\n // Project native device status -> the engine stores (the inbound feed the rest\n // of the runtime reads). Established first so the stores are live before the\n // syncs below react to them.\n startGlassesStatusProjection((changed) => localMiniappRuntime.forwardEvent(\"glasses_connection_state\", changed))\n // Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,\n // photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->\n // store, miniapp_selected -> launcher) so a bare OEM gets device data, not just the\n // Mentra app's MantleManager.\n startDeviceEventRouter()\n // Hydration contract: the native DeviceStore is in-memory and starts empty\n // every launch; seed it from the persisted settings BEFORE start() resolves\n // so every post-start getDefaultDevice() read is a trustworthy two-state\n // answer (no false \"absent\" for genuinely-paired users at cold start).\n // Ordered before startGlassesSettingsSync so the settings load can't\n // double-push through the change subscription. A failed hydration must not\n // brick the runtime: start() continues, and the guards that consume\n // hasDefaultDevice() see the rejection and fail open.\n try {\n await hydrateDeviceStore()\n // Boot repair: a persisted default_wearable without a native default\n // device (identity abandoned mid-pairing, or resurrected from the server\n // before identity stopped syncing) demotes to pending_wearable so hosts\n // render finish-pairing instead of a connect that would throw.\n await demoteOrphanedDefaultWearable()\n } catch (error) {\n console.warn(\"engine.start: device-store hydration failed:\", error instanceof Error ? error.message : error)\n }\n // Project the glasses' OTA events into the store for the engine.ota read surface.\n startOtaService()\n // Forward glasses mic_lc3 frames to the v2 cloud session so cloud transcription\n // works for any host (not just the Mentra app's host-side MantleManager fork).\n startAudioCloudUplink()\n try {\n await cloudClientService.syncCoreTokenToBluetooth()\n } catch (error) {\n console.warn(\n \"engine.start: initial Cloud V2 core token sync failed:\",\n error instanceof Error ? error.message : error,\n )\n }\n startSupportProfileSync()\n // Push device-setting changes to the glasses for ANY host, so\n // engine.glasses.settings.set() reaches the device (not just the Mentra app).\n startGlassesSettingsSync()\n // Same for phone-notification config -> the native listener (Android).\n startPhoneNotificationsSync()\n // Android internal/e2e: laptop captions tester can broadcast a failure intent;\n // engine owns turning that into a Cloud V2 report.\n startCaptionsTesterReportService()\n // MentraJS crashloop-disabled is runtime state; engine owns filing the\n // automatic report while hosts only render alert/telemetry side effects.\n startMentraJSCrashloopReportService()\n // Bring up the local-miniapp engine so a bare OEM can run MentraJS miniapps:\n // the LocalMiniappRuntime (registry + WebView bridge), the MentraJS router\n // (crust-bound spawn/dispatch pump + launcher wiring), the DisplayProcessor\n // (layout arbitration over the engine stores), and the gallery-sync service.\n // All idempotent — when the Mentra app's host bootstrap also calls these, the\n // second call is a no-op. Host-only crashloop telemetry is attached\n // separately by the Mentra app.\n localMiniappRuntime.initialize()\n ensureMiniappEngine()\n displayProcessor.attachToRuntime()\n gallerySyncService.initialize()\n },\n /** Stop the runtime: tear down the settings sync + cloud client + mark stopped.\n * Each step is guarded so one failing teardown can't skip the rest and leak\n * the remaining runtime services. */\n async stop() {\n const safely = async (label: string, step: () => unknown): Promise<void> => {\n try {\n await step()\n } catch (error) {\n console.warn(`engine.stop: ${label} failed:`, error)\n }\n }\n await safely(\"glasses settings sync\", stopGlassesSettingsSync)\n await safely(\"glasses status projection\", stopGlassesStatusProjection)\n await safely(\"device event router\", stopDeviceEventRouter)\n await safely(\"ota service\", stopOtaService)\n await safely(\"audio cloud uplink\", stopAudioCloudUplink)\n await safely(\"support profile sync\", stopSupportProfileSync)\n await safely(\"phone notifications sync\", stopPhoneNotificationsSync)\n await safely(\"captions tester report service\", stopCaptionsTesterReportService)\n await safely(\"mentrajs crashloop report service\", stopMentraJSCrashloopReportService)\n await safely(\"miniapp engine\", stopMiniappEngine)\n await safely(\"local miniapp runtime\", () => localMiniappRuntime.cleanup())\n await safely(\"display processor\", () => displayProcessor.detachFromRuntime())\n await safely(\"gallery sync service\", () => gallerySyncService.cleanup())\n await safely(\"cloud client\", () => cloudClientService.stop())\n await safely(\"bootstrap\", bootstrapStop)\n },\n glasses,\n speech,\n /** Cloud (cloud-v2) live-session status + account ops — engine owns the client. */\n session,\n /** Typed keyed user settings over the engine-owned settings store. */\n settings,\n /** Developer/debug surface (backend+cloud URL overrides, reconnect, min version). */\n dev,\n /** Bug-report, automatic runtime report, and feedback submission. */\n reports,\n /** Firmware OTA read/observe surface (updateAvailable/status + on* subscriptions). */\n ota,\n /** Gallery sync: status/onStatus · onNotice (host renders) · sync/cancel. */\n gallery,\n /** Miniapp lifecycle (the WebView bridge primitives are exported separately). */\n miniapps,\n /** First-time glasses discovery + pairing. */\n pairing,\n /** Phone→glasses notification forwarding (Android). */\n phoneNotifications,\n /** OS permissions (check/request/openSettings + per-miniapp requirements). */\n permissions,\n /** Inbound alerts engine→host (crashloop, version-incompatible, connection loss). */\n notifications,\n display,\n}\n"]}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `engine` — the namespaced OEM-facing engine API (the \"(A) host API\" from the\n * Phase-1 contract). Host UI calls `engine.<domain>.<method>()`; each domain is a\n * typed facade over the runtime. (Exported from the `@mentra/engine` module, whose\n * name stays `engine` in code; the public API surface is `engine`.)\n *\n * It grows one facade at a time. The migration-era flat store/service exports\n * remain in a private MentraOS host package; they shrink as screens move onto\n * `engine.*`.\n */\nimport {configure, start as bootstrapStart, stop as bootstrapStop, updateUiSeams} from \"./runtime/bootstrap\"\nimport {cloudClientService} from \"./services/CloudClientService\"\nimport {hydrateDeviceStore, demoteOrphanedDefaultWearable} from \"./services/DeviceStoreHydration\"\nimport {startGlassesSettingsSync, stopGlassesSettingsSync} from \"./services/GlassesSettingsSync\"\nimport {\n startGlassesStatusProjection,\n stopGlassesStatusProjection,\n toMiniappConnectionData,\n} from \"./services/GlassesStatusProjection\"\nimport {startOtaService, stopOtaService} from \"./services/OtaService\"\nimport {startAudioCloudUplink, stopAudioCloudUplink} from \"./services/AudioCloudUplink\"\nimport {startSupportProfileSync, stopSupportProfileSync} from \"./services/SupportProfileSync\"\nimport {startDeviceEventRouter, stopDeviceEventRouter} from \"./services/DeviceEventRouter\"\nimport {startPhoneNotificationsSync, stopPhoneNotificationsSync} from \"./services/PhoneNotificationsSync\"\nimport {startCaptionsTesterReportService, stopCaptionsTesterReportService} from \"./services/CaptionsTesterReportService\"\nimport {\n startMentraJSCrashloopReportService,\n stopMentraJSCrashloopReportService,\n} from \"./services/MentraJSCrashloopReportService\"\nimport {ensureMiniappEngine, stopMiniappEngine} from \"./services/MiniappEngine\"\nimport localMiniappRuntime from \"./services/LocalMiniappRuntime\"\nimport displayProcessor from \"./services/DisplayProcessor\"\nimport {gallerySyncService} from \"./services/asg/gallerySyncService\"\nimport {glasses} from \"./facades/glasses\"\nimport {display} from \"./facades/display\"\nimport {speech} from \"./facades/speech\"\nimport {session} from \"./facades/session\"\nimport {settings} from \"./facades/settings\"\nimport {dev} from \"./facades/dev\"\nimport {reports} from \"./facades/reports\"\nimport {ota} from \"./facades/ota\"\nimport {gallery} from \"./facades/gallery\"\nimport {miniapps} from \"./facades/miniapps\"\nimport {pairing} from \"./facades/pairing\"\nimport {phoneNotifications} from \"./facades/phoneNotifications\"\nimport {permissions} from \"./facades/permissions\"\nimport {notifications} from \"./facades/notifications\"\nimport {logBuffer} from \"./utils/devLogging\"\n\nexport const engine = {\n /** Front door — hand engine auth + config, then start/stop the runtime. */\n configure,\n /** Merge host-UI seams on a running runtime (scan overlay, wifi setup, …). */\n updateUiSeams,\n /** Start the runtime: mark started + construct/connect the cloud client + begin\n * syncing device settings to the glasses. */\n async start() {\n // Reports attach recent phone logs, so engine owns console interception for\n // OEM hosts too. Idempotent; the Mentra host may start it earlier.\n logBuffer.startConsoleInterception()\n await bootstrapStart()\n // Construct + connect the cloud client so the documented configure()+start()\n // lifecycle yields a live engine.session for OEMs. Idempotent for repeated\n // start() calls.\n cloudClientService.init()\n // Project native device status -> the engine stores (the inbound feed the rest\n // of the runtime reads). Established first so the stores are live before the\n // syncs below react to them.\n startGlassesStatusProjection((changed) => {\n const connection = toMiniappConnectionData(changed)\n if (!connection) return\n localMiniappRuntime.forwardEvent(\"glasses_connection_state\", connection)\n })\n // Route the rest of the inbound device events (wifi/hotspot/gallery -> stores+bus,\n // photo/stream -> coordinators, button/touch/accel/head -> miniapps, save_setting ->\n // store, miniapp_selected -> launcher) so a bare OEM gets device data, not just the\n // Mentra app's MantleManager.\n startDeviceEventRouter()\n // Hydration contract: the native DeviceStore is in-memory and starts empty\n // every launch; seed it from the persisted settings BEFORE start() resolves\n // so every post-start getDefaultDevice() read is a trustworthy two-state\n // answer (no false \"absent\" for genuinely-paired users at cold start).\n // Ordered before startGlassesSettingsSync so the settings load can't\n // double-push through the change subscription. A failed hydration must not\n // brick the runtime: start() continues, and the guards that consume\n // hasDefaultDevice() see the rejection and fail open.\n try {\n await hydrateDeviceStore()\n // Boot repair: a persisted default_wearable without a native default\n // device (identity abandoned mid-pairing, or resurrected from the server\n // before identity stopped syncing) demotes to pending_wearable so hosts\n // render finish-pairing instead of a connect that would throw.\n await demoteOrphanedDefaultWearable()\n } catch (error) {\n console.warn(\"engine.start: device-store hydration failed:\", error instanceof Error ? error.message : error)\n }\n // Project the glasses' OTA events into the store for the engine.ota read surface.\n startOtaService()\n // Forward glasses mic_lc3 frames to the v2 cloud session so cloud transcription\n // works for any host (not just the Mentra app's host-side MantleManager fork).\n startAudioCloudUplink()\n try {\n await cloudClientService.syncCoreTokenToBluetooth()\n } catch (error) {\n console.warn(\n \"engine.start: initial Cloud V2 core token sync failed:\",\n error instanceof Error ? error.message : error,\n )\n }\n startSupportProfileSync()\n // Push device-setting changes to the glasses for ANY host, so\n // engine.glasses.settings.set() reaches the device (not just the Mentra app).\n startGlassesSettingsSync()\n // Same for phone-notification config -> the native listener (Android).\n startPhoneNotificationsSync()\n // Android internal/e2e: laptop captions tester can broadcast a failure intent;\n // engine owns turning that into a Cloud V2 report.\n startCaptionsTesterReportService()\n // MentraJS crashloop-disabled is runtime state; engine owns filing the\n // automatic report while hosts only render alert/telemetry side effects.\n startMentraJSCrashloopReportService()\n // Bring up the local-miniapp engine so a bare OEM can run MentraJS miniapps:\n // the LocalMiniappRuntime (registry + WebView bridge), the MentraJS router\n // (crust-bound spawn/dispatch pump + launcher wiring), the DisplayProcessor\n // (layout arbitration over the engine stores), and the gallery-sync service.\n // All idempotent — when the Mentra app's host bootstrap also calls these, the\n // second call is a no-op. Host-only crashloop telemetry is attached\n // separately by the Mentra app.\n localMiniappRuntime.initialize()\n ensureMiniappEngine()\n displayProcessor.attachToRuntime()\n gallerySyncService.initialize()\n },\n /** Stop the runtime: tear down the settings sync + cloud client + mark stopped.\n * Each step is guarded so one failing teardown can't skip the rest and leak\n * the remaining runtime services. */\n async stop() {\n const safely = async (label: string, step: () => unknown): Promise<void> => {\n try {\n await step()\n } catch (error) {\n console.warn(`engine.stop: ${label} failed:`, error)\n }\n }\n await safely(\"glasses settings sync\", stopGlassesSettingsSync)\n await safely(\"glasses status projection\", stopGlassesStatusProjection)\n await safely(\"device event router\", stopDeviceEventRouter)\n await safely(\"ota service\", stopOtaService)\n await safely(\"audio cloud uplink\", stopAudioCloudUplink)\n await safely(\"support profile sync\", stopSupportProfileSync)\n await safely(\"phone notifications sync\", stopPhoneNotificationsSync)\n await safely(\"captions tester report service\", stopCaptionsTesterReportService)\n await safely(\"mentrajs crashloop report service\", stopMentraJSCrashloopReportService)\n await safely(\"miniapp engine\", stopMiniappEngine)\n await safely(\"local miniapp runtime\", () => localMiniappRuntime.cleanup())\n await safely(\"display processor\", () => displayProcessor.detachFromRuntime())\n await safely(\"gallery sync service\", () => gallerySyncService.cleanup())\n await safely(\"cloud client\", () => cloudClientService.stop())\n await safely(\"bootstrap\", bootstrapStop)\n },\n glasses,\n speech,\n /** Cloud (cloud-v2) live-session status + account ops — engine owns the client. */\n session,\n /** Typed keyed user settings over the engine-owned settings store. */\n settings,\n /** Developer/debug surface (backend+cloud URL overrides, reconnect, min version). */\n dev,\n /** Bug-report, automatic runtime report, and feedback submission. */\n reports,\n /** Firmware OTA read/observe surface (updateAvailable/status + on* subscriptions). */\n ota,\n /** Gallery sync: status/onStatus · onNotice (host renders) · sync/cancel. */\n gallery,\n /** Miniapp lifecycle (the WebView bridge primitives are exported separately). */\n miniapps,\n /** First-time glasses discovery + pairing. */\n pairing,\n /** Phone→glasses notification forwarding (Android). */\n phoneNotifications,\n /** OS permissions (check/request/openSettings + per-miniapp requirements). */\n permissions,\n /** Inbound alerts engine→host (crashloop, version-incompatible, connection loss). */\n notifications,\n display,\n}\n"]}
@@ -1,10 +1,10 @@
1
1
  export const ENGINE_RELEASE_METADATA = Object.freeze({
2
2
  "schemaVersion": 1,
3
3
  "familyBaseVersion": "3.2.0",
4
- "releaseIdentity": "3.2.0-dev.116",
5
- "releaseSetId": "mentra-3.2.0-dev.116",
6
- "sourceCommit": "d5ccf36f2b9bb3ca8384ac628bf9ef0502e0b379",
7
- "otaManifestUrl": "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.116.json",
8
- "otaManifestSha256": "b6a4b0b6ececa107f8b20691a10b8e31066da83698748cbdbbb8f4d392177040"
4
+ "releaseIdentity": "3.2.0-dev.120",
5
+ "releaseSetId": "mentra-3.2.0-dev.120",
6
+ "sourceCommit": "1b8b39b87dc44799c88f414f088629df0f013850",
7
+ "otaManifestUrl": "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.120.json",
8
+ "otaManifestSha256": "4a5e13392f0d395a33867331fed19e9e5980526bc1b7e78f6ba2711c9e9ae1df"
9
9
  });
10
10
  //# sourceMappingURL=releaseMetadata.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,wHAAwH;IAC1I,mBAAmB,EAAE,kEAAkE;CACxF,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"3.2.0\",\n \"releaseIdentity\": \"3.2.0-dev.116\",\n \"releaseSetId\": \"mentra-3.2.0-dev.116\",\n \"sourceCommit\": \"d5ccf36f2b9bb3ca8384ac628bf9ef0502e0b379\",\n \"otaManifestUrl\": \"https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.116.json\",\n \"otaManifestSha256\": \"b6a4b0b6ececa107f8b20691a10b8e31066da83698748cbdbbb8f4d392177040\"\n})\n"]}
1
+ {"version":3,"file":"releaseMetadata.js","sourceRoot":"","sources":["../../src/generated/releaseMetadata.ts"],"names":[],"mappings":"AAWA,MAAM,CAAC,MAAM,uBAAuB,GAAoC,MAAM,CAAC,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC;IAClB,mBAAmB,EAAE,OAAO;IAC5B,iBAAiB,EAAE,eAAe;IAClC,cAAc,EAAE,sBAAsB;IACtC,cAAc,EAAE,0CAA0C;IAC1D,gBAAgB,EAAE,wHAAwH;IAC1I,mBAAmB,EAAE,kEAAkE;CACxF,CAAC,CAAA","sourcesContent":["/** Generated by release CI. Do not edit in a release checkout. */\nexport interface EngineReleaseMetadata {\n schemaVersion: 1\n familyBaseVersion: string | null\n releaseIdentity: string | null\n releaseSetId: string | null\n sourceCommit: string | null\n otaManifestUrl: string | null\n otaManifestSha256: string | null\n}\n\nexport const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({\n \"schemaVersion\": 1,\n \"familyBaseVersion\": \"3.2.0\",\n \"releaseIdentity\": \"3.2.0-dev.120\",\n \"releaseSetId\": \"mentra-3.2.0-dev.120\",\n \"sourceCommit\": \"1b8b39b87dc44799c88f414f088629df0f013850\",\n \"otaManifestUrl\": \"https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.2.0/mentra-live-ota-3.2.0-dev.120.json\",\n \"otaManifestSha256\": \"4a5e13392f0d395a33867331fed19e9e5980526bc1b7e78f6ba2711c9e9ae1df\"\n})\n"]}
@@ -1,4 +1,11 @@
1
1
  import type { StreamAudioConfig, StreamVideoConfig } from "./config";
2
2
  export declare const normalizeStreamVideoConfig: (value: unknown) => StreamVideoConfig | undefined;
3
3
  export declare const normalizeStreamAudioConfig: (value: unknown) => StreamAudioConfig | undefined;
4
+ /** Absent or non-boolean values keep the caller-supplied fallback (default true). */
5
+ export declare const normalizeCaptureAudio: (value: unknown, fallback?: boolean) => boolean;
6
+ /**
7
+ * Glasses capture is locked to the ACS source for the WHIP session.
8
+ * Phone/bluetooth never encode the glasses mic, even if a miniapp asks for it.
9
+ */
10
+ export declare const resolveCaptureAudio: (payload: unknown, source: "glasses" | "phone") => boolean;
4
11
  //# sourceMappingURL=streamConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamConfig.d.ts","sourceRoot":"","sources":["../../src/runtime/streamConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,UAAU,CAAA;AAQlE,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,iBAAiB,GAAG,SAa/E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,iBAAiB,GAAG,SAU/E,CAAA"}
1
+ {"version":3,"file":"streamConfig.d.ts","sourceRoot":"","sources":["../../src/runtime/streamConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAE,iBAAiB,EAAC,MAAM,UAAU,CAAA;AAQlE,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,iBAAiB,GAAG,SAa/E,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,OAAO,OAAO,KAAG,iBAAiB,GAAG,SAU/E,CAAA;AAED,qFAAqF;AACrF,eAAO,MAAM,qBAAqB,GAAI,OAAO,OAAO,EAAE,kBAAe,KAAG,OACzB,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAC9B,SAAS,OAAO,EAChB,QAAQ,SAAS,GAAG,OAAO,KAC1B,OAAuE,CAAA"}
@@ -35,4 +35,11 @@ export const normalizeStreamAudioConfig = (value) => {
35
35
  config.noiseSuppression = value.noiseSuppression;
36
36
  return Object.keys(config).length > 0 ? config : undefined;
37
37
  };
38
+ /** Absent or non-boolean values keep the caller-supplied fallback (default true). */
39
+ export const normalizeCaptureAudio = (value, fallback = true) => typeof value === "boolean" ? value : fallback;
40
+ /**
41
+ * Glasses capture is locked to the ACS source for the WHIP session.
42
+ * Phone/bluetooth never encode the glasses mic, even if a miniapp asks for it.
43
+ */
44
+ export const resolveCaptureAudio = (payload, source) => source === "glasses" && normalizeCaptureAudio(payload, true);
38
45
  //# sourceMappingURL=streamConfig.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"streamConfig.js","sourceRoot":"","sources":["../../src/runtime/streamConfig.ts"],"names":[],"mappings":"AAEA,MAAM,QAAQ,GAAG,CAAC,KAAc,EAAoC,EAAE,CACpE,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;AAEtE,MAAM,YAAY,GAAG,CAAC,KAAc,EAAsB,EAAE,CAC1D,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAA;AAEzE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,KAAc,EAAiC,EAAE;IAC1F,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACtC,MAAM,MAAM,GAAsB,EAAE,CAAA;IACpC,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;IACzC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC3C,MAAM,SAAS,GAAG,YAAY,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;IAC/C,MAAM,GAAG,GAAG,SAAS,IAAI,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;IAChD,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,CAAC,KAAK,GAAG,KAAK,CAAA;IAC7C,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,CAAC,MAAM,GAAG,MAAM,CAAA;IAChD,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IACnD,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,GAAG,GAAG,CAAA;IACvC,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,KAAc,EAAiC,EAAE;IAC1F,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,SAAS,CAAA;IACtC,MAAM,MAAM,GAAsB,EAAE,CAAA;IACpC,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IACjD,IAAI,OAAO,KAAK,SAAS;QAAE,MAAM,CAAC,OAAO,GAAG,OAAO,CAAA;IACnD,IAAI,UAAU,KAAK,SAAS;QAAE,MAAM,CAAC,UAAU,GAAG,UAAU,CAAA;IAC5D,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,SAAS;QAAE,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAA;IACjG,IAAI,OAAO,KAAK,CAAC,gBAAgB,KAAK,SAAS;QAAE,MAAM,CAAC,gBAAgB,GAAG,KAAK,CAAC,gBAAgB,CAAA;IACjG,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAA;AAC5D,CAAC,CAAA","sourcesContent":["import type {StreamAudioConfig, StreamVideoConfig} from \"./config\"\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst finiteNumber = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined\n\nexport const normalizeStreamVideoConfig = (value: unknown): StreamVideoConfig | undefined => {\n if (!isRecord(value)) return undefined\n const config: StreamVideoConfig = {}\n const width = finiteNumber(value.width)\n const height = finiteNumber(value.height)\n const bitrate = finiteNumber(value.bitrate)\n const frameRate = finiteNumber(value.frameRate)\n const fps = frameRate ?? finiteNumber(value.fps)\n if (width !== undefined) config.width = width\n if (height !== undefined) config.height = height\n if (bitrate !== undefined) config.bitrate = bitrate\n if (fps !== undefined) config.fps = fps\n return Object.keys(config).length > 0 ? config : undefined\n}\n\nexport const normalizeStreamAudioConfig = (value: unknown): StreamAudioConfig | undefined => {\n if (!isRecord(value)) return undefined\n const config: StreamAudioConfig = {}\n const bitrate = finiteNumber(value.bitrate)\n const sampleRate = finiteNumber(value.sampleRate)\n if (bitrate !== undefined) config.bitrate = bitrate\n if (sampleRate !== undefined) config.sampleRate = sampleRate\n if (typeof value.echoCancellation === \"boolean\") config.echoCancellation = value.echoCancellation\n if (typeof value.noiseSuppression === \"boolean\") config.noiseSuppression = value.noiseSuppression\n return Object.keys(config).length > 0 ? config : undefined\n}\n"]}
1
+ {"version":3,"file":"streamConfig.js","sourceRoot":"","sources":["../../src/runtime/streamConfig.ts"],"names":[],"mappings":"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","sourcesContent":["import type {StreamAudioConfig, StreamVideoConfig} from \"./config\"\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value)\n\nconst finiteNumber = (value: unknown): number | undefined =>\n typeof value === \"number\" && Number.isFinite(value) ? value : undefined\n\nexport const normalizeStreamVideoConfig = (value: unknown): StreamVideoConfig | undefined => {\n if (!isRecord(value)) return undefined\n const config: StreamVideoConfig = {}\n const width = finiteNumber(value.width)\n const height = finiteNumber(value.height)\n const bitrate = finiteNumber(value.bitrate)\n const frameRate = finiteNumber(value.frameRate)\n const fps = frameRate ?? finiteNumber(value.fps)\n if (width !== undefined) config.width = width\n if (height !== undefined) config.height = height\n if (bitrate !== undefined) config.bitrate = bitrate\n if (fps !== undefined) config.fps = fps\n return Object.keys(config).length > 0 ? config : undefined\n}\n\nexport const normalizeStreamAudioConfig = (value: unknown): StreamAudioConfig | undefined => {\n if (!isRecord(value)) return undefined\n const config: StreamAudioConfig = {}\n const bitrate = finiteNumber(value.bitrate)\n const sampleRate = finiteNumber(value.sampleRate)\n if (bitrate !== undefined) config.bitrate = bitrate\n if (sampleRate !== undefined) config.sampleRate = sampleRate\n if (typeof value.echoCancellation === \"boolean\") config.echoCancellation = value.echoCancellation\n if (typeof value.noiseSuppression === \"boolean\") config.noiseSuppression = value.noiseSuppression\n return Object.keys(config).length > 0 ? config : undefined\n}\n\n/** Absent or non-boolean values keep the caller-supplied fallback (default true). */\nexport const normalizeCaptureAudio = (value: unknown, fallback = true): boolean =>\n typeof value === \"boolean\" ? value : fallback\n\n/**\n * Glasses capture is locked to the ACS source for the WHIP session.\n * Phone/bluetooth never encode the glasses mic, even if a miniapp asks for it.\n */\nexport const resolveCaptureAudio = (\n payload: unknown,\n source: \"glasses\" | \"phone\",\n): boolean => source === \"glasses\" && normalizeCaptureAudio(payload, true)\n"]}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Host-side ACS meeting controller. One active meeting. Native module owns
3
+ * WHEP + ACS; this service maps that into miniapp envelopes and pipes
4
+ * incoming PCM into AudioPlaybackService (A2DP / PcmStreamPlayer).
5
+ */
6
+ import { ACS_CALL_MIC, type ResolvedAudioSource, type SourceReason } from "./acsAudioSource";
7
+ export { ACS_CALL_MIC };
8
+ export type { ResolvedAudioSource, SourceReason };
9
+ type MeetingPhase = "idle" | "connecting" | "lobby" | "connected" | "disconnected" | "error";
10
+ export type AudioSafety = "safe" | "degraded" | "unsafe";
11
+ export type ActiveStream = "none" | "virtual" | "local";
12
+ /**
13
+ * Health of the glasses WHEP subscription that feeds the call. `failed` means ICE
14
+ * dropped or the WHEP endpoint went away (glasses stopped publishing, phone changed
15
+ * networks); the ACS call itself may still be `connected` with a frozen last frame.
16
+ */
17
+ export type MediaSourceState = "idle" | "connecting" | "live" | "failed";
18
+ export type MeetingParticipantState = "idle" | "connecting" | "connected" | "lobby" | "hold" | "disconnected";
19
+ export interface MeetingParticipant {
20
+ id: string;
21
+ displayName: string | null;
22
+ state: MeetingParticipantState;
23
+ isMuted: boolean;
24
+ isSpeaking: boolean;
25
+ }
26
+ export interface MeetingState {
27
+ state: MeetingPhase;
28
+ muted: boolean;
29
+ error?: string;
30
+ meetingUrl?: string;
31
+ provider?: "acs-teams";
32
+ audioSource?: "glasses" | "phone";
33
+ audioSourceReason?: SourceReason;
34
+ activeStream?: ActiveStream;
35
+ audioSafety?: AudioSafety;
36
+ mediaSource?: MediaSourceState;
37
+ participants?: MeetingParticipant[];
38
+ }
39
+ /**
40
+ * The call microphone is [ACS_CALL_MIC]. Flip that constant to `"glasses"`
41
+ * to restore glasses WHIP → Cloudflare → WHEP PCM. Do not use ACS
42
+ * LocalOutgoingAudioStream for phone: that path makes ACS own the route
43
+ * (MODE_IN_COMMUNICATION + forced speaker) and opens an echo loop.
44
+ * preferred_mic governs MentraOS STT capture, not this call.
45
+ */
46
+ export declare function resolveAcsAudioSource(): ResolvedAudioSource;
47
+ export declare function parseMeetingParticipants(raw: unknown): MeetingParticipant[] | undefined;
48
+ export type AcsOutgoingVideo = {
49
+ width: number;
50
+ height: number;
51
+ fps: number;
52
+ maxBitrateBps: number;
53
+ };
54
+ export declare function parseAcsOutgoingVideo(raw: unknown): AcsOutgoingVideo | undefined;
55
+ type NativeModule = {
56
+ join(options: {
57
+ meetingUrl: string;
58
+ token: string;
59
+ whepUrl: string;
60
+ displayName?: string;
61
+ dumpPcmWav?: boolean;
62
+ audioSource?: "glasses" | "phone";
63
+ video?: AcsOutgoingVideo;
64
+ }): Promise<MeetingState>;
65
+ leave(): Promise<void>;
66
+ setMuted(muted: boolean): Promise<MeetingState>;
67
+ setAudioSource(source: "glasses" | "phone"): Promise<MeetingState>;
68
+ updateVideoSource(whepUrl: string): Promise<void>;
69
+ /** Force a WHEP rebuild on the current URL. Absent on natives that predate it. */
70
+ restartVideoSource?(): Promise<void>;
71
+ getState(): Promise<MeetingState>;
72
+ addListener(event: string, listener: (event: Record<string, unknown>) => void): {
73
+ remove: () => void;
74
+ };
75
+ };
76
+ /** Test seam: skip the native require and inject a fake ACS module. */
77
+ export declare function setAcsMeetingNativeForTests(mod: NativeModule | null | undefined): void;
78
+ /**
79
+ * Phone connectivity feed. Only the subset of `@react-native-community/netinfo`
80
+ * this service needs, so tests can inject a fake and hosts without the package
81
+ * (or a bare test runtime) degrade to "no phone-network awareness" instead of
82
+ * failing to load the meeting service.
83
+ */
84
+ export type PhoneNetworkInfo = {
85
+ type: string;
86
+ isConnected: boolean | null;
87
+ };
88
+ type PhoneNetworkSource = {
89
+ addEventListener(listener: (state: PhoneNetworkInfo) => void): () => void;
90
+ };
91
+ /** Test seam: inject a fake phone-network feed (or `null` to disable it). */
92
+ export declare function setAcsMeetingPhoneNetworkForTests(source: PhoneNetworkSource | null | undefined): void;
93
+ declare class AcsMeetingService {
94
+ private owner;
95
+ private pcmStreamId;
96
+ private pcmFormat;
97
+ private pcmReopen;
98
+ private pcmWriteChain;
99
+ private lastBacklogWarnAt;
100
+ private subscriptions;
101
+ private lastState;
102
+ private onState;
103
+ /** WHEP URL native is (or should be) subscribed to; what a host-triggered restart re-feeds. */
104
+ private whepUrl;
105
+ private phoneNetworkUnsub;
106
+ private lastPhoneNetworkKey;
107
+ private lastMediaRestartAt;
108
+ setStateHandler(handler: (packageName: string, state: MeetingState) => void): void;
109
+ getState(): MeetingState;
110
+ ownerPackage(): string | null;
111
+ join(packageName: string, args: {
112
+ meetingUrl: string;
113
+ token: string;
114
+ whepUrl: string;
115
+ displayName?: string;
116
+ video?: AcsOutgoingVideo;
117
+ }): Promise<MeetingState>;
118
+ leave(packageName: string): Promise<void>;
119
+ /**
120
+ * Drop everything the host set up around a session: the network watcher, return
121
+ * audio, native listeners, ownership. Runs after native has been told to leave
122
+ * (or after a join that never produced a native call).
123
+ */
124
+ private releaseHostState;
125
+ setMuted(packageName: string, muted: boolean): Promise<MeetingState>;
126
+ updateVideoSource(packageName: string, whepUrl: string): Promise<void>;
127
+ readState(packageName: string): Promise<MeetingState>;
128
+ leaveIfOwner(packageName: string): Promise<void>;
129
+ private assertOwner;
130
+ private unbindNative;
131
+ private bindNative;
132
+ /**
133
+ * The WHEP PeerConnection does not survive the phone changing networks
134
+ * (Wi-Fi↔cellular, or a different Wi-Fi): ICE fails and native parks the source
135
+ * as `failed` while the ACS call itself reconnects on its own. Nudge native to
136
+ * rebuild the subscription whenever the phone's network identity changes during
137
+ * a live meeting. Native ignores the request when the source is healthy on the
138
+ * same URL, so a spurious event costs nothing.
139
+ */
140
+ private watchPhoneNetwork;
141
+ private unwatchPhoneNetwork;
142
+ private restartMediaSource;
143
+ /**
144
+ * Native normalizes to 16 kHz mono, so this is normally a straight write.
145
+ * If the format ever differs, reopen the player to match rather than play
146
+ * the bytes at the wrong rate (that is what slows and deepens the audio).
147
+ */
148
+ private writeIncomingPcm;
149
+ private ensurePcmPlayback;
150
+ private stopPcm;
151
+ }
152
+ declare const acsMeetingService: AcsMeetingService;
153
+ export default acsMeetingService;
154
+ //# sourceMappingURL=AcsMeetingService.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AcsMeetingService.d.ts","sourceRoot":"","sources":["../../src/services/AcsMeetingService.ts"],"names":[],"mappings":"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"}