@modelhealth/sdk 0.1.0 → 0.1.7

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
@@ -1,40 +1,315 @@
1
- # Model Health SDK
1
+ # Model Health SDK for TypeScript
2
2
 
3
- TypeScript/JavaScript SDK for biomechanical analysis from smartphone videos.
3
+ TypeScript/JavaScript SDK for the Model Health biomechanics platform.
4
+
5
+ ## Features
6
+
7
+ - 📦 **Type-safe**: Full TypeScript type definitions
8
+ - 🌐 **Cross-platform**: Works in browsers, Node.js, React, Vue, Svelte, etc.
9
+ - 🔒 **Secure**: Pluggable storage system for authentication tokens
10
+ - ⚡ **Fast**: WASM performance with JavaScript ergonomics
4
11
 
5
12
  ## Installation
13
+
6
14
  ```bash
7
15
  npm install @modelhealth/sdk
8
16
  ```
9
17
 
10
18
  ## Quick Start
19
+
11
20
  ```typescript
12
21
  import { ModelHealthService } from '@modelhealth/sdk';
13
22
 
14
- const service = new ModelHealthService();
15
- await service.login('user@example.com', 'password');
23
+ // Create client
24
+ const client = new ModelHealthService();
25
+ await client.init();
26
+
27
+ // Login
28
+ const result = await client.login('username', 'password');
29
+ if (result === 'verification_r_equired') {
30
+ await client.verify('123456', true);
31
+ }
32
+
33
+ // Get sessions
34
+ const sessions = await client.sessionList();
35
+ console.log(sessions);
36
+ ```
37
+
38
+ ## Configuration
39
+
40
+ ### Development Mode
41
+
42
+ ```typescript
43
+ const client = new ModelHealthService({
44
+ development: true, // Use development API endpoint
45
+ });
46
+ ```
47
+
48
+ ### Custom Token Storage
49
+
50
+ By default, the SDK uses in-memory token storage (tokens are lost on page refresh). For production, implement secure token storage:
51
+
52
+ ```typescript
53
+ import { ModelHealthService, TokenStorage } from '@modelhealth/sdk';
54
+
55
+ // Option 1: Use provided LocalStorage implementation (basic security)
56
+ import { LocalStorageTokenStorage } from '@modelhealth/sdk';
57
+
58
+ const client = new ModelHealthService({
59
+ storage: new LocalStorageTokenStorage(),
60
+ });
61
+
62
+ // Option 2: Implement your own secure storage
63
+ class SecureTokenStorage implements TokenStorage {
64
+ async getToken(): Promise<string | null> {
65
+ // Your secure storage implementation
66
+ // Examples: encrypted IndexedDB, secure cookies, etc.
67
+ }
68
+
69
+ async setToken(token: string): Promise<void> {
70
+ // Store token securely
71
+ }
72
+
73
+ async removeToken(): Promise<void> {
74
+ // Remove token
75
+ }
76
+ }
77
+
78
+ const secureClient = new ModelHealthService({
79
+ storage: new SecureTokenStorage(),
80
+ });
16
81
  ```
17
82
 
18
- ## Documentation
83
+ ### Storage Security Recommendations
19
84
 
