@pose-tracker/react-native-pose-estimation-light 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/LICENSE +45 -0
  2. package/PoseTrackerVision.podspec +28 -0
  3. package/README.md +161 -0
  4. package/THIRD_PARTY_NOTICES.md +19 -0
  5. package/ios/PoseTrackerVision/PoseTrackerBodyPosePlugin.m +18 -0
  6. package/ios/PoseTrackerVision/PoseTrackerBodyPosePlugin.swift +108 -0
  7. package/lib/PoseTrackerProvider.d.ts +102 -0
  8. package/lib/PoseTrackerProvider.js +204 -0
  9. package/lib/api/configure.d.ts +29 -0
  10. package/lib/api/configure.js +64 -0
  11. package/lib/api/skeleton.d.ts +17 -0
  12. package/lib/api/skeleton.js +53 -0
  13. package/lib/api/track.d.ts +61 -0
  14. package/lib/api/track.js +146 -0
  15. package/lib/backends/PoseBackend.d.ts +50 -0
  16. package/lib/backends/PoseBackend.js +11 -0
  17. package/lib/backends/vision/VisionPoseBackend.d.ts +72 -0
  18. package/lib/backends/vision/VisionPoseBackend.js +177 -0
  19. package/lib/backends/vision/mapVisionJoints.d.ts +35 -0
  20. package/lib/backends/vision/mapVisionJoints.js +162 -0
  21. package/lib/backends/vision/optionalVision.d.ts +32 -0
  22. package/lib/backends/vision/optionalVision.js +76 -0
  23. package/lib/backends/webview/WebViewPoseBackend.d.ts +223 -0
  24. package/lib/backends/webview/WebViewPoseBackend.js +382 -0
  25. package/lib/backends/webview/brandAssets.d.ts +5 -0
  26. package/lib/backends/webview/brandAssets.js +8 -0
  27. package/lib/backends/webview/onlineRuntime.d.ts +45 -0
  28. package/lib/backends/webview/onlineRuntime.js +57 -0
  29. package/lib/backends/webview/poseHtml.d.ts +71 -0
  30. package/lib/backends/webview/poseHtml.js +188 -0
  31. package/lib/backends/webview/poseRuntimeSource.d.ts +3 -0
  32. package/lib/backends/webview/poseRuntimeSource.js +4 -0
  33. package/lib/cache/obfuscate.d.ts +18 -0
  34. package/lib/cache/obfuscate.js +90 -0
  35. package/lib/camera/PoseCameraView.d.ts +51 -0
  36. package/lib/camera/PoseCameraView.js +99 -0
  37. package/lib/camera/WebViewPoseView.d.ts +81 -0
  38. package/lib/camera/WebViewPoseView.js +312 -0
  39. package/lib/client.d.ts +361 -0
  40. package/lib/client.js +1046 -0
  41. package/lib/diagnostics/logReport.d.ts +23 -0
  42. package/lib/diagnostics/logReport.js +102 -0
  43. package/lib/engine/EngineLoader.d.ts +95 -0
  44. package/lib/engine/EngineLoader.js +347 -0
  45. package/lib/engine/types.d.ts +83 -0
  46. package/lib/engine/types.js +11 -0
  47. package/lib/events/classicMessage.d.ts +31 -0
  48. package/lib/events/classicMessage.js +259 -0
  49. package/lib/exercises/aliases.d.ts +18 -0
  50. package/lib/exercises/aliases.js +48 -0
  51. package/lib/index.d.ts +72 -0
  52. package/lib/index.js +170 -0
  53. package/lib/models/poseModels.d.ts +39 -0
  54. package/lib/models/poseModels.js +63 -0
  55. package/lib/quality/AdaptiveQualityController.d.ts +120 -0
  56. package/lib/quality/AdaptiveQualityController.js +423 -0
  57. package/lib/quality/RuntimeGuard.d.ts +34 -0
  58. package/lib/quality/RuntimeGuard.js +105 -0
  59. package/lib/quality/captureMode.d.ts +82 -0
  60. package/lib/quality/captureMode.js +75 -0
  61. package/lib/quality/deviceCapability.d.ts +37 -0
  62. package/lib/quality/deviceCapability.js +177 -0
  63. package/lib/quality/profiles.d.ts +125 -0
  64. package/lib/quality/profiles.js +202 -0
  65. package/lib/runtime/RuntimeCache.d.ts +75 -0
  66. package/lib/runtime/RuntimeCache.js +230 -0
  67. package/lib/sdkVersion.d.ts +2 -0
  68. package/lib/sdkVersion.js +5 -0
  69. package/lib/support/optionalModules.d.ts +46 -0
  70. package/lib/support/optionalModules.js +82 -0
  71. package/lib/types/acceleration.d.ts +86 -0
  72. package/lib/types/acceleration.js +15 -0
  73. package/lib/types/events.d.ts +345 -0
  74. package/lib/types/events.js +10 -0
  75. package/lib/types/features.d.ts +90 -0
  76. package/lib/types/features.js +122 -0
  77. package/lib/types/manifest.d.ts +197 -0
  78. package/lib/types/manifest.js +10 -0
  79. package/lib/types/pose.d.ts +36 -0
  80. package/lib/types/pose.js +41 -0
  81. package/lib/types/preload.d.ts +17 -0
  82. package/lib/types/preload.js +10 -0
  83. package/lib/types/skeleton.d.ts +29 -0
  84. package/lib/types/skeleton.js +52 -0
  85. package/package.json +92 -0
  86. package/react-native.config.js +12 -0
  87. package/src/PoseTrackerProvider.tsx +332 -0
  88. package/src/api/configure.ts +82 -0
  89. package/src/api/skeleton.ts +60 -0
  90. package/src/api/track.ts +182 -0
  91. package/src/backends/PoseBackend.ts +59 -0
  92. package/src/backends/vision/VisionPoseBackend.ts +238 -0
  93. package/src/backends/vision/mapVisionJoints.ts +185 -0
  94. package/src/backends/vision/optionalVision.ts +94 -0
  95. package/src/backends/webview/WebViewPoseBackend.ts +582 -0
  96. package/src/backends/webview/brandAssets.ts +5 -0
  97. package/src/backends/webview/onlineRuntime.ts +94 -0
  98. package/src/backends/webview/poseHtml.ts +259 -0
  99. package/src/backends/webview/poseRuntimeSource.d.ts +3 -0
  100. package/src/cache/obfuscate.ts +94 -0
  101. package/src/camera/PoseCameraView.tsx +223 -0
  102. package/src/camera/WebViewPoseView.tsx +466 -0
  103. package/src/client.ts +1295 -0
  104. package/src/diagnostics/logReport.ts +131 -0
  105. package/src/engine/EngineLoader.ts +428 -0
  106. package/src/engine/types.ts +93 -0
  107. package/src/events/classicMessage.ts +271 -0
  108. package/src/exercises/aliases.ts +50 -0
  109. package/src/index.ts +243 -0
  110. package/src/models/poseModels.ts +93 -0
  111. package/src/quality/AdaptiveQualityController.ts +579 -0
  112. package/src/quality/RuntimeGuard.ts +119 -0
  113. package/src/quality/captureMode.ts +97 -0
  114. package/src/quality/deviceCapability.ts +187 -0
  115. package/src/quality/profiles.ts +253 -0
  116. package/src/runtime/RuntimeCache.ts +300 -0
  117. package/src/sdkVersion.ts +2 -0
  118. package/src/support/optionalModules.ts +114 -0
  119. package/src/types/acceleration.ts +94 -0
  120. package/src/types/events.ts +437 -0
  121. package/src/types/features.ts +176 -0
  122. package/src/types/manifest.ts +230 -0
  123. package/src/types/pose.ts +85 -0
  124. package/src/types/preload.ts +19 -0
  125. package/src/types/skeleton.ts +77 -0
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Framework-agnostic orchestrator. `PoseTrackerProvider` is a thin React
3
+ * wrapper around this class.
4
+ *
5
+ * Lifecycle (exposed as `PoseTrackerStatus`):
6
+ * idle → configuring (handshake attempt) → downloading (engine bundle)
7
+ * → warming (TF runtime + model + dummy inferences) → ready | error
8
+ *
9
+ * Operating modes (commercial boundary, see ARCHITECTURE.md §Modes):
10
+ * - 'keypoints-only': always reachable — online MoveNet (CDN TF.js + model
11
+ * URL) + warm-up + camera pipeline, raw `keypoints` events only. A failed
12
+ * handshake (offline API, missing/invalid token, quota) NEVER blocks
13
+ * `ready`: it degrades to this mode with a non-fatal `error` event.
14
+ * `error` status is reserved for unrecoverable local failures (model load).
15
+ * - 'full-engine': requires a validated handshake — live, or replayed from
16
+ * the encrypted session cache written after a previous successful
17
+ * handshake (Sency-style offline cold start). The npm package itself
18
+ * ships ZERO movement intelligence.
19
+ *
20
+ * The mode upgrades at runtime without restarting the camera pipeline:
21
+ * `configure()` can be called at any time (e.g. when the network comes back
22
+ * or the host obtains a token) — the inference backend is untouched, and
23
+ * business events simply start flowing once the engine is up.
24
+ */
25
+ import { type ConfigureOptions } from './api/configure';
26
+ import { UsageTracker } from './api/track';
27
+ import { EngineLoader, type EngineLoadResult, type FileStore } from './engine/EngineLoader';
28
+ import { type OnlineRuntimeParts } from './backends/webview/onlineRuntime';
29
+ import type { CustomExerciseDescriptor } from './engine/types';
30
+ import type { PoseBackend, PoseInputFrame } from './backends/PoseBackend';
31
+ import type { ExerciseConfig, SdkManifest } from './types/manifest';
32
+ import type { ColdStartMode, PreloadOptions } from './types/preload';
33
+ import type { SkeletonDefinition } from './types/skeleton';
34
+ import type { ErrorEvent, PoseTrackerEventListener, PoseTrackerMode, PoseTrackerStatus } from './types/events';
35
+ import type { Pose } from './types/pose';
36
+ import type { AccelerationDiagnostics, AccelerationState } from './types/acceleration';
37
+ import { type QualityState } from './quality/AdaptiveQualityController';
38
+ import { type CapturePriority, type QualityChoice, type QualityProfile } from './quality/profiles';
39
+ import { type ClassicMessageListener } from './events/classicMessage';
40
+ import { type PoseTrackerFeatures, type ResolvedFeatures } from './types/features';
41
+ import type { PoseModelAlias } from './models/poseModels';
42
+ /**
43
+ * Inference backend selection:
44
+ * - 'auto' (default) / 'webview': MoveNet SinglePose Lightning (17 keypoints,
45
+ * 192×192) inside a Chromium/WKWebView — TF.js WebGL, **online** (CDN TF.js
46
+ * + model URL each boot). Base runtime on BOTH platforms; works in Expo Go.
47
+ * - 'vision': Apple Vision (`VNDetectHumanBodyPoseRequest`) — iOS native
48
+ * builds only, explicit opt-in. No automatic fallback: an init failure
49
+ * surfaces as status 'error'.
50
+ */
51
+ export type PreferredBackend = 'auto' | 'webview' | 'vision';
52
+ export interface PoseTrackerClientOptions extends ConfigureOptions {
53
+ /** Injectable for tests / custom hosts (takes precedence over `preferredBackend`). */
54
+ backend?: PoseBackend;
55
+ /** See {@link PreferredBackend}. */
56
+ preferredBackend?: PreferredBackend;
57
+ engineLoader?: EngineLoader;
58
+ fileStore?: FileStore | null;
59
+ /** Injectable for tests. */
60
+ usageTracker?: UsageTracker;
61
+ /**
62
+ * Docs API `model` query parity (`movenet` default, `blazepose`, …).
63
+ * BlazePose is not wired in the light WebView yet — use `modelUrl` for a
64
+ * custom TF.js graph model. Ignored when {@link modelUrl} is set.
65
+ */
66
+ model?: PoseModelAlias;
67
+ /**
68
+ * Explicit TF.js graph-model topology URL. Default: PoseTracker Front
69
+ * MoveNet SinglePose Lightning
70
+ * (`https://app.posetracker.com/scripts/tmp_model_to_remove.json`).
71
+ */
72
+ modelUrl?: string;
73
+ /** Override jsDelivr (or mirror) root for TF.js scripts. */
74
+ tfjsCdnBase?: string;
75
+ /** Override TF.js CDN version pin (default `4.22.0`). */
76
+ tfjsVersion?: string;
77
+ /**
78
+ * Camera / preprocess quality tier. Default `AdaptiveChoice` — picks a
79
+ * profile from device capability, crash-loop guard, and live FPS.
80
+ * See docs/ADAPTIVE_QUALITY.md.
81
+ */
82
+ qualityChoice?: QualityChoice;
83
+ /**
84
+ * Trade-off between pose FPS and camera preview sharpness.
85
+ * Default `performance` — SDK may lower capture (esp. Android) to hold the
86
+ * FPS floor. Pass `quality` to keep a sharp preview and accept slower pose
87
+ * updates (no FPS-driven capture downgrade). See docs/ADAPTIVE_QUALITY.md.
88
+ */
89
+ capturePriority?: CapturePriority;
90
+ /**
91
+ * Tracking feature flags — SDK port of the WebView query params
92
+ * (`angles`, `recommendations`, `progression`, `keypoints`, `minGrade`)
93
+ * with the SAME plan gating and error messages as the WebView product:
94
+ * paid plans only; `free` gets the exact `TrackingAppV3` error strings.
95
+ * Defaults: everything off (WebView parity). Pose-only keypoints (no
96
+ * exercise) always stream and are never gated. See docs/FEATURES.md.
97
+ */
98
+ features?: PoseTrackerFeatures;
99
+ /**
100
+ * Receives SDK diagnostic lines (GL flags, GPU health check, fallbacks,
101
+ * context-loss recoveries). Route to your logger/telemetry; useful for
102
+ * triaging Android GPU issues in the field.
103
+ */
104
+ onDiagnostic?: (message: string) => void;
105
+ }
106
+ /**
107
+ * Per-session options for {@link PoseTrackerClient.startExercise} — the SDK
108
+ * port of the WebView query params `difficulty`, `userHeightCm` and
109
+ * `devicePitchDeg`.
110
+ */
111
+ export interface StartExerciseOptions {
112
+ /**
113
+ * Difficulty key into the movement `scale_acceptance` maps (FSM exercises).
114
+ * WebView `difficulty` param parity. Default: 'medium'.
115
+ */
116
+ difficulty?: string;
117
+ /** Athlete height in cm — REQUIRED by `jump_analysis` (cm/pixel calibration). */
118
+ userHeightCm?: number;
119
+ /** Device pitch in degrees — jump exercises compensate camera tilt. */
120
+ devicePitchDeg?: number;
121
+ }
122
+ export declare class PoseTrackerClient {
123
+ private status;
124
+ private mode;
125
+ private lastError;
126
+ private manifest;
127
+ private engine;
128
+ private engineSource;
129
+ private session;
130
+ private currentExerciseId;
131
+ private apiToken;
132
+ private backend;
133
+ private readonly engineLoader;
134
+ private readonly files;
135
+ private readonly tracker;
136
+ private readonly quality;
137
+ private readonly listeners;
138
+ private readonly messageListeners;
139
+ private readonly stateListeners;
140
+ private preloadPromise;
141
+ /** Last requested cold-start mode (default basic — no getUserMedia). */
142
+ private coldStartMode;
143
+ private configurePromise;
144
+ /** One handshake per configuration cycle, shared by runtime warm + engine load. */
145
+ private handshakePromise;
146
+ /** Online pose-runtime descriptor (CDN TF.js + model URL + thin page runtime). */
147
+ private runtimePromise;
148
+ /**
149
+ * Metered-session gate: with an API key, the `camera_start` track call must
150
+ * succeed online before key-gated features run ('refused' = offline/quota).
151
+ */
152
+ private meteredSessionState;
153
+ /** Last camera_start payload — lets configure() retry a refused metered gate. */
154
+ private lastCameraStartInfo;
155
+ /** Consecutive engine processPose failures (see SESSION_ERROR_STREAK_LIMIT). */
156
+ private sessionErrorStreak;
157
+ /** Requested tracking features with WebView-parity defaults applied. */
158
+ private readonly features;
159
+ /** WebView-only keys passed by untyped hosts (blazepose, poseEngine, …). */
160
+ private readonly unsupportedFeatureKeys;
161
+ /** One-shot flags so plan-gating errors are not re-emitted on every retry. */
162
+ private featureGateReported;
163
+ private keypointsSuppressionLogged;
164
+ private readonly options;
165
+ constructor(apiToken?: string, options?: PoseTrackerClientOptions);
166
+ /** Backend selection — see {@link PreferredBackend}. */
167
+ private createBackend;
168
+ getStatus(): PoseTrackerStatus;
169
+ getMode(): PoseTrackerMode;
170
+ /** Last non-fatal or fatal error (also emitted as an `error` event). */
171
+ getError(): ErrorEvent | null;
172
+ getManifest(): SdkManifest | null;
173
+ /** Plan type from the manifest ('free', 'developer', …) or null (keyless/offline). */
174
+ getPlanType(): string | null;
175
+ /** Requested tracking features with WebView-parity defaults applied. */
176
+ getFeatures(): ResolvedFeatures;
177
+ /** 'remote-cache' | 'remote-download' | null (keypoints-only). */
178
+ getEngineSource(): EngineLoadResult['source'] | null;
179
+ /**
180
+ * GPU-acceleration verdict from the warm-up health check ('unknown' until
181
+ * preload/warmup completes). See docs/ANDROID_GL_ACCELERATION.md.
182
+ */
183
+ getAcceleration(): AccelerationState;
184
+ /** Full diagnostics (backend, timings, GL renderer, flags, downgrade trail). */
185
+ getAccelerationDiagnostics(): AccelerationDiagnostics | null;
186
+ /**
187
+ * Adaptive camera-quality state (profile, capability score, mean FPS).
188
+ * See docs/ADAPTIVE_QUALITY.md.
189
+ */
190
+ getQualityState(): QualityState;
191
+ /** Resolve (and cache) the initial quality profile before mounting the WebView. */
192
+ resolveQualityProfile(): Promise<QualityProfile>;
193
+ /** Mark the active profile as PROBING (crash-loop guard) before page boot. */
194
+ beginQualitySession(): Promise<void>;
195
+ /**
196
+ * Wire the live WebView injector so auto-downgrades can restart getUserMedia.
197
+ * Called by {@link WebViewPoseView}.
198
+ */
199
+ setQualityApplyHandler(fn: ((profile: QualityProfile) => void) | undefined): void;
200
+ addEventListener(listener: PoseTrackerEventListener): () => void;
201
+ /**
202
+ * Classic PoseTracker WebView parity: receive `sendDataToNative`-shaped JSON
203
+ * (`{ type: 'keypoints', data: [...] }`, `{ type: 'initialization', message, ready }`, …).
204
+ * Prefer typed {@link addEventListener} for new apps; use this to migrate
205
+ * existing `onMessage` parsers with minimal changes.
206
+ */
207
+ addMessageListener(listener: ClassicMessageListener): () => void;
208
+ /** Fired on any status/mode/manifest change. */
209
+ onStateChange(listener: () => void): () => void;
210
+ /**
211
+ * Idempotent warm-up: bundled pose runtime, optional engine handshake,
212
+ * then backend cold-start. Does **not** run when the provider mounts
213
+ * (unless `autoPreload`). For WebView, mount a `WebViewPoseView` so the
214
+ * page can load MoveNet — see docs/PRELOAD.md.
215
+ *
216
+ * Cold-start modes (`options.coldStart`):
217
+ * - `basic` (**default**): model + WebGL zeros only — **no getUserMedia**,
218
+ * so lobby / home preload never prompts for camera permission.
219
+ * - `full`: also open the camera (legacy). Pair with
220
+ * `<WebViewPoseView coldStart="full" />` or call after basic ready to
221
+ * upgrade via `__PT_OPEN_CAMERA`.
222
+ *
223
+ * Always reaches `ready` unless the local model path fails; a failed
224
+ * handshake degrades to keypoints-only mode.
225
+ */
226
+ preload(options?: PreloadOptions): Promise<void>;
227
+ /** Alias of preload(), matching the Sency-style naming. */
228
+ warmup(options?: PreloadOptions): Promise<void>;
229
+ /** Current preferred cold-start mode (for hosts / WebView wiring). */
230
+ getColdStartMode(): ColdStartMode;
231
+ private doPreload;
232
+ /**
233
+ * After model ready, optionally open the camera for `coldStart: 'full'`.
234
+ * No-op for basic, or when the WebView already booted with coldStart=full.
235
+ */
236
+ private ensureColdStartMode;
237
+ /**
238
+ * Online runtime descriptor used by {@link WebViewPoseView} / {@link buildPoseHtml}.
239
+ * Resolves model URL + CDN script list synchronously; the WebView performs
240
+ * the actual network fetches at boot.
241
+ */
242
+ getRuntimeParts(): Promise<OnlineRuntimeParts>;
243
+ /**
244
+ * Load a custom skeleton overlay by Strapi `api_uuid`
245
+ * (WebView `?skeleton=<uuid>`). Pass the result to
246
+ * `<WebViewPoseView skeletonDef={…} />` or let the view fetch via
247
+ * `skeletonUuid`.
248
+ */
249
+ fetchSkeleton(uuid: string): Promise<SkeletonDefinition>;
250
+ private loadOnlineRuntime;
251
+ /**
252
+ * One handshake per configuration cycle — shared by the pose-runtime warm
253
+ * and the engine load, with or without API key. Never throws; resolves to
254
+ * null when unreachable AND no sealed session cache can be replayed.
255
+ */
256
+ private resolveManifestOnce;
257
+ private doResolveManifestOnce;
258
+ /**
259
+ * Revocation signal: purge the sealed engine artifacts and downgrade to
260
+ * keypoints-only. The public pose-runtime cache is NOT purged (public
261
+ * payload, keypoints-only keeps working).
262
+ */
263
+ private handleRevocation;
264
+ /**
265
+ * Usage metering — fired when the WebView reports the camera started with
266
+ * the model ready. With an API key the call MUST succeed (quota check +
267
+ * counter increment + usage row): offline metered sessions are refused.
268
+ * Without a key the event is fire-and-forget with a local retry queue.
269
+ */
270
+ private handleCameraStart;
271
+ /** Backend init + warm-up. An init failure surfaces as status 'error'. */
272
+ private initAndWarmupBackend;
273
+ /**
274
+ * Runtime (re)configuration — the keypoints-only → full-engine upgrade
275
+ * path. Can be called before or after `ready`; when the camera pipeline
276
+ * is already running it keeps running, business events simply start once
277
+ * the engine is loaded. Resolves to true when full-engine mode is active.
278
+ */
279
+ configure(apiToken?: string): Promise<boolean>;
280
+ /**
281
+ * Re-run the `camera_start` metered gate after a configure() retry. A
282
+ * session refused offline becomes usable as soon as the network is back —
283
+ * WebView parity: the front revalidates on reload, the SDK on configure().
284
+ */
285
+ private retryMeteredSessionIfRefused;
286
+ /**
287
+ * Handshake + engine load. Never throws; returns whether full-engine mode
288
+ * was reached. `silentStatus` avoids status regressions (e.g. hot upgrade
289
+ * while `ready` and the camera is streaming).
290
+ */
291
+ private tryConfigure;
292
+ /**
293
+ * Handshake with the session-cache fallback:
294
+ * - live call → cache the manifest, sealed with the token-derived secret;
295
+ * - network/server failure → replay the sealed cached manifest (only
296
+ * readable with the same token: the "already configured once" proof);
297
+ * - invalid token → purge the cache (a revoked key must not keep the
298
+ * engine alive) and report a non-fatal error;
299
+ * - quota exceeded → non-fatal error, cache kept (transient condition)
300
+ * but not replayed this session.
301
+ */
302
+ private resolveManifest;
303
+ /**
304
+ * WebView parity — the load-time gating of `TrackingAppV3`:
305
+ * - `blazepose` / `poseEngine` / other WebView-only keys → clear error
306
+ * (this SDK ships MoveNet Lightning only);
307
+ * - developer features requested WITHOUT an API key → the front's exact
308
+ * "Invalid params… token=YOUR API_KEY…" message;
309
+ * - plan `free` + angles/recommendations/progression → the front's exact
310
+ * "You cannot use developer features." message (keypoints alone stays
311
+ * allowed here: pose-only mode is free; the +exercise case is enforced
312
+ * in {@link startExercise}).
313
+ * All non-fatal: keypoints-only pose estimation keeps running. One-shot
314
+ * per condition so `configure()` retries don't spam the host.
315
+ */
316
+ private validateRequestedFeatures;
317
+ private resolveModel;
318
+ getAvailableExercises(): ExerciseConfig[];
319
+ /**
320
+ * Custom exercises shipped inside the engine bundle (jump_analysis,
321
+ * air_time_jump — WebView `customHandlers.js` parity). Empty in
322
+ * keypoints-only mode or with an engine bundle older than 1.2.0.
323
+ */
324
+ getAvailableCustomExercises(): CustomExerciseDescriptor[];
325
+ startExercise(exerciseId: string, options?: StartExerciseOptions): void;
326
+ /** Custom engine session (jump_analysis / air_time_jump). */
327
+ private startCustomExercise;
328
+ /**
329
+ * Engine → host emission gate (WebView parity): `angles`,
330
+ * `recommendations` and `progression` only stream when their flag is on.
331
+ * Double safety on top of the engine-side flags — a cached engine bundle
332
+ * predating features support still gets filtered here.
333
+ */
334
+ private emitFromSession;
335
+ /** Ends the active session (emits a final `exercise_summary`). */
336
+ stopExercise(): void;
337
+ getCurrentExerciseId(): string | null;
338
+ /** Active inference backend (auto-selected, forced, or injected). */
339
+ getBackend(): PoseBackend;
340
+ /** Raw pose estimation, no engine involvement. */
341
+ estimatePose(frame: PoseInputFrame): Promise<Pose | null>;
342
+ /**
343
+ * Full pipeline for one camera frame: pose estimation + `keypoints` event
344
+ * (both modes), then engine processing when a session is active
345
+ * (full-engine mode). Mode upgrades take effect transparently here.
346
+ */
347
+ processFrame(frame: PoseInputFrame): Promise<Pose | null>;
348
+ /**
349
+ * Feed an externally-estimated pose into the pipeline: `keypoints` event
350
+ * (both modes) + engine processing when a session is active. This is how
351
+ * the vision-camera path (`PoseCameraView`) delivers poses computed
352
+ * synchronously inside the frame-processor worklet.
353
+ */
354
+ ingestPose(pose: Pose): void;
355
+ dispose(): Promise<void>;
356
+ private setStatus;
357
+ private setMode;
358
+ private reportError;
359
+ private notifyState;
360
+ private emit;
361
+ }