cogfy-data-exchange 1.0.10 → 1.0.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cogfy-data-exchange",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,6 +15,17 @@ const flow = {
15
15
  id: 'SCREEN_A',
16
16
  layout: {
17
17
  children: [
18
+ {
19
+ 'on-click-action': {
20
+ name: 'data_exchange',
21
+ payload: {
22
+ test_payload: 'This is a test_payload',
23
+ trigger: 'screen.SCREEN_A.event.embedded_link_click'
24
+ }
25
+ },
26
+ text: 'This is an embedded link',
27
+ type: 'EmbeddedLink'
28
+ },
18
29
  {
19
30
  label: 'Continuar',
20
31
  'on-click-action': {
@@ -53,13 +64,19 @@ const flow = {
53
64
  describe('createFlow', () => {
54
65
  test('should dispatch screens correctly', async ({ expect }) => {
55
66
  const engine = createFlow(flow, {
56
- SCREEN_A: async () => {
67
+ 'screen.SCREEN_A': async () => {
68
+ return {
69
+ data: { age: 30 },
70
+ screen: 'SCREEN_B'
71
+ }
72
+ },
73
+ 'screen.SCREEN_A.event.embedded_link_click': async () => {
57
74
  return {
58
75
  data: { age: 30 },
59
76
  screen: 'SCREEN_B'
60
77
  }
61
78
  },
62
- SCREEN_B: async () => {
79
+ 'screen.SCREEN_B': async () => {
63
80
  return {
64
81
  data: {
65
82
  profile: { age: 20, name: 'John' }
@@ -67,7 +84,7 @@ describe('createFlow', () => {
67
84
  screen: 'SCREEN_D'
68
85
  }
69
86
  },
70
- SCREEN_C: async () => {
87
+ 'screen.SCREEN_C': async () => {
71
88
  return {
72
89
  data: {
73
90
  profile: { age: 25, name: 'Jane' }
@@ -75,7 +92,7 @@ describe('createFlow', () => {
75
92
  screen: 'SCREEN_D'
76
93
  }
77
94
  },
78
- SCREEN_D: async () => {
95
+ 'screen.SCREEN_D': async () => {
79
96
  throw new Error('end')
80
97
  }
81
98
  })
@@ -87,4 +104,50 @@ describe('createFlow', () => {
87
104
  screen: 'SCREEN_B'
88
105
  })
89
106
  })
107
+
108
+ test('should dispatch embedded link event correctly', async ({ expect }) => {
109
+ const engine = createFlow(flow, {
110
+ 'screen.SCREEN_A': async () => {
111
+ return {
112
+ data: { age: 30 },
113
+ screen: 'SCREEN_B'
114
+ }
115
+ },
116
+ 'screen.SCREEN_A.event.embedded_link_click': async () => {
117
+ return {
118
+ data: { age: 25 },
119
+ screen: 'SCREEN_B'
120
+ }
121
+ },
122
+ 'screen.SCREEN_B': async () => {
123
+ return {
124
+ data: {
125
+ profile: { age: 20, name: 'John' }
126
+ },
127
+ screen: 'SCREEN_D'
128
+ }
129
+ },
130
+ 'screen.SCREEN_C': async () => {
131
+ return {
132
+ data: {
133
+ profile: { age: 25, name: 'Jane' }
134
+ },
135
+ screen: 'SCREEN_D'
136
+ }
137
+ },
138
+ 'screen.SCREEN_D': async () => {
139
+ throw new Error('end')
140
+ }
141
+ })
142
+
143
+ const result = await engine.dispatch('screen.SCREEN_A.event.embedded_link_click', {
144
+ test_payload: 'This is a test_payload',
145
+ trigger: 'screen.SCREEN_A.event.embedded_link_click'
146
+ })
147
+
148
+ expect(result).toEqual({
149
+ data: { age: 25 },
150
+ screen: 'SCREEN_B'
151
+ })
152
+ })
90
153
  })
@@ -1,24 +1,25 @@
1
- import type { ExtractScreen, FlowJson, NextResult, PayloadByScreenId, ScreenName, ScreenTrigger } from './types'
1
+ import type { AllTriggers, ExtractScreen, FlowJson, NextResult, PayloadByTrigger } from './types'
2
2
 
3
3
  type Handlers<F extends FlowJson> = {
4
- [K in ScreenName<F>]: (data: PayloadByScreenId<F, K>) => Promise<NextResult<F, K>>
4
+ [K in AllTriggers<F>]: (
5
+ data: PayloadByTrigger<F, K, ExtractScreen<K, F>>
6
+ ) => Promise<NextResult<F, ExtractScreen<K, F>>>
5
7
  }
6
8
 
7
9
  /**
8
10
  * Creates a flow engine based on the provided flow definition and handlers.
9
11
  * @param flow The flow definition, which includes the routing model and screen definitions.
10
- * @param handlers An object mapping screen IDs to their corresponding handler functions. Each handler receives the data for its screen and returns a promise that resolves to the next result, which includes the next screen and its data.
11
- * @returns An object with a `dispatch` method to trigger screen handlers and the original flow definition.
12
+ * @param handlers An object mapping trigger strings to their corresponding handler functions. Each handler receives the payload for its trigger and returns a promise that resolves to the next result, which includes the next screen and its data.
13
+ * @returns An object with a `dispatch` method to trigger handlers and the original flow definition.
12
14
  */
13
15
  export function createFlow<F extends FlowJson>(flow: F, handlers: Handlers<F>) {
14
16
  return {
15
- dispatch<T extends ScreenTrigger<ScreenName<F>>>(
17
+ dispatch<T extends AllTriggers<F>>(
16
18
  trigger: T,
17
- payload: PayloadByScreenId<F, ExtractScreen<T, F>>
19
+ payload: PayloadByTrigger<F, T, ExtractScreen<T, F>>
18
20
  ): Promise<NextResult<F, ExtractScreen<T, F>>> {
19
- const screen = trigger.replace('screen.', '') as ExtractScreen<T, F>
20
-
21
- return handlers[screen](payload)
21
+ const handler = handlers[trigger] as (data: typeof payload) => Promise<NextResult<F, ExtractScreen<T, F>>>
22
+ return handler(payload)
22
23
  },
23
24
 
24
25
  flow
@@ -1,21 +1,27 @@
1
1
  type ExtractScreenById<T, Id extends string> = T extends {
2
- screens: infer Screens;
2
+ screens: infer Screens
3
3
  }
4
4
  ? Screens extends readonly unknown[]
5
5
  ? Extract<Screens[number], { id: Id }>
6
6
  : never
7
- : never;
7
+ : never
8
8
 
9
9
  type ExtractChildren<T> = T extends { layout: { children: infer C } }
10
10
  ? C extends readonly unknown[]
11
11
  ? C[number]
12
12
  : never
13
- : never;
13
+ : never
14
14
 
15
- type ExtractPayload<T> = T extends { "on-click-action": { payload: infer P } }
16
- ? P
17
- : never;
15
+ type ExtractPayload<T> = T extends { 'on-click-action': { payload: infer P } } ? P : never
18
16
 
19
- export type PayloadByScreenId<T, Id extends string> = ExtractPayload<
20
- ExtractChildren<ExtractScreenById<T, Id>>
21
- >;
17
+ type ExtractChildByTrigger<Children, Trigger extends string> = Children extends {
18
+ 'on-click-action': { payload: { trigger: Trigger } }
19
+ }
20
+ ? Children
21
+ : never
22
+
23
+ export type PayloadByScreenId<T, Id extends string> = ExtractPayload<ExtractChildren<ExtractScreenById<T, Id>>>
24
+
25
+ export type PayloadByTrigger<T, Trigger extends string, ScreenId extends string> = ExtractPayload<
26
+ ExtractChildByTrigger<ExtractChildren<ExtractScreenById<T, ScreenId>>, Trigger>
27
+ >
@@ -3,7 +3,19 @@ import type { ScreenName } from './screen'
3
3
 
4
4
  export type ScreenTrigger<S extends string> = `screen.${S}`
5
5
 
6
+ type AllChildTriggers<F extends FlowJson> = F['screens'][number] extends infer S
7
+ ? S extends { layout: { children: readonly (infer C)[] } }
8
+ ? C extends { 'on-click-action': { payload: { trigger: infer T } } }
9
+ ? T extends string
10
+ ? T
11
+ : never
12
+ : never
13
+ : never
14
+ : never
15
+
16
+ export type AllTriggers<F extends FlowJson> = ScreenTrigger<ScreenName<F>> | AllChildTriggers<F>
17
+
6
18
  export type ExtractScreen<T extends string, F extends FlowJson> = Extract<
7
- T extends `screen.${infer S}` ? S : never,
19
+ T extends `screen.${infer S}.event.${string}` ? S : T extends `screen.${infer S}` ? S : never,
8
20
  ScreenName<F>
9
21
  >