@mentra/engine 3.1.0-dev.4 → 3.1.0-dev.40

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 (103) hide show
  1. package/README.md +19 -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 +9 -6
  9. package/build/facades/ota.d.ts.map +1 -1
  10. package/build/facades/ota.js +6 -4
  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 +1 -1
  19. package/build/index.d.ts.map +1 -1
  20. package/build/index.js.map +1 -1
  21. package/build/react/MentraLiveOtaFlow.d.ts +3 -2
  22. package/build/react/MentraLiveOtaFlow.d.ts.map +1 -1
  23. package/build/react/MentraLiveOtaFlow.js +113 -352
  24. package/build/react/MentraLiveOtaFlow.js.map +1 -1
  25. package/build/react/index.d.ts +1 -0
  26. package/build/react/index.d.ts.map +1 -1
  27. package/build/react/index.js +1 -0
  28. package/build/react/index.js.map +1 -1
  29. package/build/react/useMentraLiveOta.d.ts +80 -0
  30. package/build/react/useMentraLiveOta.d.ts.map +1 -0
  31. package/build/react/useMentraLiveOta.js +550 -0
  32. package/build/react/useMentraLiveOta.js.map +1 -0
  33. package/build/services/BlobStore.d.ts +2 -0
  34. package/build/services/BlobStore.d.ts.map +1 -1
  35. package/build/services/BlobStore.js +63 -10
  36. package/build/services/BlobStore.js.map +1 -1
  37. package/build/services/GlassesStatusProjection.d.ts +15 -2
  38. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  39. package/build/services/GlassesStatusProjection.js +3 -3
  40. package/build/services/GlassesStatusProjection.js.map +1 -1
  41. package/build/services/HotspotOtaTransport.d.ts.map +1 -1
  42. package/build/services/HotspotOtaTransport.js +8 -7
  43. package/build/services/HotspotOtaTransport.js.map +1 -1
  44. package/build/services/OtaAutoChain.d.ts +9 -2
  45. package/build/services/OtaAutoChain.d.ts.map +1 -1
  46. package/build/services/OtaAutoChain.js +10 -2
  47. package/build/services/OtaAutoChain.js.map +1 -1
  48. package/build/services/OtaInstallCoordinator.d.ts +24 -3
  49. package/build/services/OtaInstallCoordinator.d.ts.map +1 -1
  50. package/build/services/OtaInstallCoordinator.js +14 -12
  51. package/build/services/OtaInstallCoordinator.js.map +1 -1
  52. package/build/services/OtaService.d.ts.map +1 -1
  53. package/build/services/OtaService.js +1 -1
  54. package/build/services/OtaService.js.map +1 -1
  55. package/build/services/OtaUpdateCheckService.d.ts +4 -1
  56. package/build/services/OtaUpdateCheckService.d.ts.map +1 -1
  57. package/build/services/OtaUpdateCheckService.js +21 -5
  58. package/build/services/OtaUpdateCheckService.js.map +1 -1
  59. package/build/services/asg/localNetworkTransport.d.ts.map +1 -1
  60. package/build/services/asg/localNetworkTransport.js +13 -12
  61. package/build/services/asg/localNetworkTransport.js.map +1 -1
  62. package/build/services/glassesClockSync.js +1 -1
  63. package/build/services/glassesClockSync.js.map +1 -1
  64. package/build/services/otaReleaseVersion.d.ts +10 -0
  65. package/build/services/otaReleaseVersion.d.ts.map +1 -0
  66. package/build/services/otaReleaseVersion.js +14 -0
  67. package/build/services/otaReleaseVersion.js.map +1 -0
  68. package/build/stores/appVisibility.d.ts +3 -0
  69. package/build/stores/appVisibility.d.ts.map +1 -0
  70. package/build/stores/appVisibility.js +3 -0
  71. package/build/stores/appVisibility.js.map +1 -0
  72. package/build/stores/apps.d.ts.map +1 -1
  73. package/build/stores/apps.js +7 -1
  74. package/build/stores/apps.js.map +1 -1
  75. package/build/stores/core.d.ts +3 -3
  76. package/build/stores/core.d.ts.map +1 -1
  77. package/build/stores/core.js.map +1 -1
  78. package/build/stores/glasses.d.ts +10 -4
  79. package/build/stores/glasses.d.ts.map +1 -1
  80. package/build/stores/glasses.js.map +1 -1
  81. package/package.json +12 -6
  82. package/src/bluetooth-sdk/ota-transport.ts +1 -0
  83. package/src/facades/ota.ts +16 -5
  84. package/src/facades/pairing.ts +88 -12
  85. package/src/generated/releaseMetadata.ts +5 -5
  86. package/src/index.ts +1 -0
  87. package/src/react/MentraLiveOtaFlow.tsx +178 -465
  88. package/src/react/index.ts +14 -0
  89. package/src/react/useMentraLiveOta.ts +707 -0
  90. package/src/services/BlobStore.ts +57 -10
  91. package/src/services/GlassesStatusProjection.ts +7 -6
  92. package/src/services/HotspotOtaTransport.ts +8 -7
  93. package/src/services/OtaAutoChain.ts +26 -2
  94. package/src/services/OtaInstallCoordinator.ts +16 -13
  95. package/src/services/OtaService.ts +1 -2
  96. package/src/services/OtaUpdateCheckService.ts +26 -8
  97. package/src/services/asg/localNetworkTransport.ts +20 -19
  98. package/src/services/glassesClockSync.ts +1 -1
  99. package/src/services/otaReleaseVersion.ts +22 -0
  100. package/src/stores/appVisibility.ts +3 -0
  101. package/src/stores/apps.ts +7 -1
  102. package/src/stores/core.ts +4 -4
  103. package/src/stores/glasses.ts +13 -6
