@pose-tracker/react-native-pose-estimation-light 0.2.0 → 0.2.1

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/README.md CHANGED
@@ -47,6 +47,10 @@ npx expo install react-native-webview expo-camera
47
47
  **Required:** host app must declare camera permissions — see
48
48
  [PERMISSIONS.md](../../docs/PERMISSIONS.md).
49
49
 
50
+ **Media inputs (v0.2):** camera (default), uploaded video, still image — host
51
+ picks the file. See [MEDIA_SOURCES.md](../../docs/MEDIA_SOURCES.md) and
52
+ https://docs.posetracker.com/media-sources.
53
+
50
54
  ## Quick start (keypoints — needs network, no API key)
51
55
 
52
56
  ```tsx
@@ -154,6 +154,9 @@ function usePoseTracker(callbacks = {}) {
154
154
  case 'progression':
155
155
  cb.onProgression?.(event);
156
156
  break;
157
+ case 'engine_debug':
158
+ cb.onEngineDebug?.(event);
159
+ break;
157
160
  case 'recommendations':
158
161
  cb.onRecommendations?.(event);
159
162
  break;
package/lib/client.d.ts CHANGED
@@ -102,6 +102,12 @@ export interface PoseTrackerClientOptions extends ConfigureOptions {
102
102
  * triaging Android GPU issues in the field.
103
103
  */
104
104
  onDiagnostic?: (message: string) => void;
105
+ /**
106
+ * When true, exercise sessions request `engine_debug` snapshots from the
107
+ * remote engine (bundle ≥ 1.2.4). Overridable per call via
108
+ * `startExercise(id, { debug: true|false })`.
109
+ */
110
+ debugEngine?: boolean;
105
111
  }
106
112
  /**
107
113
  * Per-session options for {@link PoseTrackerClient.startExercise} — the SDK
@@ -118,6 +124,11 @@ export interface StartExerciseOptions {
118
124
  userHeightCm?: number;
119
125
  /** Device pitch in degrees — jump exercises compensate camera tilt. */
120
126
  devicePitchDeg?: number;
127
+ /**
128
+ * Request throttled `engine_debug` events for this session (movement FSM
129
+ * QA). Defaults to {@link PoseTrackerClientOptions.debugEngine}.
130
+ */
131
+ debug?: boolean;
121
132
  }
122
133
  export declare class PoseTrackerClient {
123
134
  private status;
package/lib/client.js CHANGED
@@ -818,17 +818,21 @@ class PoseTrackerClient {
818
818
  this.stopExercise();
819
819
  this.currentExerciseId = exerciseId;
820
820
  this.keypointsSuppressionLogged = false;
821
+ const debug = options.debug ?? this.options.debugEngine === true;
821
822
  this.session = this.engine.createSession({
822
823
  exercise,
823
824
  locale: this.options.locale ?? 'en',
824
825
  difficulty: options.difficulty,
825
826
  minGrade: this.features.minGrade ?? undefined,
827
+ debug,
826
828
  features: {
827
829
  angles: this.features.angles,
828
830
  recommendations: this.features.recommendations,
829
831
  progression: this.features.progression,
830
832
  },
831
833
  }, (event) => this.emitFromSession(event));
834
+ this.options.onDiagnostic?.(`[posetracker] startExercise id=${exercise.id} difficulty=${options.difficulty ?? 'medium'} ` +
835
+ `debug=${debug} engine=${this.engine.version} minGrade=${this.features.minGrade ?? 'off'}`);
832
836
  }
833
837
  /** Custom engine session (jump_analysis / air_time_jump). */
834
838
  startCustomExercise(custom, options) {
@@ -1032,6 +1036,10 @@ class PoseTrackerClient {
1032
1036
  return;
1033
1037
  }
1034
1038
  const classic = (0, classicMessage_1.toClassicNativeMessage)(event);
1039
+ if (classic == null) {
1040
+ // SDK-only events (e.g. engine_debug) have no classic equivalent.
1041
+ return;
1042
+ }
1035
1043
  this.messageListeners.forEach((l) => {
1036
1044
  try {
1037
1045
  l(classic);
@@ -36,6 +36,11 @@ export interface EngineSessionOptions {
36
36
  minGrade?: MinGrade;
37
37
  /** Emission flags — engines older than 1.1.0 ignore them (client re-filters). */
38
38
  features?: EngineSessionFeatures;
39
+ /**
40
+ * When true, the engine emits throttled `engine_debug` events (movement
41
+ * FSM snapshot). Requires engine bundle ≥ 1.2.4. Ignored by older engines.
42
+ */
43
+ debug?: boolean;
39
44
  }
40
45
  export interface EngineSession {
41
46
  /** Feed one estimated pose; the session emits events through the sink. */
@@ -26,6 +26,6 @@ export declare function anglesToClassicTree(angles: AngleValue[]): {
26
26
  /**
27
27
  * Map a typed SDK event to a classic PoseTracker `sendDataToNative` payload.
28
28
  * Returns null for SDK-only events that have no classic equivalent and should
29
- * not be mirrored (none today — quality/performance map to error/warning).
29
+ * not be mirrored (e.g. `engine_debug` QA snapshots).
30
30
  */
31
- export declare function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMessage;
31
+ export declare function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMessage | null;
@@ -49,7 +49,7 @@ function anglesToClassicTree(angles) {
49
49
  /**
50
50
  * Map a typed SDK event to a classic PoseTracker `sendDataToNative` payload.
51
51
  * Returns null for SDK-only events that have no classic equivalent and should
52
- * not be mirrored (none today — quality/performance map to error/warning).
52
+ * not be mirrored (e.g. `engine_debug` QA snapshots).
53
53
  */
54
54
  function toClassicNativeMessage(event) {
55
55
  switch (event.type) {
@@ -236,6 +236,9 @@ function toClassicNativeMessage(event) {
236
236
  totalParts: event.totalParts,
237
237
  timestampMs: event.timestampMs,
238
238
  };
239
+ case 'engine_debug':
240
+ // SDK-only QA stream — no classic WebView equivalent; skip onMessage.
241
+ return null;
239
242
  default: {
240
243
  const _exhaustive = event;
241
244
  return { type: 'unknown', event: _exhaustive };
@@ -1,2 +1,2 @@
1
1
  /** AUTO-GENERATED by scripts/sync-sdk-version.mjs — do not edit. */
2
- export declare const SDK_VERSION = "0.2.0";
2
+ export declare const SDK_VERSION = "0.2.1";
package/lib/sdkVersion.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SDK_VERSION = void 0;
4
4
  /** AUTO-GENERATED by scripts/sync-sdk-version.mjs — do not edit. */
5
- exports.SDK_VERSION = '0.2.0';
5
+ exports.SDK_VERSION = '0.2.1';
@@ -154,6 +154,40 @@ export interface ProgressionEvent {
154
154
  value: number;
155
155
  timestampMs: number;
156
156
  }
157
+ /**
158
+ * Throttled movement / rep-FSM snapshot for QA (engine ≥ 1.2.4).
159
+ * Enable via `PoseTrackerClientOptions.debugEngine` or `startExercise(..., { debug: true })`.
160
+ */
161
+ export interface EngineDebugEvent {
162
+ type: 'engine_debug';
163
+ exerciseId: string;
164
+ engineVersion: string;
165
+ ready: boolean;
166
+ postureHint: string;
167
+ direction?: string;
168
+ missingKeypoints: string[];
169
+ stepIndex: number;
170
+ stepCount: number;
171
+ stepPosition: number | null;
172
+ stepProgression: number;
173
+ progression: number;
174
+ /** Raw FSM rep count (before minGrade gate). */
175
+ rawCount: number;
176
+ /** Public counter after minGrade gate. */
177
+ publicCount: number;
178
+ difficulty: string;
179
+ minGrade: MinGrade | null;
180
+ pointOfView: 'low' | 'up';
181
+ computeError?: string;
182
+ lastSkipReason: string | null;
183
+ posesProcessed: number;
184
+ visibleKeypoints: number;
185
+ knees: {
186
+ left: number | null;
187
+ right: number | null;
188
+ };
189
+ timestampMs: number;
190
+ }
157
191
  export interface RecommendationsEvent {
158
192
  type: 'recommendations';
159
193
  /** Localized form advice strings. */
@@ -309,7 +343,7 @@ export interface RuntimeDownloadProgressEvent {
309
343
  partBytes: number;
310
344
  timestampMs: number;
311
345
  }
312
- export type PoseTrackerEvent = InitializationEvent | ErrorEvent | WarningEvent | RuntimeDownloadProgressEvent | KeypointsEvent | AnglesEvent | CounterEvent | PostureEvent | ProgressionEvent | RecommendationsEvent | FormScoreEvent | ExerciseSummaryEvent | JumpCalibrationEvent | JumpStartedEvent | JumpHeightEvent | JumpDiscardedEvent | JumpResultEvent | JumpSummaryEvent | QualityChangedEvent | PerformanceWarningEvent;
346
+ export type PoseTrackerEvent = InitializationEvent | ErrorEvent | WarningEvent | RuntimeDownloadProgressEvent | KeypointsEvent | AnglesEvent | CounterEvent | PostureEvent | ProgressionEvent | EngineDebugEvent | RecommendationsEvent | FormScoreEvent | ExerciseSummaryEvent | JumpCalibrationEvent | JumpStartedEvent | JumpHeightEvent | JumpDiscardedEvent | JumpResultEvent | JumpSummaryEvent | QualityChangedEvent | PerformanceWarningEvent;
313
347
  export type PoseTrackerEventType = PoseTrackerEvent['type'];
314
348
  export type PoseTrackerEventListener = (event: PoseTrackerEvent) => void;
315
349
  /**
@@ -325,6 +359,7 @@ export interface PoseTrackerCallbacks {
325
359
  onCounter?: (event: CounterEvent) => void;
326
360
  onPosture?: (event: PostureEvent) => void;
327
361
  onProgression?: (event: ProgressionEvent) => void;
362
+ onEngineDebug?: (event: EngineDebugEvent) => void;
328
363
  onRecommendations?: (event: RecommendationsEvent) => void;
329
364
  onFormScore?: (event: FormScoreEvent) => void;
330
365
  onExerciseSummary?: (event: ExerciseSummaryEvent) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pose-tracker/react-native-pose-estimation-light",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Human pose estimation SDK for React Native (light / online) — MoveNet Lightning via CDN + model URL each session, no bundled weights. iOS & Android (Expo Go). Optional API-key exercise engine.",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -281,6 +281,9 @@ export function usePoseTracker(callbacks: PoseTrackerCallbacks = {}): PoseTracke
281
281
  case 'progression':
282
282
  cb.onProgression?.(event);
283
283
  break;
284
+ case 'engine_debug':
285
+ cb.onEngineDebug?.(event);
286
+ break;
284
287
  case 'recommendations':
285
288
  cb.onRecommendations?.(event);
286
289
  break;
package/src/client.ts CHANGED
@@ -69,7 +69,6 @@ import {
69
69
  import {
70
70
  toClassicNativeMessage,
71
71
  type ClassicMessageListener,
72
- type ClassicNativeMessage,
73
72
  } from './events/classicMessage';
74
73
  import {
75
74
  FREE_PLAN_FEATURES_MESSAGE,
@@ -164,6 +163,12 @@ export interface PoseTrackerClientOptions extends ConfigureOptions {
164
163
  * triaging Android GPU issues in the field.
165
164
  */
166
165
  onDiagnostic?: (message: string) => void;
166
+ /**
167
+ * When true, exercise sessions request `engine_debug` snapshots from the
168
+ * remote engine (bundle ≥ 1.2.4). Overridable per call via
169
+ * `startExercise(id, { debug: true|false })`.
170
+ */
171
+ debugEngine?: boolean;
167
172
  }
168
173
 
169
174
  /**
@@ -181,6 +186,11 @@ export interface StartExerciseOptions {
181
186
  userHeightCm?: number;
182
187
  /** Device pitch in degrees — jump exercises compensate camera tilt. */
183
188
  devicePitchDeg?: number;
189
+ /**
190
+ * Request throttled `engine_debug` events for this session (movement FSM
191
+ * QA). Defaults to {@link PoseTrackerClientOptions.debugEngine}.
192
+ */
193
+ debug?: boolean;
184
194
  }
185
195
 
186
196
  export class PoseTrackerClient {
@@ -1040,12 +1050,14 @@ export class PoseTrackerClient {
1040
1050
  this.stopExercise();
1041
1051
  this.currentExerciseId = exerciseId;
1042
1052
  this.keypointsSuppressionLogged = false;
1053
+ const debug = options.debug ?? this.options.debugEngine === true;
1043
1054
  this.session = this.engine.createSession(
1044
1055
  {
1045
1056
  exercise,
1046
1057
  locale: this.options.locale ?? 'en',
1047
1058
  difficulty: options.difficulty,
1048
1059
  minGrade: this.features.minGrade ?? undefined,
1060
+ debug,
1049
1061
  features: {
1050
1062
  angles: this.features.angles,
1051
1063
  recommendations: this.features.recommendations,
@@ -1054,6 +1066,10 @@ export class PoseTrackerClient {
1054
1066
  },
1055
1067
  (event) => this.emitFromSession(event),
1056
1068
  );
1069
+ this.options.onDiagnostic?.(
1070
+ `[posetracker] startExercise id=${exercise.id} difficulty=${options.difficulty ?? 'medium'} ` +
1071
+ `debug=${debug} engine=${this.engine.version} minGrade=${this.features.minGrade ?? 'off'}`,
1072
+ );
1057
1073
  }
1058
1074
 
1059
1075
  /** Custom engine session (jump_analysis / air_time_jump). */
@@ -1280,7 +1296,11 @@ export class PoseTrackerClient {
1280
1296
  // Skip the classic-message conversion entirely (per-frame allocation).
1281
1297
  return;
1282
1298
  }
1283
- const classic: ClassicNativeMessage = toClassicNativeMessage(event);
1299
+ const classic = toClassicNativeMessage(event);
1300
+ if (classic == null) {
1301
+ // SDK-only events (e.g. engine_debug) have no classic equivalent.
1302
+ return;
1303
+ }
1284
1304
  this.messageListeners.forEach((l) => {
1285
1305
  try {
1286
1306
  l(classic);
@@ -39,6 +39,11 @@ export interface EngineSessionOptions {
39
39
  minGrade?: MinGrade;
40
40
  /** Emission flags — engines older than 1.1.0 ignore them (client re-filters). */
41
41
  features?: EngineSessionFeatures;
42
+ /**
43
+ * When true, the engine emits throttled `engine_debug` events (movement
44
+ * FSM snapshot). Requires engine bundle ≥ 1.2.4. Ignored by older engines.
45
+ */
46
+ debug?: boolean;
42
47
  }
43
48
 
44
49
  export interface EngineSession {
@@ -59,9 +59,11 @@ export function anglesToClassicTree(angles: AngleValue[]): {
59
59
  /**
60
60
  * Map a typed SDK event to a classic PoseTracker `sendDataToNative` payload.
61
61
  * Returns null for SDK-only events that have no classic equivalent and should
62
- * not be mirrored (none today — quality/performance map to error/warning).
62
+ * not be mirrored (e.g. `engine_debug` QA snapshots).
63
63
  */
64
- export function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMessage {
64
+ export function toClassicNativeMessage(
65
+ event: PoseTrackerEvent,
66
+ ): ClassicNativeMessage | null {
65
67
  switch (event.type) {
66
68
  case 'initialization':
67
69
  return {
@@ -247,6 +249,9 @@ export function toClassicNativeMessage(event: PoseTrackerEvent): ClassicNativeMe
247
249
  totalParts: event.totalParts,
248
250
  timestampMs: event.timestampMs,
249
251
  };
252
+ case 'engine_debug':
253
+ // SDK-only QA stream — no classic WebView equivalent; skip onMessage.
254
+ return null;
250
255
  default: {
251
256
  const _exhaustive: never = event;
252
257
  return { type: 'unknown', event: _exhaustive };
package/src/sdkVersion.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** AUTO-GENERATED by scripts/sync-sdk-version.mjs — do not edit. */
2
- export const SDK_VERSION = '0.2.0';
2
+ export const SDK_VERSION = '0.2.1';
@@ -198,6 +198,38 @@ export interface ProgressionEvent {
198
198
  timestampMs: number;
199
199
  }
200
200
 
201
+ /**
202
+ * Throttled movement / rep-FSM snapshot for QA (engine ≥ 1.2.4).
203
+ * Enable via `PoseTrackerClientOptions.debugEngine` or `startExercise(..., { debug: true })`.
204
+ */
205
+ export interface EngineDebugEvent {
206
+ type: 'engine_debug';
207
+ exerciseId: string;
208
+ engineVersion: string;
209
+ ready: boolean;
210
+ postureHint: string;
211
+ direction?: string;
212
+ missingKeypoints: string[];
213
+ stepIndex: number;
214
+ stepCount: number;
215
+ stepPosition: number | null;
216
+ stepProgression: number;
217
+ progression: number;
218
+ /** Raw FSM rep count (before minGrade gate). */
219
+ rawCount: number;
220
+ /** Public counter after minGrade gate. */
221
+ publicCount: number;
222
+ difficulty: string;
223
+ minGrade: MinGrade | null;
224
+ pointOfView: 'low' | 'up';
225
+ computeError?: string;
226
+ lastSkipReason: string | null;
227
+ posesProcessed: number;
228
+ visibleKeypoints: number;
229
+ knees: { left: number | null; right: number | null };
230
+ timestampMs: number;
231
+ }
232
+
201
233
  export interface RecommendationsEvent {
202
234
  type: 'recommendations';
203
235
  /** Localized form advice strings. */
@@ -389,6 +421,7 @@ export type PoseTrackerEvent =
389
421
  | CounterEvent
390
422
  | PostureEvent
391
423
  | ProgressionEvent
424
+ | EngineDebugEvent
392
425
  | RecommendationsEvent
393
426
  | FormScoreEvent
394
427
  | ExerciseSummaryEvent
@@ -418,6 +451,7 @@ export interface PoseTrackerCallbacks {
418
451
  onCounter?: (event: CounterEvent) => void;
419
452
  onPosture?: (event: PostureEvent) => void;
420
453
  onProgression?: (event: ProgressionEvent) => void;
454
+ onEngineDebug?: (event: EngineDebugEvent) => void;
421
455
  onRecommendations?: (event: RecommendationsEvent) => void;
422
456
  onFormScore?: (event: FormScoreEvent) => void;
423
457
  onExerciseSummary?: (event: ExerciseSummaryEvent) => void;