@glassly/engine 0.4.0-beta.1023 → 0.4.0-beta.1045
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/engine.d.ts +2 -1
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +6 -4
- package/build/engine.js.map +1 -1
- package/build/facades/glasses.js +1 -1
- package/build/facades/glasses.js.map +1 -1
- package/build/facades/providerKeys.d.ts +1 -1
- package/build/facades/providerKeys.js +1 -1
- package/build/facades/providerKeys.js.map +1 -1
- package/build/facades/reports.d.ts +15 -0
- package/build/facades/reports.d.ts.map +1 -1
- package/build/facades/reports.js +37 -0
- package/build/facades/reports.js.map +1 -1
- package/build/generated/releaseMetadata.js +3 -3
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/react/useMentraLiveOta.d.ts.map +1 -1
- package/build/react/useMentraLiveOta.js.map +1 -1
- package/build/runtime/config.d.ts.map +1 -1
- package/build/runtime/config.js.map +1 -1
- package/build/services/AiTierResolution.d.ts +1 -1
- package/build/services/AiTierResolution.d.ts.map +1 -1
- package/build/services/AiTierResolution.js.map +1 -1
- package/build/services/AutomaticReportResult.d.ts.map +1 -1
- package/build/services/AutomaticReportResult.js.map +1 -1
- package/build/services/CloudClientService.d.ts +7 -5
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +17 -14
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DisplayProcessor.d.ts.map +1 -1
- package/build/services/DisplayProcessor.js +2 -1
- package/build/services/DisplayProcessor.js.map +1 -1
- package/build/services/GestureDotsService.js +1 -1
- package/build/services/GestureDotsService.js.map +1 -1
- package/build/services/HotspotOtaTransport.d.ts.map +1 -1
- package/build/services/HotspotOtaTransport.js +0 -1
- package/build/services/HotspotOtaTransport.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +5 -2
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +54 -23
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.d.ts.map +1 -1
- package/build/services/LocalSttFallbackCoordinator.js.map +1 -1
- package/build/services/NativeNavigationService.d.ts.map +1 -1
- package/build/services/NativeNavigationService.js.map +1 -1
- package/build/services/NavigationHandlers.d.ts +1 -1
- package/build/services/NavigationHandlers.js +2 -2
- package/build/services/NavigationHandlers.js.map +1 -1
- package/build/services/NavigationService.d.ts +2 -2
- package/build/services/NavigationService.d.ts.map +1 -1
- package/build/services/NavigationService.js +11 -11
- package/build/services/NavigationService.js.map +1 -1
- package/build/services/PairingIdentity.d.ts.map +1 -1
- package/build/services/PairingIdentity.js.map +1 -1
- package/build/services/PhoneCalendarService.d.ts.map +1 -1
- package/build/services/PhoneCalendarService.js.map +1 -1
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +2 -1
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/PhoneStreamCoordinator.d.ts.map +1 -1
- package/build/services/PhoneStreamCoordinator.js.map +1 -1
- package/build/services/ProviderKeyValidation.d.ts +1 -1
- package/build/services/ProviderKeyValidation.js +1 -1
- package/build/services/ProviderKeyValidation.js.map +1 -1
- package/build/services/STTModelManager.d.ts.map +1 -1
- package/build/services/STTModelManager.js +1 -6
- package/build/services/STTModelManager.js.map +1 -1
- package/build/services/SupportProfileSync.d.ts.map +1 -1
- package/build/services/SupportProfileSync.js +3 -0
- package/build/services/SupportProfileSync.js.map +1 -1
- package/build/services/TranscriptionRouting.d.ts +3 -0
- package/build/services/TranscriptionRouting.d.ts.map +1 -1
- package/build/services/TranscriptionRouting.js +14 -0
- package/build/services/TranscriptionRouting.js.map +1 -1
- package/build/services/UIRouter.d.ts.map +1 -1
- package/build/services/UIRouter.js.map +1 -1
- package/build/services/controllers.d.ts.map +1 -1
- package/build/services/controllers.js +1 -0
- package/build/services/controllers.js.map +1 -1
- package/build/services/effectiveCapabilities.js +3 -2
- package/build/services/effectiveCapabilities.js.map +1 -1
- package/build/services/gestureDotGlyphs.d.ts.map +1 -1
- package/build/services/gestureDotGlyphs.js.map +1 -1
- package/build/services/manifestActions.d.ts.map +1 -1
- package/build/services/manifestActions.js.map +1 -1
- package/build/services/notificationAppPayload.d.ts +14 -0
- package/build/services/notificationAppPayload.d.ts.map +1 -0
- package/build/services/notificationAppPayload.js +15 -0
- package/build/services/notificationAppPayload.js.map +1 -0
- package/build/services/settingsBridge.d.ts.map +1 -1
- package/build/services/settingsBridge.js.map +1 -1
- package/build/stores/appVisibility.d.ts.map +1 -1
- package/build/stores/appVisibility.js.map +1 -1
- package/build/stores/gallerySync.d.ts.map +1 -1
- package/build/stores/gallerySync.js.map +1 -1
- package/build/stores/glasses.d.ts.map +1 -1
- package/build/stores/glasses.js +1 -0
- package/build/stores/glasses.js.map +1 -1
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +5 -3
- package/build/stores/settings.js.map +1 -1
- package/build/types/capabilities/nimo.d.ts.map +1 -1
- package/build/types/capabilities/nimo.js +19 -7
- package/build/types/capabilities/nimo.js.map +1 -1
- package/build/types/enums.d.ts +2 -1
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +1 -0
- package/build/types/enums.js.map +1 -1
- package/build/utils/display/index.d.ts +1 -0
- package/build/utils/display/index.d.ts.map +1 -1
- package/build/utils/display/index.js +2 -2
- package/build/utils/display/index.js.map +1 -1
- package/build/utils/display/profiles/index.d.ts +1 -0
- package/build/utils/display/profiles/index.d.ts.map +1 -1
- package/build/utils/display/profiles/index.js +1 -0
- package/build/utils/display/profiles/index.js.map +1 -1
- package/build/utils/display/profiles/nimo.d.ts +2 -0
- package/build/utils/display/profiles/nimo.d.ts.map +1 -0
- package/build/utils/display/profiles/nimo.js +3 -0
- package/build/utils/display/profiles/nimo.js.map +1 -0
- package/build/utils/display/scene/svgPath.js.map +1 -1
- package/build/utils/memory/search.d.ts.map +1 -1
- package/build/utils/memory/search.js +17 -7
- package/build/utils/memory/search.js.map +1 -1
- package/package.json +7 -7
- package/src/engine.ts +9 -7
- package/src/facades/glasses.ts +1 -1
- package/src/facades/providerKeys.ts +1 -1
- package/src/facades/reports.ts +41 -0
- package/src/generated/releaseMetadata.ts +3 -3
- package/src/react/useMentraLiveOta.ts +1 -4
- package/src/runtime/config.ts +1 -6
- package/src/services/AiTierResolution.ts +1 -1
- package/src/services/AutomaticReportResult.ts +1 -3
- package/src/services/CloudClientService.ts +17 -11
- package/src/services/DisplayProcessor.ts +2 -0
- package/src/services/GestureDotsService.ts +1 -1
- package/src/services/HotspotOtaTransport.ts +1 -5
- package/src/services/LocalMiniappRuntime.ts +66 -24
- package/src/services/LocalSttFallbackCoordinator.ts +1 -5
- package/src/services/NativeNavigationService.ts +1 -2
- package/src/services/NavigationHandlers.ts +2 -2
- package/src/services/NavigationService.ts +12 -11
- package/src/services/PairingIdentity.ts +1 -3
- package/src/services/PhoneCalendarService.ts +1 -3
- package/src/services/PhoneNotificationsSync.ts +2 -1
- package/src/services/PhoneStreamCoordinator.ts +1 -2
- package/src/services/ProviderKeyValidation.ts +1 -1
- package/src/services/STTModelManager.ts +1 -6
- package/src/services/SupportProfileSync.ts +2 -0
- package/src/services/TranscriptionRouting.ts +18 -0
- package/src/services/UIRouter.ts +3 -9
- package/src/services/controllers.ts +1 -0
- package/src/services/effectiveCapabilities.ts +3 -2
- package/src/services/gestureDotGlyphs.ts +10 -5
- package/src/services/manifestActions.ts +2 -1
- package/src/services/notificationAppPayload.ts +15 -0
- package/src/services/settingsBridge.ts +1 -2
- package/src/stores/appVisibility.ts +2 -5
- package/src/stores/gallerySync.ts +1 -7
- package/src/stores/glasses.ts +1 -0
- package/src/stores/settings.ts +5 -3
- package/src/types/capabilities/nimo.ts +20 -7
- package/src/types/enums.ts +1 -0
- package/src/utils/display/index.ts +2 -2
- package/src/utils/display/profiles/index.ts +2 -0
- package/src/utils/display/profiles/nimo.ts +2 -0
- package/src/utils/display/scene/svgPath.ts +1 -1
- package/src/utils/memory/search.ts +17 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SupportProfileSync.js","sourceRoot":"","sources":["../../src/services/SupportProfileSync.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from \"expo-constants\"\nimport * as Device from \"expo-device\"\nimport {Platform} from \"react-native\"\nimport type {SupportStateInput} from \"@glassly/cloud-client\"\n\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport {cloudClientService} from \"./CloudClientService\"\n\nconst ENGINE_VERSION = (require(\"../../package.json\") as {version?: string}).version\nconst BLUETOOTH_SDK_VERSION = (require(\"@glassly/bluetooth-sdk/package.json\") as {version?: string}).version\nconst DEBOUNCE_MS = 2_000\nconst RETRY_MS = 30_000\nconst HEARTBEAT_MS = 6 * 60 * 60_000\n\nlet unsubscribe: (() => void) | null = null\nlet debounceTimer: number | null = null\nlet retryTimer: number | null = null\nlet heartbeatTimer: number | null = null\nlet lastSentFingerprint: string | null = null\nlet queuedFingerprint: string | null = null\nlet sendingGeneration: number | null = null\nlet syncGeneration = 0\nlet consecutiveSendFailures = 0\nlet lastFailure: {code: string; stage: string} | null = null\nlet lastConnectionState: string | null = null\n\n/**\n * Keep Cloud's canonical support snapshot current without creating an event\n * stream from noisy store updates. Only the explicitly selected fields below\n * leave the phone; Wi-Fi, Bluetooth addresses, location and diagnostics do not.\n */\nexport function startSupportProfileSync(): void {\n if (unsubscribe) return\n const generation = ++syncGeneration\n lastConnectionState = useGlassesStore.getState().connection.state\n unsubscribe = useGlassesStore.subscribe(() => handleGlassesStoreChange(generation))\n heartbeatTimer = BgTimer.setInterval(() => void sendCurrentSnapshot(true, generation), HEARTBEAT_MS)\n void sendCurrentSnapshot(true, generation)\n}\n\nexport function stopSupportProfileSync(): void {\n syncGeneration += 1\n unsubscribe?.()\n unsubscribe = null\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n if (heartbeatTimer !== null) BgTimer.clearInterval(heartbeatTimer)\n debounceTimer = null\n retryTimer = null\n heartbeatTimer = null\n lastSentFingerprint = null\n queuedFingerprint = null\n sendingGeneration = null\n consecutiveSendFailures = 0\n lastFailure = null\n lastConnectionState = null\n}\n\nfunction handleGlassesStoreChange(generation: number): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const connectionState = useGlassesStore.getState().connection.state\n if (connectionState === \"connected\" && lastConnectionState !== \"connected\") lastFailure = null\n lastConnectionState = connectionState\n scheduleMeaningfulUpdate(generation)\n}\n\nfunction scheduleMeaningfulUpdate(generation = syncGeneration): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint === lastSentFingerprint) return\n queuedFingerprint = fingerprint\n armDebounce(generation)\n}\n\nfunction armDebounce(generation: number): void {\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n debounceTimer = BgTimer.setTimeout(() => {\n debounceTimer = null\n void sendCurrentSnapshot(false, generation)\n }, DEBOUNCE_MS)\n}\n\nasync function sendCurrentSnapshot(force: boolean, generation = syncGeneration): Promise<void> {\n if (!unsubscribe || generation !== syncGeneration) return\n if (sendingGeneration === generation) {\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint !== lastSentFingerprint) queuedFingerprint = fingerprint\n return\n }\n const snapshot = buildSnapshot()\n const fingerprint = snapshotFingerprint(snapshot)\n if (!force && fingerprint === lastSentFingerprint) return\n\n sendingGeneration = generation\n let retryDelayMs: number | null = null\n try {\n const result = await cloudClientService.core.supportProfile.update(snapshot)\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures = 0\n retryDelayMs = retryDelayForSupportProfileResult(result)\n if (retryDelayMs === null) {\n lastSentFingerprint = fingerprint\n if (queuedFingerprint === fingerprint) queuedFingerprint = null\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = null\n }\n } catch (error) {\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures += 1\n retryDelayMs = retryDelayForSendFailure(consecutiveSendFailures)\n console.warn(\n `supportProfile: Cloud update failed (retry in ${Math.round(retryDelayMs / 1_000)}s):`,\n error instanceof Error ? error.message : error,\n )\n } finally {\n const generationIsActive = generation === syncGeneration && sendingGeneration === generation && Boolean(unsubscribe)\n if (generationIsActive) {\n sendingGeneration = null\n if (retryDelayMs !== null) {\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = BgTimer.setTimeout(() => {\n retryTimer = null\n void sendCurrentSnapshot(true, generation)\n }, retryDelayMs)\n } else {\n const currentFingerprint = snapshotFingerprint(buildSnapshot())\n if (currentFingerprint !== lastSentFingerprint) {\n queuedFingerprint = currentFingerprint\n if (retryTimer === null) armDebounce(generation)\n }\n }\n }\n }\n}\n\nexport function retryDelayForSupportProfileResult(result: {\n status: \"accepted\" | \"deduplicated\" | \"stale\"\n}): number | null {\n if (result.status === \"accepted\" || result.status === \"deduplicated\") return null\n return RETRY_MS\n}\n\n/**\n * Support freshness is not worth an aggressive retry loop. A snapshot the\n * server keeps rejecting (skewed clock, deleted account, signed-out host)\n * backs off exponentially until it converges on the heartbeat cadence.\n */\nexport function retryDelayForSendFailure(consecutiveFailures: number): number {\n return Math.min(HEARTBEAT_MS, RETRY_MS * 2 ** Math.min(Math.max(consecutiveFailures, 1) - 1, 10))\n}\n\nexport function buildSnapshot(observedAt = new Date()): SupportStateInput {\n const glasses = useGlassesStore.getState()\n const device = {\n hardwareId: optional(glasses.serialNumber),\n model: optional(glasses.deviceModel),\n androidVersion: optional(glasses.androidVersion),\n firmwareVersion: optional(glasses.firmwareVersion),\n mtkFirmwareVersion: optional(glasses.mtkFirmwareVersion),\n besFirmwareVersion: optional(glasses.besFirmwareVersion),\n appVersion: optional(glasses.appVersion),\n buildNumber: optional(glasses.buildNumber),\n }\n const hasDevice = Object.values(device).some(Boolean)\n const constants = Constants as typeof Constants & {\n nativeAppVersion?: string | null\n nativeBuildVersion?: string | null\n }\n return {\n observedAt: observedAt.toISOString(),\n host: {\n appVersion: optional(constants.nativeAppVersion ?? Constants.expoConfig?.version),\n appBuild: optional(constants.nativeBuildVersion),\n engineVersion: optional(ENGINE_VERSION),\n bluetoothSdkVersion: optional(BLUETOOTH_SDK_VERSION),\n phonePlatform: Platform.OS === \"ios\" || Platform.OS === \"android\" ? Platform.OS : \"unknown\",\n phoneModel: optional(Device.modelName),\n phoneOsVersion: optional(\n Platform.OS === \"android\"\n ? String((Platform.constants as {Release?: string} | undefined)?.Release ?? Platform.Version)\n : String(Platform.Version),\n ),\n connectionState: glasses.connection.state,\n ...(lastFailure ? {failureCode: lastFailure.code, failureStage: lastFailure.stage} : {}),\n },\n ...(hasDevice ? {device} : {}),\n }\n}\n\n/** Record only normalized connection failures; arbitrary exception messages never leave the phone. */\nexport function recordSupportProfileConnectionFailure(error: unknown, stage: string): void {\n const rawCode =\n typeof error === \"object\" && error && \"code\" in error ? String((error as {code?: unknown}).code ?? \"\") : \"\"\n const message = error instanceof Error ? `${error.name} ${error.message}`.toLowerCase() : \"\"\n const code = /^[a-zA-Z0-9_.-]{1,64}$/.test(rawCode)\n ? rawCode.toLowerCase()\n : message.includes(\"permission\")\n ? \"permission_denied\"\n : message.includes(\"bluetooth\") && (message.includes(\"off\") || message.includes(\"unavailable\"))\n ? \"bluetooth_unavailable\"\n : message.includes(\"not found\") || message.includes(\"no default\")\n ? \"device_not_found\"\n : message.includes(\"timeout\")\n ? \"connect_timeout\"\n : \"connect_failed\"\n lastFailure = {code, stage: stage.replace(/[^a-zA-Z0-9_.-]/g, \"_\").slice(0, 64)}\n scheduleMeaningfulUpdate()\n}\n\nexport function snapshotFingerprint(snapshot: SupportStateInput): string {\n return JSON.stringify({host: snapshot.host, device: snapshot.device})\n}\n\nfunction optional(value: string | null | undefined): string | undefined {\n const trimmed = value?.trim()\n return trimmed ? trimmed.slice(0, 128) : undefined\n}\n"]}
|
|
1
|
+
{"version":3,"file":"SupportProfileSync.js","sourceRoot":"","sources":["../../src/services/SupportProfileSync.ts"],"names":[],"mappings":"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","sourcesContent":["import Constants from \"expo-constants\"\nimport * as Device from \"expo-device\"\nimport {Platform} from \"react-native\"\nimport type {SupportStateInput} from \"@glassly/cloud-client\"\n\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport {cloudClientService} from \"./CloudClientService\"\n\nconst ENGINE_VERSION = (require(\"../../package.json\") as {version?: string}).version\nconst BLUETOOTH_SDK_VERSION = (require(\"@glassly/bluetooth-sdk/package.json\") as {version?: string}).version\nconst DEBOUNCE_MS = 2_000\nconst RETRY_MS = 30_000\nconst HEARTBEAT_MS = 6 * 60 * 60_000\n\nlet unsubscribe: (() => void) | null = null\nlet debounceTimer: number | null = null\nlet retryTimer: number | null = null\nlet heartbeatTimer: number | null = null\nlet lastSentFingerprint: string | null = null\nlet queuedFingerprint: string | null = null\nlet sendingGeneration: number | null = null\nlet syncGeneration = 0\nlet consecutiveSendFailures = 0\nlet lastFailure: {code: string; stage: string} | null = null\nlet lastConnectionState: string | null = null\n\n/**\n * Keep Cloud's canonical support snapshot current without creating an event\n * stream from noisy store updates. Only the explicitly selected fields below\n * leave the phone; Wi-Fi, Bluetooth addresses, location and diagnostics do not.\n */\nexport function startSupportProfileSync(): void {\n if (unsubscribe) return\n const generation = ++syncGeneration\n lastConnectionState = useGlassesStore.getState().connection.state\n unsubscribe = useGlassesStore.subscribe(() => handleGlassesStoreChange(generation))\n heartbeatTimer = BgTimer.setInterval(() => void sendCurrentSnapshot(true, generation), HEARTBEAT_MS)\n void sendCurrentSnapshot(true, generation)\n}\n\nexport function stopSupportProfileSync(): void {\n syncGeneration += 1\n unsubscribe?.()\n unsubscribe = null\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n if (heartbeatTimer !== null) BgTimer.clearInterval(heartbeatTimer)\n debounceTimer = null\n retryTimer = null\n heartbeatTimer = null\n lastSentFingerprint = null\n queuedFingerprint = null\n sendingGeneration = null\n consecutiveSendFailures = 0\n lastFailure = null\n lastConnectionState = null\n}\n\nfunction handleGlassesStoreChange(generation: number): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const connectionState = useGlassesStore.getState().connection.state\n if (connectionState === \"connected\" && lastConnectionState !== \"connected\") lastFailure = null\n lastConnectionState = connectionState\n scheduleMeaningfulUpdate(generation)\n}\n\nfunction scheduleMeaningfulUpdate(generation = syncGeneration): void {\n if (!unsubscribe || generation !== syncGeneration) return\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint === lastSentFingerprint) return\n queuedFingerprint = fingerprint\n armDebounce(generation)\n}\n\nfunction armDebounce(generation: number): void {\n if (debounceTimer !== null) BgTimer.clearTimeout(debounceTimer)\n debounceTimer = BgTimer.setTimeout(() => {\n debounceTimer = null\n void sendCurrentSnapshot(false, generation)\n }, DEBOUNCE_MS)\n}\n\nasync function sendCurrentSnapshot(force: boolean, generation = syncGeneration): Promise<void> {\n if (!unsubscribe || generation !== syncGeneration) return\n // Every send would fail into the retry backoff with no client to send through.\n if (cloudClientService.isCloudDisabled()) return\n if (sendingGeneration === generation) {\n const fingerprint = snapshotFingerprint(buildSnapshot())\n if (fingerprint !== lastSentFingerprint) queuedFingerprint = fingerprint\n return\n }\n const snapshot = buildSnapshot()\n const fingerprint = snapshotFingerprint(snapshot)\n if (!force && fingerprint === lastSentFingerprint) return\n\n sendingGeneration = generation\n let retryDelayMs: number | null = null\n try {\n const result = await cloudClientService.core.supportProfile.update(snapshot)\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures = 0\n retryDelayMs = retryDelayForSupportProfileResult(result)\n if (retryDelayMs === null) {\n lastSentFingerprint = fingerprint\n if (queuedFingerprint === fingerprint) queuedFingerprint = null\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = null\n }\n } catch (error) {\n if (generation !== syncGeneration || !unsubscribe) return\n consecutiveSendFailures += 1\n retryDelayMs = retryDelayForSendFailure(consecutiveSendFailures)\n console.warn(\n `supportProfile: Cloud update failed (retry in ${Math.round(retryDelayMs / 1_000)}s):`,\n error instanceof Error ? error.message : error,\n )\n } finally {\n const generationIsActive = generation === syncGeneration && sendingGeneration === generation && Boolean(unsubscribe)\n if (generationIsActive) {\n sendingGeneration = null\n if (retryDelayMs !== null) {\n if (retryTimer !== null) BgTimer.clearTimeout(retryTimer)\n retryTimer = BgTimer.setTimeout(() => {\n retryTimer = null\n void sendCurrentSnapshot(true, generation)\n }, retryDelayMs)\n } else {\n const currentFingerprint = snapshotFingerprint(buildSnapshot())\n if (currentFingerprint !== lastSentFingerprint) {\n queuedFingerprint = currentFingerprint\n if (retryTimer === null) armDebounce(generation)\n }\n }\n }\n }\n}\n\nexport function retryDelayForSupportProfileResult(result: {\n status: \"accepted\" | \"deduplicated\" | \"stale\"\n}): number | null {\n if (result.status === \"accepted\" || result.status === \"deduplicated\") return null\n return RETRY_MS\n}\n\n/**\n * Support freshness is not worth an aggressive retry loop. A snapshot the\n * server keeps rejecting (skewed clock, deleted account, signed-out host)\n * backs off exponentially until it converges on the heartbeat cadence.\n */\nexport function retryDelayForSendFailure(consecutiveFailures: number): number {\n return Math.min(HEARTBEAT_MS, RETRY_MS * 2 ** Math.min(Math.max(consecutiveFailures, 1) - 1, 10))\n}\n\nexport function buildSnapshot(observedAt = new Date()): SupportStateInput {\n const glasses = useGlassesStore.getState()\n const device = {\n hardwareId: optional(glasses.serialNumber),\n model: optional(glasses.deviceModel),\n androidVersion: optional(glasses.androidVersion),\n firmwareVersion: optional(glasses.firmwareVersion),\n mtkFirmwareVersion: optional(glasses.mtkFirmwareVersion),\n besFirmwareVersion: optional(glasses.besFirmwareVersion),\n appVersion: optional(glasses.appVersion),\n buildNumber: optional(glasses.buildNumber),\n }\n const hasDevice = Object.values(device).some(Boolean)\n const constants = Constants as typeof Constants & {\n nativeAppVersion?: string | null\n nativeBuildVersion?: string | null\n }\n return {\n observedAt: observedAt.toISOString(),\n host: {\n appVersion: optional(constants.nativeAppVersion ?? Constants.expoConfig?.version),\n appBuild: optional(constants.nativeBuildVersion),\n engineVersion: optional(ENGINE_VERSION),\n bluetoothSdkVersion: optional(BLUETOOTH_SDK_VERSION),\n phonePlatform: Platform.OS === \"ios\" || Platform.OS === \"android\" ? Platform.OS : \"unknown\",\n phoneModel: optional(Device.modelName),\n phoneOsVersion: optional(\n Platform.OS === \"android\"\n ? String((Platform.constants as {Release?: string} | undefined)?.Release ?? Platform.Version)\n : String(Platform.Version),\n ),\n connectionState: glasses.connection.state,\n ...(lastFailure ? {failureCode: lastFailure.code, failureStage: lastFailure.stage} : {}),\n },\n ...(hasDevice ? {device} : {}),\n }\n}\n\n/** Record only normalized connection failures; arbitrary exception messages never leave the phone. */\nexport function recordSupportProfileConnectionFailure(error: unknown, stage: string): void {\n const rawCode =\n typeof error === \"object\" && error && \"code\" in error ? String((error as {code?: unknown}).code ?? \"\") : \"\"\n const message = error instanceof Error ? `${error.name} ${error.message}`.toLowerCase() : \"\"\n const code = /^[a-zA-Z0-9_.-]{1,64}$/.test(rawCode)\n ? rawCode.toLowerCase()\n : message.includes(\"permission\")\n ? \"permission_denied\"\n : message.includes(\"bluetooth\") && (message.includes(\"off\") || message.includes(\"unavailable\"))\n ? \"bluetooth_unavailable\"\n : message.includes(\"not found\") || message.includes(\"no default\")\n ? \"device_not_found\"\n : message.includes(\"timeout\")\n ? \"connect_timeout\"\n : \"connect_failed\"\n lastFailure = {code, stage: stage.replace(/[^a-zA-Z0-9_.-]/g, \"_\").slice(0, 64)}\n scheduleMeaningfulUpdate()\n}\n\nexport function snapshotFingerprint(snapshot: SupportStateInput): string {\n return JSON.stringify({host: snapshot.host, device: snapshot.device})\n}\n\nfunction optional(value: string | null | undefined): string | undefined {\n const trimmed = value?.trim()\n return trimmed ? trimmed.slice(0, 128) : undefined\n}\n"]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { TranscriptionSubscription } from "@glassly/cloud-protocol";
|
|
2
|
+
/** Match a provider result to a logical miniapp subscription. */
|
|
3
|
+
export declare function matchesTranscriptionSubscription(stream: string, resolvedStream: string, subscription: TranscriptionSubscription): boolean;
|
|
1
4
|
export interface TranscriptionRouteSummary {
|
|
2
5
|
hasCloudSubscriber: boolean;
|
|
3
6
|
hasForceLocalSubscriber: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranscriptionRouting.d.ts","sourceRoot":"","sources":["../../src/services/TranscriptionRouting.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,yBAAyB;IACxC,kBAAkB,EAAE,OAAO,CAAA;IAC3B,uBAAuB,EAAE,OAAO,CAAA;IAChC,sFAAsF;IACtF,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,OAAO,CAAA;IACnB,gEAAgE;IAChE,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,0FAA0F;AAC1F,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,KAAK,CAAA;AAEtF,wBAAgB,4BAA4B,CAAC,CAAC,EAC5C,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,EACxB,SAAS,EAAE,CAAC,UAAU,EAAE,CAAC,KAAK,6BAA6B,GAC1D,yBAAyB,CAW3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,MAAM,EAAE,6BAA6B,EACrC,SAAS,EAAE,OAAO,GACjB,0BAA0B,GAAG,IAAI,CAOnC"}
|
|
1
|
+
{"version":3,"file":"TranscriptionRouting.d.ts","sourceRoot":"","sources":["../../src/services/TranscriptionRouting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,yBAAyB,EAAC,MAAM,yBAAyB,CAAA;AAEtE,iEAAiE;AACjE,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,yBAAyB,GACtC,OAAO,CAST;AAED,MAAM,WAAW,yBAAyB;IACxC,kBAAkB,EAAE,OAAO,CAAA;IAC3B,uBAAuB,EAAE,OAAO,CAAA;IAChC,sFAAsF;IACtF,qBAAqB,EAAE,OAAO,CAAA;CAC/B;AAED,MAAM,WAAW,6BAA6B;IAC5C,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,OAAO,CAAA;IACnB,gEAAgE;IAChE,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED,0FAA0F;AAC1F,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,YAAY,GAAG,UAAU,GAAG,KAAK,CAAA;AAEtF,wBAAgB,4BAA4B,CAAC,CAAC,EAC5C,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,EACxB,SAAS,EAAE,CAAC,UAAU,EAAE,CAAC,KAAK,6BAA6B,GAC1D,yBAAyB,CAW3B;AAED;;;;;;;;;GASG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,OAAO,GAAG,OAAO,EACzB,MAAM,EAAE,6BAA6B,EACrC,SAAS,EAAE,OAAO,GACjB,0BAA0B,GAAG,IAAI,CAOnC"}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/** Match a provider result to a logical miniapp subscription. */
|
|
2
|
+
export function matchesTranscriptionSubscription(stream, resolvedStream, subscription) {
|
|
3
|
+
const prefix = "transcription:";
|
|
4
|
+
if (!stream.startsWith(prefix) || !resolvedStream.startsWith(prefix))
|
|
5
|
+
return false;
|
|
6
|
+
if (subscription.language.mode === "specific")
|
|
7
|
+
return stream === `${prefix}${subscription.language.code}`;
|
|
8
|
+
if (stream === `${prefix}auto`)
|
|
9
|
+
return true;
|
|
10
|
+
// Providers detect ISO language codes; miniapps request regional BCP-47 tags.
|
|
11
|
+
// Unknown language stays auto-only until the recognizer identifies it.
|
|
12
|
+
const detected = resolvedStream.slice(prefix.length).split("-")[0].toLowerCase();
|
|
13
|
+
return detected !== "auto" && detected !== "" && stream.slice(prefix.length).split("-")[0].toLowerCase() === detected;
|
|
14
|
+
}
|
|
1
15
|
export function summarizeTranscriptionRoutes(subscribers, routesFor) {
|
|
2
16
|
let hasCloudSubscriber = false;
|
|
3
17
|
let hasForceLocalSubscriber = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TranscriptionRouting.js","sourceRoot":"","sources":["../../src/services/TranscriptionRouting.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TranscriptionRouting.js","sourceRoot":"","sources":["../../src/services/TranscriptionRouting.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,MAAM,UAAU,gCAAgC,CAC9C,MAAc,EACd,cAAsB,EACtB,YAAuC;IAEvC,MAAM,MAAM,GAAG,gBAAgB,CAAA;IAC/B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,KAAK,CAAA;IAClF,IAAI,YAAY,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,MAAM,KAAK,GAAG,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAA;IACzG,IAAI,MAAM,KAAK,GAAG,MAAM,MAAM;QAAE,OAAO,IAAI,CAAA;IAC3C,8EAA8E;IAC9E,uEAAuE;IACvE,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;IAChF,OAAO,QAAQ,KAAK,MAAM,IAAI,QAAQ,KAAK,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,QAAQ,CAAA;AACvH,CAAC;AAmBD,MAAM,UAAU,4BAA4B,CAC1C,WAAwB,EACxB,SAA2D;IAE3D,IAAI,kBAAkB,GAAG,KAAK,CAAA;IAC9B,IAAI,uBAAuB,GAAG,KAAK,CAAA;IACnC,IAAI,qBAAqB,GAAG,KAAK,CAAA;IACjC,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;QACpC,IAAI,MAAM,CAAC,KAAK;YAAE,kBAAkB,GAAG,IAAI,CAAA;QAC3C,IAAI,MAAM,CAAC,UAAU;YAAE,uBAAuB,GAAG,IAAI,CAAA;QACrD,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,aAAa,KAAK,KAAK;YAAE,qBAAqB,GAAG,IAAI,CAAA;IAClF,CAAC;IACD,OAAO,EAAC,kBAAkB,EAAE,uBAAuB,EAAE,qBAAqB,EAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CACxC,MAAyB,EACzB,MAAqC,EACrC,SAAkB;IAElB,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAA;IAC9D,IAAI,SAAS;QAAE,OAAO,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAA;IAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,aAAa,KAAK,KAAK,CAAA;IAC/D,IAAI,QAAQ,IAAI,MAAM,CAAC,UAAU;QAAE,OAAO,KAAK,CAAA;IAC/C,IAAI,MAAM,CAAC,UAAU;QAAE,OAAO,YAAY,CAAA;IAC1C,OAAO,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAA;AACrC,CAAC","sourcesContent":["import type {TranscriptionSubscription} from \"@glassly/cloud-protocol\"\n\n/** Match a provider result to a logical miniapp subscription. */\nexport function matchesTranscriptionSubscription(\n stream: string,\n resolvedStream: string,\n subscription: TranscriptionSubscription,\n): boolean {\n const prefix = \"transcription:\"\n if (!stream.startsWith(prefix) || !resolvedStream.startsWith(prefix)) return false\n if (subscription.language.mode === \"specific\") return stream === `${prefix}${subscription.language.code}`\n if (stream === `${prefix}auto`) return true\n // Providers detect ISO language codes; miniapps request regional BCP-47 tags.\n // Unknown language stays auto-only until the recognizer identifies it.\n const detected = resolvedStream.slice(prefix.length).split(\"-\")[0].toLowerCase()\n return detected !== \"auto\" && detected !== \"\" && stream.slice(prefix.length).split(\"-\")[0].toLowerCase() === detected\n}\n\nexport interface TranscriptionRouteSummary {\n hasCloudSubscriber: boolean\n hasForceLocalSubscriber: boolean\n /** A default-route subscriber that takes on-device text while the primary is down. */\n hasFallbackSubscriber: boolean\n}\n\nexport interface TranscriptionSubscriberRoutes {\n cloud: boolean\n forceLocal: boolean\n /** Default-route fallback acceptance; absent means accepted. */\n localFallback?: boolean\n}\n\n/** \"fallback\" is on-device text serving the default route because the primary is down. */\nexport type TranscriptionDeliveryRoute = \"default\" | \"forceLocal\" | \"fallback\" | \"all\"\n\nexport function summarizeTranscriptionRoutes<T>(\n subscribers: Iterable<T>,\n routesFor: (subscriber: T) => TranscriptionSubscriberRoutes,\n): TranscriptionRouteSummary {\n let hasCloudSubscriber = false\n let hasForceLocalSubscriber = false\n let hasFallbackSubscriber = false\n for (const subscriber of subscribers) {\n const routes = routesFor(subscriber)\n if (routes.cloud) hasCloudSubscriber = true\n if (routes.forceLocal) hasForceLocalSubscriber = true\n if (routes.cloud && routes.localFallback !== false) hasFallbackSubscriber = true\n }\n return {hasCloudSubscriber, hasForceLocalSubscriber, hasFallbackSubscriber}\n}\n\n/**\n * Decide which subscription route(s) a transcript reaches.\n *\n * `source` is who produced the transcript: \"cloud\" is the PRIMARY provider\n * (the cloud runtime, or Soniox-direct when a user API key is set — both\n * deliver through the default route); \"local\" is on-device sherpa.\n * `primaryUp` is whether that primary path is currently believed usable\n * (cloud connectivity, or Soniox-direct session health) — when it is down,\n * local transcripts also serve default-route subscribers.\n */\nexport function transcriptionDeliveryRoute(\n source: \"cloud\" | \"local\",\n routes: TranscriptionSubscriberRoutes,\n primaryUp: boolean,\n): TranscriptionDeliveryRoute | null {\n if (source === \"cloud\") return routes.cloud ? \"default\" : null\n if (primaryUp) return routes.forceLocal ? \"forceLocal\" : null\n const fallback = routes.cloud && routes.localFallback !== false\n if (fallback && routes.forceLocal) return \"all\"\n if (routes.forceLocal) return \"forceLocal\"\n return fallback ? \"fallback\" : null\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UIRouter.d.ts","sourceRoot":"","sources":["../../src/services/UIRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,UAAU,UAAU;IAClB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC7F;AAMD;;;;;;;;;GASG;AAEH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAE1B,KAAK,EAAE,cAAc;IAIjC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI;IAI5D;;;;OAIG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMxC,kEAAkE;IAClE,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIrC;;;;;;;;OAQG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKvC;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IA2C5D;;;;;;;;OAQG;IACH,mBAAmB,CACjB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,GACA,IAAI;
|
|
1
|
+
{"version":3,"file":"UIRouter.d.ts","sourceRoot":"","sources":["../../src/services/UIRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,UAAU,UAAU;IAClB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;CAC7F;AAMD;;;;;;;;;GASG;AAEH,qBAAa,QAAQ;IACnB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuC;IAChE,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;gBAE1B,KAAK,EAAE,cAAc;IAIjC;;;;;;;;;;;OAWG;IACH,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,GAAG,IAAI;IAI5D;;;;OAIG;IACH,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAMxC,kEAAkE;IAClE,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO;IAIrC;;;;;;;;OAQG;IACH,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAKvC;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IA2C5D;;;;;;;;OAQG;IACH,mBAAmB,CACjB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE;QACb,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,GAAG,CAAC,EAAE,MAAM,CAAA;QACZ,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,GACA,IAAI;IAsBP;;;;OAIG;IACH,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI;IAQpG;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;CAa5B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UIRouter.js","sourceRoot":"","sources":["../../src/services/UIRouter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * UIRouter — bidirectional bus between a per-miniapp UI WebView\n * and its bound background JSContext.\n *\n * The flow:\n *\n * WebView (glassly.send/on) Background (session.ui.send/on)\n * │ │\n * │ window.ReactNativeWebView │\n * │ .postMessage(jsonEnvelope) │ session.sendOneShot({\n * │ │ type: \"UI_SEND\", channel, payload, seq\n * │ │ })\n * │ │\n * ▼ ▼\n * MiniappHost.onMessage JSRouter (recognises payload.type===\"UI_SEND\")\n * │ │\n * ▼ ▼\n * ──── UIRouter.routeFromWebView ──── UIRouter.routeFromBackground\n * ──► Crust.jsDispatchToJs ──► webView.injectJavaScript(\"window.__host.recv(...)\")\n * {kind:\"bridge\", raw: JSON({\n * payload:{\n * type:\"EVENT\", streamType:\"_ui\",\n * data:{type:\"UI_MESSAGE\", channel, payload, seq}\n * }})}\n *\n * The router is a singleton — one instance for the whole host process —\n * because only one WebView is allowed open at a time per spec. The\n * binding map is therefore N entries (one per \"currently has a UI\n * WebView mounted\" miniapp), but in practice it's 0 or 1.\n *\n * UI_OPEN / UI_CLOSE lifecycle envelopes are pushed by the WebView's\n * `glassly.ready()` and the host's WebView teardown handler; the router\n * forwards them to background via the same EVENT/_ui envelope shape.\n */\n\ninterface UIInjectFn {\n (jsSource: string): void\n}\n\n/**\n * Subset of the Crust native module that UIRouter touches.\n * Loose binding keeps tests free of Expo imports.\n */\nexport interface UICrustBinding {\n jsDispatchToJs(packageName: string, envelope: Record<string, unknown>): Promise<void> | void\n}\n\ninterface BoundWebView {\n inject: UIInjectFn\n}\n\n/**\n * NOTE: the WebView ↔ host heartbeat was removed when the lifecycle\n * inversion landed. The current model is **at most one WebView at a\n * time, foreground UI with an always-on background JSContext** (same\n * shape as the cloud-WebView miniapps). User navigation closes it\n * explicitly and `onContentProcessDidTerminate` catches OS-level\n * crashes, but the host may still re-announce UI_OPEN for an already\n * mounted WebView after app resume/dev respawn so the background can\n * push a fresh authoritative snapshot.\n */\n\nexport class UIRouter {\n private readonly bindings: Map<string, BoundWebView> = new Map()\n private readonly crust: UICrustBinding\n\n constructor(crust: UICrustBinding) {\n this.crust = crust\n }\n\n /**\n * Called when a UI WebView mounts. `injectFn` wraps\n * `webView.injectJavaScript` — the router calls it with prebuilt\n * `window.__host.recv(...)` strings to deliver background-side\n * frames into the WebView's glassly global.\n *\n * The router also pushes a UI_OPEN envelope to the background side\n * once the WebView signals ready (see {@link routeFromWebView}).\n * Calling bindWebView on a packageName that already has a binding\n * replaces the previous one (defensive — should not happen in\n * practice because only one WebView is open at a time).\n */\n bindWebView(packageName: string, injectFn: UIInjectFn): void {\n this.bindings.set(packageName, {inject: injectFn})\n }\n\n /**\n * Called when the WebView unmounts (user navigated away or the host\n * tore it down on heartbeat timeout). Pushes UI_CLOSE to background\n * so handlers can flush state, then drops the binding.\n */\n unbindWebView(packageName: string): void {\n if (!this.bindings.has(packageName)) return\n this.bindings.delete(packageName)\n this.deliverToBackground(packageName, {type: \"UI_CLOSE\"})\n }\n\n /** True iff a WebView is currently bound to the named package. */\n isBound(packageName: string): boolean {\n return this.bindings.has(packageName)\n }\n\n /**\n * Re-announce the already-mounted WebView to the background JSContext.\n * This covers dev background hot-reload, app resume, and thawed WebViews\n * whose injected UI_SEND frames may have been missed while the host was\n * suspended. Re-emitting UI_OPEN flips `ui.bound` back to true if needed\n * and lets background code push a fresh snapshot via session.ui.onOpen.\n *\n * No-op if no WebView is currently bound for the package.\n */\n notifyReopen(packageName: string): void {\n if (!this.bindings.has(packageName)) return\n this.deliverToBackground(packageName, {type: \"UI_OPEN\"})\n }\n\n /**\n * Forward a WebView-originated postMessage envelope to the JSContext.\n * `rawJson` is the raw string from `event.nativeEvent.data` — the\n * caller hasn't parsed it yet so the router controls the wire format\n * end-to-end.\n *\n * Recognised envelope types from the WebView shim:\n * - {type: \"ready\"} → fire UI_OPEN\n * - {type: \"msg\", seq, channel, payload} → fire UI_MESSAGE\n * - {type: \"heartbeat\", seq} → silently ack\n */\n routeFromWebView(packageName: string, rawJson: string): void {\n let env: {\n type?: string\n seq?: number\n channel?: string\n payload?: unknown\n requestId?: string\n }\n try {\n env = JSON.parse(rawJson)\n } catch {\n return\n }\n if (typeof env.type !== \"string\") return\n\n if (env.type === \"ready\") {\n this.deliverToBackground(packageName, {type: \"UI_OPEN\"})\n return\n }\n if (env.type === \"msg\" && typeof env.channel === \"string\") {\n const out: Record<string, unknown> = {\n type: \"UI_MESSAGE\",\n channel: env.channel,\n payload: env.payload,\n seq: env.seq,\n }\n if (typeof env.requestId === \"string\") out.requestId = env.requestId\n this.deliverToBackground(packageName, out)\n return\n }\n if (env.type === \"cancel\" && typeof env.requestId === \"string\") {\n this.deliverToBackground(packageName, {type: \"UI_CANCEL\", requestId: env.requestId})\n return\n }\n // NOTE: console.* logs do NOT come through this router. The\n // miniappGlobals console-tap shim posts {payload:{type:\"dev_log\"}}\n // envelopes which LocalMiniappRuntime handles and forwards to the\n // dev sidecar tagged source:\"ui\". Keeping that path one-way means\n // we don't have two console-capture pipelines competing.\n //\n // Unknown envelope — drop silently.\n }\n\n /**\n * Called by JSRouter when it sees a `__bridge.send` outbound\n * frame whose parsed payload is a UI_SEND envelope. The router\n * forwards it as a `msg` frame to the bound WebView (or drops if no\n * WebView is currently mounted).\n *\n * `uiSendPayload` is the raw `{type:\"UI_SEND\", channel, payload, seq}`\n * shape produced by `session.ui.send` on the background side.\n */\n routeFromBackground(\n packageName: string,\n uiSendPayload: {\n type: string\n channel?: string\n payload?: unknown\n seq?: number\n requestId?: string\n },\n ): void {\n const binding = this.bindings.get(packageName)\n if (!binding) return\n if (uiSendPayload.type === \"UI_CANCEL\" && typeof uiSendPayload.requestId === \"string\") {\n const cancel = {type: \"cancel\", requestId: uiSendPayload.requestId}\n const literal = JSON.stringify(cancel)\n const escaped = JSON.stringify(literal)\n binding.inject(\n `if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`,\n )\n return\n }\n const outbound: Record<string, unknown> = {\n type: \"msg\",\n seq: uiSendPayload.seq ?? 0,\n channel: uiSendPayload.channel,\n payload: uiSendPayload.payload,\n }\n if (typeof uiSendPayload.requestId === \"string\") outbound.requestId = uiSendPayload.requestId\n const literal = JSON.stringify(outbound)\n const escaped = JSON.stringify(literal)\n binding.inject(\n `if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`,\n )\n }\n\n /**\n * Send a synthetic frame to the WebView. Used for host-initiated\n * lifecycle events (`open`, `close`, `ack`). The wire shape is the\n * same as the WebView shim's recv handler expects.\n */\n pushLifecycleFrame(packageName: string, frame: {type: \"open\" | \"close\" | \"ack\"; seq?: number}): void {\n const binding = this.bindings.get(packageName)\n if (!binding) return\n const literal = JSON.stringify(frame)\n const escaped = JSON.stringify(literal)\n binding.inject(\n `if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`,\n )\n }\n\n /**\n * Wrap an EVENT envelope and push it to background via the bridge.\n * Background's UIModule listens for stream `_ui`. The `type` is the\n * wire value `miniapp_event` — must match `MiniappResponseType.EVENT`\n * exactly, otherwise the SDK's session switch falls through and the\n * `_ui` fan-out never fires (bound stays false; `ui.send` drops).\n */\n private deliverToBackground(packageName: string, data: Record<string, unknown>): void {\n const innerEnvelope = {\n payload: {\n type: \"miniapp_event\",\n streamType: \"_ui\",\n data,\n },\n }\n void this.crust.jsDispatchToJs(packageName, {\n kind: \"bridge\",\n raw: JSON.stringify(innerEnvelope),\n })\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"UIRouter.js","sourceRoot":"","sources":["../../src/services/UIRouter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * UIRouter — bidirectional bus between a per-miniapp UI WebView\n * and its bound background JSContext.\n *\n * The flow:\n *\n * WebView (glassly.send/on) Background (session.ui.send/on)\n * │ │\n * │ window.ReactNativeWebView │\n * │ .postMessage(jsonEnvelope) │ session.sendOneShot({\n * │ │ type: \"UI_SEND\", channel, payload, seq\n * │ │ })\n * │ │\n * ▼ ▼\n * MiniappHost.onMessage JSRouter (recognises payload.type===\"UI_SEND\")\n * │ │\n * ▼ ▼\n * ──── UIRouter.routeFromWebView ──── UIRouter.routeFromBackground\n * ──► Crust.jsDispatchToJs ──► webView.injectJavaScript(\"window.__host.recv(...)\")\n * {kind:\"bridge\", raw: JSON({\n * payload:{\n * type:\"EVENT\", streamType:\"_ui\",\n * data:{type:\"UI_MESSAGE\", channel, payload, seq}\n * }})}\n *\n * The router is a singleton — one instance for the whole host process —\n * because only one WebView is allowed open at a time per spec. The\n * binding map is therefore N entries (one per \"currently has a UI\n * WebView mounted\" miniapp), but in practice it's 0 or 1.\n *\n * UI_OPEN / UI_CLOSE lifecycle envelopes are pushed by the WebView's\n * `glassly.ready()` and the host's WebView teardown handler; the router\n * forwards them to background via the same EVENT/_ui envelope shape.\n */\n\ninterface UIInjectFn {\n (jsSource: string): void\n}\n\n/**\n * Subset of the Crust native module that UIRouter touches.\n * Loose binding keeps tests free of Expo imports.\n */\nexport interface UICrustBinding {\n jsDispatchToJs(packageName: string, envelope: Record<string, unknown>): Promise<void> | void\n}\n\ninterface BoundWebView {\n inject: UIInjectFn\n}\n\n/**\n * NOTE: the WebView ↔ host heartbeat was removed when the lifecycle\n * inversion landed. The current model is **at most one WebView at a\n * time, foreground UI with an always-on background JSContext** (same\n * shape as the cloud-WebView miniapps). User navigation closes it\n * explicitly and `onContentProcessDidTerminate` catches OS-level\n * crashes, but the host may still re-announce UI_OPEN for an already\n * mounted WebView after app resume/dev respawn so the background can\n * push a fresh authoritative snapshot.\n */\n\nexport class UIRouter {\n private readonly bindings: Map<string, BoundWebView> = new Map()\n private readonly crust: UICrustBinding\n\n constructor(crust: UICrustBinding) {\n this.crust = crust\n }\n\n /**\n * Called when a UI WebView mounts. `injectFn` wraps\n * `webView.injectJavaScript` — the router calls it with prebuilt\n * `window.__host.recv(...)` strings to deliver background-side\n * frames into the WebView's glassly global.\n *\n * The router also pushes a UI_OPEN envelope to the background side\n * once the WebView signals ready (see {@link routeFromWebView}).\n * Calling bindWebView on a packageName that already has a binding\n * replaces the previous one (defensive — should not happen in\n * practice because only one WebView is open at a time).\n */\n bindWebView(packageName: string, injectFn: UIInjectFn): void {\n this.bindings.set(packageName, {inject: injectFn})\n }\n\n /**\n * Called when the WebView unmounts (user navigated away or the host\n * tore it down on heartbeat timeout). Pushes UI_CLOSE to background\n * so handlers can flush state, then drops the binding.\n */\n unbindWebView(packageName: string): void {\n if (!this.bindings.has(packageName)) return\n this.bindings.delete(packageName)\n this.deliverToBackground(packageName, {type: \"UI_CLOSE\"})\n }\n\n /** True iff a WebView is currently bound to the named package. */\n isBound(packageName: string): boolean {\n return this.bindings.has(packageName)\n }\n\n /**\n * Re-announce the already-mounted WebView to the background JSContext.\n * This covers dev background hot-reload, app resume, and thawed WebViews\n * whose injected UI_SEND frames may have been missed while the host was\n * suspended. Re-emitting UI_OPEN flips `ui.bound` back to true if needed\n * and lets background code push a fresh snapshot via session.ui.onOpen.\n *\n * No-op if no WebView is currently bound for the package.\n */\n notifyReopen(packageName: string): void {\n if (!this.bindings.has(packageName)) return\n this.deliverToBackground(packageName, {type: \"UI_OPEN\"})\n }\n\n /**\n * Forward a WebView-originated postMessage envelope to the JSContext.\n * `rawJson` is the raw string from `event.nativeEvent.data` — the\n * caller hasn't parsed it yet so the router controls the wire format\n * end-to-end.\n *\n * Recognised envelope types from the WebView shim:\n * - {type: \"ready\"} → fire UI_OPEN\n * - {type: \"msg\", seq, channel, payload} → fire UI_MESSAGE\n * - {type: \"heartbeat\", seq} → silently ack\n */\n routeFromWebView(packageName: string, rawJson: string): void {\n let env: {\n type?: string\n seq?: number\n channel?: string\n payload?: unknown\n requestId?: string\n }\n try {\n env = JSON.parse(rawJson)\n } catch {\n return\n }\n if (typeof env.type !== \"string\") return\n\n if (env.type === \"ready\") {\n this.deliverToBackground(packageName, {type: \"UI_OPEN\"})\n return\n }\n if (env.type === \"msg\" && typeof env.channel === \"string\") {\n const out: Record<string, unknown> = {\n type: \"UI_MESSAGE\",\n channel: env.channel,\n payload: env.payload,\n seq: env.seq,\n }\n if (typeof env.requestId === \"string\") out.requestId = env.requestId\n this.deliverToBackground(packageName, out)\n return\n }\n if (env.type === \"cancel\" && typeof env.requestId === \"string\") {\n this.deliverToBackground(packageName, {type: \"UI_CANCEL\", requestId: env.requestId})\n return\n }\n // NOTE: console.* logs do NOT come through this router. The\n // miniappGlobals console-tap shim posts {payload:{type:\"dev_log\"}}\n // envelopes which LocalMiniappRuntime handles and forwards to the\n // dev sidecar tagged source:\"ui\". Keeping that path one-way means\n // we don't have two console-capture pipelines competing.\n //\n // Unknown envelope — drop silently.\n }\n\n /**\n * Called by JSRouter when it sees a `__bridge.send` outbound\n * frame whose parsed payload is a UI_SEND envelope. The router\n * forwards it as a `msg` frame to the bound WebView (or drops if no\n * WebView is currently mounted).\n *\n * `uiSendPayload` is the raw `{type:\"UI_SEND\", channel, payload, seq}`\n * shape produced by `session.ui.send` on the background side.\n */\n routeFromBackground(\n packageName: string,\n uiSendPayload: {\n type: string\n channel?: string\n payload?: unknown\n seq?: number\n requestId?: string\n },\n ): void {\n const binding = this.bindings.get(packageName)\n if (!binding) return\n if (uiSendPayload.type === \"UI_CANCEL\" && typeof uiSendPayload.requestId === \"string\") {\n const cancel = {type: \"cancel\", requestId: uiSendPayload.requestId}\n const literal = JSON.stringify(cancel)\n const escaped = JSON.stringify(literal)\n binding.inject(`if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`)\n return\n }\n const outbound: Record<string, unknown> = {\n type: \"msg\",\n seq: uiSendPayload.seq ?? 0,\n channel: uiSendPayload.channel,\n payload: uiSendPayload.payload,\n }\n if (typeof uiSendPayload.requestId === \"string\") outbound.requestId = uiSendPayload.requestId\n const literal = JSON.stringify(outbound)\n const escaped = JSON.stringify(literal)\n binding.inject(`if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`)\n }\n\n /**\n * Send a synthetic frame to the WebView. Used for host-initiated\n * lifecycle events (`open`, `close`, `ack`). The wire shape is the\n * same as the WebView shim's recv handler expects.\n */\n pushLifecycleFrame(packageName: string, frame: {type: \"open\" | \"close\" | \"ack\"; seq?: number}): void {\n const binding = this.bindings.get(packageName)\n if (!binding) return\n const literal = JSON.stringify(frame)\n const escaped = JSON.stringify(literal)\n binding.inject(`if (window.__host && window.__host.recv) window.__host.recv(JSON.parse(${escaped})); true;`)\n }\n\n /**\n * Wrap an EVENT envelope and push it to background via the bridge.\n * Background's UIModule listens for stream `_ui`. The `type` is the\n * wire value `miniapp_event` — must match `MiniappResponseType.EVENT`\n * exactly, otherwise the SDK's session switch falls through and the\n * `_ui` fan-out never fires (bound stays false; `ui.send` drops).\n */\n private deliverToBackground(packageName: string, data: Record<string, unknown>): void {\n const innerEnvelope = {\n payload: {\n type: \"miniapp_event\",\n streamType: \"_ui\",\n data,\n },\n }\n void this.crust.jsDispatchToJs(packageName, {\n kind: \"bridge\",\n raw: JSON.stringify(innerEnvelope),\n })\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controllers.d.ts","sourceRoot":"","sources":["../../src/services/controllers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,wBAAwB,CAAA;AAE9E,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,UAAU,CAAA;AAGhD,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"controllers.d.ts","sourceRoot":"","sources":["../../src/services/controllers.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,wBAAwB,CAAA;AAE9E,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,UAAU,CAAA;AAGhD,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;AAqD7E,iFAAiF;AACjF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAErE;AAED,0CAA0C;AAC1C,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAEpE;AAED,2EAA2E;AAC3E,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,EAAE,CAUxE;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,SAAS,GAAG,OAAO,CAE/E;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,GAAG,gBAAgB,EAAE,CAE3G;AAED,wDAAwD;AACxD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,GAAG,MAAM,CAKlG"}
|
|
@@ -43,6 +43,7 @@ const INPUT_SURFACES = {
|
|
|
43
43
|
[ControllerTypes.IINE_ANANKE]: [GAMEBRICK_SURFACE],
|
|
44
44
|
[ControllerTypes.ZERO2]: [GAMEBRICK_SURFACE],
|
|
45
45
|
[ControllerTypes.MICRO]: [GAMEBRICK_SURFACE],
|
|
46
|
+
[ControllerTypes.CRKD_ATOM_PLUS]: [GAMEBRICK_SURFACE],
|
|
46
47
|
[ControllerTypes.R1]: [],
|
|
47
48
|
};
|
|
48
49
|
/** The input surfaces a connected controller of `model` adds to the glasses'. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controllers.js","sourceRoot":"","sources":["../../src/services/controllers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Controller registry read-model: the paired records (the native-authoritative\n * `controllers` setting) and the live driver statuses (glasses status\n * `controllers`), plus what each model adds to the input surfaces. Pure.\n */\nimport type {ControllerStatus, PairedController} from \"@glassly/bluetooth-sdk\"\n\nimport type {ButtonCapabilities} from \"../types\"\nimport {ControllerTypes} from \"../types/enums\"\n\nexport type InputSurface = NonNullable<ButtonCapabilities[\"buttons\"]>[number]\n\n/** The Neural Band's thumb swipes, pinches and dial. */\nconst NEURAL_BAND_SURFACE: InputSurface = {\n type: \"swipe2d\",\n events: [\n \"TAP\",\n \"DOUBLE_TAP\",\n \"PRESS_HOLD\",\n \"SWIPE_UP\",\n \"SWIPE_DOWN\",\n \"SWIPE_LEFT\",\n \"SWIPE_RIGHT\",\n \"DIAL_UP\",\n \"DIAL_DOWN\",\n ],\n}\n\n/** A watch trackpad's taps and four-way swipes, and the crown (Apple) or rotary bezel (Wear OS) as the dial. */\nconst WATCH_SURFACE: InputSurface = {\n type: \"swipe2d\",\n events: [\n \"TAP\",\n \"DOUBLE_TAP\",\n \"PRESS_HOLD\",\n \"SWIPE_UP\",\n \"SWIPE_DOWN\",\n \"SWIPE_LEFT\",\n \"SWIPE_RIGHT\",\n \"DIAL_UP\",\n \"DIAL_DOWN\",\n ],\n}\n\n/** The Gamebrick's D-pad is four absolute swipes; A is the press lifecycle (tap and hold) and B a double tap. */\nconst GAMEBRICK_SURFACE: InputSurface = {\n type: \"swipe2d\",\n events: [\"TAP\", \"DOUBLE_TAP\", \"PRESS_HOLD\", \"SWIPE_UP\", \"SWIPE_DOWN\", \"SWIPE_LEFT\", \"SWIPE_RIGHT\"],\n}\n\n// The R1 swipes up/down like the temples it stands in for, so it adds nothing.\nconst INPUT_SURFACES: Readonly<Record<string, readonly InputSurface[]>> = {\n [ControllerTypes.NEURAL_BAND]: [NEURAL_BAND_SURFACE],\n [ControllerTypes.APPLE_WATCH]: [WATCH_SURFACE],\n [ControllerTypes.WEAR_OS]: [WATCH_SURFACE],\n [ControllerTypes.GAMEBRICK]: [GAMEBRICK_SURFACE],\n [ControllerTypes.IINE_ANANKE]: [GAMEBRICK_SURFACE],\n [ControllerTypes.ZERO2]: [GAMEBRICK_SURFACE],\n [ControllerTypes.MICRO]: [GAMEBRICK_SURFACE],\n [ControllerTypes.R1]: [],\n}\n\n/** The input surfaces a connected controller of `model` adds to the glasses'. */\nexport function controllerInputSurfaces(model: string): InputSurface[] {\n return (INPUT_SURFACES[model] ?? []).map((surface) => ({...surface, events: [...surface.events]}))\n}\n\n/** The model swipes in two dimensions. */\nexport function hasInput2d(model: string): boolean {\n return (INPUT_SURFACES[model] ?? []).some((surface) => surface.type === \"swipe2d\")\n}\n\nexport function isControllerModel(model: string | undefined): boolean {\n return model !== undefined && (Object.values(ControllerTypes) as string[]).includes(model)\n}\n\n/** The `controllers` setting as records; malformed entries are dropped. */\nexport function pairedControllersFrom(value: unknown): PairedController[] {\n if (!Array.isArray(value)) return []\n const records: PairedController[] = []\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") continue\n const {id, model, name} = entry as Record<string, unknown>\n if (typeof id !== \"string\" || !id || typeof model !== \"string\") continue\n records.push({id, model, name: typeof name === \"string\" ? name : id})\n }\n return records\n}\n\n/** Delivering input: link up and the route or claim done. */\nexport function isControllerReady(status: ControllerStatus | undefined): boolean {\n return status?.connected === true && status.fullyBooted === true\n}\n\nexport function readyControllers(statuses: Record<string, ControllerStatus> | undefined): ControllerStatus[] {\n return Object.values(statuses ?? {}).filter(isControllerReady)\n}\n\n/** Change key over the controllers delivering input. */\nexport function readyControllersKey(statuses: Record<string, ControllerStatus> | undefined): string {\n return readyControllers(statuses)\n .map((status) => `${status.id}=${status.model}`)\n .sort()\n .join(\",\")\n}\n"]}
|
|
1
|
+
{"version":3,"file":"controllers.js","sourceRoot":"","sources":["../../src/services/controllers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Controller registry read-model: the paired records (the native-authoritative\n * `controllers` setting) and the live driver statuses (glasses status\n * `controllers`), plus what each model adds to the input surfaces. Pure.\n */\nimport type {ControllerStatus, PairedController} from \"@glassly/bluetooth-sdk\"\n\nimport type {ButtonCapabilities} from \"../types\"\nimport {ControllerTypes} from \"../types/enums\"\n\nexport type InputSurface = NonNullable<ButtonCapabilities[\"buttons\"]>[number]\n\n/** The Neural Band's thumb swipes, pinches and dial. */\nconst NEURAL_BAND_SURFACE: InputSurface = {\n type: \"swipe2d\",\n events: [\n \"TAP\",\n \"DOUBLE_TAP\",\n \"PRESS_HOLD\",\n \"SWIPE_UP\",\n \"SWIPE_DOWN\",\n \"SWIPE_LEFT\",\n \"SWIPE_RIGHT\",\n \"DIAL_UP\",\n \"DIAL_DOWN\",\n ],\n}\n\n/** A watch trackpad's taps and four-way swipes, and the crown (Apple) or rotary bezel (Wear OS) as the dial. */\nconst WATCH_SURFACE: InputSurface = {\n type: \"swipe2d\",\n events: [\n \"TAP\",\n \"DOUBLE_TAP\",\n \"PRESS_HOLD\",\n \"SWIPE_UP\",\n \"SWIPE_DOWN\",\n \"SWIPE_LEFT\",\n \"SWIPE_RIGHT\",\n \"DIAL_UP\",\n \"DIAL_DOWN\",\n ],\n}\n\n/** The Gamebrick's D-pad is four absolute swipes; A is the press lifecycle (tap and hold) and B a double tap. */\nconst GAMEBRICK_SURFACE: InputSurface = {\n type: \"swipe2d\",\n events: [\"TAP\", \"DOUBLE_TAP\", \"PRESS_HOLD\", \"SWIPE_UP\", \"SWIPE_DOWN\", \"SWIPE_LEFT\", \"SWIPE_RIGHT\"],\n}\n\n// The R1 swipes up/down like the temples it stands in for, so it adds nothing.\nconst INPUT_SURFACES: Readonly<Record<string, readonly InputSurface[]>> = {\n [ControllerTypes.NEURAL_BAND]: [NEURAL_BAND_SURFACE],\n [ControllerTypes.APPLE_WATCH]: [WATCH_SURFACE],\n [ControllerTypes.WEAR_OS]: [WATCH_SURFACE],\n [ControllerTypes.GAMEBRICK]: [GAMEBRICK_SURFACE],\n [ControllerTypes.IINE_ANANKE]: [GAMEBRICK_SURFACE],\n [ControllerTypes.ZERO2]: [GAMEBRICK_SURFACE],\n [ControllerTypes.MICRO]: [GAMEBRICK_SURFACE],\n [ControllerTypes.CRKD_ATOM_PLUS]: [GAMEBRICK_SURFACE],\n [ControllerTypes.R1]: [],\n}\n\n/** The input surfaces a connected controller of `model` adds to the glasses'. */\nexport function controllerInputSurfaces(model: string): InputSurface[] {\n return (INPUT_SURFACES[model] ?? []).map((surface) => ({...surface, events: [...surface.events]}))\n}\n\n/** The model swipes in two dimensions. */\nexport function hasInput2d(model: string): boolean {\n return (INPUT_SURFACES[model] ?? []).some((surface) => surface.type === \"swipe2d\")\n}\n\nexport function isControllerModel(model: string | undefined): boolean {\n return model !== undefined && (Object.values(ControllerTypes) as string[]).includes(model)\n}\n\n/** The `controllers` setting as records; malformed entries are dropped. */\nexport function pairedControllersFrom(value: unknown): PairedController[] {\n if (!Array.isArray(value)) return []\n const records: PairedController[] = []\n for (const entry of value) {\n if (!entry || typeof entry !== \"object\") continue\n const {id, model, name} = entry as Record<string, unknown>\n if (typeof id !== \"string\" || !id || typeof model !== \"string\") continue\n records.push({id, model, name: typeof name === \"string\" ? name : id})\n }\n return records\n}\n\n/** Delivering input: link up and the route or claim done. */\nexport function isControllerReady(status: ControllerStatus | undefined): boolean {\n return status?.connected === true && status.fullyBooted === true\n}\n\nexport function readyControllers(statuses: Record<string, ControllerStatus> | undefined): ControllerStatus[] {\n return Object.values(statuses ?? {}).filter(isControllerReady)\n}\n\n/** Change key over the controllers delivering input. */\nexport function readyControllersKey(statuses: Record<string, ControllerStatus> | undefined): string {\n return readyControllers(statuses)\n .map((status) => `${status.id}=${status.model}`)\n .sort()\n .join(\",\")\n}\n"]}
|
|
@@ -53,8 +53,9 @@ function glassesCapabilities(model) {
|
|
|
53
53
|
// Glassly CFW supports the complete vector contract, including SVG and rotation.
|
|
54
54
|
// Upstream g2flash publishes a raster canvas with sceneVector=false.
|
|
55
55
|
const vector = useGlassesStore.getState().sceneVector === true;
|
|
56
|
-
// Depth is a disparity between the
|
|
57
|
-
|
|
56
|
+
// Depth is a disparity between the eyes: a lens per eye, or firmware that
|
|
57
|
+
// presents a separate raster to each eye's panel (MemoMind One CFW 22+).
|
|
58
|
+
const stereo = (base.display.count ?? 1) >= 2 || useGlassesStore.getState().sceneStereo === true;
|
|
58
59
|
return {
|
|
59
60
|
...(volumeGate ? withVolumeGate(base) : base),
|
|
60
61
|
hasNativeNavigation: resolveNativeNavigation(base.hasNativeNavigation, true, forceNativeNavigationOnCfw()),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"effectiveCapabilities.js","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,QAAQ,EAAE,gBAAgB,EAAC,MAAM,oBAAoB,CAAA;AAC7D,OAAO,EAAC,kBAAkB,EAAe,oBAAoB,EAAoB,MAAM,UAAU,CAAA;AACjG,OAAO,EAAC,uBAAuB,EAAE,gBAAgB,EAAoB,MAAM,eAAe,CAAA;AAC1F,OAAO,EAAC,uBAAuB,EAAC,MAAM,wBAAwB,CAAA;AAE9D,MAAM,qBAAqB,GAAG,EAAE,CAAA;AAChC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AACjC,MAAM,uBAAuB,GAAG,GAAG,CAAA;AAOnC,MAAM,UAAU,kBAAkB;IAChC,MAAM,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACxE,IAAI,CAAC,gBAAgB,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,IAAI,CAAC,IAAI,iBAAiB,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3G,OAAO,EAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,iBAAiB,EAAC,CAAA;AAC7D,CAAC;AAED,SAAS,0BAA0B;IACjC,OAAO,gBAAgB,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,qBAAqB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;AAC5F,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,iBAAiB;IAC/B,OAAO,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,KAAK,IAAI,CAAA;AACvD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,KAAkB;IACzD,OAAO,mBAAmB,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAA;AACxD,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAkB;IAC7C,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;IACxC,0EAA0E;IAC1E,2CAA2C;IAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;IACnE,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,IAAI,IAAI,CAAC,aAAa,IAAI,iBAAiB,EAAE,CAAA;IACtF,IAAI,CAAC,MAAM;QAAE,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAC5D,IAAI,CAAC,IAAI,CAAC,OAAO;QAAE,OAAO,UAAU,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAClE,iFAAiF;IACjF,qEAAqE;IACrE,MAAM,MAAM,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,KAAK,IAAI,CAAA;IAC9D,
|
|
1
|
+
{"version":3,"file":"effectiveCapabilities.js","sourceRoot":"","sources":["../../src/services/effectiveCapabilities.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Effective device capabilities — the static model profile plus what the\n * connected firmware reports at runtime. The runtime override is the scene\n * canvas: Glassly CFW on the G2 rasterizes scenes phone-side straight into\n * the 640×480 panel, so the drawable canvas grows past stock's 576×288; on\n * the RayNeo iO it opens a 540×180 page that stock firmware has no\n * equivalent of. Any model whose profile declares `hasCustomFirmware` reads it.\n * Native publishes the canvas into the glasses status (0 = none). Because\n * that path is phone-side rasterization, the stock firmware's container\n * pools (6 text / 4 image) don't bound a CFW frame either — element caps are\n * lifted alongside the canvas, bounded only to keep frames sane. Firmware\n * that draws vector shapes keeps 128 scene slots, so shape-heavy frames\n * (a game board, a chart) get a larger shared text/shape budget.\n *\n * Every connected controller adds its model's input surfaces to\n * `button.buttons` (the Meta Neural Band a `swipe2d` entry), so a miniapp can\n * tell four-way swipes from the temples' and the R1 ring's up/down.\n */\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {SETTINGS, useSettingsStore} from \"../stores/settings\"\nimport {ALL_DISPLAY_SHAPES, DeviceTypes, getModelCapabilities, type Capabilities} from \"../types\"\nimport {controllerInputSurfaces, readyControllers, type InputSurface} from \"./controllers\"\nimport {resolveNativeNavigation} from \"./nativeNavigationGate\"\n\nconst CFW_MAX_TEXT_ELEMENTS = 24\nconst CFW_MAX_IMAGE_ELEMENTS = 16\nconst CFW_VECTOR_MAX_ELEMENTS = 120\n\nexport interface SceneCanvasSize {\n width: number\n height: number\n}\n\nexport function runtimeSceneCanvas(): SceneCanvasSize | null {\n const {sceneCanvasWidth, sceneCanvasHeight} = useGlassesStore.getState()\n if (!sceneCanvasWidth || !sceneCanvasHeight || sceneCanvasWidth <= 0 || sceneCanvasHeight <= 0) return null\n return {width: sceneCanvasWidth, height: sceneCanvasHeight}\n}\n\nfunction forceNativeNavigationOnCfw(): boolean {\n return useSettingsStore.getState().getSetting(SETTINGS.cfw_native_navigation.key) === true\n}\n\n/** The connected firmware gates microphone streaming on volume (G2 Glassly CFW revision 40+). */\nexport function runtimeVolumeGate(): boolean {\n return useGlassesStore.getState().volumeGate === true\n}\n\nexport function getEffectiveCapabilities(model: DeviceTypes): Capabilities {\n return withControllerInput(glassesCapabilities(model))\n}\n\nfunction glassesCapabilities(model: DeviceTypes): Capabilities {\n const base = getModelCapabilities(model)\n // Only models with a Glassly CFW publish a canvas or a volume gate; never\n // let a stale value reshape another model.\n const canvas = base.hasCustomFirmware ? runtimeSceneCanvas() : null\n const volumeGate = base.hasCustomFirmware && base.hasMicrophone && runtimeVolumeGate()\n if (!canvas) return volumeGate ? withVolumeGate(base) : base\n if (!base.display) return volumeGate ? withVolumeGate(base) : base\n // Glassly CFW supports the complete vector contract, including SVG and rotation.\n // Upstream g2flash publishes a raster canvas with sceneVector=false.\n const vector = useGlassesStore.getState().sceneVector === true\n // Depth is a disparity between the eyes: a lens per eye, or firmware that\n // presents a separate raster to each eye's panel (MemoMind One CFW 22+).\n const stereo = (base.display.count ?? 1) >= 2 || useGlassesStore.getState().sceneStereo === true\n return {\n ...(volumeGate ? withVolumeGate(base) : base),\n hasNativeNavigation: resolveNativeNavigation(base.hasNativeNavigation, true, forceNativeNavigationOnCfw()),\n display: {\n ...base.display,\n width: canvas.width,\n height: canvas.height,\n // A Glassly CFW that publishes a canvas takes positioned elements, whatever\n // the stock profile says (the G1's stock firmware degrades scenes to text walls).\n canPosition: true,\n maxTextElements: Math.max(\n base.display.maxTextElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_TEXT_ELEMENTS,\n ),\n // Vector firmware draws an image as one cached slot, the same as a shape.\n maxImageElements: Math.max(\n base.display.maxImageElements ?? 0,\n vector ? CFW_VECTOR_MAX_ELEMENTS : CFW_MAX_IMAGE_ELEMENTS,\n ),\n ...(vector\n ? {shapes: [...ALL_DISPLAY_SHAPES, \"svg\" as const], animation: true, rotation: true, depth: stereo}\n : {}),\n },\n }\n}\n\nfunction withControllerInput(caps: Capabilities): Capabilities {\n const buttons = caps.button?.buttons ?? []\n const types = new Set(buttons.map((surface) => surface.type))\n const added: InputSurface[] = []\n for (const status of readyControllers(useGlassesStore.getState().controllers)) {\n for (const surface of controllerInputSurfaces(status.model)) {\n if (types.has(surface.type)) continue\n types.add(surface.type)\n added.push(surface)\n }\n }\n if (added.length === 0) return caps\n return {\n ...caps,\n hasButton: true,\n button: {\n ...caps.button,\n count: (caps.button?.count ?? buttons.length) + added.length,\n buttons: [...buttons, ...added],\n },\n }\n}\n\nfunction withVolumeGate(base: Capabilities): Capabilities {\n return {...base, microphone: {...(base.microphone ?? {}), volumeGate: true}}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gestureDotGlyphs.d.ts","sourceRoot":"","sources":["../../src/services/gestureDotGlyphs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAA;AAExC,MAAM,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"gestureDotGlyphs.d.ts","sourceRoot":"","sources":["../../src/services/gestureDotGlyphs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,sBAAsB,KAAK,CAAA;AAExC,MAAM,MAAM,eAAe,GACzB,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAA;AAE7G,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAgB9D,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gestureDotGlyphs.js","sourceRoot":"","sources":["../../src/services/gestureDotGlyphs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"gestureDotGlyphs.js","sourceRoot":"","sources":["../../src/services/gestureDotGlyphs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AAKxC,MAAM,CAAC,MAAM,kBAAkB,GAAoC;IACjE,GAAG,EAAE,8IAA8I;IACnJ,MAAM,EACJ,kHAAkH;IACpH,IAAI,EAAE,sJAAsJ;IAC5J,UAAU,EACR,8HAA8H;IAChI,EAAE,EAAE,8IAA8I;IAClJ,IAAI,EAAE,0IAA0I;IAChJ,IAAI,EAAE,8HAA8H;IACpI,KAAK,EACH,0HAA0H;IAC5H,IAAI,EAAE,8KAA8K;IACpL,QAAQ,EACN,0KAA0K;IAC5K,KAAK,EAAE,kGAAkG;CAC1G,CAAA","sourcesContent":["/**\n * GENERATED by scripts/gen-gesture-dot-glyphs.mjs — do not edit by hand.\n * 24×24 8-bit grayscale PNGs (white on black) for the gesture-dots indicator.\n */\nexport const GESTURE_DOT_GLYPH_SIZE = 24\n\nexport type GestureDotGlyph =\n \"dot\" | \"double\" | \"ring\" | \"doubleRing\" | \"up\" | \"down\" | \"left\" | \"right\" | \"hold\" | \"holdRing\" | \"blank\"\n\nexport const GESTURE_DOT_GLYPHS: Record<GestureDotGlyph, string> = {\n dot: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAALklEQVR4nM2QsQ0AAAjC/P/pmrhqZ+xIF6DqBQyWbwO3gduAmKjQuj7QL/ETEzQmMptl7Q9NBAAAAABJRU5ErkJggg==\",\n double:\n \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAG0lEQVR4nGNgGD7gPxjgYkN4yOyBlcDp3GEBAB3sd4lPaQxDAAAAAElFTkSuQmCC\",\n ring: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAANElEQVR4nGNgGBTgPxjgEseUgQphyCD4qDL/kSX+Y9WApoWqEjgsx+lc3B7EHSS4A3EgAAC+cEu1JTNREQAAAABJRU5ErkJggg==\",\n doubleRing:\n \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAIklEQVR4nGNgGD7gPxjgYkN4yGwGmBA6SV0JHJbjdO6wAADBMlep8zl7TAAAAABJRU5ErkJggg==\",\n up: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAMElEQVR4nGNgoCv4////f1zi2GT+/4ciTHE4RhdHIlDFUUhkcTQKQx9WBw8PCVoBAIcbOcf3xeeBAAAAAElFTkSuQmCC\",\n down: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAALUlEQVR4nGNgoC/4/3+4SkBFUCkkNjKJIoMg0GRgGEMGgrC4CQSwuxanR2gEAO1/Ocfgp8uvAAAAAElFTkSuQmCC\",\n left: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAI0lEQVR4nGNgoCv4j0sch8RAiTP8RwPESOAwajDI4JKgGQAAKO05x7DqJxIAAAAASUVORK5CYII=\",\n right:\n \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAIElEQVR4nGNgoDf4j1NiMMn8RwOEJYizZKDEcQc7bQAAS7w5x+ro2lsAAAAASUVORK5CYII=\",\n hold: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAR0lEQVR4nGNgIAj+gwF2UUy5//+xyyDzcLGRedjMhTEwXAKl0Z0Lof7DKbgMhBpQCZzOxedBHEGCMxAJBTXhKGRAA9hFMQEANr7jHQU9fO0AAAAASUVORK5CYII=\",\n holdRing:\n \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAQ0lEQVR4nGNgIAj+gwF2UUy5//+xyyDzcLGRedjMhTEwXAKlMd2IVQNMaEAlcDoXnwdxBAnOQCQU1ISjEIvjsYhiAgAo9KdZzePY3AAAAABJRU5ErkJggg==\",\n blank: \"iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAAAAADFHGIkAAAAD0lEQVR4nGNgGAWjgPoAAAJYAAGgxYwDAAAAAElFTkSuQmCC\",\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestActions.d.ts","sourceRoot":"","sources":["../../src/services/manifestActions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAqB,MAAM,iBAAiB,CAAA;AAEvF,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,cAAc,EAAE,CAAA;IAC1B,aAAa,CAAC,EAAE;QAAC,YAAY,EAAE,OAAO,CAAA;KAAC,CAAA;CACxC;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,EAAE,EACrB,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,OAAO,GACtB,aAAa,EAAE,CAkBjB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CA0BvE;
|
|
1
|
+
{"version":3,"file":"manifestActions.d.ts","sourceRoot":"","sources":["../../src/services/manifestActions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,cAAc,EAAE,cAAc,EAAqB,MAAM,iBAAiB,CAAA;AAEvF,gGAAgG;AAChG,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,cAAc,EAAE,CAAA;IAC1B,aAAa,CAAC,EAAE;QAAC,YAAY,EAAE,OAAO,CAAA;KAAC,CAAA;CACxC;AAED,8EAA8E;AAC9E,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;IACf,EAAE,EAAE,MAAM,CAAA;IACV,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACvC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,aAAa,EAAE,EACrB,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,OAAO,GACtB,aAAa,EAAE,CAkBjB;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CA0BvE;AAMD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,EAAE,CA2BvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifestActions.js","sourceRoot":"","sources":["../../src/services/manifestActions.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAqB,EACrB,iBAAyB,EACzB,cAAuB;IAEvB,MAAM,IAAI,GAAoB,EAAE,CAAA;IAChC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,WAAW,KAAK,iBAAiB,IAAI,GAAG,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAQ;QAC7G,IAAI,GAAG,CAAC,aAAa,EAAE,YAAY,KAAK,KAAK;YAAE,SAAQ;QACvD,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,cAAc;gBAAE,SAAQ;YAC/D,IAAI,CAAC,IAAI,CAAC;gBACR,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,OAAO,EAAE,GAAG,CAAC,IAAI;gBACjB,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAC,UAAU,EAAE,MAAM,CAAC,UAAU,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC7D,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAC,YAAY,EAAE,MAAM,CAAC,YAAY,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aACpE,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAY;IACnD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IAClC,MAAM,GAAG,GAAqB,EAAE,CAAA;IAChC,KAAK,MAAM,CAAC,IAAI,GAMd,EAAE,CAAC;QACH,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;YACvE,GAAG,CAAC,IAAI,CAAC;gBACP,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,WAAW,EAAE,CAAC,CAAC,WAAW;gBAC1B,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,OAAO,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;oBAClF,CAAC,CAAC,EAAC,UAAU,EAAE,CAAC,CAAC,UAAqC,EAAC;oBACvD,CAAC,CAAC,EAAE,CAAC;gBACP,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC;oBACxF,CAAC,CAAC,EAAC,YAAY,EAAE,CAAC,CAAC,YAAuC,EAAC;oBAC3D,CAAC,CAAC,EAAE,CAAC;gBACP,yEAAyE;gBACzE,GAAG,CAAC,CAAC,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAC,UAAU,EAAE,CAAC,CAAC,UAAU,EAAC,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9F,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,MAAM,YAAY,GAAkC,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;AACnF,MAAM,YAAY,GAAG,CAAC,KAAc,EAA+B,EAAE,
|
|
1
|
+
{"version":3,"file":"manifestActions.js","sourceRoot":"","sources":["../../src/services/manifestActions.ts"],"names":[],"mappings":"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","sourcesContent":["import type {DeclaredAction, DeclaredWidget, DeclaredWidgetSize} from \"../types/applet\"\n\n/** The subset of ClientApp that action-listing needs (structural, no cycle on applet types). */\nexport interface ActionListApp {\n packageName: string\n name: string\n actions?: DeclaredAction[]\n compatibility?: {isCompatible: boolean}\n}\n\n/** One row of `session.actions.list` — a flat, MCP-tool-shaped descriptor. */\nexport interface ActionListRow {\n packageName: string\n appName: string\n id: string\n description: string\n parameters?: Record<string, unknown>\n outputSchema?: Record<string, unknown>\n}\n\n/**\n * Project the installed-app set into the caller's invokable-action rows:\n * excludes the caller's own actions, incompatible apps, and placeholder\n * packages; `visibility: \"system\"` actions only surface for system callers.\n */\nexport function visibleActionRows(\n apps: ActionListApp[],\n callerPackageName: string,\n callerIsSystem: boolean,\n): ActionListRow[] {\n const rows: ActionListRow[] = []\n for (const app of apps) {\n if (!app.packageName || app.packageName === callerPackageName || app.packageName.includes(\"@empty\")) continue\n if (app.compatibility?.isCompatible === false) continue\n for (const action of app.actions ?? []) {\n if (action.visibility === \"system\" && !callerIsSystem) continue\n rows.push({\n packageName: app.packageName,\n appName: app.name,\n id: action.id,\n description: action.description,\n ...(action.parameters ? {parameters: action.parameters} : {}),\n ...(action.outputSchema ? {outputSchema: action.outputSchema} : {}),\n })\n }\n }\n return rows\n}\n\n/**\n * Normalize manifest actions defensively for installed and dev-sideloaded\n * bundles. Input and output schemas are passed through as opaque JSON Schema.\n */\nexport function normalizeManifestActions(raw: unknown): DeclaredAction[] {\n if (!Array.isArray(raw)) return []\n const out: DeclaredAction[] = []\n for (const a of raw as Array<{\n id?: unknown\n description?: unknown\n parameters?: unknown\n outputSchema?: unknown\n visibility?: unknown\n }>) {\n if (a && typeof a.id === \"string\" && typeof a.description === \"string\") {\n out.push({\n id: a.id,\n description: a.description,\n ...(a.parameters && typeof a.parameters === \"object\" && !Array.isArray(a.parameters)\n ? {parameters: a.parameters as Record<string, unknown>}\n : {}),\n ...(a.outputSchema && typeof a.outputSchema === \"object\" && !Array.isArray(a.outputSchema)\n ? {outputSchema: a.outputSchema as Record<string, unknown>}\n : {}),\n // Unknown/absent values fall back to the default (\"public\") by omission.\n ...(a.visibility === \"system\" || a.visibility === \"public\" ? {visibility: a.visibility} : {}),\n })\n }\n }\n return out\n}\n\nconst WIDGET_SIZES: readonly DeclaredWidgetSize[] = [\"XS\", \"XSM\", \"SM\", \"MD\", \"LG\"]\nconst isWidgetSize = (value: unknown): value is DeclaredWidgetSize =>\n (WIDGET_SIZES as readonly unknown[]).includes(value)\n\n/**\n * Normalize manifest widgets for installed and dev-sideloaded bundles: an\n * entry without an id, a name or a usable card size is dropped, repeats of a\n * size are folded, and a default size the widget does not offer becomes\n * its first size. Listing `EX` makes a widget expandable; it is not a card\n * size. Taps expand it until the wearer turns that off (AppRegistry applies\n * the choice).\n */\nexport function normalizeManifestWidgets(raw: unknown): DeclaredWidget[] {\n if (!Array.isArray(raw)) return []\n const out: DeclaredWidget[] = []\n const seen = new Set<string>()\n for (const w of raw as Array<{\n id?: unknown\n name?: unknown\n sizes?: unknown\n defaultSize?: unknown\n expandable?: unknown\n }>) {\n if (!w || typeof w.id !== \"string\" || !w.id || typeof w.name !== \"string\" || !w.name || seen.has(w.id)) continue\n const sizes = Array.isArray(w.sizes) ? Array.from(new Set(w.sizes.filter(isWidgetSize))) : []\n if (sizes.length === 0) continue\n seen.add(w.id)\n // `expandable: true` is how bundles from before `EX` said the same.\n const expandable = (Array.isArray(w.sizes) && w.sizes.includes(\"EX\")) || w.expandable === true\n out.push({\n id: w.id,\n name: w.name,\n sizes,\n defaultSize: isWidgetSize(w.defaultSize) && sizes.includes(w.defaultSize) ? w.defaultSize : sizes[0],\n expandable,\n expandOnTap: expandable,\n })\n }\n return out\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Keep installed-app icons from exhausting the miniapp's 32 MiB JS heap.
|
|
2
|
+
* Icons are optional; clients already render a fallback when one is absent.
|
|
3
|
+
* Bound both individual icons and their total before JSON crosses the bridge.
|
|
4
|
+
*/
|
|
5
|
+
export declare function notificationAppPayload(apps: Array<{
|
|
6
|
+
packageName: string;
|
|
7
|
+
appName: string;
|
|
8
|
+
icon: string | null;
|
|
9
|
+
}>): Array<{
|
|
10
|
+
packageName: string;
|
|
11
|
+
appName: string;
|
|
12
|
+
icon: string | null;
|
|
13
|
+
}>;
|
|
14
|
+
//# sourceMappingURL=notificationAppPayload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notificationAppPayload.d.ts","sourceRoot":"","sources":["../../src/services/notificationAppPayload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAAC,GACvE,KAAK,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAC,CAAC,CAQpE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Keep installed-app icons from exhausting the miniapp's 32 MiB JS heap.
|
|
2
|
+
* Icons are optional; clients already render a fallback when one is absent.
|
|
3
|
+
* Bound both individual icons and their total before JSON crosses the bridge.
|
|
4
|
+
*/
|
|
5
|
+
export function notificationAppPayload(apps) {
|
|
6
|
+
let remaining = 128 * 1024;
|
|
7
|
+
return apps.map(({ packageName, appName, icon }) => {
|
|
8
|
+
const size = icon?.length ?? 0;
|
|
9
|
+
const keep = size <= 8 * 1024 && size <= remaining;
|
|
10
|
+
if (keep)
|
|
11
|
+
remaining -= size;
|
|
12
|
+
return { packageName, appName, icon: keep ? icon : null };
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=notificationAppPayload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notificationAppPayload.js","sourceRoot":"","sources":["../../src/services/notificationAppPayload.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAwE;IAExE,IAAI,SAAS,GAAG,GAAG,GAAG,IAAI,CAAA;IAC1B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAC,EAAE,EAAE;QAC/C,MAAM,IAAI,GAAG,IAAI,EAAE,MAAM,IAAI,CAAC,CAAA;QAC9B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,IAAI,SAAS,CAAA;QAClD,IAAI,IAAI;YAAE,SAAS,IAAI,IAAI,CAAA;QAC3B,OAAO,EAAC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAC,CAAA;IACzD,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["/** Keep installed-app icons from exhausting the miniapp's 32 MiB JS heap.\n * Icons are optional; clients already render a fallback when one is absent.\n * Bound both individual icons and their total before JSON crosses the bridge.\n */\nexport function notificationAppPayload(\n apps: Array<{packageName: string; appName: string; icon: string | null}>,\n): Array<{packageName: string; appName: string; icon: string | null}> {\n let remaining = 128 * 1024\n return apps.map(({packageName, appName, icon}) => {\n const size = icon?.length ?? 0\n const keep = size <= 8 * 1024 && size <= remaining\n if (keep) remaining -= size\n return {packageName, appName, icon: keep ? icon : null}\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settingsBridge.d.ts","sourceRoot":"","sources":["../../src/services/settingsBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,wBAAwB,CAAA;AAK9E,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEnD,2FAA2F;AAC3F,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAwB/E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sEAAuE,CAAA;AACzG,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,kBAAkB,CAE3E;AAED,yFAAyF;AACzF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAG7E;AAED,wDAAwD;AACxD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,CAIrE;AAED,MAAM,MAAM,qBAAqB,
|
|
1
|
+
{"version":3,"file":"settingsBridge.d.ts","sourceRoot":"","sources":["../../src/services/settingsBridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAC,gBAAgB,EAAE,gBAAgB,EAAC,MAAM,wBAAwB,CAAA;AAK9E,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,CAAA;AAEnD,2FAA2F;AAC3F,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAwB/E,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sEAAuE,CAAA;AACzG,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEvE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,kBAAkB,CAE3E;AAED,yFAAyF;AACzF,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI,CAG7E;AAED,wDAAwD;AACxD,wBAAgB,qBAAqB,IAAI,MAAM,EAAE,CAEhD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,EAAE,CAIrE;AAED,MAAM,MAAM,qBAAqB,GAC/B;IAAC,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAC,GAAG;IAAC,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,kBAAkB,GAAG,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAC,CAAA;AAEpH,0FAA0F;AAC1F,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,qBAAqB,CAY3F;AAED,wEAAwE;AACxE,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,wBAAwB;IACxB,SAAS,EAAE,OAAO,CAAA;IAClB,6BAA6B;IAC7B,OAAO,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAC,CAAA;IAC3C,qEAAqE;IACrE,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,gGAAgG;AAChG,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,OAAO,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,YAAY,EAAE,OAAO,CAAA;CACtB;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,EAAE,EAC3B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,SAAS,EACtD,OAAO,EAAE,WAAW,GACnB,sBAAsB,EAAE,CAqB1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settingsBridge.js","sourceRoot":"","sources":["../../src/services/settingsBridge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The settings bridge's vocabulary (session.settings): which engine settings\n * a miniapp with the PLATFORM_SETTINGS permission may read or write, the\n * derived read-only keys the engine computes rather than stores, and the\n * request validation. Pure, so the runtime's handlers stay thin and this can\n * be tested without the native import surface the runtime pulls in.\n *\n * A dashboard miniapp is the usual consumer: it edits the notification,\n * glasses-menu, display-position, brightness and microphone keys the phone's\n * settings screens do, through the store, so persistence, server sync and the\n * Bluetooth sync behave as if a phone screen wrote them. A dashboard's own\n * look is not here; it keeps that in its storage.\n */\n\nimport type {ControllerStatus, PairedController} from \"@glassly/bluetooth-sdk\"\n\nimport {ControllerTypes} from \"../types/enums\"\nimport {hasInput2d, isControllerReady} from \"./controllers\"\n\nexport type SettingsBridgeAccess = \"read\" | \"write\"\n\n/** Stored settings the bridge serves, by key, with what a permitted app may do to each. */\nexport const SETTINGS_BRIDGE_KEYS: Readonly<Record<string, SettingsBridgeAccess>> = {\n // The dashboard's master switch is a phone-side debug knob.\n custom_dashboard_enabled: \"read\",\n contextual_dashboard: \"write\",\n head_up_angle: \"write\",\n // Where the glasses draw; each model's steps are its display.positionRange.\n dashboard_depth: \"write\",\n dashboard_height: \"write\",\n // Device settings the dashboard's glasses Settings page edits.\n brightness: \"write\",\n auto_brightness: \"write\",\n // Per paired model: the store resolves the indexed key.\n preferred_mic: \"write\",\n twelve_hour_time: \"write\",\n menu_apps: \"write\",\n notifications_enabled: \"write\",\n notifications_popups: \"write\",\n notifications_popup_seconds: \"write\",\n notifications_batch_seconds: \"write\",\n notifications_hold_during_apps: \"write\",\n notifications_ignore_while_active: \"write\",\n notifications_blocklist: \"write\",\n // Apps the glasses reported posting notifications; the engine records it.\n notification_seen_apps: \"read\",\n}\n\n/**\n * Read-only keys the engine computes: whether the wearer can see the phone,\n * whether the foreground miniapp is drawing on the glasses, and the paired\n * controllers with their battery and input. They change on their own clocks;\n * the runtime pushes them like stored keys.\n */\nexport const DERIVED_SETTINGS_KEYS = [\"phone_active\", \"foreground_app_on_screen\", \"controllers\"] as const\nexport type DerivedSettingsKey = (typeof DERIVED_SETTINGS_KEYS)[number]\n\nexport function isDerivedSettingsKey(key: string): key is DerivedSettingsKey {\n return (DERIVED_SETTINGS_KEYS as readonly string[]).includes(key)\n}\n\n/** What a permitted app may do with `key`, or null when the bridge does not serve it. */\nexport function settingsBridgeAccess(key: string): SettingsBridgeAccess | null {\n if (isDerivedSettingsKey(key)) return \"read\"\n return SETTINGS_BRIDGE_KEYS[key] ?? null\n}\n\n/** Every key the bridge serves, stored then derived. */\nexport function allSettingsBridgeKeys(): string[] {\n return [...Object.keys(SETTINGS_BRIDGE_KEYS), ...DERIVED_SETTINGS_KEYS]\n}\n\n/**\n * The keys a SETTINGS_GET asks for: everything when `requested` is absent,\n * else the known ones among the requested strings (unknown keys are left\n * out, never rejected).\n */\nexport function selectSettingsBridgeKeys(requested: unknown): string[] {\n if (requested === undefined || requested === null) return allSettingsBridgeKeys()\n if (!Array.isArray(requested)) return []\n return requested.filter((key): key is string => typeof key === \"string\" && settingsBridgeAccess(key) !== null)\n}\n\nexport type SettingsSetValidation =\n | {ok: true; key: string; value: unknown}\n | {ok: false; code: \"INVALID_ARGUMENT\" | \"NOT_PERMITTED\"; message: string}\n\n/** A SETTINGS_SET payload: a writable key and a JSON value (undefined is not a value). */\nexport function validateSettingsSet(payload: Record<string, unknown>): SettingsSetValidation {\n const key = payload.key\n if (typeof key !== \"string\" || !key) {\n return {ok: false, code: \"INVALID_ARGUMENT\", message: \"settings.set requires a key\"}\n }\n const access = settingsBridgeAccess(key)\n if (access === null) return {ok: false, code: \"INVALID_ARGUMENT\", message: `Unknown setting \"${key}\"`}\n if (access !== \"write\") return {ok: false, code: \"NOT_PERMITTED\", message: `Setting \"${key}\" is read-only`}\n if (!(\"value\" in payload) || payload.value === undefined) {\n return {ok: false, code: \"INVALID_ARGUMENT\", message: \"settings.set requires a value\"}\n }\n return {ok: true, key, value: payload.value}\n}\n\n/** One paired controller as the `controllers` derived key serves it. */\nexport interface ControllerSettingEntry {\n id: string\n model: string\n name: string\n /** Delivering input. */\n connected: boolean\n /** level -1 when unknown. */\n battery: {level: number; charging: boolean}\n /** Swipes sideways as well as up and down (the Meta Neural Band). */\n input2d: boolean\n}\n\n/** What the glasses report about the ring linked to them (G2 with the R1 routed through it). */\nexport interface RelayedRing {\n ringConnected: boolean\n ringBatteryLevel: number\n ringCharging: boolean\n}\n\n/**\n * The R1 the glasses' ring report is about: a ring routed through the G2 keeps\n * its phone link for telemetry, so prefer a linked ring, else the first one.\n */\nfunction relayedRingId(\n records: PairedController[],\n statuses: Record<string, ControllerStatus> | undefined,\n): string | undefined {\n const rings = records.filter((record) => record.model === ControllerTypes.R1)\n return (rings.find((ring) => statuses?.[ring.id]?.connected === true) ?? rings[0])?.id\n}\n\n/**\n * One entry per paired record, registry order. While the glasses report a\n * linked ring, that report is that ring's link and battery: a ring routed\n * through the G2 reports there, not to the phone.\n */\nexport function controllersSettingFrom(\n records: PairedController[],\n statuses: Record<string, ControllerStatus> | undefined,\n relayed: RelayedRing,\n): ControllerSettingEntry[] {\n const relayedId = relayed.ringConnected ? relayedRingId(records, statuses) : undefined\n return records.map((record) => {\n const status = statuses?.[record.id]\n let connected = isControllerReady(status)\n let battery = {level: status?.batteryLevel ?? -1, charging: status?.charging === true}\n if (record.id === relayedId) {\n connected = true\n if (relayed.ringBatteryLevel >= 0) {\n battery = {level: relayed.ringBatteryLevel, charging: relayed.ringCharging}\n }\n }\n return {\n id: record.id,\n model: record.model,\n name: record.name,\n connected,\n battery,\n input2d: connected && hasInput2d(record.model),\n }\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"settingsBridge.js","sourceRoot":"","sources":["../../src/services/settingsBridge.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The settings bridge's vocabulary (session.settings): which engine settings\n * a miniapp with the PLATFORM_SETTINGS permission may read or write, the\n * derived read-only keys the engine computes rather than stores, and the\n * request validation. Pure, so the runtime's handlers stay thin and this can\n * be tested without the native import surface the runtime pulls in.\n *\n * A dashboard miniapp is the usual consumer: it edits the notification,\n * glasses-menu, display-position, brightness and microphone keys the phone's\n * settings screens do, through the store, so persistence, server sync and the\n * Bluetooth sync behave as if a phone screen wrote them. A dashboard's own\n * look is not here; it keeps that in its storage.\n */\n\nimport type {ControllerStatus, PairedController} from \"@glassly/bluetooth-sdk\"\n\nimport {ControllerTypes} from \"../types/enums\"\nimport {hasInput2d, isControllerReady} from \"./controllers\"\n\nexport type SettingsBridgeAccess = \"read\" | \"write\"\n\n/** Stored settings the bridge serves, by key, with what a permitted app may do to each. */\nexport const SETTINGS_BRIDGE_KEYS: Readonly<Record<string, SettingsBridgeAccess>> = {\n // The dashboard's master switch is a phone-side debug knob.\n custom_dashboard_enabled: \"read\",\n contextual_dashboard: \"write\",\n head_up_angle: \"write\",\n // Where the glasses draw; each model's steps are its display.positionRange.\n dashboard_depth: \"write\",\n dashboard_height: \"write\",\n // Device settings the dashboard's glasses Settings page edits.\n brightness: \"write\",\n auto_brightness: \"write\",\n // Per paired model: the store resolves the indexed key.\n preferred_mic: \"write\",\n twelve_hour_time: \"write\",\n menu_apps: \"write\",\n notifications_enabled: \"write\",\n notifications_popups: \"write\",\n notifications_popup_seconds: \"write\",\n notifications_batch_seconds: \"write\",\n notifications_hold_during_apps: \"write\",\n notifications_ignore_while_active: \"write\",\n notifications_blocklist: \"write\",\n // Apps the glasses reported posting notifications; the engine records it.\n notification_seen_apps: \"read\",\n}\n\n/**\n * Read-only keys the engine computes: whether the wearer can see the phone,\n * whether the foreground miniapp is drawing on the glasses, and the paired\n * controllers with their battery and input. They change on their own clocks;\n * the runtime pushes them like stored keys.\n */\nexport const DERIVED_SETTINGS_KEYS = [\"phone_active\", \"foreground_app_on_screen\", \"controllers\"] as const\nexport type DerivedSettingsKey = (typeof DERIVED_SETTINGS_KEYS)[number]\n\nexport function isDerivedSettingsKey(key: string): key is DerivedSettingsKey {\n return (DERIVED_SETTINGS_KEYS as readonly string[]).includes(key)\n}\n\n/** What a permitted app may do with `key`, or null when the bridge does not serve it. */\nexport function settingsBridgeAccess(key: string): SettingsBridgeAccess | null {\n if (isDerivedSettingsKey(key)) return \"read\"\n return SETTINGS_BRIDGE_KEYS[key] ?? null\n}\n\n/** Every key the bridge serves, stored then derived. */\nexport function allSettingsBridgeKeys(): string[] {\n return [...Object.keys(SETTINGS_BRIDGE_KEYS), ...DERIVED_SETTINGS_KEYS]\n}\n\n/**\n * The keys a SETTINGS_GET asks for: everything when `requested` is absent,\n * else the known ones among the requested strings (unknown keys are left\n * out, never rejected).\n */\nexport function selectSettingsBridgeKeys(requested: unknown): string[] {\n if (requested === undefined || requested === null) return allSettingsBridgeKeys()\n if (!Array.isArray(requested)) return []\n return requested.filter((key): key is string => typeof key === \"string\" && settingsBridgeAccess(key) !== null)\n}\n\nexport type SettingsSetValidation =\n {ok: true; key: string; value: unknown} | {ok: false; code: \"INVALID_ARGUMENT\" | \"NOT_PERMITTED\"; message: string}\n\n/** A SETTINGS_SET payload: a writable key and a JSON value (undefined is not a value). */\nexport function validateSettingsSet(payload: Record<string, unknown>): SettingsSetValidation {\n const key = payload.key\n if (typeof key !== \"string\" || !key) {\n return {ok: false, code: \"INVALID_ARGUMENT\", message: \"settings.set requires a key\"}\n }\n const access = settingsBridgeAccess(key)\n if (access === null) return {ok: false, code: \"INVALID_ARGUMENT\", message: `Unknown setting \"${key}\"`}\n if (access !== \"write\") return {ok: false, code: \"NOT_PERMITTED\", message: `Setting \"${key}\" is read-only`}\n if (!(\"value\" in payload) || payload.value === undefined) {\n return {ok: false, code: \"INVALID_ARGUMENT\", message: \"settings.set requires a value\"}\n }\n return {ok: true, key, value: payload.value}\n}\n\n/** One paired controller as the `controllers` derived key serves it. */\nexport interface ControllerSettingEntry {\n id: string\n model: string\n name: string\n /** Delivering input. */\n connected: boolean\n /** level -1 when unknown. */\n battery: {level: number; charging: boolean}\n /** Swipes sideways as well as up and down (the Meta Neural Band). */\n input2d: boolean\n}\n\n/** What the glasses report about the ring linked to them (G2 with the R1 routed through it). */\nexport interface RelayedRing {\n ringConnected: boolean\n ringBatteryLevel: number\n ringCharging: boolean\n}\n\n/**\n * The R1 the glasses' ring report is about: a ring routed through the G2 keeps\n * its phone link for telemetry, so prefer a linked ring, else the first one.\n */\nfunction relayedRingId(\n records: PairedController[],\n statuses: Record<string, ControllerStatus> | undefined,\n): string | undefined {\n const rings = records.filter((record) => record.model === ControllerTypes.R1)\n return (rings.find((ring) => statuses?.[ring.id]?.connected === true) ?? rings[0])?.id\n}\n\n/**\n * One entry per paired record, registry order. While the glasses report a\n * linked ring, that report is that ring's link and battery: a ring routed\n * through the G2 reports there, not to the phone.\n */\nexport function controllersSettingFrom(\n records: PairedController[],\n statuses: Record<string, ControllerStatus> | undefined,\n relayed: RelayedRing,\n): ControllerSettingEntry[] {\n const relayedId = relayed.ringConnected ? relayedRingId(records, statuses) : undefined\n return records.map((record) => {\n const status = statuses?.[record.id]\n let connected = isControllerReady(status)\n let battery = {level: status?.batteryLevel ?? -1, charging: status?.charging === true}\n if (record.id === relayedId) {\n connected = true\n if (relayed.ringBatteryLevel >= 0) {\n battery = {level: relayed.ringBatteryLevel, charging: relayed.ringCharging}\n }\n }\n return {\n id: record.id,\n model: record.model,\n name: record.name,\n connected,\n battery,\n input2d: connected && hasInput2d(record.model),\n }\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appVisibility.d.ts","sourceRoot":"","sources":["../../src/stores/appVisibility.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,eAAO,MAAM,eAAe,GAAI,KAAK;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,KAAG,OAC/B,CAAA;AAEzC,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,GAAI,gBAAgB,OAAO,EAAE,YAAY,OAAO,KAAG,OACrD,CAAA;AAE9B;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAA2D,CAAA;AAEnH,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,KAAG,OAAmD,CAAA;AAE7G;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAKjD,CAAA;AAEF,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,EAAE,iBAAiB,OAAO,KAAG,OACzB,CAAA;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAAkC,CAAA;AAE1F,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,
|
|
1
|
+
{"version":3,"file":"appVisibility.d.ts","sourceRoot":"","sources":["../../src/stores/appVisibility.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,eAAO,MAAM,eAAe,GAAI,KAAK;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,KAAG,OAC/B,CAAA;AAEzC,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,GAAI,gBAAgB,OAAO,EAAE,YAAY,OAAO,KAAG,OACrD,CAAA;AAE9B;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAA2D,CAAA;AAEnH,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB,GAAI,aAAa,MAAM,KAAG,OAAmD,CAAA;AAE7G;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAKjD,CAAA;AAEF,iEAAiE;AACjE,eAAO,MAAM,iBAAiB,GAAI,aAAa,MAAM,EAAE,iBAAiB,OAAO,KAAG,OACzB,CAAA;AAEzD;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAAkC,CAAA;AAE1F,uFAAuF;AACvF,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,EAAE,iBAAiB,OAAO,EAAE,kBAAkB,OAAO,KAAG,OAC3B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appVisibility.js","sourceRoot":"","sources":["../../src/stores/appVisibility.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAqC,EAAW,EAAE,CAChF,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAA;AAEzC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,cAAuB,EAAE,UAAmB,EAAW,EAAE,CAC3F,cAAc,IAAI,UAAU,CAAA;AAE9B;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAAC,CAAA;AAEnH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,WAAmB,EAAW,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AAE7G;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IAC7D,wBAAwB;IACxB,qBAAqB;IACrB,oBAAoB;IACpB,qBAAqB;CACtB,CAAC,CAAA;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,eAAwB,EAAW,EAAE,CAC1F,CAAC,eAAe,IAAI,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AAEzD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAA;AAE1F,uFAAuF;AACvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,
|
|
1
|
+
{"version":3,"file":"appVisibility.js","sourceRoot":"","sources":["../../src/stores/appVisibility.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAqC,EAAW,EAAE,CAChF,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,CAAA;AAEzC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,cAAuB,EAAE,UAAmB,EAAW,EAAE,CAC3F,cAAc,IAAI,UAAU,CAAA;AAE9B;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,oBAAoB,EAAE,sBAAsB,CAAC,CAAC,CAAA;AAEnH,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,WAAmB,EAAW,EAAE,CAAC,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AAE7G;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAwB,IAAI,GAAG,CAAC;IAC7D,wBAAwB;IACxB,qBAAqB;IACrB,oBAAoB;IACpB,qBAAqB;CACtB,CAAC,CAAA;AAEF,iEAAiE;AACjE,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,WAAmB,EAAE,eAAwB,EAAW,EAAE,CAC1F,CAAC,eAAe,IAAI,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;AAEzD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAwB,IAAI,GAAG,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAA;AAE1F,uFAAuF;AACvF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,WAAmB,EAAE,eAAwB,EAAE,gBAAyB,EAAW,EAAE,CACtH,CAAC,eAAe,IAAI,CAAC,gBAAgB,IAAI,uBAAuB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA","sourcesContent":["/** Host built-in phone pages and dashboard-type miniapps: never launched from a glasses menu. */\nexport const isSystemMiniapp = (app: {offline: boolean; type: string}): boolean =>\n app.offline || app.type === \"dashboard\"\n\n/** Combine registry-enforced visibility with the user's home-screen choice. */\nexport const resolveHiddenStatus = (registryHidden: boolean, userHidden: boolean): boolean =>\n registryHidden || userHidden\n\n/**\n * Miniapps that start off the primary home screen. They stay listed under\n * \"view all apps\", where \"Add to Home\" saves an explicit choice that wins\n * over this default from then on.\n */\nexport const DEFAULT_HIDDEN_PACKAGES: ReadonlySet<string> = new Set([\"com.glassly.camera\", \"com.glassly.recorder\"])\n\n/** The home-screen visibility of an app the user has never hidden or added. */\nexport const defaultHiddenStatus = (packageName: string): boolean => DEFAULT_HIDDEN_PACKAGES.has(packageName)\n\n/**\n * Miniapps that exist only for developers: the Miniapp Developer launcher and\n * the bundled sample/test miniapps. They are projected into the app store\n * only while the `dev_tools` setting is on; off, they are absent from every\n * launcher surface (home, all apps, glasses menu, AI listing), not merely\n * hidden from the primary home screen.\n */\nexport const DEV_TOOLS_PACKAGES: ReadonlySet<string> = new Set([\n \"com.glassly.miniappdev\",\n \"com.glassly.example\",\n \"com.glassly.tetris\",\n \"com.glassly.compass\",\n])\n\n/** True when the app is dev-only and developer tools are off. */\nexport const isGatedByDevTools = (packageName: string, devToolsEnabled: boolean): boolean =>\n !devToolsEnabled && DEV_TOOLS_PACKAGES.has(packageName)\n\n/**\n * Miniapps that unlock once a real pair of glasses has been paired on this\n * phone (`has_paired_glasses`, latched by PairedGlassesLatch and never\n * cleared, so forgetting the glasses keeps them). Developer tools open them\n * early. Until either, they are absent from every launcher surface like the\n * dev-only set above.\n */\nexport const PAIRED_GLASSES_PACKAGES: ReadonlySet<string> = new Set([\"com.glassly.store\"])\n\n/** True when the app waits on a pairing that hasn't happened and dev tools are off. */\nexport const isGatedUntilPaired = (packageName: string, devToolsEnabled: boolean, hasPairedGlasses: boolean): boolean =>\n !devToolsEnabled && !hasPairedGlasses && PAIRED_GLASSES_PACKAGES.has(packageName)\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gallerySync.d.ts","sourceRoot":"","sources":["../../src/stores/gallerySync.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IAEjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,aAAa,CAAC,EAAE,MAAM,CAAA;IAEtB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAGD,MAAM,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"gallerySync.d.ts","sourceRoot":"","sources":["../../src/stores/gallerySync.ts"],"names":[],"mappings":"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"}
|