@getflip/bridge 0.1.0-alpha.8 → 0.1.0

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 (50) hide show
  1. package/README.md +211 -5
  2. package/dist/dialog/dialog.d.ts +10 -0
  3. package/dist/dialog/dialog.js +45 -0
  4. package/dist/dialog/dialog.js.map +1 -0
  5. package/dist/dialog/dialog.spec.d.ts +1 -0
  6. package/dist/dialog/dialog.spec.js +83 -0
  7. package/dist/dialog/dialog.spec.js.map +1 -0
  8. package/dist/dialog/dialog.types.d.ts +33 -0
  9. package/dist/dialog/dialog.types.js +2 -0
  10. package/dist/dialog/dialog.types.js.map +1 -0
  11. package/dist/dialog/index.d.ts +2 -0
  12. package/dist/dialog/index.js +3 -0
  13. package/dist/dialog/index.js.map +1 -0
  14. package/dist/events/events.d.ts +3 -0
  15. package/dist/events/events.js +44 -0
  16. package/dist/events/events.js.map +1 -0
  17. package/dist/events/events.spec.d.ts +1 -0
  18. package/dist/events/events.spec.js +64 -0
  19. package/dist/events/events.spec.js.map +1 -0
  20. package/dist/events/events.types.d.ts +27 -0
  21. package/dist/events/events.types.js +8 -0
  22. package/dist/events/events.types.js.map +1 -0
  23. package/dist/events/index.d.ts +2 -0
  24. package/dist/events/index.js +3 -0
  25. package/dist/events/index.js.map +1 -0
  26. package/dist/i18n/i18n.types.d.ts +2 -1
  27. package/dist/index.cjs.js +127 -20
  28. package/dist/index.cjs.js.map +1 -1
  29. package/dist/index.d.ts +3 -0
  30. package/dist/index.js +3 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +122 -21
  33. package/dist/index.mjs.map +1 -1
  34. package/dist/messaging/index.d.ts +1 -0
  35. package/dist/messaging/index.js +1 -0
  36. package/dist/messaging/index.js.map +1 -1
  37. package/dist/messaging/messaging.d.ts +3 -1
  38. package/dist/messaging/messaging.js +27 -21
  39. package/dist/messaging/messaging.js.map +1 -1
  40. package/dist/messaging/messaging.spec.js +1 -0
  41. package/dist/messaging/messaging.spec.js.map +1 -1
  42. package/dist/messaging/messaging.types.d.ts +11 -0
  43. package/dist/messaging/messaging.types.js +2 -0
  44. package/dist/messaging/messaging.types.js.map +1 -0
  45. package/dist/navigation/navigation.types.d.ts +2 -1
  46. package/dist/theming/theming.types.d.ts +5 -4
  47. package/dist/types.d.ts +15 -11
  48. package/dist/types.js +6 -0
  49. package/dist/types.js.map +1 -1
  50. package/package.json +2 -2
package/README.md CHANGED
@@ -7,9 +7,12 @@ App or Flip Admin Console.
7
7
 
