Wearables Module Integration And SDK Implementation
- Plan type:
plan - Parent plan:
N/A - Depends on:
N/A - Status:
documentation
System Intent
- What is being built: A source-of-truth contract for using
WearablesModule from the app layer, plus an implementation map of how the module bridges to Android, iOS, web, and Meta Ray-Ban SDK dependencies. - Primary consumer(s): Mobile app surfaces that call wearables functions (
AppInit, SettingsScreen, Debugger) and maintainers of main/app/wearables-module. - Boundary (black-box scope only): The public API exported by
main/app/wearables-module/src/WearablesModule.ts and the runtime outcomes it guarantees for initialize, registration, stream lifecycle, recording lifecycle, and debug-state retrieval.
Stage Gate Tracker
- [x] Stage 1 Mermaid approved
- [x] Stage 2 I/O contracts approved
- [x] Stage 3 pseudocode approved or skipped
1. Mermaid Diagram
Reference: .agent/skills/create-mermaid-diagram/SKILL.md
flowchart TD
A[WearablesModule black box - main/app/wearables-module/src/WearablesModule.ts] -->|android runtime resolves module API calls| D[Android implementation - main/app/wearables-module/android/src/main/java/expo/modules/wearablesmodule/WearablesModule.kt]
A -->|ios runtime resolves module API calls| E[iOS implementation - main/app/wearables-module/ios/WearablesModule.swift]
A -->|web runtime resolves module API calls to stub behavior| F[Web implementation - main/app/wearables-module/src/WearablesModule.web.ts]
D -->|implements Android native contract and delegates helper utilities| G[Android helpers - main/app/wearables-module/android/src/main/java/expo/modules/wearablesmodule/WearablesHelpers.kt]
E -->|implements iOS native contract and delegates helper utilities| I[iOS helpers - main/app/wearables-module/ios/WearablesHelpers.swift]
D -->|uses Android SDK runtime for device lifecycle permissions and streaming| K[Meta SDK Android libs - main/app/wearables-module/android/libs/mwdat-core-0.3.0.aar main/app/wearables-module/android/libs/mwdat-camera-0.3.0.aar]
G -->|creates stream sessions and device availability checks via SDK| K
E -->|uses iOS SDK runtime for device lifecycle permissions and streaming| L[Meta SDK iOS frameworks - main/app/wearables-module/ios/Frameworks/MWDATCore.xcframework main/app/wearables-module/ios/Frameworks/MWDATCamera.xcframework]
classDef unchanged fill:#d3d3d3,stroke:#666,stroke-width:1px;
classDef updated fill:#ffe58a,stroke:#666,stroke-width:1px;
classDef deleted fill:#f4a6a6,stroke:#666,stroke-width:1px;
classDef created fill:#a8e6a3,stroke:#666,stroke-width:1px;
class A,D,E,F,G,I,K,L unchanged;
Keep this short. Define types in JSON-style blocks and capture each flow with path-level rows.
Global Types
Define shared types used across multiple flows.
Platform {
value: "android" | "ios"
}
DeviceDebugInfo {
sdkAvailable: boolean
registrationState: string
deviceCount: number
devices: Array<{
id: string
name: string
linkState: string
deviceType: string
compatibility: string
}>
}
Flow: main/app/wearables-module/src/WearablesModule.ts.initialize, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
InitializeInput = none (no parameters)
InitializeOutput = void (no return payload)
Paths
| path-name | input | output/expected state change | path-type | notes |
initialize.success | none | void; module runtime state becomes initialized | happy path | native module is ready for subsequent calls |
initialize.sdk-unavailable-stub | none | throws Error | error | SDK unavailable path should fail fast instead of silently stubbing |
initialize.failure | none | throws Error | error | propagate native initialization error |
Flow: main/app/wearables-module/src/WearablesModule.ts.isAnyDeviceAvailable, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
IsAnyDeviceAvailableInput = none (no parameters)
IsAnyDeviceAvailableOutput {
value: boolean
}
Paths
| path-name | input | output/expected state change | path-type | notes |
isAnyDeviceAvailable.snapshot | none | IsAnyDeviceAvailableOutput value=true | false | happy path | reads current device availability snapshot |
Flow: main/app/wearables-module/src/WearablesModule.ts.isAnyDeviceRegisted, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
IsAnyDeviceRegistedInput = none (no parameters)
IsAnyDeviceRegistedOutput {
value: boolean
}
Paths
| path-name | input | output/expected state change | path-type | notes |
isAnyDeviceRegisted.snapshot | none | IsAnyDeviceRegistedOutput value=true | false | happy path | reads current registration snapshot |
isAnyDeviceRegisted.sdk-unavailable | none | IsAnyDeviceRegistedOutput value=true | false | subpath | value comes from native helper fallback state when SDK is unavailable |
Flow: main/app/wearables-module/src/WearablesModule.ts.startRegistration, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
StartRegistrationInput = none (no parameters)
StartRegistrationOutput = void (no return payload)
Paths
| path-name | input | output/expected state change | path-type | notes |
startRegistration.success | none | void | happy path | registration flow is requested on platform SDK |
startRegistration.failure | none | throws Error | error | platform failure is surfaced to caller |
Flow: main/app/wearables-module/src/WearablesModule.ts.startUnregistration, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
StartUnregistrationInput = none (no parameters)
StartUnregistrationOutput = void (no return payload)
Paths
| path-name | input | output/expected state change | path-type | notes |
startUnregistration.success | none | void | happy path | unregistration flow is requested on platform SDK |
startUnregistration.failure | none | throws Error | error | platform failure is surfaced to caller |
Flow: main/app/wearables-module/src/WearablesModule.ts.startStreamSession, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
StartStreamSessionInput = none (no parameters)
StartStreamSessionOutput = void (no return payload)
Paths
| path-name | input | output/expected state change | path-type | notes |
startStreamSession.success | none | void | happy path | stream session is active and can be recorded |
startStreamSession.failure | none | throws Error | error | e.g. no available device or permission denied |
Flow: main/app/wearables-module/src/WearablesModule.ts.stopStreamSession, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt, main/app/wearables-module/ios/WearablesModuleTests/WearablesModuleTests.swift
Type Definitions
StopStreamSessionInput = none (no parameters)
StopStreamSessionOutput = void (no return payload)
Paths
| path-name | input | output/expected state change | path-type | notes |
stopStreamSession.success | none | void | happy path | stream session is stopped and recording cleanup is performed if active |
stopStreamSession.failure | none | throws Error | error | platform stop failure is surfaced to caller |
Flow: main/app/wearables-module/src/WearablesModule.ts.startRecordingStream, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt
Type Definitions
StartRecordingStreamInput = none (no parameters)
StartRecordingStreamOutput {
recording_path: string
}
Paths
| path-name | input | output/expected state change | path-type | notes |
startRecordingStream.success | none | StartRecordingStreamOutput recording_path=string | happy path | returns recording file path/URI token |
startRecordingStream.failure | none | throws Error | error | fails when no active stream or platform write failure |
Flow: main/app/wearables-module/src/WearablesModule.ts.stopRecordingStream, main/app/wearables-module/android/src/androidTest/java/expo/modules/wearablesmodule/WearablesModuleTest.kt
Type Definitions
StopRecordingStreamInput = none (no parameters)
StopRecordingStreamOutput {
recording_path: string | null
}
Paths
| path-name | input | output/expected state change | path-type | notes |
stopRecordingStream.success | none | StopRecordingStreamOutput recording_path=string|null | happy path | returns finalized path when available |
stopRecordingStream.failure | none | throws Error | error | platform stop-recording failure is surfaced to caller |
Flow: main/app/wearables-module/src/WearablesModule.ts.getDeviceDebugInfo, N/A
Type Definitions
DeviceDebugInfoInput = none (no parameters)
DeviceDebugInfoOutput {
info: DeviceDebugInfo
}
Paths
| path-name | input | output/expected state change | path-type | notes |
getDeviceDebugInfo.success | none | DeviceDebugInfoOutput info.sdkAvailable=true|false | happy path | returns current device and SDK status snapshot |
getDeviceDebugInfo.stub | none | DeviceDebugInfoOutput info.sdkAvailable=false deviceCount=0 | subpath | SDK-unavailable path returns empty device set |
3. Pseudocode for Critical Flows (Optional)
After all stages are approved, apply .agent/skills/reconcile-plans/SKILL.md to propagate contract updates across linked plans.