Plugin Communication

Each plugin exists inside its own sandbox meaning they cannot communicate with each other. IcePanel provides a communication mechanism which proxies and routes the request between plugins asynchronously.

Exporting methods

Exporting an instance method or static method from a plugins backend component will allow it to be executed by the frontend component or other plugins backend components. For static methods the plugin name is used for identification or for instance methods the id property is used.

See the example below for how to export methods.

import { AppPlugin, IAppPlugin, Export } from '@icepanel/core'

export default class MyApp extends AppPlugin implements IAppPlugin {

  @Export()
  getStatus() {
    return this.state.status
  }

  @Export()
  static getRandomNumber() {
    return Math.random()
  }
}

Then use method or staticMethod to execute methods on the remote plugin.

import { AppPlugin, IAppPlugin, Export } from '@icepanel/core'

export default class MyOtherApp extends AppPlugin implements IAppPlugin {

  async init() {
    const number = await this.engine.staticMethod('my-app', 'getRandomNumber')()
    console.log(`the random number is ${number}`)
  }
}

PubSub topic

You can also create a Topic to publish messages in one direction from one plugin to many. Topics can only be created on the backend component of plugins.

import { EnginePlugin, IEnginePlugin, Topic } from '@icepanel/core'

export default class MyEngine extends EnginePlugin implements IEnginePlugin {

  topic: Topic<{ data: string }>

  async init() {
    await super.init()

    this.topic = this.createTopic('my-topic')
  }

  publishData(data: string) {
    this.topic.publish({ data })
  }
}

PubSub subscription

Once the topic has been created you can listen for messages published to the topic by subscribing on the frontend component or other backend plugins.

import { AppPlugin, IAppPlugin, Subscription } from '@icepanel/core'

export default class MyApp extends AppPlugin implements IAppPlugin {

  sub: Subscription<{ data: string }>

  async init() {
    await super.init()

    this.sub = await this.createEngineSubscription('my-topic')
    this.sub.on('message', data => {
      console.log(data)
    })
  }

  async destroy() {
    await super.destroy()

    if (this.sub) {
      this.sub.destroy()
    }
  }
}