8
8
  - [Installation](#installation)
9
9
  - [Usage](#usage)
10
+ - [Methods](#methods)
10
11
  - [Internationalization](#internationalization)
11
12
  - [Navigation](#navigation)
12
13
  - [Theming](#theming)
14
+ - [User Interface](#user-interface)
15
+ - [Events](#events)
13
16
  - [Error Handling](#error-handling)
14
17
  - [Development](#development)
15
18
 
@@ -38,13 +41,15 @@ initFlipBridge({
38
41
  });
39
42
  ```
40
43
 
44
+ ## Methods
45
+
41
46
  ### Internationalization
42
47
 
43
48
  #### `getAvailableLangs`
44
49
 
45
50
  Get all available languages of the host app.
46
51
 
47
- **Returns** `string[]`
52
+ **Returns** `Promise<string[]>`
48
53
 
49
54
  **Example**
50
55
 
@@ -58,7 +63,7 @@ const availableLanguages = await getAvailableLangs(); // e.g. ['de', 'en', 'fr',
58
63
 
59
64
  Get the current language of the host app.
60
65
 
61
- **Returns** `string`
66
+ **Returns** `Promise<string>`
62
67
 
63
68
  **Example**
64
69
 
@@ -74,7 +79,9 @@ const currentLanguage = await getLang(); // e.g. 'en'
74
79
 
75
80
  Navigate to a specific route.
76
81
 
77
- **Returns** `boolean`
82
+ **Param** `string`
83
+
84
+ **Returns** `Promise<boolean>`
78
85
 
79
86
  **Example**
80
87
 
@@ -93,10 +100,10 @@ Get the current theme.
93
100
  **Returns**
94
101
 
95
102
  ```js
96
- {
103
+ Promise<{
97
104
  activeTheme: "light" | "dark";
98
105
  preferredTheme: "light" | "dark" | undefined;
99
- }
106
+ }>
100
107
  ```
101
108
 
102
109
  **Example**
@@ -107,6 +114,205 @@ import { getTheme } from "@getflip/bridge";
107
114
  const theme = await getTheme();
108
115
  ```
109
116
 
117
+ ### User Interface
118
+
119
+ #### `createDialog`
120
+
121
+ Creates a modal dialog rendered by the host app.
122
+
123
+ **Param**
124
+
125
+ ```js
126
+ {
127
+ hideLabel?: boolean;
128
+ id: string;
129
+ intent?: 'primary' | 'critical';
130
+ label: string;
131
+ text: string;
132
+ primaryAction?: {
133
+ label: string;
134
+ };
135
+ secondaryAction?: {
136
+ label: string;
137
+ };
138
+ }
139
+ ```
140
+
141
+ **Returns**
142
+
143
+ ```js
144
+ Promise<{
145
+ id: string;
146
+ open: () => Promise<boolean>;
147
+ close: () => Promise<boolean>;
148
+ destroy: () => Promise<boolean>;
149
+ }>
150
+ ```
151
+
152
+ **Example**
153
+
154
+ ```js
155
+ import { createDialog } from "@getflip/bridge";
156
+
157
+ const dialog = await createDialog({
158
+ id: "my-dialog",
159
+ label: "My Dialog",
160
+ text: "Lorem ipsum",
161
+ primaryAction: {
162
+ label: "Close",
163
+ },
164
+ });
165
+
166
+ await dialog.open();
167
+ ```
168
+
169
+ #### `openDialog`
170
+
171
+ Opens a dialog.
172
+
173
+ **Param**
174
+
175
+ ```js
176
+ {
177
+ id: string; // the dialog id
178
+ }
179
+ ```
180
+
181
+ **Returns** `Promise<boolean>`
182
+
183
+ **Example**
184
+
185
+ ```js
186
+ import { createDialog, openDialog } from "@getflip/bridge";
187
+
188
+ await createDialog({
189
+ id: "my-dialog",
190
+ label: "My Dialog",
191
+ text: "Lorem ipsum",
192
+ });
193
+
194
+ await openDialog({ id: "my-dialog" });
195
+ ```
196
+
197
+ #### `closeDialog`
198
+
199
+ Closes a dialog.
200
+
201
+ **Param**
202
+
203
+ ```js
204
+ {
205
+ id: string; // the dialog id
206
+ }
207
+ ```
208
+
209
+ **Returns** `Promise<boolean>`
210
+
211
+ **Example**
212
+
213
+ ```js
214
+ import { closeDialog } from "@getflip/bridge";
215
+
216
+ await closeDialog({ id: "my-dialog" });
217
+ ```
218
+
219
+ #### `destroyDialog`
220
+
221
+ Destroys a dialog, removing it from the DOM.
222
+
223
+ **Param**
224
+
225
+ ```js
226
+ {
227
+ id: string; // the dialog id
228
+ }
229
+ ```
230
+
231
+ **Returns** `Promise<boolean>`
232
+
233
+ **Example**
234
+
235
+ ```js
236
+ import { destroyDialog } from "@getflip/bridge";
237
+
238
+ await destroyDialog({ id: "my-dialog" });
239
+ ```
240
+
241
+ ## Events
242
+
243
+ Use the `subscribe` functions to subscribe to events.
244
+
245
+ ```js
246
+ import { subscribe, BridgeEventType } from "@getflip/bridge";
247
+
248
+ const unsubscribe = await subscribe(BridgeEventType.THEME_CHANGE, (event) => {
249
+ console.log(event.data);
250
+ });
251
+
252
+ // …
253
+
254
+ await unsubscribe();
255
+ ```
256
+
257
+ ### `LANG_CHANGE`
258
+
259
+ Fires when the user selected language changes.
260
+
261
+ **Event**
262
+
263
+ ```js
264
+ {
265
+ data: string; // e.g. 'en'
266
+ type: BridgeEventType.LANG_CHANGE;
267
+ }
268
+ ```
269
+
270
+ ### `PRIMARY_ACTION_CLICK`
271
+
272
+ Fires when the primary action button of a dialog or modal is clicked.
273
+
274
+ **Event**
275
+
276
+ ```js
277
+ {
278
+ data: {
279
+ parentId: string; // id of the action's dialog or modal
280
+ }
281
+ type: BridgeEventType.PRIMARY_ACTION_CLICK;
282
+ }
283
+ ```
284
+
285
+ ### `SECONDARY_ACTION_CLICK`
286
+
287
+ Fires when the secondary action button of a dialog or modal is clicked.
288
+
289
+ **Event**
290
+
291
+ ```js
292
+ {
293
+ data: {
294
+ parentId: string; // id of the action's dialog or modal
295
+ }
296
+ type: BridgeEventType.SECONDARY_ACTION_CLICK;
297
+ }
298
+ ```
299
+
300
+ ### `THEME_CHANGE`
301
+
302
+ Fires when the user theme changes.
303
+
304
+ **Event**
305
+
306
+ ```js
307
+ {
308
+ data: {
309
+ activeTheme: "light" | "dark";
310
+ preferredTheme: "light" | "dark" | undefined;
311
+ }
312
+ type: BridgeEventType.THEME_CHANGE;
313
+ }
314
+ ```
315
+
110
316
  ## Error Handling
111
317
 
112
318
  All provided functions return promises that throw an error if the execution
@@ -0,0 +1,10 @@
1
+ import { CloseDialogRequest, CloseDialogRequestParams, CreateDialogRequestParams, DestroyDialogRequest, DestroyDialogRequestParams, OpenDialogRequest, OpenDialogRequestParams } from "./dialog.types";
2
+ export declare function createDialog(params: CreateDialogRequestParams): Promise<{
3
+ id: string;
4
+ open: () => Promise<import("../types").BridgeError | OpenDialogRequest>;
5
+ close: () => Promise<import("../types").BridgeError | CloseDialogRequest>;
6
+ destroy: () => Promise<import("../types").BridgeError | DestroyDialogRequest>;
7
+ } | undefined>;
8
+ export declare function openDialog(params: OpenDialogRequestParams): Promise<import("../types").BridgeError | OpenDialogRequest>;
9
+ export declare function closeDialog(params: CloseDialogRequestParams): Promise<import("../types").BridgeError | CloseDialogRequest>;
10
+ export declare function destroyDialog(params: DestroyDialogRequestParams): Promise<import("../types").BridgeError | DestroyDialogRequest>;
@@ -0,0 +1,45 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import { makeRequest } from "../messaging";
3
+ import { BridgeMethod } from "../types";
4
+ export async function createDialog(params) {
5
+ const request = {
6
+ id: uuidv4(),
7
+ method: BridgeMethod.CREATE_DIALOG,
8
+ params,
9
+ };
10
+ const result = await makeRequest(request);
11
+ if (!result) {
12
+ return;
13
+ }
14
+ return {
15
+ id: params.id,
16
+ open: async () => openDialog({ id: params.id }),
17
+ close: async () => closeDialog({ id: params.id }),
18
+ destroy: async () => destroyDialog({ id: params.id }),
19
+ };
20
+ }
21
+ export async function openDialog(params) {
22
+ const request = {
23
+ id: uuidv4(),
24
+ method: BridgeMethod.OPEN_DIALOG,
25
+ params,
26
+ };
27
+ return makeRequest(request);
28
+ }
29
+ export async function closeDialog(params) {
30
+ const request = {
31
+ id: uuidv4(),
32
+ method: BridgeMethod.CLOSE_DIALOG,
33
+ params,
34
+ };
35
+ return makeRequest(request);
36
+ }
37
+ export async function destroyDialog(params) {
38
+ const request = {
39
+ id: uuidv4(),
40
+ method: BridgeMethod.DESTROY_DIALOG,
41
+ params,
42
+ };
43
+ return makeRequest(request);
44
+ }
45
+ //# sourceMappingURL=dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/dialog/dialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAYxC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAiC;IAClE,MAAM,OAAO,GAAwB;QACnC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,YAAY,CAAC,aAAa;QAClC,MAAM;KACP,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,WAAW,CAAsB,OAAO,CAAC,CAAC;IAE/D,IAAI,CAAC,MAAM,EAAE;QACX,OAAO;KACR;IAED,OAAO;QACL,EAAE,EAAE,MAAM,CAAC,EAAE;QACb,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QAC/C,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;QACjD,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC;KACtD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,MAA+B;IAC9D,MAAM,OAAO,GAAsB;QACjC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,YAAY,CAAC,WAAW;QAChC,MAAM;KACP,CAAC;IAEF,OAAO,WAAW,CAAoB,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAgC;IAChE,MAAM,OAAO,GAAuB;QAClC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,YAAY,CAAC,YAAY;QACjC,MAAM;KACP,CAAC;IAEF,OAAO,WAAW,CAAqB,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,MAAkC;IACpE,MAAM,OAAO,GAAyB;QACpC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,YAAY,CAAC,cAAc;QACnC,MAAM;KACP,CAAC;IAEF,OAAO,WAAW,CAAuB,OAAO,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,83 @@
1
+ import { BridgeMethod } from "../types";
2
+ import { closeDialog, createDialog, destroyDialog, openDialog } from "./dialog";
3
+ jest.mock("../messaging", () => {
4
+ const originalModule = jest.requireActual("../messaging");
5
+ return Object.assign(Object.assign({ __esModule: true }, originalModule), { makeRequest: async (request) => {
6
+ originalModule.makeRequest(request);
7
+ return true;
8
+ } });
9
+ });
10
+ describe("dialog", () => {
11
+ beforeAll(() => {
12
+ global.flipBridgeOptions = { hostAppOrigin: "http://localhost" };
13
+ });
14
+ test("'createDialog' sends correct request", async () => {
15
+ const params = {
16
+ hideLabel: false,
17
+ id: "my-dialog",
18
+ label: "My Dialog",
19
+ text: "Lorem ipsum",
20
+ intent: "critical",
21
+ primaryAction: {
22
+ label: "Primary",
23
+ },
24
+ secondaryAction: {
25
+ label: "Secondary",
26
+ },
27
+ };
28
+ const spy = jest.fn();
29
+ window.top.postMessage = spy;
30
+ const response = await createDialog(params);
31
+ expect(spy).toHaveBeenCalledWith({
32
+ id: spy.mock.calls[0][0].id,
33
+ method: BridgeMethod.CREATE_DIALOG,
34
+ params,
35
+ }, "http://localhost");
36
+ expect(response === null || response === void 0 ? void 0 : response.id).toBe(params.id);
37
+ expect(typeof (response === null || response === void 0 ? void 0 : response.close)).toBe("function");
38
+ expect(typeof (response === null || response === void 0 ? void 0 : response.open)).toBe("function");
39
+ });
40
+ test("'openDialog' sends correct request", async () => {
41
+ const params = {
42
+ id: "my-dialog",
43
+ };
44
+ const spy = jest.fn();
45
+ window.top.postMessage = spy;
46
+ const response = await openDialog(params);
47
+ expect(spy).toHaveBeenCalledWith({
48
+ id: spy.mock.calls[0][0].id,
49
+ method: BridgeMethod.OPEN_DIALOG,
50
+ params,
51
+ }, "http://localhost");
52
+ expect(response).toBe(true);
53
+ });
54
+ test("'closeDialog' sends correct request", async () => {
55
+ const params = {
56
+ id: "my-dialog",
57
+ };
58
+ const spy = jest.fn();
59
+ window.top.postMessage = spy;
60
+ const response = await closeDialog(params);
61
+ expect(spy).toHaveBeenCalledWith({
62
+ id: spy.mock.calls[0][0].id,
63
+ method: BridgeMethod.CLOSE_DIALOG,
64
+ params,
65
+ }, "http://localhost");
66
+ expect(response).toBe(true);
67
+ });
68
+ test("'destroyDialog' sends correct request", async () => {
69
+ const params = {
70
+ id: "my-dialog",
71
+ };
72
+ const spy = jest.fn();
73
+ window.top.postMessage = spy;
74
+ const response = await destroyDialog(params);
75
+ expect(spy).toHaveBeenCalledWith({
76
+ id: spy.mock.calls[0][0].id,
77
+ method: BridgeMethod.DESTROY_DIALOG,
78
+ params,
79
+ }, "http://localhost");
80
+ expect(response).toBe(true);
81
+ });
82
+ });
83
+ //# sourceMappingURL=dialog.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.spec.js","sourceRoot":"","sources":["../../src/dialog/dialog.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { SwirlDialogIntent } from "@getflip/swirl-components/dist/types/components/swirl-dialog/swirl-dialog";
2
+ import { BridgeRequest } from "../messaging/messaging.types";
3
+ import { BridgeMethod } from "../types";
4
+ export type CreateDialogRequestParams = {
5
+ hideLabel?: boolean;
6
+ id: string;
7
+ intent?: SwirlDialogIntent;
8
+ label: string;
9
+ text: string;
10
+ primaryAction?: {
11
+ label: string;
12
+ };
13
+ secondaryAction?: {
14
+ label: string;
15
+ };
16
+ };
17
+ export type OpenDialogRequestParams = {
18
+ id: string;
19
+ };
20
+ export type CloseDialogRequestParams = {
21
+ id: string;
22
+ };
23
+ export type DestroyDialogRequestParams = {
24
+ id: string;
25
+ };
26
+ export type CreateDialogRequest = BridgeRequest<BridgeMethod.CREATE_DIALOG, CreateDialogRequestParams>;
27
+ export type OpenDialogRequest = BridgeRequest<BridgeMethod.OPEN_DIALOG, OpenDialogRequestParams>;
28
+ export type CloseDialogRequest = BridgeRequest<BridgeMethod.CLOSE_DIALOG, CloseDialogRequestParams>;
29
+ export type DestroyDialogRequest = BridgeRequest<BridgeMethod.DESTROY_DIALOG, CloseDialogRequestParams>;
30
+ export type CreateDialogResult = boolean;
31
+ export type OpenDialogResult = boolean;
32
+ export type CloseDialogResult = boolean;
33
+ export type DestroyDialogResult = boolean;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dialog.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.types.js","sourceRoot":"","sources":["../../src/dialog/dialog.types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export * from "./dialog.types";
2
+ export * from "./dialog";
@@ -0,0 +1,3 @@
1
+ export * from "./dialog.types";
2
+ export * from "./dialog";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/dialog/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { BridgeEvent, BridgeEventType, SubscribeOptions, UnsubscribeFunction } from "./events.types";
2
+ export declare function subscribe<EventDataType = unknown>(type: BridgeEventType, callback: (event?: BridgeEvent<EventDataType>) => void, options?: SubscribeOptions): Promise<UnsubscribeFunction>;
3
+ export declare function isEvent(message: Object): message is BridgeEvent;
@@ -0,0 +1,44 @@
1
+ import { v4 as uuidv4 } from "uuid";
2
+ import { log } from "../logging";
3
+ import { isAllowedOrigin, makeRequest } from "../messaging";
4
+ import { BridgeMethod } from "../types";
5
+ import { BridgeEventType, } from "./events.types";
6
+ export async function subscribe(type, callback, options) {
7
+ const subscriptionId = (options === null || options === void 0 ? void 0 : options.id) || uuidv4();
8
+ const subscribeRequest = {
9
+ id: uuidv4(),
10
+ method: BridgeMethod.SUBSCRIBE,
11
+ params: { id: subscriptionId, type },
12
+ };
13
+ const eventHandler = (event) => {
14
+ if (!isAllowedOrigin(event.origin) ||
15
+ !isEvent(event.data) ||
16
+ event.data.type !== type ||
17
+ event.data.id !== subscriptionId) {
18
+ return;
19
+ }
20
+ log("handleEvent", event.data);
21
+ callback(event.data);
22
+ };
23
+ window.addEventListener("message", eventHandler);
24
+ const subscribed = await makeRequest(subscribeRequest);
25
+ if (!subscribed) {
26
+ window.removeEventListener("message", eventHandler);
27
+ throw new Error(`Could not subscribe to event "${type}".`);
28
+ }
29
+ return async () => {
30
+ const unsubscribeRequest = {
31
+ id: uuidv4(),
32
+ method: BridgeMethod.UNSUBSCRIBE,
33
+ params: { id: subscriptionId, type },
34
+ };
35
+ await makeRequest(unsubscribeRequest);
36
+ window.removeEventListener("message", eventHandler);
37
+ };
38
+ }
39
+ export function isEvent(message) {
40
+ return (typeof message === "object" &&
41
+ "type" in message &&
42
+ Object.values(BridgeEventType).includes(message.type));
43
+ }
44
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/events/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAEL,eAAe,GAOhB,MAAM,gBAAgB,CAAC;AAExB,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,IAAqB,EACrB,QAAsD,EACtD,OAA0B;IAE1B,MAAM,cAAc,GAAG,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,EAAE,KAAI,MAAM,EAAE,CAAC;IAE/C,MAAM,gBAAgB,GAAqB;QACzC,EAAE,EAAE,MAAM,EAAE;QACZ,MAAM,EAAE,YAAY,CAAC,SAAS;QAC9B,MAAM,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;KACrC,CAAC;IAEF,MAAM,YAAY,GAAG,CAAC,KAA+C,EAAE,EAAE;QACvE,IACE,CAAC,eAAe,CAAC,KAAK,CAAC,MAAM,CAAC;YAC9B,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI;YACxB,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,cAAc,EAChC;YACA,OAAO;SACR;QAED,GAAG,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE/B,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACvB,CAAC,CAAC;IAEF,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAEjD,MAAM,UAAU,GAAG,MAAM,WAAW,CAAkB,gBAAgB,CAAC,CAAC;IAExE,IAAI,CAAC,UAAU,EAAE;QACf,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,IAAI,CAAC,CAAC;KAC5D;IAED,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,kBAAkB,GAAuB;YAC7C,EAAE,EAAE,MAAM,EAAE;YACZ,MAAM,EAAE,YAAY,CAAC,WAAW;YAChC,MAAM,EAAE,EAAE,EAAE,EAAE,cAAc,EAAE,IAAI,EAAE;SACrC,CAAC;QAEF,MAAM,WAAW,CAAoB,kBAAkB,CAAC,CAAC;QAEzD,MAAM,CAAC,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACtD,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,OAAO,CACL,OAAO,OAAO,KAAK,QAAQ;QAC3B,MAAM,IAAI,OAAO;QACjB,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAuB,CAAC,CACzE,CAAC;AACJ,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,64 @@
1
+ import { subscribe } from "./events";
2
+ import { BridgeEventType } from "./events.types";
3
+ jest.mock("../messaging", () => {
4
+ const originalModule = jest.requireActual("../messaging");
5
+ return Object.assign(Object.assign({ __esModule: true }, originalModule), { makeRequest: async (request) => {
6
+ originalModule.makeRequest(request);
7
+ return true;
8
+ } });
9
+ });
10
+ describe("events", () => {
11
+ beforeEach(() => {
12
+ global.flipBridgeOptions = { hostAppOrigin: "http://localhost" };
13
+ });
14
+ test("'subscribe' sends subscription request", async () => {
15
+ const spy = jest.fn();
16
+ window.top.postMessage = spy;
17
+ subscribe(BridgeEventType.LANG_CHANGE, () => { });
18
+ expect(spy).toHaveBeenCalledWith({
19
+ id: spy.mock.calls[0][0].id,
20
+ method: "SUBSCRIBE",
21
+ params: {
22
+ id: spy.mock.calls[0][0].params.id,
23
+ type: "LANG_CHANGE",
24
+ },
25
+ }, "http://localhost");
26
+ });
27
+ test("'subscribe' registers listener with callback function", async () => {
28
+ const callback = jest.fn();
29
+ const unsubscribe = await subscribe(BridgeEventType.LANG_CHANGE, callback, {
30
+ id: "SUBSCRIPTION_ID",
31
+ });
32
+ global.dispatchEvent(new MessageEvent("message", {
33
+ source: window,
34
+ origin: global.flipBridgeOptions.hostAppOrigin,
35
+ data: {
36
+ data: "DATA",
37
+ id: "SUBSCRIPTION_ID",
38
+ type: BridgeEventType.LANG_CHANGE,
39
+ },
40
+ }));
41
+ expect(callback).toHaveBeenCalledWith({
42
+ data: "DATA",
43
+ id: "SUBSCRIPTION_ID",
44
+ type: "LANG_CHANGE",
45
+ });
46
+ await unsubscribe();
47
+ });
48
+ test("'subscribe' returns function to unsubscribe", async () => {
49
+ const spy = jest.fn();
50
+ window.top.postMessage = spy;
51
+ const unsubscribe = await subscribe(BridgeEventType.LANG_CHANGE, () => { });
52
+ expect(typeof unsubscribe).toBe("function");
53
+ await unsubscribe();
54
+ expect(spy).toHaveBeenCalledWith({
55
+ id: spy.mock.calls[1][0].id,
56
+ method: "UNSUBSCRIBE",
57
+ params: {
58
+ id: spy.mock.calls[1][0].params.id,
59
+ type: "LANG_CHANGE",
60
+ },
61
+ }, "http://localhost");
62
+ });
63
+ });
64
+ //# sourceMappingURL=events.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.spec.js","sourceRoot":"","sources":["../../src/events/events.spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { BridgeRequest } from "../messaging/messaging.types";
2
+ import { BridgeMethod } from "../types";
3
+ export declare enum BridgeEventType {
4
+ PRIMARY_ACTION_CLICK = "PRIMARY_ACTION_CLICK",
5
+ LANG_CHANGE = "LANG_CHANGE",
6
+ SECONDARY_ACTION_CLICK = "SECONDARY_ACTION_CLICK",
7
+ THEME_CHANGE = "THEME_CHANGE"
8
+ }
9
+ export type BridgeEvent<DataType = unknown> = {
10
+ data?: DataType;
11
+ id: string;
12
+ type: BridgeEventType;
13
+ };
14
+ export type SubscribeRequest = BridgeRequest<BridgeMethod.SUBSCRIBE, {
15
+ id: string;
16
+ type: BridgeEventType;
17
+ }>;
18
+ export type UnsubscribeRequest = BridgeRequest<BridgeMethod.UNSUBSCRIBE, {
19
+ id: string;
20
+ type: BridgeEventType;
21
+ }>;
22
+ export type SubscribeResult = boolean;
23
+ export type UnsubscribeResult = boolean;
24
+ export type UnsubscribeFunction = () => Promise<void>;
25
+ export type SubscribeOptions = {
26
+ id?: string;
27
+ };
@@ -0,0 +1,8 @@
1
+ export var BridgeEventType;
2
+ (function (BridgeEventType) {
3
+ BridgeEventType["PRIMARY_ACTION_CLICK"] = "PRIMARY_ACTION_CLICK";
4
+ BridgeEventType["LANG_CHANGE"] = "LANG_CHANGE";
5
+ BridgeEventType["SECONDARY_ACTION_CLICK"] = "SECONDARY_ACTION_CLICK";
6
+ BridgeEventType["THEME_CHANGE"] = "THEME_CHANGE";
7
+ })(BridgeEventType || (BridgeEventType = {}));
8
+ //# sourceMappingURL=events.types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.types.js","sourceRoot":"","sources":["../../src/events/events.types.ts"],"names":[],"mappings":"AAGA,MAAM,CAAN,IAAY,eAKX;AALD,WAAY,eAAe;IACzB,gEAA6C,CAAA;IAC7C,8CAA2B,CAAA;IAC3B,oEAAiD,CAAA;IACjD,gDAA6B,CAAA;AAC/B,CAAC,EALW,eAAe,KAAf,eAAe,QAK1B"}
@@ -0,0 +1,2 @@
1
+ export * from "./events.types";
2
+ export * from "./events";
@@ -0,0 +1,3 @@
1
+ export * from "./events.types";
2
+ export * from "./events";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/events/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,UAAU,CAAC"}
@@ -1,4 +1,5 @@
1
- import { BridgeMethod, BridgeRequest } from "../types";
1
+ import { BridgeMethod } from "../types";
2
+ import { BridgeRequest } from "../messaging/messaging.types";
2
3
  export type GetAvailableLangsRequest = BridgeRequest<BridgeMethod.GET_AVAILABLE_LANGS, undefined>;
3
4
  export type GetAvailableLangsResult = string[];
4
5
  export type GetLangRequest = BridgeRequest<BridgeMethod.GET_LANG, undefined>;