@modelhealth/sdk 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.
- package/README.md +40 -0
- package/dist/index.d.ts +850 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1016 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +458 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +204 -0
- package/dist/types.js.map +1 -0
- package/model_health_wasm.d.ts +112 -0
- package/model_health_wasm.js +1110 -0
- package/model_health_wasm_bg.wasm +0 -0
- package/model_health_wasm_bg.wasm.d.ts +45 -0
- package/package.json +28 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,850 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model Health SDK Client
|
|
3
|
+
*
|
|
4
|
+
* TypeScript/JavaScript client for the Model Health biomechanics SDK.
|
|
5
|
+
* Provides a clean, typed API over the WASM bindings.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*
|
|
9
|
+
* @example Basic usage
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { ModelHealthService } from '@modelhealth/sdk';
|
|
12
|
+
*
|
|
13
|
+
* // Create and initialize client with API key
|
|
14
|
+
* const client = new ModelHealthService({ apiKey: "your-api-key-here" });
|
|
15
|
+
* await client.init();
|
|
16
|
+
*
|
|
17
|
+
* // Authenticate (optional - API key already provides authentication)
|
|
18
|
+
* const result = await client.login("user@example.com", "password");
|
|
19
|
+
* if (result === "verification_required") {
|
|
20
|
+
* await client.verify("123456", true);
|
|
21
|
+
* }
|
|
22
|
+
*
|
|
23
|
+
* // Get sessions
|
|
24
|
+
* const sessions = await client.sessionList();
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
import type { LoginResult, RegistrationParameters, CheckerboardDetails, Session, Subject, SubjectParameters, Activity, ActivitySort, ActivityTag, VideoVersion, ResultDataType, ResultData, AnalysisType, AnalysisTask, AnalysisTaskStatus, ActivityProcessingStatus, TokenStorage, CalibrationStatus, AnalysisResult } from "./types.js";
|
|
28
|
+
import { MemoryTokenStorage, LocalStorageTokenStorage } from "./types.js";
|
|
29
|
+
/**
|
|
30
|
+
* Configuration options for the Model Health client.
|
|
31
|
+
*/
|
|
32
|
+
export interface ModelHealthConfig {
|
|
33
|
+
/**
|
|
34
|
+
* Your ModelHealth API key for authentication.
|
|
35
|
+
*
|
|
36
|
+
* This is required to use the SDK. Get your API key from the
|
|
37
|
+
* ModelHealth dashboard.
|
|
38
|
+
*
|
|
39
|
+
* @required
|
|
40
|
+
*/
|
|
41
|
+
apiKey: string;
|
|
42
|
+
/**
|
|
43
|
+
* Token storage implementation for persisting authentication.
|
|
44
|
+
*
|
|
45
|
+
* Provide a custom implementation for secure storage.
|
|
46
|
+
*
|
|
47
|
+
* @default MemoryTokenStorage (not secure - for development only)
|
|
48
|
+
*/
|
|
49
|
+
storage?: TokenStorage;
|
|
50
|
+
/**
|
|
51
|
+
* Automatically initialize WASM on construction.
|
|
52
|
+
*
|
|
53
|
+
* When false, you must manually call `init()` before using the client.
|
|
54
|
+
*
|
|
55
|
+
* @default true
|
|
56
|
+
*/
|
|
57
|
+
autoInit?: boolean;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Model Health SDK Client for biomechanical analysis.
|
|
61
|
+
*
|
|
62
|
+
* Main entry point for interacting with the Model Health SDK.
|
|
63
|
+
* Provides authentication, session management, data download,
|
|
64
|
+
* and analysis capabilities.
|
|
65
|
+
*
|
|
66
|
+
* @example Create with API key
|
|
67
|
+
* ```typescript
|
|
68
|
+
* const client = new ModelHealthService({
|
|
69
|
+
* apiKey: "your-api-key-here"
|
|
70
|
+
* });
|
|
71
|
+
* await client.init();
|
|
72
|
+
*
|
|
73
|
+
* // SDK is ready to use
|
|
74
|
+
* const sessions = await client.sessionList();
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example With custom configuration
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const client = new ModelHealthService({
|
|
80
|
+
* apiKey: "your-api-key",
|
|
81
|
+
* storage: new LocalStorageTokenStorage()
|
|
82
|
+
* });
|
|
83
|
+
* await client.init();
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare class ModelHealthService {
|
|
87
|
+
private wasmClient;
|
|
88
|
+
private storage;
|
|
89
|
+
private config;
|
|
90
|
+
private initialized;
|
|
91
|
+
/**
|
|
92
|
+
* Create a new Model Health client.
|
|
93
|
+
*
|
|
94
|
+
* @param config Configuration options including API key
|
|
95
|
+
* @throws If API key is not provided
|
|
96
|
+
*
|
|
97
|
+
* @example Default configuration
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const client = new ModelHealthService({
|
|
100
|
+
* apiKey: "your-api-key-here"
|
|
101
|
+
* });
|
|
102
|
+
* ```
|
|
103
|
+
*
|
|
104
|
+
* @example Custom configuration
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const client = new ModelHealthService({
|
|
107
|
+
* apiKey: "your-api-key",
|
|
108
|
+
* storage: new LocalStorageTokenStorage(),
|
|
109
|
+
* autoInit: false
|
|
110
|
+
* });
|
|
111
|
+
* ```
|
|
112
|
+
*/
|
|
113
|
+
constructor(config: ModelHealthConfig);
|
|
114
|
+
/**
|
|
115
|
+
* Initialize the WASM module and client.
|
|
116
|
+
*
|
|
117
|
+
* Must be called before using any other methods if `autoInit: false`
|
|
118
|
+
* was specified in the configuration. Safe to call multiple times.
|
|
119
|
+
*
|
|
120
|
+
* @throws If WASM initialization fails
|
|
121
|
+
*
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const client = new ModelHealthService({
|
|
125
|
+
* apiKey: "your-key",
|
|
126
|
+
* autoInit: false
|
|
127
|
+
* });
|
|
128
|
+
* await client.init();
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
init(): Promise<void>;
|
|
132
|
+
/**
|
|
133
|
+
* Ensure the client is initialized.
|
|
134
|
+
*
|
|
135
|
+
* @private
|
|
136
|
+
* @throws If client is not initialized
|
|
137
|
+
*/
|
|
138
|
+
private ensureInitialized;
|
|
139
|
+
/**
|
|
140
|
+
* Registers a new user account.
|
|
141
|
+
*
|
|
142
|
+
* Creates a new user account and automatically authenticates the user.
|
|
143
|
+
* After successful registration, the SDK is ready to use immediately
|
|
144
|
+
* without requiring a separate login call.
|
|
145
|
+
*
|
|
146
|
+
* @param parameters Registration details including credentials and user information
|
|
147
|
+
* @throws If registration fails (duplicate username/email, validation errors, etc.)
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```typescript
|
|
151
|
+
* const params = {
|
|
152
|
+
* username: "user123",
|
|
153
|
+
* email: "user@example.com",
|
|
154
|
+
* password: "securePassword123456789",
|
|
155
|
+
* first_name: "John",
|
|
156
|
+
* last_name: "Doe",
|
|
157
|
+
* country: "United States",
|
|
158
|
+
* institution: "Example University",
|
|
159
|
+
* profession: "Researcher",
|
|
160
|
+
* reason: "Biomechanical research",
|
|
161
|
+
* language: "en",
|
|
162
|
+
* unit: "metric",
|
|
163
|
+
* newsletter: false
|
|
164
|
+
* };
|
|
165
|
+
*
|
|
166
|
+
* await client.register(params);
|
|
167
|
+
* // User is now authenticated and ready to use SDK
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
register(parameters: RegistrationParameters): Promise<void>;
|
|
171
|
+
/**
|
|
172
|
+
* Authenticates a user with username and password.
|
|
173
|
+
*
|
|
174
|
+
* This initiates the login process. Depending on the account's security settings
|
|
175
|
+
* and device trust status, either:
|
|
176
|
+
* - Returns `"ok"` if the device is trusted (previously verified with
|
|
177
|
+
* `rememberDevice: true` within the last 90 days)
|
|
178
|
+
* - Returns `"verification_required"` if email verification is needed
|
|
179
|
+
*
|
|
180
|
+
* When verification is required, a code is automatically sent to the user's
|
|
181
|
+
* registered email address. Complete authentication by calling `verify()`.
|
|
182
|
+
*
|
|
183
|
+
* @param username User's email address
|
|
184
|
+
* @param password User's password
|
|
185
|
+
* @returns A `LoginResult` indicating whether verification is required
|
|
186
|
+
* @throws If authentication fails (invalid credentials, network issues, etc.)
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* const result = await client.login("user@example.com", "secure_pass");
|
|
191
|
+
*
|
|
192
|
+
* switch (result) {
|
|
193
|
+
* case "ok":
|
|
194
|
+
* // Authentication complete, proceed with SDK usage
|
|
195
|
+
* console.log("Login successful");
|
|
196
|
+
* break;
|
|
197
|
+
*
|
|
198
|
+
* case "verification_required":
|
|
199
|
+
* // Prompt user for email verification code and
|
|
200
|
+
* // trust this device for 90 days
|
|
201
|
+
* const code = await promptUserForCode();
|
|
202
|
+
* await client.verify(code, true);
|
|
203
|
+
* break;
|
|
204
|
+
* }
|
|
205
|
+
* ```
|
|
206
|
+
*/
|
|
207
|
+
login(username: string, password: string): Promise<LoginResult>;
|
|
208
|
+
/**
|
|
209
|
+
* Completes authentication by verifying an email code.
|
|
210
|
+
*
|
|
211
|
+
* After `login()` returns `"verification_required"`, call this method with
|
|
212
|
+
* the verification code sent to the user's email.
|
|
213
|
+
*
|
|
214
|
+
* Set `rememberDevice: true` to skip email verification on this device for 90 days.
|
|
215
|
+
* Future login attempts from this device will return `"ok"` directly.
|
|
216
|
+
*
|
|
217
|
+
* @param code 6-digit verification code from email
|
|
218
|
+
* @param rememberDevice If `true`, trust this device for 90 days (default: `false`)
|
|
219
|
+
* @throws If the code is invalid or expired
|
|
220
|
+
*
|
|
221
|
+
* @example
|
|
222
|
+
* ```typescript
|
|
223
|
+
* // After receiving "verification_required" from login
|
|
224
|
+
* await client.verify("123456", true);
|
|
225
|
+
* // Authentication now complete, SDK ready for use
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
verify(code: string, rememberDevice: boolean): Promise<void>;
|
|
229
|
+
/**
|
|
230
|
+
* Logs out the current user.
|
|
231
|
+
*
|
|
232
|
+
* After logout, the user must call `login()` or `register()` to use the SDK again.
|
|
233
|
+
*
|
|
234
|
+
* @throws If the logout request fails
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* ```typescript
|
|
238
|
+
* await client.logout();
|
|
239
|
+
* // User is now logged out
|
|
240
|
+
* ```
|
|
241
|
+
*/
|
|
242
|
+
logout(): Promise<void>;
|
|
243
|
+
/**
|
|
244
|
+
* Checks if a user is currently authenticated.
|
|
245
|
+
*
|
|
246
|
+
* @returns `true` if authenticated, `false` otherwise
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* if (await client.isAuthenticated()) {
|
|
251
|
+
* // Proceed with authenticated operations
|
|
252
|
+
* const sessions = await client.sessionList();
|
|
253
|
+
* } else {
|
|
254
|
+
* // Show login screen
|
|
255
|
+
* }
|
|
256
|
+
* ```
|
|
257
|
+
*/
|
|
258
|
+
isAuthenticated(): Promise<boolean>;
|
|
259
|
+
/**
|
|
260
|
+
* Get the current authentication token.
|
|
261
|
+
*
|
|
262
|
+
* @returns The authentication token string, or null if not authenticated
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```typescript
|
|
266
|
+
* const token = client.getToken();
|
|
267
|
+
* if (token) {
|
|
268
|
+
* // Store for later use
|
|
269
|
+
* localStorage.setItem('backup_token', token);
|
|
270
|
+
* }
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
getToken(): string | null;
|
|
274
|
+
/**
|
|
275
|
+
* Set authentication token directly.
|
|
276
|
+
*
|
|
277
|
+
* Use this to restore a previously saved session without logging in again.
|
|
278
|
+
*
|
|
279
|
+
* @param token The authentication token to restore
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* const savedToken = localStorage.getItem('backup_token');
|
|
284
|
+
* if (savedToken) {
|
|
285
|
+
* client.setToken(savedToken);
|
|
286
|
+
* }
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
setToken(token: string): void;
|
|
290
|
+
/**
|
|
291
|
+
* Retrieves all sessions for the authenticated user.
|
|
292
|
+
*
|
|
293
|
+
* @returns An array of `Session` objects. Returns an empty array if no sessions exist.
|
|
294
|
+
* @throws If the request fails due to network issues, authentication problems,
|
|
295
|
+
* or server errors.
|
|
296
|
+
*
|
|
297
|
+
* @example
|
|
298
|
+
* ```typescript
|
|
299
|
+
* try {
|
|
300
|
+
* const sessions = await client.sessionList();
|
|
301
|
+
* console.log(`Found ${sessions.length} sessions`);
|
|
302
|
+
* for (const session of sessions) {
|
|
303
|
+
* console.log(`Session: ${session.id}`);
|
|
304
|
+
* }
|
|
305
|
+
* } catch (error) {
|
|
306
|
+
* console.log(`Failed to fetch sessions: ${error}`);
|
|
307
|
+
* }
|
|
308
|
+
* ```
|
|
309
|
+
*/
|
|
310
|
+
sessionList(): Promise<Session[]>;
|
|
311
|
+
/**
|
|
312
|
+
* Retrieve a specific session by ID with all activities populated.
|
|
313
|
+
*
|
|
314
|
+
* @param sessionId Unique session identifier
|
|
315
|
+
* @returns The requested session with complete activity data
|
|
316
|
+
* @throws If the session doesn't exist, user lacks access, or request fails
|
|
317
|
+
*
|
|
318
|
+
* @example
|
|
319
|
+
* ```typescript
|
|
320
|
+
* const session = await client.getSession("session-abc123");
|
|
321
|
+
* console.log(`Session has ${session.activities.length} activities`);
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
getSession(sessionId: string): Promise<Session>;
|
|
325
|
+
/**
|
|
326
|
+
* Creates a new session.
|
|
327
|
+
*
|
|
328
|
+
* A session is required before performing camera calibration. It represents
|
|
329
|
+
* a single calibration workflow and groups multiple cameras together.
|
|
330
|
+
*
|
|
331
|
+
* After creating a session, use camera calibration methods to calibrate your cameras.
|
|
332
|
+
*
|
|
333
|
+
* @returns A `Session` object with a unique identifier
|
|
334
|
+
* @throws If session creation fails
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```typescript
|
|
338
|
+
* // Create session
|
|
339
|
+
* const session = await client.createSession();
|
|
340
|
+
*
|
|
341
|
+
* // Proceed with calibration
|
|
342
|
+
* const details = {
|
|
343
|
+
* rows: 4,
|
|
344
|
+
* columns: 5,
|
|
345
|
+
* square_size: 35,
|
|
346
|
+
* placement: "perpendicular"
|
|
347
|
+
* };
|
|
348
|
+
* // await client.calibrateCamera(session, details, (status) => { ... });
|
|
349
|
+
* ```
|
|
350
|
+
*/
|
|
351
|
+
createSession(): Promise<Session>;
|
|
352
|
+
/**
|
|
353
|
+
* Calibrates a camera using a checkerboard pattern.
|
|
354
|
+
*
|
|
355
|
+
* **Requirements:**
|
|
356
|
+
* - A printed checkerboard pattern
|
|
357
|
+
* - Accurate measurement of square size in millimeters
|
|
358
|
+
* - Multiple views of the checkerboard from different angles
|
|
359
|
+
*
|
|
360
|
+
* The calibration is automated and typically completes in a few seconds
|
|
361
|
+
*
|
|
362
|
+
* @param session The session created with `createSession()`
|
|
363
|
+
* @param checkerboardDetails Configuration of the calibration checkerboard
|
|
364
|
+
* @param statusCallback Callback function called with calibration progress updates
|
|
365
|
+
* @throws If calibration fails (insufficient views, pattern not detected, etc.)
|
|
366
|
+
*
|
|
367
|
+
* @example
|
|
368
|
+
* ```typescript
|
|
369
|
+
* const session = await client.createSession();
|
|
370
|
+
*
|
|
371
|
+
* const details = {
|
|
372
|
+
* rows: 4, // Internal corners, not squares (for 5×6 board)
|
|
373
|
+
* columns: 5, // Internal corners, not squares (for 5×6 board)
|
|
374
|
+
* square_size: 35, // Measured in millimeters
|
|
375
|
+
* placement: "perpendicular"
|
|
376
|
+
* };
|
|
377
|
+
*
|
|
378
|
+
* await client.calibrateCamera(session, details, (status) => {
|
|
379
|
+
* console.log("Calibration status:", status);
|
|
380
|
+
* });
|
|
381
|
+
* // Calibration complete, proceed to neutral pose
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
calibrateCamera(session: Session, checkerboardDetails: CheckerboardDetails, statusCallback: (status: CalibrationStatus) => void): Promise<void>;
|
|
385
|
+
/**
|
|
386
|
+
* Captures the subject's neutral standing pose for model scaling.
|
|
387
|
+
*
|
|
388
|
+
* This step is required after camera calibration and before recording movement activities.
|
|
389
|
+
* It takes a quick video of the subject standing in a neutral position, which is
|
|
390
|
+
* used to scale the biomechanical model to match the subject's dimensions.
|
|
391
|
+
*
|
|
392
|
+
* **Instructions for subject:**
|
|
393
|
+
* - Stand upright in a relaxed, natural position
|
|
394
|
+
* - Face forward with arms spread slightly at sides
|
|
395
|
+
* - Remain still for a few seconds
|
|
396
|
+
*
|
|
397
|
+
* @param subject The subject to calibrate the neutral pose for
|
|
398
|
+
* @param session The session to perform calibration in
|
|
399
|
+
* @param statusCallback Callback function called with calibration progress updates
|
|
400
|
+
* @throws If pose capture fails (subject not detected, poor lighting, etc.)
|
|
401
|
+
*
|
|
402
|
+
* @example
|
|
403
|
+
* ```typescript
|
|
404
|
+
* // After successful camera calibration
|
|
405
|
+
* await client.calibrateNeutralPose(subject, session, (status) => {
|
|
406
|
+
* console.log("Neutral pose status:", status);
|
|
407
|
+
* });
|
|
408
|
+
* // Model now scaled, ready to record movement activities
|
|
409
|
+
* ```
|
|
410
|
+
*/
|
|
411
|
+
calibrateNeutralPose(subject: Subject, session: Session, statusCallback: (status: CalibrationStatus) => void): Promise<void>;
|
|
412
|
+
/**
|
|
413
|
+
* Retrieves all subjects associated with the authenticated account.
|
|
414
|
+
*
|
|
415
|
+
* Subjects represent individuals being monitored or assessed. Each subject
|
|
416
|
+
* contains demographic information, physical measurements, and categorization tags.
|
|
417
|
+
*
|
|
418
|
+
* @returns An array of `Subject` objects
|
|
419
|
+
* @throws If the request fails or authentication has expired
|
|
420
|
+
*
|
|
421
|
+
* @example
|
|
422
|
+
* ```typescript
|
|
423
|
+
* const subjects = await client.subjectList();
|
|
424
|
+
* for (const subject of subjects) {
|
|
425
|
+
* console.log(`${subject.name}: ${subject.height ?? 0}cm, ${subject.weight ?? 0}kg`);
|
|
426
|
+
* }
|
|
427
|
+
*
|
|
428
|
+
* // Filter by tags
|
|
429
|
+
* const athletes = subjects.filter(s => s.subject_tags.includes("athlete"));
|
|
430
|
+
* ```
|
|
431
|
+
*/
|
|
432
|
+
subjectList(): Promise<Subject[]>;
|
|
433
|
+
/**
|
|
434
|
+
* Creates a new subject in the system.
|
|
435
|
+
*
|
|
436
|
+
* Subjects represent individuals being monitored or assessed. After creating
|
|
437
|
+
* a subject, they can be associated with sessions for neutral pose calibration
|
|
438
|
+
* and movement activities.
|
|
439
|
+
*
|
|
440
|
+
* @param parameters Subject details including name, measurements, and tags
|
|
441
|
+
* @returns The newly created `Subject` with its assigned ID
|
|
442
|
+
* @throws If creation fails (validation errors, duplicate name, etc.)
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* const params = {
|
|
447
|
+
* name: "John Doe",
|
|
448
|
+
* weight: 75.0, // kilograms
|
|
449
|
+
* height: 180.0, // centimeters
|
|
450
|
+
* birth_year: 1990,
|
|
451
|
+
* gender: "man",
|
|
452
|
+
* sex_at_birth: "man",
|
|
453
|
+
* characteristics: "Regular training schedule",
|
|
454
|
+
* subject_tags: ["athlete"],
|
|
455
|
+
* terms: true
|
|
456
|
+
* };
|
|
457
|
+
*
|
|
458
|
+
* const subject = await client.createSubject(params);
|
|
459
|
+
* console.log(`Created subject with ID: ${subject.id}`);
|
|
460
|
+
*
|
|
461
|
+
* // Use the subject for calibration
|
|
462
|
+
* // await client.calibrateNeutralPose(subject, session, (status) => { ... });
|
|
463
|
+
* ```
|
|
464
|
+
*/
|
|
465
|
+
createSubject(parameters: SubjectParameters): Promise<Subject>;
|
|
466
|
+
/**
|
|
467
|
+
* Retrieves activities for a specific subject with pagination and sorting.
|
|
468
|
+
*
|
|
469
|
+
* This method allows you to fetch activities associated with a particular subject,
|
|
470
|
+
* with control over pagination and sort order. This is useful for displaying
|
|
471
|
+
* activity history or implementing infinite scroll interfaces.
|
|
472
|
+
*
|
|
473
|
+
* @param subjectId The ID of the subject whose activities to retrieve
|
|
474
|
+
* @param startIndex Zero-based index to start from (for pagination). Use 0 for first page.
|
|
475
|
+
* @param count Number of activities to retrieve per request
|
|
476
|
+
* @param sort Sort order for the results (e.g., "updated_at" for most recent first)
|
|
477
|
+
* @returns An array of activities for the specified subject
|
|
478
|
+
* @throws If the request fails or authentication has expired
|
|
479
|
+
*
|
|
480
|
+
* @example
|
|
481
|
+
* ```typescript
|
|
482
|
+
* // Get the 20 most recent activities for a subject
|
|
483
|
+
* const recentActivities = await client.getActivitiesForSubject(
|
|
484
|
+
* "subject-123",
|
|
485
|
+
* 0,
|
|
486
|
+
* 20,
|
|
487
|
+
* "updated_at"
|
|
488
|
+
* );
|
|
489
|
+
*
|
|
490
|
+
* // Pagination - get the next 20 activities
|
|
491
|
+
* const nextPage = await client.getActivitiesForSubject(
|
|
492
|
+
* "subject-123",
|
|
493
|
+
* 20,
|
|
494
|
+
* 20,
|
|
495
|
+
* "updated_at"
|
|
496
|
+
* );
|
|
497
|
+
* ```
|
|
498
|
+
*/
|
|
499
|
+
getActivitiesForSubject(subjectId: string, startIndex: number, count: number, sort: ActivitySort): Promise<Activity[]>;
|
|
500
|
+
/**
|
|
501
|
+
* Retrieves a specific activity by its ID.
|
|
502
|
+
*
|
|
503
|
+
* Use this method to fetch the complete details of an activity, including
|
|
504
|
+
* its videos, results, and current processing status.
|
|
505
|
+
*
|
|
506
|
+
* @param activityId The unique identifier of the activity
|
|
507
|
+
* @returns The requested activity with all its details
|
|
508
|
+
* @throws If the activity doesn't exist, or if authentication has expired
|
|
509
|
+
*
|
|
510
|
+
* @example
|
|
511
|
+
* ```typescript
|
|
512
|
+
* const activity = await client.getActivity("abc123");
|
|
513
|
+
* console.log(`Activity: ${activity.name ?? "Unnamed"}`);
|
|
514
|
+
* console.log(`Status: ${activity.status}`);
|
|
515
|
+
* console.log(`Videos: ${activity.videos.length}`);
|
|
516
|
+
* ```
|
|
517
|
+
*/
|
|
518
|
+
getActivity(activityId: string): Promise<Activity>;
|
|
519
|
+
/**
|
|
520
|
+
* Updates an existing activity.
|
|
521
|
+
*
|
|
522
|
+
* Use this method to modify activity properties such as the name.
|
|
523
|
+
* The activity is updated on the server and the updated version is returned.
|
|
524
|
+
*
|
|
525
|
+
* @param activity The activity to update (with modified properties)
|
|
526
|
+
* @returns The updated activity as stored on the server
|
|
527
|
+
* @throws If the update fails or authentication has expired
|
|
528
|
+
*
|
|
529
|
+
* @example
|
|
530
|
+
* ```typescript
|
|
531
|
+
* let activity = await client.getActivity("abc123");
|
|
532
|
+
* // Modify the activity name
|
|
533
|
+
* activity.name = "CMJ Baseline Test";
|
|
534
|
+
* const updated = await client.updateActivity(activity);
|
|
535
|
+
* console.log(`Updated: ${updated.name ?? ""}`);
|
|
536
|
+
* ```
|
|
537
|
+
*
|
|
538
|
+
* @note Not all activity properties can be modified. Only mutable fields
|
|
539
|
+
* (such as `name`) will be updated on the server.
|
|
540
|
+
*/
|
|
541
|
+
updateActivity(activity: Activity): Promise<Activity>;
|
|
542
|
+
/**
|
|
543
|
+
* Deletes an activity from the system.
|
|
544
|
+
*
|
|
545
|
+
* This permanently removes the activity and all its associated data,
|
|
546
|
+
* including videos and analysis results. This action cannot be undone.
|
|
547
|
+
*
|
|
548
|
+
* @param activity The activity to delete
|
|
549
|
+
* @throws If the deletion fails or authentication has expired
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```typescript
|
|
553
|
+
* const activity = await client.getActivity("abc123");
|
|
554
|
+
* await client.deleteActivity(activity);
|
|
555
|
+
* // Activity and all associated data are now permanently deleted
|
|
556
|
+
* ```
|
|
557
|
+
*
|
|
558
|
+
* @warning This operation is irreversible. All videos, analysis results,
|
|
559
|
+
* and metadata associated with this activity will be permanently lost.
|
|
560
|
+
*/
|
|
561
|
+
deleteActivity(activity: Activity): Promise<void>;
|
|
562
|
+
/**
|
|
563
|
+
* Retrieves all available activity tags.
|
|
564
|
+
*
|
|
565
|
+
* Activity tags provide a way to categorize and filter activities.
|
|
566
|
+
* This method returns all tags configured in the system, which can be
|
|
567
|
+
* used for filtering or organizing activities in your application.
|
|
568
|
+
*
|
|
569
|
+
* @returns An array of available activity tags
|
|
570
|
+
* @throws If the request fails or authentication has expired
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* ```typescript
|
|
574
|
+
* const tags = await client.getActivityTags();
|
|
575
|
+
* for (const tag of tags) {
|
|
576
|
+
* console.log(`${tag.label}: ${tag.value}`);
|
|
577
|
+
* }
|
|
578
|
+
*
|
|
579
|
+
* // Use tags for filtering or categorization
|
|
580
|
+
* const cmjTag = tags.find(t => t.value === "cmj");
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
getActivityTags(): Promise<ActivityTag[]>;
|
|
584
|
+
/**
|
|
585
|
+
* Retrieves all movement activities associated with the authenticated account.
|
|
586
|
+
*
|
|
587
|
+
* Activities represent individual recording sessions and contain references to
|
|
588
|
+
* captured videos and analysis results. Use this to review past data or
|
|
589
|
+
* fetch analysis for completed activities.
|
|
590
|
+
*
|
|
591
|
+
* @param sessionId Session identifier
|
|
592
|
+
* @returns An array of `Activity` objects
|
|
593
|
+
* @throws If the request fails or authentication has expired
|
|
594
|
+
*
|
|
595
|
+
* @example
|
|
596
|
+
* ```typescript
|
|
597
|
+
* const activities = await client.activityList(session.id);
|
|
598
|
+
*
|
|
599
|
+
* // Find completed activities ready for analysis
|
|
600
|
+
* const completed = activities.filter(t => t.status === "completed");
|
|
601
|
+
*
|
|
602
|
+
* // Access videos and results
|
|
603
|
+
* for (const activity of completed) {
|
|
604
|
+
* console.log(`Activity: ${activity.name ?? activity.id}`);
|
|
605
|
+
* console.log(`Videos: ${activity.videos.length}`);
|
|
606
|
+
* console.log(`Results: ${activity.results.length}`);
|
|
607
|
+
* }
|
|
608
|
+
* ```
|
|
609
|
+
*/
|
|
610
|
+
activityList(sessionId: string): Promise<Activity[]>;
|
|
611
|
+
/**
|
|
612
|
+
* Download video data for a specific activity.
|
|
613
|
+
*
|
|
614
|
+
* Asynchronously fetches all videos associated with a given activity that match the specified type.
|
|
615
|
+
* Videos with invalid URLs or failed downloads are silently excluded from the result.
|
|
616
|
+
*
|
|
617
|
+
* @param activity The activity whose videos should be downloaded
|
|
618
|
+
* @param version The version type of videos to download (default: "synced")
|
|
619
|
+
* @returns An array of video data as Uint8Array. The array may be empty if no valid
|
|
620
|
+
* videos are available or all downloads fail.
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* ```typescript
|
|
624
|
+
* const activity = // ... obtained activity
|
|
625
|
+
* const videoData = await client.downloadActivityVideos(activity, "raw");
|
|
626
|
+
*
|
|
627
|
+
* for (const data of videoData) {
|
|
628
|
+
* // Process video data
|
|
629
|
+
* }
|
|
630
|
+
* ```
|
|
631
|
+
*
|
|
632
|
+
* @note This method performs concurrent downloads for optimal performance. Individual download
|
|
633
|
+
* failures do not affect other requests.
|
|
634
|
+
*/
|
|
635
|
+
downloadActivityVideos(activity: Activity, version?: VideoVersion): Promise<Uint8Array[]>;
|
|
636
|
+
/**
|
|
637
|
+
* Downloads result data files from a processed activity.
|
|
638
|
+
*
|
|
639
|
+
* After an activity completes processing, various result files become available for download.
|
|
640
|
+
* Use this method to retrieve specific types of data (kinematic measurements, visualizations)
|
|
641
|
+
* in their native file formats (JSON, CSV).
|
|
642
|
+
*
|
|
643
|
+
* This method is useful when you need access to raw analysis data rather than the
|
|
644
|
+
* structured metrics provided by analysis result methods.
|
|
645
|
+
*
|
|
646
|
+
* @param activity The completed activity to download data from
|
|
647
|
+
* @param dataTypes The types of result data to download (kinematic, visualization, or both)
|
|
648
|
+
* @returns An array of result files with their formats. Returns an empty array if no
|
|
649
|
+
* results are available or all downloads fail.
|
|
650
|
+
*
|
|
651
|
+
* @example
|
|
652
|
+
* ```typescript
|
|
653
|
+
* // Download kinematic data only
|
|
654
|
+
* const kinematicData = await client.downloadActivityResultData(activity, ["kinematic"]);
|
|
655
|
+
*
|
|
656
|
+
* for (const result of kinematicData) {
|
|
657
|
+
* switch (result.file_type) {
|
|
658
|
+
* case "json":
|
|
659
|
+
* const json = JSON.parse(new TextDecoder().decode(result.data));
|
|
660
|
+
* console.log("Parsed kinematic JSON");
|
|
661
|
+
* break;
|
|
662
|
+
*
|
|
663
|
+
* case "csv":
|
|
664
|
+
* const csvString = new TextDecoder().decode(result.data);
|
|
665
|
+
* console.log(`CSV data:\n${csvString}`);
|
|
666
|
+
* break;
|
|
667
|
+
* }
|
|
668
|
+
* }
|
|
669
|
+
*
|
|
670
|
+
* // Download all available data types
|
|
671
|
+
* const allData = await client.downloadActivityResultData(
|
|
672
|
+
* activity,
|
|
673
|
+
* ["kinematic", "visualization"]
|
|
674
|
+
* );
|
|
675
|
+
* console.log(`Downloaded ${allData.length} result files`);
|
|
676
|
+
* ```
|
|
677
|
+
*
|
|
678
|
+
* @note This method performs concurrent downloads for optimal performance.
|
|
679
|
+
* Individual download failures do not affect other requests and failed downloads
|
|
680
|
+
* are silently excluded from results.
|
|
681
|
+
*/
|
|
682
|
+
downloadActivityResultData(activity: Activity, dataTypes: ResultDataType[]): Promise<ResultData[]>;
|
|
683
|
+
/**
|
|
684
|
+
* Starts recording a dynamic movement activity.
|
|
685
|
+
*
|
|
686
|
+
* After completing calibration steps (camera calibration and neutral pose),
|
|
687
|
+
* use this method to begin recording an activity.
|
|
688
|
+
*
|
|
689
|
+
* @param activityName A descriptive name for this activity (e.g., "cmj-test")
|
|
690
|
+
* @param session The session this activity is associated with
|
|
691
|
+
* @returns The newly created activity
|
|
692
|
+
* @throws If recording cannot start (session not calibrated, camera issues, etc.)
|
|
693
|
+
*
|
|
694
|
+
* @example
|
|
695
|
+
* ```typescript
|
|
696
|
+
* // Record a CMJ session
|
|
697
|
+
* const activity = await client.record("cmj-2024", session);
|
|
698
|
+
* // Subject performs CMJ while cameras record
|
|
699
|
+
*
|
|
700
|
+
* // When complete, stop recording
|
|
701
|
+
* await client.stopRecording(session);
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
record(activityName: string, session: Session): Promise<Activity>;
|
|
705
|
+
/**
|
|
706
|
+
* Stops recording of a dynamic movement activity in a session.
|
|
707
|
+
*
|
|
708
|
+
* Call this method when the subject has completed the movement activity.
|
|
709
|
+
*
|
|
710
|
+
* @param session The session to stop recording in
|
|
711
|
+
* @throws If the activity cannot be stopped (invalid session ID, already stopped, etc.)
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* ```typescript
|
|
715
|
+
* // After recording is complete
|
|
716
|
+
* await client.stopRecording(session);
|
|
717
|
+
* ```
|
|
718
|
+
*/
|
|
719
|
+
stopRecording(session: Session): Promise<void>;
|
|
720
|
+
/**
|
|
721
|
+
* Retrieves the current processing status of an activity.
|
|
722
|
+
*
|
|
723
|
+
* Poll this method to determine when an activity is ready for analysis.
|
|
724
|
+
* Activities must complete video upload and processing before analysis can begin.
|
|
725
|
+
*
|
|
726
|
+
* @param activity A completed activity
|
|
727
|
+
* @returns The current processing status
|
|
728
|
+
* @throws Network or authentication errors
|
|
729
|
+
*
|
|
730
|
+
* @example
|
|
731
|
+
* ```typescript
|
|
732
|
+
* const status = await client.getStatus(activity);
|
|
733
|
+
*
|
|
734
|
+
* switch (status.type) {
|
|
735
|
+
* case "ready":
|
|
736
|
+
* console.log("Activity ready for analysis");
|
|
737
|
+
* break;
|
|
738
|
+
* case "processing":
|
|
739
|
+
* console.log("Still processing...");
|
|
740
|
+
* break;
|
|
741
|
+
* case "uploading":
|
|
742
|
+
* console.log(`Uploaded ${status.uploaded}/${status.total} videos`);
|
|
743
|
+
* break;
|
|
744
|
+
* case "failed":
|
|
745
|
+
* console.log("Processing failed");
|
|
746
|
+
* break;
|
|
747
|
+
* }
|
|
748
|
+
* ```
|
|
749
|
+
*/
|
|
750
|
+
getStatus(activity: Activity): Promise<ActivityProcessingStatus>;
|
|
751
|
+
/**
|
|
752
|
+
* Starts an analysis task for a completed activity.
|
|
753
|
+
*
|
|
754
|
+
* The activity must have completed processing (status `.ready`) before analysis can begin.
|
|
755
|
+
* Use the returned `AnalysisTask` to poll for completion.
|
|
756
|
+
*
|
|
757
|
+
* @param analysisType The type of analysis to perform
|
|
758
|
+
* @param activity The activity to analyze
|
|
759
|
+
* @param session The session containing the activity
|
|
760
|
+
* @returns An analysis task for tracking completion
|
|
761
|
+
* @throws Network or authentication errors
|
|
762
|
+
*
|
|
763
|
+
* @example
|
|
764
|
+
* ```typescript
|
|
765
|
+
* const task = await client.startAnalysis(
|
|
766
|
+
* "counter_movement_jump",
|
|
767
|
+
* activity,
|
|
768
|
+
* session
|
|
769
|
+
* );
|
|
770
|
+
*
|
|
771
|
+
* // Poll for completion
|
|
772
|
+
* const status = await client.getAnalysisStatus(task);
|
|
773
|
+
* ```
|
|
774
|
+
*/
|
|
775
|
+
startAnalysis(analysisType: AnalysisType, activity: Activity, session: Session): Promise<AnalysisTask>;
|
|
776
|
+
/**
|
|
777
|
+
* Retrieves the current status of an analysis task.
|
|
778
|
+
*
|
|
779
|
+
* Poll this method to monitor analysis progress. When status is `.completed`,
|
|
780
|
+
* use the returned result tags to download analysis files.
|
|
781
|
+
*
|
|
782
|
+
* @param task The task returned from `startAnalysis`
|
|
783
|
+
* @returns The current analysis status
|
|
784
|
+
* @throws Network or authentication errors
|
|
785
|
+
*
|
|
786
|
+
* @example
|
|
787
|
+
* ```typescript
|
|
788
|
+
* const status = await client.getAnalysisStatus(task);
|
|
789
|
+
*
|
|
790
|
+
* switch (status.type) {
|
|
791
|
+
* case "processing":
|
|
792
|
+
* console.log("Analysis running...");
|
|
793
|
+
* break;
|
|
794
|
+
* case "completed":
|
|
795
|
+
* for (const tag of status.result_tags) {
|
|
796
|
+
* const data = await client.downloadAnalysisResult(activity, tag);
|
|
797
|
+
* }
|
|
798
|
+
* break;
|
|
799
|
+
* case "failed":
|
|
800
|
+
* console.log("Analysis failed");
|
|
801
|
+
* break;
|
|
802
|
+
* }
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
805
|
+
getAnalysisStatus(task: AnalysisTask): Promise<AnalysisTaskStatus>;
|
|
806
|
+
/**
|
|
807
|
+
* Downloads an analysis result.
|
|
808
|
+
*
|
|
809
|
+
* Result tags are provided in the `.completed` status from `getAnalysisStatus`.
|
|
810
|
+
* Each tag represents a specific analysis output with structured biomechanical metrics.
|
|
811
|
+
*
|
|
812
|
+
* @param activity The completed and analyzed activity
|
|
813
|
+
* @param resultTag The specific result identifier
|
|
814
|
+
* @returns An `AnalysisResult` containing structured metrics
|
|
815
|
+
* @throws Network or authentication errors
|
|
816
|
+
*
|
|
817
|
+
* @example
|
|
818
|
+
* ```typescript
|
|
819
|
+
* const result = await client.downloadAnalysisResult(
|
|
820
|
+
* activity,
|
|
821
|
+
* "countermovement_jump"
|
|
822
|
+
* );
|
|
823
|
+
*
|
|
824
|
+
* console.log(`Analysis: ${result.analysis_title}`);
|
|
825
|
+
* console.log(`Description: ${result.analysis_description}`);
|
|
826
|
+
*
|
|
827
|
+
* // Access specific metrics
|
|
828
|
+
* if (result.jump_height) {
|
|
829
|
+
* console.log(`Jump Height: ${result.jump_height} cm`);
|
|
830
|
+
* }
|
|
831
|
+
*
|
|
832
|
+
* // Iterate all metrics
|
|
833
|
+
* for (const [key, metric] of Object.entries(result.metrics)) {
|
|
834
|
+
* console.log(`${metric.label}:`, metric.value);
|
|
835
|
+
* }
|
|
836
|
+
* ```
|
|
837
|
+
*/
|
|
838
|
+
downloadAnalysisResult(activity: Activity, resultTag: string): Promise<AnalysisResult>;
|
|
839
|
+
/**
|
|
840
|
+
* Parse JSON response from WASM.
|
|
841
|
+
*
|
|
842
|
+
* @private
|
|
843
|
+
* @param value Value from WASM (may be string or object)
|
|
844
|
+
* @returns Parsed TypeScript object
|
|
845
|
+
*/
|
|
846
|
+
private parseResponse;
|
|
847
|
+
}
|
|
848
|
+
export * from "./types.js";
|
|
849
|
+
export { MemoryTokenStorage, LocalStorageTokenStorage };
|
|
850
|
+
//# sourceMappingURL=index.d.ts.map
|