@mentra/engine 3.4.0-dev.1207 → 3.4.0-dev.1209
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.
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +5 -3
- package/build/facades/glasses.js.map +1 -1
- package/build/generated/releaseMetadata.js +5 -5
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/services/AppRegistry.d.ts +2 -0
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +2 -0
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +18 -1
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/MentraJSCrashController.d.ts +2 -0
- package/build/services/MentraJSCrashController.d.ts.map +1 -1
- package/build/services/MentraJSCrashController.js +4 -0
- package/build/services/MentraJSCrashController.js.map +1 -1
- package/build/services/MentraJSRouter.d.ts.map +1 -1
- package/build/services/MentraJSRouter.js +14 -3
- package/build/services/MentraJSRouter.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts +6 -0
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +20 -3
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/fleet/FleetReporter.d.ts.map +1 -1
- package/build/services/fleet/FleetReporter.js +43 -0
- package/build/services/fleet/FleetReporter.js.map +1 -1
- package/build/services/fleet/fleetCollector.d.ts +1 -1
- package/build/services/fleet/fleetCollector.d.ts.map +1 -1
- package/build/services/fleet/fleetCollector.js +146 -5
- package/build/services/fleet/fleetCollector.js.map +1 -1
- package/build/services/fleet/fleetEvents.d.ts +39 -3
- package/build/services/fleet/fleetEvents.d.ts.map +1 -1
- package/build/services/fleet/fleetEvents.js +66 -22
- package/build/services/fleet/fleetEvents.js.map +1 -1
- package/build/services/fleet/fleetQueue.d.ts +26 -0
- package/build/services/fleet/fleetQueue.d.ts.map +1 -1
- package/build/services/fleet/fleetQueue.js +94 -8
- package/build/services/fleet/fleetQueue.js.map +1 -1
- package/build/services/fleet/telemetryLimits.d.ts +16 -0
- package/build/services/fleet/telemetryLimits.d.ts.map +1 -0
- package/build/services/fleet/telemetryLimits.js +69 -0
- package/build/services/fleet/telemetryLimits.js.map +1 -0
- package/build/services/installMiniapp.d.ts +13 -0
- package/build/services/installMiniapp.d.ts.map +1 -1
- package/build/services/installMiniapp.js +64 -1
- package/build/services/installMiniapp.js.map +1 -1
- package/build/services/miniappReleaseInstall.js +1 -1
- package/build/services/miniappReleaseInstall.js.map +1 -1
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +16 -1
- package/build/stores/apps.js.map +1 -1
- package/package.json +8 -8
- package/src/facades/glasses.ts +5 -3
- package/src/generated/releaseMetadata.ts +5 -5
- package/src/services/AppRegistry.ts +2 -0
- package/src/services/LocalMiniappRuntime.ts +20 -1
- package/src/services/MentraJSCrashController.ts +5 -0
- package/src/services/MentraJSRouter.ts +15 -3
- package/src/services/MiniappLauncher.ts +18 -2
- package/src/services/fleet/FleetReporter.ts +40 -0
- package/src/services/fleet/fleetCollector.ts +160 -6
- package/src/services/fleet/fleetEvents.ts +104 -20
- package/src/services/fleet/fleetQueue.ts +100 -7
- package/src/services/fleet/telemetryLimits.ts +78 -0
- package/src/services/installMiniapp.ts +78 -2
- package/src/services/miniappReleaseInstall.ts +1 -1
- package/src/stores/apps.ts +19 -2
package/build/stores/apps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/stores/apps.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Engine apps store — runtime state of installed and local applets.\n *\n * The OEM-facing API: subscribe to the running set, install/uninstall\n * miniapps, start/stop them. The store delegates install plumbing to\n * AppRegistry, and exposes hooks (`useApps`, `useStart`, `useStop`,\n * `useRefresh`, `useStopAll`) that the host UI can read.\n *\n * Source of `apps`:\n * - Local: appRegistry.getInstalledMiniapps() (always)\n */\n\nimport {useMemo} from \"react\"\nimport {AppState} from \"react-native\"\nimport {AsyncResult, Result, result as Res} from \"typesafe-ts\"\nimport {create} from \"zustand\"\n\nimport type {ClientApp} from \"../types/applet\"\nimport {DeviceTypes} from \"../types/enums\"\nimport {getModelCapabilities} from \"../types/hardware\"\nimport {HardwareCompatibility, type CompatibilityResult} from \"../utils/hardware/hardware\"\nimport {storage} from \"../utils/storage/storage\"\nimport appRegistry, {type UninstallOptions} from \"../services/AppRegistry\"\nimport localDisplayManager from \"../services/LocalDisplayManager\"\nimport {fleetEvents} from \"../services/fleet/fleetEvents\"\nimport {islandNotifications} from \"../services/NotificationsEmitter\"\nimport sttModelManager from \"../services/STTModelManager\"\nimport {miniappLauncher} from \"../services/MiniappLauncher\"\nimport {checkMiniappAge, isMiniappAgeGateOn, miniappRequiredAge} from \"../services/miniappAgeGate\"\nimport {miniappRunningRegistry} from \"../services/MiniappRunningRegistry\"\nimport {nativeMiniappExecution} from \"../services/NativeMiniappExecution\"\nimport {noteMiniappOpened} from \"../services/runningUpdatePrompt\"\nimport {isMiniappAvailable} from \"../runtime/bootstrap\"\nimport {resolveHiddenStatus} from \"./appVisibility\"\nimport {SETTINGS, useSettingsStore} from \"./settings\"\nimport BluetoothSdk from \"@mentra/bluetooth-sdk\"\n\n// ---------------------------------------------------------------------------\n// Configuration / hooks\n// ---------------------------------------------------------------------------\n\nexport interface StartOptions {\n skipNavigation?: boolean\n /** Present the app after launch checks, before bundle loading and runtime startup. */\n onAccepted?: () => void | Promise<void>\n /**\n * Who started the miniapp: `\"user\"` for a person's own choice (a tap on Home, a pick from the glasses menu),\n * `\"automatic\"` for everything else. It is the default. Fleet's launch record names it, and only a person's start\n * shows UI: an automatic start that a check refuses (glasses not connected, an update in progress, no speech\n * model) is refused silently.\n */\n trigger?: \"user\" | \"automatic\"\n}\n\n/** Host seams for a start. The refusal explanations are only for a person's own start. */\nexport interface AppStoreHooks {\n /** An open was refused because the miniapp is updating; the host explains why. */\n onUpdateBlocked?: (app: ClientApp) => void\n /**\n * A start was blocked because the app is hardware-incompatible. Engine made\n * the decision (and raised the `version_incompatible` notification); the host\n * renders its branded alert here.\n */\n onIncompatibleBlocked?: (app: ClientApp) => void\n /**\n * A start was blocked because the app requires the on-device STT model\n * (declared at registration — see AppRegistry.installOfflineApp) and none is\n * installed. Engine decided via its model manager; the host renders the\n * alert / settings navigation here.\n */\n onMissingSpeechModel?: (app: ClientApp) => void\n /** A start was refused because the miniapp's server no longer admits this account; the host explains why. */\n onAccessRevoked?: (app: ClientApp) => void\n /**\n * An open request passed the gates — fired on EVERY open, including\n * re-opening an already-running app, so the host's navigation / open\n * animation always plays.\n */\n onOpenRequested?: (app: ClientApp, opts?: StartOptions) => void\n}\n\nlet hostHooks: AppStoreHooks = {}\n\n/** The running-state change at the end of each start, one at a time (see `start`). */\nlet startTransitions: Promise<unknown> = Promise.resolve()\n/** How many times each package has been stopped, so a start can tell whether a later start stopped it. */\nconst stopCounts = new Map<string, number>()\n\nfunction oneStartAtATime<T>(transition: () => Promise<T>): Promise<T> {\n const run = startTransitions.then(transition)\n startTransitions = run.catch(() => {})\n return run\n}\nconst uninstallingPackages = new Set<string>()\nconst openedByUserListeners = new Set<(packageName: string) => void>()\n\nexport function installAppStoreHooks(hooks: AppStoreHooks): void {\n hostHooks = {...hostHooks, ...hooks}\n}\n\n/**\n * A person started a miniapp (a `\"user\"` start) and it now runs. Re-opening one\n * that already runs, and automatic starts (restoring what ran before, an\n * update's restart), are not announced. Returns an unsubscribe.\n */\nexport function onMiniappOpenedByUser(listener: (packageName: string) => void): () => void {\n openedByUserListeners.add(listener)\n return () => {\n openedByUserListeners.delete(listener)\n }\n}\n\nfunction announceOpenedByUser(packageName: string): void {\n for (const listener of [...openedByUserListeners]) {\n try {\n listener(packageName)\n } catch (error) {\n console.warn(\"Miniapp opened listener threw\", error)\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Store\n// ---------------------------------------------------------------------------\n\ninterface AppStatusState {\n apps: ClientApp[]\n /** Packages with an update downloading or activating. Opens and uninstall are refused meanwhile. */\n updatingPackages: ReadonlySet<string>\n /**\n * Mark a package as updating until the returned function is called. Throws\n * while it is already updating or being uninstalled.\n */\n beginUpdate: (packageName: string) => () => void\n /** Run `update` with the package marked as updating. */\n runUpdate: <T>(packageName: string, update: () => Promise<T>) => Promise<T>\n /**\n * Source of truth for which app is foregrounded in the Compositor overlay.\n * The per-app `foregrounded` boolean is derived from this in `projectApps`\n * so a refresh can never drop the flag when an app is transiently missing\n * from one of the two refresh passes (local-only then merged). See\n * `projectApps` / `setForeground` / `clearForeground`.\n */\n foregroundedPackage: string | null\n refresh: () => Promise<void>\n /** Resolves true if the app actually started; false if a host gate aborted it or its JS context failed to spawn. */\n start: (app: ClientApp, opts?: StartOptions) => Promise<boolean>\n stop: (packageName: string) => Promise<void>\n setForeground: (packageName: string) => Promise<void>\n clearForeground: () => void\n stopAll: () => AsyncResult<void, Error>\n install: (url: string, opts?: {versionOverride?: string}) => AsyncResult<void, Error>\n uninstall: (packageName: string, version?: string, options?: UninstallOptions) => AsyncResult<void, Error>\n saveScreenshot: (packageName: string, screenshot: string) => Promise<void>\n setHiddenStatus: (packageName: string, status: boolean) => void\n getHiddenStatus: (packageName: string) => boolean\n /** Replace the whole apps array. Hosts use this when their extra source changes. */\n setApps: (apps: ClientApp[]) => void\n}\n\nexport const DUMMY_APPLET: ClientApp = {\n packageName: \"\",\n name: \"\",\n webviewUrl: \"\",\n logoUrl: \"\",\n type: \"standard\",\n permissions: [],\n running: false,\n loading: false,\n healthy: true,\n hardwareRequirements: [],\n offline: true,\n offlineRoute: \"\",\n local: false,\n hidden: false,\n}\n\nexport type OrderMap = Record<string, number>\nconst APP_ORDER_KEY = \"foreground_apps_order\"\n\nexport const saveAppsOrder = (orderMap: OrderMap): Result<void, Error> => {\n return storage.save(APP_ORDER_KEY, orderMap)\n}\n\nexport const getAppsOrder = (): Result<OrderMap, Error> => {\n return storage.load<OrderMap>(APP_ORDER_KEY)\n}\n\n// In-memory cache for hidden flags. `projectApps` reads getHiddenStatus once\n// per app per refresh — without a cache that was a synchronous JNI hop per\n// app per refresh on a hot UI path. Kept consistent with disk by writing\n// through in setHiddenStatus. Map of packageName → hidden boolean.\nconst hiddenStatusCache = new Map<string, boolean>()\n\nconst getRawPackageNamePriority = (pkg: string): number => {\n if (pkg.includes(\"@empty\")) {\n return 1000\n }\n return 0\n}\n\nexport const sortAppsByPackageNamePriority = (a: ClientApp, b: ClientApp): number => {\n const pa = getRawPackageNamePriority(a.packageName)\n const pb = getRawPackageNamePriority(b.packageName)\n if (pa !== pb) {\n return pa - pb\n }\n return a.name.localeCompare(b.name)\n}\n\nexport const saveLastOpenTime = (packageName: string): void => {\n storage.save(`${packageName}_last_open_time`, Date.now())\n}\n\nexport const getLastOpenTime = (packageName: string): number => {\n const res = storage.load<number>(`${packageName}_last_open_time`)\n if (res.is_ok()) return res.value\n return 0\n}\n\nexport const sortAppsByLastOpenTime = async <T extends {packageName: string}>(apps: T[]): Promise<T[]> => {\n const timestamps = apps.map((app) => ({app, time: getLastOpenTime(app.packageName)}))\n return timestamps.sort((a, b) => a.time - b.time).map((entry) => entry.app)\n}\n\nconst startStopApp = async (app: ClientApp, status: boolean): Promise<void> => {\n if (!status && app.onStop) {\n try {\n app.onStop()\n } catch (e) {\n console.warn(`ISLAND: onStop threw for ${app.packageName}`, e)\n }\n }\n if (status && app.onStart) {\n try {\n app.onStart()\n } catch (e) {\n console.warn(`ISLAND: onStart threw for ${app.packageName}`, e)\n }\n }\n}\n\n/**\n * Build the final `apps` array for the store from the installed/offline app\n * source. Pure — same inputs -> same outputs.\n */\nfunction projectApps(previousState: AppStatusState, localApps: ClientApp[]): ClientApp[] {\n // Dedupe by packageName, keep first occurrence. A miniapp the host keeps\n // background-only (a Store) never enters the user-facing list.\n const byPackage = new Map<string, ClientApp>()\n for (const app of localApps) {\n if (!isMiniappAvailable(app.packageName)) continue\n if (!byPackage.has(app.packageName)) byPackage.set(app.packageName, app)\n }\n\n // Index previous snapshot for cheap lookups (was O(N²) via .find()).\n const previousByPackage = new Map<string, ClientApp>()\n for (const oldApp of previousState.apps) {\n previousByPackage.set(oldApp.packageName, oldApp)\n }\n\n const defaultWearable =\n (useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key) as DeviceTypes | undefined) ||\n DeviceTypes.NONE\n const capabilities = getModelCapabilities(defaultWearable)\n\n // Single pass: dedupe → screenshot carry-over → compat → hidden, all into\n // fresh objects. The previous in-place mutation re-used object references\n // across refreshes, which broke React.memo / referential-equality\n // memoization downstream (every refresh propagated re-renders even when\n // nothing meaningful changed) AND tripped Reanimated's \"tried to modify\n // key of an object already passed to a worklet\" warning whenever the home\n // screen's animated app cards held a reference to a previous snapshot's\n // app object that we then mutated.\n //\n // Identity stability: refresh() is event-driven and fires repeatedly (and\n // twice per cycle via the local-only → merged two-pass emit). If we always\n // returned fresh objects, every poll changed the identity of EVERY app —\n // which re-rendered the Compositor (via useForegroundApp) mid-slide and made\n // the open/close animation hitch, and churned the home grid / switcher pill.\n // So we build the candidate object, then REUSE the previous reference when\n // nothing meaningful changed. Same pattern as the miniappRunningRegistry\n // projection below. A stable foreground-app reference lets the Compositor's\n // slide run uninterrupted on the UI thread.\n return Array.from(byPackage.values()).map((app) => {\n const next: ClientApp = {\n ...app,\n screenshot: previousByPackage.get(app.packageName)?.screenshot ?? app.screenshot,\n compatibility: HardwareCompatibility.checkCompatibility(app.hardwareRequirements, capabilities),\n // A registry source can force an app off the primary home screen (for\n // example, Miniapp Developer while its home-screen setting is disabled).\n // Compose that gate with the user's persisted home-screen layout instead\n // of replacing it, otherwise a default-false persisted value makes a\n // source-hidden app visible again during projection.\n hidden: resolveHiddenStatus(app.hidden, previousState.getHiddenStatus(app.packageName)),\n // Derive the foreground flag from the store's single source of truth\n // (`foregroundedPackage`), NOT from the previous snapshot. Carrying it over\n // per-app meant a refresh that momentarily omitted an app (e.g. the\n // two-pass local-only → merged emit) would reset its flag to false — which\n // raced OfflineAppHost's interceptor guard and made the hosted miniapp fall\n // through to the root router (restart). Deriving here keeps the flag stable\n // across both passes.\n foregrounded: app.packageName === previousState.foregroundedPackage,\n updating: previousState.updatingPackages.has(app.packageName),\n }\n const prev = previousByPackage.get(app.packageName)\n return prev && shallowEqualApp(prev, next) ? prev : next\n })\n}\n\n// Cheap equality check used by projectApps to preserve object identity across\n// refreshes when nothing meaningful changed. Most keys are compared by\n// reference (the source app's nested fields — permissions, hardwareRequirements,\n// parameters — are reference-stable within a refresh). The ONE exception is\n// `compatibility`, which projectApps recomputes into a fresh object every call;\n// comparing it by reference would always differ and defeat the whole point. We\n// compare it structurally instead so identity is only broken when the device's\n// actual compatibility verdict changes (e.g. glasses connect/disconnect).\nfunction shallowEqualApp(a: ClientApp, b: ClientApp): boolean {\n const aKeys = Object.keys(a) as (keyof ClientApp)[]\n const bKeys = Object.keys(b) as (keyof ClientApp)[]\n if (aKeys.length !== bKeys.length) return false\n for (const k of aKeys) {\n if (k === \"compatibility\") {\n if (!compatibilityEqual(a.compatibility, b.compatibility)) return false\n continue\n }\n if (a[k] !== b[k]) return false\n }\n return true\n}\n\nfunction compatibilityEqual(a?: CompatibilityResult, b?: CompatibilityResult): boolean {\n if (a === b) return true\n if (!a || !b) return false\n return (\n a.isCompatible === b.isCompatible &&\n a.missingRequired.length === b.missingRequired.length &&\n a.missingOptional.length === b.missingOptional.length &&\n a.warnings.length === b.warnings.length\n )\n}\n\n/** Called by a start once it is past every gate and actually starts the miniapp. */\ninterface LaunchAttempt {\n begin(): void\n}\n\n/**\n * Tells Fleet how each start went, around the launch and without touching it: the result, or the failure it throws,\n * is returned as the launch gave it. Only a start that got past every gate is a launch: `started` when it succeeded,\n * `failed` when the spawn or start itself failed. A refusal (another miniapp is loading, incompatible glasses, a\n * missing speech model, an update in progress, a package that is not available) and re-opening a miniapp that is\n * already running start nothing and are not reported. Nor is opening one of the Mentra App's own screens (a native\n * built-in that declares no `nativeExecution`), which is not a miniapp to Fleet. Fleet's `launch` never throws.\n *\n * From the moment it begins, the start claims the miniapp (`fleetEvents.claimLaunch`): the spawn it causes, which the\n * launcher reports for every other path, and the Compositor's own call to the launcher are this launch, not more.\n */\nfunction reportingLaunches(\n launch: (app: ClientApp, opts: StartOptions | undefined, attempt: LaunchAttempt) => Promise<boolean>,\n): (app: ClientApp, opts?: StartOptions) => Promise<boolean> {\n return async (clientApp, opts) => {\n let attempted = false\n let started = false\n const claim: {release?: () => void} = {}\n try {\n started = await launch(clientApp, opts, {\n begin: () => {\n attempted = true\n claim.release ??= fleetEvents.claimLaunch(clientApp.packageName)\n },\n })\n return started\n } finally {\n if (attempted) {\n fleetEvents.launch({\n packageName: clientApp.packageName,\n miniappName: clientApp.name,\n versionName: clientApp.version,\n start: opts?.trigger ?? \"automatic\",\n outcome: started ? \"started\" : \"failed\",\n })\n }\n claim.release?.()\n }\n }\n}\n\nexport const useAppStatusStore = create<AppStatusState>((set, get) => ({\n apps: [],\n updatingPackages: new Set(),\n foregroundedPackage: null,\n\n refresh: async () => {\n const localApps = await appRegistry.getInstalledMiniapps()\n // Update and foreground state may have changed while the registry was read.\n set((state) => {\n // An app the host made unavailable loses foreground ownership. A temporary\n // registry omission keeps it, so ordinary refreshes never reopen the UI.\n const foregroundedPackage =\n state.foregroundedPackage && isMiniappAvailable(state.foregroundedPackage) ? state.foregroundedPackage : null\n return {foregroundedPackage, apps: projectApps({...state, foregroundedPackage}, localApps)}\n })\n },\n\n beginUpdate: (packageName) => {\n if (get().updatingPackages.has(packageName)) throw new Error(`${packageName} is already updating`)\n if (uninstallingPackages.has(packageName)) throw new Error(`${packageName} is being uninstalled`)\n const setUpdating = (updating: boolean) => {\n set((state) => {\n const updatingPackages = new Set(state.updatingPackages)\n if (updating) updatingPackages.add(packageName)\n else updatingPackages.delete(packageName)\n return {\n updatingPackages,\n apps: state.apps.map((app) => (app.packageName === packageName ? {...app, updating} : app)),\n }\n })\n }\n setUpdating(true)\n let ended = false\n return () => {\n if (ended) return\n ended = true\n setUpdating(false)\n }\n },\n\n runUpdate: async (packageName, update) => {\n const end = get().beginUpdate(packageName)\n try {\n return await update()\n } finally {\n end()\n }\n },\n\n start: reportingLaunches(async (clientApp: ClientApp, opts: StartOptions | undefined, attempt: LaunchAttempt) => {\n const state = get()\n const packageName = clientApp.packageName\n // Only a person's own start explains a refusal; anything else is refused silently.\n const byUser = opts?.trigger === \"user\"\n const explain = byUser ? hostHooks : {}\n if (!isMiniappAvailable(packageName)) return false\n const app = state.apps.find((a) => a.packageName === packageName)\n if (!app) {\n console.error(`ISLAND: app not found for package name: ${packageName}`)\n return false\n }\n if (state.updatingPackages.has(packageName)) {\n explain.onUpdateBlocked?.(app)\n return false\n }\n if (app.local && appRegistry.isMiniappAccessRevoked(packageName)) {\n explain.onAccessRevoked?.(app)\n return false\n }\n\n // Skip spawning a NEW app while another is mid-launch — concurrent spawns\n // race the foreground-only-one teardown. This is checked BEFORE the gates\n // and the onOpenRequested seam (which navigates/foregrounds) so a gated\n // launch doesn't paint a splash it can't back. Re-opening an already-running\n // app is exempt: it has nothing to spawn, so it skips this gate and is\n // allowed to re-navigate/animate below.\n // That exemption is the fix for the \"second tap during another app's launch\n // window silently does nothing\" bug.\n if (!app.running && state.apps.some((a) => a.loading)) {\n console.log(`ISLAND: skipping start ${packageName} — another app is loading`)\n return false\n }\n\n if (!app.offline && !app.local) {\n console.warn(`ISLAND: cloud-v1 app entries are no longer supported: ${packageName}`)\n return false\n }\n\n // Hardware-compatibility gate — engine decides and blocks; for a person's\n // start the host renders its branded alert via onIncompatibleBlocked\n // (and/or the structured notification below). `!isCompatible` (not `=== false`) keeps the semantics\n // of the host gate this replaces: an unknown verdict blocks, not launches.\n if (!app.compatibility?.isCompatible) {\n islandNotifications.emit({\n kind: \"version_incompatible\",\n packageName,\n reason: `${app.name ?? packageName} is not compatible with the connected glasses`,\n metadata: {missingRequired: app.compatibility?.missingRequired ?? []},\n timestamp: Date.now(),\n })\n explain.onIncompatibleBlocked?.(app)\n return false\n }\n\n // Missing-speech-model gate for apps registered with requiresLocalSttModel.\n // Engine decides via its own model manager; the host renders the alert and\n // any settings navigation via onMissingSpeechModel.\n if (appRegistry.requiresLocalSttModel(packageName) && !(await sttModelManager.isModelAvailable())) {\n islandNotifications.emit({\n kind: \"missing_speech_model\",\n packageName,\n reason: `${app.name ?? packageName} needs an on-device speech model before it can start`,\n timestamp: Date.now(),\n })\n explain.onMissingSpeechModel?.(app)\n return false\n }\n\n // The age gate, before the screen opens or another miniapp stops, so a refusal changes nothing: the person was\n // asked their age, or told why. Only a gated miniapp waits here. The launch is checked again as its context\n // spawns, for every other way in.\n if (app.local && !app.running && isMiniappAgeGateOn()) {\n const rated = miniappLauncher.installedAgeRating(packageName)\n if (miniappRequiredAge(rated.ageRating) !== null) {\n const verdict = await checkMiniappAge(rated, {interactive: AppState.currentState === \"active\"})\n if (verdict !== \"allowed\") return false\n }\n }\n\n // A model check or the age gate above may have yielded while an update started.\n if (get().updatingPackages.has(packageName)) {\n explain.onUpdateBlocked?.(app)\n return false\n }\n\n // Host navigation / open-animation seam. Runs on EVERY accepted open —\n // including re-opening an already-running app — so the animation always\n // plays (BuiltInMiniappCatalog.navigateForApp: overlay apps setForeground\n // for the slide).\n const presentation = opts?.onAccepted?.()\n if (presentation) await presentation\n hostHooks.onOpenRequested?.(app, opts)\n\n // First-activation mark (moved from the host's old beforeStart — engine\n // owns the settings store).\n useSettingsStore.getState().setSetting(SETTINGS.has_ever_activated_app.key, true)\n\n // If the tapped app is already running, this is a re-open: the nav/foreground\n // above already drove the animation, and there's nothing to spawn. Short-\n // circuit before the spawn pipeline. Another start of it may have finished\n // while this one waited above.\n if (app.running || get().apps.find((a) => a.packageName === packageName)?.running) {\n saveLastOpenTime(packageName)\n return true\n }\n\n // Past every gate: from here on this is a launch, reported to Fleet as started or failed. A native built-in that\n // declares no execution is the Mentra App's own interface (Settings, Feedback), not a miniapp, and is not reported.\n if (app.local || app.nativeExecution) attempt.begin()\n\n // Foreground-only-one rule: stop other running standard apps, then mark this one running. Starts that waited\n // above (the age question, a presentation) can get here together, so each does this one at a time, on the\n // state as it is then: the last one in stops the others.\n let stopsWhenMarked = 0\n await oneStartAtATime(async () => {\n if (app.type === \"standard\") {\n const runningForeground = get().apps.filter(\n (a) => a.running && a.type === \"standard\" && a.packageName !== packageName,\n )\n for (const r of runningForeground) {\n await get().stop(r.packageName)\n }\n }\n\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, running: true, loading: false} : a)),\n }))\n saveLastOpenTime(packageName)\n await startStopApp(app, true)\n stopsWhenMarked = stopCounts.get(packageName) ?? 0\n })\n // A start that came in after this one may have stopped it already: it doesn't come back.\n if ((stopCounts.get(packageName) ?? 0) !== stopsWhenMarked) return false\n\n // Spawn the background JS context for local miniapps. This used to be a\n // side effect of LocalMiniappView mounting on foreground; pulling it here\n // lets start() actually run the app even when nothing foregrounds it (e.g.\n // a system app launching another miniapp via session.miniapps). Idempotent\n // with the view's own ensureRunning; skipped for native offline built-ins\n // (no JS bundle).\n if (app.local) {\n try {\n await miniappLauncher.ensureRunning(packageName)\n } catch (e) {\n // Spawn / bundle-resolve failed — revert the optimistic running flag so\n // the home list and miniapps.list() don't show a \"running\" app with no\n // JS context, and report failure to the caller (session.miniapps.start).\n console.warn(`ISLAND: launcher.ensureRunning failed for ${packageName}`, e)\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, running: false, loading: false} : a)),\n }))\n // onStart already persisted running:true to disk (saveLocalAppRunningState)\n // before the spawn; run onStop to undo it so a refresh/reboot doesn't\n // resurrect a \"running\" app with no JS context.\n await startStopApp(app, false)\n return false\n }\n }\n\n if (byUser) announceOpenedByUser(packageName)\n return true\n }),\n\n stop: async (packageName: string) => {\n stopCounts.set(packageName, (stopCounts.get(packageName) ?? 0) + 1)\n const state = get()\n const app = state.apps.find((a) => a.packageName === packageName)\n if (!app) {\n console.error(`ISLAND: app not found for package name: ${packageName}`)\n return\n }\n\n set((s) => ({\n apps: s.apps.map((a) =>\n a.packageName === packageName ? {...a, running: false, screenshot: undefined, loading: false} : a,\n ),\n }))\n\n // if there are no apps running, call clearDisplay():\n // read fresh state via get() — `state` was captured before the set() above, so it still shows\n // this app as running and would never reach 0 when stopping the last app.\n if (get().apps.filter((a) => a.running).length === 0) {\n BluetoothSdk.clearDisplay()\n }\n await startStopApp(app, false)\n\n // Tear down the background JS context for local miniapps. No-op for native\n // offline built-ins.\n if (app.local) {\n try {\n await miniappLauncher.stop(packageName)\n } catch (e) {\n console.warn(`ISLAND: launcher.stop failed for ${packageName}`, e)\n }\n }\n },\n\n setForeground: async (packageName: string) => {\n if (!isMiniappAvailable(packageName)) return\n const app = get().apps.find((a) => a.packageName === packageName)\n if (!app) {\n console.error(`ISLAND: setForeground — app not found: ${packageName}`)\n return\n }\n if (get().updatingPackages.has(packageName)) {\n hostHooks.onUpdateBlocked?.(app)\n return\n }\n if (app.local && appRegistry.isMiniappAccessRevoked(packageName)) {\n hostHooks.onAccessRevoked?.(app)\n return\n }\n\n // Flip the foreground flag synchronously so the Compositor's open\n // animation starts on the same frame as the tap. We do NOT await start()\n // first — that gated the flag (and thus the animation) behind the whole\n // JSContext-spawn chain, which was the perceived launch delay. The\n // Compositor/LocalMiniappView already handle the spawn being in-flight\n // (the phase machine), so foregrounding needn't wait for it.\n saveLastOpenTime(packageName)\n set((s) => ({\n foregroundedPackage: packageName,\n apps: s.apps.map((a) => ({...a, foregrounded: a.packageName === packageName})),\n }))\n noteMiniappOpened(packageName)\n\n // Ensure the JSContext exists. start() is idempotent for an\n // already-running app and enforces the foreground-only-one rule for\n // standard apps. Fire-and-forget after the flag flip so it doesn't block\n // paint.\n // if (!app.running) {\n // get().start(app)\n // }\n },\n\n clearForeground: () => {\n set((s) => ({\n foregroundedPackage: null,\n apps: s.apps.some((a) => a.foregrounded)\n ? s.apps.map((a) => (a.foregrounded ? {...a, foregrounded: false} : a))\n : s.apps,\n }))\n },\n\n stopAll: () => {\n return Res.try_async(async () => {\n const running = get().apps.filter((a) => a.running)\n for (const a of running) {\n await get().stop(a.packageName)\n }\n })\n },\n\n install: (url, opts) => appRegistry.installFromUrl(url, opts),\n\n uninstall: (packageName, version, options) => {\n return Res.try_async(async () => {\n if (get().updatingPackages.has(packageName)) throw new Error(`${packageName} is updating; try again shortly`)\n if (uninstallingPackages.has(packageName)) throw new Error(`${packageName} is already being uninstalled`)\n uninstallingPackages.add(packageName)\n try {\n const res = await appRegistry.uninstall(packageName, version, options)\n if (res.is_error()) throw res.error\n set((s) => ({apps: s.apps.filter((a) => a.packageName !== packageName)}))\n } finally {\n uninstallingPackages.delete(packageName)\n }\n })\n },\n\n saveScreenshot: async (packageName: string, screenshot: string) => {\n storage.save(`${packageName}_screenshot`, screenshot)\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, screenshot} : a)),\n }))\n },\n\n setHiddenStatus: (packageName: string, status: boolean) => {\n hiddenStatusCache.set(packageName, status)\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, hidden: status} : a)),\n }))\n storage.save(`${packageName}_hidden`, status)\n if (!status) {\n const orderMap = getAppsOrder()\n if (orderMap.is_ok()) {\n delete orderMap.value[packageName]\n saveAppsOrder(orderMap.value)\n }\n }\n },\n\n getHiddenStatus: (packageName: string): boolean => {\n const cached = hiddenStatusCache.get(packageName)\n if (cached !== undefined) return cached\n const res = storage.load<boolean>(`${packageName}_hidden`)\n const value = res.is_ok() ? res.value : false\n hiddenStatusCache.set(packageName, value)\n return value\n },\n\n setApps: (apps) =>\n set((state) => ({apps: apps.map((app) => ({...app, updating: state.updatingPackages.has(app.packageName)}))})),\n}))\n\n// Project miniappRunningRegistry membership into the store's `running` field\n// for local apps so the home tray and switcher reflect actual mount state\n// without waiting for the next refresh() cycle.\nminiappRunningRegistry.subscribe(() => {\n const running = new Set(miniappRunningRegistry.getAll())\n const state = useAppStatusStore.getState()\n let changed = false\n const updated = state.apps.map((app) => {\n if (!app.local) return app\n const next = running.has(app.packageName)\n if (app.running === next) return app\n changed = true\n return {...app, running: next}\n })\n if (changed) {\n useAppStatusStore.setState({apps: updated})\n }\n})\n\n/**\n * The miniapp the user can see: the foregrounded one, while the Mentra App itself is in the foreground. The store\n * keeps a miniapp foregrounded when the app goes to the background or the phone locks; it is not visible then.\n */\nexport function visibleMiniappPackage(\n state: Pick<AppStatusState, \"foregroundedPackage\"> = useAppStatusStore.getState(),\n): string | null {\n return AppState.currentState === \"active\" ? state.foregroundedPackage : null\n}\n\n// Native built-ins have no JS context, so they never enter miniappRunningRegistry. Which of them is executing is\n// derived here, from the store every open, minimize and stop goes through, and from the app state: one that executes\n// while open (Gallery) only while it is running and visible, one that executes while running (Notify) whenever it\n// runs. A running flag alone is not execution for the first kind: it outlives a minimize, and even a restart.\nfunction executingNativeMiniapps(state: AppStatusState): string[] {\n const visible = visibleMiniappPackage(state)\n const executing: string[] = []\n for (const app of state.apps) {\n if (app.local || !app.running) continue\n if (app.nativeExecution === \"running\" || (app.nativeExecution === \"open\" && app.packageName === visible)) {\n executing.push(app.packageName)\n }\n }\n return executing\n}\n/** The built-ins that execute while they run (Notify) that were executing at the last publish. */\nlet executingWhileRunning: ReadonlySet<string> = new Set()\n\n/**\n * A built-in that executes while it runs, and starts running without the store's `start`, was restored: its running\n * flag was read back after a process death. That is an automatic launch. A `start` claims, and reports, its own.\n */\nfunction reportRestoredBuiltIns(state: AppStatusState, executing: readonly string[]): void {\n const now = new Set<string>()\n for (const app of state.apps) {\n if (app.local || app.nativeExecution !== \"running\" || !executing.includes(app.packageName)) continue\n now.add(app.packageName)\n if (executingWhileRunning.has(app.packageName)) continue\n fleetEvents.launchUnlessClaimed({\n packageName: app.packageName,\n miniappName: app.name,\n versionName: app.version,\n start: \"automatic\",\n outcome: \"started\",\n })\n }\n executingWhileRunning = now\n}\n\nconst publishNativeExecution = () => {\n const state = useAppStatusStore.getState()\n const executing = executingNativeMiniapps(state)\n reportRestoredBuiltIns(state, executing)\n nativeMiniappExecution.set(executing)\n}\nuseAppStatusStore.subscribe(publishNativeExecution)\nAppState.addEventListener(\"change\", publishNativeExecution)\n\n// The display-manager's core (foreground) slot is DERIVED state: always the\n// currently-running standard app, no matter HOW it came to run — user tap\n// (start()), boot restore (autostartLocalMiniapps → registry projection\n// above), crash-respawn, or interop. One reconciler instead of per-path call\n// sites, so no launch/stop path can forget to claim or release the slot.\n// onCoreAppChange is idempotent, so firing on every store write is free.\nuseAppStatusStore.subscribe((state) => {\n const core = state.apps.find((a) => a.running && (a.type === \"standard\" || !a.type))\n localDisplayManager.onCoreAppChange(core?.packageName ?? null)\n})\n\n// AppRegistry change events trigger a store refresh.\nappRegistry.subscribe(() => {\n void useAppStatusStore.getState().refresh()\n})\n\n// Re-evaluate hardware compatibility when the paired/default wearable changes.\nuseSettingsStore.subscribe(\n (state) => state.getSetting(SETTINGS.default_wearable.key),\n () => {\n void useAppStatusStore.getState().refresh()\n },\n)\n\n// ---------------------------------------------------------------------------\n// Public hooks\n// ---------------------------------------------------------------------------\n\nexport const useApps = () => useAppStatusStore((state) => state.apps)\n\n/** `start` for a person's own action (a tap on Home): the launch is reported as a user start unless the caller says otherwise. */\nconst startForUser: AppStatusState[\"start\"] = (app, opts) =>\n useAppStatusStore.getState().start(app, {...opts, trigger: opts?.trigger ?? \"user\"})\n\n/** The start function for UI the user acts in. Automatic and system callers use the store's `start` directly. */\nexport const useStart = () => startForUser\nexport const useStop = () => useAppStatusStore((state) => state.stop)\nexport const useSetForeground = () => useAppStatusStore((state) => state.setForeground)\nexport const useClearForeground = () => useAppStatusStore((state) => state.clearForeground)\nexport const useRefresh = () => useAppStatusStore((state) => state.refresh)\nexport const useStopAll = () => useAppStatusStore((state) => state.stopAll)\nexport const useInstall = () => useAppStatusStore((state) => state.install)\nexport const useUninstall = () => useAppStatusStore((state) => state.uninstall)\n\nexport const useActiveApps = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.running), [apps])\n}\n\nexport const useActiveBackgroundApps = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.type === \"background\" && app.running), [apps])\n}\n\nexport const useBackgroundApps = () => {\n const apps = useApps()\n return useMemo(\n () => ({\n active: apps.filter((app) => app.type === \"background\" && app.running),\n inactive: apps.filter((app) => app.type === \"background\" && !app.running),\n }),\n [apps],\n )\n}\n\nexport const useActiveForegroundApp = () => {\n const apps = useApps()\n return useMemo(() => apps.find((app) => (app.type === \"standard\" || !app.type) && app.running) ?? null, [apps])\n}\n\n/**\n * The single app currently foregrounded in the Compositor overlay, or null.\n * Driven by setForeground/clearForeground — distinct from the \"active\n * standard app\" (running) selector above.\n */\nexport const useForegroundApp = () => {\n const apps = useApps()\n return useMemo(() => apps.find((app) => app.foregrounded) ?? null, [apps])\n}\n\nexport const useActiveBackgroundAppsCount = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.type === \"background\" && app.running).length, [apps])\n}\n\nexport const useLocalMiniApps = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.local), [apps])\n}\n"]}
|
|
1
|
+
{"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/stores/apps.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Engine apps store — runtime state of installed and local applets.\n *\n * The OEM-facing API: subscribe to the running set, install/uninstall\n * miniapps, start/stop them. The store delegates install plumbing to\n * AppRegistry, and exposes hooks (`useApps`, `useStart`, `useStop`,\n * `useRefresh`, `useStopAll`) that the host UI can read.\n *\n * Source of `apps`:\n * - Local: appRegistry.getInstalledMiniapps() (always)\n */\n\nimport {useMemo} from \"react\"\nimport {AppState} from \"react-native\"\nimport {AsyncResult, Result, result as Res} from \"typesafe-ts\"\nimport {create} from \"zustand\"\nimport type {FleetLaunchFailureReason} from \"@mentra/cloud-protocol\"\n\nimport type {ClientApp} from \"../types/applet\"\nimport {DeviceTypes} from \"../types/enums\"\nimport {getModelCapabilities} from \"../types/hardware\"\nimport {HardwareCompatibility, type CompatibilityResult} from \"../utils/hardware/hardware\"\nimport {storage} from \"../utils/storage/storage\"\nimport appRegistry, {type UninstallOptions} from \"../services/AppRegistry\"\nimport localDisplayManager from \"../services/LocalDisplayManager\"\nimport {fleetEvents} from \"../services/fleet/fleetEvents\"\nimport {islandNotifications} from \"../services/NotificationsEmitter\"\nimport sttModelManager from \"../services/STTModelManager\"\nimport {miniappLauncher} from \"../services/MiniappLauncher\"\nimport {checkMiniappAge, isMiniappAgeGateOn, miniappRequiredAge} from \"../services/miniappAgeGate\"\nimport {miniappRunningRegistry} from \"../services/MiniappRunningRegistry\"\nimport {nativeMiniappExecution} from \"../services/NativeMiniappExecution\"\nimport {noteMiniappOpened} from \"../services/runningUpdatePrompt\"\nimport {isMiniappAvailable} from \"../runtime/bootstrap\"\nimport {resolveHiddenStatus} from \"./appVisibility\"\nimport {SETTINGS, useSettingsStore} from \"./settings\"\nimport BluetoothSdk from \"@mentra/bluetooth-sdk\"\n\n// ---------------------------------------------------------------------------\n// Configuration / hooks\n// ---------------------------------------------------------------------------\n\nexport interface StartOptions {\n skipNavigation?: boolean\n /** Present the app after launch checks, before bundle loading and runtime startup. */\n onAccepted?: () => void | Promise<void>\n /**\n * Who started the miniapp: `\"user\"` for a person's own choice (a tap on Home, a pick from the glasses menu),\n * `\"automatic\"` for everything else. It is the default. Fleet's launch record names it, and only a person's start\n * shows UI: an automatic start that a check refuses (glasses not connected, an update in progress, no speech\n * model) is refused silently.\n */\n trigger?: \"user\" | \"automatic\"\n}\n\n/** Host seams for a start. The refusal explanations are only for a person's own start. */\nexport interface AppStoreHooks {\n /** An open was refused because the miniapp is updating; the host explains why. */\n onUpdateBlocked?: (app: ClientApp) => void\n /**\n * A start was blocked because the app is hardware-incompatible. Engine made\n * the decision (and raised the `version_incompatible` notification); the host\n * renders its branded alert here.\n */\n onIncompatibleBlocked?: (app: ClientApp) => void\n /**\n * A start was blocked because the app requires the on-device STT model\n * (declared at registration — see AppRegistry.installOfflineApp) and none is\n * installed. Engine decided via its model manager; the host renders the\n * alert / settings navigation here.\n */\n onMissingSpeechModel?: (app: ClientApp) => void\n /** A start was refused because the miniapp's server no longer admits this account; the host explains why. */\n onAccessRevoked?: (app: ClientApp) => void\n /**\n * An open request passed the gates — fired on EVERY open, including\n * re-opening an already-running app, so the host's navigation / open\n * animation always plays.\n */\n onOpenRequested?: (app: ClientApp, opts?: StartOptions) => void\n}\n\nlet hostHooks: AppStoreHooks = {}\n\n/** The running-state change at the end of each start, one at a time (see `start`). */\nlet startTransitions: Promise<unknown> = Promise.resolve()\n/** How many times each package has been stopped, so a start can tell whether a later start stopped it. */\nconst stopCounts = new Map<string, number>()\n\nfunction oneStartAtATime<T>(transition: () => Promise<T>): Promise<T> {\n const run = startTransitions.then(transition)\n startTransitions = run.catch(() => {})\n return run\n}\nconst uninstallingPackages = new Set<string>()\nconst openedByUserListeners = new Set<(packageName: string) => void>()\n\nexport function installAppStoreHooks(hooks: AppStoreHooks): void {\n hostHooks = {...hostHooks, ...hooks}\n}\n\n/**\n * A person started a miniapp (a `\"user\"` start) and it now runs. Re-opening one\n * that already runs, and automatic starts (restoring what ran before, an\n * update's restart), are not announced. Returns an unsubscribe.\n */\nexport function onMiniappOpenedByUser(listener: (packageName: string) => void): () => void {\n openedByUserListeners.add(listener)\n return () => {\n openedByUserListeners.delete(listener)\n }\n}\n\nfunction announceOpenedByUser(packageName: string): void {\n for (const listener of [...openedByUserListeners]) {\n try {\n listener(packageName)\n } catch (error) {\n console.warn(\"Miniapp opened listener threw\", error)\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Store\n// ---------------------------------------------------------------------------\n\ninterface AppStatusState {\n apps: ClientApp[]\n /** Packages with an update downloading or activating. Opens and uninstall are refused meanwhile. */\n updatingPackages: ReadonlySet<string>\n /**\n * Mark a package as updating until the returned function is called. Throws\n * while it is already updating or being uninstalled.\n */\n beginUpdate: (packageName: string) => () => void\n /** Run `update` with the package marked as updating. */\n runUpdate: <T>(packageName: string, update: () => Promise<T>) => Promise<T>\n /**\n * Source of truth for which app is foregrounded in the Compositor overlay.\n * The per-app `foregrounded` boolean is derived from this in `projectApps`\n * so a refresh can never drop the flag when an app is transiently missing\n * from one of the two refresh passes (local-only then merged). See\n * `projectApps` / `setForeground` / `clearForeground`.\n */\n foregroundedPackage: string | null\n refresh: () => Promise<void>\n /** Resolves true if the app actually started; false if a host gate aborted it or its JS context failed to spawn. */\n start: (app: ClientApp, opts?: StartOptions) => Promise<boolean>\n stop: (packageName: string) => Promise<void>\n setForeground: (packageName: string) => Promise<void>\n clearForeground: () => void\n stopAll: () => AsyncResult<void, Error>\n install: (url: string, opts?: {versionOverride?: string}) => AsyncResult<void, Error>\n uninstall: (packageName: string, version?: string, options?: UninstallOptions) => AsyncResult<void, Error>\n saveScreenshot: (packageName: string, screenshot: string) => Promise<void>\n setHiddenStatus: (packageName: string, status: boolean) => void\n getHiddenStatus: (packageName: string) => boolean\n /** Replace the whole apps array. Hosts use this when their extra source changes. */\n setApps: (apps: ClientApp[]) => void\n}\n\nexport const DUMMY_APPLET: ClientApp = {\n packageName: \"\",\n name: \"\",\n webviewUrl: \"\",\n logoUrl: \"\",\n type: \"standard\",\n permissions: [],\n running: false,\n loading: false,\n healthy: true,\n hardwareRequirements: [],\n offline: true,\n offlineRoute: \"\",\n local: false,\n hidden: false,\n}\n\nexport type OrderMap = Record<string, number>\nconst APP_ORDER_KEY = \"foreground_apps_order\"\n\nexport const saveAppsOrder = (orderMap: OrderMap): Result<void, Error> => {\n return storage.save(APP_ORDER_KEY, orderMap)\n}\n\nexport const getAppsOrder = (): Result<OrderMap, Error> => {\n return storage.load<OrderMap>(APP_ORDER_KEY)\n}\n\n// In-memory cache for hidden flags. `projectApps` reads getHiddenStatus once\n// per app per refresh — without a cache that was a synchronous JNI hop per\n// app per refresh on a hot UI path. Kept consistent with disk by writing\n// through in setHiddenStatus. Map of packageName → hidden boolean.\nconst hiddenStatusCache = new Map<string, boolean>()\n\nconst getRawPackageNamePriority = (pkg: string): number => {\n if (pkg.includes(\"@empty\")) {\n return 1000\n }\n return 0\n}\n\nexport const sortAppsByPackageNamePriority = (a: ClientApp, b: ClientApp): number => {\n const pa = getRawPackageNamePriority(a.packageName)\n const pb = getRawPackageNamePriority(b.packageName)\n if (pa !== pb) {\n return pa - pb\n }\n return a.name.localeCompare(b.name)\n}\n\nexport const saveLastOpenTime = (packageName: string): void => {\n storage.save(`${packageName}_last_open_time`, Date.now())\n}\n\nexport const getLastOpenTime = (packageName: string): number => {\n const res = storage.load<number>(`${packageName}_last_open_time`)\n if (res.is_ok()) return res.value\n return 0\n}\n\nexport const sortAppsByLastOpenTime = async <T extends {packageName: string}>(apps: T[]): Promise<T[]> => {\n const timestamps = apps.map((app) => ({app, time: getLastOpenTime(app.packageName)}))\n return timestamps.sort((a, b) => a.time - b.time).map((entry) => entry.app)\n}\n\nconst startStopApp = async (app: ClientApp, status: boolean): Promise<void> => {\n if (!status && app.onStop) {\n try {\n app.onStop()\n } catch (e) {\n console.warn(`ISLAND: onStop threw for ${app.packageName}`, e)\n }\n }\n if (status && app.onStart) {\n try {\n app.onStart()\n } catch (e) {\n console.warn(`ISLAND: onStart threw for ${app.packageName}`, e)\n }\n }\n}\n\n/**\n * Build the final `apps` array for the store from the installed/offline app\n * source. Pure — same inputs -> same outputs.\n */\nfunction projectApps(previousState: AppStatusState, localApps: ClientApp[]): ClientApp[] {\n // Dedupe by packageName, keep first occurrence. A miniapp the host keeps\n // background-only (a Store) never enters the user-facing list.\n const byPackage = new Map<string, ClientApp>()\n for (const app of localApps) {\n if (!isMiniappAvailable(app.packageName)) continue\n if (!byPackage.has(app.packageName)) byPackage.set(app.packageName, app)\n }\n\n // Index previous snapshot for cheap lookups (was O(N²) via .find()).\n const previousByPackage = new Map<string, ClientApp>()\n for (const oldApp of previousState.apps) {\n previousByPackage.set(oldApp.packageName, oldApp)\n }\n\n const defaultWearable =\n (useSettingsStore.getState().getSetting(SETTINGS.default_wearable.key) as DeviceTypes | undefined) ||\n DeviceTypes.NONE\n const capabilities = getModelCapabilities(defaultWearable)\n\n // Single pass: dedupe → screenshot carry-over → compat → hidden, all into\n // fresh objects. The previous in-place mutation re-used object references\n // across refreshes, which broke React.memo / referential-equality\n // memoization downstream (every refresh propagated re-renders even when\n // nothing meaningful changed) AND tripped Reanimated's \"tried to modify\n // key of an object already passed to a worklet\" warning whenever the home\n // screen's animated app cards held a reference to a previous snapshot's\n // app object that we then mutated.\n //\n // Identity stability: refresh() is event-driven and fires repeatedly (and\n // twice per cycle via the local-only → merged two-pass emit). If we always\n // returned fresh objects, every poll changed the identity of EVERY app —\n // which re-rendered the Compositor (via useForegroundApp) mid-slide and made\n // the open/close animation hitch, and churned the home grid / switcher pill.\n // So we build the candidate object, then REUSE the previous reference when\n // nothing meaningful changed. Same pattern as the miniappRunningRegistry\n // projection below. A stable foreground-app reference lets the Compositor's\n // slide run uninterrupted on the UI thread.\n return Array.from(byPackage.values()).map((app) => {\n const next: ClientApp = {\n ...app,\n screenshot: previousByPackage.get(app.packageName)?.screenshot ?? app.screenshot,\n compatibility: HardwareCompatibility.checkCompatibility(app.hardwareRequirements, capabilities),\n // A registry source can force an app off the primary home screen (for\n // example, Miniapp Developer while its home-screen setting is disabled).\n // Compose that gate with the user's persisted home-screen layout instead\n // of replacing it, otherwise a default-false persisted value makes a\n // source-hidden app visible again during projection.\n hidden: resolveHiddenStatus(app.hidden, previousState.getHiddenStatus(app.packageName)),\n // Derive the foreground flag from the store's single source of truth\n // (`foregroundedPackage`), NOT from the previous snapshot. Carrying it over\n // per-app meant a refresh that momentarily omitted an app (e.g. the\n // two-pass local-only → merged emit) would reset its flag to false — which\n // raced OfflineAppHost's interceptor guard and made the hosted miniapp fall\n // through to the root router (restart). Deriving here keeps the flag stable\n // across both passes.\n foregrounded: app.packageName === previousState.foregroundedPackage,\n updating: previousState.updatingPackages.has(app.packageName),\n }\n const prev = previousByPackage.get(app.packageName)\n return prev && shallowEqualApp(prev, next) ? prev : next\n })\n}\n\n// Cheap equality check used by projectApps to preserve object identity across\n// refreshes when nothing meaningful changed. Most keys are compared by\n// reference (the source app's nested fields — permissions, hardwareRequirements,\n// parameters — are reference-stable within a refresh). The ONE exception is\n// `compatibility`, which projectApps recomputes into a fresh object every call;\n// comparing it by reference would always differ and defeat the whole point. We\n// compare it structurally instead so identity is only broken when the device's\n// actual compatibility verdict changes (e.g. glasses connect/disconnect).\nfunction shallowEqualApp(a: ClientApp, b: ClientApp): boolean {\n const aKeys = Object.keys(a) as (keyof ClientApp)[]\n const bKeys = Object.keys(b) as (keyof ClientApp)[]\n if (aKeys.length !== bKeys.length) return false\n for (const k of aKeys) {\n if (k === \"compatibility\") {\n if (!compatibilityEqual(a.compatibility, b.compatibility)) return false\n continue\n }\n if (a[k] !== b[k]) return false\n }\n return true\n}\n\nfunction compatibilityEqual(a?: CompatibilityResult, b?: CompatibilityResult): boolean {\n if (a === b) return true\n if (!a || !b) return false\n return (\n a.isCompatible === b.isCompatible &&\n a.missingRequired.length === b.missingRequired.length &&\n a.missingOptional.length === b.missingOptional.length &&\n a.warnings.length === b.warnings.length\n )\n}\n\n/** Called by a start once it is past every gate and actually starts the miniapp. */\ninterface LaunchAttempt {\n begin(): void\n}\n\n/**\n * Tells Fleet how each start went, around the launch and without touching it: the result, or the failure it throws,\n * is returned as the launch gave it. Only a start that got past every gate is a launch: `started` when it succeeded,\n * `failed` when the spawn or start itself failed. A refusal (another miniapp is loading, incompatible glasses, a\n * missing speech model, an update in progress, a package that is not available) and re-opening a miniapp that is\n * already running start nothing and are not reported. Nor is opening one of the Mentra App's own screens (a native\n * built-in that declares no `nativeExecution`), which is not a miniapp to Fleet. Fleet's `launch` never throws.\n *\n * From the moment it begins, the start claims the miniapp (`fleetEvents.claimLaunch`): the spawn it causes, which the\n * launcher reports for every other path, and the Compositor's own call to the launcher are this launch, not more.\n */\nfunction reportingLaunches(\n launch: (app: ClientApp, opts: StartOptions | undefined, attempt: LaunchAttempt) => Promise<boolean>,\n): (app: ClientApp, opts?: StartOptions) => Promise<boolean> {\n return async (clientApp, opts) => {\n let attempted = false\n let started = false\n const claim: {release?: () => FleetLaunchFailureReason | undefined} = {}\n try {\n started = await launch(clientApp, opts, {\n begin: () => {\n attempted = true\n claim.release ??= fleetEvents.claimLaunch(clientApp.packageName)\n },\n })\n return started\n } finally {\n // The launcher classified any spawn failure it held back for this start; this report carries it.\n const failureReason = claim.release?.()\n if (attempted) {\n fleetEvents.launch({\n packageName: clientApp.packageName,\n miniappName: clientApp.name,\n versionName: clientApp.version,\n start: opts?.trigger ?? \"automatic\",\n outcome: started ? \"started\" : \"failed\",\n ...(!started && failureReason ? {failureReason} : {}),\n })\n }\n }\n }\n}\n\nexport const useAppStatusStore = create<AppStatusState>((set, get) => ({\n apps: [],\n updatingPackages: new Set(),\n foregroundedPackage: null,\n\n refresh: async () => {\n const localApps = await appRegistry.getInstalledMiniapps()\n // Update and foreground state may have changed while the registry was read.\n set((state) => {\n // An app the host made unavailable loses foreground ownership. A temporary\n // registry omission keeps it, so ordinary refreshes never reopen the UI.\n const foregroundedPackage =\n state.foregroundedPackage && isMiniappAvailable(state.foregroundedPackage) ? state.foregroundedPackage : null\n return {foregroundedPackage, apps: projectApps({...state, foregroundedPackage}, localApps)}\n })\n },\n\n beginUpdate: (packageName) => {\n if (get().updatingPackages.has(packageName)) throw new Error(`${packageName} is already updating`)\n if (uninstallingPackages.has(packageName)) throw new Error(`${packageName} is being uninstalled`)\n const setUpdating = (updating: boolean) => {\n set((state) => {\n const updatingPackages = new Set(state.updatingPackages)\n if (updating) updatingPackages.add(packageName)\n else updatingPackages.delete(packageName)\n return {\n updatingPackages,\n apps: state.apps.map((app) => (app.packageName === packageName ? {...app, updating} : app)),\n }\n })\n }\n setUpdating(true)\n let ended = false\n return () => {\n if (ended) return\n ended = true\n setUpdating(false)\n }\n },\n\n runUpdate: async (packageName, update) => {\n const end = get().beginUpdate(packageName)\n try {\n return await update()\n } finally {\n end()\n }\n },\n\n start: reportingLaunches(async (clientApp: ClientApp, opts: StartOptions | undefined, attempt: LaunchAttempt) => {\n const state = get()\n const packageName = clientApp.packageName\n // Only a person's own start explains a refusal; anything else is refused silently.\n const byUser = opts?.trigger === \"user\"\n const explain = byUser ? hostHooks : {}\n if (!isMiniappAvailable(packageName)) return false\n const app = state.apps.find((a) => a.packageName === packageName)\n if (!app) {\n console.error(`ISLAND: app not found for package name: ${packageName}`)\n return false\n }\n if (state.updatingPackages.has(packageName)) {\n explain.onUpdateBlocked?.(app)\n return false\n }\n if (app.local && appRegistry.isMiniappAccessRevoked(packageName)) {\n explain.onAccessRevoked?.(app)\n return false\n }\n\n // Skip spawning a NEW app while another is mid-launch — concurrent spawns\n // race the foreground-only-one teardown. This is checked BEFORE the gates\n // and the onOpenRequested seam (which navigates/foregrounds) so a gated\n // launch doesn't paint a splash it can't back. Re-opening an already-running\n // app is exempt: it has nothing to spawn, so it skips this gate and is\n // allowed to re-navigate/animate below.\n // That exemption is the fix for the \"second tap during another app's launch\n // window silently does nothing\" bug.\n if (!app.running && state.apps.some((a) => a.loading)) {\n console.log(`ISLAND: skipping start ${packageName} — another app is loading`)\n return false\n }\n\n if (!app.offline && !app.local) {\n console.warn(`ISLAND: cloud-v1 app entries are no longer supported: ${packageName}`)\n return false\n }\n\n // Hardware-compatibility gate — engine decides and blocks; for a person's\n // start the host renders its branded alert via onIncompatibleBlocked\n // (and/or the structured notification below). `!isCompatible` (not `=== false`) keeps the semantics\n // of the host gate this replaces: an unknown verdict blocks, not launches.\n if (!app.compatibility?.isCompatible) {\n islandNotifications.emit({\n kind: \"version_incompatible\",\n packageName,\n reason: `${app.name ?? packageName} is not compatible with the connected glasses`,\n metadata: {missingRequired: app.compatibility?.missingRequired ?? []},\n timestamp: Date.now(),\n })\n explain.onIncompatibleBlocked?.(app)\n return false\n }\n\n // Missing-speech-model gate for apps registered with requiresLocalSttModel.\n // Engine decides via its own model manager; the host renders the alert and\n // any settings navigation via onMissingSpeechModel.\n if (appRegistry.requiresLocalSttModel(packageName) && !(await sttModelManager.isModelAvailable())) {\n islandNotifications.emit({\n kind: \"missing_speech_model\",\n packageName,\n reason: `${app.name ?? packageName} needs an on-device speech model before it can start`,\n timestamp: Date.now(),\n })\n explain.onMissingSpeechModel?.(app)\n return false\n }\n\n // The age gate, before the screen opens or another miniapp stops, so a refusal changes nothing: the person was\n // asked their age, or told why. Only a gated miniapp waits here. The launch is checked again as its context\n // spawns, for every other way in.\n if (app.local && !app.running && isMiniappAgeGateOn()) {\n const rated = miniappLauncher.installedAgeRating(packageName)\n if (miniappRequiredAge(rated.ageRating) !== null) {\n const verdict = await checkMiniappAge(rated, {interactive: AppState.currentState === \"active\"})\n if (verdict !== \"allowed\") return false\n }\n }\n\n // A model check or the age gate above may have yielded while an update started.\n if (get().updatingPackages.has(packageName)) {\n explain.onUpdateBlocked?.(app)\n return false\n }\n\n // Host navigation / open-animation seam. Runs on EVERY accepted open —\n // including re-opening an already-running app — so the animation always\n // plays (BuiltInMiniappCatalog.navigateForApp: overlay apps setForeground\n // for the slide).\n const presentation = opts?.onAccepted?.()\n if (presentation) await presentation\n hostHooks.onOpenRequested?.(app, opts)\n\n // First-activation mark (moved from the host's old beforeStart — engine\n // owns the settings store).\n useSettingsStore.getState().setSetting(SETTINGS.has_ever_activated_app.key, true)\n\n // If the tapped app is already running, this is a re-open: the nav/foreground\n // above already drove the animation, and there's nothing to spawn. Short-\n // circuit before the spawn pipeline. Another start of it may have finished\n // while this one waited above.\n if (app.running || get().apps.find((a) => a.packageName === packageName)?.running) {\n saveLastOpenTime(packageName)\n return true\n }\n\n // Past every gate: from here on this is a launch, reported to Fleet as started or failed. A native built-in that\n // declares no execution is the Mentra App's own interface (Settings, Feedback), not a miniapp, and is not reported.\n if (app.local || app.nativeExecution) attempt.begin()\n\n // Foreground-only-one rule: stop other running standard apps, then mark this one running. Starts that waited\n // above (the age question, a presentation) can get here together, so each does this one at a time, on the\n // state as it is then: the last one in stops the others.\n let stopsWhenMarked = 0\n await oneStartAtATime(async () => {\n if (app.type === \"standard\") {\n const runningForeground = get().apps.filter(\n (a) => a.running && a.type === \"standard\" && a.packageName !== packageName,\n )\n for (const r of runningForeground) {\n await get().stop(r.packageName)\n }\n }\n\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, running: true, loading: false} : a)),\n }))\n saveLastOpenTime(packageName)\n await startStopApp(app, true)\n stopsWhenMarked = stopCounts.get(packageName) ?? 0\n })\n // A start that came in after this one may have stopped it already: it doesn't come back.\n if ((stopCounts.get(packageName) ?? 0) !== stopsWhenMarked) return false\n\n // Spawn the background JS context for local miniapps. This used to be a\n // side effect of LocalMiniappView mounting on foreground; pulling it here\n // lets start() actually run the app even when nothing foregrounds it (e.g.\n // a system app launching another miniapp via session.miniapps). Idempotent\n // with the view's own ensureRunning; skipped for native offline built-ins\n // (no JS bundle).\n if (app.local) {\n try {\n await miniappLauncher.ensureRunning(packageName)\n } catch (e) {\n // Spawn / bundle-resolve failed — revert the optimistic running flag so\n // the home list and miniapps.list() don't show a \"running\" app with no\n // JS context, and report failure to the caller (session.miniapps.start).\n console.warn(`ISLAND: launcher.ensureRunning failed for ${packageName}`, e)\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, running: false, loading: false} : a)),\n }))\n // onStart already persisted running:true to disk (saveLocalAppRunningState)\n // before the spawn; run onStop to undo it so a refresh/reboot doesn't\n // resurrect a \"running\" app with no JS context.\n await startStopApp(app, false)\n return false\n }\n }\n\n if (byUser) announceOpenedByUser(packageName)\n return true\n }),\n\n stop: async (packageName: string) => {\n stopCounts.set(packageName, (stopCounts.get(packageName) ?? 0) + 1)\n const state = get()\n const app = state.apps.find((a) => a.packageName === packageName)\n if (!app) {\n console.error(`ISLAND: app not found for package name: ${packageName}`)\n return\n }\n\n set((s) => ({\n apps: s.apps.map((a) =>\n a.packageName === packageName ? {...a, running: false, screenshot: undefined, loading: false} : a,\n ),\n }))\n\n // if there are no apps running, call clearDisplay():\n // read fresh state via get() — `state` was captured before the set() above, so it still shows\n // this app as running and would never reach 0 when stopping the last app.\n if (get().apps.filter((a) => a.running).length === 0) {\n BluetoothSdk.clearDisplay()\n }\n await startStopApp(app, false)\n\n // Tear down the background JS context for local miniapps. No-op for native\n // offline built-ins.\n if (app.local) {\n try {\n await miniappLauncher.stop(packageName)\n } catch (e) {\n console.warn(`ISLAND: launcher.stop failed for ${packageName}`, e)\n }\n }\n },\n\n setForeground: async (packageName: string) => {\n if (!isMiniappAvailable(packageName)) return\n const app = get().apps.find((a) => a.packageName === packageName)\n if (!app) {\n console.error(`ISLAND: setForeground — app not found: ${packageName}`)\n return\n }\n if (get().updatingPackages.has(packageName)) {\n hostHooks.onUpdateBlocked?.(app)\n return\n }\n if (app.local && appRegistry.isMiniappAccessRevoked(packageName)) {\n hostHooks.onAccessRevoked?.(app)\n return\n }\n\n // Flip the foreground flag synchronously so the Compositor's open\n // animation starts on the same frame as the tap. We do NOT await start()\n // first — that gated the flag (and thus the animation) behind the whole\n // JSContext-spawn chain, which was the perceived launch delay. The\n // Compositor/LocalMiniappView already handle the spawn being in-flight\n // (the phase machine), so foregrounding needn't wait for it.\n saveLastOpenTime(packageName)\n set((s) => ({\n foregroundedPackage: packageName,\n apps: s.apps.map((a) => ({...a, foregrounded: a.packageName === packageName})),\n }))\n noteMiniappOpened(packageName)\n\n // Ensure the JSContext exists. start() is idempotent for an\n // already-running app and enforces the foreground-only-one rule for\n // standard apps. Fire-and-forget after the flag flip so it doesn't block\n // paint.\n // if (!app.running) {\n // get().start(app)\n // }\n },\n\n clearForeground: () => {\n set((s) => ({\n foregroundedPackage: null,\n apps: s.apps.some((a) => a.foregrounded)\n ? s.apps.map((a) => (a.foregrounded ? {...a, foregrounded: false} : a))\n : s.apps,\n }))\n },\n\n stopAll: () => {\n return Res.try_async(async () => {\n const running = get().apps.filter((a) => a.running)\n for (const a of running) {\n await get().stop(a.packageName)\n }\n })\n },\n\n install: (url, opts) => appRegistry.installFromUrl(url, opts),\n\n uninstall: (packageName, version, options) => {\n return Res.try_async(async () => {\n if (get().updatingPackages.has(packageName)) throw new Error(`${packageName} is updating; try again shortly`)\n if (uninstallingPackages.has(packageName)) throw new Error(`${packageName} is already being uninstalled`)\n uninstallingPackages.add(packageName)\n try {\n // Only for Fleet's record: a lookup that fails (or throws) never stops the removal.\n const removed =\n version ??\n (await Promise.resolve()\n .then(() => appRegistry.getActiveVersion(packageName))\n .catch(() => undefined))\n const res = await appRegistry.uninstall(packageName, version, options)\n // Fleet (Phase 12): every removal attempt, and how it went. The reason of a failed one is not known here.\n fleetEvents.install({\n packageName,\n operation: \"remove\",\n source: options?.fleetSource ?? \"url\",\n ...(removed ? {fromVersion: removed} : {}),\n ...(res.is_error() ? {outcome: \"failed\" as const, reason: \"unknown\" as const} : {outcome: \"succeeded\" as const}),\n })\n if (res.is_error()) throw res.error\n set((s) => ({apps: s.apps.filter((a) => a.packageName !== packageName)}))\n } finally {\n uninstallingPackages.delete(packageName)\n }\n })\n },\n\n saveScreenshot: async (packageName: string, screenshot: string) => {\n storage.save(`${packageName}_screenshot`, screenshot)\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, screenshot} : a)),\n }))\n },\n\n setHiddenStatus: (packageName: string, status: boolean) => {\n hiddenStatusCache.set(packageName, status)\n set((s) => ({\n apps: s.apps.map((a) => (a.packageName === packageName ? {...a, hidden: status} : a)),\n }))\n storage.save(`${packageName}_hidden`, status)\n if (!status) {\n const orderMap = getAppsOrder()\n if (orderMap.is_ok()) {\n delete orderMap.value[packageName]\n saveAppsOrder(orderMap.value)\n }\n }\n },\n\n getHiddenStatus: (packageName: string): boolean => {\n const cached = hiddenStatusCache.get(packageName)\n if (cached !== undefined) return cached\n const res = storage.load<boolean>(`${packageName}_hidden`)\n const value = res.is_ok() ? res.value : false\n hiddenStatusCache.set(packageName, value)\n return value\n },\n\n setApps: (apps) =>\n set((state) => ({apps: apps.map((app) => ({...app, updating: state.updatingPackages.has(app.packageName)}))})),\n}))\n\n// Project miniappRunningRegistry membership into the store's `running` field\n// for local apps so the home tray and switcher reflect actual mount state\n// without waiting for the next refresh() cycle.\nminiappRunningRegistry.subscribe(() => {\n const running = new Set(miniappRunningRegistry.getAll())\n const state = useAppStatusStore.getState()\n let changed = false\n const updated = state.apps.map((app) => {\n if (!app.local) return app\n const next = running.has(app.packageName)\n if (app.running === next) return app\n changed = true\n return {...app, running: next}\n })\n if (changed) {\n useAppStatusStore.setState({apps: updated})\n }\n})\n\n/**\n * The miniapp the user can see: the foregrounded one, while the Mentra App itself is in the foreground. The store\n * keeps a miniapp foregrounded when the app goes to the background or the phone locks; it is not visible then.\n */\nexport function visibleMiniappPackage(\n state: Pick<AppStatusState, \"foregroundedPackage\"> = useAppStatusStore.getState(),\n): string | null {\n return AppState.currentState === \"active\" ? state.foregroundedPackage : null\n}\n\n// Native built-ins have no JS context, so they never enter miniappRunningRegistry. Which of them is executing is\n// derived here, from the store every open, minimize and stop goes through, and from the app state: one that executes\n// while open (Gallery) only while it is running and visible, one that executes while running (Notify) whenever it\n// runs. A running flag alone is not execution for the first kind: it outlives a minimize, and even a restart.\nfunction executingNativeMiniapps(state: AppStatusState): string[] {\n const visible = visibleMiniappPackage(state)\n const executing: string[] = []\n for (const app of state.apps) {\n if (app.local || !app.running) continue\n if (app.nativeExecution === \"running\" || (app.nativeExecution === \"open\" && app.packageName === visible)) {\n executing.push(app.packageName)\n }\n }\n return executing\n}\n/** The built-ins that execute while they run (Notify) that were executing at the last publish. */\nlet executingWhileRunning: ReadonlySet<string> = new Set()\n\n/**\n * A built-in that executes while it runs, and starts running without the store's `start`, was restored: its running\n * flag was read back after a process death. That is an automatic launch. A `start` claims, and reports, its own.\n */\nfunction reportRestoredBuiltIns(state: AppStatusState, executing: readonly string[]): void {\n const now = new Set<string>()\n for (const app of state.apps) {\n if (app.local || app.nativeExecution !== \"running\" || !executing.includes(app.packageName)) continue\n now.add(app.packageName)\n if (executingWhileRunning.has(app.packageName)) continue\n fleetEvents.launchUnlessClaimed({\n packageName: app.packageName,\n miniappName: app.name,\n versionName: app.version,\n start: \"automatic\",\n outcome: \"started\",\n })\n }\n executingWhileRunning = now\n}\n\nconst publishNativeExecution = () => {\n const state = useAppStatusStore.getState()\n const executing = executingNativeMiniapps(state)\n reportRestoredBuiltIns(state, executing)\n nativeMiniappExecution.set(executing)\n}\nuseAppStatusStore.subscribe(publishNativeExecution)\nAppState.addEventListener(\"change\", publishNativeExecution)\n\n// The display-manager's core (foreground) slot is DERIVED state: always the\n// currently-running standard app, no matter HOW it came to run — user tap\n// (start()), boot restore (autostartLocalMiniapps → registry projection\n// above), crash-respawn, or interop. One reconciler instead of per-path call\n// sites, so no launch/stop path can forget to claim or release the slot.\n// onCoreAppChange is idempotent, so firing on every store write is free.\nuseAppStatusStore.subscribe((state) => {\n const core = state.apps.find((a) => a.running && (a.type === \"standard\" || !a.type))\n localDisplayManager.onCoreAppChange(core?.packageName ?? null)\n})\n\n// AppRegistry change events trigger a store refresh.\nappRegistry.subscribe(() => {\n void useAppStatusStore.getState().refresh()\n})\n\n// Re-evaluate hardware compatibility when the paired/default wearable changes.\nuseSettingsStore.subscribe(\n (state) => state.getSetting(SETTINGS.default_wearable.key),\n () => {\n void useAppStatusStore.getState().refresh()\n },\n)\n\n// ---------------------------------------------------------------------------\n// Public hooks\n// ---------------------------------------------------------------------------\n\nexport const useApps = () => useAppStatusStore((state) => state.apps)\n\n/** `start` for a person's own action (a tap on Home): the launch is reported as a user start unless the caller says otherwise. */\nconst startForUser: AppStatusState[\"start\"] = (app, opts) =>\n useAppStatusStore.getState().start(app, {...opts, trigger: opts?.trigger ?? \"user\"})\n\n/** The start function for UI the user acts in. Automatic and system callers use the store's `start` directly. */\nexport const useStart = () => startForUser\nexport const useStop = () => useAppStatusStore((state) => state.stop)\nexport const useSetForeground = () => useAppStatusStore((state) => state.setForeground)\nexport const useClearForeground = () => useAppStatusStore((state) => state.clearForeground)\nexport const useRefresh = () => useAppStatusStore((state) => state.refresh)\nexport const useStopAll = () => useAppStatusStore((state) => state.stopAll)\nexport const useInstall = () => useAppStatusStore((state) => state.install)\nexport const useUninstall = () => useAppStatusStore((state) => state.uninstall)\n\nexport const useActiveApps = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.running), [apps])\n}\n\nexport const useActiveBackgroundApps = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.type === \"background\" && app.running), [apps])\n}\n\nexport const useBackgroundApps = () => {\n const apps = useApps()\n return useMemo(\n () => ({\n active: apps.filter((app) => app.type === \"background\" && app.running),\n inactive: apps.filter((app) => app.type === \"background\" && !app.running),\n }),\n [apps],\n )\n}\n\nexport const useActiveForegroundApp = () => {\n const apps = useApps()\n return useMemo(() => apps.find((app) => (app.type === \"standard\" || !app.type) && app.running) ?? null, [apps])\n}\n\n/**\n * The single app currently foregrounded in the Compositor overlay, or null.\n * Driven by setForeground/clearForeground — distinct from the \"active\n * standard app\" (running) selector above.\n */\nexport const useForegroundApp = () => {\n const apps = useApps()\n return useMemo(() => apps.find((app) => app.foregrounded) ?? null, [apps])\n}\n\nexport const useActiveBackgroundAppsCount = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.type === \"background\" && app.running).length, [apps])\n}\n\nexport const useLocalMiniApps = () => {\n const apps = useApps()\n return useMemo(() => apps.filter((app) => app.local), [apps])\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mentra/engine",
|
|
3
|
-
"version": "3.4.0-dev.
|
|
3
|
+
"version": "3.4.0-dev.1209",
|
|
4
4
|
"description": "Mentra Engine — miniapp registry, WebView bridge, and miniapp store",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"react-native": "src/index.ts",
|
|
@@ -97,13 +97,13 @@
|
|
|
97
97
|
"registry": "https://registry.npmjs.org/"
|
|
98
98
|
},
|
|
99
99
|
"dependencies": {
|
|
100
|
-
"@mentra/acs-meeting": "3.4.0-dev.
|
|
101
|
-
"@mentra/glasses-media": "3.4.0-dev.
|
|
102
|
-
"@mentra/bluetooth-sdk": "3.4.0-dev.
|
|
103
|
-
"@mentra/cloud-client": "3.4.0-dev.
|
|
104
|
-
"@mentra/cloud-protocol": "3.4.0-dev.
|
|
105
|
-
"@mentra/crust": "3.4.0-dev.
|
|
106
|
-
"@mentra/miniapp": "3.4.0-dev.
|
|
100
|
+
"@mentra/acs-meeting": "3.4.0-dev.1209",
|
|
101
|
+
"@mentra/glasses-media": "3.4.0-dev.1209",
|
|
102
|
+
"@mentra/bluetooth-sdk": "3.4.0-dev.1209",
|
|
103
|
+
"@mentra/cloud-client": "3.4.0-dev.1209",
|
|
104
|
+
"@mentra/cloud-protocol": "3.4.0-dev.1209",
|
|
105
|
+
"@mentra/crust": "3.4.0-dev.1209",
|
|
106
|
+
"@mentra/miniapp": "3.4.0-dev.1209",
|
|
107
107
|
"buffer": "^6.0.3",
|
|
108
108
|
"events": "^3.3.0",
|
|
109
109
|
"jszip": "^3.10.1",
|
package/src/facades/glasses.ts
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// standalone build); jest moduleNameMapper + tsconfig both resolve it.
|
|
13
13
|
import BluetoothSdk from "@mentra/bluetooth-sdk/internal"
|
|
14
14
|
import type {ButtonPressEvent, ConnectOptions, Device, TouchEvent} from "@mentra/bluetooth-sdk"
|
|
15
|
+
import {fleetEvents} from "../services/fleet/fleetEvents"
|
|
15
16
|
import {useGlassesStore} from "../stores/glasses"
|
|
16
17
|
import {useSettingsStore, SETTINGS} from "../stores/settings"
|
|
17
18
|
import {hasDefaultDevice} from "../services/DeviceStoreHydration"
|
|
@@ -94,10 +95,11 @@ export const glasses = {
|
|
|
94
95
|
throw error
|
|
95
96
|
}
|
|
96
97
|
},
|
|
97
|
-
disconnect
|
|
98
|
-
|
|
98
|
+
// Fleet counts a disconnect the person asked for as theirs, not as a connection problem (Phase 12).
|
|
99
|
+
disconnect: (): Promise<void> => (fleetEvents.userDisconnect(), BluetoothSdk.disconnect()),
|
|
100
|
+
forget: (): Promise<void> => (fleetEvents.userDisconnect(), BluetoothSdk.forget()),
|
|
99
101
|
/** Explicit user Unpair; NIMO is reset before its local pairing is cleared. */
|
|
100
|
-
unpair: (): Promise<void> => BluetoothSdk.unpair(),
|
|
102
|
+
unpair: (): Promise<void> => (fleetEvents.userDisconnect(), BluetoothSdk.unpair()),
|
|
101
103
|
/** Connect to a specific (discovered) device. */
|
|
102
104
|
connect: async (device: Device, options?: ConnectOptions): Promise<void> => {
|
|
103
105
|
try {
|
|
@@ -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.4.0",
|
|
15
|
-
"releaseIdentity": "3.4.0-dev.
|
|
16
|
-
"releaseSetId": "mentra-3.4.0-dev.
|
|
17
|
-
"sourceCommit": "
|
|
18
|
-
"otaManifestUrl": "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.4.0/mentra-live-ota-3.4.0-dev.
|
|
19
|
-
"otaManifestSha256": "
|
|
15
|
+
"releaseIdentity": "3.4.0-dev.1209",
|
|
16
|
+
"releaseSetId": "mentra-3.4.0-dev.1209",
|
|
17
|
+
"sourceCommit": "1f73b5402e1a0b5f06000b84300695f0dfc879c1",
|
|
18
|
+
"otaManifestUrl": "https://artifactscdn.mentraglass.com/Mentra-Community/MentraOS/releases/mentra-builds-v3.4.0/mentra-live-ota-3.4.0-dev.1209.json",
|
|
19
|
+
"otaManifestSha256": "f93b7fed880136625a8b29c4e74210e882b5322bd79f76aa84d79a31bb95b82a"
|
|
20
20
|
})
|
|
@@ -293,6 +293,8 @@ export interface UninstallOptions {
|
|
|
293
293
|
* that checked what it may remove checks again here, where no install can change it.
|
|
294
294
|
*/
|
|
295
295
|
beforeRemove?: () => void
|
|
296
|
+
/** What Fleet records the removal as started by (Phase 12, `miniapp_install`); the person's own removal by default. */
|
|
297
|
+
fleetSource?: "url" | "assignment" | "manifest" | "local" | "bundled"
|
|
296
298
|
}
|
|
297
299
|
|
|
298
300
|
/** Local ZIP installs may additionally adopt an identical, already installed bundle. */
|
|
@@ -989,6 +989,11 @@ class LocalMiniappRuntime {
|
|
|
989
989
|
// App registration
|
|
990
990
|
// ===========================================================================
|
|
991
991
|
|
|
992
|
+
/** The installed version of a connected miniapp, for Fleet's records; undefined when it is not known. */
|
|
993
|
+
public installedVersionOf(packageName: string): string | undefined {
|
|
994
|
+
return this.connectedApps.get(packageName)?.installedManifest?.version || undefined
|
|
995
|
+
}
|
|
996
|
+
|
|
992
997
|
public registerApp(
|
|
993
998
|
packageName: string,
|
|
994
999
|
sendFn: (raw: string) => void,
|
|
@@ -1736,6 +1741,19 @@ class LocalMiniappRuntime {
|
|
|
1736
1741
|
// MentraJSRouter observes READY to open the UI; nothing to do here.
|
|
1737
1742
|
break
|
|
1738
1743
|
|
|
1744
|
+
case MiniappRequestType.TELEMETRY_CAPTURE:
|
|
1745
|
+
// A miniapp's own event (`session.telemetry.capture`). It is this package's because it came over this
|
|
1746
|
+
// package's bridge, whatever the payload says; the Fleet collector applies the limits. One-shot: no reply.
|
|
1747
|
+
fleetEvents.telemetry({
|
|
1748
|
+
packageName,
|
|
1749
|
+
...(this.connectedApps.get(packageName)?.installedManifest?.version
|
|
1750
|
+
? {versionName: this.connectedApps.get(packageName)!.installedManifest!.version}
|
|
1751
|
+
: {}),
|
|
1752
|
+
event: payload.event,
|
|
1753
|
+
properties: payload.properties,
|
|
1754
|
+
})
|
|
1755
|
+
break
|
|
1756
|
+
|
|
1739
1757
|
default:
|
|
1740
1758
|
// NACK instead of silent drop (issue 021 S3): an SDK that sends a
|
|
1741
1759
|
// request this runtime doesn't implement must get a rejected promise,
|
|
@@ -1811,7 +1829,8 @@ class LocalMiniappRuntime {
|
|
|
1811
1829
|
configuration: getMiniappConfiguration(packageName),
|
|
1812
1830
|
// The SDK's HostFeatures. miniappInstall: system-list miniapps may call session.miniapps.install({url});
|
|
1813
1831
|
// the Mentra Apps before it answer NOT_PERMITTED.
|
|
1814
|
-
|
|
1832
|
+
// telemetry: `session.telemetry.capture` reaches the workspace's Fleet Management (Phase 12).
|
|
1833
|
+
hostFeatures: {captureAudio: true, initReady: true, transcriptionListeners: true, miniappInstall: true, telemetry: true},
|
|
1815
1834
|
},
|
|
1816
1835
|
requestId,
|
|
1817
1836
|
)
|
|
@@ -106,6 +106,11 @@ export class MentraJSCrashController {
|
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
/** The crashes of `packageName` inside the current crash window, the latest included (Fleet's `crashesInWindow`). */
|
|
110
|
+
crashCount(packageName: string): number {
|
|
111
|
+
return this.packages.get(packageName)?.crashesInWindow.length ?? 0
|
|
112
|
+
}
|
|
113
|
+
|
|
109
114
|
/** Called when MentraJSRouter explicitly tears down (user-initiated). */
|
|
110
115
|
onKill(packageName: string): void {
|
|
111
116
|
this.packages.delete(packageName)
|
|
@@ -33,9 +33,11 @@
|
|
|
33
33
|
* visible without bringing up a separate sink.
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
|
+
import type {FleetCrashCategory} from "@mentra/cloud-protocol"
|
|
36
37
|
import type {EventSubscription} from "expo-modules-core"
|
|
37
38
|
|
|
38
39
|
import devServerBridge from "./DevServerBridge"
|
|
40
|
+
import {fleetEvents} from "./fleet/fleetEvents"
|
|
39
41
|
import type localMiniappRuntime from "./LocalMiniappRuntime"
|
|
40
42
|
import type {InstalledMiniappManifest} from "./LocalMiniappRuntime"
|
|
41
43
|
import type {MentraJSCrashController} from "./MentraJSCrashController"
|
|
@@ -201,7 +203,7 @@ export class MentraJSRouter {
|
|
|
201
203
|
// respawn machinery as a crash so it comes back automatically, with
|
|
202
204
|
// the crash controller's backoff + crash-loop protection.
|
|
203
205
|
this.runtime.onLivenessTimeout = (packageName) => {
|
|
204
|
-
this.handleCrash(packageName, "liveness: missed pings")
|
|
206
|
+
this.handleCrash(packageName, "liveness: missed pings", "unresponsive")
|
|
205
207
|
}
|
|
206
208
|
}
|
|
207
209
|
|
|
@@ -337,7 +339,7 @@ export class MentraJSRouter {
|
|
|
337
339
|
* handler. The controller returns an outcome that tells us whether
|
|
338
340
|
* to respawn (with delay) or leave the context dead.
|
|
339
341
|
*/
|
|
340
|
-
private handleCrash(packageName: string, reason: string): void {
|
|
342
|
+
private handleCrash(packageName: string, reason: string, category: FleetCrashCategory = "unknown"): void {
|
|
341
343
|
const cached = this.spawnCache.get(packageName)
|
|
342
344
|
// A transient action cannot resume after a crash. Remove the worker (which
|
|
343
345
|
// fails its pending invocations); only a new invocation may spawn another.
|
|
@@ -371,6 +373,16 @@ export class MentraJSRouter {
|
|
|
371
373
|
return
|
|
372
374
|
}
|
|
373
375
|
const outcome = controller.onCrash(packageName, reason)
|
|
376
|
+
// Fleet hears the crash by its category, never its reason text (Phase 12).
|
|
377
|
+
const versionName = this.runtime.installedVersionOf?.(packageName)
|
|
378
|
+
fleetEvents.crash({
|
|
379
|
+
packageName,
|
|
380
|
+
...(versionName ? {versionName} : {}),
|
|
381
|
+
surface: "context",
|
|
382
|
+
category,
|
|
383
|
+
outcome: outcome.surfaceCrashloopBanner || outcome.scheduleRespawnAfterMs == null ? "crash_loop_stopped" : "respawn_scheduled",
|
|
384
|
+
crashesInWindow: Math.max(1, controller.crashCount(packageName)),
|
|
385
|
+
})
|
|
374
386
|
if (outcome.surfaceCrashloopBanner) {
|
|
375
387
|
this.uiRouter?.backgroundStopped(packageName)
|
|
376
388
|
this.onCrashloop?.(packageName, reason)
|
|
@@ -621,7 +633,7 @@ export class MentraJSRouter {
|
|
|
621
633
|
// log path — those don't end the JSContext.
|
|
622
634
|
const isCrash = method === "exception" || method === "unhandledRejection" || method === "uncaught"
|
|
623
635
|
if (isCrash) {
|
|
624
|
-
this.handleCrash(packageName, this.summarizeReason(payload, method))
|
|
636
|
+
this.handleCrash(packageName, this.summarizeReason(payload, method), "uncaught_exception")
|
|
625
637
|
}
|
|
626
638
|
}
|
|
627
639
|
return
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
* declared already.
|
|
37
37
|
*/
|
|
38
38
|
|
|
39
|
+
import type {FleetLaunchFailureReason} from "@mentra/cloud-protocol"
|
|
39
40
|
import {File} from "expo-file-system"
|
|
40
41
|
import {AppState, Platform} from "react-native"
|
|
41
42
|
|
|
@@ -180,6 +181,19 @@ function serverOrigin(url: string): string | null {
|
|
|
180
181
|
return match ? match[1].toLowerCase() : null
|
|
181
182
|
}
|
|
182
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Why a launch failed, as the code Fleet takes (Phase 12): never the error's text. A bundle that cannot be found is
|
|
186
|
+
* `bundle_missing`; a deployment, age or access block `policy_blocked`; a context that did not start `spawn_failed`.
|
|
187
|
+
*/
|
|
188
|
+
export function launchFailureReason(error: unknown): FleetLaunchFailureReason {
|
|
189
|
+
if (error instanceof MiniappAgeRestrictedError || error instanceof MiniappAccessRevokedError) return "policy_blocked"
|
|
190
|
+
const message = error instanceof Error ? error.message : ""
|
|
191
|
+
if (message.includes("cannot resolve bundle")) return "bundle_missing"
|
|
192
|
+
if (message.includes("by deployment policy")) return "policy_blocked"
|
|
193
|
+
if (message.includes("spawn failed")) return "spawn_failed"
|
|
194
|
+
return "unknown"
|
|
195
|
+
}
|
|
196
|
+
|
|
183
197
|
class MiniappLauncher {
|
|
184
198
|
private deps: LauncherDeps | null = null
|
|
185
199
|
|
|
@@ -525,7 +539,7 @@ class MiniappLauncher {
|
|
|
525
539
|
result = await pending
|
|
526
540
|
} catch (error) {
|
|
527
541
|
// A visible launch reports its own failure; one joined to a hidden wake fails with it.
|
|
528
|
-
if (projectRunning && joinedHidden) this.reportLaunch(packageName, "failed", runtimeOptions)
|
|
542
|
+
if (projectRunning && joinedHidden) this.reportLaunch(packageName, "failed", runtimeOptions, undefined, launchFailureReason(error))
|
|
529
543
|
throw error
|
|
530
544
|
}
|
|
531
545
|
if (projectRunning && this.promote(packageName)) this.reportLaunch(packageName, "started", runtimeOptions)
|
|
@@ -538,7 +552,7 @@ class MiniappLauncher {
|
|
|
538
552
|
try {
|
|
539
553
|
return await launch
|
|
540
554
|
} catch (error) {
|
|
541
|
-
if (projectRunning) this.reportLaunch(packageName, "failed", runtimeOptions)
|
|
555
|
+
if (projectRunning) this.reportLaunch(packageName, "failed", runtimeOptions, undefined, launchFailureReason(error))
|
|
542
556
|
throw error
|
|
543
557
|
} finally {
|
|
544
558
|
this.inFlight.delete(packageName)
|
|
@@ -560,6 +574,7 @@ class MiniappLauncher {
|
|
|
560
574
|
outcome: "started" | "failed",
|
|
561
575
|
runtimeOptions?: RuntimeLaunchOptions,
|
|
562
576
|
manifest?: InstalledMiniappManifest,
|
|
577
|
+
failureReason?: FleetLaunchFailureReason,
|
|
563
578
|
): void {
|
|
564
579
|
fleetEvents.launchUnlessClaimed({
|
|
565
580
|
packageName,
|
|
@@ -567,6 +582,7 @@ class MiniappLauncher {
|
|
|
567
582
|
...(manifest?.version ? {versionName: manifest.version} : {}),
|
|
568
583
|
start: runtimeOptions?.trigger ?? "automatic",
|
|
569
584
|
outcome,
|
|
585
|
+
...(outcome === "failed" ? {failureReason: failureReason ?? "unknown"} : {}),
|
|
570
586
|
})
|
|
571
587
|
}
|
|
572
588
|
|