@@ -0,0 +1,550 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { ota } from "../facades/ota";
3
+ import { beginOtaAutoChain, clearOtaAutoChainReconnectWait, isOtaAutoChainActive, otaAutoChainFingerprint, otaAutoChainReleaseRange, otaAutoChainReconnectWaitRemaining, stopOtaAutoChain, tryAdvanceOtaAutoChain, } from "../services/OtaAutoChain";
4
+ import { BES_INSTALL_RESTART_MESSAGE, getOtaErrorMessage, shouldRequireGlassesRebootForBesFailure, shouldShowChangeWifiForOtaDownloadFailure, } from "../services/OtaErrorMapping";
5
+ import { useEngineSnapshot } from "./useEngineSnapshot";
6
+ const AUTO_CHAIN_NETWORK_RETRY_DELAY_MS = 5000;
7
+ const AUTO_CHAIN_COMPLETE_DELAY_MS = 750;
8
+ function releaseRangeTargetVersion(result) {
9
+ return result.releaseVersion ?? result.updateInfo?.versionName ?? result.latestVersionInfo?.versionName ?? null;
10
+ }
11
+ function currentReleaseVersion(appVersion) {
12
+ const version = appVersion?.trim();
13
+ return version || null;
14
+ }
15
+ function releaseTransitionFromRange(range) {
16
+ if (!range?.releaseVersion)
17
+ return null;
18
+ return { fromVersion: range.fromVersion, toVersion: range.releaseVersion };
19
+ }
20
+ function releaseChangelogsForActiveChain() {
21
+ const range = otaAutoChainReleaseRange();
22
+ if (!range?.toVersion)
23
+ return [];
24
+ try {
25
+ return ota.getReleaseChangelogs(range.fromVersion, range.toVersion);
26
+ }
27
+ catch {
28
+ try {
29
+ return ota.getReleaseChangelogs(null, range.toVersion);
30
+ }
31
+ catch {
32
+ return [];
33
+ }
34
+ }
35
+ }
36
+ function installProgress(snapshot) {
37
+ if (snapshot.displayState !== "updating")
38
+ return null;
39
+ const { otaStatus } = snapshot;
40
+ const isDownload = otaStatus?.phase === "download";
41
+ const totalSteps = otaStatus?.totalSteps ?? 1;
42
+ const rawPercent = isDownload
43
+ ? otaStatus?.stepPercent ?? 0
44
+ : totalSteps >= 2
45
+ ? otaStatus?.overallPercent ?? 0
46
+ : otaStatus?.stepPercent ?? 0;
47
+ return Math.min(Math.max(rawPercent, snapshot.mtkInstallStallSimulatedPercent ?? 0, 0), 100);
48
+ }
49
+ function progressScreen(snapshot) {
50
+ if (snapshot.versionChangePhase === "restarting")
51
+ return "restarting";
52
+ if (snapshot.versionChangePhase === "verifying")
53
+ return "verifying";
54
+ switch (snapshot.displayState) {
55
+ case "starting":
56
+ return snapshot.hotspotPhase === "idle" || snapshot.hotspotPhase === "serving" ? "starting" : "preparing_hotspot";
57
+ case "updating":
58
+ return "updating";
59
+ case "restarting":
60
+ return "restarting";
61
+ case "complete":
62
+ return "complete";
63
+ case "failed":
64
+ return "failed";
65
+ default:
66
+ return "disconnected";
67
+ }
68
+ }
69
+ /**
70
+ * Headless Mentra Live OTA flow. Engine owns checking, hotspot staging,
71
+ * APK/MTK/BES sequencing, restart recovery, retries, and verification; the host
72
+ * renders semantic state and invokes these idempotent actions.
73
+ */
74
+ export function useMentraLiveOta(options = {}) {
75
+ const { initialPage = "check", initializeRuntime = true, onFinished, onFirmwareRestartingChange, onOpenWifiSetup, } = options;
76
+ const otaSnapshot = useEngineSnapshot(ota.snapshot, ota.onSnapshot);
77
+ const installSnapshot = useEngineSnapshot(ota.installSession.snapshot, ota.installSession.onSnapshot);
78
+ const [page, setPage] = useState(initialPage);
79
+ const [runtimeReady, setRuntimeReady] = useState(!initializeRuntime);
80
+ const [checkState, setCheckState] = useState("checking");
81
+ const [isUpdateRequired, setIsUpdateRequired] = useState(true);
82
+ const [isVersionChange, setIsVersionChange] = useState(false);
83
+ const [errorKind, setErrorKind] = useState("network");
84
+ const [updateFingerprint, setUpdateFingerprint] = useState(null);
85
+ const [offeredReleaseTransition, setOfferedReleaseTransition] = useState(null);
86
+ const [completedReleaseTransition, setCompletedReleaseTransition] = useState(null);
87
+ const [completedChangelogs, setCompletedChangelogs] = useState([]);
88
+ const [checkGeneration, setCheckGeneration] = useState(0);
89
+ const performCheckGenerationRef = useRef(0);
90
+ const activeCheckKeyRef = useRef(null);
91
+ const checkStartedRef = useRef(false);
92
+ const checkCompletedRef = useRef(false);
93
+ const selectedCheckResultRef = useRef(null);
94
+ const autoChainAdvancedRef = useRef(false);
95
+ const installActionPendingRef = useRef(false);
96
+ const onFinishedRef = useRef(onFinished);
97
+ const onOpenWifiSetupRef = useRef(onOpenWifiSetup);
98
+ const onFirmwareRestartingChangeRef = useRef(onFirmwareRestartingChange);
99
+ onFinishedRef.current = onFinished;
100
+ onOpenWifiSetupRef.current = onOpenWifiSetup;
101
+ onFirmwareRestartingChangeRef.current = onFirmwareRestartingChange;
102
+ useEffect(() => {
103
+ if (!initializeRuntime) {
104
+ setRuntimeReady(true);
105
+ return;
106
+ }
107
+ let cancelled = false;
108
+ setRuntimeReady(false);
109
+ void ota.initialize().finally(() => {
110
+ if (!cancelled)
111
+ setRuntimeReady(true);
112
+ });
113
+ return () => {
114
+ cancelled = true;
115
+ };
116
+ }, [initializeRuntime]);
117
+ const returnToCheck = useCallback(() => {
118
+ installActionPendingRef.current = false;
119
+ autoChainAdvancedRef.current = false;
120
+ setPage("check");
121
+ setCheckGeneration((generation) => generation + 1);
122
+ }, []);
123
+ const navigateToProgress = useCallback(() => {
124
+ installActionPendingRef.current = true;
125
+ ota.clearProgress();
126
+ setPage("progress");
127
+ }, []);
128
+ useEffect(() => {
129
+ if (!runtimeReady || page !== "check")
130
+ return;
131
+ const MIN_DISPLAY_TIME_MS = 1100;
132
+ const MAX_WAIT_FOR_VERSION_INFO_MS = 10_000;
133
+ const checkKey = String(checkGeneration);
134
+ if (activeCheckKeyRef.current !== checkKey) {
135
+ activeCheckKeyRef.current = checkKey;
136
+ checkStartedRef.current = false;
137
+ checkCompletedRef.current = false;
138
+ selectedCheckResultRef.current = null;
139
+ installActionPendingRef.current = false;
140
+ setCheckState("checking");
141
+ }
142
+ const myGeneration = ++performCheckGenerationRef.current;
143
+ let cancelled = false;
144
+ let reconnectTimeout = null;
145
+ const performCheck = async () => {
146
+ if (checkCompletedRef.current)
147
+ return;
148
+ if (!otaSnapshot.connected) {
149
+ if (isOtaAutoChainActive()) {
150
+ const remainingMs = otaAutoChainReconnectWaitRemaining();
151
+ if (remainingMs === null)
152
+ return;
153
+ reconnectTimeout = setTimeout(() => {
154
+ if (cancelled || myGeneration !== performCheckGenerationRef.current || ota.snapshot().connected)
155
+ return;
156
+ stopOtaAutoChain();
157
+ checkCompletedRef.current = true;
158
+ setCheckState("error");
159
+ }, remainingMs);
160
+ return;
161
+ }
162
+ if (checkStartedRef.current) {
163
+ stopOtaAutoChain();
164
+ checkCompletedRef.current = true;
165
+ setCheckState("error");
166
+ return;
167
+ }
168
+ checkCompletedRef.current = true;
169
+ onFinishedRef.current?.();
170
+ return;
171
+ }
172
+ clearOtaAutoChainReconnectWait();
173
+ checkStartedRef.current = true;
174
+ const startTime = Date.now();
175
+ try {
176
+ const checkOptions = {
177
+ waitForBuildNumberMs: MAX_WAIT_FOR_VERSION_INFO_MS,
178
+ waitForBesVersionMs: 5000,
179
+ waitForMtkVersionMs: 2000,
180
+ refreshVersionInfo: true,
181
+ fixClockBeforeCheck: false,
182
+ };
183
+ let result = await ota.checkForUpdates(checkOptions);
184
+ if (cancelled || myGeneration !== performCheckGenerationRef.current)
185
+ return;
186
+ if (!result.hasCheckCompleted && result.checkFailureReason === "network" && isOtaAutoChainActive()) {
187
+ await new Promise((resolve) => setTimeout(resolve, AUTO_CHAIN_NETWORK_RETRY_DELAY_MS));
188
+ if (cancelled || myGeneration !== performCheckGenerationRef.current)
189
+ return;
190
+ result = await ota.checkForUpdates(checkOptions);
191
+ }
192
+ if (cancelled || myGeneration !== performCheckGenerationRef.current)
193
+ return;
194
+ selectedCheckResultRef.current = result;
195
+ await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))));
196
+ if (cancelled || myGeneration !== performCheckGenerationRef.current)
197
+ return;
198
+ if (result.skippedReason === "disconnected") {
199
+ stopOtaAutoChain();
200
+ checkCompletedRef.current = true;
201
+ setCheckState("error");
202
+ return;
203
+ }
204
+ if (result.skippedReason === "missing_build") {
205
+ checkCompletedRef.current = true;
206
+ if (isOtaAutoChainActive()) {
207
+ stopOtaAutoChain();
208
+ setCheckState("error");
209
+ }
210
+ else {
211
+ onFinishedRef.current?.();
212
+ }
213
+ return;
214
+ }
215
+ if (result.skippedReason === "dev_build") {
216
+ stopOtaAutoChain();
217
+ checkCompletedRef.current = true;
218
+ ota.clearUpdateAvailable();
219
+ setCheckState("dev_build");
220
+ return;
221
+ }
222
+ if (!result.hasCheckCompleted) {
223
+ stopOtaAutoChain();
224
+ checkCompletedRef.current = true;
225
+ setErrorKind(result.checkFailureReason === "pin_unavailable" ? "pin_unavailable" : "network");
226
+ setCheckState("error");
227
+ return;
228
+ }
229
+ if (result.updateAvailable && result.updateInfo) {
230
+ setIsUpdateRequired(result.isRequired);
231
+ setIsVersionChange(result.updateInfo.isDowngrade === true);
232
+ const fingerprint = otaAutoChainFingerprint(result);
233
+ setUpdateFingerprint(fingerprint);
234
+ if (!isOtaAutoChainActive()) {
235
+ const fromVersion = currentReleaseVersion(ota.snapshot().appVersion);
236
+ setOfferedReleaseTransition(result.releaseVersion ? { fromVersion, toVersion: result.releaseVersion } : null);
237
+ }
238
+ if (isOtaAutoChainActive()) {
239
+ const snapshot = ota.snapshot();
240
+ if (!snapshot.wifiStatusKnown)
241
+ return;
242
+ if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {
243
+ stopOtaAutoChain();
244
+ }
245
+ else {
246
+ const admission = tryAdvanceOtaAutoChain(fingerprint, result.updateInfo.isDowngrade === true, releaseRangeTargetVersion(result), result.releaseVersion);
247
+ if (admission.advance) {
248
+ checkCompletedRef.current = true;
249
+ ota.installSession.prepare(result);
250
+ navigateToProgress();
251
+ return;
252
+ }
253
+ }
254
+ }
255
+ checkCompletedRef.current = true;
256
+ setCheckState("update_available");
257
+ return;
258
+ }
259
+ if (isOtaAutoChainActive()) {
260
+ setCompletedChangelogs(releaseChangelogsForActiveChain());
261
+ setCompletedReleaseTransition(releaseTransitionFromRange(otaAutoChainReleaseRange()));
262
+ }
263
+ stopOtaAutoChain();
264
+ checkCompletedRef.current = true;
265
+ ota.clearUpdateAvailable();
266
+ setCheckState("no_update");
267
+ }
268
+ catch (error) {
269
+ console.error("OTA check failed:", error);
270
+ await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))));
271
+ if (cancelled || myGeneration !== performCheckGenerationRef.current)
272
+ return;
273
+ stopOtaAutoChain();
274
+ checkCompletedRef.current = true;
275
+ setErrorKind("network");
276
+ setCheckState("error");
277
+ }
278
+ };
279
+ void performCheck();
280
+ return () => {
281
+ cancelled = true;
282
+ if (reconnectTimeout)
283
+ clearTimeout(reconnectTimeout);
284
+ };
285
+ }, [checkGeneration, navigateToProgress, otaSnapshot.connected, otaSnapshot.wifiStatusKnown, page, runtimeReady]);
286
+ useEffect(() => {
287
+ if (!runtimeReady || page !== "progress")
288
+ return;
289
+ ota.installSession.attach();
290
+ return () => ota.installSession.detach();
291
+ }, [page, runtimeReady]);
292
+ const firmwareRestarting = page === "progress" &&
293
+ ((!installSnapshot.connected && installSnapshot.displayState === "restarting") ||
294
+ installSnapshot.versionChangePhase === "restarting");
295
+ useEffect(() => {
296
+ if (page !== "progress")
297
+ return;
298
+ onFirmwareRestartingChangeRef.current?.(firmwareRestarting, true);
299
+ }, [firmwareRestarting, page]);
300
+ useEffect(() => {
301
+ if (page !== "progress")
302
+ return;
303
+ return () => {
304
+ onFirmwareRestartingChangeRef.current?.(false, false);
305
+ };
306
+ }, [page]);
307
+ useEffect(() => {
308
+ if (page !== "progress" ||
309
+ installSnapshot.displayState !== "complete" ||
310
+ !installSnapshot.connected ||
311
+ !isOtaAutoChainActive() ||
312
+ autoChainAdvancedRef.current) {
313
+ return;
314
+ }
315
+ const timeout = setTimeout(async () => {
316
+ if (!isOtaAutoChainActive())
317
+ return;
318
+ autoChainAdvancedRef.current = true;
319
+ await ota.installSession.finish();
320
+ returnToCheck();
321
+ }, AUTO_CHAIN_COMPLETE_DELAY_MS);
322
+ return () => clearTimeout(timeout);
323
+ }, [installSnapshot.connected, installSnapshot.displayState, page, returnToCheck]);
324
+ const check = useCallback(() => {
325
+ setOfferedReleaseTransition(null);
326
+ setCompletedReleaseTransition(null);
327
+ setCompletedChangelogs([]);
328
+ setPage("check");
329
+ setCheckState("checking");
330
+ setCheckGeneration((generation) => generation + 1);
331
+ }, []);
332
+ const install = useCallback(() => {
333
+ if (installActionPendingRef.current || page !== "check")
334
+ return;
335
+ const result = selectedCheckResultRef.current;
336
+ if (!result) {
337
+ setErrorKind("network");
338
+ setCheckState("error");
339
+ return;
340
+ }
341
+ const snapshot = ota.snapshot();
342
+ if (!snapshot.wifiStatusKnown) {
343
+ check();
344
+ return;
345
+ }
346
+ if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {
347
+ onOpenWifiSetupRef.current?.();
348
+ return;
349
+ }
350
+ ota.installSession.prepare(result);
351
+ setCompletedChangelogs([]);
352
+ if (updateFingerprint) {
353
+ const fromVersion = offeredReleaseTransition
354
+ ? offeredReleaseTransition.fromVersion
355
+ : currentReleaseVersion(snapshot.appVersion);
356
+ beginOtaAutoChain(updateFingerprint, isVersionChange, {
357
+ fromVersion,
358
+ toVersion: releaseRangeTargetVersion(result),
359
+ releaseVersion: result.releaseVersion,
360
+ });
361
+ }
362
+ navigateToProgress();
363
+ }, [check, isVersionChange, navigateToProgress, offeredReleaseTransition, page, updateFingerprint]);
364
+ const retryInstall = useCallback(() => {
365
+ if (page !== "progress")
366
+ return;
367
+ onFirmwareRestartingChangeRef.current?.(false, true);
368
+ ota.installSession.retry();
369
+ }, [page]);
370
+ const finish = useCallback(async () => {
371
+ if (page === "check") {
372
+ onFinishedRef.current?.();
373
+ return;
374
+ }
375
+ if (installSnapshot.displayState === "restarting")
376
+ stopOtaAutoChain();
377
+ const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(installSnapshot.otaStatus, installSnapshot.otaProgress, installSnapshot.errorMsg);
378
+ if (requiresGlassesReboot)
379
+ stopOtaAutoChain();
380
+ await ota.installSession.finish();
381
+ returnToCheck();
382
+ }, [installSnapshot, page, returnToCheck]);
383
+ const discard = useCallback(async () => {
384
+ if (page !== "progress")
385
+ return;
386
+ stopOtaAutoChain();
387
+ await ota.installSession.discard();
388
+ returnToCheck();
389
+ }, [page, returnToCheck]);
390
+ const openWifiSetup = useCallback(() => {
391
+ if (page === "progress")
392
+ stopOtaAutoChain();
393
+ onOpenWifiSetupRef.current?.();
394
+ }, [page]);
395
+ const state = useMemo(() => {
396
+ const hotspotSupported = otaSnapshot.hotspotOtaVersion === 1;
397
+ const canInstall = otaSnapshot.wifiStatusKnown && (otaSnapshot.wifiConnected || hotspotSupported);
398
+ if (!runtimeReady) {
399
+ return {
400
+ screen: "initializing",
401
+ connected: otaSnapshot.connected,
402
+ transport: null,
403
+ updateRequired: isUpdateRequired,
404
+ versionChange: isVersionChange,
405
+ versionChangeConverged: false,
406
+ versionChangePhase: null,
407
+ wifiConnected: otaSnapshot.wifiConnected,
408
+ wifiStatusKnown: otaSnapshot.wifiStatusKnown,
409
+ hotspotSupported,
410
+ hotspotPhase: "idle",
411
+ hotspotArtifactPercent: null,
412
+ phase: null,
413
+ step: null,
414
+ currentStep: null,
415
+ totalSteps: null,
416
+ progress: null,
417
+ installingApkOnly: false,
418
+ firmwareRestarting: false,
419
+ error: null,
420
+ canInstall: false,
421
+ canRetry: false,
422
+ canFinish: false,
423
+ canDismiss: false,
424
+ canDiscard: false,
425
+ canOpenWifiSetup: false,
426
+ continueDisabled: false,
427
+ releaseTransition: null,
428
+ changelogs: [],
429
+ };
430
+ }
431
+ if (page === "check") {
432
+ const wifiRequired = otaSnapshot.wifiStatusKnown && !otaSnapshot.wifiConnected && !hotspotSupported;
433
+ const screen = checkState === "checking"
434
+ ? "checking"
435
+ : checkState === "update_available"
436
+ ? wifiRequired
437
+ ? "wifi_required"
438
+ : "update_available"
439
+ : checkState === "no_update"
440
+ ? "up_to_date"
441
+ : checkState === "dev_build"
442
+ ? "dev_build"
443
+ : errorKind === "pin_unavailable"
444
+ ? "update_info_unavailable"
445
+ : "check_failed";
446
+ const error = screen === "check_failed"
447
+ ? { code: "check_failed", message: "Couldn't check for updates. Please check your connection and try again." }
448
+ : screen === "update_info_unavailable"
449
+ ? { code: "update_info_unavailable", message: "Update information for this app version is unavailable." }
450
+ : null;
451
+ return {
452
+ screen,
453
+ connected: otaSnapshot.connected,
454
+ transport: otaSnapshot.wifiConnected ? "wifi" : hotspotSupported ? "hotspot" : null,
455
+ updateRequired: isUpdateRequired,
456
+ versionChange: isVersionChange,
457
+ versionChangeConverged: false,
458
+ versionChangePhase: null,
459
+ wifiConnected: otaSnapshot.wifiConnected,
460
+ wifiStatusKnown: otaSnapshot.wifiStatusKnown,
461
+ hotspotSupported,
462
+ hotspotPhase: "idle",
463
+ hotspotArtifactPercent: null,
464
+ phase: null,
465
+ step: null,
466
+ currentStep: null,
467
+ totalSteps: null,
468
+ progress: null,
469
+ installingApkOnly: false,
470
+ firmwareRestarting: false,
471
+ error,
472
+ canInstall: screen === "update_available" && canInstall,
473
+ canRetry: screen === "check_failed",
474
+ canFinish: screen === "up_to_date" || screen === "dev_build" || screen === "update_info_unavailable",
475
+ canDismiss: (screen === "update_available" || screen === "wifi_required") && !isUpdateRequired,
476
+ canDiscard: false,
477
+ canOpenWifiSetup: screen === "wifi_required",
478
+ continueDisabled: false,
479
+ releaseTransition: screen === "update_available" || screen === "wifi_required"
480
+ ? offeredReleaseTransition
481
+ : screen === "up_to_date"
482
+ ? completedReleaseTransition
483
+ : null,
484
+ changelogs: screen === "up_to_date" ? completedChangelogs : [],
485
+ };
486
+ }
487
+ const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(installSnapshot.otaStatus, installSnapshot.otaProgress, installSnapshot.errorMsg);
488
+ const showChangeWifi = shouldShowChangeWifiForOtaDownloadFailure(installSnapshot.otaStatus, installSnapshot.otaProgress, installSnapshot.errorMsg);
489
+ const displayedError = requiresGlassesReboot
490
+ ? BES_INSTALL_RESTART_MESSAGE
491
+ : installSnapshot.errorMsg || getOtaErrorMessage(installSnapshot.otaStatus?.error);
492
+ const screen = progressScreen(installSnapshot);
493
+ const error = screen === "failed"
494
+ ? {
495
+ code: requiresGlassesReboot ? "bes_restart_required" : "install_failed",
496
+ message: displayedError,
497
+ }
498
+ : null;
499
+ const totalSteps = installSnapshot.otaStatus?.totalSteps ?? null;
500
+ const changelogs = screen === "complete" ? releaseChangelogsForActiveChain() : [];
501
+ return {
502
+ screen,
503
+ connected: installSnapshot.connected,
504
+ transport: installSnapshot.transport,
505
+ updateRequired: isUpdateRequired,
506
+ versionChange: installSnapshot.isVersionChange,
507
+ versionChangeConverged: installSnapshot.versionChangeConverged,
508
+ versionChangePhase: installSnapshot.versionChangePhase,
509
+ wifiConnected: otaSnapshot.wifiConnected,
510
+ wifiStatusKnown: otaSnapshot.wifiStatusKnown,
511
+ hotspotSupported,
512
+ hotspotPhase: installSnapshot.hotspotPhase,
513
+ hotspotArtifactPercent: installSnapshot.hotspotArtifactPercent,
514
+ phase: installSnapshot.otaStatus?.phase ?? installSnapshot.otaProgress?.stage ?? null,
515
+ step: installSnapshot.otaStatus?.stepType ?? null,
516
+ currentStep: installSnapshot.otaStatus?.currentStep ?? null,
517
+ totalSteps,
518
+ progress: installProgress(installSnapshot),
519
+ installingApkOnly: installSnapshot.otaStatus?.stepType === "apk" &&
520
+ installSnapshot.otaStatus.phase === "install" &&
521
+ totalSteps === 1,
522
+ firmwareRestarting,
523
+ error,
524
+ canInstall: false,
525
+ canRetry: screen === "failed" && !requiresGlassesReboot,
526
+ canFinish: screen === "complete" || screen === "restarting" || (screen === "failed" && requiresGlassesReboot),
527
+ canDismiss: false,
528
+ canDiscard: screen === "disconnected",
529
+ canOpenWifiSetup: screen === "failed" && showChangeWifi,
530
+ continueDisabled: installSnapshot.continueButtonDisabled,
531
+ releaseTransition: releaseTransitionFromRange(otaAutoChainReleaseRange()),
532
+ changelogs,
533
+ };
534
+ }, [
535
+ checkState,
536
+ completedChangelogs,
537
+ completedReleaseTransition,
538
+ errorKind,
539
+ firmwareRestarting,
540
+ installSnapshot,
541
+ isUpdateRequired,
542
+ isVersionChange,
543
+ otaSnapshot,
544
+ offeredReleaseTransition,
545
+ page,
546
+ runtimeReady,
547
+ ]);
548
+ return useMemo(() => ({ state, check, retryCheck: check, install, retryInstall, finish, discard, openWifiSetup }), [check, discard, finish, install, openWifiSetup, retryInstall, state]);
549
+ }
550
+ //# sourceMappingURL=useMentraLiveOta.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMentraLiveOta.js","sourceRoot":"","sources":["../../src/react/useMentraLiveOta.ts"],"names":[],"mappings":"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","sourcesContent":["import {useCallback, useEffect, useMemo, useRef, useState} from \"react\"\n\nimport {ota} from \"../facades/ota\"\nimport {\n beginOtaAutoChain,\n clearOtaAutoChainReconnectWait,\n isOtaAutoChainActive,\n otaAutoChainFingerprint,\n otaAutoChainReleaseRange,\n otaAutoChainReconnectWaitRemaining,\n stopOtaAutoChain,\n tryAdvanceOtaAutoChain,\n type OtaAutoChainReleaseRange,\n} from \"../services/OtaAutoChain\"\nimport {\n BES_INSTALL_RESTART_MESSAGE,\n getOtaErrorMessage,\n shouldRequireGlassesRebootForBesFailure,\n shouldShowChangeWifiForOtaDownloadFailure,\n} from \"../services/OtaErrorMapping\"\nimport type {OtaInstallSnapshot} from \"../services/OtaInstallCoordinator\"\nimport type {OtaCheckCurrentGlassesResult} from \"../services/OtaUpdateCheckService\"\nimport type {ReleaseChangelog} from \"../facades/ota\"\nimport {useEngineSnapshot} from \"./useEngineSnapshot\"\n\nexport type MentraLiveOtaFlowPage = \"check\" | \"progress\"\n\nexport type MentraLiveOtaScreen =\n | \"initializing\"\n | \"checking\"\n | \"update_available\"\n | \"wifi_required\"\n | \"up_to_date\"\n | \"dev_build\"\n | \"check_failed\"\n | \"update_info_unavailable\"\n | \"starting\"\n | \"preparing_hotspot\"\n | \"updating\"\n | \"restarting\"\n | \"verifying\"\n | \"complete\"\n | \"failed\"\n | \"disconnected\"\n\nexport type MentraLiveOtaErrorCode =\n | \"check_failed\"\n | \"update_info_unavailable\"\n | \"install_failed\"\n | \"bes_restart_required\"\n\nexport type MentraLiveOtaError = {\n code: MentraLiveOtaErrorCode\n message: string\n}\n\nexport type MentraLiveOtaTransport = \"wifi\" | \"hotspot\"\nexport type MentraLiveOtaHotspotPhase = \"idle\" | \"downloading\" | \"starting_hotspot\" | \"joining_hotspot\" | \"serving\"\nexport type MentraLiveOtaInstallPhase = \"download\" | \"install\"\nexport type MentraLiveOtaStep = \"apk\" | \"mtk\" | \"bes\"\n\nexport type MentraLiveOtaReleaseTransition = {\n /** Current glasses software label. Temporarily backed by the reported ASG app version. */\n fromVersion: string | null\n /** Exact coordinated release identity for the selected OTA pin. */\n toVersion: string\n}\n\nexport type MentraLiveOtaState = {\n screen: MentraLiveOtaScreen\n connected: boolean\n transport: MentraLiveOtaTransport | null\n updateRequired: boolean\n versionChange: boolean\n versionChangeConverged: boolean\n versionChangePhase: \"installing\" | \"restarting\" | \"verifying\" | null\n wifiConnected: boolean\n wifiStatusKnown: boolean\n hotspotSupported: boolean\n hotspotPhase: MentraLiveOtaHotspotPhase\n hotspotArtifactPercent: number | null\n phase: MentraLiveOtaInstallPhase | null\n step: MentraLiveOtaStep | null\n currentStep: number | null\n totalSteps: number | null\n progress: number | null\n installingApkOnly: boolean\n firmwareRestarting: boolean\n error: MentraLiveOtaError | null\n canInstall: boolean\n canRetry: boolean\n canFinish: boolean\n canDismiss: boolean\n canDiscard: boolean\n canOpenWifiSetup: boolean\n continueDisabled: boolean\n /** Release labels for the offered or just-completed coordinated update. */\n releaseTransition: MentraLiveOtaReleaseTransition | null\n /** Release notes crossed by this update, newest first. Populated on completion. */\n changelogs: ReleaseChangelog[]\n}\n\nexport type UseMentraLiveOtaOptions = {\n /** Entry page. `progress` exists for interrupted-session recovery. */\n initialPage?: MentraLiveOtaFlowPage\n /** Start Engine's OTA-only projections. Full Engine hosts should pass false. */\n initializeRuntime?: boolean\n /** Called after the final check or when an optional update is dismissed. */\n onFinished?: () => void\n /** Host-owned Wi-Fi setup for glasses without hotspot OTA support. */\n onOpenWifiSetup?: () => void\n /** Lets a host coordinate its connection overlay with OTA firmware restarts. */\n onFirmwareRestartingChange?: (restarting: boolean, progressActive: boolean) => void\n}\n\nexport type MentraLiveOtaController = {\n state: MentraLiveOtaState\n check: () => void\n retryCheck: () => void\n install: () => void\n retryInstall: () => void\n finish: () => void\n discard: () => void\n openWifiSetup: () => void\n}\n\ntype CheckState = \"checking\" | \"update_available\" | \"no_update\" | \"dev_build\" | \"error\"\n\nconst AUTO_CHAIN_NETWORK_RETRY_DELAY_MS = 5000\nconst AUTO_CHAIN_COMPLETE_DELAY_MS = 750\n\nfunction releaseRangeTargetVersion(result: OtaCheckCurrentGlassesResult): string | null {\n return result.releaseVersion ?? result.updateInfo?.versionName ?? result.latestVersionInfo?.versionName ?? null\n}\n\nfunction currentReleaseVersion(appVersion: string | null): string | null {\n const version = appVersion?.trim()\n return version || null\n}\n\nfunction releaseTransitionFromRange(range: OtaAutoChainReleaseRange | null): MentraLiveOtaReleaseTransition | null {\n if (!range?.releaseVersion) return null\n return {fromVersion: range.fromVersion, toVersion: range.releaseVersion}\n}\n\nfunction releaseChangelogsForActiveChain(): ReleaseChangelog[] {\n const range = otaAutoChainReleaseRange()\n if (!range?.toVersion) return []\n try {\n return ota.getReleaseChangelogs(range.fromVersion, range.toVersion)\n } catch {\n try {\n return ota.getReleaseChangelogs(null, range.toVersion)\n } catch {\n return []\n }\n }\n}\n\nfunction installProgress(snapshot: OtaInstallSnapshot): number | null {\n if (snapshot.displayState !== \"updating\") return null\n const {otaStatus} = snapshot\n const isDownload = otaStatus?.phase === \"download\"\n const totalSteps = otaStatus?.totalSteps ?? 1\n const rawPercent = isDownload\n ? otaStatus?.stepPercent ?? 0\n : totalSteps >= 2\n ? otaStatus?.overallPercent ?? 0\n : otaStatus?.stepPercent ?? 0\n return Math.min(Math.max(rawPercent, snapshot.mtkInstallStallSimulatedPercent ?? 0, 0), 100)\n}\n\nfunction progressScreen(snapshot: OtaInstallSnapshot): MentraLiveOtaScreen {\n if (snapshot.versionChangePhase === \"restarting\") return \"restarting\"\n if (snapshot.versionChangePhase === \"verifying\") return \"verifying\"\n switch (snapshot.displayState) {\n case \"starting\":\n return snapshot.hotspotPhase === \"idle\" || snapshot.hotspotPhase === \"serving\" ? \"starting\" : \"preparing_hotspot\"\n case \"updating\":\n return \"updating\"\n case \"restarting\":\n return \"restarting\"\n case \"complete\":\n return \"complete\"\n case \"failed\":\n return \"failed\"\n default:\n return \"disconnected\"\n }\n}\n\n/**\n * Headless Mentra Live OTA flow. Engine owns checking, hotspot staging,\n * APK/MTK/BES sequencing, restart recovery, retries, and verification; the host\n * renders semantic state and invokes these idempotent actions.\n */\nexport function useMentraLiveOta(options: UseMentraLiveOtaOptions = {}): MentraLiveOtaController {\n const {\n initialPage = \"check\",\n initializeRuntime = true,\n onFinished,\n onFirmwareRestartingChange,\n onOpenWifiSetup,\n } = options\n const otaSnapshot = useEngineSnapshot(ota.snapshot, ota.onSnapshot)\n const installSnapshot = useEngineSnapshot(ota.installSession.snapshot, ota.installSession.onSnapshot)\n const [page, setPage] = useState<MentraLiveOtaFlowPage>(initialPage)\n const [runtimeReady, setRuntimeReady] = useState(!initializeRuntime)\n const [checkState, setCheckState] = useState<CheckState>(\"checking\")\n const [isUpdateRequired, setIsUpdateRequired] = useState(true)\n const [isVersionChange, setIsVersionChange] = useState(false)\n const [errorKind, setErrorKind] = useState<\"network\" | \"pin_unavailable\">(\"network\")\n const [updateFingerprint, setUpdateFingerprint] = useState<string | null>(null)\n const [offeredReleaseTransition, setOfferedReleaseTransition] = useState<MentraLiveOtaReleaseTransition | null>(null)\n const [completedReleaseTransition, setCompletedReleaseTransition] = useState<MentraLiveOtaReleaseTransition | null>(\n null,\n )\n const [completedChangelogs, setCompletedChangelogs] = useState<ReleaseChangelog[]>([])\n const [checkGeneration, setCheckGeneration] = useState(0)\n const performCheckGenerationRef = useRef(0)\n const activeCheckKeyRef = useRef<string | null>(null)\n const checkStartedRef = useRef(false)\n const checkCompletedRef = useRef(false)\n const selectedCheckResultRef = useRef<OtaCheckCurrentGlassesResult | null>(null)\n const autoChainAdvancedRef = useRef(false)\n const installActionPendingRef = useRef(false)\n const onFinishedRef = useRef(onFinished)\n const onOpenWifiSetupRef = useRef(onOpenWifiSetup)\n const onFirmwareRestartingChangeRef = useRef(onFirmwareRestartingChange)\n onFinishedRef.current = onFinished\n onOpenWifiSetupRef.current = onOpenWifiSetup\n onFirmwareRestartingChangeRef.current = onFirmwareRestartingChange\n\n useEffect(() => {\n if (!initializeRuntime) {\n setRuntimeReady(true)\n return\n }\n let cancelled = false\n setRuntimeReady(false)\n void ota.initialize().finally(() => {\n if (!cancelled) setRuntimeReady(true)\n })\n return () => {\n cancelled = true\n }\n }, [initializeRuntime])\n\n const returnToCheck = useCallback(() => {\n installActionPendingRef.current = false\n autoChainAdvancedRef.current = false\n setPage(\"check\")\n setCheckGeneration((generation) => generation + 1)\n }, [])\n\n const navigateToProgress = useCallback(() => {\n installActionPendingRef.current = true\n ota.clearProgress()\n setPage(\"progress\")\n }, [])\n\n useEffect(() => {\n if (!runtimeReady || page !== \"check\") return\n const MIN_DISPLAY_TIME_MS = 1100\n const MAX_WAIT_FOR_VERSION_INFO_MS = 10_000\n const checkKey = String(checkGeneration)\n if (activeCheckKeyRef.current !== checkKey) {\n activeCheckKeyRef.current = checkKey\n checkStartedRef.current = false\n checkCompletedRef.current = false\n selectedCheckResultRef.current = null\n installActionPendingRef.current = false\n setCheckState(\"checking\")\n }\n\n const myGeneration = ++performCheckGenerationRef.current\n let cancelled = false\n let reconnectTimeout: ReturnType<typeof setTimeout> | null = null\n\n const performCheck = async () => {\n if (checkCompletedRef.current) return\n if (!otaSnapshot.connected) {\n if (isOtaAutoChainActive()) {\n const remainingMs = otaAutoChainReconnectWaitRemaining()\n if (remainingMs === null) return\n reconnectTimeout = setTimeout(() => {\n if (cancelled || myGeneration !== performCheckGenerationRef.current || ota.snapshot().connected) return\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setCheckState(\"error\")\n }, remainingMs)\n return\n }\n if (checkStartedRef.current) {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setCheckState(\"error\")\n return\n }\n checkCompletedRef.current = true\n onFinishedRef.current?.()\n return\n }\n\n clearOtaAutoChainReconnectWait()\n checkStartedRef.current = true\n const startTime = Date.now()\n try {\n const checkOptions = {\n waitForBuildNumberMs: MAX_WAIT_FOR_VERSION_INFO_MS,\n waitForBesVersionMs: 5000,\n waitForMtkVersionMs: 2000,\n refreshVersionInfo: true,\n fixClockBeforeCheck: false,\n }\n let result = await ota.checkForUpdates(checkOptions)\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n if (!result.hasCheckCompleted && result.checkFailureReason === \"network\" && isOtaAutoChainActive()) {\n await new Promise((resolve) => setTimeout(resolve, AUTO_CHAIN_NETWORK_RETRY_DELAY_MS))\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n result = await ota.checkForUpdates(checkOptions)\n }\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n selectedCheckResultRef.current = result\n await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))))\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n\n if (result.skippedReason === \"disconnected\") {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setCheckState(\"error\")\n return\n }\n if (result.skippedReason === \"missing_build\") {\n checkCompletedRef.current = true\n if (isOtaAutoChainActive()) {\n stopOtaAutoChain()\n setCheckState(\"error\")\n } else {\n onFinishedRef.current?.()\n }\n return\n }\n if (result.skippedReason === \"dev_build\") {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n ota.clearUpdateAvailable()\n setCheckState(\"dev_build\")\n return\n }\n if (!result.hasCheckCompleted) {\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setErrorKind(result.checkFailureReason === \"pin_unavailable\" ? \"pin_unavailable\" : \"network\")\n setCheckState(\"error\")\n return\n }\n if (result.updateAvailable && result.updateInfo) {\n setIsUpdateRequired(result.isRequired)\n setIsVersionChange(result.updateInfo.isDowngrade === true)\n const fingerprint = otaAutoChainFingerprint(result)\n setUpdateFingerprint(fingerprint)\n if (!isOtaAutoChainActive()) {\n const fromVersion = currentReleaseVersion(ota.snapshot().appVersion)\n setOfferedReleaseTransition(result.releaseVersion ? {fromVersion, toVersion: result.releaseVersion} : null)\n }\n if (isOtaAutoChainActive()) {\n const snapshot = ota.snapshot()\n if (!snapshot.wifiStatusKnown) return\n if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {\n stopOtaAutoChain()\n } else {\n const admission = tryAdvanceOtaAutoChain(\n fingerprint,\n result.updateInfo.isDowngrade === true,\n releaseRangeTargetVersion(result),\n result.releaseVersion,\n )\n if (admission.advance) {\n checkCompletedRef.current = true\n ota.installSession.prepare(result)\n navigateToProgress()\n return\n }\n }\n }\n checkCompletedRef.current = true\n setCheckState(\"update_available\")\n return\n }\n if (isOtaAutoChainActive()) {\n setCompletedChangelogs(releaseChangelogsForActiveChain())\n setCompletedReleaseTransition(releaseTransitionFromRange(otaAutoChainReleaseRange()))\n }\n stopOtaAutoChain()\n checkCompletedRef.current = true\n ota.clearUpdateAvailable()\n setCheckState(\"no_update\")\n } catch (error) {\n console.error(\"OTA check failed:\", error)\n await new Promise((resolve) => setTimeout(resolve, Math.max(0, MIN_DISPLAY_TIME_MS - (Date.now() - startTime))))\n if (cancelled || myGeneration !== performCheckGenerationRef.current) return\n stopOtaAutoChain()\n checkCompletedRef.current = true\n setErrorKind(\"network\")\n setCheckState(\"error\")\n }\n }\n\n void performCheck()\n return () => {\n cancelled = true\n if (reconnectTimeout) clearTimeout(reconnectTimeout)\n }\n }, [checkGeneration, navigateToProgress, otaSnapshot.connected, otaSnapshot.wifiStatusKnown, page, runtimeReady])\n\n useEffect(() => {\n if (!runtimeReady || page !== \"progress\") return\n ota.installSession.attach()\n return () => ota.installSession.detach()\n }, [page, runtimeReady])\n\n const firmwareRestarting =\n page === \"progress\" &&\n ((!installSnapshot.connected && installSnapshot.displayState === \"restarting\") ||\n installSnapshot.versionChangePhase === \"restarting\")\n\n useEffect(() => {\n if (page !== \"progress\") return\n onFirmwareRestartingChangeRef.current?.(firmwareRestarting, true)\n }, [firmwareRestarting, page])\n\n useEffect(() => {\n if (page !== \"progress\") return\n return () => {\n onFirmwareRestartingChangeRef.current?.(false, false)\n }\n }, [page])\n\n useEffect(() => {\n if (\n page !== \"progress\" ||\n installSnapshot.displayState !== \"complete\" ||\n !installSnapshot.connected ||\n !isOtaAutoChainActive() ||\n autoChainAdvancedRef.current\n ) {\n return\n }\n const timeout = setTimeout(async () => {\n if (!isOtaAutoChainActive()) return\n autoChainAdvancedRef.current = true\n await ota.installSession.finish()\n returnToCheck()\n }, AUTO_CHAIN_COMPLETE_DELAY_MS)\n return () => clearTimeout(timeout)\n }, [installSnapshot.connected, installSnapshot.displayState, page, returnToCheck])\n\n const check = useCallback(() => {\n setOfferedReleaseTransition(null)\n setCompletedReleaseTransition(null)\n setCompletedChangelogs([])\n setPage(\"check\")\n setCheckState(\"checking\")\n setCheckGeneration((generation) => generation + 1)\n }, [])\n\n const install = useCallback(() => {\n if (installActionPendingRef.current || page !== \"check\") return\n const result = selectedCheckResultRef.current\n if (!result) {\n setErrorKind(\"network\")\n setCheckState(\"error\")\n return\n }\n const snapshot = ota.snapshot()\n if (!snapshot.wifiStatusKnown) {\n check()\n return\n }\n if (!snapshot.wifiConnected && snapshot.hotspotOtaVersion !== 1) {\n onOpenWifiSetupRef.current?.()\n return\n }\n ota.installSession.prepare(result)\n setCompletedChangelogs([])\n if (updateFingerprint) {\n const fromVersion = offeredReleaseTransition\n ? offeredReleaseTransition.fromVersion\n : currentReleaseVersion(snapshot.appVersion)\n beginOtaAutoChain(updateFingerprint, isVersionChange, {\n fromVersion,\n toVersion: releaseRangeTargetVersion(result),\n releaseVersion: result.releaseVersion,\n })\n }\n navigateToProgress()\n }, [check, isVersionChange, navigateToProgress, offeredReleaseTransition, page, updateFingerprint])\n\n const retryInstall = useCallback(() => {\n if (page !== \"progress\") return\n onFirmwareRestartingChangeRef.current?.(false, true)\n ota.installSession.retry()\n }, [page])\n\n const finish = useCallback(async () => {\n if (page === \"check\") {\n onFinishedRef.current?.()\n return\n }\n if (installSnapshot.displayState === \"restarting\") stopOtaAutoChain()\n const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(\n installSnapshot.otaStatus,\n installSnapshot.otaProgress,\n installSnapshot.errorMsg,\n )\n if (requiresGlassesReboot) stopOtaAutoChain()\n await ota.installSession.finish()\n returnToCheck()\n }, [installSnapshot, page, returnToCheck])\n\n const discard = useCallback(async () => {\n if (page !== \"progress\") return\n stopOtaAutoChain()\n await ota.installSession.discard()\n returnToCheck()\n }, [page, returnToCheck])\n\n const openWifiSetup = useCallback(() => {\n if (page === \"progress\") stopOtaAutoChain()\n onOpenWifiSetupRef.current?.()\n }, [page])\n\n const state = useMemo<MentraLiveOtaState>(() => {\n const hotspotSupported = otaSnapshot.hotspotOtaVersion === 1\n const canInstall = otaSnapshot.wifiStatusKnown && (otaSnapshot.wifiConnected || hotspotSupported)\n if (!runtimeReady) {\n return {\n screen: \"initializing\",\n connected: otaSnapshot.connected,\n transport: null,\n updateRequired: isUpdateRequired,\n versionChange: isVersionChange,\n versionChangeConverged: false,\n versionChangePhase: null,\n wifiConnected: otaSnapshot.wifiConnected,\n wifiStatusKnown: otaSnapshot.wifiStatusKnown,\n hotspotSupported,\n hotspotPhase: \"idle\",\n hotspotArtifactPercent: null,\n phase: null,\n step: null,\n currentStep: null,\n totalSteps: null,\n progress: null,\n installingApkOnly: false,\n firmwareRestarting: false,\n error: null,\n canInstall: false,\n canRetry: false,\n canFinish: false,\n canDismiss: false,\n canDiscard: false,\n canOpenWifiSetup: false,\n continueDisabled: false,\n releaseTransition: null,\n changelogs: [],\n }\n }\n\n if (page === \"check\") {\n const wifiRequired = otaSnapshot.wifiStatusKnown && !otaSnapshot.wifiConnected && !hotspotSupported\n const screen: MentraLiveOtaScreen =\n checkState === \"checking\"\n ? \"checking\"\n : checkState === \"update_available\"\n ? wifiRequired\n ? \"wifi_required\"\n : \"update_available\"\n : checkState === \"no_update\"\n ? \"up_to_date\"\n : checkState === \"dev_build\"\n ? \"dev_build\"\n : errorKind === \"pin_unavailable\"\n ? \"update_info_unavailable\"\n : \"check_failed\"\n const error: MentraLiveOtaError | null =\n screen === \"check_failed\"\n ? {code: \"check_failed\", message: \"Couldn't check for updates. Please check your connection and try again.\"}\n : screen === \"update_info_unavailable\"\n ? {code: \"update_info_unavailable\", message: \"Update information for this app version is unavailable.\"}\n : null\n return {\n screen,\n connected: otaSnapshot.connected,\n transport: otaSnapshot.wifiConnected ? \"wifi\" : hotspotSupported ? \"hotspot\" : null,\n updateRequired: isUpdateRequired,\n versionChange: isVersionChange,\n versionChangeConverged: false,\n versionChangePhase: null,\n wifiConnected: otaSnapshot.wifiConnected,\n wifiStatusKnown: otaSnapshot.wifiStatusKnown,\n hotspotSupported,\n hotspotPhase: \"idle\",\n hotspotArtifactPercent: null,\n phase: null,\n step: null,\n currentStep: null,\n totalSteps: null,\n progress: null,\n installingApkOnly: false,\n firmwareRestarting: false,\n error,\n canInstall: screen === \"update_available\" && canInstall,\n canRetry: screen === \"check_failed\",\n canFinish: screen === \"up_to_date\" || screen === \"dev_build\" || screen === \"update_info_unavailable\",\n canDismiss: (screen === \"update_available\" || screen === \"wifi_required\") && !isUpdateRequired,\n canDiscard: false,\n canOpenWifiSetup: screen === \"wifi_required\",\n continueDisabled: false,\n releaseTransition:\n screen === \"update_available\" || screen === \"wifi_required\"\n ? offeredReleaseTransition\n : screen === \"up_to_date\"\n ? completedReleaseTransition\n : null,\n changelogs: screen === \"up_to_date\" ? completedChangelogs : [],\n }\n }\n\n const requiresGlassesReboot = shouldRequireGlassesRebootForBesFailure(\n installSnapshot.otaStatus,\n installSnapshot.otaProgress,\n installSnapshot.errorMsg,\n )\n const showChangeWifi = shouldShowChangeWifiForOtaDownloadFailure(\n installSnapshot.otaStatus,\n installSnapshot.otaProgress,\n installSnapshot.errorMsg,\n )\n const displayedError = requiresGlassesReboot\n ? BES_INSTALL_RESTART_MESSAGE\n : installSnapshot.errorMsg || getOtaErrorMessage(installSnapshot.otaStatus?.error)\n const screen = progressScreen(installSnapshot)\n const error =\n screen === \"failed\"\n ? {\n code: requiresGlassesReboot ? (\"bes_restart_required\" as const) : (\"install_failed\" as const),\n message: displayedError,\n }\n : null\n const totalSteps = installSnapshot.otaStatus?.totalSteps ?? null\n const changelogs = screen === \"complete\" ? releaseChangelogsForActiveChain() : []\n return {\n screen,\n connected: installSnapshot.connected,\n transport: installSnapshot.transport,\n updateRequired: isUpdateRequired,\n versionChange: installSnapshot.isVersionChange,\n versionChangeConverged: installSnapshot.versionChangeConverged,\n versionChangePhase: installSnapshot.versionChangePhase,\n wifiConnected: otaSnapshot.wifiConnected,\n wifiStatusKnown: otaSnapshot.wifiStatusKnown,\n hotspotSupported,\n hotspotPhase: installSnapshot.hotspotPhase,\n hotspotArtifactPercent: installSnapshot.hotspotArtifactPercent,\n phase: installSnapshot.otaStatus?.phase ?? installSnapshot.otaProgress?.stage ?? null,\n step: installSnapshot.otaStatus?.stepType ?? null,\n currentStep: installSnapshot.otaStatus?.currentStep ?? null,\n totalSteps,\n progress: installProgress(installSnapshot),\n installingApkOnly:\n installSnapshot.otaStatus?.stepType === \"apk\" &&\n installSnapshot.otaStatus.phase === \"install\" &&\n totalSteps === 1,\n firmwareRestarting,\n error,\n canInstall: false,\n canRetry: screen === \"failed\" && !requiresGlassesReboot,\n canFinish: screen === \"complete\" || screen === \"restarting\" || (screen === \"failed\" && requiresGlassesReboot),\n canDismiss: false,\n canDiscard: screen === \"disconnected\",\n canOpenWifiSetup: screen === \"failed\" && showChangeWifi,\n continueDisabled: installSnapshot.continueButtonDisabled,\n releaseTransition: releaseTransitionFromRange(otaAutoChainReleaseRange()),\n changelogs,\n }\n }, [\n checkState,\n completedChangelogs,\n completedReleaseTransition,\n errorKind,\n firmwareRestarting,\n installSnapshot,\n isUpdateRequired,\n isVersionChange,\n otaSnapshot,\n offeredReleaseTransition,\n page,\n runtimeReady,\n ])\n\n return useMemo(\n () => ({state, check, retryCheck: check, install, retryInstall, finish, discard, openWifiSetup}),\n [check, discard, finish, install, openWifiSetup, retryInstall, state],\n )\n}\n"]}
@@ -78,6 +78,8 @@ export declare class BlobStore {
78
78
  handleOpenRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void;
79
79
  handleRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void;
80
80
  handleCloseRead(packageName: string, payload: Record<string, unknown>, requestId?: string): void;
81
+ /** Best-effort GC for prepared share handoffs retained in the OS cache. */
82
+ private cleanupShareCache;
81
83
  handleShare(packageName: string, payload: Record<string, unknown>, requestId?: string): Promise<void>;
82
84
  /** Called from LocalMiniappRuntime.unregisterApp — drop this app's in-flight state. */
83
85
  onAppGone(packageName: string): void;