@mentra/engine 3.1.0-dev.9 → 3.1.0-dev.94

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 (109) hide show
  1. package/README.md +23 -5
  2. package/build/bluetooth-sdk/ota-transport.d.ts +2 -0
  3. package/build/bluetooth-sdk/ota-transport.d.ts.map +1 -0
  4. package/build/bluetooth-sdk/ota-transport.js +2 -0
  5. package/build/bluetooth-sdk/ota-transport.js.map +1 -0
  6. package/build/engine.d.ts +5 -2
  7. package/build/engine.d.ts.map +1 -1
  8. package/build/facades/ota.d.ts +11 -6
  9. package/build/facades/ota.d.ts.map +1 -1
  10. package/build/facades/ota.js +9 -5
  11. package/build/facades/ota.js.map +1 -1
  12. package/build/facades/pairing.d.ts +4 -0
  13. package/build/facades/pairing.d.ts.map +1 -1
  14. package/build/facades/pairing.js +81 -7
  15. package/build/facades/pairing.js.map +1 -1
  16. package/build/generated/releaseMetadata.js +5 -5
  17. package/build/generated/releaseMetadata.js.map +1 -1
  18. package/build/index.d.ts +2 -2
  19. package/build/index.d.ts.map +1 -1
  20. package/build/index.js +1 -1
  21. package/build/index.js.map +1 -1
  22. package/build/react/MentraLiveOtaFlow.d.ts +8 -2
  23. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -1
  24. package/build/react/MentraLiveOtaFlow.js +256 -354
  25. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  26. package/build/react/index.d.ts +1 -0
  27. package/build/react/index.d.ts.map +1 -1
  28. package/build/react/index.js +1 -0
  29. package/build/react/index.js.map +1 -1
  30. package/build/react/useMentraLiveOta.d.ts +84 -0
  31. package/build/react/useMentraLiveOta.d.ts.map +1 -0
  32. package/build/react/useMentraLiveOta.js +627 -0
  33. package/build/react/useMentraLiveOta.js.map +1 -0
  34. package/build/services/BlobStore.d.ts +2 -0
  35. package/build/services/BlobStore.d.ts.map +1 -1
  36. package/build/services/BlobStore.js +63 -10
  37. package/build/services/BlobStore.js.map +1 -1
  38. package/build/services/GlassesStatusProjection.d.ts +15 -2
  39. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  40. package/build/services/GlassesStatusProjection.js +3 -3
  41. package/build/services/GlassesStatusProjection.js.map +1 -1
  42. package/build/services/HotspotOtaTransport.d.ts.map +1 -1
  43. package/build/services/HotspotOtaTransport.js +8 -7
  44. package/build/services/HotspotOtaTransport.js.map +1 -1
  45. package/build/services/OtaAutoChain.d.ts +9 -2
  46. package/build/services/OtaAutoChain.d.ts.map +1 -1
  47. package/build/services/OtaAutoChain.js +10 -2
  48. package/build/services/OtaAutoChain.js.map +1 -1
  49. package/build/services/OtaInstallCoordinator.d.ts +26 -3
  50. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  51. package/build/services/OtaInstallCoordinator.js +35 -13
  52. package/build/services/OtaInstallCoordinator.js.map +1 -1
  53. package/build/services/OtaService.d.ts.map +1 -1
  54. package/build/services/OtaService.js +1 -1
  55. package/build/services/OtaService.js.map +1 -1
  56. package/build/services/OtaUpdateCheckService.d.ts +4 -1
  57. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  58. package/build/services/OtaUpdateCheckService.js +21 -5
  59. package/build/services/OtaUpdateCheckService.js.map +1 -1
  60. package/build/services/asg/localNetworkTransport.d.ts.map +1 -1
  61. package/build/services/asg/localNetworkTransport.js +13 -12
  62. package/build/services/asg/localNetworkTransport.js.map +1 -1
  63. package/build/services/glassesClockSync.js +1 -1
  64. package/build/services/glassesClockSync.js.map +1 -1
  65. package/build/services/otaInstallPolicy.d.ts +4 -0
  66. package/build/services/otaInstallPolicy.d.ts.map +1 -1
  67. package/build/services/otaInstallPolicy.js +4 -0
  68. package/build/services/otaInstallPolicy.js.map +1 -1
  69. package/build/services/otaReleaseVersion.d.ts +10 -0
  70. package/build/services/otaReleaseVersion.d.ts.map +1 -0
  71. package/build/services/otaReleaseVersion.js +14 -0
  72. package/build/services/otaReleaseVersion.js.map +1 -0
  73. package/build/stores/appVisibility.d.ts +3 -0
  74. package/build/stores/appVisibility.d.ts.map +1 -0
  75. package/build/stores/appVisibility.js +3 -0
  76. package/build/stores/appVisibility.js.map +1 -0
  77. package/build/stores/apps.d.ts.map +1 -1
  78. package/build/stores/apps.js +7 -1
  79. package/build/stores/apps.js.map +1 -1
  80. package/build/stores/core.d.ts +3 -3
  81. package/build/stores/core.d.ts.map +1 -1
  82. package/build/stores/core.js.map +1 -1
  83. package/build/stores/glasses.d.ts +10 -4
  84. package/build/stores/glasses.d.ts.map +1 -1
  85. package/build/stores/glasses.js.map +1 -1
  86. package/package.json +13 -6
  87. package/src/bluetooth-sdk/ota-transport.ts +1 -0
  88. package/src/facades/ota.ts +19 -6
  89. package/src/facades/pairing.ts +88 -12
  90. package/src/generated/releaseMetadata.ts +5 -5
  91. package/src/index.ts +2 -0
  92. package/src/react/MentraLiveOtaFlow.tsx +378 -480
  93. package/src/react/index.ts +14 -0
  94. package/src/react/useMentraLiveOta.ts +793 -0
  95. package/src/services/BlobStore.ts +57 -10
  96. package/src/services/GlassesStatusProjection.ts +7 -6
  97. package/src/services/HotspotOtaTransport.ts +8 -7
  98. package/src/services/OtaAutoChain.ts +26 -2
  99. package/src/services/OtaInstallCoordinator.ts +37 -13
  100. package/src/services/OtaService.ts +1 -2
  101. package/src/services/OtaUpdateCheckService.ts +26 -8
  102. package/src/services/asg/localNetworkTransport.ts +20 -19
  103. package/src/services/glassesClockSync.ts +1 -1
  104. package/src/services/otaInstallPolicy.ts +4 -0
  105. package/src/services/otaReleaseVersion.ts +22 -0
  106. package/src/stores/appVisibility.ts +3 -0
  107. package/src/stores/apps.ts +7 -1
  108. package/src/stores/core.ts +4 -4
  109. package/src/stores/glasses.ts +13 -6
