You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2022/10/10 13:28:06 UTC

[superset] branch master updated: feat(embedded-dashboard): Share Switchboard State for Sending Events from Plugins (#21319)

This is an automated email from the ASF dual-hosted git repository.

villebro pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git


The following commit(s) were added to refs/heads/master by this push:
     new 20b9dc8444 feat(embedded-dashboard): Share Switchboard State for Sending Events from Plugins (#21319)
20b9dc8444 is described below

commit 20b9dc84449969706efb94210bc11b2e43cc9a0f
Author: Shubham Sinha <si...@gmail.com>
AuthorDate: Mon Oct 10 18:57:43 2022 +0530

    feat(embedded-dashboard): Share Switchboard State for Sending Events from Plugins (#21319)
---
 .../packages/superset-ui-switchboard/src/index.ts  |  3 ++
 .../src/switchboard.test.ts                        | 27 +++++++++++++++-
 .../superset-ui-switchboard/src/switchboard.ts     | 36 ++++++++++++++++++++--
 superset-frontend/src/embedded/index.tsx           | 14 ++++-----
 4 files changed, 70 insertions(+), 10 deletions(-)

diff --git a/superset-frontend/packages/superset-ui-switchboard/src/index.ts b/superset-frontend/packages/superset-ui-switchboard/src/index.ts
index adbd7450fc..8e6bef5ff7 100644
--- a/superset-frontend/packages/superset-ui-switchboard/src/index.ts
+++ b/superset-frontend/packages/superset-ui-switchboard/src/index.ts
@@ -17,4 +17,7 @@
  * under the License.
  */
 
+import Switchboard from './switchboard';
+
 export * from './switchboard';
+export default Switchboard;
diff --git a/superset-frontend/packages/superset-ui-switchboard/src/switchboard.test.ts b/superset-frontend/packages/superset-ui-switchboard/src/switchboard.test.ts
index fc9ed46b21..9e36f541e1 100644
--- a/superset-frontend/packages/superset-ui-switchboard/src/switchboard.test.ts
+++ b/superset-frontend/packages/superset-ui-switchboard/src/switchboard.test.ts
@@ -17,7 +17,7 @@
  * under the License.
  */
 
-import { Switchboard } from './switchboard';
+import SingletonSwitchboard, { Switchboard } from './switchboard';
 
 type EventHandler = (event: MessageEvent) => void;
 
@@ -114,6 +114,7 @@ describe('comms', () => {
 
   beforeEach(() => {
     console.debug = jest.fn(); // silencio bruno
+    console.error = jest.fn();
   });
 
   afterEach(() => {
@@ -128,6 +129,30 @@ describe('comms', () => {
     expect(sb).toHaveProperty('debugMode');
   });
 
+  it('singleton', async () => {
+    SingletonSwitchboard.start();
+    expect(console.error).toHaveBeenCalledWith(
+      '[]',
+      'Switchboard not initialised',
+    );
+    SingletonSwitchboard.emit('someEvent', 42);
+    expect(console.error).toHaveBeenCalledWith(
+      '[]',
+      'Switchboard not initialised',
+    );
+    await expect(SingletonSwitchboard.get('failing')).rejects.toThrow(
+      'Switchboard not initialised',
+    );
+    SingletonSwitchboard.init({ port: new MessageChannel().port1 });
+    expect(SingletonSwitchboard).toHaveProperty('name');
+    expect(SingletonSwitchboard).toHaveProperty('debugMode');
+    SingletonSwitchboard.init({ port: new MessageChannel().port1 });
+    expect(console.error).toHaveBeenCalledWith(
+      '[switchboard]',
+      'already initialized',
+    );
+  });
+
   describe('emit', () => {
     it('triggers the method', async () => {
       const channel = new MessageChannel();
diff --git a/superset-frontend/packages/superset-ui-switchboard/src/switchboard.ts b/superset-frontend/packages/superset-ui-switchboard/src/switchboard.ts
index f12c9b6482..2a870e7b69 100644
--- a/superset-frontend/packages/superset-ui-switchboard/src/switchboard.ts
+++ b/superset-frontend/packages/superset-ui-switchboard/src/switchboard.ts
@@ -90,7 +90,7 @@ function isError(message: Message): message is ErrorMessage {
 export class Switchboard {
   port: MessagePort;
 
-  name: string;
+  name = '';
 
   methods: Record<string, Method<any, unknown>> = {};
 
@@ -99,7 +99,23 @@ export class Switchboard {
 
   debugMode: boolean;
 
-  constructor({ port, name = 'switchboard', debug = false }: Params) {
+  private isInitialised: boolean;
+
+  constructor(params?: Params) {
+    if (!params) {
+      return;
+    }
+    this.init(params);
+  }
+
+  init(params: Params) {
+    if (this.isInitialised) {
+      this.logError('already initialized');
+      return;
+    }
+
+    const { port, name = 'switchboard', debug = false } = params;
+
     this.port = port;
     this.name = name;
     this.debugMode = debug;
@@ -122,6 +138,8 @@ export class Switchboard {
         }
       }
     });
+
+    this.isInitialised = true;
   }
 
   private async getMethodResult({
@@ -178,6 +196,10 @@ export class Switchboard {
    */
   get<T = unknown>(method: string, args: unknown = undefined): Promise<T> {
     return new Promise((resolve, reject) => {
+      if (!this.isInitialised) {
+        reject(new Error('Switchboard not initialised'));
+        return;
+      }
       // In order to "call a method" on the other side of the port,
       // we will send a message with a unique id
       const messageId = this.getNewMessageId();
@@ -215,6 +237,10 @@ export class Switchboard {
    * @param args
    */
   emit(method: string, args: unknown = undefined) {
+    if (!this.isInitialised) {
+      this.logError('Switchboard not initialised');
+      return;
+    }
     const message: EmitMessage = {
       switchboardAction: Actions.EMIT,
       method,
@@ -224,6 +250,10 @@ export class Switchboard {
   }
 
   start() {
+    if (!this.isInitialised) {
+      this.logError('Switchboard not initialised');
+      return;
+    }
     this.port.start();
   }
 
@@ -242,3 +272,5 @@ export class Switchboard {
     return `m_${this.name}_${this.incrementor++}`;
   }
 }
+
+export default new Switchboard();
diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx
index df673f24e7..832c76a767 100644
--- a/superset-frontend/src/embedded/index.tsx
+++ b/superset-frontend/src/embedded/index.tsx
@@ -20,7 +20,7 @@ import React, { lazy, Suspense } from 'react';
 import ReactDOM from 'react-dom';
 import { BrowserRouter as Router, Route } from 'react-router-dom';
 import { makeApi, t, logging } from '@superset-ui/core';
-import { Switchboard } from '@superset-ui/switchboard';
+import Switchboard from '@superset-ui/switchboard';
 import { bootstrapData } from 'src/preamble';
 import setupClient from 'src/setup/setupClient';
 import { RootContextProviders } from 'src/views/RootContextProviders';
@@ -176,7 +176,7 @@ window.addEventListener('message', function embeddedPageInitializer(event) {
   if (event.data.handshake === 'port transfer' && port) {
     log('message port received', event);
 
-    const switchboard = new Switchboard({
+    Switchboard.init({
       port,
       name: 'superset',
       debug: debugMode,
@@ -184,7 +184,7 @@ window.addEventListener('message', function embeddedPageInitializer(event) {
 
     let started = false;
 
-    switchboard.defineMethod(
+    Switchboard.defineMethod(
       'guestToken',
       ({ guestToken }: { guestToken: string }) => {
         setupGuestClient(guestToken);
@@ -195,13 +195,13 @@ window.addEventListener('message', function embeddedPageInitializer(event) {
       },
     );
 
-    switchboard.defineMethod('getScrollSize', embeddedApi.getScrollSize);
-    switchboard.defineMethod(
+    Switchboard.defineMethod('getScrollSize', embeddedApi.getScrollSize);
+    Switchboard.defineMethod(
       'getDashboardPermalink',
       embeddedApi.getDashboardPermalink,
     );
-    switchboard.defineMethod('getActiveTabs', embeddedApi.getActiveTabs);
-    switchboard.start();
+    Switchboard.defineMethod('getActiveTabs', embeddedApi.getActiveTabs);
+    Switchboard.start();
   }
 });