@moveris/shared 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +453 -11
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,25 +1,467 @@
1
1
  # @moveris/shared
2
2
 
3
- Core business logic for Moveris Live SDK. This package contains:
4
-
5
- - WebSocket client with reconnection logic
6
- - Frame buffer management
7
- - Authentication manager
8
- - Type definitions
9
- - Utility functions
3
+ Core business logic for Moveris Live SDK. This package provides the HTTP client, types, utilities, and frame management for liveness detection.
10
4
 
11
5
  ## Installation
12
6
 
13
7
  ```bash
14
8
  pnpm add @moveris/shared
9
+ # or
10
+ npm install @moveris/shared
11
+ # or
12
+ yarn add @moveris/shared
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { LivenessClient, generateSessionId } from '@moveris/shared';
19
+
20
+ // Create the client
21
+ const client = new LivenessClient({
22
+ apiKey: 'mv_your_api_key',
23
+ baseUrl: 'https://api.moveris.io', // optional, uses default
24
+ });
25
+
26
+ // Perform a fast liveness check
27
+ const result = await client.fastCheck(frames, {
28
+ model: '10',
29
+ source: 'live',
30
+ });
31
+
32
+ console.log(result.verdict); // 'live' or 'fake'
33
+ console.log(result.confidence); // 0-1
34
+ console.log(result.score); // 0-100
35
+ ```
36
+
37
+ ## API Reference
38
+
39
+ ### LivenessClient
40
+
41
+ The main client for interacting with the Moveris Liveness API.
42
+
43
+ #### Constructor
44
+
45
+ ```typescript
46
+ const client = new LivenessClient(config: LivenessClientConfig);
47
+ ```
48
+
49
+ | Option | Type | Default | Description |
50
+ | ------------- | -------------- | -------------------------- | ----------------------------------------------- |
51
+ | `apiKey` | `string` | **required** | Your Moveris API key |
52
+ | `baseUrl` | `string` | `'https://api.moveris.io'` | API base URL |
53
+ | `timeout` | `number` | `30000` | Request timeout in milliseconds |
54
+ | `enableRetry` | `boolean` | `true` | Enable automatic retry with exponential backoff |
55
+ | `customFetch` | `typeof fetch` | `fetch` | Custom fetch implementation (for React Native) |
56
+
57
+ #### Methods
58
+
59
+ ##### `fastCheck(frames, options)`
60
+
61
+ Perform fast liveness check with server-side face detection. Ideal for quick verification with 10-250 frames.
62
+
63
+ ```typescript
64
+ const result = await client.fastCheck(frames, {
65
+ sessionId: 'optional-uuid',
66
+ model: '10', // '10' | '50' | '250'
67
+ source: 'live', // 'live' | 'media'
68
+ });
69
+ ```
70
+
71
+ **Parameters:**
72
+
73
+ | Option | Type | Default | Description |
74
+ | ----------- | ---------------- | -------------- | ----------------------------------------------------------------------- |
75
+ | `sessionId` | `string` | auto-generated | Unique session identifier (UUID) |
76
+ | `model` | `FastCheckModel` | `'10'` | Model to use: `'10'` (fast), `'50'` (balanced), `'250'` (high-accuracy) |
77
+ | `source` | `FrameSource` | `'live'` | Frame source: `'live'` (camera) or `'media'` (recorded video) |
78
+
79
+ **Returns:** `Promise<LivenessResult>`
80
+
81
+ ##### `fastCheckCrops(crops, options)`
82
+
83
+ Perform fast liveness check with pre-cropped 224x224 face images. Use this when you handle face detection client-side.
84
+
85
+ ```typescript
86
+ const result = await client.fastCheckCrops(crops, {
87
+ model: '50',
88
+ });
89
+ ```
90
+
91
+ ##### `verify(frames, options)`
92
+
93
+ Verify liveness using spatial feature-based detection. Requires minimum 50 frames.
94
+
95
+ ```typescript
96
+ const result = await client.verify(frames, {
97
+ fps: 30,
98
+ frameWidth: 640,
99
+ frameHeight: 480,
100
+ });
101
+ ```
102
+
103
+ ##### `hybridCheck(frames, options)`
104
+
105
+ Perform hybrid liveness check combining CNN with physiological features. Requires minimum 50 frames.
106
+
107
+ ```typescript
108
+ const result = await client.hybridCheck(frames, { fps: 30 });
109
+ ```
110
+
111
+ ##### `hybrid50(frames, options)`
112
+
113
+ 50-frame hybrid model with 93.8% balanced accuracy.
114
+
115
+ ```typescript
116
+ const result = await client.hybrid50(frames, { fps: 30 });
117
+ ```
118
+
119
+ ##### `hybrid150(frames, options)`
120
+
121
+ 150-frame hybrid model with 96.2% balanced accuracy. Best for high-security scenarios.
122
+
123
+ ```typescript
124
+ const result = await client.hybrid150(frames, { fps: 30 });
125
+ ```
126
+
127
+ ##### `health()`
128
+
129
+ Check API health status.
130
+
131
+ ```typescript
132
+ const health = await client.health();
133
+ console.log(health.status); // 'ok'
134
+ console.log(health.models_loaded); // ['10', '50', '250']
135
+ ```
136
+
137
+ ##### `getJobResult(jobId)`
138
+
139
+ Get job status for async processing.
140
+
141
+ ```typescript
142
+ const job = await client.getJobResult('job-uuid');
143
+ console.log(job.status); // 'queued' | 'processing' | 'complete' | 'failed'
144
+ ```
145
+
146
+ ##### `waitForJobResult(jobId, timeout)`
147
+
148
+ Long-poll for job completion (max 120 seconds).
149
+
150
+ ```typescript
151
+ const job = await client.waitForJobResult('job-uuid', 30);
152
+ ```
153
+
154
+ ---
155
+
156
+ ### Types
157
+
158
+ #### FastCheckModel
159
+
160
+ Model selection for liveness detection speed/accuracy trade-off.
161
+
162
+ ```typescript
163
+ type FastCheckModel = '10' | '50' | '250';
164
+ ```
165
+
166
+ | Value | Frames | Description |
167
+ | ------- | ------ | --------------------------------- |
168
+ | `'10'` | 10 | Fast verification, lowest latency |
169
+ | `'50'` | 50 | Balanced speed and accuracy |
170
+ | `'250'` | 250 | Highest accuracy, slower |
171
+
172
+ #### FrameSource
173
+
174
+ Source of the captured frames.
175
+
176
+ ```typescript
177
+ type FrameSource = 'media' | 'live';
178
+ ```
179
+
180
+ | Value | Description |
181
+ | --------- | ----------------------- |
182
+ | `'live'` | Real-time camera feed |
183
+ | `'media'` | Pre-recorded video file |
184
+
185
+ #### Verdict
186
+
187
+ Liveness determination result.
188
+
189
+ ```typescript
190
+ type Verdict = 'live' | 'fake';
191
+ ```
192
+
193
+ | Value | Description |
194
+ | -------- | ---------------------------------------------------- |
195
+ | `'live'` | Real person detected |
196
+ | `'fake'` | Spoofing attempt detected (photo, video, mask, etc.) |
197
+
198
+ #### LivenessState
199
+
200
+ State machine for liveness detection flow.
201
+
202
+ ```typescript
203
+ type LivenessState =
204
+ | 'idle' // Ready to start
205
+ | 'capturing' // Capturing frames from camera
206
+ | 'uploading' // Uploading frames to API
207
+ | 'processing' // API is processing frames
208
+ | 'complete' // Verification complete
209
+ | 'error'; // Error occurred
210
+ ```
211
+
212
+ #### LivenessResult
213
+
214
+ Result returned from liveness verification.
215
+
216
+ ```typescript
217
+ interface LivenessResult {
218
+ verdict: Verdict; // 'live' or 'fake'
219
+ confidence: number; // Confidence score (0-1)
220
+ score: number; // Liveness score (0-100)
221
+ sessionId: string; // Session identifier
222
+ processingMs: number; // Server processing time
223
+ framesProcessed: number; // Number of frames analyzed
224
+ }
225
+ ```
226
+
227
+ #### CapturedFrame
228
+
229
+ Individual frame captured from camera.
230
+
231
+ ```typescript
232
+ interface CapturedFrame {
233
+ index: number; // Frame sequence number (0-based)
234
+ timestampMs: number; // Timestamp from capture start
235
+ pixels: string; // Base64-encoded image data
236
+ }
237
+ ```
238
+
239
+ ---
240
+
241
+ ### Utilities
242
+
243
+ #### `generateSessionId()`
244
+
245
+ Generate a UUID v4 for session identification.
246
+
247
+ ```typescript
248
+ import { generateSessionId } from '@moveris/shared';
249
+
250
+ const sessionId = generateSessionId();
251
+ // e.g., 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d'
252
+ ```
253
+
254
+ #### `toFrameData(frames)`
255
+
256
+ Convert CapturedFrame array to API format.
257
+
258
+ ```typescript
259
+ import { toFrameData } from '@moveris/shared';
260
+
261
+ const apiFrames = toFrameData(capturedFrames);
15
262
  ```