@@ -8,9 +8,16 @@
8
8
  * `installSession` fronts the OtaInstallCoordinator state machine (WP 8B) — the host
9
9
  * progress screen is a pure renderer over its snapshot + attach/detach/retry/finish.
10
10
  */
11
- import BluetoothSdk from "@mentra/bluetooth-sdk/internal"
12
- import type {OtaProgress, OtaProgressStatus, OtaStartAckEvent, OtaStatus, OtaUpdateInfo} from "@mentra/bluetooth-sdk"
13
- import {isGlassesConnected, useGlassesStore} from "../stores/glasses"
11
+ import BluetoothSdk from "@mentra/bluetooth-sdk"
12
+ import type {
13
+ OtaProgress,
14
+ OtaProgressStatus,
15
+ OtaStartAckEvent,
16
+ OtaStatus,
17
+ OtaUpdateInfo,
18
+ ReleaseChangelog,
19
+ } from "@mentra/bluetooth-sdk"
20
+ import {isGlassesConnected, isGlassesReady, useGlassesStore} from "../stores/glasses"
14
21
  import {resolveOtaManifestUrl} from "../services/otaManifestUrl"
15
22
  import {otaInstallCoordinator, type OtaInstallSnapshot} from "../services/OtaInstallCoordinator"
16
23
  import {startGlassesStatusProjection} from "../services/GlassesStatusProjection"
