Skip to content

Commit bb7b6b5

Browse files
Jake WoodJake Wood
authored andcommitted
feat(handlers): remove ability to have multiple handlers
1 parent 3c1d8bb commit bb7b6b5

5 files changed

Lines changed: 63 additions & 42 deletions

File tree

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ This package provides two sets of functionality:
2020

2121
* Communication to TestBox for user experience purposes
2222
* [Client-side Auto-login][1]
23+
2324
### Base Usage
2425

2526
If you just need the basics of TestBox for your app, you'll use something like this:
@@ -52,6 +53,31 @@ export default function App() {
5253
}
5354
```
5455

56+
### Navigation
57+
58+
If you use react-router, or any kind of client-side routing, you may want to override
59+
our standard navigation behavior. Navigation happens when a user chooses a use case
60+
they want to try out. By default, TestBox will use `window.location` to push the iFrame
61+
to a new URL. You might want to do something more sophisticated.
62+
63+
There are two ways to interact with the browser SDK for events:
64+
65+
```javascript
66+
// Option 1: you can use the config object
67+
startTestBox({
68+
navigateHandler: (url) => {
69+
history.push(url);
70+
}
71+
});
72+
73+
// Option 2: you can set the handler directly
74+
import testbox from "@testboxlab/browser-sdk";
75+
76+
testbox.navigateHandler = (url) => {
77+
history.push(url);
78+
};
79+
```
80+
5581
### Auto-login
5682

5783
If you have opted to use our client-side auto-login functionality, you have a bit

src/config.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export interface TestBoxConfig {
88
healthCheckInterval?: number;
99
window?: Window;
1010

11-
onNavigate?: (url: NavigateEvent) => Promise<void>;
12-
onLogin?: (props: LoginEvent) => Promise<string | boolean>;
11+
navigateHandler?: (url: NavigateEvent) => Promise<void>;
12+
loginHandler?: (props: LoginEvent) => Promise<string | boolean>;
1313
}
1414

1515
declare global {

src/index.ts

Lines changed: 18 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import {
44
isValidIncomingTestBoxMessage,
55
sendMessageToTestBox,
66
} from "./messaging";
7-
import { routeMessage, TestBoxEventRouter } from "./router";
7+
import { routeMessage } from "./router";
88
import { INITIALIZE_REQUEST } from "./messaging/outgoing";
9-
import { IncomingEventHandlers, IncomingEventMap } from "./messaging/incoming";
9+
import { LoginEvent, NavigateEvent } from "./messaging/incoming";
1010

1111
let tbxStarted = false;
12-
let messageHandlers: TestBoxEventRouter = {};
12+
13+
export let navigateHandler: (data: NavigateEvent) => void;
14+
export let loginHandler: (
15+
data: LoginEvent
16+
) => Promise<string | boolean> = async () => false;
1317

1418
export function startTestBox(config?: TestBoxConfig) {
1519
if (tbxStarted) {
@@ -18,18 +22,16 @@ export function startTestBox(config?: TestBoxConfig) {
1822

1923
window.__tbxConfig = config;
2024

21-
if (window.__tbxConfig.onNavigate) {
22-
messageHandlers["navigate"] = [window.__tbxConfig.onNavigate];
25+
if (window.__tbxConfig.navigateHandler) {
26+
navigateHandler = window.__tbxConfig.navigateHandler;
2327
} else {
24-
messageHandlers["navigate"] = [
25-
(data) => {
26-
window.location.href = data.url;
27-
},
28-
];
28+
navigateHandler = (data) => {
29+
window.location.href = data.url;
30+
};
2931
}
3032

31-
if (window.__tbxConfig.onLogin) {
32-
messageHandlers["login"] = [window.__tbxConfig.onLogin];
33+
if (window.__tbxConfig.loginHandler) {
34+
loginHandler = window.__tbxConfig.loginHandler;
3335
}
3436

3537
window.addEventListener("message", (ev) => {
@@ -49,7 +51,10 @@ export function startTestBox(config?: TestBoxConfig) {
4951
return;
5052
}
5153

52-
routeMessage(data, messageHandlers);
54+
routeMessage(data, {
55+
navigate: navigateHandler,
56+
login: loginHandler,
57+
});
5358
});
5459

5560
sendMessageToTestBox(INITIALIZE_REQUEST);
@@ -58,16 +63,4 @@ export function startTestBox(config?: TestBoxConfig) {
5863

5964
export const start = startTestBox;
6065

61-
export function on<K extends keyof IncomingEventHandlers>(
62-
message: K,
63-
handler: IncomingEventHandlers[K]
64-
) {
65-
if (message in messageHandlers) {
66-
messageHandlers[message].push(handler);
67-
} else {
68-
// TODO: TypeScript narrowing does not work here. See if we can fix.
69-
messageHandlers[message] = [handler as any];
70-
}
71-
}
72-
7366
export { TestBoxConfig };

src/router.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,14 @@ import { autoLogin } from "./utils/login";
1212
import { sendMessageToTestBox } from "./messaging";
1313
import { INITIALIZE_ACK, LOGIN_ACK, NAVIGATE_ACK } from "./messaging/outgoing";
1414

15-
export type TestBoxEventRouter = {
16-
[K in keyof IncomingEventHandlers]?: IncomingEventHandlers[K][];
17-
};
18-
1915
let loggingIn = false;
2016
let navigateUrl = "";
2117

2218
// Note to future selves: you cannot destructure testbox here, the
2319
// type narrowing does not work correctly if you do so here.
2420
export function routeMessage(
2521
{ testbox }: UnionedIncomingMessages,
26-
router: TestBoxEventRouter
22+
router: Partial<IncomingEventHandlers>
2723
) {
2824
const { event, data } = testbox;
2925
if (VALID_INCOMING_EVENTS.includes(event)) {
@@ -37,8 +33,10 @@ export function routeMessage(
3733
if (loggingIn) {
3834
navigateUrl = data.url;
3935
} else {
40-
const navigateFunc = router["navigate"][0];
41-
navigateFunc(data);
36+
const func = router["navigate"];
37+
if (func) {
38+
func(data);
39+
}
4240
}
4341
break;
4442
case LOGIN:
@@ -48,8 +46,10 @@ export function routeMessage(
4846
loggingIn = false;
4947
const goTo = navigateUrl || nextUrl;
5048
if (goTo && goTo !== window.location.href) {
51-
const navigateFunc = router["navigate"][0];
52-
navigateFunc({ url: goTo });
49+
const func = router["navigate"];
50+
if (func) {
51+
func({ url: goTo });
52+
}
5353
}
5454
});
5555
break;

src/utils/login.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
import { sendMessageToTestBox } from "../messaging";
22
import { LOGIN_FAIL, LOGIN_SUCCESS } from "../messaging/outgoing";
3-
import { TestBoxEventRouter } from "../router";
4-
import { LoginEvent } from "../messaging/incoming";
3+
import { IncomingEventHandlers, LoginEvent } from "../messaging/incoming";
54

65
export let loggingIn = false;
76

8-
export async function autoLogin(data: LoginEvent, router: TestBoxEventRouter) {
7+
export async function autoLogin(
8+
data: LoginEvent,
9+
router: Partial<IncomingEventHandlers>
10+
) {
911
let nextUrl: string | boolean;
1012
loggingIn = true;
1113
try {
12-
const funcs = router["login"];
13-
if (!funcs) {
14+
const func = router["login"];
15+
if (!func) {
1416
console.log("No login callback exists!");
1517
sendMessageToTestBox(LOGIN_FAIL);
1618
return;
1719
}
18-
nextUrl = await Promise.any(funcs.map((func) => func(data)));
20+
nextUrl = await func(data);
1921
} catch (e) {
2022
console.log(e);
2123
nextUrl = false;

0 commit comments

Comments
 (0)