@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,86 @@
1
+ /**
2
+ * GPU-acceleration status types.
3
+ *
4
+ * Historical context (see docs/ANDROID_GL_ACCELERATION.md): on Android the
5
+ * previous product generation had to run TF.js inside a WebView because it
6
+ * was the only reliable way to get a working WebGL backend. The native path
7
+ * (tfjs-react-native over expo-gl) can silently degrade — the platform
8
+ * adapter *shims* float-texture extension queries, so TF.js may believe the
9
+ * GPU supports float32 render targets when it does not, and expo-gl contexts
10
+ * die on Android when the surface is backgrounded. These types exist so the
11
+ * SDK reports an explicit acceleration verdict instead of failing silently
12
+ * into a 1-2 fps CPU fallback.
13
+ */
14
+ /**
15
+ * - 'unknown': warm-up has not completed yet.
16
+ * - 'gpu': rn-webgl (expo-gl) active and the warm-up health check
17
+ * produced sane outputs within the latency budget.
18
+ * - 'cpu-fallback': inference works but is NOT GPU-accelerated (rn-webgl
19
+ * failed to initialize, produced NaN/garbage, or was
20
+ * pathologically slow — i.e. software rendering).
21
+ * - 'unavailable': no backend could run the model at all (fatal; the
22
+ * client also reports status 'error').
23
+ */
24
+ export type AccelerationState = 'unknown' | 'gpu' | 'cpu-fallback' | 'unavailable';
25
+ /** Raw GL context facts, gathered best-effort after backend init. */
26
+ export interface GlCapabilities {
27
+ /** e.g. "OpenGL ES 3.0 ..." */
28
+ glVersion: string | null;
29
+ /** e.g. "Adreno (TM) 640", "Mali-G78", "PowerVR ..." — key for triage. */
30
+ renderer: string | null;
31
+ vendor: string | null;
32
+ maxTextureSize: number | null;
33
+ /**
34
+ * Extension presence *as reported to TF.js*. WARNING: on rn-webgl the
35
+ * tfjs-react-native platform adapter shims `getExtension` and always
36
+ * reports EXT_color_buffer_float (Android) / EXT_color_buffer_half_float
37
+ * as present, so `true` here does NOT prove hardware support. That lie is
38
+ * exactly why the SDK forces f16 textures on Android and validates real
39
+ * outputs in the health check.
40
+ */
41
+ colorBufferFloat: boolean;
42
+ colorBufferHalfFloat: boolean;
43
+ textureFloat: boolean;
44
+ textureHalfFloat: boolean;
45
+ /** True when the extension answers above come from the shimmed adapter. */
46
+ extensionQueriesShimmed: boolean;
47
+ }
48
+ /** Snapshot of the TF.js WebGL flags that matter for Android stability. */
49
+ export type TfjsFlagSnapshot = Record<string, boolean | number | string | null>;
50
+ /**
51
+ * Inference runtime that produced the acceleration verdict:
52
+ * - 'webview': TF.js MoveNet inside a Chromium/WKWebView (ANGLE WebGL) —
53
+ * the SDK's base runtime, offline, same stack as the
54
+ * PoseTracker WebView product.
55
+ * - 'vision': Apple Vision (`VNDetectHumanBodyPoseRequest`) — iOS only.
56
+ */
57
+ export type InferenceRuntime = 'webview' | 'vision';
58
+ /** Native accelerator label (Apple Vision). */
59
+ export type VisionDelegateLabel = 'apple-vision';
60
+ export type NativeDelegateLabel = VisionDelegateLabel;
61
+ export interface AccelerationDiagnostics {
62
+ state: AccelerationState;
63
+ /** Active TF.js backend after init/fallbacks: 'rn-webgl' | 'cpu' | null. */
64
+ tfjsBackend: string | null;
65
+ /** Which runtime produced this verdict (absent = 'tfjs', pre-TFLite SDKs). */
66
+ runtime?: InferenceRuntime;
67
+ /** Active native accelerator; null/absent for the TF.js backend. */
68
+ delegate?: NativeDelegateLabel | null;
69
+ /** Median duration of the timed warm-up inferences, in ms. */
70
+ medianInferenceMs: number | null;
71
+ /** Individual timed warm-up runs, in ms (first run includes shader compilation). */
72
+ inferenceTimesMs: number[];
73
+ /** Latency budget used by the health check to accept the GPU path. */
74
+ maxAcceptableInferenceMs: number;
75
+ capabilities: GlCapabilities | null;
76
+ flags: TfjsFlagSnapshot;
77
+ /** Number of GL context losses recovered since init (Android lifecycle). */
78
+ contextLossCount: number;
79
+ /**
80
+ * Human-readable trail of every downgrade / recovery decision, e.g.
81
+ * "rn-webgl produced NaN outputs — falling back to CPU".
82
+ */
83
+ reasons: string[];
84
+ }
85
+ /** Callback for host apps that want SDK diagnostics in their own logger. */
86
+ export type DiagnosticListener = (message: string) => void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ /**
3
+ * GPU-acceleration status types.
4
+ *
5
+ * Historical context (see docs/ANDROID_GL_ACCELERATION.md): on Android the
6
+ * previous product generation had to run TF.js inside a WebView because it
7
+ * was the only reliable way to get a working WebGL backend. The native path
8
+ * (tfjs-react-native over expo-gl) can silently degrade — the platform
9
+ * adapter *shims* float-texture extension queries, so TF.js may believe the
10
+ * GPU supports float32 render targets when it does not, and expo-gl contexts
11
+ * die on Android when the surface is backgrounded. These types exist so the
12
+ * SDK reports an explicit acceleration verdict instead of failing silently
13
+ * into a 1-2 fps CPU fallback.
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,345 @@
1
+ /**
2
+ * SDK event types.
3
+ *
4
+ * These mirror the postMessage payloads of the existing PoseTracker WebView
5
+ * API (keypoints, angles, counter, posture, progression, recommendations,
6
+ * form_score, exercise_summary) so existing integrations can migrate with
7
+ * minimal changes: the WebView `onMessage` JSON becomes a typed callback.
8
+ */
9
+ import type { Keypoint } from './pose';
10
+ import type { AccelerationState } from './acceleration';
11
+ import type { QualityProfile, QualityProfileId } from '../quality/profiles';
12
+ export type PoseTrackerStatus = 'idle' | 'configuring' | 'downloading' | 'warming' | 'ready' | 'error';
13
+ /**
14
+ * Operating mode (commercial boundary):
15
+ * - 'keypoints-only': no validated API key/session — the SDK provides its
16
+ * core value only (bundled MoveNet, warm-up, camera pipeline) and streams
17
+ * raw `keypoints` events. No business events (counter, angles, posture,
18
+ * progression, recommendations, form_score, exercise_summary).
19
+ * - 'full-engine': a handshake succeeded (live or from the encrypted local
20
+ * session cache) and the engine bundle is loaded — all events available.
21
+ *
22
+ * The mode can upgrade at runtime (keypoints-only → full-engine) without
23
+ * restarting the camera pipeline, via `configure()` or a preload retry.
24
+ */
25
+ export type PoseTrackerMode = 'keypoints-only' | 'full-engine';
26
+ export type InitializationStep = 'configuring' | 'downloading' | 'warming' | 'accessing_webcam' | 'loading_pose_model' | 'ready';
27
+ export interface InitializationEvent {
28
+ type: 'initialization';
29
+ /**
30
+ * Machine step. Classic PoseTracker used free-form `message` strings
31
+ * ("accessing webcam", "loading pose model", "running"); both are set.
32
+ */
33
+ step: InitializationStep;
34
+ /** Human-readable status (PoseTracker WebView parity). */
35
+ message: string;
36
+ ready: boolean;
37
+ /** Present on the `ready` step. */
38
+ mode?: PoseTrackerMode;
39
+ /**
40
+ * Present on the `ready` step: GPU-acceleration verdict from the warm-up
41
+ * health check ('gpu' | 'cpu-fallback' | 'unavailable'). See
42
+ * docs/ANDROID_GL_ACCELERATION.md.
43
+ */
44
+ acceleration?: AccelerationState;
45
+ }
46
+ export interface ErrorEvent {
47
+ type: 'error';
48
+ code: 'invalid_token' | 'quota_exceeded' | 'network'
49
+ /**
50
+ * First launch, no network, empty runtime cache: the pose runtime cannot
51
+ * be initialized without downloading the payload once. Fatal.
52
+ */
53
+ | 'network_required'
54
+ /**
55
+ * Offline with an API key: metered features (engine/exercises) are
56
+ * refused because PoseTracker cannot count their usage. Non-fatal —
57
+ * keypoints-only keeps running from the cache.
58
+ */
59
+ | 'offline_metered'
60
+ /**
61
+ * The `free` plan requested developer features (angles, recommendations,
62
+ * progression, or keypoints combined with an exercise). Same message as
63
+ * the PoseTracker WebView (`TrackingAppV3`). Non-fatal: keypoints-only
64
+ * pose estimation keeps running.
65
+ */
66
+ | 'free_plan_feature_blocked'
67
+ /**
68
+ * A WebView-only option was requested (blazepose, poseEngine,
69
+ * mediapipeModel, …): this SDK ships MoveNet Lightning only.
70
+ */
71
+ | 'feature_not_supported'
72
+ /** Unknown exercise id (WebView parity: `invalid_exercise`). */
73
+ | 'invalid_exercise'
74
+ /** jump_analysis requires `userHeightCm` (WebView parity). */
75
+ | 'jump_analysis_missing_height' | 'model_load_failed' | 'engine_load_failed' | 'integrity_check_failed' | 'webview_error' | 'device_too_slow' | 'backend_fallback_wasm' | 'internal';
76
+ message: string;
77
+ }
78
+ /**
79
+ * Non-fatal warning the host can surface (telemetry / soft UX).
80
+ * Classic WebView sometimes used `type: "warning"`; V3 degradations often
81
+ * reuse `type: "error"` with a code — see {@link PerformanceWarningEvent}.
82
+ */
83
+ export interface WarningEvent {
84
+ type: 'warning';
85
+ code: 'quality_downgraded' | 'backend_fallback_wasm' | 'webview' | 'internal';
86
+ message: string;
87
+ timestampMs: number;
88
+ }
89
+ export interface KeypointsEvent {
90
+ type: 'keypoints';
91
+ keypoints: Keypoint[];
92
+ /** Mean confidence of the pose. */
93
+ score: number;
94
+ timestampMs: number;
95
+ }
96
+ export interface AngleValue {
97
+ /** Angle id from the exercise config, e.g. "left_knee". */
98
+ id: string;
99
+ side: 'left' | 'right' | 'center';
100
+ degrees: number;
101
+ /** Min confidence of the three keypoints defining the angle. */
102
+ score: number;
103
+ }
104
+ export interface AnglesEvent {
105
+ type: 'angles';
106
+ angles: AngleValue[];
107
+ timestampMs: number;
108
+ }
109
+ /**
110
+ * Letter grade for a 0–100 form score (GitBook / Front BaseExercise):
111
+ * A ≥ 90, B ≥ 80, C ≥ 70, D ≥ 60, F &lt; 60.
112
+ */
113
+ export type FormGrade = 'A' | 'B' | 'C' | 'D' | 'F';
114
+ /** Valid `minGrade` filter values (F is not a valid minGrade config). */
115
+ export type MinGrade = 'A' | 'B' | 'C' | 'D';
116
+ /**
117
+ * Nested form score on a counted rep — GitBook / WebView V3
118
+ * `counter.form_score` (authoritative grade for that rep).
119
+ */
120
+ export interface CounterFormScore {
121
+ /** Score of the rep that was just counted, 0–100. */
122
+ score: number;
123
+ /** Running average across counted reps, 0–100. */
124
+ average: number;
125
+ grade: FormGrade;
126
+ }
127
+ export interface CounterEvent {
128
+ type: 'counter';
129
+ count: number;
130
+ /**
131
+ * Authoritative form score for the counted rep (WebView
132
+ * `counter.form_score`). Prefer this over a standalone `form_score` event
133
+ * when mirroring the tracking endpoint.
134
+ */
135
+ formScore?: CounterFormScore;
136
+ /** Similarity score vs. reference movement for the last rep, when a reference is active. */
137
+ referenceScore?: number;
138
+ timestampMs: number;
139
+ }
140
+ export interface PostureEvent {
141
+ type: 'posture';
142
+ /** True when the user placement satisfies the exercise posture requirements. */
143
+ ready: boolean;
144
+ /** Localized human hint ("Face the camera", "Get ready…"). */
145
+ hint: string;
146
+ /** WebView parity: placement direction hint ("in-frame", "face-camera", "profile-camera"). */
147
+ direction?: string;
148
+ missingKeypoints: string[];
149
+ timestampMs: number;
150
+ }
151
+ export interface ProgressionEvent {
152
+ type: 'progression';
153
+ /** Movement progression within the current rep, 0–100. */
154
+ value: number;
155
+ timestampMs: number;
156
+ }
157
+ export interface RecommendationsEvent {
158
+ type: 'recommendations';
159
+ /** Localized form advice strings. */
160
+ recommendations: string[];
161
+ timestampMs: number;
162
+ }
163
+ export interface FormScoreEvent {
164
+ type: 'form_score';
165
+ /** Score of the last completed rep, 0–100. */
166
+ score: number;
167
+ /** Running average across the session, 0–100. */
168
+ average: number;
169
+ grade: FormGrade;
170
+ timestampMs: number;
171
+ }
172
+ export interface RepSummary {
173
+ index: number;
174
+ formScore: number;
175
+ durationMs: number;
176
+ referenceScore?: number;
177
+ }
178
+ export interface ExerciseSummaryEvent {
179
+ type: 'exercise_summary';
180
+ exercise: string;
181
+ counter: number;
182
+ averageFormScore: number;
183
+ averageSimilarity?: number;
184
+ grade: FormGrade;
185
+ history: RepSummary[];
186
+ durationMs: number;
187
+ timestampMs: number;
188
+ }
189
+ export interface VisibleHipsInfo {
190
+ left: boolean;
191
+ right: boolean;
192
+ }
193
+ /** jump_analysis only: cm/pixel calibration established from userHeightCm. */
194
+ export interface JumpCalibrationEvent {
195
+ type: 'jump_calibration';
196
+ calibrated: true;
197
+ cmPerPixel: number;
198
+ baselineY: number | null;
199
+ visibleHips: VisibleHipsInfo;
200
+ /** WebView literal: "Calibration complete - ready to jump". */
201
+ message: string;
202
+ timestampMs: number;
203
+ }
204
+ /** Push-off detected — measurement in progress. */
205
+ export interface JumpStartedEvent {
206
+ type: 'jump_started';
207
+ /** WebView literal: "Jump detected - measuring height". */
208
+ message: string;
209
+ timestampMs: number;
210
+ }
211
+ /** Live/final jump height. `final: true` closes the jump (see JumpResultEvent). */
212
+ export interface JumpHeightEvent {
213
+ type: 'jump_height';
214
+ jumpHeightCm: number;
215
+ baselineY?: number | null;
216
+ minY?: number | null;
217
+ measuring: boolean;
218
+ landed: boolean;
219
+ final?: boolean;
220
+ deltaPixels?: number;
221
+ sideUsed?: string | null;
222
+ airTimeMs?: number;
223
+ airTimeSeconds?: number;
224
+ visibleHips?: VisibleHipsInfo;
225
+ timestampMs: number;
226
+ }
227
+ /** Detection aborted (approach toward camera, timeout, tracking lost…). */
228
+ export interface JumpDiscardedEvent {
229
+ type: 'jump_discarded';
230
+ reason: string;
231
+ userMessage: string;
232
+ timestampMs: number;
233
+ }
234
+ /** One completed jump (final height for jump N). */
235
+ export interface JumpResultEvent {
236
+ type: 'jump_result';
237
+ jumpNumber: number;
238
+ jumpHeightCm: number;
239
+ airTimeMs?: number;
240
+ airTimeSeconds?: number;
241
+ baselineY?: number | null;
242
+ minY?: number | null;
243
+ deltaPixels?: number;
244
+ sideUsed?: string | null;
245
+ visibleHips?: VisibleHipsInfo;
246
+ timestampMs: number;
247
+ }
248
+ export interface JumpSummaryEntry {
249
+ jumpNumber: number;
250
+ jumpHeightCm: number;
251
+ airTimeMs?: number;
252
+ airTimeSeconds?: number;
253
+ }
254
+ /** Running summary of all completed jumps (emitted after each jump_result). */
255
+ export interface JumpSummaryEvent {
256
+ type: 'jump_summary';
257
+ totalJumps: number;
258
+ avgJumpHeight: number;
259
+ maxJumpHeight: number;
260
+ minJumpHeight: number;
261
+ avgAirTimeSeconds?: number;
262
+ jumps: JumpSummaryEntry[];
263
+ timestampMs: number;
264
+ }
265
+ /**
266
+ * Camera / preprocess quality tier changed (AdaptiveChoice auto-downgrade,
267
+ * crash-guard recovery, or GL capability hint). English, for app developers.
268
+ */
269
+ export interface QualityChangedEvent {
270
+ type: 'quality_changed';
271
+ previousProfile: QualityProfileId;
272
+ activeProfile: QualityProfileId;
273
+ reason: 'low_fps' | 'device_capability' | 'crash_guard' | 'warmup_estimate' | 'manual';
274
+ detail: string;
275
+ profile: QualityProfile;
276
+ /** Present when reason is warmup_estimate / low_fps. */
277
+ estimatedFps?: number | null;
278
+ medianInferenceMs?: number | null;
279
+ timestampMs: number;
280
+ }
281
+ /**
282
+ * Fired when mean inference FPS stays critically low. English developer alert —
283
+ * surface in your own telemetry / support tooling; do not show raw to end users
284
+ * unless you localize it.
285
+ */
286
+ export interface PerformanceWarningEvent {
287
+ type: 'performance_warning';
288
+ code: 'device_too_slow';
289
+ message: string;
290
+ meanFps: number;
291
+ thresholdFps: number;
292
+ activeProfile: QualityProfileId;
293
+ medianInferenceMs: number | null;
294
+ videoSize?: string;
295
+ timestampMs: number;
296
+ }
297
+ /**
298
+ * Download progress of the pose-runtime payload (first preload, or version
299
+ * update). Lets the host app show a loader/progress bar during the initial
300
+ * ~9 MB download; never fired when the cache is already up-to-date.
301
+ */
302
+ export interface RuntimeDownloadProgressEvent {
303
+ type: 'runtime_download_progress';
304
+ /** Part being downloaded (tfjs, tfjs-wasm, model, weights, pipeline, runtime). */
305
+ part: string;
306
+ completedParts: number;
307
+ totalParts: number;
308
+ /** Size of the current part, from the signed manifest. */
309
+ partBytes: number;
310
+ timestampMs: number;
311
+ }
312
+ export type PoseTrackerEvent = InitializationEvent | ErrorEvent | WarningEvent | RuntimeDownloadProgressEvent | KeypointsEvent | AnglesEvent | CounterEvent | PostureEvent | ProgressionEvent | RecommendationsEvent | FormScoreEvent | ExerciseSummaryEvent | JumpCalibrationEvent | JumpStartedEvent | JumpHeightEvent | JumpDiscardedEvent | JumpResultEvent | JumpSummaryEvent | QualityChangedEvent | PerformanceWarningEvent;
313
+ export type PoseTrackerEventType = PoseTrackerEvent['type'];
314
+ export type PoseTrackerEventListener = (event: PoseTrackerEvent) => void;
315
+ /**
316
+ * Typed per-event callbacks, convenient for `usePoseTracker({ onCounter, ... })`.
317
+ * Also accepts {@link onMessage} for classic PoseTracker WebView JSON parity.
318
+ */
319
+ export interface PoseTrackerCallbacks {
320
+ onInitialization?: (event: InitializationEvent) => void;
321
+ onError?: (event: ErrorEvent) => void;
322
+ onWarning?: (event: WarningEvent) => void;
323
+ onKeypoints?: (event: KeypointsEvent) => void;
324
+ onAngles?: (event: AnglesEvent) => void;
325
+ onCounter?: (event: CounterEvent) => void;
326
+ onPosture?: (event: PostureEvent) => void;
327
+ onProgression?: (event: ProgressionEvent) => void;
328
+ onRecommendations?: (event: RecommendationsEvent) => void;
329
+ onFormScore?: (event: FormScoreEvent) => void;
330
+ onExerciseSummary?: (event: ExerciseSummaryEvent) => void;
331
+ onJumpCalibration?: (event: JumpCalibrationEvent) => void;
332
+ onJumpStarted?: (event: JumpStartedEvent) => void;
333
+ onJumpHeight?: (event: JumpHeightEvent) => void;
334
+ onJumpDiscarded?: (event: JumpDiscardedEvent) => void;
335
+ onJumpResult?: (event: JumpResultEvent) => void;
336
+ onJumpSummary?: (event: JumpSummaryEvent) => void;
337
+ onQualityChanged?: (event: QualityChangedEvent) => void;
338
+ onPerformanceWarning?: (event: PerformanceWarningEvent) => void;
339
+ onRuntimeDownloadProgress?: (event: RuntimeDownloadProgressEvent) => void;
340
+ /**
341
+ * Classic PoseTracker `sendDataToNative` JSON stream (same `type` / field
342
+ * names as the WebView product). Fires for every typed event.
343
+ */
344
+ onMessage?: (message: import('../events/classicMessage').ClassicNativeMessage) => void;
345
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * SDK event types.
4
+ *
5
+ * These mirror the postMessage payloads of the existing PoseTracker WebView
6
+ * API (keypoints, angles, counter, posture, progression, recommendations,
7
+ * form_score, exercise_summary) so existing integrations can migrate with
8
+ * minimal changes: the WebView `onMessage` JSON becomes a typed callback.
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Host-selectable tracking features — SDK port of the PoseTracker WebView
3
+ * query params (`/pose_tracker/tracking?angles=true&…`) with the SAME plan
4
+ * gating and the SAME error messages as `TrackingAppV3`.
5
+ *
6
+ * Rules (mirroring the WebView product):
7
+ * - Without an API key the SDK always runs keypoints-only (offline, free,
8
+ * no gating) — pose-only mode streams `keypoints` unconditionally.
9
+ * - `angles`, `recommendations`, `progression` require a PAID plan
10
+ * (anything but `free`).
11
+ * - `keypoints` DURING an exercise session requires a paid plan too
12
+ * (free may stream keypoints only in pose-only mode, i.e. no exercise).
13
+ * - `blazepose` / `poseEngine` / `mediapipeModel` / `poseBackend` /
14
+ * `runInWorker` are NOT part of this SDK (MoveNet Lightning only) and are
15
+ * rejected with a clear error.
16
+ */
17
+ import type { MinGrade } from './events';
18
+ export interface PoseTrackerFeatures {
19
+ /**
20
+ * Stream `angles` events during an exercise session. Default `false`
21
+ * (WebView parity: `angles="false"`). Paid plans only.
22
+ */
23
+ angles?: boolean;
24
+ /**
25
+ * Stream `recommendations` events (form advice) during an exercise
26
+ * session. Default `false`. Paid plans only.
27
+ */
28
+ recommendations?: boolean;
29
+ /**
30
+ * Stream `progression` events (0–100 within the rep) during an exercise
31
+ * session. Default `false`. Paid plans only.
32
+ */
33
+ progression?: boolean;
34
+ /**
35
+ * Stream raw `keypoints` events DURING an exercise session. Default
36
+ * `false` (WebView parity: free plans cannot combine keypoints with an
37
+ * exercise). Outside a session (pose-only mode) keypoints always stream —
38
+ * that is the SDK's free offline base and is never gated.
39
+ */
40
+ keypoints?: boolean;
41
+ /**
42
+ * Only count reps whose form grade is at or above this letter (`A` best).
43
+ * WebView parity: `minGrade` query param (`A`…`D` only). Works on all
44
+ * plans that can run the exercise.
45
+ */
46
+ minGrade?: MinGrade;
47
+ }
48
+ /** Feature keys after defaults are applied. */
49
+ export interface ResolvedFeatures {
50
+ angles: boolean;
51
+ recommendations: boolean;
52
+ progression: boolean;
53
+ keypoints: boolean;
54
+ minGrade: MinGrade | null;
55
+ }
56
+ /** WebView-parity defaults: everything opt-in, like the query params. */
57
+ export declare const DEFAULT_FEATURES: ResolvedFeatures;
58
+ /** Free plan requested developer features (angles/recommendations/progression/keypoints+exercise). */
59
+ export declare const FREE_PLAN_FEATURES_MESSAGE = "You cannot use developer features. (visit: https://posetracker.gitbook.io/posetracker-api/tracking-endpoint)";
60
+ /** Missing/invalid API token when key-gated features are requested. */
61
+ export declare const INVALID_TOKEN_MESSAGE = "Invalid params. Please refer to the documentation and set token=YOUR API_KEY et exercise=A correct exercise. (visit: https://posetracker.gitbook.io/posetracker-api/tracking-endpoint)";
62
+ /** Reference movement and exercise are mutually exclusive (Phase 2 surface). */
63
+ export declare const COMBINED_REFERENCE_EXERCISE_MESSAGE = "You cannot combine reference & exercise. Please check the documentation.";
64
+ /** SDK-specific: the requested WebView feature does not exist in this SDK. */
65
+ export declare function featureNotSupportedMessage(key: string): string;
66
+ /**
67
+ * Apply WebView-parity defaults and detect unsupported keys passed by
68
+ * untyped JS hosts (e.g. `{ blazepose: true }`).
69
+ */
70
+ export declare function resolveFeatures(input: PoseTrackerFeatures | undefined): {
71
+ features: ResolvedFeatures;
72
+ unsupportedKeys: string[];
73
+ };
74
+ /**
75
+ * Which requested features a `free` plan is NOT allowed to use — exact port
76
+ * of the TrackingAppV3 condition (keypoints only blocked when an exercise
77
+ * is involved; pose-only keypoints stay free).
78
+ */
79
+ export declare function freeBlockedFeatures(features: ResolvedFeatures, options: {
80
+ withExercise: boolean;
81
+ }): string[];
82
+ /** True for every plan type except `free` (developer / company / custom). */
83
+ export declare function isPaidPlan(planType: string | null | undefined): boolean;
84
+ /**
85
+ * Whether the live camera overlay should show the PoseTracker watermark.
86
+ * Shown for keyless (null), `free`, and any non-paid plan. Hidden for paid
87
+ * plans (`developer`, `company`, `enterprise`, custom, …) — same rule as
88
+ * {@link isPaidPlan}.
89
+ */
90
+ export declare function shouldShowWatermark(planType: string | null | undefined): boolean;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Host-selectable tracking features — SDK port of the PoseTracker WebView
4
+ * query params (`/pose_tracker/tracking?angles=true&…`) with the SAME plan
5
+ * gating and the SAME error messages as `TrackingAppV3`.
6
+ *
7
+ * Rules (mirroring the WebView product):
8
+ * - Without an API key the SDK always runs keypoints-only (offline, free,
9
+ * no gating) — pose-only mode streams `keypoints` unconditionally.
10
+ * - `angles`, `recommendations`, `progression` require a PAID plan
11
+ * (anything but `free`).
12
+ * - `keypoints` DURING an exercise session requires a paid plan too
13
+ * (free may stream keypoints only in pose-only mode, i.e. no exercise).
14
+ * - `blazepose` / `poseEngine` / `mediapipeModel` / `poseBackend` /
15
+ * `runInWorker` are NOT part of this SDK (MoveNet Lightning only) and are
16
+ * rejected with a clear error.
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.COMBINED_REFERENCE_EXERCISE_MESSAGE = exports.INVALID_TOKEN_MESSAGE = exports.FREE_PLAN_FEATURES_MESSAGE = exports.DEFAULT_FEATURES = void 0;
20
+ exports.featureNotSupportedMessage = featureNotSupportedMessage;
21
+ exports.resolveFeatures = resolveFeatures;
22
+ exports.freeBlockedFeatures = freeBlockedFeatures;
23
+ exports.isPaidPlan = isPaidPlan;
24
+ exports.shouldShowWatermark = shouldShowWatermark;
25
+ /** WebView-parity defaults: everything opt-in, like the query params. */
26
+ exports.DEFAULT_FEATURES = {
27
+ angles: false,
28
+ recommendations: false,
29
+ progression: false,
30
+ keypoints: false,
31
+ minGrade: null,
32
+ };
33
+ const KNOWN_FEATURE_KEYS = new Set([
34
+ 'angles',
35
+ 'recommendations',
36
+ 'progression',
37
+ 'keypoints',
38
+ 'minGrade',
39
+ ]);
40
+ /**
41
+ * WebView params that this SDK deliberately does NOT ship (one SDK, one
42
+ * model: MoveNet Lightning). Passing them (possible from untyped JS hosts)
43
+ * produces a clear `feature_not_supported` error.
44
+ */
45
+ const UNSUPPORTED_FEATURE_HINTS = {
46
+ blazepose: 'BlazePose',
47
+ poseEngine: 'pose engine selection (MediaPipe/PoseLandmarker)',
48
+ mediapipeModel: 'MediaPipe model selection',
49
+ poseBackend: 'pose backend selection',
50
+ runInWorker: 'worker thread selection',
51
+ };
52
+ // ---------------------------------------------------------------------------
53
+ // Error messages — EXACT copies of PoseTrackerFront/components/v3/TrackingAppV3.js
54
+ // so hosts migrating from the WebView see identical strings.
55
+ // ---------------------------------------------------------------------------
56
+ /** Free plan requested developer features (angles/recommendations/progression/keypoints+exercise). */
57
+ exports.FREE_PLAN_FEATURES_MESSAGE = 'You cannot use developer features. (visit: https://posetracker.gitbook.io/posetracker-api/tracking-endpoint)';
58
+ /** Missing/invalid API token when key-gated features are requested. */
59
+ exports.INVALID_TOKEN_MESSAGE = 'Invalid params. Please refer to the documentation and set token=YOUR API_KEY et exercise=A correct exercise. (visit: https://posetracker.gitbook.io/posetracker-api/tracking-endpoint)';
60
+ /** Reference movement and exercise are mutually exclusive (Phase 2 surface). */
61
+ exports.COMBINED_REFERENCE_EXERCISE_MESSAGE = 'You cannot combine reference & exercise. Please check the documentation.';
62
+ /** SDK-specific: the requested WebView feature does not exist in this SDK. */
63
+ function featureNotSupportedMessage(key) {
64
+ const hint = UNSUPPORTED_FEATURE_HINTS[key] ?? `'${key}'`;
65
+ return (`The '${key}' option (${hint}) is not available in this SDK. ` +
66
+ 'This SDK ships MoveNet Lightning only — pose engine and model cannot be changed. ' +
67
+ 'Remove the option, or use the PoseTracker WebView product if you need it. ' +
68
+ '(visit: https://posetracker.gitbook.io/posetracker-api/tracking-endpoint)');
69
+ }
70
+ // ---------------------------------------------------------------------------
71
+ // Helpers
72
+ // ---------------------------------------------------------------------------
73
+ /**
74
+ * Apply WebView-parity defaults and detect unsupported keys passed by
75
+ * untyped JS hosts (e.g. `{ blazepose: true }`).
76
+ */
77
+ function resolveFeatures(input) {
78
+ if (!input) {
79
+ return { features: { ...exports.DEFAULT_FEATURES }, unsupportedKeys: [] };
80
+ }
81
+ const unsupportedKeys = Object.keys(input).filter((k) => !KNOWN_FEATURE_KEYS.has(k));
82
+ return {
83
+ features: {
84
+ angles: input.angles === true,
85
+ recommendations: input.recommendations === true,
86
+ progression: input.progression === true,
87
+ keypoints: input.keypoints === true,
88
+ minGrade: input.minGrade ?? null,
89
+ },
90
+ unsupportedKeys,
91
+ };
92
+ }
93
+ /**
94
+ * Which requested features a `free` plan is NOT allowed to use — exact port
95
+ * of the TrackingAppV3 condition (keypoints only blocked when an exercise
96
+ * is involved; pose-only keypoints stay free).
97
+ */
98
+ function freeBlockedFeatures(features, options) {
99
+ const blocked = [];
100
+ if (features.angles)
101
+ blocked.push('angles');
102
+ if (features.recommendations)
103
+ blocked.push('recommendations');
104
+ if (features.progression)
105
+ blocked.push('progression');
106
+ if (features.keypoints && options.withExercise)
107
+ blocked.push('keypoints');
108
+ return blocked;
109
+ }
110
+ /** True for every plan type except `free` (developer / company / custom). */
111
+ function isPaidPlan(planType) {
112
+ return typeof planType === 'string' && planType.length > 0 && planType !== 'free';
113
+ }
114
+ /**
115
+ * Whether the live camera overlay should show the PoseTracker watermark.
116
+ * Shown for keyless (null), `free`, and any non-paid plan. Hidden for paid
117
+ * plans (`developer`, `company`, `enterprise`, custom, …) — same rule as
118
+ * {@link isPaidPlan}.
119
+ */
120
+ function shouldShowWatermark(planType) {
121
+ return !isPaidPlan(planType);
122
+ }