@@ -25,9 +32,12 @@ function projectSnapshot() {
25
32
  const s = useGlassesStore.getState()
26
33
  return {
27
34
  connected: isGlassesConnected(s.connection),
35
+ ready: isGlassesReady(s.connection),
28
36
  buildNumber: s.buildNumber || null,
37
+ appVersion: s.appVersion || null,
29
38
  mtkFirmwareVersion: s.mtkFirmwareVersion || null,
30
39
  besFirmwareVersion: s.besFirmwareVersion || null,
40
+ batteryLevel: s.batteryLevel >= 0 ? s.batteryLevel : null,
31
41
  hotspotOtaVersion: s.hotspotOtaVersion ?? 0,
32
42
  wifiConnected: s.wifi.state === "connected",
33
43
  wifiStatusKnown: s.wifiStatusKnown,
@@ -46,6 +56,7 @@ export type {
46
56
  OtaProgressStatus,
47
57
  OtaStatus,
48
58
  OtaUpdateInfo,
59
+ ReleaseChangelog,
49
60
  OtaInstallSnapshot,
50
61
  OtaCheckCurrentGlassesOptions,
51
62
  OtaCheckCurrentGlassesResult,
@@ -84,6 +95,9 @@ export const ota = {
84
95
  ping: () => BluetoothSdk.ping(),
85
96
  /** Resolve and compare the current glasses against the OTA manifest, then update the OTA snapshot. */
86
97
  checkForUpdates: (options?: OtaCheckCurrentGlassesOptions) => checkCurrentGlassesForUpdate(options),
98
+ /** Return bundled release changelogs crossed between two coordinated product versions, newest first. */
99
+ getReleaseChangelogs: (fromVersion?: string | null, toVersion?: string | null): ReleaseChangelog[] =>
100
+ BluetoothSdk.getReleaseChangelogs(fromVersion, toVersion),
87
101
  /** Clear the available-update prompt state. */
88
102
  clearUpdateAvailable: () => useGlassesStore.getState().setOtaUpdateAvailable(null),
89
103
  /** Clear active progress/status before entering a fresh install flow. */
@@ -113,7 +127,6 @@ export const ota = {
113
127
  * @deprecated Legacy progress route (build < 37) only — removed with WP 8D.
114
128
  */
115
129
  clearBuildNumberForNextCheck: () => {
116
- BluetoothSdk.updateGlasses({buildNumber: ""})
117
130
  useGlassesStore.getState().setGlassesInfo({buildNumber: ""})
118
131
  },
119
132
  /**
@@ -136,9 +149,9 @@ export const ota = {
136
149
  detach: () => otaInstallCoordinator.detach(),
137
150
  /** Retry after a failure: clear state and re-send ota_start (if connected). */
138
151
  retry: () => otaInstallCoordinator.retry(),
139
- /** Terminal cleanup for Continue/Done (navigation stays in the screen). */
152
+ /** Terminal cleanup for Continue/Done, including hotspot route teardown. */
140
153
  finish: () => otaInstallCoordinator.finish(),
141
- /** Abandon an interrupted session (super-mode skip): finish() + drop the session's status/progress. */
154
+ /** Abandon an interrupted session: await finish() then drop the session's status/progress. */
142
155
  discard: () => otaInstallCoordinator.discard(),
143
156
  /** Current install read model (displayState/errorMsg/lockout + glasses OTA data). */
144
157
  snapshot: (): OtaInstallSnapshot => otaInstallCoordinator.snapshot(),
@@ -13,6 +13,7 @@ import BluetoothSdk from "@mentra/bluetooth-sdk/internal"
13
13
  import type {ConnectOptions, Device, DeviceModel, PairFailureEvent, GlassesNotReadyEvent} from "@mentra/bluetooth-sdk"
14
14
  import {useCoreStore} from "../stores/core"
15
15
  import {useGlassesStore} from "../stores/glasses"
16
+ import {SETTINGS, useSettingsStore} from "../stores/settings"
16
17
  import {hasDefaultDevice} from "../services/DeviceStoreHydration"
17
18
  import {
18
19
  markPendingSelection,
@@ -20,18 +21,14 @@ import {
20
21
  subscribePairingIdentity,
21
22
  type IdentitySnapshot,
22
23
  } from "../services/PairingIdentity"
23
- import {
24
- isGlassesConnected,
25
- isGlassesLinkLayerBusy,
26
- isGlassesReady,
27
- waitForGlassesReady,
28
- } from "../services/GlassesReadiness"
24
+ import {isGlassesConnected, isGlassesLinkLayerBusy, isGlassesReady} from "../services/GlassesReadiness"
29
25
  import {
30
26
  logAutomaticReportSubmissionStatus,
31
27
  toAutomaticReportSubmissionStatus,
32
28
  type AutomaticReportSubmissionStatus,
33
29
  } from "../services/AutomaticReportResult"
34
30
  import {pushAllBluetoothSettings} from "../services/GlassesSettingsSync"
31
+ import {ControllerTypes} from "../types"
35
32
  import {submitAutomaticReport} from "./reports"
36
33
 
37
34
  export type {IdentitySnapshot} from "../services/PairingIdentity"
@@ -60,6 +57,82 @@ function projectReadiness() {
60
57
  }
61
58
  }
62
59
 
60
+ function projectTargetReady(options: Pick<PairingReadyWaitOptions, "deviceModel" | "deviceName">): boolean {
61
+ const {deviceModel, deviceName} = options
62
+ const glasses = useGlassesStore.getState()
63
+
64
+ if (deviceModel === ControllerTypes.R1) {
65
+ if (!glasses.controllerConnected || !glasses.controllerFullyBooted) return false
66
+ const settings = useSettingsStore.getState()
67
+ const pairedModel = settings.getSetting(SETTINGS.default_controller.key)
68
+ const pairedName = settings.getSetting(SETTINGS.controller_device_name.key)
69
+ return (!deviceModel || pairedModel === deviceModel) && (!deviceName || pairedName === deviceName)
70
+ }
71
+
72
+ if (!isGlassesReady(glasses.connection)) return false
73
+ const identity = projectPairingIdentity()
74
+ if (!deviceModel && !deviceName) return true
75
+ return (
76
+ identity.kind === "paired" &&
77
+ (!deviceModel || identity.model === deviceModel) &&
78
+ (!deviceName || identity.name === deviceName)
79
+ )
80
+ }
81
+
82
+ function subscribeTargetReady(
83
+ options: Pick<PairingReadyWaitOptions, "deviceModel" | "deviceName">,
84
+ cb: (ready: boolean) => void,
85
+ ): () => void {
86
+ let last = projectTargetReady(options)
87
+ const notify = () => {
88
+ const ready = projectTargetReady(options)
89
+ if (ready === last) return
90
+ last = ready
91
+ cb(ready)
92
+ }
93
+ const unsubscribeGlasses = useGlassesStore.subscribe(notify)
94
+ const unsubscribeSettings = useSettingsStore.subscribe(notify)
95
+ return () => {
96
+ unsubscribeGlasses()
97
+ unsubscribeSettings()
98
+ }
99
+ }
100
+
101
+ async function waitForTargetReady(options: PairingReadyWaitOptions, timeoutMs: number): Promise<boolean> {
102
+ return new Promise((resolve) => {
103
+ if (options.signal?.aborted) {
104
+ resolve(false)
105
+ return
106
+ }
107
+ if (projectTargetReady(options)) {
108
+ resolve(true)
109
+ return
110
+ }
111
+
112
+ let settled = false
113
+ let timeout: ReturnType<typeof setTimeout> | null = null
114
+ let unsubscribe: (() => void) | null = null
115
+ let onAbort: (() => void) | null = null
116
+ const finish = (ready: boolean) => {
117
+ if (settled) return
118
+ settled = true
119
+ if (timeout) clearTimeout(timeout)
120
+ if (unsubscribe) unsubscribe()
121
+ if (onAbort && options.signal) options.signal.removeEventListener("abort", onAbort)
122
+ resolve(ready)
123
+ }
124
+
125
+ unsubscribe = subscribeTargetReady(options, (ready) => {
126
+ if (ready) finish(true)
127
+ })
128
+ if (options.signal) {
129
+ onAbort = () => finish(false)
130
+ options.signal.addEventListener("abort", onAbort)
131
+ }
132
+ timeout = setTimeout(() => finish(projectTargetReady(options)), timeoutMs)
133
+ })
134
+ }
135
+
63
136
  export type PairingReadinessSnapshot = ReturnType<typeof projectReadiness>
64
137
 
65
138
  export async function submitPairingBootTimeoutReport(params: {
@@ -108,12 +181,7 @@ async function waitForReadyDuringPairing(options: PairingReadyWaitOptions = {}):
108
181
  })
109
182
 
110
183
  try {
111
- const ready = await waitForGlassesReady({
112
- getConnection: () => useGlassesStore.getState().connection,
113
- subscribe: (listener) => useGlassesStore.subscribe((state) => state.connection, listener),
114
- timeoutMs,
115
- signal: options.signal,
116
- })
184
+ const ready = await waitForTargetReady(options, timeoutMs)
117
185
 
118
186
  if (!ready && !options.signal?.aborted) {
119
187
  void submitPairingBootTimeoutReport({
@@ -193,6 +261,14 @@ export const pairing = {
193
261
  cb(snap)
194
262
  })
195
263
  },
264
+ /** Whether the exact wearable or controller selected on the scan screen is ready. */
265
+ targetReady: (options: Pick<PairingReadyWaitOptions, "deviceModel" | "deviceName">): boolean =>
266
+ projectTargetReady(options),
267
+ /** Subscribe to readiness for the exact selected target, excluding stale devices. */
268
+ onTargetReady: (
269
+ options: Pick<PairingReadyWaitOptions, "deviceModel" | "deviceName">,
270
+ cb: (ready: boolean) => void,
271
+ ): (() => void) => subscribeTargetReady(options, cb),
196
272
 
197
273
  // --- pairing-identity lifecycle (the PairingIdentity read-model + the JS-owned
198
274
  // identity writes; promotion to `paired` only ever happens natively) ---
@@ -12,9 +12,9 @@ export interface EngineReleaseMetadata {
12
12
  export const ENGINE_RELEASE_METADATA: Readonly<EngineReleaseMetadata> = Object.freeze({
13
13
  "schemaVersion": 1,
14
14
  "familyBaseVersion": "3.1.0",
15
- "releaseIdentity": "3.1.0-dev.9",
16
- "releaseSetId": "mentra-3.1.0-dev.9",
17
- "sourceCommit": "24201a3bb26253c4ce435d1fc125b0164774ebec",
18
- "otaManifestUrl": "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-v3.1.0-dev.9/mentra-live-ota-3.1.0-dev.9.json",
19
- "otaManifestSha256": "214d92c8894033eaab276e668cb553c79990005d3330d23aaf499a514dc08cff"
15
+ "releaseIdentity": "3.1.0-dev.94",
16
+ "releaseSetId": "mentra-3.1.0-dev.94",
17
+ "sourceCommit": "bf3af209501b232b997ab25e2b8341e7bfba79f9",
18
+ "otaManifestUrl": "https://github.com/Mentra-Community/MentraOS/releases/download/mentra-builds-v3.1.0/mentra-live-ota-3.1.0-dev.94.json",
19
+ "otaManifestSha256": "1770ca3bbd0af3d586c7869826d93d98475070b6e5cf5f81a9b5be9bd1227c6c"
20
20
  })
package/src/index.ts CHANGED
@@ -89,6 +89,7 @@ export {
89
89
  GLOBAL_OTA_TIMEOUT_MS,
90
90
  PING_INTERVAL_MS,
91
91
  QUERY_REPLY_TIMEOUT_MS,
92
+ BES_RESTART_TIMEOUT_MS,
92
93
  OtaProgressMessages,
93
94
  } from "./services/otaInstallPolicy"
94
95
  export {deriveDisplayState} from "./services/otaDisplayState"
@@ -98,6 +99,7 @@ export type {
98
99
  OtaProgressStatus,
99
100
  OtaStatus,
100
101
  OtaUpdateInfo,
102
+ ReleaseChangelog,
101
103
  OtaSnapshot,
102
104
  OtaInstallSnapshot,
103
105
  } from "./facades/ota"