16
263
 
17
- ## Usage
264
+ #### `toHybridFrameData(frames)`
265
+
266
+ Convert frames to hybrid endpoint format.
18
267
 
19
268
  ```typescript
20
- import { WebSocketClient, FrameBuffer, AuthManager } from '@moveris/shared';
269
+ import { toHybridFrameData } from '@moveris/shared';
270
+
271
+ const hybridFrames = toHybridFrameData(capturedFrames);
21
272
  ```
22
273
 
23
- ## API
274
+ ---
275
+
276
+ ### Frame Buffer Management
277
+
278
+ #### FrameBuffer
279
+
280
+ Manages a sliding window buffer of frames with automatic cleanup.
281
+
282
+ ```typescript
283
+ import { FrameBuffer } from '@moveris/shared';
284
+
285
+ const buffer = new FrameBuffer({
286
+ maxSize: 10, // Maximum frames to keep
287
+ maxMemoryBytes: 4 * 1024 * 1024, // 4MB limit
288
+ });
289
+
290
+ // Add frames
291
+ buffer.add(frame);
292
+
293
+ // Get all frames
294
+ const frames = buffer.getAll();
295
+
296
+ // Acknowledge processed frames
297
+ buffer.acknowledge(5); // Remove frames up to index 5
298
+
299
+ // Clear buffer
300
+ buffer.clear();
301
+ ```
302
+
303
+ #### FrameQueue
304
+
305
+ FIFO queue for frame processing.
306
+
307
+ ```typescript
308
+ import { FrameQueue } from '@moveris/shared';
309
+
310
+ const queue = new FrameQueue({ maxSize: 50 });
311
+
312
+ queue.enqueue(frame);
313
+ const frame = queue.dequeue();
314
+ const peeked = queue.peek();
315
+ ```
316
+
317
+ ---
318
+
319
+ ### Error Handling
320
+
321
+ #### LivenessApiError
322
+
323
+ Custom error class for API errors.
324
+
325
+ ```typescript
326
+ import { LivenessApiError } from '@moveris/shared';
327
+
328
+ try {
329
+ await client.fastCheck(frames);
330
+ } catch (error) {
331
+ if (error instanceof LivenessApiError) {
332
+ console.log(error.code); // 'insufficient_frames'
333
+ console.log(error.message); // 'Not enough frames provided'
334
+ console.log(error.statusCode); // 400
335
+ console.log(error.required); // 10
336
+ console.log(error.received); // 5
337
+ }
338
+ }
339
+ ```
340
+
341
+ **Error Codes:**
342
+
343
+ | Code | Description |
344
+ | --------------------- | -------------------------- |
345
+ | `insufficient_frames` | Not enough frames provided |
346
+ | `invalid_model` | Invalid model specified |
347
+ | `invalid_key` | Invalid API key |
348
+ | `missing_field` | Required field missing |
349
+ | `timeout` | Request timeout |
350
+ | `network_error` | Network connectivity issue |
351
+
352
+ ---
353
+
354
+ ### Feedback Messages
355
+
356
+ Localized user feedback for liveness detection UI.
357
+
358
+ ```typescript
359
+ import { getFeedbackMessage, getStatusMessage, DEFAULT_LOCALE, ES_LOCALE } from '@moveris/shared';
360
+
361
+ // Get localized feedback
362
+ const message = getFeedbackMessage('face_not_centered', ES_LOCALE);
363
+ // "Centra tu rostro en el óvalo"
364
+
365
+ // Get status message
366
+ const status = getStatusMessage('capturing', DEFAULT_LOCALE);
367
+ // "Hold still..."
368
+ ```
369
+
370
+ #### Feedback Keys
371
+
372
+ | Key | English | Description |
373
+ | ------------------- | ------------------------------ | ---------------------------- |
374
+ | `no_face` | "No face detected" | Face detection failed |
375
+ | `face_not_centered` | "Center your face in the oval" | Face outside guide |
376
+ | `too_close` | "Move back a little" | Face too close to camera |
377
+ | `too_far` | "Move closer" | Face too far from camera |
378
+ | `poor_lighting` | "Improve lighting" | Insufficient light |
379
+ | `hold_still` | "Hold still" | Movement detected |
380
+ | `capturing` | "Capturing..." | Frame capture in progress |
381
+ | `processing` | "Processing..." | API verification in progress |
382
+ | `success` | "Verification complete" | Successful completion |
383
+ | `failed` | "Verification failed" | Failed verification |
384
+
385
+ ---
386
+
387
+ ### Oval Guide States
388
+
389
+ Visual feedback states for the face positioning guide.
390
+
391
+ ```typescript
392
+ import { getOvalGuideState, OVAL_GUIDE_COLORS } from '@moveris/shared';
393
+
394
+ const state = getOvalGuideState(alignmentScore);
395
+ // Returns: 'no_face' | 'poor' | 'good' | 'perfect'
396
+
397
+ const color = OVAL_GUIDE_COLORS[state];
398
+ // 'red' | 'orange' | 'yellow' | 'green'
399
+ ```
400
+
401
+ | State | Color | Alignment Score |
402
+ | --------- | ------ | ---------------- |
403
+ | `no_face` | Red | No face detected |
404
+ | `poor` | Orange | < 0.5 |
405
+ | `good` | Yellow | 0.5 - 0.8 |
406
+ | `perfect` | Green | > 0.8 |
407
+
408
+ ---
409
+
410
+ ### Frame Analysis Utilities
411
+
412
+ Utilities for assessing frame quality before submission.
413
+
414
+ ```typescript
415
+ import { isFaceFullyVisible, isFaceInOval, calculateFaceCropRegion } from '@moveris/shared';
416
+
417
+ // Check if face is fully visible in frame
418
+ const visibility = isFaceFullyVisible(faceBbox, frameWidth, frameHeight);
419
+ console.log(visibility.isVisible); // true/false
420
+ console.log(visibility.reason); // 'left_edge' | 'top_edge' | etc.
421
+
422
+ // Check if face is within the oval guide
423
+ const inOval = isFaceInOval(faceBbox, ovalRegion);
424
+ console.log(inOval.isInOval); // true/false
425
+ console.log(inOval.alignmentScore); // 0-1
426
+
427
+ // Calculate crop region for face
428
+ const cropRegion = calculateFaceCropRegion(faceBbox, frameWidth, frameHeight);
429
+ ```
430
+
431
+ ---
432
+
433
+ ## Configuration Constants
434
+
435
+ ```typescript
436
+ import { DEFAULT_ENDPOINT, AUTH_CONFIG, RETRY_CONFIG, FRAME_CONFIG } from '@moveris/shared';
437
+
438
+ console.log(DEFAULT_ENDPOINT); // 'https://api.moveris.io'
439
+ console.log(AUTH_CONFIG.apiKeyHeader); // 'X-API-Key'
440
+ console.log(RETRY_CONFIG.maxAttempts); // 3
441
+ console.log(FRAME_CONFIG.maxBufferSize); // 10
442
+ ```
443
+
444
+ ---
445
+
446
+ ## TypeScript Support
447
+
448
+ This package is written in TypeScript and provides full type definitions.
449
+
450
+ ```typescript
451
+ import type {
452
+ LivenessResult,
453
+ LivenessState,
454
+ LivenessConfig,
455
+ FastCheckModel,
456
+ FrameSource,
457
+ Verdict,
458
+ CapturedFrame,
459
+ LivenessClientConfig,
460
+ } from '@moveris/shared';
461
+ ```
462
+
463
+ ---
464
+
465
+ ## License
24
466
 
25
- See [API Documentation](../../docs/api-reference.md#shared-package) for complete API reference.
467
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moveris/shared",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Core business logic for Moveris Live SDK",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",