@incodetech/core 2.0.0-alpha.1 → 2.0.0-alpha.10

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 (106) hide show
  1. package/dist/Manager-BGfxEmyv.d.ts +19 -0
  2. package/dist/OpenViduLogger-BdPfiZO6.esm.js +3 -0
  3. package/dist/OpenViduLogger-CQyDxBvM.esm.js +803 -0
  4. package/dist/StateMachine-DRE1oH2B.d.ts +2 -0
  5. package/dist/addEvent-W0ORK0jT.esm.js +16 -0
  6. package/dist/chunk-C_Yo44FK.esm.js +49 -0
  7. package/dist/email.d.ts +264 -0
  8. package/dist/email.esm.js +479 -0
  9. package/dist/endpoints-BSTFaHYo.esm.js +1706 -0
  10. package/dist/flow.d.ts +578 -0
  11. package/dist/flow.esm.js +628 -0
  12. package/dist/index.d.ts +226 -0
  13. package/dist/index.esm.js +155 -0
  14. package/dist/lib-Bu9XGMBW.esm.js +11700 -0
  15. package/dist/permissionServices-I6vX6DBy.esm.js +72 -0
  16. package/dist/phone.d.ts +292 -0
  17. package/dist/phone.esm.js +550 -0
  18. package/dist/selfie.d.ts +759 -0
  19. package/dist/selfie.esm.js +995 -0
  20. package/dist/types-iZi2rawo.d.ts +5 -0
  21. package/dist/warmup-CEJTfxQr.d.ts +55 -0
  22. package/dist/xstate.esm-B_rda9yU.esm.js +3261 -0
  23. package/package.json +14 -11
  24. package/src/camera/cameraActor.ts +0 -21
  25. package/src/camera/cameraService.test.ts +0 -437
  26. package/src/camera/cameraService.ts +0 -165
  27. package/src/camera/cameraServices.test.ts +0 -66
  28. package/src/camera/cameraServices.ts +0 -26
  29. package/src/camera/cameraStateMachine.test.ts +0 -602
  30. package/src/camera/cameraStateMachine.ts +0 -264
  31. package/src/camera/index.ts +0 -5
  32. package/src/camera/types.ts +0 -17
  33. package/src/device/getBrowser.ts +0 -31
  34. package/src/device/getDeviceClass.ts +0 -29
  35. package/src/device/index.ts +0 -2
  36. package/src/email/__mocks__/emailMocks.ts +0 -59
  37. package/src/email/emailActor.ts +0 -15
  38. package/src/email/emailManager.test.ts +0 -573
  39. package/src/email/emailManager.ts +0 -427
  40. package/src/email/emailServices.ts +0 -66
  41. package/src/email/emailStateMachine.test.ts +0 -741
  42. package/src/email/emailStateMachine.ts +0 -367
  43. package/src/email/index.ts +0 -39
  44. package/src/email/types.ts +0 -60
  45. package/src/events/addEvent.ts +0 -20
  46. package/src/events/types.ts +0 -7
  47. package/src/flow/__mocks__/flowMocks.ts +0 -84
  48. package/src/flow/flowActor.ts +0 -13
  49. package/src/flow/flowAnalyzer.test.ts +0 -266
  50. package/src/flow/flowAnalyzer.ts +0 -37
  51. package/src/flow/flowCompletionService.ts +0 -21
  52. package/src/flow/flowManager.test.ts +0 -560
  53. package/src/flow/flowManager.ts +0 -235
  54. package/src/flow/flowServices.test.ts +0 -109
  55. package/src/flow/flowServices.ts +0 -13
  56. package/src/flow/flowStateMachine.test.ts +0 -334
  57. package/src/flow/flowStateMachine.ts +0 -182
  58. package/src/flow/index.ts +0 -21
  59. package/src/flow/moduleLoader.test.ts +0 -136
  60. package/src/flow/moduleLoader.ts +0 -73
  61. package/src/flow/orchestratedFlowManager.test.ts +0 -240
  62. package/src/flow/orchestratedFlowManager.ts +0 -231
  63. package/src/flow/orchestratedFlowStateMachine.test.ts +0 -199
  64. package/src/flow/orchestratedFlowStateMachine.ts +0 -325
  65. package/src/flow/types.ts +0 -434
  66. package/src/http/__mocks__/api.ts +0 -88
  67. package/src/http/api.test.ts +0 -231
  68. package/src/http/api.ts +0 -90
  69. package/src/http/endpoints.ts +0 -17
  70. package/src/index.ts +0 -33
  71. package/src/permissions/index.ts +0 -2
  72. package/src/permissions/permissionServices.ts +0 -31
  73. package/src/permissions/types.ts +0 -3
  74. package/src/phone/__mocks__/phoneMocks.ts +0 -71
  75. package/src/phone/index.ts +0 -39
  76. package/src/phone/phoneActor.ts +0 -15
  77. package/src/phone/phoneManager.test.ts +0 -393
  78. package/src/phone/phoneManager.ts +0 -458
  79. package/src/phone/phoneServices.ts +0 -98
  80. package/src/phone/phoneStateMachine.test.ts +0 -918
  81. package/src/phone/phoneStateMachine.ts +0 -422
  82. package/src/phone/types.ts +0 -83
  83. package/src/recordings/recordingsRepository.test.ts +0 -87
  84. package/src/recordings/recordingsRepository.ts +0 -48
  85. package/src/recordings/streamingEvents.ts +0 -10
  86. package/src/selfie/__mocks__/selfieMocks.ts +0 -26
  87. package/src/selfie/index.ts +0 -14
  88. package/src/selfie/selfieActor.ts +0 -17
  89. package/src/selfie/selfieErrorUtils.test.ts +0 -116
  90. package/src/selfie/selfieErrorUtils.ts +0 -66
  91. package/src/selfie/selfieManager.test.ts +0 -297
  92. package/src/selfie/selfieManager.ts +0 -301
  93. package/src/selfie/selfieServices.ts +0 -362
  94. package/src/selfie/selfieStateMachine.test.ts +0 -283
  95. package/src/selfie/selfieStateMachine.ts +0 -804
  96. package/src/selfie/selfieUploadService.test.ts +0 -90
  97. package/src/selfie/selfieUploadService.ts +0 -81
  98. package/src/selfie/types.ts +0 -103
  99. package/src/session/index.ts +0 -5
  100. package/src/session/sessionService.ts +0 -78
  101. package/src/setup.test.ts +0 -61
  102. package/src/setup.ts +0 -171
  103. package/tsconfig.json +0 -13
  104. package/tsdown.config.ts +0 -22
  105. package/vitest.config.ts +0 -37
  106. package/vitest.setup.ts +0 -135
