@incodetech/core 0.0.0-dev-20260126-4504c5b

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.
@@ -0,0 +1,638 @@
1
+ import { C as createManager } from "./src-DYtpbFY5.esm.js";
2
+ import { a as fromPromise, i as fromCallback, n as setup, o as createActor, r as assign, t as endpoints } from "./endpoints-BUsSVoJV.esm.js";
3
+ import { t as api } from "./api-DfRLAneb.esm.js";
4
+
5
+ //#region src/modules/flow/flowAnalyzer.ts
6
+ const WASM_MODULE_PIPELINES = {
7
+ SELFIE: "selfie",
8
+ AUTHENTICATION: "selfie",
9
+ FACE_MATCH: "selfie",
10
+ VIDEO_ONBOARDING: "selfie",
11
+ ID: "idCapture",
12
+ TUTORIAL_ID: "idCapture",
13
+ SECOND_ID: "idCapture",
14
+ THIRD_ID: "idCapture"
15
+ };
16
+ /**
17
+ * Analyzes a flow configuration and returns the WASM pipelines needed.
18
+ * Use this to conditionally warmup WASM only when required by the flow.
19
+ *
20
+ * @param flow - The flow configuration from /omni/onboarding/flow
21
+ * @returns Array of WASM pipelines needed (e.g., ['selfie', 'idCapture'])
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const pipelines = getRequiredWasmPipelines(flow);
26
+ * if (pipelines.length > 0) {
27
+ * warmupWasm({ ...wasmConfig, pipelines });
28
+ * }
29
+ * ```
30
+ */
31
+ function getRequiredWasmPipelines(flow) {
32
+ const pipelines = /* @__PURE__ */ new Set();
33
+ for (const module of flow.flowModules) {
34
+ const pipeline = WASM_MODULE_PIPELINES[module.key];
35
+ if (pipeline) pipelines.add(pipeline);
36
+ }
37
+ return [...pipelines];
38
+ }
39
+
40
+ //#endregion
41
+ //#region src/modules/flow/flowServices.ts
42
+ const getFlow = async (signal) => {
43
+ const res = await api.get(endpoints.flow, { signal });
44
+ if (!res.ok) throw new Error(`GET /flow failed: ${res.status} ${res.statusText}`);
45
+ return res.data;
46
+ };
47
+
48
+ //#endregion
49
+ //#region src/modules/flow/flowStateMachine.ts
50
+ const flowMachine = setup({
51
+ types: {
52
+ context: {},
53
+ events: {},
54
+ input: {}
55
+ },
56
+ actors: { fetchFlow: fromPromise(async ({ input, signal }) => {
57
+ return input.getFlow(signal);
58
+ }) },
59
+ actions: {
60
+ resetContext: assign(({ context }) => ({
61
+ flow: void 0,
62
+ error: void 0,
63
+ steps: [],
64
+ currentStepIndex: -1,
65
+ currentStep: void 0,
66
+ config: void 0,
67
+ getFlow: context.getFlow
68
+ })),
69
+ setFlowData: assign(({ event }) => {
70
+ const flow = event.output;
71
+ return {
72
+ flow,
73
+ steps: (flow.flowModules ?? []).map((m) => m.key),
74
+ currentStepIndex: (flow.flowModules ?? []).length > 0 ? 0 : -1,
75
+ currentStep: flow.flowModules?.[0]?.key,
76
+ config: flow.flowModules?.[0]?.configuration
77
+ };
78
+ }),
79
+ setError: assign(({ event }) => ({ error: String(event.error) })),
80
+ incrementStep: assign(({ context }) => {
81
+ const nextIndex = context.currentStepIndex + 1;
82
+ const module = context.flow?.flowModules?.[nextIndex];
83
+ return {
84
+ currentStepIndex: nextIndex,
85
+ currentStep: module?.key,
86
+ config: module?.configuration
87
+ };
88
+ }),
89
+ decrementStep: assign(({ context }) => {
90
+ const prevIndex = context.currentStepIndex - 1;
91
+ const module = context.flow?.flowModules?.[prevIndex];
92
+ return {
93
+ currentStepIndex: prevIndex,
94
+ currentStep: module?.key,
95
+ config: module?.configuration
96
+ };
97
+ })
98
+ },
99
+ guards: {
100
+ isLastStep: ({ context }) => context.currentStepIndex >= 0 && context.currentStepIndex === context.steps.length - 1,
101
+ canGoNext: ({ context }) => context.currentStepIndex >= 0 && context.currentStepIndex < context.steps.length - 1,
102
+ canGoPrev: ({ context }) => context.currentStepIndex > 0
103
+ }
104
+ }).createMachine({
105
+ id: "flow",
106
+ initial: "idle",
107
+ context: ({ input }) => ({
108
+ flow: void 0,
109
+ error: void 0,
110
+ steps: [],
111
+ currentStepIndex: -1,
112
+ currentStep: void 0,
113
+ config: void 0,
114
+ getFlow: input.getFlow
115
+ }),
116
+ states: {
117
+ idle: { on: { LOAD: {
118
+ target: "loading",
119
+ actions: "resetContext"
120
+ } } },
121
+ loading: {
122
+ invoke: {
123
+ id: "fetchFlow",
124
+ src: "fetchFlow",
125
+ input: ({ context }) => ({ getFlow: context.getFlow }),
126
+ onDone: {
127
+ target: "ready",
128
+ actions: "setFlowData"
129
+ },
130
+ onError: {
131
+ target: "error",
132
+ actions: "setError"
133
+ }
134
+ },
135
+ on: { CANCEL: {
136
+ target: "idle",
137
+ actions: "resetContext"
138
+ } }
139
+ },
140
+ ready: { on: {
141
+ NEXT_STEP: [{
142
+ target: "finished",
143
+ guard: "isLastStep"
144
+ }, {
145
+ target: "ready",
146
+ guard: "canGoNext",
147
+ actions: "incrementStep"
148
+ }],
149
+ PREV_STEP: {
150
+ target: "ready",
151
+ guard: "canGoPrev",
152
+ actions: "decrementStep"
153
+ },
154
+ RESET: {
155
+ target: "idle",
156
+ actions: "resetContext"
157
+ }
158
+ } },
159
+ finished: { on: { RESET: {
160
+ target: "idle",
161
+ actions: "resetContext"
162
+ } } },
163
+ error: { on: { RESET: {
164
+ target: "idle",
165
+ actions: "resetContext"
166
+ } } }
167
+ }
168
+ });
169
+
170
+ //#endregion
171
+ //#region src/modules/flow/flowActor.ts
172
+ function createFlowActor(options) {
173
+ return createActor(flowMachine, { input: { getFlow: options?.getFlow ?? getFlow } }).start();
174
+ }
175
+
176
+ //#endregion
177
+ //#region src/modules/flow/flowManager.ts
178
+ function mapState$1(snapshot) {
179
+ const { value, context } = snapshot;
180
+ switch (value) {
181
+ case "idle": return { status: "idle" };
182
+ case "loading": return { status: "loading" };
183
+ case "ready": return {
184
+ status: "ready",
185
+ flow: context.flow ?? {},
186
+ steps: context.steps,
187
+ currentStepIndex: context.currentStepIndex,
188
+ currentStep: context.currentStep,
189
+ config: context.config
190
+ };
191
+ case "finished": return {
192
+ status: "finished",
193
+ flow: context.flow ?? {}
194
+ };
195
+ case "error": return {
196
+ status: "error",
197
+ error: context.error ?? "Unknown error"
198
+ };
199
+ default: return { status: "idle" };
200
+ }
201
+ }
202
+ function createApi$1({ actor, getSnapshot }) {
203
+ function getCanNext() {
204
+ const snapshot = getSnapshot();
205
+ const { currentStepIndex, steps } = snapshot.context;
206
+ return snapshot.matches("ready") && currentStepIndex >= 0 && currentStepIndex < steps.length - 1;
207
+ }
208
+ function getCanPrev() {
209
+ const snapshot = getSnapshot();
210
+ return snapshot.matches("ready") && snapshot.context.currentStepIndex > 0;
211
+ }
212
+ function getModuleConfig(moduleKey) {
213
+ const snapshot = getSnapshot();
214
+ if (!snapshot.matches("ready")) return;
215
+ return (snapshot.context.flow?.flowModules.find((m) => m.key === moduleKey))?.configuration;
216
+ }
217
+ function isModuleEnabled(moduleKey) {
218
+ const snapshot = getSnapshot();
219
+ if (!snapshot.matches("ready")) return false;
220
+ return !!snapshot.context.flow?.flowModules.some((m) => m.key === moduleKey);
221
+ }
222
+ return {
223
+ load() {
224
+ actor.send({ type: "LOAD" });
225
+ },
226
+ cancel() {
227
+ actor.send({ type: "CANCEL" });
228
+ },
229
+ reset() {
230
+ actor.send({ type: "RESET" });
231
+ },
232
+ nextStep() {
233
+ actor.send({ type: "NEXT_STEP" });
234
+ },
235
+ prevStep() {
236
+ actor.send({ type: "PREV_STEP" });
237
+ },
238
+ get canNext() {
239
+ return getCanNext();
240
+ },
241
+ get canPrev() {
242
+ return getCanPrev();
243
+ },
244
+ getModuleConfig,
245
+ isModuleEnabled
246
+ };
247
+ }
248
+ /**
249
+ * Creates a flow manager instance for managing onboarding flow state and navigation.
250
+ *
251
+ * The flow manager provides:
252
+ * - State management with statuses: `idle`, `loading`, `ready`, `finished`, `error`
253
+ * - Step navigation with `nextStep()` and `prevStep()`
254
+ * - Current step info via `state.currentStep` and `state.config` when in `ready` state
255
+ * - Module configuration lookup via `getModuleConfig()`
256
+ *
257
+ * @param options - Optional configuration for the flow actor
258
+ * @param options.getFlow - Custom function to fetch flow data. Defaults to `getOnboardingFlow`
259
+ * @returns A manager instance with state subscription, API methods, and lifecycle controls
260
+ *
261
+ * @example
262
+ * ```ts
263
+ * const flowManager = createFlowManager();
264
+ *
265
+ * flowManager.subscribe((state) => {
266
+ * if (state.status === 'ready') {
267
+ * console.log(state.currentStep, state.config);
268
+ * }
269
+ * });
270
+ *
271
+ * flowManager.load({ token: 'session-token' });
272
+ * ```
273
+ */
274
+ function createFlowManager(options) {
275
+ return createManager({
276
+ actor: createFlowActor(options),
277
+ mapState: mapState$1,
278
+ createApi: createApi$1
279
+ });
280
+ }
281
+
282
+ //#endregion
283
+ //#region src/modules/flow/moduleLoader.ts
284
+ var ModuleLoaderImpl = class {
285
+ constructor(registry) {
286
+ this.registry = registry;
287
+ this.loadedModules = /* @__PURE__ */ new Map();
288
+ this.prefetchedModules = /* @__PURE__ */ new Set();
289
+ }
290
+ async load(moduleKey) {
291
+ if (!this.registry[moduleKey]) throw new Error(`Module ${moduleKey} not found in registry`);
292
+ const cached = this.loadedModules.get(moduleKey);
293
+ if (cached) return await cached;
294
+ const loadPromise = this.registry[moduleKey]().then((module) => {
295
+ if (module && typeof module === "object" && "default" in module) return module.default;
296
+ return module;
297
+ });
298
+ this.loadedModules.set(moduleKey, loadPromise);
299
+ try {
300
+ return await loadPromise;
301
+ } catch (error) {
302
+ this.loadedModules.delete(moduleKey);
303
+ throw error;
304
+ }
305
+ }
306
+ prefetch(moduleKey) {
307
+ if (!this.registry[moduleKey]) return;
308
+ if (this.prefetchedModules.has(moduleKey) || this.loadedModules.has(moduleKey)) return;
309
+ this.prefetchedModules.add(moduleKey);
310
+ this.registry[moduleKey]().catch(() => {
311
+ this.prefetchedModules.delete(moduleKey);
312
+ });
313
+ }
314
+ isLoaded(moduleKey) {
315
+ return this.loadedModules.has(moduleKey);
316
+ }
317
+ };
318
+ function createModuleLoader(registry) {
319
+ return new ModuleLoaderImpl(registry);
320
+ }
321
+
322
+ //#endregion
323
+ //#region src/modules/flow/flowCompletionService.ts
324
+ const getFinishStatus = async (flowId, signal) => {
325
+ const url = `/omni/finish-status${flowId ? `?flowId=${flowId}` : ""}`;
326
+ const res = await api.get(url, { signal });
327
+ if (!res.ok) throw new Error(`GET ${url} failed: ${res.status} ${res.statusText}`);
328
+ return res.data;
329
+ };
330
+
331
+ //#endregion
332
+ //#region src/modules/flow/orchestratedFlowStateMachine.ts
333
+ const orchestratedFlowMachine = setup({
334
+ types: {
335
+ context: {},
336
+ events: {},
337
+ input: {}
338
+ },
339
+ actors: {
340
+ fetchFlow: fromPromise(async ({ input, signal }) => {
341
+ return input.getFlow(signal);
342
+ }),
343
+ notifyBackend: fromPromise(async ({ input, signal }) => {
344
+ return await input.getFinishStatus(input.flowId, signal);
345
+ }),
346
+ runChildModule: fromCallback(({ sendBack, input }) => {
347
+ const { machine, config } = input;
348
+ if (!machine) return () => {};
349
+ const actor = createActor(machine, { input: { config } });
350
+ const subscription = actor.subscribe({
351
+ complete: () => {
352
+ sendBack({ type: "MODULE_COMPLETE" });
353
+ },
354
+ error: (err) => {
355
+ sendBack({
356
+ type: "MODULE_ERROR",
357
+ error: err
358
+ });
359
+ }
360
+ });
361
+ actor.start();
362
+ return () => {
363
+ subscription.unsubscribe();
364
+ actor.stop();
365
+ };
366
+ })
367
+ },
368
+ actions: {
369
+ resetContext: assign(({ context }) => ({
370
+ flow: void 0,
371
+ error: void 0,
372
+ steps: [],
373
+ currentStepIndex: -1,
374
+ currentStep: void 0,
375
+ config: void 0,
376
+ getFlow: context.getFlow,
377
+ registeredModules: context.registeredModules,
378
+ getFinishStatus: context.getFinishStatus,
379
+ finishStatus: void 0
380
+ })),
381
+ setFlowData: assign(({ event }) => {
382
+ const flow = event.output;
383
+ const flowModules = flow.flowModules ?? [];
384
+ const firstModule = flowModules[0];
385
+ const config = {
386
+ ...firstModule?.configuration,
387
+ ds: flow.ds
388
+ };
389
+ return {
390
+ flow,
391
+ steps: Object.keys(flowModules),
392
+ currentStepIndex: flowModules.length > 0 ? 0 : -1,
393
+ currentStep: firstModule?.key,
394
+ config
395
+ };
396
+ }),
397
+ setError: assign(({ event }) => ({ error: String(event.error) })),
398
+ incrementStep: assign(({ context }) => {
399
+ const nextIndex = context.currentStepIndex + 1;
400
+ const module = context.flow?.flowModules?.[nextIndex];
401
+ const config = {
402
+ ...module?.configuration,
403
+ ds: context.flow?.ds
404
+ };
405
+ return {
406
+ currentStepIndex: nextIndex,
407
+ currentStep: module?.key,
408
+ config
409
+ };
410
+ }),
411
+ setFinishStatus: assign(({ event }) => ({ finishStatus: event.output }))
412
+ },
413
+ guards: {
414
+ isLastStep: ({ context }) => context.currentStepIndex >= 0 && context.currentStepIndex === context.steps.length - 1,
415
+ canGoNext: ({ context }) => context.currentStepIndex >= 0 && context.currentStepIndex < context.steps.length - 1,
416
+ hasModule: ({ context, event }) => {
417
+ if (!("output" in event)) return false;
418
+ const firstModuleKey = event.output.flowModules?.[0]?.key;
419
+ if (!firstModuleKey) return false;
420
+ return context.registeredModules[firstModuleKey] != null;
421
+ }
422
+ }
423
+ }).createMachine({
424
+ id: "orchestratedFlow",
425
+ initial: "idle",
426
+ context: ({ input }) => ({
427
+ flow: void 0,
428
+ error: void 0,
429
+ steps: [],
430
+ currentStepIndex: -1,
431
+ currentStep: void 0,
432
+ config: void 0,
433
+ getFlow: input.getFlow,
434
+ registeredModules: input.modules,
435
+ getFinishStatus: input.getFinishStatus ?? getFinishStatus,
436
+ finishStatus: void 0
437
+ }),
438
+ states: {
439
+ idle: { on: { LOAD: {
440
+ target: "loading",
441
+ actions: "resetContext"
442
+ } } },
443
+ loading: {
444
+ invoke: {
445
+ id: "fetchFlow",
446
+ src: "fetchFlow",
447
+ input: ({ context }) => ({ getFlow: context.getFlow }),
448
+ onDone: [{
449
+ target: "runningModule",
450
+ guard: "hasModule",
451
+ actions: "setFlowData"
452
+ }, {
453
+ target: "error",
454
+ actions: assign({ error: () => "No registered module found for flow" })
455
+ }],
456
+ onError: {
457
+ target: "error",
458
+ actions: "setError"
459
+ }
460
+ },
461
+ on: { CANCEL: {
462
+ target: "idle",
463
+ actions: "resetContext"
464
+ } }
465
+ },
466
+ runningModule: {
467
+ invoke: {
468
+ id: "currentModule",
469
+ src: "runChildModule",
470
+ input: ({ context }) => {
471
+ if (!context.currentStep) throw new Error("No current step");
472
+ return {
473
+ machine: context.registeredModules[context.currentStep],
474
+ config: context.config
475
+ };
476
+ },
477
+ onDone: [{
478
+ target: "completing",
479
+ guard: "isLastStep"
480
+ }, {
481
+ target: "runningModule",
482
+ actions: "incrementStep",
483
+ reenter: true
484
+ }],
485
+ onError: {
486
+ target: "error",
487
+ actions: "setError"
488
+ }
489
+ },
490
+ on: {
491
+ MODULE_COMPLETE: [{
492
+ target: "completing",
493
+ guard: "isLastStep"
494
+ }, {
495
+ target: "runningModule",
496
+ actions: "incrementStep",
497
+ reenter: true
498
+ }],
499
+ MODULE_ERROR: {
500
+ target: "error",
501
+ actions: assign(({ event }) => ({ error: String(event.error) }))
502
+ },
503
+ RESET: {
504
+ target: "idle",
505
+ actions: "resetContext"
506
+ }
507
+ }
508
+ },
509
+ completing: {
510
+ invoke: {
511
+ id: "notifyBackend",
512
+ src: "notifyBackend",
513
+ input: ({ context }) => ({
514
+ getFinishStatus: context.getFinishStatus,
515
+ flowId: context.flow?.flowId
516
+ }),
517
+ onDone: {
518
+ target: "finished",
519
+ actions: "setFinishStatus"
520
+ },
521
+ onError: {
522
+ target: "error",
523
+ actions: "setError"
524
+ }
525
+ },
526
+ on: { RESET: {
527
+ target: "idle",
528
+ actions: "resetContext"
529
+ } }
530
+ },
531
+ finished: { on: { RESET: {
532
+ target: "idle",
533
+ actions: "resetContext"
534
+ } } },
535
+ error: { on: { RESET: {
536
+ target: "idle",
537
+ actions: "resetContext"
538
+ } } }
539
+ }
540
+ });
541
+
542
+ //#endregion
543
+ //#region src/modules/flow/orchestratedFlowManager.ts
544
+ function mapState(snapshot) {
545
+ const { value, context } = snapshot;
546
+ switch (value) {
547
+ case "idle": return { status: "idle" };
548
+ case "loading": return { status: "loading" };
549
+ case "runningModule": {
550
+ const childSnapshot = snapshot.children.currentModule?.getSnapshot();
551
+ return {
552
+ status: "ready",
553
+ flow: context.flow ?? {},
554
+ steps: context.steps,
555
+ currentStepIndex: context.currentStepIndex,
556
+ currentStep: context.currentStep,
557
+ config: context.config,
558
+ moduleState: childSnapshot ?? null
559
+ };
560
+ }
561
+ case "finished": return {
562
+ status: "finished",
563
+ flow: context.flow ?? {},
564
+ finishStatus: context.finishStatus ?? {
565
+ redirectionUrl: "",
566
+ action: "none",
567
+ scoreStatus: "UNKNOWN"
568
+ }
569
+ };
570
+ case "error": return {
571
+ status: "error",
572
+ error: context.error ?? "Unknown error"
573
+ };
574
+ default: return { status: "idle" };
575
+ }
576
+ }
577
+ function createApi({ actor, getSnapshot }) {
578
+ function getCanNext() {
579
+ const snapshot = getSnapshot();
580
+ const { currentStepIndex, steps } = snapshot.context;
581
+ return snapshot.value === "runningModule" && currentStepIndex >= 0 && currentStepIndex < steps.length - 1;
582
+ }
583
+ function getModuleConfig(moduleKey) {
584
+ const snapshot = getSnapshot();
585
+ if (snapshot.value !== "runningModule") return;
586
+ return (snapshot.context.flow?.flowModules.find((m) => m.key === moduleKey))?.configuration;
587
+ }
588
+ function isModuleEnabled(moduleKey) {
589
+ const snapshot = getSnapshot();
590
+ if (snapshot.value !== "runningModule") return false;
591
+ return !!snapshot.context.flow?.flowModules.some((m) => m.key === moduleKey);
592
+ }
593
+ return {
594
+ load() {
595
+ actor.send({ type: "LOAD" });
596
+ },
597
+ cancel() {
598
+ actor.send({ type: "CANCEL" });
599
+ },
600
+ reset() {
601
+ actor.send({ type: "RESET" });
602
+ },
603
+ completeModule() {
604
+ actor.send({ type: "MODULE_COMPLETE" });
605
+ },
606
+ errorModule(error) {
607
+ actor.send({
608
+ type: "MODULE_ERROR",
609
+ error
610
+ });
611
+ },
612
+ send(event) {
613
+ actor.send(event);
614
+ },
615
+ get canNext() {
616
+ return getCanNext();
617
+ },
618
+ getModuleConfig,
619
+ isModuleEnabled
620
+ };
621
+ }
622
+ function createOrchestratedFlowActor(options) {
623
+ return createActor(orchestratedFlowMachine, { input: {
624
+ getFlow: options.getFlow ?? getFlow,
625
+ modules: options.modules,
626
+ getFinishStatus: options.getFinishStatus
627
+ } }).start();
628
+ }
629
+ function createOrchestratedFlowManager(options) {
630
+ return createManager({
631
+ actor: createOrchestratedFlowActor(options),
632
+ mapState,
633
+ createApi
634
+ });
635
+ }
636
+
637
+ //#endregion
638
+ export { createFlowManager, createModuleLoader, createOrchestratedFlowManager, getRequiredWasmPipelines };
@@ -0,0 +1,41 @@
1
+ //#region ../infra/src/device/getBrowser.ts
2
+ function getUserAgent() {
3
+ if (typeof navigator === "undefined") return "";
4
+ return navigator.userAgent;
5
+ }
6
+
7
+ //#endregion
8
+ //#region ../infra/src/device/getDeviceClass.ts
9
+ function getDeviceInfo() {
10
+ if (typeof navigator === "undefined") return {
11
+ userAgent: "",
12
+ platform: "",
13
+ maxTouchPoints: 0
14
+ };
15
+ return {
16
+ userAgent: navigator.userAgent,
17
+ platform: navigator.platform,
18
+ maxTouchPoints: navigator.maxTouchPoints
19
+ };
20
+ }
21
+ /**
22
+ * Gets the current window dimensions.
23
+ * Returns default values (1280x720) in non-browser environments.
24
+ */
25
+ function getWindowDimensions(defaultWidth = 1280, defaultHeight = 720) {
26
+ if (typeof window === "undefined") return {
27
+ outerWidth: defaultWidth,
28
+ outerHeight: defaultHeight,
29
+ innerWidth: defaultWidth,
30
+ innerHeight: defaultHeight
31
+ };
32
+ return {
33
+ outerWidth: window.outerWidth,
34
+ outerHeight: window.outerHeight,
35
+ innerWidth: window.innerWidth,
36
+ innerHeight: window.innerHeight
37
+ };
38
+ }
39
+
40
+ //#endregion
41
+ export { getWindowDimensions as n, getUserAgent as r, getDeviceInfo as t };