From 6de067578401d1734b6eed75cdd0c0c425e7bd4c Mon Sep 17 00:00:00 2001 From: Lukasz Ostrowski Date: Fri, 26 Aug 2022 09:24:56 +0200 Subject: [PATCH] Install debug package and add debug messages to AppBridge --- package.json | 19 +++++++------ pnpm-lock.yaml | 12 ++++++++ src/app-bridge/app-bridge.ts | 55 +++++++++++++++++++++++++++++++++--- 3 files changed, 73 insertions(+), 13 deletions(-) diff --git a/package.json b/package.json index b853824..a24e0a1 100644 --- a/package.json +++ b/package.json @@ -17,17 +17,21 @@ "author": "", "license": "ISC", "dependencies": { + "debug": "^4.3.4", "fast-glob": "^3.2.11", "graphql": "^16.5.0", "jose": "^4.8.3", "retes": "^0.32.0", - "uuid": "^8.3.2", - "debug": "^4.3.4" + "uuid": "^8.3.2" }, "devDependencies": { + "@testing-library/dom": "^8.17.1", + "@types/debug": "^4.1.7", "@types/node": "^18.6.5", + "@types/uuid": "^8.3.4", "@typescript-eslint/eslint-plugin": "^5.33.0", "@typescript-eslint/parser": "^5.33.0", + "@vitejs/plugin-react": "^2.0.0", "clean-publish": "^4.0.1", "eslint": "8.21.0", "eslint-config-airbnb": "^19.0.4", @@ -39,18 +43,15 @@ "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-simple-import-sort": "^7.0.0", "husky": "^8.0.1", + "jsdom": "^20.0.0", + "np": "^7.6.1", "prettier": "2.7.1", "tsm": "^2.2.2", "tsup": "^6.2.1", "typescript": "^4.7.4", + "vite": "^3.0.5", "vitest": "^0.21.1", - "watchlist": "^0.3.1", - "np": "^7.6.1", - "@types/uuid": "^8.3.4", - "@testing-library/dom": "^8.17.1", - "@vitejs/plugin-react": "^2.0.0", - "jsdom": "^20.0.0", - "vite": "^3.0.5" + "watchlist": "^0.3.1" }, "lint-staged": { "*.{js,ts,tsx}": "eslint --cache --fix", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d8a1b5e..06fc574 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2,6 +2,7 @@ lockfileVersion: 5.4 specifiers: '@testing-library/dom': ^8.17.1 + '@types/debug': ^4.1.7 '@types/node': ^18.6.5 '@types/uuid': ^8.3.4 '@typescript-eslint/eslint-plugin': ^5.33.0 @@ -44,6 +45,7 @@ dependencies: devDependencies: '@testing-library/dom': 8.17.1 + '@types/debug': 4.1.7 '@types/node': 18.7.1 '@types/uuid': 8.3.4 '@typescript-eslint/eslint-plugin': 5.33.0_njno5y7ry2l2lcmiu4tywxkwnq @@ -547,6 +549,12 @@ packages: resolution: {integrity: sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==} dev: true + /@types/debug/4.1.7: + resolution: {integrity: sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==} + dependencies: + '@types/ms': 0.7.31 + dev: true + /@types/http-cache-semantics/4.0.1: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: true @@ -573,6 +581,10 @@ packages: resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} dev: true + /@types/ms/0.7.31: + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: true + /@types/node/18.7.1: resolution: {integrity: sha512-GKX1Qnqxo4S+Z/+Z8KKPLpH282LD7jLHWJcVryOflnsnH+BtSDfieR6ObwBMwpnNws0bUK8GI7z0unQf9bARNQ==} dev: true diff --git a/src/app-bridge/app-bridge.ts b/src/app-bridge/app-bridge.ts index 8596916..da18d45 100644 --- a/src/app-bridge/app-bridge.ts +++ b/src/app-bridge/app-bridge.ts @@ -1,3 +1,5 @@ +import { debug as createDebug } from "debug"; + import { Actions } from "./actions"; import { AppBridgeState, AppBridgeStateContainer } from "./app-bridge-state"; import { SSR } from "./constants"; @@ -10,7 +12,11 @@ type SubscribeMap = { [type in EventType]: Record>>; }; +const debug = createDebug("AppBridge"); + function eventStateReducer(state: AppBridgeState, event: Events) { + debug("Event reducer received event: %j", event); + switch (event.type) { case EventType.handshake: { return { @@ -69,6 +75,8 @@ export class AppBridge { private combinedOptions = getDefaultOptions(); constructor(options: AppBridgeOptions = {}) { + debug("Constructor called with options: %j", options); + if (SSR) { throw new Error( "AppBridge detected you're running this app in SSR mode. Make sure to call `new AppBridge()` when window object exists." @@ -80,6 +88,8 @@ export class AppBridge { ...options, }; + debug("Resolved combined AppBridge options: %j", this.combinedOptions); + if (!this.refererOrigin) { // TODO probably throw console.warn("document.referrer is empty"); @@ -100,11 +110,15 @@ export class AppBridge { eventType: TEventType, cb: EventCallback ) { + debug("subscribe() called with event %s and callback %s", eventType, cb.name); + const key = Symbol("Callback token"); // @ts-ignore fixme this.subscribeMap[eventType][key] = cb; return () => { + debug("unsubscribe called with event %s and callback %s", eventType, cb.name); + delete this.subscribeMap[eventType][key]; }; } @@ -117,8 +131,12 @@ export class AppBridge { */ unsubscribeAll(eventType?: EventType) { if (eventType) { + debug("unsubscribeAll called with event: %s", eventType); + this.subscribeMap[eventType] = {}; } else { + debug("unsubscribeAll called without argument"); + this.subscribeMap = createEmptySubscribeMap(); } } @@ -127,10 +145,16 @@ export class AppBridge { * Dispatch event to dashboard */ async dispatch(action: T) { + debug("dispatch called with action argument: %j", action); + return new Promise((resolve, reject) => { if (!window.parent) { + debug("window.parent doesnt exist, will throw"); + reject(new Error("Parent window does not exist.")); } else { + debug("Calling window.parent.postMessage with %j", action); + window.parent.postMessage( { type: action.type, @@ -142,7 +166,15 @@ export class AppBridge { let intervalId: number; const unsubscribe = this.subscribe(EventType.response, ({ actionId, ok }) => { + debug( + "Subscribing to %s with action id: %s and status 'ok' is: %s", + EventType.response, + actionId, + ok + ); + if (action.payload.actionId === actionId) { + debug("Received matching action id: %s. Will unsubscribe", actionId); unsubscribe(); clearInterval(intervalId); @@ -170,28 +202,42 @@ export class AppBridge { * Gets current state */ getState() { + debug("getState() called and will return %j", this.state.getState()); + return this.state.getState(); } private setInitialState() { + debug("setInitialState() called"); + const url = new URL(window.location.href); const id = url.searchParams.get("id") || ""; const path = window.location.pathname || ""; const theme: ThemeType = url.searchParams.get("theme") === "light" ? "light" : "dark"; - this.state.setState({ domain: this.combinedOptions.targetDomain, id, path, theme }); + const state = { domain: this.combinedOptions.targetDomain, id, path, theme }; + + debug("setInitialState() will setState with %j", state); + + this.state.setState(state); } private listenOnMessages() { + debug("listenOnMessages() called"); + window.addEventListener( "message", ({ origin, data }: Omit & { data: Events }) => { + debug("Received message from origin: %s and data: %j", origin, data); + if (origin !== this.refererOrigin) { + debug("Origin from message doesnt match refererOrigin. Function will return now"); // TODO what should happen here - be explicit return; } const newState = eventStateReducer(this.state.getState(), data); + debug("Computed new state: %j. Will be set with setState", newState); this.state.setState(newState); /** @@ -200,10 +246,11 @@ export class AppBridge { const { type, payload } = data; if (EventType[type]) { - Object.getOwnPropertySymbols(this.subscribeMap[type]).forEach((key) => + Object.getOwnPropertySymbols(this.subscribeMap[type]).forEach((key) => { // @ts-ignore fixme - this.subscribeMap[type][key](payload) - ); + this.subscribeMap[type][key](payload); + debug("Setting listener for event: %s and payload %j", type, payload); + }); } } );