@pose-tracker/react-native-pose-estimation-light 0.2.1 → 0.3.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.
- package/README.md +22 -11
- package/lib/PoseTrackerProvider.d.ts +6 -1
- package/lib/PoseTrackerProvider.js +5 -2
- package/lib/api/configure.d.ts +6 -0
- package/lib/api/configure.js +1 -0
- package/lib/client.d.ts +8 -5
- package/lib/client.js +56 -2
- package/lib/engine/types.d.ts +9 -2
- package/lib/engineChannel.d.ts +6 -0
- package/lib/engineChannel.js +17 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +6 -2
- package/lib/sdkVersion.d.ts +1 -1
- package/lib/sdkVersion.js +1 -1
- package/lib/types/events.d.ts +2 -2
- package/lib/types/manifest.d.ts +7 -0
- package/package.json +1 -1
- package/src/PoseTrackerProvider.tsx +10 -1
- package/src/api/configure.ts +7 -0
- package/src/client.ts +61 -7
- package/src/engine/types.ts +9 -2
- package/src/engineChannel.ts +17 -0
- package/src/index.ts +2 -0
- package/src/sdkVersion.ts +1 -1
- package/src/types/events.ts +2 -2
- package/src/types/manifest.ts +7 -0
package/README.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# PoseTracker React Native — Light (online) Human Pose Estimation SDK
|
|
2
2
|
|
|
3
|
+
**⭐ Star us on GitHub:** [Movelytics/react-native-pose-estimation-light](https://github.com/Movelytics/react-native-pose-estimation-light) — it helps other React Native and Expo developers find the SDK.
|
|
4
|
+
|
|
5
|
+
**Try it on your phone (no Xcode / Android Studio):**
|
|
6
|
+
1. Install [Expo Go](https://expo.dev/go)
|
|
7
|
+
2. Open the [Expo Snack](https://snack.expo.dev/@fsepret/posetracker-sdk-light-demo-app) → **Run on device**
|
|
8
|
+
3. Scan the QR — live pose estimation, no API key
|
|
9
|
+
|
|
10
|
+
Steps and QR: https://docs.posetracker.com/try-expo-go
|
|
11
|
+
|
|
3
12
|
**PoseTracker Light** is a **human pose estimation SDK for React Native**,
|
|
4
13
|
fully optimized for **iOS and Android** (including **Expo Go**). Same API
|
|
5
14
|
surface as the offline SDK for keypoints + optional API-key exercise engine —
|
|
@@ -27,10 +36,10 @@ package stays tiny.
|
|
|
27
36
|
download at session start.
|
|
28
37
|
**Choose light** when app install / OTA size matters and devices are online.
|
|
29
38
|
|
|
30
|
-
Full comparison: [LIGHT_SDK.md](
|
|
39
|
+
Full comparison: [LIGHT_SDK.md](docs/LIGHT_SDK.md).
|
|
31
40
|
|
|
32
41
|
**Agents:** shared UX/API/bugfixes → mirror to offline (or ask first). See
|
|
33
|
-
[`DUAL_SDK_CHANGES.md`](
|
|
42
|
+
[`DUAL_SDK_CHANGES.md`](docs/DUAL_SDK_CHANGES.md).
|
|
34
43
|
|
|
35
44
|
## Install
|
|
36
45
|
|
|
@@ -45,10 +54,10 @@ npx expo install react-native-webview expo-camera
|
|
|
45
54
|
> **Offline sibling:** [`@pose-tracker/react-native-pose-estimation`](https://www.npmjs.com/package/@pose-tracker/react-native-pose-estimation)
|
|
46
55
|
|
|
47
56
|
**Required:** host app must declare camera permissions — see
|
|
48
|
-
[PERMISSIONS.md](
|
|
57
|
+
[PERMISSIONS.md](docs/PERMISSIONS.md).
|
|
49
58
|
|
|
50
59
|
**Media inputs (v0.2):** camera (default), uploaded video, still image — host
|
|
51
|
-
picks the file. See [MEDIA_SOURCES.md](
|
|
60
|
+
picks the file. See [MEDIA_SOURCES.md](docs/MEDIA_SOURCES.md) and
|
|
52
61
|
https://docs.posetracker.com/media-sources.
|
|
53
62
|
|
|
54
63
|
## Quick start (keypoints — needs network, no API key)
|
|
@@ -135,11 +144,11 @@ Same contract as the offline SDK / web tracking URL:
|
|
|
135
144
|
|
|
136
145
|
| Doc | Topic |
|
|
137
146
|
|-----|--------|
|
|
138
|
-
| [LIGHT_SDK.md](
|
|
139
|
-
| [PERMISSIONS.md](
|
|
140
|
-
| [PRELOAD.md](
|
|
141
|
-
| [FEATURES.md](
|
|
142
|
-
| [EVENTS.md](
|
|
147
|
+
| [LIGHT_SDK.md](docs/LIGHT_SDK.md) | Offline vs light, sizes, model URL |
|
|
148
|
+
| [PERMISSIONS.md](docs/PERMISSIONS.md) | Camera permission setup (required) |
|
|
149
|
+
| [PRELOAD.md](docs/PRELOAD.md) | Preload / warm-up / lifecycle |
|
|
150
|
+
| [FEATURES.md](docs/FEATURES.md) | Plan gating, watermark, loading text |
|
|
151
|
+
| [EVENTS.md](docs/EVENTS.md) | Typed events + classic `onMessage` |
|
|
143
152
|
|
|
144
153
|
## FAQ
|
|
145
154
|
|
|
@@ -168,6 +177,8 @@ see [`THIRD_PARTY_NOTICES.md`](./THIRD_PARTY_NOTICES.md).
|
|
|
168
177
|
## Links
|
|
169
178
|
|
|
170
179
|
- Product: https://www.posetracker.com
|
|
171
|
-
-
|
|
172
|
-
-
|
|
180
|
+
- Docs: https://docs.posetracker.com
|
|
181
|
+
- Try on your phone: https://docs.posetracker.com/try-expo-go
|
|
182
|
+
- Expo Snack: https://snack.expo.dev/@fsepret/posetracker-sdk-light-demo-app
|
|
173
183
|
- Light demo: https://github.com/Movelytics/react-native-pose-estimation-light-demo
|
|
184
|
+
- Offline SDK: https://github.com/Movelytics/react-native-pose-estimation
|
|
@@ -83,12 +83,17 @@ export interface PoseTrackerContextValue {
|
|
|
83
83
|
export interface PoseTrackerProviderProps {
|
|
84
84
|
/** Optional: without a token the SDK runs in keypoints-only mode. */
|
|
85
85
|
apiToken?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Opt-in V4 engine (`'v4'`). Default `'v3'` — production FSM, unchanged.
|
|
88
|
+
* Merged into `options.engine` when both are set, this prop wins.
|
|
89
|
+
*/
|
|
90
|
+
engine?: 'v3' | 'v4';
|
|
86
91
|
options?: PoseTrackerClientOptions;
|
|
87
92
|
/** Start preloading as soon as the provider mounts. Default: false. */
|
|
88
93
|
autoPreload?: boolean;
|
|
89
94
|
children: React.ReactNode;
|
|
90
95
|
}
|
|
91
|
-
export declare function PoseTrackerProvider({ apiToken, options, autoPreload, children, }: PoseTrackerProviderProps): React.JSX.Element;
|
|
96
|
+
export declare function PoseTrackerProvider({ apiToken, engine, options, autoPreload, children, }: PoseTrackerProviderProps): React.JSX.Element;
|
|
92
97
|
/**
|
|
93
98
|
* Access the PoseTracker pipeline and subscribe to typed events.
|
|
94
99
|
*
|
|
@@ -22,10 +22,13 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
22
22
|
const react_1 = require("react");
|
|
23
23
|
const client_1 = require("./client");
|
|
24
24
|
const PoseTrackerContext = (0, react_1.createContext)(null);
|
|
25
|
-
function PoseTrackerProvider({ apiToken, options, autoPreload = false, children, }) {
|
|
25
|
+
function PoseTrackerProvider({ apiToken, engine, options, autoPreload = false, children, }) {
|
|
26
26
|
const clientRef = (0, react_1.useRef)(null);
|
|
27
27
|
if (!clientRef.current) {
|
|
28
|
-
clientRef.current = new client_1.PoseTrackerClient(apiToken,
|
|
28
|
+
clientRef.current = new client_1.PoseTrackerClient(apiToken, {
|
|
29
|
+
...options,
|
|
30
|
+
engine: engine ?? options?.engine,
|
|
31
|
+
});
|
|
29
32
|
}
|
|
30
33
|
const client = clientRef.current;
|
|
31
34
|
const [status, setStatus] = (0, react_1.useState)(client.getStatus());
|
package/lib/api/configure.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
*/
|
|
12
12
|
import { SDK_VERSION } from '../sdkVersion';
|
|
13
13
|
import type { ConfigureRequest, PoseModelProfile, SdkManifest } from '../types/manifest';
|
|
14
|
+
import type { EngineChannel } from '../engineChannel';
|
|
14
15
|
export declare const SDK_NAME: "posetracker-rn-light";
|
|
15
16
|
export { SDK_VERSION };
|
|
16
17
|
/** Overridable for staging/self-hosted backends. */
|
|
@@ -21,6 +22,11 @@ export interface ConfigureOptions {
|
|
|
21
22
|
locale?: string;
|
|
22
23
|
/** Local cache versions, so the backend can answer `upToDate` per module. */
|
|
23
24
|
localVersions?: ConfigureRequest['localVersions'];
|
|
25
|
+
/**
|
|
26
|
+
* Opt-in V4 heuristic engine. Default `'v3'` (production FSM).
|
|
27
|
+
* Set `'v4'` at init — the handshake downloads `engine-v4.bundle.js`.
|
|
28
|
+
*/
|
|
29
|
+
engine?: EngineChannel;
|
|
24
30
|
}
|
|
25
31
|
export declare class ConfigureError extends Error {
|
|
26
32
|
readonly code: 'invalid_token' | 'quota_exceeded' | 'network' | 'internal';
|
package/lib/api/configure.js
CHANGED
|
@@ -37,6 +37,7 @@ async function configure(apiToken, options = {}) {
|
|
|
37
37
|
poseModelProfile: options.poseModelProfile ?? 'AdaptiveChoice',
|
|
38
38
|
locale: options.locale,
|
|
39
39
|
localVersions: options.localVersions,
|
|
40
|
+
engineChannel: options.engine === 'v4' ? 'v4' : 'v3',
|
|
40
41
|
};
|
|
41
42
|
let response;
|
|
42
43
|
try {
|
package/lib/client.d.ts
CHANGED
|
@@ -28,6 +28,7 @@ import { EngineLoader, type EngineLoadResult, type FileStore } from './engine/En
|
|
|
28
28
|
import { type OnlineRuntimeParts } from './backends/webview/onlineRuntime';
|
|
29
29
|
import type { CustomExerciseDescriptor } from './engine/types';
|
|
30
30
|
import type { PoseBackend, PoseInputFrame } from './backends/PoseBackend';
|
|
31
|
+
import { type EngineChannel } from './engineChannel';
|
|
31
32
|
import type { ExerciseConfig, SdkManifest } from './types/manifest';
|
|
32
33
|
import type { ColdStartMode, PreloadOptions } from './types/preload';
|
|
33
34
|
import type { SkeletonDefinition } from './types/skeleton';
|
|
@@ -103,9 +104,8 @@ export interface PoseTrackerClientOptions extends ConfigureOptions {
|
|
|
103
104
|
*/
|
|
104
105
|
onDiagnostic?: (message: string) => void;
|
|
105
106
|
/**
|
|
106
|
-
*
|
|
107
|
-
*
|
|
108
|
-
* `startExercise(id, { debug: true|false })`.
|
|
107
|
+
* @internal PoseTracker QA only — not a supported public API.
|
|
108
|
+
* See `.private/ENGINE_DEBUG_QA.md` (do not document in Mintlify).
|
|
109
109
|
*/
|
|
110
110
|
debugEngine?: boolean;
|
|
111
111
|
}
|
|
@@ -125,8 +125,8 @@ export interface StartExerciseOptions {
|
|
|
125
125
|
/** Device pitch in degrees — jump exercises compensate camera tilt. */
|
|
126
126
|
devicePitchDeg?: number;
|
|
127
127
|
/**
|
|
128
|
-
*
|
|
129
|
-
*
|
|
128
|
+
* @internal PoseTracker QA only — not a supported public API.
|
|
129
|
+
* Defaults to {@link PoseTrackerClientOptions.debugEngine}.
|
|
130
130
|
*/
|
|
131
131
|
debug?: boolean;
|
|
132
132
|
}
|
|
@@ -327,6 +327,8 @@ export declare class PoseTrackerClient {
|
|
|
327
327
|
private validateRequestedFeatures;
|
|
328
328
|
private resolveModel;
|
|
329
329
|
getAvailableExercises(): ExerciseConfig[];
|
|
330
|
+
getEngineChannel(): EngineChannel;
|
|
331
|
+
private v4ExerciseConfig;
|
|
330
332
|
/**
|
|
331
333
|
* Custom exercises shipped inside the engine bundle (jump_analysis,
|
|
332
334
|
* air_time_jump — WebView `customHandlers.js` parity). Empty in
|
|
@@ -334,6 +336,7 @@ export declare class PoseTrackerClient {
|
|
|
334
336
|
*/
|
|
335
337
|
getAvailableCustomExercises(): CustomExerciseDescriptor[];
|
|
336
338
|
startExercise(exerciseId: string, options?: StartExerciseOptions): void;
|
|
339
|
+
private beginEngineSession;
|
|
337
340
|
/** Custom engine session (jump_analysis / air_time_jump). */
|
|
338
341
|
private startCustomExercise;
|
|
339
342
|
/**
|
package/lib/client.js
CHANGED
|
@@ -34,6 +34,7 @@ const obfuscate_1 = require("./cache/obfuscate");
|
|
|
34
34
|
const VisionPoseBackend_1 = require("./backends/vision/VisionPoseBackend");
|
|
35
35
|
const WebViewPoseBackend_1 = require("./backends/webview/WebViewPoseBackend");
|
|
36
36
|
const aliases_1 = require("./exercises/aliases");
|
|
37
|
+
const engineChannel_1 = require("./engineChannel");
|
|
37
38
|
const skeleton_1 = require("./api/skeleton");
|
|
38
39
|
const logReport_1 = require("./diagnostics/logReport");
|
|
39
40
|
const AdaptiveQualityController_1 = require("./quality/AdaptiveQualityController");
|
|
@@ -755,7 +756,32 @@ class PoseTrackerClient {
|
|
|
755
756
|
// Exercise sessions (full-engine mode only)
|
|
756
757
|
// -------------------------------------------------------------------------
|
|
757
758
|
getAvailableExercises() {
|
|
758
|
-
|
|
759
|
+
if (this.mode !== 'full-engine')
|
|
760
|
+
return [];
|
|
761
|
+
if ((0, engineChannel_1.normalizeEngineChannel)(this.options.engine) === 'v4') {
|
|
762
|
+
const listed = this.engine?.listExercises?.() ?? [];
|
|
763
|
+
if (listed.length)
|
|
764
|
+
return listed.map((e) => this.v4ExerciseConfig(e));
|
|
765
|
+
}
|
|
766
|
+
return this.manifest?.exercises ?? [];
|
|
767
|
+
}
|
|
768
|
+
getEngineChannel() {
|
|
769
|
+
return (0, engineChannel_1.normalizeEngineChannel)(this.options.engine);
|
|
770
|
+
}
|
|
771
|
+
v4ExerciseConfig(entry) {
|
|
772
|
+
const type = entry.type === 'static' ? 'static' : 'dynamic';
|
|
773
|
+
return {
|
|
774
|
+
id: entry.id,
|
|
775
|
+
name: entry.displayName || entry.id,
|
|
776
|
+
type,
|
|
777
|
+
movement: {
|
|
778
|
+
name: entry.id,
|
|
779
|
+
type,
|
|
780
|
+
scale_acceptance: {},
|
|
781
|
+
movement_steps: [],
|
|
782
|
+
movement_initial_posture: null,
|
|
783
|
+
},
|
|
784
|
+
};
|
|
759
785
|
}
|
|
760
786
|
/**
|
|
761
787
|
* Custom exercises shipped inside the engine bundle (jump_analysis,
|
|
@@ -798,6 +824,29 @@ class PoseTrackerClient {
|
|
|
798
824
|
throw new Error(features_1.FREE_PLAN_FEATURES_MESSAGE);
|
|
799
825
|
}
|
|
800
826
|
}
|
|
827
|
+
if ((0, engineChannel_1.requiresEngineV4)(exerciseId) && (0, engineChannel_1.normalizeEngineChannel)(this.options.engine) !== 'v4') {
|
|
828
|
+
const message = `Exercise '${exerciseId}' requires engine: 'v4'`;
|
|
829
|
+
this.reportError({ type: 'error', code: 'invalid_exercise', message });
|
|
830
|
+
throw new Error(message);
|
|
831
|
+
}
|
|
832
|
+
if ((0, engineChannel_1.normalizeEngineChannel)(this.options.engine) === 'v4') {
|
|
833
|
+
const listed = this.engine.listExercises?.() ?? [];
|
|
834
|
+
const v4Hit = listed.find((e) => e.id === exerciseId);
|
|
835
|
+
if (v4Hit) {
|
|
836
|
+
this.beginEngineSession(this.v4ExerciseConfig(v4Hit), options);
|
|
837
|
+
return;
|
|
838
|
+
}
|
|
839
|
+
const customs = this.getAvailableCustomExercises();
|
|
840
|
+
const custom = customs.find((e) => e.id === exerciseId) ??
|
|
841
|
+
(0, aliases_1.findExerciseByIdOrAlias)(exerciseId, customs);
|
|
842
|
+
if (custom) {
|
|
843
|
+
this.startCustomExercise(custom, options);
|
|
844
|
+
return;
|
|
845
|
+
}
|
|
846
|
+
const message = `Exercise '${exerciseId}' is not available in V4 engine`;
|
|
847
|
+
this.reportError({ type: 'error', code: 'invalid_exercise', message });
|
|
848
|
+
throw new Error(message);
|
|
849
|
+
}
|
|
801
850
|
const available = this.getAvailableExercises();
|
|
802
851
|
const exercise = (0, aliases_1.findExerciseByIdOrAlias)(exerciseId, available);
|
|
803
852
|
if (!exercise) {
|
|
@@ -815,8 +864,13 @@ class PoseTrackerClient {
|
|
|
815
864
|
this.reportError({ type: 'error', code: 'invalid_exercise', message });
|
|
816
865
|
throw new Error(message);
|
|
817
866
|
}
|
|
867
|
+
this.beginEngineSession(exercise, options);
|
|
868
|
+
}
|
|
869
|
+
beginEngineSession(exercise, options) {
|
|
870
|
+
if (!this.engine)
|
|
871
|
+
return;
|
|
818
872
|
this.stopExercise();
|
|
819
|
-
this.currentExerciseId =
|
|
873
|
+
this.currentExerciseId = exercise.id;
|
|
820
874
|
this.keypointsSuppressionLogged = false;
|
|
821
875
|
const debug = options.debug ?? this.options.debugEngine === true;
|
|
822
876
|
this.session = this.engine.createSession({
|
package/lib/engine/types.d.ts
CHANGED
|
@@ -37,8 +37,8 @@ export interface EngineSessionOptions {
|
|
|
37
37
|
/** Emission flags — engines older than 1.1.0 ignore them (client re-filters). */
|
|
38
38
|
features?: EngineSessionFeatures;
|
|
39
39
|
/**
|
|
40
|
-
*
|
|
41
|
-
*
|
|
40
|
+
* @internal PoseTracker QA only — not a supported public API.
|
|
41
|
+
* Ignored by older engines.
|
|
42
42
|
*/
|
|
43
43
|
debug?: boolean;
|
|
44
44
|
}
|
|
@@ -78,6 +78,13 @@ export interface PoseTrackerEngine {
|
|
|
78
78
|
createSession(options: EngineSessionOptions, emit: EventSink): EngineSession;
|
|
79
79
|
/** Engine >= 1.2.0: custom exercises shipped in the bundle (jump analysis…). */
|
|
80
80
|
listCustomExercises?(): CustomExerciseDescriptor[];
|
|
81
|
+
/** Engine V4 catalog (opt-in channel). Absent on V3 bundles. */
|
|
82
|
+
listExercises?(): Array<{
|
|
83
|
+
id: string;
|
|
84
|
+
displayName: string;
|
|
85
|
+
type: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
}>;
|
|
81
88
|
/** Engine >= 1.2.0: start a custom exercise session (placement + jump_* events). */
|
|
82
89
|
createCustomSession?(options: CustomSessionOptions, emit: EventSink): EngineSession;
|
|
83
90
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Opt-in remote engine channel. Default is production V3. */
|
|
2
|
+
export type EngineChannel = 'v3' | 'v4';
|
|
3
|
+
/** Movements that exist only in the V4 catalog (not in V3 FSM / Strapi). */
|
|
4
|
+
export declare const V4_ONLY_EXERCISE_IDS: readonly ["shoulder_roll", "shoulder_deep_breath", "chair_forward_fold"];
|
|
5
|
+
export declare function normalizeEngineChannel(raw?: string | null): EngineChannel;
|
|
6
|
+
export declare function requiresEngineV4(exerciseId: string): boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.V4_ONLY_EXERCISE_IDS = void 0;
|
|
4
|
+
exports.normalizeEngineChannel = normalizeEngineChannel;
|
|
5
|
+
exports.requiresEngineV4 = requiresEngineV4;
|
|
6
|
+
/** Movements that exist only in the V4 catalog (not in V3 FSM / Strapi). */
|
|
7
|
+
exports.V4_ONLY_EXERCISE_IDS = [
|
|
8
|
+
'shoulder_roll',
|
|
9
|
+
'shoulder_deep_breath',
|
|
10
|
+
'chair_forward_fold',
|
|
11
|
+
];
|
|
12
|
+
function normalizeEngineChannel(raw) {
|
|
13
|
+
return raw === 'v4' ? 'v4' : 'v3';
|
|
14
|
+
}
|
|
15
|
+
function requiresEngineV4(exerciseId) {
|
|
16
|
+
return exports.V4_ONLY_EXERCISE_IDS.includes(exerciseId);
|
|
17
|
+
}
|
package/lib/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ export { DEFAULT_MOVENET_LIGHTNING_URL, originFromModelUrl, resolvePoseModel, }
|
|
|
25
25
|
export type { PoseModelAlias, PoseModelKind, ResolvePoseModelOptions, ResolvedPoseModel, } from './models/poseModels';
|
|
26
26
|
export { PoseTrackerClient } from './client';
|
|
27
27
|
export type { PoseTrackerClientOptions, PreferredBackend, StartExerciseOptions } from './client';
|
|
28
|
+
export type { EngineChannel } from './engineChannel';
|
|
29
|
+
export { V4_ONLY_EXERCISE_IDS, normalizeEngineChannel, requiresEngineV4 } from './engineChannel';
|
|
28
30
|
export type { ColdStartMode, PreloadOptions } from './types/preload';
|
|
29
31
|
export type { SkeletonAnglesStyle, SkeletonCirclesStyle, SkeletonDefinition, SkeletonLinesStyle, } from './types/skeleton';
|
|
30
32
|
export { DEFAULT_SKELETON_DEFINITION } from './types/skeleton';
|
package/lib/index.js
CHANGED
|
@@ -28,8 +28,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
28
28
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
29
29
|
};
|
|
30
30
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
31
|
-
exports.
|
|
32
|
-
exports.resolveFeatures = exports.shouldShowWatermark = exports.isPaidPlan = exports.freeBlockedFeatures = exports.featureNotSupportedMessage = exports.COMBINED_REFERENCE_EXERCISE_MESSAGE = exports.INVALID_TOKEN_MESSAGE = exports.FREE_PLAN_FEATURES_MESSAGE = exports.DEFAULT_FEATURES = exports.RuntimeGuard = exports.scoreDeviceCapability = exports.profileFromScore = exports.isMaliRenderer = exports.ENABLE_MALI_HARD_CAP = exports.CAPTURE_CONSTRAINT_MODE = exports.ANDROID_SOFT_CAP_PROFILE = exports.ANDROID_PREPROCESS_PATH = exports.ANDROID_PERF_DEBUG = exports.ANDROID_MIN_TARGET_FPS = exports.ANDROID_INFER_FRAME_SKIP = exports.profileFromWarmupMedianMs = exports.nextLowerQualityProfile = exports.minMedianMsForMinTarget = exports.lowerQualityProfile = exports.isQualityProfileId = exports.getQualityProfile = exports.getMinTargetFps = exports.getIdealFpsRange = exports.getCriticalFpsThreshold = exports.estimatedFpsFromMedianMs = exports.currentQualityPlatform = exports.TARGET_MEDIAN_MS = exports.TARGET_FPS = exports.QUALITY_PROFILES = exports.QUALITY_LADDER = exports.MIN_TARGET_FPS_IOS = exports.MIN_TARGET_FPS_DEFAULT = exports.MIN_TARGET_FPS_ANDROID = exports.QUALITY_SETTLE_MS = exports.LOW_FPS_STREAK_BEFORE_DOWNGRADE = exports.IDEAL_FPS_RANGE_IOS = exports.IDEAL_FPS_RANGE_ANDROID = exports.CRITICAL_FPS_THRESHOLD = exports.AdaptiveQualityController = exports.toClassicNativeMessage = exports.logPlatformBanner = exports.logFrameStats = void 0;
|
|
31
|
+
exports.createMemoryFileStore = exports.createBlobUtilFileStore = exports.createRnfsFileStore = exports.createExpoFileStore = exports.EngineLoader = exports.isExpoGo = exports.PoseCameraView = exports.VISION_JOINT_TO_SDK = exports.poseFromVisionPluginResult = exports.VISION_BODY_POSE_PLUGIN_NAME = exports.isVisionPoseCameraAvailable = exports.isVisionBackendAvailable = exports.VisionUnavailableError = exports.VisionPoseBackend = exports.POSETRACKER_LOGO_DATA_URL = exports.POSE_HTML_BUILD = exports.DEFAULT_LOADING_TEXT = exports.buildPoseHtml = exports.WebViewPoseView = exports.isWebViewPoseBackend = exports.WebViewPoseBackend = exports.usePoseTracker = exports.PoseTrackerProvider = exports.SkeletonFetchError = exports.fetchSkeletonDefinition = exports.DEFAULT_SKELETON_DEFINITION = exports.requiresEngineV4 = exports.normalizeEngineChannel = exports.V4_ONLY_EXERCISE_IDS = exports.PoseTrackerClient = exports.resolvePoseModel = exports.originFromModelUrl = exports.DEFAULT_MOVENET_LIGHTNING_URL = exports.ONLINE_POSE_DETECTION_VERSION = exports.ONLINE_TFJS_VERSION = exports.defaultPoseDetectionCdnUrl = exports.defaultOnlineRuntimeUrls = exports.getOnlineRuntimeVersion = exports.getOnlineRuntimeParts = exports.RuntimeCache = exports.TrackError = exports.UsageTracker = exports.resolveExerciseName = exports.findExerciseByIdOrAlias = exports.EXERCISE_ALIASES = exports.SDK_VERSION = exports.SDK_NAME = exports.DEFAULT_BASE_URL = exports.ConfigureError = exports.configure = void 0;
|
|
32
|
+
exports.resolveFeatures = exports.shouldShowWatermark = exports.isPaidPlan = exports.freeBlockedFeatures = exports.featureNotSupportedMessage = exports.COMBINED_REFERENCE_EXERCISE_MESSAGE = exports.INVALID_TOKEN_MESSAGE = exports.FREE_PLAN_FEATURES_MESSAGE = exports.DEFAULT_FEATURES = exports.RuntimeGuard = exports.scoreDeviceCapability = exports.profileFromScore = exports.isMaliRenderer = exports.ENABLE_MALI_HARD_CAP = exports.CAPTURE_CONSTRAINT_MODE = exports.ANDROID_SOFT_CAP_PROFILE = exports.ANDROID_PREPROCESS_PATH = exports.ANDROID_PERF_DEBUG = exports.ANDROID_MIN_TARGET_FPS = exports.ANDROID_INFER_FRAME_SKIP = exports.profileFromWarmupMedianMs = exports.nextLowerQualityProfile = exports.minMedianMsForMinTarget = exports.lowerQualityProfile = exports.isQualityProfileId = exports.getQualityProfile = exports.getMinTargetFps = exports.getIdealFpsRange = exports.getCriticalFpsThreshold = exports.estimatedFpsFromMedianMs = exports.currentQualityPlatform = exports.TARGET_MEDIAN_MS = exports.TARGET_FPS = exports.QUALITY_PROFILES = exports.QUALITY_LADDER = exports.MIN_TARGET_FPS_IOS = exports.MIN_TARGET_FPS_DEFAULT = exports.MIN_TARGET_FPS_ANDROID = exports.QUALITY_SETTLE_MS = exports.LOW_FPS_STREAK_BEFORE_DOWNGRADE = exports.IDEAL_FPS_RANGE_IOS = exports.IDEAL_FPS_RANGE_ANDROID = exports.CRITICAL_FPS_THRESHOLD = exports.AdaptiveQualityController = exports.toClassicNativeMessage = exports.logPlatformBanner = exports.logFrameStats = exports.logAccelerationReport = exports.defaultDiagnosticLogger = exports.createNativeFileStore = void 0;
|
|
33
33
|
// Handshake + usage tracking
|
|
34
34
|
var configure_1 = require("./api/configure");
|
|
35
35
|
Object.defineProperty(exports, "configure", { enumerable: true, get: function () { return configure_1.configure; } });
|
|
@@ -61,6 +61,10 @@ Object.defineProperty(exports, "resolvePoseModel", { enumerable: true, get: func
|
|
|
61
61
|
// Orchestrator + React layer
|
|
62
62
|
var client_1 = require("./client");
|
|
63
63
|
Object.defineProperty(exports, "PoseTrackerClient", { enumerable: true, get: function () { return client_1.PoseTrackerClient; } });
|
|
64
|
+
var engineChannel_1 = require("./engineChannel");
|
|
65
|
+
Object.defineProperty(exports, "V4_ONLY_EXERCISE_IDS", { enumerable: true, get: function () { return engineChannel_1.V4_ONLY_EXERCISE_IDS; } });
|
|
66
|
+
Object.defineProperty(exports, "normalizeEngineChannel", { enumerable: true, get: function () { return engineChannel_1.normalizeEngineChannel; } });
|
|
67
|
+
Object.defineProperty(exports, "requiresEngineV4", { enumerable: true, get: function () { return engineChannel_1.requiresEngineV4; } });
|
|
64
68
|
var skeleton_1 = require("./types/skeleton");
|
|
65
69
|
Object.defineProperty(exports, "DEFAULT_SKELETON_DEFINITION", { enumerable: true, get: function () { return skeleton_1.DEFAULT_SKELETON_DEFINITION; } });
|
|
66
70
|
var skeleton_2 = require("./api/skeleton");
|
package/lib/sdkVersion.d.ts
CHANGED
|
@@ -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
|
+
export declare const SDK_VERSION = "0.3.0";
|
package/lib/sdkVersion.js
CHANGED
package/lib/types/events.d.ts
CHANGED
|
@@ -155,8 +155,8 @@ export interface ProgressionEvent {
|
|
|
155
155
|
timestampMs: number;
|
|
156
156
|
}
|
|
157
157
|
/**
|
|
158
|
-
*
|
|
159
|
-
*
|
|
158
|
+
* @internal PoseTracker QA only — not a supported public API (do not document in Mintlify).
|
|
159
|
+
* Throttled movement / rep-FSM snapshot. See `.private/ENGINE_DEBUG_QA.md`.
|
|
160
160
|
*/
|
|
161
161
|
export interface EngineDebugEvent {
|
|
162
162
|
type: 'engine_debug';
|
package/lib/types/manifest.d.ts
CHANGED
|
@@ -126,6 +126,8 @@ export interface EngineBundleDescriptor {
|
|
|
126
126
|
minSdkVersion: string;
|
|
127
127
|
/** True when the version sent in `localVersions.engine` is already current. */
|
|
128
128
|
upToDate?: boolean;
|
|
129
|
+
/** Which interpreter this descriptor is. Absent on older backends = v3. */
|
|
130
|
+
channel?: 'v3' | 'v4';
|
|
129
131
|
}
|
|
130
132
|
export interface PoseRuntimePartDescriptor {
|
|
131
133
|
/** Download URL of this part (`GET /api/sdk/pose-runtime?part=...&v=...`). */
|
|
@@ -166,6 +168,11 @@ export interface ConfigureRequest {
|
|
|
166
168
|
poseRuntime?: string | null;
|
|
167
169
|
engine?: string | null;
|
|
168
170
|
};
|
|
171
|
+
/**
|
|
172
|
+
* Which remote engine to download. Default / omitted = v3 (production).
|
|
173
|
+
* `v4` is opt-in (heuristic catalog: squat, shoulder_roll, …).
|
|
174
|
+
*/
|
|
175
|
+
engineChannel?: 'v3' | 'v4';
|
|
169
176
|
}
|
|
170
177
|
export interface PlanInfo {
|
|
171
178
|
plan: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pose-tracker/react-native-pose-estimation-light",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
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",
|
|
@@ -106,6 +106,11 @@ const PoseTrackerContext = createContext<PoseTrackerContextValue | null>(null);
|
|
|
106
106
|
export interface PoseTrackerProviderProps {
|
|
107
107
|
/** Optional: without a token the SDK runs in keypoints-only mode. */
|
|
108
108
|
apiToken?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Opt-in V4 engine (`'v4'`). Default `'v3'` — production FSM, unchanged.
|
|
111
|
+
* Merged into `options.engine` when both are set, this prop wins.
|
|
112
|
+
*/
|
|
113
|
+
engine?: 'v3' | 'v4';
|
|
109
114
|
options?: PoseTrackerClientOptions;
|
|
110
115
|
/** Start preloading as soon as the provider mounts. Default: false. */
|
|
111
116
|
autoPreload?: boolean;
|
|
@@ -114,13 +119,17 @@ export interface PoseTrackerProviderProps {
|
|
|
114
119
|
|
|
115
120
|
export function PoseTrackerProvider({
|
|
116
121
|
apiToken,
|
|
122
|
+
engine,
|
|
117
123
|
options,
|
|
118
124
|
autoPreload = false,
|
|
119
125
|
children,
|
|
120
126
|
}: PoseTrackerProviderProps): React.JSX.Element {
|
|
121
127
|
const clientRef = useRef<PoseTrackerClient | null>(null);
|
|
122
128
|
if (!clientRef.current) {
|
|
123
|
-
clientRef.current = new PoseTrackerClient(apiToken,
|
|
129
|
+
clientRef.current = new PoseTrackerClient(apiToken, {
|
|
130
|
+
...options,
|
|
131
|
+
engine: engine ?? options?.engine,
|
|
132
|
+
});
|
|
124
133
|
}
|
|
125
134
|
const client = clientRef.current;
|
|
126
135
|
|
package/src/api/configure.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { Platform } from 'react-native';
|
|
|
14
14
|
|
|
15
15
|
import { SDK_VERSION } from '../sdkVersion';
|
|
16
16
|
import type { ConfigureRequest, PoseModelProfile, SdkManifest } from '../types/manifest';
|
|
17
|
+
import type { EngineChannel } from '../engineChannel';
|
|
17
18
|
|
|
18
19
|
export const SDK_NAME = 'posetracker-rn-light' as const;
|
|
19
20
|
export { SDK_VERSION };
|
|
@@ -28,6 +29,11 @@ export interface ConfigureOptions {
|
|
|
28
29
|
locale?: string;
|
|
29
30
|
/** Local cache versions, so the backend can answer `upToDate` per module. */
|
|
30
31
|
localVersions?: ConfigureRequest['localVersions'];
|
|
32
|
+
/**
|
|
33
|
+
* Opt-in V4 heuristic engine. Default `'v3'` (production FSM).
|
|
34
|
+
* Set `'v4'` at init — the handshake downloads `engine-v4.bundle.js`.
|
|
35
|
+
*/
|
|
36
|
+
engine?: EngineChannel;
|
|
31
37
|
}
|
|
32
38
|
|
|
33
39
|
export class ConfigureError extends Error {
|
|
@@ -53,6 +59,7 @@ export async function configure(
|
|
|
53
59
|
poseModelProfile: options.poseModelProfile ?? 'AdaptiveChoice',
|
|
54
60
|
locale: options.locale,
|
|
55
61
|
localVersions: options.localVersions,
|
|
62
|
+
engineChannel: options.engine === 'v4' ? 'v4' : 'v3',
|
|
56
63
|
};
|
|
57
64
|
|
|
58
65
|
let response: Response;
|
package/src/client.ts
CHANGED
|
@@ -38,6 +38,7 @@ import type { PoseBackend, PoseInputFrame } from './backends/PoseBackend';
|
|
|
38
38
|
import { VisionPoseBackend } from './backends/vision/VisionPoseBackend';
|
|
39
39
|
import { WebViewPoseBackend } from './backends/webview/WebViewPoseBackend';
|
|
40
40
|
import { findExerciseByIdOrAlias } from './exercises/aliases';
|
|
41
|
+
import { normalizeEngineChannel, requiresEngineV4, type EngineChannel } from './engineChannel';
|
|
41
42
|
import { fetchSkeletonDefinition } from './api/skeleton';
|
|
42
43
|
import type { ExerciseConfig, ModelDescriptor, SdkManifest } from './types/manifest';
|
|
43
44
|
import type { ColdStartMode, PreloadOptions } from './types/preload';
|
|
@@ -164,9 +165,8 @@ export interface PoseTrackerClientOptions extends ConfigureOptions {
|
|
|
164
165
|
*/
|
|
165
166
|
onDiagnostic?: (message: string) => void;
|
|
166
167
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* `startExercise(id, { debug: true|false })`.
|
|
168
|
+
* @internal PoseTracker QA only — not a supported public API.
|
|
169
|
+
* See `.private/ENGINE_DEBUG_QA.md` (do not document in Mintlify).
|
|
170
170
|
*/
|
|
171
171
|
debugEngine?: boolean;
|
|
172
172
|
}
|
|
@@ -187,8 +187,8 @@ export interface StartExerciseOptions {
|
|
|
187
187
|
/** Device pitch in degrees — jump exercises compensate camera tilt. */
|
|
188
188
|
devicePitchDeg?: number;
|
|
189
189
|
/**
|
|
190
|
-
*
|
|
191
|
-
*
|
|
190
|
+
* @internal PoseTracker QA only — not a supported public API.
|
|
191
|
+
* Defaults to {@link PoseTrackerClientOptions.debugEngine}.
|
|
192
192
|
*/
|
|
193
193
|
debug?: boolean;
|
|
194
194
|
}
|
|
@@ -980,7 +980,32 @@ export class PoseTrackerClient {
|
|
|
980
980
|
// -------------------------------------------------------------------------
|
|
981
981
|
|
|
982
982
|
getAvailableExercises(): ExerciseConfig[] {
|
|
983
|
-
|
|
983
|
+
if (this.mode !== 'full-engine') return [];
|
|
984
|
+
if (normalizeEngineChannel(this.options.engine) === 'v4') {
|
|
985
|
+
const listed = this.engine?.listExercises?.() ?? [];
|
|
986
|
+
if (listed.length) return listed.map((e) => this.v4ExerciseConfig(e));
|
|
987
|
+
}
|
|
988
|
+
return this.manifest?.exercises ?? [];
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
getEngineChannel(): EngineChannel {
|
|
992
|
+
return normalizeEngineChannel(this.options.engine);
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
private v4ExerciseConfig(entry: { id: string; displayName?: string; type?: string }): ExerciseConfig {
|
|
996
|
+
const type = entry.type === 'static' ? 'static' : 'dynamic';
|
|
997
|
+
return {
|
|
998
|
+
id: entry.id,
|
|
999
|
+
name: entry.displayName || entry.id,
|
|
1000
|
+
type,
|
|
1001
|
+
movement: {
|
|
1002
|
+
name: entry.id,
|
|
1003
|
+
type,
|
|
1004
|
+
scale_acceptance: {},
|
|
1005
|
+
movement_steps: [],
|
|
1006
|
+
movement_initial_posture: null,
|
|
1007
|
+
},
|
|
1008
|
+
};
|
|
984
1009
|
}
|
|
985
1010
|
|
|
986
1011
|
/**
|
|
@@ -1029,6 +1054,30 @@ export class PoseTrackerClient {
|
|
|
1029
1054
|
throw new Error(FREE_PLAN_FEATURES_MESSAGE);
|
|
1030
1055
|
}
|
|
1031
1056
|
}
|
|
1057
|
+
if (requiresEngineV4(exerciseId) && normalizeEngineChannel(this.options.engine) !== 'v4') {
|
|
1058
|
+
const message = `Exercise '${exerciseId}' requires engine: 'v4'`;
|
|
1059
|
+
this.reportError({ type: 'error', code: 'invalid_exercise', message });
|
|
1060
|
+
throw new Error(message);
|
|
1061
|
+
}
|
|
1062
|
+
if (normalizeEngineChannel(this.options.engine) === 'v4') {
|
|
1063
|
+
const listed = this.engine.listExercises?.() ?? [];
|
|
1064
|
+
const v4Hit = listed.find((e) => e.id === exerciseId);
|
|
1065
|
+
if (v4Hit) {
|
|
1066
|
+
this.beginEngineSession(this.v4ExerciseConfig(v4Hit), options);
|
|
1067
|
+
return;
|
|
1068
|
+
}
|
|
1069
|
+
const customs = this.getAvailableCustomExercises();
|
|
1070
|
+
const custom =
|
|
1071
|
+
customs.find((e) => e.id === exerciseId) ??
|
|
1072
|
+
findExerciseByIdOrAlias(exerciseId, customs);
|
|
1073
|
+
if (custom) {
|
|
1074
|
+
this.startCustomExercise(custom, options);
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
const message = `Exercise '${exerciseId}' is not available in V4 engine`;
|
|
1078
|
+
this.reportError({ type: 'error', code: 'invalid_exercise', message });
|
|
1079
|
+
throw new Error(message);
|
|
1080
|
+
}
|
|
1032
1081
|
const available = this.getAvailableExercises();
|
|
1033
1082
|
const exercise = findExerciseByIdOrAlias(exerciseId, available);
|
|
1034
1083
|
if (!exercise) {
|
|
@@ -1047,8 +1096,13 @@ export class PoseTrackerClient {
|
|
|
1047
1096
|
this.reportError({ type: 'error', code: 'invalid_exercise', message });
|
|
1048
1097
|
throw new Error(message);
|
|
1049
1098
|
}
|
|
1099
|
+
this.beginEngineSession(exercise, options);
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
private beginEngineSession(exercise: ExerciseConfig, options: StartExerciseOptions): void {
|
|
1103
|
+
if (!this.engine) return;
|
|
1050
1104
|
this.stopExercise();
|
|
1051
|
-
this.currentExerciseId =
|
|
1105
|
+
this.currentExerciseId = exercise.id;
|
|
1052
1106
|
this.keypointsSuppressionLogged = false;
|
|
1053
1107
|
const debug = options.debug ?? this.options.debugEngine === true;
|
|
1054
1108
|
this.session = this.engine.createSession(
|
package/src/engine/types.ts
CHANGED
|
@@ -40,8 +40,8 @@ export interface EngineSessionOptions {
|
|
|
40
40
|
/** Emission flags — engines older than 1.1.0 ignore them (client re-filters). */
|
|
41
41
|
features?: EngineSessionFeatures;
|
|
42
42
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
43
|
+
* @internal PoseTracker QA only — not a supported public API.
|
|
44
|
+
* Ignored by older engines.
|
|
45
45
|
*/
|
|
46
46
|
debug?: boolean;
|
|
47
47
|
}
|
|
@@ -86,6 +86,13 @@ export interface PoseTrackerEngine {
|
|
|
86
86
|
createSession(options: EngineSessionOptions, emit: EventSink): EngineSession;
|
|
87
87
|
/** Engine >= 1.2.0: custom exercises shipped in the bundle (jump analysis…). */
|
|
88
88
|
listCustomExercises?(): CustomExerciseDescriptor[];
|
|
89
|
+
/** Engine V4 catalog (opt-in channel). Absent on V3 bundles. */
|
|
90
|
+
listExercises?(): Array<{
|
|
91
|
+
id: string;
|
|
92
|
+
displayName: string;
|
|
93
|
+
type: string;
|
|
94
|
+
description?: string;
|
|
95
|
+
}>;
|
|
89
96
|
/** Engine >= 1.2.0: start a custom exercise session (placement + jump_* events). */
|
|
90
97
|
createCustomSession?(options: CustomSessionOptions, emit: EventSink): EngineSession;
|
|
91
98
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Opt-in remote engine channel. Default is production V3. */
|
|
2
|
+
export type EngineChannel = 'v3' | 'v4';
|
|
3
|
+
|
|
4
|
+
/** Movements that exist only in the V4 catalog (not in V3 FSM / Strapi). */
|
|
5
|
+
export const V4_ONLY_EXERCISE_IDS = [
|
|
6
|
+
'shoulder_roll',
|
|
7
|
+
'shoulder_deep_breath',
|
|
8
|
+
'chair_forward_fold',
|
|
9
|
+
] as const;
|
|
10
|
+
|
|
11
|
+
export function normalizeEngineChannel(raw?: string | null): EngineChannel {
|
|
12
|
+
return raw === 'v4' ? 'v4' : 'v3';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function requiresEngineV4(exerciseId: string): boolean {
|
|
16
|
+
return (V4_ONLY_EXERCISE_IDS as readonly string[]).includes(exerciseId);
|
|
17
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -59,6 +59,8 @@ export type {
|
|
|
59
59
|
// Orchestrator + React layer
|
|
60
60
|
export { PoseTrackerClient } from './client';
|
|
61
61
|
export type { PoseTrackerClientOptions, PreferredBackend, StartExerciseOptions } from './client';
|
|
62
|
+
export type { EngineChannel } from './engineChannel';
|
|
63
|
+
export { V4_ONLY_EXERCISE_IDS, normalizeEngineChannel, requiresEngineV4 } from './engineChannel';
|
|
62
64
|
export type { ColdStartMode, PreloadOptions } from './types/preload';
|
|
63
65
|
export type {
|
|
64
66
|
SkeletonAnglesStyle,
|
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
|
+
export const SDK_VERSION = '0.3.0';
|
package/src/types/events.ts
CHANGED
|
@@ -199,8 +199,8 @@ export interface ProgressionEvent {
|
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
/**
|
|
202
|
-
*
|
|
203
|
-
*
|
|
202
|
+
* @internal PoseTracker QA only — not a supported public API (do not document in Mintlify).
|
|
203
|
+
* Throttled movement / rep-FSM snapshot. See `.private/ENGINE_DEBUG_QA.md`.
|
|
204
204
|
*/
|
|
205
205
|
export interface EngineDebugEvent {
|
|
206
206
|
type: 'engine_debug';
|
package/src/types/manifest.ts
CHANGED
|
@@ -146,6 +146,8 @@ export interface EngineBundleDescriptor {
|
|
|
146
146
|
minSdkVersion: string;
|
|
147
147
|
/** True when the version sent in `localVersions.engine` is already current. */
|
|
148
148
|
upToDate?: boolean;
|
|
149
|
+
/** Which interpreter this descriptor is. Absent on older backends = v3. */
|
|
150
|
+
channel?: 'v3' | 'v4';
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
// ---------------------------------------------------------------------------
|
|
@@ -197,6 +199,11 @@ export interface ConfigureRequest {
|
|
|
197
199
|
poseRuntime?: string | null;
|
|
198
200
|
engine?: string | null;
|
|
199
201
|
};
|
|
202
|
+
/**
|
|
203
|
+
* Which remote engine to download. Default / omitted = v3 (production).
|
|
204
|
+
* `v4` is opt-in (heuristic catalog: squat, shoulder_roll, …).
|
|
205
|
+
*/
|
|
206
|
+
engineChannel?: 'v3' | 'v4';
|
|
200
207
|
}
|
|
201
208
|
|
|
202
209
|
export interface PlanInfo {
|