@incodetech/core 2.0.0-alpha.2 → 2.0.0-alpha.3

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 (134) hide show
  1. package/package.json +4 -1
  2. package/.turbo/turbo-build.log +0 -33
  3. package/.turbo/turbo-coverage.log +0 -22
  4. package/.turbo/turbo-format.log +0 -6
  5. package/.turbo/turbo-lint$colon$fix.log +0 -77
  6. package/.turbo/turbo-lint.log +0 -95
  7. package/.turbo/turbo-test.log +0 -870
  8. package/.turbo/turbo-typecheck.log +0 -5
  9. package/coverage/base.css +0 -224
  10. package/coverage/block-navigation.js +0 -87
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/index.html +0 -221
  13. package/coverage/prettify.css +0 -1
  14. package/coverage/prettify.js +0 -2
  15. package/coverage/sort-arrow-sprite.png +0 -0
  16. package/coverage/sorter.js +0 -210
  17. package/coverage/src/camera/cameraService.ts.html +0 -580
  18. package/coverage/src/camera/cameraServices.ts.html +0 -163
  19. package/coverage/src/camera/cameraStateMachine.ts.html +0 -877
  20. package/coverage/src/camera/index.html +0 -146
  21. package/coverage/src/email/emailActor.ts.html +0 -130
  22. package/coverage/src/email/emailManager.ts.html +0 -1366
  23. package/coverage/src/email/emailStateMachine.ts.html +0 -1186
  24. package/coverage/src/email/index.html +0 -146
  25. package/coverage/src/flow/flowActor.ts.html +0 -124
  26. package/coverage/src/flow/flowAnalyzer.ts.html +0 -196
  27. package/coverage/src/flow/flowManager.ts.html +0 -790
  28. package/coverage/src/flow/flowServices.ts.html +0 -124
  29. package/coverage/src/flow/flowStateMachine.ts.html +0 -631
  30. package/coverage/src/flow/index.html +0 -221
  31. package/coverage/src/flow/moduleLoader.ts.html +0 -304
  32. package/coverage/src/flow/orchestratedFlowManager.ts.html +0 -778
  33. package/coverage/src/flow/orchestratedFlowStateMachine.ts.html +0 -1060
  34. package/coverage/src/http/api.ts.html +0 -355
  35. package/coverage/src/http/endpoints.ts.html +0 -136
  36. package/coverage/src/http/index.html +0 -131
  37. package/coverage/src/index.html +0 -116
  38. package/coverage/src/phone/index.html +0 -146
  39. package/coverage/src/phone/phoneActor.ts.html +0 -130
  40. package/coverage/src/phone/phoneManager.ts.html +0 -1459
  41. package/coverage/src/phone/phoneStateMachine.ts.html +0 -1351
  42. package/coverage/src/recordings/index.html +0 -116
  43. package/coverage/src/recordings/recordingsRepository.ts.html +0 -229
  44. package/coverage/src/selfie/index.html +0 -191
  45. package/coverage/src/selfie/selfieActor.ts.html +0 -136
  46. package/coverage/src/selfie/selfieErrorUtils.ts.html +0 -283
  47. package/coverage/src/selfie/selfieManager.ts.html +0 -988
  48. package/coverage/src/selfie/selfieStateMachine.ts.html +0 -2497
  49. package/coverage/src/selfie/selfieUploadService.ts.html +0 -328
  50. package/coverage/src/selfie/types.ts.html +0 -394
  51. package/coverage/src/setup.ts.html +0 -598
  52. package/src/camera/cameraActor.ts +0 -21
  53. package/src/camera/cameraService.test.ts +0 -437
  54. package/src/camera/cameraService.ts +0 -165
  55. package/src/camera/cameraServices.test.ts +0 -66
  56. package/src/camera/cameraServices.ts +0 -26
  57. package/src/camera/cameraStateMachine.test.ts +0 -602
  58. package/src/camera/cameraStateMachine.ts +0 -264
  59. package/src/camera/index.ts +0 -5
  60. package/src/camera/types.ts +0 -17
  61. package/src/device/getBrowser.ts +0 -31
  62. package/src/device/getDeviceClass.ts +0 -29
  63. package/src/device/index.ts +0 -2
  64. package/src/email/__mocks__/emailMocks.ts +0 -59
  65. package/src/email/emailActor.ts +0 -15
  66. package/src/email/emailManager.test.ts +0 -573
  67. package/src/email/emailManager.ts +0 -427
  68. package/src/email/emailServices.ts +0 -66
  69. package/src/email/emailStateMachine.test.ts +0 -741
  70. package/src/email/emailStateMachine.ts +0 -367
  71. package/src/email/index.ts +0 -39
  72. package/src/email/types.ts +0 -60
  73. package/src/events/addEvent.ts +0 -20
  74. package/src/events/types.ts +0 -7
  75. package/src/flow/__mocks__/flowMocks.ts +0 -84
  76. package/src/flow/flowActor.ts +0 -13
  77. package/src/flow/flowAnalyzer.test.ts +0 -266
  78. package/src/flow/flowAnalyzer.ts +0 -37
  79. package/src/flow/flowCompletionService.ts +0 -21
  80. package/src/flow/flowManager.test.ts +0 -560
  81. package/src/flow/flowManager.ts +0 -235
  82. package/src/flow/flowServices.test.ts +0 -109
  83. package/src/flow/flowServices.ts +0 -13
  84. package/src/flow/flowStateMachine.test.ts +0 -334
  85. package/src/flow/flowStateMachine.ts +0 -182
  86. package/src/flow/index.ts +0 -21
  87. package/src/flow/moduleLoader.test.ts +0 -136
  88. package/src/flow/moduleLoader.ts +0 -73
  89. package/src/flow/orchestratedFlowManager.test.ts +0 -240
  90. package/src/flow/orchestratedFlowManager.ts +0 -231
  91. package/src/flow/orchestratedFlowStateMachine.test.ts +0 -199
  92. package/src/flow/orchestratedFlowStateMachine.ts +0 -325
  93. package/src/flow/types.ts +0 -434
  94. package/src/http/__mocks__/api.ts +0 -88
  95. package/src/http/api.test.ts +0 -231
  96. package/src/http/api.ts +0 -90
  97. package/src/http/endpoints.ts +0 -17
  98. package/src/index.ts +0 -33
  99. package/src/permissions/index.ts +0 -2
  100. package/src/permissions/permissionServices.ts +0 -31
  101. package/src/permissions/types.ts +0 -3
  102. package/src/phone/__mocks__/phoneMocks.ts +0 -71
  103. package/src/phone/index.ts +0 -39
  104. package/src/phone/phoneActor.ts +0 -15
  105. package/src/phone/phoneManager.test.ts +0 -393
  106. package/src/phone/phoneManager.ts +0 -458
  107. package/src/phone/phoneServices.ts +0 -98
  108. package/src/phone/phoneStateMachine.test.ts +0 -918
  109. package/src/phone/phoneStateMachine.ts +0 -422
  110. package/src/phone/types.ts +0 -83
  111. package/src/recordings/recordingsRepository.test.ts +0 -87
  112. package/src/recordings/recordingsRepository.ts +0 -48
  113. package/src/recordings/streamingEvents.ts +0 -10
  114. package/src/selfie/__mocks__/selfieMocks.ts +0 -26
  115. package/src/selfie/index.ts +0 -14
  116. package/src/selfie/selfieActor.ts +0 -17
  117. package/src/selfie/selfieErrorUtils.test.ts +0 -116
  118. package/src/selfie/selfieErrorUtils.ts +0 -66
  119. package/src/selfie/selfieManager.test.ts +0 -297
  120. package/src/selfie/selfieManager.ts +0 -301
  121. package/src/selfie/selfieServices.ts +0 -362
  122. package/src/selfie/selfieStateMachine.test.ts +0 -283
  123. package/src/selfie/selfieStateMachine.ts +0 -804
  124. package/src/selfie/selfieUploadService.test.ts +0 -90
  125. package/src/selfie/selfieUploadService.ts +0 -81
  126. package/src/selfie/types.ts +0 -103
  127. package/src/session/index.ts +0 -5
  128. package/src/session/sessionService.ts +0 -78
  129. package/src/setup.test.ts +0 -61
  130. package/src/setup.ts +0 -171
  131. package/tsconfig.json +0 -13
  132. package/tsdown.config.ts +0 -22
  133. package/vitest.config.ts +0 -37
  134. package/vitest.setup.ts +0 -135
