SAFE-electron interop

In one of our projects electron needs to communicate with an SAFE stack hosted in a iframe in the renderer. This project prototypes how such a setup might look like.

How does the responding part in electron look?

This is done in the renderer part of a vue electron app.

<script lang="ts" setup>
import { BrowserView } from 'electron';
import { reactive, onMounted, watch, ref } from 'vue';

let iframe: any | HTMLElement = ref({})

enum Msg {
  InitResponse,
  Error
}

interface Message {
  swate: boolean;
  api: string;
  data: any;
}

type MessageHandler = (data: any) => void;

interface SwateAPI {
  handleEvent: (e: MessageEvent) => void;
  [key: string]: MessageHandler;
}

const send = (msg: Msg, data: any = null): void => {
  const toSwate = (data: any): void => {
    const methodName = Msg[msg];
    const content: Message = {swate: true, api: methodName, data: data }
    iframe.value.contentWindow?.postMessage(content, '*');
  };
  switch (msg) {
    case Msg.InitResponse:
      toSwate("Hello from ARCitect!");
      break;
    case Msg.Error:
      toSwate(data);
      break;
    // Add more cases as needed
  }
};

const SwateAPI : SwateAPI = {
  handleEvent: (e: MessageEvent) => {
    if (e.data.swate) {
      const apiHandler = SwateAPI[e.data.api];
      apiHandler(e.data.data);
    }
  },
  Init: (msg: string) => {
    console.log(msg)
    send(Msg.InitResponse)
  }
}

Install pre-requisites

You'll need to install the following pre-requisites in order to build SAFE applications

Starting the application

Before you run the project for the first time only you must install dotnet "local tools" with this command:

dotnet tool restore

To concurrently run the server and the client components in watch mode use the following command:

dotnet run

Then open http://localhost:8080 in your browser.

The build project in root directory contains a couple of different build targets. You can specify them after -- (target name is case-insensitive).

To run concurrently server and client tests in watch mode (you can run this command in parallel to the previous one in new terminal):

dotnet run -- RunTests

Client tests are available under http://localhost:8081 in your browser and server tests are running in watch mode in console.

Finally, there are Bundle and Azure targets that you can use to package your app and deploy to Azure, respectively:

dotnet run -- Bundle
dotnet run -- Azure