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

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 (84) 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/index.d.ts +1 -0
  7. package/build/index.d.ts.map +1 -1
  8. package/build/index.js +1 -0
  9. package/build/index.js.map +1 -1
  10. package/build/runtime/streamConfig.d.ts +7 -0
  11. package/build/runtime/streamConfig.d.ts.map +1 -1
  12. package/build/runtime/streamConfig.js +7 -0
  13. package/build/runtime/streamConfig.js.map +1 -1
  14. package/build/services/AcsMeetingService.d.ts +154 -0
  15. package/build/services/AcsMeetingService.d.ts.map +1 -0
  16. package/build/services/AcsMeetingService.js +477 -0
  17. package/build/services/AcsMeetingService.js.map +1 -0
  18. package/build/services/AppRegistry.d.ts +9 -0
  19. package/build/services/AppRegistry.d.ts.map +1 -1
  20. package/build/services/AppRegistry.js +22 -0
  21. package/build/services/AppRegistry.js.map +1 -1
  22. package/build/services/DeviceEventRouter.d.ts.map +1 -1
  23. package/build/services/DeviceEventRouter.js +12 -3
  24. package/build/services/DeviceEventRouter.js.map +1 -1
  25. package/build/services/GlassesSettingsSync.d.ts.map +1 -1
  26. package/build/services/GlassesSettingsSync.js +11 -1
  27. package/build/services/GlassesSettingsSync.js.map +1 -1
  28. package/build/services/GlassesStatusProjection.d.ts +12 -0
  29. package/build/services/GlassesStatusProjection.d.ts.map +1 -1
  30. package/build/services/GlassesStatusProjection.js +23 -0
  31. package/build/services/GlassesStatusProjection.js.map +1 -1
  32. package/build/services/LocalMiniappRuntime.d.ts +12 -0
  33. package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
  34. package/build/services/LocalMiniappRuntime.js +184 -2
  35. package/build/services/LocalMiniappRuntime.js.map +1 -1
  36. package/build/services/MentraJSRouter.d.ts.map +1 -1
  37. package/build/services/MentraJSRouter.js +8 -1
  38. package/build/services/MentraJSRouter.js.map +1 -1
  39. package/build/services/MiniappLauncher.d.ts +3 -1
  40. package/build/services/MiniappLauncher.d.ts.map +1 -1
  41. package/build/services/MiniappLauncher.js +66 -50
  42. package/build/services/MiniappLauncher.js.map +1 -1
  43. package/build/services/PhoneCameraFovCoordinator.d.ts +18 -0
  44. package/build/services/PhoneCameraFovCoordinator.d.ts.map +1 -1
  45. package/build/services/PhoneCameraFovCoordinator.js +36 -0
  46. package/build/services/PhoneCameraFovCoordinator.js.map +1 -1
  47. package/build/services/PhoneStreamCoordinator.d.ts +67 -1
  48. package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
  49. package/build/services/PhoneStreamCoordinator.js +204 -15
  50. package/build/services/PhoneStreamCoordinator.js.map +1 -1
  51. package/build/services/StreamLifecycleController.d.ts +23 -5
  52. package/build/services/StreamLifecycleController.d.ts.map +1 -1
  53. package/build/services/StreamLifecycleController.js +31 -10
  54. package/build/services/StreamLifecycleController.js.map +1 -1
  55. package/build/services/acsAudioSource.d.ts +24 -0
  56. package/build/services/acsAudioSource.d.ts.map +1 -0
  57. package/build/services/acsAudioSource.js +37 -0
  58. package/build/services/acsAudioSource.js.map +1 -0
  59. package/build/utils/devMiniappLaunch.d.ts.map +1 -1
  60. package/build/utils/devMiniappLaunch.js +4 -0
  61. package/build/utils/devMiniappLaunch.js.map +1 -1
  62. package/build/utils/devMiniappSnapshot.d.ts +46 -0
  63. package/build/utils/devMiniappSnapshot.d.ts.map +1 -0
  64. package/build/utils/devMiniappSnapshot.js +94 -0
  65. package/build/utils/devMiniappSnapshot.js.map +1 -0
  66. package/package.json +7 -6
  67. package/src/engine.ts +10 -2
  68. package/src/generated/releaseMetadata.ts +5 -5
  69. package/src/index.ts +4 -0
  70. package/src/runtime/streamConfig.ts +13 -0
  71. package/src/services/AcsMeetingService.ts +570 -0
  72. package/src/services/AppRegistry.ts +23 -0
  73. package/src/services/DeviceEventRouter.ts +12 -3
  74. package/src/services/GlassesSettingsSync.ts +13 -3
  75. package/src/services/GlassesStatusProjection.ts +28 -0
  76. package/src/services/LocalMiniappRuntime.ts +214 -2
  77. package/src/services/MentraJSRouter.ts +7 -1
  78. package/src/services/MiniappLauncher.ts +73 -50
  79. package/src/services/PhoneCameraFovCoordinator.ts +34 -0
  80. package/src/services/PhoneStreamCoordinator.ts +232 -19
  81. package/src/services/StreamLifecycleController.ts +42 -12
  82. package/src/services/acsAudioSource.ts +53 -0
  83. package/src/utils/devMiniappLaunch.ts +4 -0
  84. package/src/utils/devMiniappSnapshot.ts +119 -0
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Dev miniapp snapshot — keep a local copy of the last live-dev bundle so
3
+ * walking away from the laptop still opens the miniapp while Mentra App is
4
+ * running (and after, as long as the on-disk `dev-*` snapshot remains).
5
+ *
6
+ * Live launches load HTTP off `mentra-miniapp dev` for hot reload. After a
7
+ * successful reachability probe we fire-and-forget `${devUrl}/bundle.zip`
8
+ * into `lmas/<pkg>/dev-<ms>/`. When the laptop is unreachable, launch
9
+ * routes and MiniappLauncher fall back to that snapshot instead of the
10
+ * "Dev server offline" dead-end.
11
+ */
12
+
13
+ import appRegistry from "../services/AppRegistry"
14
+ import {storage} from "./storage/storage"
15
+ import {
16
+ decideDevLaunchRoute,
17
+ type DecideDevLaunchOptions,
18
+ type DevLaunchResult,
19
+ type DevManifest,
20
+ } from "./devMiniappLaunch"
21
+
22
+ export type DevOpenDecision =
23
+ | {decision: "live"; manifest: DevManifest; resolvedUrl: string}
24
+ | {decision: "cached"}
25
+ | {decision: "offline"}
26
+
27
+ export type DevBundleSource =
28
+ | {kind: "live"; resolvedUrl: string; manifest: DevManifest}
29
+ | {kind: "snapshot"; version: string}
30
+ | {kind: "none"}
31
+
32
+ const snapshotInFlight = new Map<string, Promise<void>>()
33
+
34
+ /** Candidate zip URLs: same-origin `/bundle.zip`, then the sidecar path. */
35
+ export function snapshotCandidateUrls(baseUrl: string, sidecarPort?: number | null): string[] {
36
+ const trimmed = baseUrl.replace(/\/$/, "")
37
+ const urls = [`${trimmed}/bundle.zip`]
38
+ try {
39
+ const url = new URL(trimmed)
40
+ const userPort = Number(url.port) || (url.protocol === "https:" ? 443 : 80)
41
+ const sidecar = sidecarPort && sidecarPort > 0 ? sidecarPort : userPort + 1
42
+ url.port = String(sidecar)
43
+ const sidecarZip = `${url.origin}/__mentra_dev/bundle.zip`
44
+ if (!urls.includes(sidecarZip)) urls.push(sidecarZip)
45
+ } catch {
46
+ /* ignore malformed base */
47
+ }
48
+ return urls
49
+ }
50
+
51
+ function storedSidecarPort(packageName: string): number | undefined {
52
+ const stored = storage.load<number>(`${packageName}_dev_port`)
53
+ return stored.is_ok() && Number.isFinite(stored.value) ? stored.value : undefined
54
+ }
55
+
56
+ /**
57
+ * Download the current live-dev zip into `lmas/<pkg>/dev-<ms>/` and keep
58
+ * only the newest snapshot. Coalesces concurrent calls per package.
59
+ */
60
+ export function queueDevSnapshot(packageName: string, baseUrl: string, sidecarPort?: number | null): void {
61
+ if (!packageName || !baseUrl) return
62
+ if (snapshotInFlight.has(packageName)) return
63
+ const promise = installDevSnapshot(packageName, baseUrl, sidecarPort ?? storedSidecarPort(packageName)).finally(() => {
64
+ snapshotInFlight.delete(packageName)
65
+ })
66
+ snapshotInFlight.set(packageName, promise)
67
+ }
68
+
69
+ async function installDevSnapshot(packageName: string, baseUrl: string, sidecarPort?: number | null): Promise<void> {
70
+ let lastError: unknown
71
+ for (const url of snapshotCandidateUrls(baseUrl, sidecarPort)) {
72
+ const res = await appRegistry.installFromUrl(url, {
73
+ versionOverride: `dev-${Date.now()}`,
74
+ releaseIdentity: {source: "dev_snapshot"},
75
+ })
76
+ if (res.is_ok()) {
77
+ appRegistry.gcDevVersions(packageName, 1)
78
+ return
79
+ }
80
+ lastError = res.error
81
+ }
82
+ console.warn(`Dev snapshot failed for ${packageName}:`, lastError)
83
+ }
84
+
85
+ /** Reachability first; if the laptop is down, open the last local snapshot. */
86
+ export async function decideDevOpenRoute(
87
+ packageName: string,
88
+ devUrl: string,
89
+ options?: DecideDevLaunchOptions,
90
+ ): Promise<DevOpenDecision> {
91
+ const route = await decideDevLaunchRoute(packageName, devUrl, options)
92
+ if (route.decision === "live") {
93
+ queueDevSnapshot(packageName, route.resolvedUrl)
94
+ return route
95
+ }
96
+ if (packageName && appRegistry.hasDevSnapshot(packageName)) {
97
+ return {decision: "cached"}
98
+ }
99
+ return {decision: "offline"}
100
+ }
101
+
102
+ /**
103
+ * Same live-vs-snapshot choice MiniappLauncher uses to resolve a bundle.
104
+ * Live also kicks a background snapshot so the next offline open has a copy.
105
+ */
106
+ export async function resolveDevBundleSource(
107
+ packageName: string,
108
+ devUrl: string,
109
+ options?: DecideDevLaunchOptions,
110
+ ): Promise<DevBundleSource> {
111
+ const route: DevLaunchResult = await decideDevLaunchRoute(packageName, devUrl, options)
112
+ if (route.decision === "live" && route.manifest) {
113
+ queueDevSnapshot(packageName, route.resolvedUrl)
114
+ return {kind: "live", resolvedUrl: route.resolvedUrl, manifest: route.manifest}
115
+ }
116
+ const version = appRegistry.getLatestDevSnapshotVersion(packageName)
117
+ if (version) return {kind: "snapshot", version}
118
+ return {kind: "none"}
119
+ }