@@ -1,90 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { uploadSelfie } from './selfieUploadService';
3
- import { FACE_ERROR_CODES } from './types';
4
-
5
- vi.mock('../device', () => ({
6
- getDeviceClass: vi.fn(() => 'desktop'),
7
- }));
8
-
9
- vi.mock('../http/api', () => ({
10
- api: {
11
- post: vi.fn(),
12
- },
13
- }));
14
-
15
- describe('selfieUploadService', () => {
16
- it('returns data on success', async () => {
17
- const { api } = await import('../http/api');
18
- vi.mocked(api.post).mockResolvedValueOnce({
19
- ok: true,
20
- status: 200,
21
- statusText: 'OK',
22
- url: 'x',
23
- headers: {},
24
- data: {
25
- age: 1,
26
- confidence: 0,
27
- hasClosedEyes: false,
28
- hasFaceMask: false,
29
- hasHeadCover: false,
30
- hasLenses: false,
31
- isBright: true,
32
- liveness: true,
33
- imageBase64: '',
34
- sessionStatus: 'ok',
35
- },
36
- });
37
-
38
- await expect(
39
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
40
- ).resolves.toMatchObject({ confidence: 0, sessionStatus: 'ok' });
41
- });
42
-
43
- it('maps HTTP 400 status 4019 to FACE_NOT_FOUND', async () => {
44
- const { api } = await import('../http/api');
45
- vi.mocked(api.post).mockRejectedValueOnce({
46
- ok: false,
47
- status: 400,
48
- data: { status: 4019 },
49
- });
50
-
51
- await expect(
52
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
53
- ).rejects.toThrow(FACE_ERROR_CODES.FACE_NOT_FOUND);
54
- });
55
-
56
- it('maps HTTP 400 with missing backend status to BAD_REQUEST', async () => {
57
- const { api } = await import('../http/api');
58
- vi.mocked(api.post).mockRejectedValueOnce({
59
- ok: false,
60
- status: 400,
61
- data: {},
62
- });
63
-
64
- await expect(
65
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
66
- ).rejects.toThrow(FACE_ERROR_CODES.BAD_REQUEST);
67
- });
68
-
69
- it('maps non-400 HTTP error to SERVER_ERROR', async () => {
70
- const { api } = await import('../http/api');
71
- vi.mocked(api.post).mockRejectedValueOnce({
72
- ok: false,
73
- status: 500,
74
- data: { status: 9999 },
75
- });
76
-
77
- await expect(
78
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
79
- ).rejects.toThrow(FACE_ERROR_CODES.SERVER);
80
- });
81
-
82
- it('maps unknown error shapes to SERVER_ERROR', async () => {
83
- const { api } = await import('../http/api');
84
- vi.mocked(api.post).mockRejectedValueOnce(new Error('boom'));
85
-
86
- await expect(
87
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
88
- ).rejects.toThrow(FACE_ERROR_CODES.SERVER);
89
- });
90
- });
@@ -1,81 +0,0 @@
1
- import type { FaceCoordinates } from '@incodetech/infra';
2
- import { getDeviceClass } from '../device';
3
- import { api } from '../http/api';
4
- import { endpoints } from '../http/endpoints';
5
- import type { FaceErrorCode, SendFaceImageResponse } from './types';
6
- import { FACE_ERROR_CODES } from './types';
7
-
8
- export type UploadSelfieParams = {
9
- encryptedBase64Image: string;
10
- faceCoordinates?: FaceCoordinates;
11
- signal?: AbortSignal;
12
- };
13
-
14
- /**
15
- * Uploads a selfie image to the backend.
16
- */
17
- export async function uploadSelfie({
18
- encryptedBase64Image,
19
- faceCoordinates,
20
- signal,
21
- }: UploadSelfieParams): Promise<SendFaceImageResponse> {
22
- try {
23
- const res = await api.post<SendFaceImageResponse>(
24
- endpoints.selfie,
25
- {
26
- base64Image: encryptedBase64Image,
27
- faceCoordinates: faceCoordinates ?? undefined,
28
- encrypted: true,
29
- clientInfo: { deviceClass: getDeviceClass() },
30
- },
31
- { signal, query: { imageType: 'selfie' } },
32
- );
33
- if (!res.ok) {
34
- throw new Error(
35
- `POST ${endpoints.selfie} failed: ${res.status} ${res.statusText}`,
36
- );
37
- }
38
- return res.data as SendFaceImageResponse;
39
- } catch (error) {
40
- const errorCode = getFaceErrorCodeFromHttpError(error);
41
- if (errorCode) {
42
- throw new Error(errorCode);
43
- }
44
- throw new Error(FACE_ERROR_CODES.SERVER);
45
- }
46
- }
47
-
48
- const getFaceErrorCodeFromHttpError = (
49
- error: unknown,
50
- ): FaceErrorCode | undefined => {
51
- const err = error as {
52
- ok?: boolean;
53
- status?: number;
54
- data?: { status?: number };
55
- };
56
-
57
- if (err.ok !== false || typeof err.status !== 'number') {
58
- return undefined;
59
- }
60
-
61
- if (err.status !== 400) {
62
- return FACE_ERROR_CODES.SERVER;
63
- }
64
-
65
- if (typeof err.data?.status !== 'number') {
66
- return FACE_ERROR_CODES.BAD_REQUEST;
67
- }
68
-
69
- const errorMap: Record<number, FaceErrorCode> = {
70
- 3004: FACE_ERROR_CODES.FACE_NOT_FOUND,
71
- 3005: FACE_ERROR_CODES.FACE_NOT_FOUND,
72
- 3006: FACE_ERROR_CODES.TOO_BLURRY,
73
- 3007: FACE_ERROR_CODES.TOO_DARK,
74
- 4010: FACE_ERROR_CODES.MULTIPLE_FACES,
75
- 4019: FACE_ERROR_CODES.FACE_NOT_FOUND,
76
- 4077: FACE_ERROR_CODES.BAD_PHOTO_QUALITY,
77
- 4078: FACE_ERROR_CODES.FACE_OCCLUDED,
78
- };
79
-
80
- return errorMap[err.data.status] ?? FACE_ERROR_CODES.BAD_REQUEST;
81
- };
@@ -1,103 +0,0 @@
1
- import type {
2
- IRecordingCapability,
3
- RecordingConnection,
4
- } from '@incodetech/infra';
5
-
6
- export type { PermissionResult, PermissionStatus } from '../permissions/types';
7
-
8
- export type SelfieConfig = {
9
- showTutorial: boolean;
10
- showPreview: boolean;
11
- assistedOnboarding: boolean;
12
- enableFaceRecording: boolean;
13
- recording?: {
14
- capability?: IRecordingCapability;
15
- };
16
- autoCaptureTimeout: number;
17
- captureAttempts: number;
18
- validateLenses: boolean;
19
- validateFaceMask: boolean;
20
- validateHeadCover: boolean;
21
- validateClosedEyes: boolean;
22
- validateBrightness: boolean;
23
- deepsightLiveness: 'SINGLE_FRAME' | 'MULTIMODAL' | 'VIDEOLIVENESS';
24
- };
25
-
26
- export type DetectionStatus =
27
- | 'idle'
28
- | 'detecting'
29
- | 'noFace'
30
- | 'tooManyFaces'
31
- | 'tooClose'
32
- | 'tooFar'
33
- | 'blur'
34
- | 'dark'
35
- | 'faceAngle'
36
- | 'headWear'
37
- | 'lenses'
38
- | 'eyesClosed'
39
- | 'faceMask'
40
- | 'centerFace'
41
- | 'manualCapture'
42
- | 'success'
43
- | 'error'
44
- | 'capturing'
45
- | 'getReady'
46
- | 'getReadyFinished'
47
- | 'offline';
48
-
49
- export type SendFaceImageResponse = {
50
- age: number;
51
- confidence: number;
52
- hasClosedEyes: boolean;
53
- hasFaceMask: boolean;
54
- hasHeadCover: boolean;
55
- hasLenses: boolean;
56
- isBright: boolean;
57
- liveness: boolean;
58
- imageBase64: string;
59
- sessionStatus: string;
60
- };
61
-
62
- export const FACE_ERROR_CODES = {
63
- FACE_OCCLUDED: 'FACE_OCCLUDED',
64
- LIVENESS: 'LIVENESS_ERROR',
65
- BRIGHTNESS: 'BRIGHTNESS_ERROR',
66
- LENSES: 'LENSES_ERROR',
67
- MASK: 'MASK_ERROR',
68
- CLOSED_EYES: 'CLOSED_EYES_ERROR',
69
- HEAD_COVER: 'HEAD_COVER_ERROR',
70
- SERVER: 'SERVER_ERROR',
71
- FACE_NOT_FOUND: 'FACE_NOT_FOUND',
72
- MULTIPLE_FACES: 'MULTIPLE_FACES',
73
- TOO_BLURRY: 'TOO_BLURRY_ERROR',
74
- TOO_DARK: 'TOO_DARK_ERROR',
75
- USER_IS_NOT_RECOGNIZED: 'USER_IS_NOT_RECOGNIZED',
76
- SPOOF_ATTEMPT_DETECTED: 'SPOOF_ATTEMPT_DETECTED',
77
- FACE_TOO_DARK: 'FACE_TOO_DARK',
78
- LENSES_DETECTED: 'LENSES_DETECTED',
79
- FACE_MASK_DETECTED: 'FACE_MASK_DETECTED',
80
- CLOSED_EYES_DETECTED: 'CLOSED_EYES_DETECTED',
81
- HEAD_COVER_DETECTED: 'HEAD_COVER_DETECTED',
82
- FACE_CROPPING_FAILED: 'FACE_CROPPING_FAILED',
83
- FACE_TOO_SMALL: 'FACE_TOO_SMALL',
84
- FACE_TOO_BLURRY: 'FACE_TOO_BLURRY',
85
- BAD_PHOTO_QUALITY: 'BAD_PHOTO_QUALITY',
86
- PROCESSING_ERROR: 'PROCESSING_ERROR',
87
- BAD_REQUEST: 'BAD_REQUEST',
88
- NONEXISTENT_CUSTOMER: 'NONEXISTENT_CUSTOMER',
89
- HINT_NOT_PROVIDED: 'HINT_NOT_PROVIDED',
90
- SELFIE_IMAGE_LOW_QUALITY: 'SELFIE_IMAGE_LOW_QUALITY',
91
- } as const;
92
-
93
- export type FaceErrorCode =
94
- (typeof FACE_ERROR_CODES)[keyof typeof FACE_ERROR_CODES];
95
-
96
- export type RecordingSession = {
97
- token: string;
98
- sessionId: string;
99
- videoRecordingId: string;
100
- connection: RecordingConnection;
101
- resolution?: string;
102
- hasAudio: boolean;
103
- };
@@ -1,5 +0,0 @@
1
- export {
2
- type CreateSessionOptions,
3
- createSession,
4
- type Session,
5
- } from './sessionService';
@@ -1,78 +0,0 @@
1
- import { getApi } from '../http/api';
2
- import { endpoints } from '../http/endpoints';
3
-
4
- export type CreateSessionOptions = {
5
- /** The configuration/flow ID from the Incode dashboard */
6
- configurationId: string;
7
- /** External ID to associate with this session */
8
- externalId?: string;
9
- /** External customer ID */
10
- externalCustomerId?: string;
11
- /** Language for the session (e.g., 'en-US', 'es-MX') */
12
- language?: string;
13
- /** Custom fields to attach to the session */
14
- customFields?: Record<string, unknown>;
15
- /** UUID for continuing an existing session */
16
- uuid?: string;
17
- /** Interview ID for continuing an existing interview */
18
- interviewId?: string;
19
- };
20
-
21
- export type Session = {
22
- token: string;
23
- interviewId: string;
24
- uuid?: string;
25
- regulationType?: string;
26
- showMandatoryConsent?: boolean;
27
- };
28
-
29
- /**
30
- * Creates a new onboarding session.
31
- *
32
- * @param apiKey - The API key from the Incode dashboard
33
- * @param options - Session creation options
34
- * @param signal - Optional AbortSignal for request cancellation
35
- * @returns The created session with token
36
- *
37
- * @example
38
- * ```ts
39
- * const session = await createSession('your-api-key', {
40
- * configurationId: 'your-flow-id',
41
- * language: 'en-US',
42
- * });
43
- * console.log(session.token); // Use this token for subsequent API calls
44
- * ```
45
- */
46
- export async function createSession(
47
- apiKey: string,
48
- options: CreateSessionOptions,
49
- signal?: AbortSignal,
50
- ): Promise<Session> {
51
- const res = await getApi().post<Session>(
52
- endpoints.createSession,
53
- {
54
- configurationId: options.configurationId,
55
- externalId: options.externalId,
56
- externalCustomerId: options.externalCustomerId,
57
- language: options.language ?? 'en-US',
58
- customFields: options.customFields,
59
- uuid: options.uuid ?? null,
60
- interviewId: options.interviewId ?? null,
61
- },
62
- {
63
- headers: {
64
- 'x-api-key': apiKey,
65
- 'api-version': '1.0',
66
- },
67
- signal,
68
- },
69
- );
70
-
71
- if (!res.ok) {
72
- throw new Error(
73
- `POST ${endpoints.createSession} failed: ${res.status} ${res.statusText}`,
74
- );
75
- }
76
-
77
- return res.data as Session;
78
- }
package/src/setup.test.ts DELETED
@@ -1,61 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest';
2
- import { getApi, getToken } from './http/api';
3
- import { isConfigured, reset, setup } from './setup';
4
-
5
- describe('setup', () => {
6
- beforeEach(() => {
7
- reset();
8
- });
9
-
10
- describe('setup()', () => {
11
- it('should configure the SDK with apiURL and token', () => {
12
- setup({ apiURL: 'https://api.test.com', token: 'test-token' });
13
-
14
- expect(isConfigured()).toBe(true);
15
- });
16
-
17
- it('should configure the SDK with custom headers', () => {
18
- setup({
19
- apiURL: 'https://api.test.com',
20
- token: 'test-token',
21
- customHeaders: { 'X-Custom': 'value' },
22
- });
23
-
24
- const client = getApi();
25
- expect(client.defaults.headers['X-Custom']).toBe('value');
26
- expect(getToken()).toBe('test-token');
27
- });
28
-
29
- it('should configure the SDK with timeout', () => {
30
- setup({
31
- apiURL: 'https://api.test.com',
32
- token: 'test-token',
33
- timeout: 5000,
34
- });
35
-
36
- expect(isConfigured()).toBe(true);
37
- });
38
- });
39
-
40
- describe('isConfigured()', () => {
41
- it('should return false before setup()', () => {
42
- expect(isConfigured()).toBe(false);
43
- });
44
-
45
- it('should return true after setup()', () => {
46
- setup({ apiURL: 'https://api.test.com', token: 'test-token' });
47
-
48
- expect(isConfigured()).toBe(true);
49
- });
50
- });
51
-
52
- describe('reset()', () => {
53
- it('should reset the SDK', () => {
54
- setup({ apiURL: 'https://api.test.com', token: 'test-token' });
55
- expect(isConfigured()).toBe(true);
56
-
57
- reset();
58
- expect(isConfigured()).toBe(false);
59
- });
60
- });
61
- });
package/src/setup.ts DELETED
@@ -1,171 +0,0 @@
1
- import {
2
- createApi,
3
- type WasmPipeline,
4
- WasmUtilProvider,
5
- warmupWasm,
6
- } from '@incodetech/infra';
7
- import { resetApi, setClient, setToken } from './http/api';
8
-
9
- /**
10
- * WASM warmup configuration.
11
- */
12
- export type WasmConfig = {
13
- /** Path to the WASM binary */
14
- wasmPath: string;
15
- /** Path to the SIMD-optimized WASM binary (optional) */
16
- wasmSimdPath?: string;
17
- /** Path to the WASM glue code */
18
- glueCodePath: string;
19
- /** Whether to use SIMD optimizations (default: true) */
20
- useSimd?: boolean;
21
- /** Which pipelines to preload models for */
22
- pipelines?: WasmPipeline[];
23
- /**
24
- * Base path for ML model files. Models will be loaded from `${modelsBasePath}/${modelFileName}`.
25
- * If not provided, models are expected in a 'models' subdirectory relative to the WASM binary.
26
- */
27
- modelsBasePath?: string;
28
- };
29
-
30
- let wasmConfig: WasmConfig | undefined;
31
-
32
- /**
33
- * Configuration options for the SDK setup.
34
- */
35
- export type SetupOptions = {
36
- /** The base URL for the API */
37
- apiURL: string;
38
- /** The session token for API requests (optional - can be set later or omitted for createSession calls) */
39
- token?: string;
40
- /** Custom headers to include in all requests */
41
- customHeaders?: Record<string, string>;
42
- /** Request timeout in milliseconds */
43
- timeout?: number;
44
- /** Optional WASM warmup config - if provided, preloads WASM and ML models */
45
- wasm?: WasmConfig;
46
- };
47
-
48
- let configured = false;
49
-
50
- /**
51
- * Initializes the SDK with the provided configuration.
52
- * Must be called before using any SDK functionality.
53
- *
54
- * If `wasm` config is provided, this function becomes async and will
55
- * preload WASM binary and ML models. Otherwise, it's synchronous.
56
- *
57
- * @param options - Configuration options for the SDK
58
- *
59
- * @example
60
- * ```ts
61
- * import { setup, createSession } from '@incodetech/core';
62
- *
63
- * // Setup with API URL first (for session creation)
64
- * await setup({ apiURL: 'https://api.incode.com' });
65
- * const session = await createSession('api-key', { configurationId: 'flow-id' });
66
- *
67
- * // Basic setup with token
68
- * await setup({
69
- * apiURL: 'https://api.incode.com',
70
- * token: 'session-token',
71
- * });
72
- *
73
- * // Setup with WASM warmup
74
- * await setup({
75
- * apiURL: 'https://api.incode.com',
76
- * token: 'session-token',
77
- * wasm: {
78
- * wasmPath: '/wasm/ml-wasm.wasm',
79
- * glueCodePath: '/wasm/ml-wasm.js',
80
- * pipelines: ['selfie', 'idCapture'],
81
- * },
82
- * });
83
- * ```
84
- */
85
- export async function setup(options: SetupOptions): Promise<void> {
86
- const client = createApi({
87
- apiURL: options.apiURL,
88
- customHeaders: options.customHeaders,
89
- timeout: options.timeout,
90
- });
91
- setClient(client);
92
- if (options.token) {
93
- setToken(options.token);
94
- }
95
- configured = true;
96
-
97
- if (options.wasm) {
98
- await warmupWasm({
99
- wasmPath: options.wasm.wasmPath,
100
- wasmSimdPath: options.wasm.wasmSimdPath,
101
- glueCodePath: options.wasm.glueCodePath,
102
- useSimd: options.wasm.useSimd,
103
- pipelines: options.wasm.pipelines,
104
- modelsBasePath: options.wasm.modelsBasePath,
105
- });
106
-
107
- const provider = await WasmUtilProvider.getInstance();
108
- await provider.initialize({
109
- wasmPath: options.wasm.wasmPath,
110
- wasmSimdPath: options.wasm.wasmSimdPath,
111
- glueCodePath: options.wasm.glueCodePath,
112
- useSimd: options.wasm.useSimd,
113
- pipelines: options.wasm.pipelines,
114
- modelsBasePath: options.wasm.modelsBasePath,
115
- });
116
- }
117
- }
118
-
119
- /**
120
- * Sets the WASM configuration without performing warmup.
121
- * Useful when WASM warmup is handled separately (e.g., conditionally based on flow).
122
- *
123
- * @param config - WASM configuration to store
124
- */
125
- export function setWasmConfig(config: WasmConfig): void {
126
- wasmConfig = config;
127
- }
128
-
129
- /**
130
- * Initializes WasmUtilProvider with the stored WASM configuration.
131
- * Should be called after warmupWasm() completes when using conditional warmup.
132
- * This ensures image encryption works properly.
133
- *
134
- * @param config - Optional WASM configuration. If not provided, uses the stored config from setWasmConfig().
135
- * @throws Error if no config is provided and none is stored
136
- */
137
- export async function initializeWasmUtil(config?: WasmConfig): Promise<void> {
138
- const wasmConfigToUse = config ?? wasmConfig;
139
- if (!wasmConfigToUse) {
140
- throw new Error(
141
- 'WASM config is required. Provide config parameter or call setWasmConfig() first.',
142
- );
143
- }
144
- const provider = await WasmUtilProvider.getInstance();
145
- await provider.initialize({
146
- wasmPath: wasmConfigToUse.wasmPath,
147
- wasmSimdPath: wasmConfigToUse.wasmSimdPath,
148
- glueCodePath: wasmConfigToUse.glueCodePath,
149
- useSimd: wasmConfigToUse.useSimd,
150
- pipelines: wasmConfigToUse.pipelines,
151
- modelsBasePath: wasmConfigToUse.modelsBasePath,
152
- });
153
- }
154
-
155
- /**
156
- * Checks if the SDK has been configured.
157
- *
158
- * @returns true if setup() has been called, false otherwise
159
- */
160
- export function isConfigured(): boolean {
161
- return configured;
162
- }
163
-
164
- /**
165
- * Resets the SDK configuration. Useful for testing.
166
- */
167
- export function reset(): void {
168
- resetApi();
169
- configured = false;
170
- WasmUtilProvider.resetInstance();
171
- }
package/tsconfig.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "extends": "../config/ts/tsconfig.strict.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "paths": {
6
- "@incodetech/config/*": ["../config/*"],
7
- "@incodetech/infra": ["../infra/src"],
8
- "@incodetech/infra/*": ["../infra/src/*"]
9
- }
10
- },
11
- "include": ["src"],
12
- "exclude": ["node_modules", "dist"]
13
- }
package/tsdown.config.ts DELETED
@@ -1,22 +0,0 @@
1
- import { defineConfig } from 'tsdown';
2
-
3
- export default defineConfig({
4
- format: ['esm'],
5
- dts: {
6
- sourcemap: false,
7
- },
8
- sourcemap: false,
9
- clean: true,
10
- target: 'es2021',
11
- outDir: 'dist',
12
- outExtensions: () => ({ js: '.esm.js', dts: '.d.ts' }),
13
- entry: {
14
- index: 'src/index.ts',
15
- flow: 'src/flow/index.ts',
16
- selfie: 'src/selfie/index.ts',
17
- phone: 'src/phone/index.ts',
18
- email: 'src/email/index.ts',
19
- },
20
- noExternal: ['@incodetech/infra'],
21
- platform: 'browser',
22
- });
package/vitest.config.ts DELETED
@@ -1,37 +0,0 @@
1
- import { dirname, resolve } from 'node:path';
2
- import { fileURLToPath, pathToFileURL } from 'node:url';
3
- import { defineConfig, mergeConfig } from 'vitest/config';
4
-
5
- const __dirname = dirname(fileURLToPath(import.meta.url));
6
- const baseConfigUrl = pathToFileURL(
7
- resolve(__dirname, '../config/vitest/base.ts'),
8
- ).href;
9
- const baseConfig = await import(baseConfigUrl);
10
-
11
- export default mergeConfig(
12
- baseConfig.default,
13
- defineConfig({
14
- resolve: {
15
- alias: {
16
- '@incodetech/config': resolve(__dirname, '../config'),
17
- '@incodetech/infra': resolve(__dirname, '../infra/src'),
18
- },
19
- },
20
- test: {
21
- environment: 'node',
22
- setupFiles: ['./vitest.setup.ts'],
23
- coverage: {
24
- exclude: ['**/__mocks__/**', '**/id/**'],
25
- thresholds: {
26
- // Camera module has async flows that are hard to test reliably
27
- // The state machine transitions happen asynchronously and
28
- // the permission API cannot be easily mocked in Node.js
29
- lines: 45,
30
- functions: 75,
31
- branches: 20,
32
- statements: 45,
33
- },
34
- },
35
- },
36
- }),
37
- );