20
- **Full API Documentation**: [docs.modelhealth.io](https://docs.modelhealth.io/typescript)
85
+ **Development:**
86
+ - `MemoryTokenStorage`: Quick testing (default, not persistent)
87
+ - `LocalStorageTokenStorage`: Simple persistence (basic security)
21
88
 
22
- ## Examples
89
+ **Production:**
90
+ - Encrypted IndexedDB with Web Crypto API
91
+ - HttpOnly cookies with SameSite protection and CSRF tokens
92
+ - Platform-specific secure storage (React Native: Keychain/Keystore)
93
+
94
+ **Never:**
95
+ - Store tokens in plain localStorage in production
96
+ - Log tokens to console
97
+ - Embed tokens in URLs
98
+
99
+ ## API Reference
100
+
101
+ ### Authentication
102
+
103
+ ```typescript
104
+ // Register new account
105
+ await client.register({
106
+ username: 'user',
107
+ email: 'user@example.com',
108
+ password: 'secure_password',
109
+ firstName: 'John',
110
+ lastName: 'Doe',
111
+ newsletter: true,
112
+ // Optional fields
113
+ country: 'US',
114
+ institution: 'University',
115
+ profession: 'Researcher',
116
+ unit: 'metric',
117
+ });
118
+
119
+ // Login
120
+ const result = await client.login('username', 'password');
121
+
122
+ // Verify 2FA code
123
+ if (result === 'verification_required') {
124
+ await client.verify('123456', true);
125
+ }
126
+
127
+ // Check authentication status
128
+ const isAuth = await client.isAuthenticated();
129
+
130
+ // Logout
131
+ await client.logout();
132
+
133
+ // Manual token management
134
+ const token = client.getToken();
135
+ client.setToken('your-token');
136
+ ```
137
+
138
+ ### Sessions
139
+
140
+ ```typescript
141
+ // Get all sessions
142
+ const sessions = await client.sessionList();
143
+
144
+ // Get specific session with trials
145
+ const session = await client.getSession('session-id');
146
+
147
+ // Create new session
148
+ const newSession = await client.createSession();
149
+ ```
150
+
151
+ ### Subjects
152
+
153
+ ```typescript
154
+ // Get all subjects
155
+ const subjects = await client.subjectList();
156
+ ```
23
157
 
24
- See the [examples directory](https://github.com/model-health/model-health/tree/main/examples) in the GitHub repository for complete working implementations.
158
+ ### Trials
25
159
 
26
- To run examples locally:
160
+ ```typescript
161
+ // Get trials for a session
162
+ const trials = await client.trialList('session-id');
163
+
164
+ // Download trial videos
165
+ const videos = await client.downloadTrialVideos(
166
+ trial,
167
+ 'raw' // or 'synced'
168
+ );
169
+
170
+ // Download result data
171
+ const results = await client.downloadTrialResultData(
172
+ trial,
173
+ ['motData', 'csvData']
174
+ );
175
+ ```
176
+
177
+ ### Utilities
178
+
179
+ ```typescript
180
+ // Convert MOT to CSV
181
+ const motData = new Uint8Array([...]); // MOT file data
182
+ const csv = ModelHealthService.motToCsv(motData);
183
+ ```
184
+
185
+ ## React Example
186
+
187
+ ```tsx
188
+ import { useState, useEffect } from 'react';
189
+ import { ModelHealthService, Session } from '@modelhealth/sdk';
190
+
191
+ function App() {
192
+ const [client] = useState(() => new ModelHealthService());
193
+ const [sessions, setSessions] = useState<Session[]>([]);
194
+ const [loading, setLoading] = useState(true);
195
+
196
+ useEffect(() => {
197
+ async function init() {
198
+ await client.init();
199
+
200
+ // Try to restore session
201
+ const isAuth = await client.isAuthenticated();
202
+ if (!isAuth) {
203
+ // Redirect to login
204
+ return;
205
+ }
206
+
207
+ // Load sessions
208
+ const data = await client.sessionList();
209
+ setSessions(data);
210
+ setLoading(false);
211
+ }
212
+
213
+ init();
214
+ }, [client]);
215
+
216
+ if (loading) return <div>Loading...</div>;
217
+
218
+ return (
219
+ <div>
220
+ <h1>Sessions</h1>
221
+ {sessions.map(session => (
222
+ <div key={session.id}>{session.name}</div>
223
+ ))}
224
+ </div>
225
+ );
226
+ }
227
+ ```
228
+
229
+ ## Vite Configuration
230
+
231
+ If using Vite, add WASM support:
232
+
233
+ ```typescript
234
+ // vite.config.ts
235
+ import { defineConfig } from 'vite';
236
+ import wasm from 'vite-plugin-wasm';
237
+ import topLevelAwait from 'vite-plugin-top-level-await';
238
+
239
+ export default defineConfig({
240
+ plugins: [
241
+ wasm(),
242
+ topLevelAwait(),
243
+ ],
244
+ });
245
+ ```
246
+
247
+ Install plugins:
27
248
  ```bash
28
- git clone https://github.com/model-health/model-health.git
29
- cd model-health/examples
249
+ npm install -D vite-plugin-wasm vite-plugin-top-level-await
250
+ ```
251
+
252
+ ## TypeScript Types
253
+
254
+ All types are fully documented with JSDoc comments. Import types as needed:
255
+
256
+ ```typescript
257
+ import type {
258
+ Session,
259
+ Subject,
260
+ Trial,
261
+ LoginResult,
262
+ RegistrationParameters,
263
+ CheckerboardDetails,
264
+ // ... etc
265
+ } from '@modelhealth/sdk';
266
+ ```
267
+
268
+ ## Building from Source
269
+
270
+ ```bash
271
+ # Install dependencies
272
+ npm install
273
+
274
+ # Build WASM and TypeScript
275
+ npm run build
276
+
277
+ # Development build with watch mode
278
+ npm run dev
279
+ ```
280
+
281
+ ### Requirements
282
+
283
+ - Node.js 18+
284
+ - Rust 1.70+
285
+ - wasm-pack (`cargo install wasm-pack`)
286
+
287
+ ## Platform Support
288
+
289
+ - ✅ Modern browsers (Chrome, Firefox, Safari, Edge)
290
+ - ✅ Node.js 18+ (with WASM support)
291
+ - ✅ React, Vue, Svelte, Angular
292
+ - ✅ React Native (with WASM bridge)
293
+ - ✅ Electron
294
+
295
+ ## Error Handling
296
+
297
+ All async methods can throw errors. Always use try-catch:
298
+
299
+ ```typescript
300
+ try {
301
+ await client.login('username', 'password');
302
+ } catch (error) {
303
+ console.error('Login failed:', error);
304
+ }
30
305
  ```
31
306
 
32
- ## Swift SDK
307
+ ## License
33
308
 
34
- Looking for the Swift/iOS SDK? See the [main repository](https://github.com/model-health/model-health) for Swift Package Manager installation.
309
+ MIT © Model Health
35
310
 
36
311
  ## Support
37
312
 
38
- - **Issues**: [GitHub Issues](https://github.com/model-health/model-health/issues)
39
- - **Documentation**: [docs.modelhealth.io](https://docs.modelhealth.io)
40
- - **Email**: support@modelhealth.io
313
+ - Documentation: https://docs.modelhealth.io
314
+ - Issues: https://github.com/model-health/model-health/issues
315
+ - Email: support@modelhealth.io
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelhealth/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.7",
4
4
  "description": "Model Health SDK for TypeScript/JavaScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -13,6 +13,13 @@
13
13
  "model_health_wasm_bg.wasm",
14
14
  "model_health_wasm_bg.wasm.d.ts"
15
15
  ],
16
+ "scripts": {
17
+ "build:wasm": "wasm-pack build ../model-health-wasm --target web --out-dir ../../model-health-ts/wasm --scope modelhealth",
18
+ "build:ts": "tsc",
19
+ "build": "npm run build:wasm && npm run build:ts",
20
+ "dev": "npm run build:wasm -- --dev && tsc --watch",
21
+ "clean": "rm -rf dist wasm node_modules"
22
+ },
16
23
  "keywords": [
17
24
  "modelhealth",
18
25
  "biomechanics",
@@ -23,6 +30,11 @@
23
30
  "license": "MIT",
24
31
  "repository": {
25
32
  "type": "git",
26
- "url": "https://github.com/model-health/model-health.git"
33
+ "url": "https://github.com/model-health/model-health"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^20.10.0",
37
+ "typedoc": "^0.28.15",
38
+ "typescript": "^5.3.0"
27
39
  }
28
40
  }
@@ -46,46 +46,49 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
46
46
  export interface InitOutput {
47
47
  readonly memory: WebAssembly.Memory;
48
48
  readonly __wbg_modelhealthservice_free: (a: number, b: number) => void;
49
- readonly calibrateCamera: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
50
- readonly calibrateNeutralPose: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
51
- readonly modelhealthservice_createSession: (a: number) => number;
52
- readonly modelhealthservice_createSubject: (a: number, b: number) => number;
53
- readonly modelhealthservice_deleteActivity: (a: number, b: number) => number;
54
- readonly modelhealthservice_downloadAnalysisResult: (a: number, b: number, c: number, d: number) => number;
55
- readonly modelhealthservice_downloadTrialResultData: (a: number, b: number, c: number) => number;
56
- readonly modelhealthservice_downloadTrialVideos: (a: number, b: number, c: number) => number;
57
- readonly modelhealthservice_getActivitiesForSubject: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
58
- readonly modelhealthservice_getActivity: (a: number, b: number, c: number) => number;
59
- readonly modelhealthservice_getActivityTags: (a: number) => number;
60
- readonly modelhealthservice_getAnalysisStatus: (a: number, b: number) => number;
61
- readonly modelhealthservice_getSession: (a: number, b: number, c: number) => number;
62
- readonly modelhealthservice_getStatus: (a: number, b: number) => number;
63
- readonly modelhealthservice_getToken: (a: number, b: number) => void;
64
- readonly modelhealthservice_isAuthenticated: (a: number) => number;
65
- readonly modelhealthservice_login: (a: number, b: number, c: number, d: number, e: number) => number;
66
- readonly modelhealthservice_logout: (a: number) => number;
67
- readonly modelhealthservice_new: (a: number, b: number, c: number) => void;
68
- readonly modelhealthservice_record: (a: number, b: number, c: number, d: number) => number;
69
- readonly modelhealthservice_register: (a: number, b: number) => number;
70
- readonly modelhealthservice_restoreToken: (a: number) => number;
71
- readonly modelhealthservice_sessionList: (a: number) => number;
72
- readonly modelhealthservice_setStorage: (a: number, b: number) => void;
73
- readonly modelhealthservice_setToken: (a: number, b: number, c: number) => void;
74
- readonly modelhealthservice_startAnalysis: (a: number, b: number, c: number, d: number) => number;
75
- readonly modelhealthservice_stopRecording: (a: number, b: number) => number;
76
- readonly modelhealthservice_subjectList: (a: number) => number;
77
- readonly modelhealthservice_trialList: (a: number, b: number, c: number) => number;
78
- readonly modelhealthservice_updateActivity: (a: number, b: number) => number;
79
- readonly modelhealthservice_verify: (a: number, b: number, c: number, d: number) => number;
49
+ readonly calibrateCamera: (a: number, b: number, c: number, d: number, e: any, f: any, g: any) => any;
50
+ readonly calibrateNeutralPose: (a: number, b: number, c: number, d: number, e: any, f: any, g: any) => any;
80
51
  readonly init: () => void;
81
- readonly __wasm_bindgen_func_elem_883: (a: number, b: number) => void;
82
- readonly __wasm_bindgen_func_elem_1271: (a: number, b: number, c: number, d: number) => void;
83
- readonly __wasm_bindgen_func_elem_884: (a: number, b: number, c: number) => void;
84
- readonly __wbindgen_export: (a: number, b: number) => number;
85
- readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
86
- readonly __wbindgen_export3: (a: number) => void;
87
- readonly __wbindgen_export4: (a: number, b: number, c: number) => void;
88
- readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
52
+ readonly modelhealthservice_createSession: (a: number) => any;
53
+ readonly modelhealthservice_createSubject: (a: number, b: any) => any;
54
+ readonly modelhealthservice_deleteActivity: (a: number, b: any) => any;
55
+ readonly modelhealthservice_downloadAnalysisResult: (a: number, b: any, c: number, d: number) => any;
56
+ readonly modelhealthservice_downloadTrialResultData: (a: number, b: any, c: any) => any;
57
+ readonly modelhealthservice_downloadTrialVideos: (a: number, b: any, c: any) => any;
58
+ readonly modelhealthservice_getActivitiesForSubject: (a: number, b: number, c: number, d: number, e: number, f: any) => any;
59
+ readonly modelhealthservice_getActivity: (a: number, b: number, c: number) => any;
60
+ readonly modelhealthservice_getActivityTags: (a: number) => any;
61
+ readonly modelhealthservice_getAnalysisStatus: (a: number, b: any) => any;
62
+ readonly modelhealthservice_getSession: (a: number, b: number, c: number) => any;
63
+ readonly modelhealthservice_getStatus: (a: number, b: any) => any;
64
+ readonly modelhealthservice_getToken: (a: number) => [number, number];
65
+ readonly modelhealthservice_isAuthenticated: (a: number) => any;
66
+ readonly modelhealthservice_login: (a: number, b: number, c: number, d: number, e: number) => any;
67
+ readonly modelhealthservice_logout: (a: number) => any;
68
+ readonly modelhealthservice_new: (a: number, b: number) => [number, number, number];
69
+ readonly modelhealthservice_record: (a: number, b: number, c: number, d: any) => any;
70
+ readonly modelhealthservice_register: (a: number, b: any) => any;
71
+ readonly modelhealthservice_restoreToken: (a: number) => any;
72
+ readonly modelhealthservice_sessionList: (a: number) => any;
73
+ readonly modelhealthservice_setStorage: (a: number, b: any) => void;
74
+ readonly modelhealthservice_setToken: (a: number, b: number, c: number) => void;
75
+ readonly modelhealthservice_startAnalysis: (a: number, b: any, c: any, d: any) => any;
76
+ readonly modelhealthservice_stopRecording: (a: number, b: any) => any;
77
+ readonly modelhealthservice_subjectList: (a: number) => any;
78
+ readonly modelhealthservice_trialList: (a: number, b: number, c: number) => any;
79
+ readonly modelhealthservice_updateActivity: (a: number, b: any) => any;
80
+ readonly modelhealthservice_verify: (a: number, b: number, c: number, d: number) => any;
81
+ readonly wasm_bindgen__closure__destroy__ha71e9a94fc0225d6: (a: number, b: number) => void;
82
+ readonly wasm_bindgen__convert__closures_____invoke__haaf7ae974232f393: (a: number, b: number, c: any, d: any) => void;
83
+ readonly wasm_bindgen__convert__closures_____invoke__hb3dc8239211a7dce: (a: number, b: number, c: any) => void;
84
+ readonly wasm_bindgen__convert__closures_____invoke__h34a416afb1ff4b4f: (a: number, b: number) => number;
85
+ readonly __wbindgen_malloc: (a: number, b: number) => number;
86
+ readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
87
+ readonly __wbindgen_exn_store: (a: number) => void;
88
+ readonly __externref_table_alloc: () => number;
89
+ readonly __wbindgen_externrefs: WebAssembly.Table;
90
+ readonly __wbindgen_free: (a: number, b: number, c: number) => void;
91
+ readonly __externref_table_dealloc: (a: number) => void;
89
92
  readonly __wbindgen_start: () => void;
90
93
  }
91
94