@@ -1,804 +0,0 @@
1
- import {
2
- type AnyStateMachine,
3
- assign,
4
- type FaceCoordinates,
5
- type FaceDetectionProvider,
6
- fromCallback,
7
- fromPromise,
8
- type IncodeCanvas,
9
- type StateMachine,
10
- StreamCanvasCapture,
11
- setup,
12
- } from '@incodetech/infra';
13
- import { addEvent } from '../events/addEvent';
14
- import {
15
- checkPermission,
16
- requestPermission,
17
- } from '../permissions/permissionServices';
18
- import {
19
- getFaceErrorCodeFromUnknown,
20
- validateUploadResponse,
21
- } from './selfieErrorUtils';
22
- import {
23
- type CameraStream,
24
- encryptSelfieImage,
25
- initializeCamera,
26
- startDetection,
27
- startRecordingSession,
28
- stopRecording,
29
- stopStream,
30
- uploadSelfie,
31
- } from './selfieServices';
32
- import type {
33
- DetectionStatus,
34
- FaceErrorCode,
35
- PermissionResult,
36
- RecordingSession,
37
- SelfieConfig,
38
- SendFaceImageResponse,
39
- } from './types';
40
- import { FACE_ERROR_CODES } from './types';
41
-
42
- export type SelfieContext = {
43
- config: SelfieConfig;
44
- stream: CameraStream | undefined;
45
- provider: FaceDetectionProvider | undefined;
46
- frameCapturer: StreamCanvasCapture | undefined;
47
- error: string | undefined;
48
- detectionStatus: DetectionStatus;
49
- debugFrame: ImageData | undefined;
50
- capturedImage: IncodeCanvas | undefined;
51
- faceCoordinates: FaceCoordinates | undefined;
52
- uploadResponse: SendFaceImageResponse | undefined;
53
- recordingSession: RecordingSession | undefined;
54
- attemptsRemaining: number;
55
- uploadError: FaceErrorCode | undefined;
56
- permissionResult: PermissionResult | 'refresh' | undefined;
57
- resetDetection: (() => void) | undefined;
58
- };
59
-
60
- export type SelfieEvent =
61
- | { type: 'LOAD' }
62
- | { type: 'NEXT_STEP' }
63
- | { type: 'REQUEST_PERMISSION' }
64
- | { type: 'GO_TO_LEARN_MORE' }
65
- | { type: 'BACK' }
66
- | { type: 'QUIT' }
67
- | { type: 'RESET' }
68
- | { type: 'MANUAL_CAPTURE' }
69
- | { type: 'DETECTION_UPDATE'; status: DetectionStatus }
70
- | { type: 'DETECTION_FRAME'; frame: ImageData }
71
- | {
72
- type: 'DETECTION_SUCCESS';
73
- canvas: IncodeCanvas;
74
- faceCoordinates?: FaceCoordinates;
75
- }
76
- | { type: 'DETECTION_RESET_READY'; reset: () => void }
77
- | { type: 'RETRY_CAPTURE' };
78
-
79
- export type SelfieInput = {
80
- config: SelfieConfig;
81
- };
82
-
83
- const _selfieMachine = setup({
84
- types: {
85
- context: {} as SelfieContext,
86
- events: {} as SelfieEvent,
87
- input: {} as SelfieInput,
88
- },
89
- actors: {
90
- checkPermission: fromPromise<PermissionResult, void>(async () => {
91
- return checkPermission();
92
- }),
93
- requestPermission: fromPromise<PermissionResult, void>(async () => {
94
- return requestPermission();
95
- }),
96
- initializeCamera: fromPromise<
97
- { stream: CameraStream; provider: FaceDetectionProvider },
98
- SelfieConfig
99
- >(async ({ input }) => {
100
- return initializeCamera(input);
101
- }),
102
- runDetection: fromCallback<
103
- SelfieEvent,
104
- {
105
- frameCapturer: StreamCanvasCapture | undefined;
106
- provider: FaceDetectionProvider | undefined;
107
- config: SelfieConfig;
108
- }
109
- >(({ input, sendBack }) => {
110
- if (!input.frameCapturer || !input.provider) {
111
- sendBack({ type: 'DETECTION_UPDATE', status: 'error' });
112
- return () => {};
113
- }
114
- const { cleanup, reset } = startDetection({
115
- config: input.config,
116
- capturer: input.frameCapturer,
117
- onUpdate: (status: DetectionStatus) =>
118
- sendBack({ type: 'DETECTION_UPDATE', status }),
119
- onFrame: (frame: ImageData) =>
120
- sendBack({ type: 'DETECTION_FRAME', frame }),
121
- onSuccess: (canvas: IncodeCanvas, faceCoordinates?: FaceCoordinates) =>
122
- sendBack({ type: 'DETECTION_SUCCESS', canvas, faceCoordinates }),
123
- provider: input.provider,
124
- });
125
- sendBack({ type: 'DETECTION_RESET_READY', reset });
126
- return cleanup;
127
- }),
128
- uploadSelfie: fromPromise<
129
- SendFaceImageResponse,
130
- { canvas: IncodeCanvas; faceCoordinates?: FaceCoordinates }
131
- >(async ({ input, signal }) => {
132
- const encryptedBase64Image = await encryptSelfieImage({
133
- canvas: input.canvas,
134
- });
135
- return uploadSelfie({
136
- encryptedBase64Image,
137
- faceCoordinates: input.faceCoordinates,
138
- signal,
139
- });
140
- }),
141
- startRecording: fromPromise<
142
- RecordingSession | undefined,
143
- {
144
- config: SelfieConfig;
145
- stream: CameraStream | undefined;
146
- existing?: RecordingSession;
147
- }
148
- >(async ({ input }) => {
149
- if (!input.stream) {
150
- return undefined;
151
- }
152
- return startRecordingSession({
153
- config: input.config,
154
- stream: input.stream,
155
- existing: input.existing,
156
- });
157
- }),
158
- },
159
- actions: {
160
- stopMediaStream: assign(({ context }) => {
161
- context.frameCapturer?.dispose();
162
- if (context.stream) {
163
- stopStream(context.stream);
164
- }
165
- void context.provider?.dispose();
166
- return {
167
- stream: undefined,
168
- provider: undefined,
169
- frameCapturer: undefined,
170
- };
171
- }),
172
- setStreamAndCapturer: assign({
173
- stream: ({ event }) => {
174
- if ('output' in event) {
175
- return (event.output as { stream: CameraStream }).stream;
176
- }
177
- return undefined;
178
- },
179
- provider: ({ event }) => {
180
- if ('output' in event) {
181
- return (event.output as { provider: FaceDetectionProvider }).provider;
182
- }
183
- return undefined;
184
- },
185
- frameCapturer: ({ event }) => {
186
- if ('output' in event) {
187
- return new StreamCanvasCapture(
188
- (event.output as { stream: CameraStream }).stream,
189
- );
190
- }
191
- return undefined;
192
- },
193
- }),
194
- trackTutorialSelfie: () => {
195
- addEvent({
196
- code: 'tutorialSelfie',
197
- payload: { tutorialSelfie: true },
198
- });
199
- },
200
- trackContinue: () => {
201
- addEvent({
202
- code: 'continue',
203
- });
204
- },
205
- resetContext: assign(({ context }) => ({
206
- stream: undefined,
207
- provider: undefined,
208
- frameCapturer: undefined,
209
- error: undefined,
210
- detectionStatus: 'idle' as DetectionStatus,
211
- debugFrame: undefined,
212
- capturedImage: undefined,
213
- faceCoordinates: undefined,
214
- uploadResponse: undefined,
215
- recordingSession: undefined,
216
- attemptsRemaining: context.config.captureAttempts,
217
- uploadError: undefined,
218
- permissionResult: undefined,
219
- resetDetection: undefined,
220
- })),
221
- resetDetection: ({ context }) => {
222
- context.resetDetection?.();
223
- },
224
- captureImage: assign({
225
- capturedImage: ({ context }) => {
226
- if (context.capturedImage) {
227
- return context.capturedImage;
228
- }
229
- return context.frameCapturer?.getLatestCanvas() ?? undefined;
230
- },
231
- }),
232
- captureLatestFrame: assign({
233
- capturedImage: ({ context }) => {
234
- return context.frameCapturer?.getLatestCanvas() ?? undefined;
235
- },
236
- }),
237
- clearUploadFailure: assign({
238
- uploadError: () => undefined,
239
- detectionStatus: () => 'idle' as DetectionStatus,
240
- capturedImage: () => undefined,
241
- }),
242
- decrementAttemptsRemaining: assign(({ context }) => ({
243
- attemptsRemaining: context.attemptsRemaining - 1,
244
- })),
245
- setUploadErrorFromUploadValidation: assign({
246
- uploadError: ({ context }) =>
247
- validateUploadResponse({
248
- config: context.config,
249
- response: context.uploadResponse,
250
- }) ?? FACE_ERROR_CODES.SERVER,
251
- }),
252
- stopMediaRecording: ({ context }) => {
253
- if (context.recordingSession) {
254
- stopRecording(context.recordingSession);
255
- }
256
- },
257
- clearRecordingSession: assign({
258
- recordingSession: () => undefined,
259
- }),
260
- },
261
- guards: {
262
- hasShowTutorial: ({ context }) => context.config.showTutorial,
263
- isPermissionGranted: ({ event }) => {
264
- if ('output' in event) {
265
- return event.output === 'granted';
266
- }
267
- return false;
268
- },
269
- isPermissionDeniedError: ({ event }) => {
270
- if ('error' in event) {
271
- const error = event.error as Error;
272
- return (
273
- error?.name === 'NotAllowedError' ||
274
- error?.name === 'PermissionDeniedError'
275
- );
276
- }
277
- return false;
278
- },
279
- hasStream: ({ context }) => context.stream !== undefined,
280
- hasAttemptsRemaining: ({ context }) => context.attemptsRemaining > 0,
281
- hasCapturedImage: ({ context }) => context.capturedImage !== undefined,
282
- hasUploadValidationError: ({ context }) =>
283
- validateUploadResponse({
284
- config: context.config,
285
- response: context.uploadResponse,
286
- }) !== undefined,
287
- },
288
- }).createMachine({
289
- id: 'selfie',
290
- initial: 'idle',
291
- context: ({ input }) => ({
292
- config: input.config,
293
- stream: undefined,
294
- provider: undefined,
295
- frameCapturer: undefined,
296
- error: undefined,
297
- detectionStatus: 'idle',
298
- debugFrame: undefined,
299
- capturedImage: undefined,
300
- faceCoordinates: undefined,
301
- uploadResponse: undefined,
302
- recordingSession: undefined,
303
- attemptsRemaining: input.config.captureAttempts,
304
- uploadError: undefined,
305
- permissionResult: undefined,
306
- resetDetection: undefined,
307
- }),
308
- on: {
309
- QUIT: {
310
- target: '#selfie.closed',
311
- },
312
- },
313
- states: {
314
- idle: {
315
- on: {
316
- LOAD: [
317
- {
318
- target: 'tutorial',
319
- guard: 'hasShowTutorial',
320
- },
321
- {
322
- target: 'loading',
323
- },
324
- ],
325
- },
326
- },
327
-
328
- loading: {
329
- invoke: {
330
- id: 'checkPermissionLoading',
331
- src: 'checkPermission',
332
- onDone: [
333
- {
334
- target: 'capture',
335
- guard: 'isPermissionGranted',
336
- actions: assign({
337
- permissionResult: ({ event }) => event.output,
338
- }),
339
- },
340
- {
341
- target: 'permissions',
342
- actions: assign({
343
- permissionResult: ({ event }) => event.output,
344
- }),
345
- },
346
- ],
347
- },
348
- },
349
-
350
- tutorial: {
351
- initial: 'checkingPermission',
352
- entry: 'trackTutorialSelfie',
353
- states: {
354
- checkingPermission: {
355
- invoke: {
356
- id: 'checkPermissionTutorial',
357
- src: 'checkPermission',
358
- onDone: [
359
- {
360
- target: 'initializingCamera',
361
- guard: 'isPermissionGranted',
362
- actions: assign({
363
- permissionResult: ({ event }) => event.output,
364
- }),
365
- },
366
- {
367
- target: 'ready',
368
- actions: assign({
369
- permissionResult: ({ event }) => event.output,
370
- }),
371
- },
372
- ],
373
- },
374
- },
375
- initializingCamera: {
376
- initial: 'booting',
377
- invoke: {
378
- id: 'tutorialInitCamera',
379
- src: 'initializeCamera',
380
- input: ({ context }) => context.config,
381
- onDone: {
382
- actions: 'setStreamAndCapturer',
383
- },
384
- onError: [
385
- {
386
- target: 'ready',
387
- guard: 'isPermissionDeniedError',
388
- actions: assign({
389
- permissionResult: () => 'denied',
390
- }),
391
- },
392
- {
393
- target: 'ready',
394
- actions: assign({
395
- error: ({ event }) => String(event.error),
396
- }),
397
- },
398
- ],
399
- },
400
- states: {
401
- booting: {
402
- always: [
403
- {
404
- target: '#tutorialCameraReady',
405
- guard: 'hasStream',
406
- },
407
- ],
408
- on: {
409
- NEXT_STEP: {
410
- target: 'waitingForStream',
411
- actions: 'trackContinue',
412
- },
413
- },
414
- },
415
- waitingForStream: {
416
- always: [
417
- {
418
- target: '#selfie.capture',
419
- guard: 'hasStream',
420
- },
421
- ],
422
- },
423
- },
424
- },
425
- cameraReady: {
426
- id: 'tutorialCameraReady',
427
- on: {
428
- NEXT_STEP: {
429
- target: '#selfie.capture',
430
- actions: 'trackContinue',
431
- },
432
- },
433
- },
434
- ready: {
435
- on: {
436
- NEXT_STEP: {
437
- target: 'waitingForPermission',
438
- actions: 'trackContinue',
439
- },
440
- },
441
- },
442
- waitingForPermission: {
443
- invoke: {
444
- id: 'checkPermissionWaiting',
445
- src: 'checkPermission',
446
- onDone: [
447
- {
448
- target: '#selfie.capture',
449
- guard: 'isPermissionGranted',
450
- actions: assign({
451
- permissionResult: ({ event }) => event.output,
452
- }),
453
- },
454
- {
455
- target: '#selfie.permissions',
456
- actions: assign({
457
- permissionResult: ({ event }) => event.output,
458
- }),
459
- },
460
- ],
461
- },
462
- },
463
- },
464
- },
465
-
466
- permissions: {
467
- initial: 'idle',
468
- states: {
469
- idle: {
470
- invoke: {
471
- id: 'checkPermissionIdle',
472
- src: 'checkPermission',
473
- onDone: [
474
- {
475
- target: '#selfie.capture',
476
- guard: 'isPermissionGranted',
477
- actions: assign({
478
- permissionResult: ({ event }) => event.output,
479
- }),
480
- },
481
- {
482
- target: 'denied',
483
- guard: ({ event }) => event.output === 'denied',
484
- actions: assign({
485
- permissionResult: ({ event }) => event.output,
486
- }),
487
- },
488
- ],
489
- },
490
- on: {
491
- REQUEST_PERMISSION: 'requesting',
492
- GO_TO_LEARN_MORE: 'learnMore',
493
- },
494
- },
495
- learnMore: {
496
- on: {
497
- BACK: 'idle',
498
- REQUEST_PERMISSION: 'requesting',
499
- },
500
- },
501
- requesting: {
502
- invoke: {
503
- id: 'requestPermission',
504
- src: 'requestPermission',
505
- onDone: [
506
- {
507
- target: '#selfie.capture',
508
- guard: 'isPermissionGranted',
509
- actions: assign({
510
- permissionResult: ({ event }) => event.output,
511
- }),
512
- },
513
- {
514
- target: 'denied',
515
- guard: ({ event }) => event.output === 'denied',
516
- actions: assign({
517
- permissionResult: ({ event }) => event.output,
518
- }),
519
- },
520
- {
521
- target: 'idle',
522
- actions: assign({
523
- permissionResult: ({ event }) => event.output,
524
- }),
525
- },
526
- ],
527
- onError: {
528
- target: 'denied',
529
- },
530
- },
531
- },
532
- denied: {
533
- entry: assign({
534
- permissionResult: () => 'refresh',
535
- }),
536
- },
537
- },
538
- },
539
- capture: {
540
- initial: 'checkingStream',
541
- exit: ['stopMediaRecording', 'clearRecordingSession', 'stopMediaStream'],
542
- states: {
543
- checkingStream: {
544
- always: [
545
- {
546
- target: 'detecting',
547
- guard: 'hasStream',
548
- },
549
- { target: 'initializing' },
550
- ],
551
- },
552
- initializing: {
553
- invoke: {
554
- id: 'initializeCamera',
555
- src: 'initializeCamera',
556
- input: ({ context }) => context.config,
557
- onDone: {
558
- target: 'detecting',
559
- actions: 'setStreamAndCapturer',
560
- },
561
- onError: [
562
- {
563
- target: '#selfie.permissions',
564
- guard: 'isPermissionDeniedError',
565
- actions: assign({
566
- permissionResult: () => 'denied',
567
- }),
568
- },
569
- {
570
- target: '#selfie.error',
571
- actions: assign({
572
- error: ({ event }) => String(event.error),
573
- }),
574
- },
575
- ],
576
- },
577
- },
578
- detecting: {
579
- entry: [
580
- assign({
581
- detectionStatus: () => 'detecting',
582
- }),
583
- ],
584
- invoke: [
585
- {
586
- id: 'startRecording',
587
- src: 'startRecording',
588
- input: ({ context }) => ({
589
- config: context.config,
590
- stream: context.stream,
591
- existing: context.recordingSession,
592
- }),
593
- onDone: {
594
- actions: assign({
595
- recordingSession: ({ context, event }) => {
596
- const output = (event as { output?: RecordingSession })
597
- .output;
598
- return output ?? context.recordingSession;
599
- },
600
- }),
601
- },
602
- onError: {
603
- actions: () => undefined,
604
- },
605
- },
606
- {
607
- id: 'runDetection',
608
- src: 'runDetection',
609
- input: ({ context }) => ({
610
- frameCapturer: context.frameCapturer,
611
- provider: context.provider,
612
- config: context.config,
613
- }),
614
- },
615
- ],
616
- on: {
617
- DETECTION_UPDATE: {
618
- actions: assign({
619
- detectionStatus: ({ event }) => event.status,
620
- }),
621
- },
622
- DETECTION_FRAME: {
623
- actions: assign({
624
- debugFrame: ({ event }) => event.frame,
625
- }),
626
- },
627
- DETECTION_RESET_READY: {
628
- actions: assign({
629
- resetDetection: ({ event }) => event.reset,
630
- }),
631
- },
632
- DETECTION_SUCCESS: {
633
- target: 'capturing',
634
- actions: assign({
635
- capturedImage: ({ event }) => event.canvas,
636
- faceCoordinates: ({ event }) => event.faceCoordinates,
637
- }),
638
- },
639
- MANUAL_CAPTURE: {
640
- target: 'capturingManual',
641
- },
642
- },
643
- },
644
- capturing: {
645
- entry: ['captureImage'],
646
- always: [
647
- {
648
- target: 'uploading',
649
- guard: 'hasCapturedImage',
650
- },
651
- {
652
- target: 'uploadError',
653
- actions: assign(({ context }) => ({
654
- uploadError: FACE_ERROR_CODES.SERVER,
655
- attemptsRemaining: context.attemptsRemaining - 1,
656
- })),
657
- },
658
- ],
659
- },
660
- capturingManual: {
661
- entry: ['captureLatestFrame'],
662
- always: [
663
- {
664
- target: 'uploading',
665
- guard: 'hasCapturedImage',
666
- },
667
- {
668
- target: 'uploadError',
669
- actions: assign(({ context }) => ({
670
- uploadError: FACE_ERROR_CODES.SERVER,
671
- attemptsRemaining: context.attemptsRemaining - 1,
672
- })),
673
- },
674
- ],
675
- },
676
- uploading: {
677
- invoke: {
678
- id: 'uploadSelfie',
679
- src: 'uploadSelfie',
680
- input: ({ context }) => {
681
- const canvas = context.capturedImage;
682
- if (!canvas) {
683
- throw new Error(FACE_ERROR_CODES.SERVER);
684
- }
685
- return {
686
- canvas,
687
- faceCoordinates: context.faceCoordinates,
688
- };
689
- },
690
- onDone: {
691
- target: 'validatingUpload',
692
- actions: assign({
693
- uploadResponse: ({ event }) => event.output,
694
- }),
695
- },
696
- onError: {
697
- target: 'uploadError',
698
- actions: assign(({ context, event }) => ({
699
- uploadError:
700
- getFaceErrorCodeFromUnknown(event.error) ??
701
- FACE_ERROR_CODES.SERVER,
702
- attemptsRemaining: context.attemptsRemaining - 1,
703
- })),
704
- },
705
- },
706
- },
707
- validatingUpload: {
708
- always: [
709
- {
710
- target: 'uploadError',
711
- guard: 'hasUploadValidationError',
712
- actions: [
713
- 'setUploadErrorFromUploadValidation',
714
- 'decrementAttemptsRemaining',
715
- ],
716
- },
717
- { target: 'success' },
718
- ],
719
- },
720
- uploadError: {
721
- on: {
722
- RETRY_CAPTURE: {
723
- target: 'detecting',
724
- guard: 'hasAttemptsRemaining',
725
- actions: ['resetDetection', 'clearUploadFailure'],
726
- },
727
- },
728
- },
729
- success: {
730
- entry: 'stopMediaRecording',
731
- after: {
732
- 3000: {
733
- target: '#selfie.finished',
734
- },
735
- },
736
- },
737
- },
738
- },
739
-
740
- finished: {
741
- entry: 'stopMediaStream',
742
- on: {
743
- RESET: {
744
- target: 'idle',
745
- actions: 'resetContext',
746
- },
747
- },
748
- },
749
-
750
- closed: {
751
- entry: 'stopMediaStream',
752
- type: 'final',
753
- },
754
- error: {
755
- entry: 'stopMediaStream',
756
- on: {
757
- RESET: {
758
- target: 'idle',
759
- actions: 'resetContext',
760
- },
761
- },
762
- },
763
- },
764
- });
765
-
766
- /**
767
- * The selfie capture state machine.
768
- *
769
- * Note: Uses AnyStateMachine type for declaration file portability.
770
- * Type safety is ensured via the machine configuration.
771
- */
772
- export const selfieMachine: AnyStateMachine = _selfieMachine;
773
-
774
- /**
775
- * Type representing the selfie machine.
776
- * For advanced use cases requiring specific machine types.
777
- */
778
- export type SelfieMachine = StateMachine<
779
- SelfieContext,
780
- SelfieEvent,
781
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
782
- any,
783
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
784
- any,
785
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
786
- any,
787
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
788
- any,
789
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
790
- any,
791
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
792
- any,
793
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
794
- any,
795
- SelfieInput,
796
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
797
- any,
798
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
799
- any,
800
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
801
- any,
802
- // biome-ignore lint/suspicious/noExplicitAny: Required for declaration portability
803
- any
804
- >;