Skip to content

Commit

Permalink
Merge pull request #3 from finos-labs/rob-first-version
Browse files Browse the repository at this point in the history
Created import() loader
  • Loading branch information
robmoffat authored Jul 1, 2023
2 parents 08bcf6e + 1bfbe91 commit e9e3b0a
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 30 deletions.
11 changes: 10 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,24 @@ This is a minimal proof-of-concept for FDC3 For the Web.
- In `\lib`: A minimal implementation called `webc3.ts`. This relies on the `post-message` strategy for communicating between apps and the desktop agent. This supports two functions:
- `supply`: Called by the desktop agent on startup, allows it to supply FDC3 APIs to apps when they ask for one.
- `supply`: Called by the desktop agent on startup, allows it to supply FDC3 APIs to apps when they ask for one. This takes a parameter of a url of a piece of javascript that the App will load in order to initialise it's API.
- `load`: Called (with options) by an FDC3 Aoo to retrieve the API.
- In `\demo`: A fixture for demonstrating the above, containing two apps, `app1` and `app2` and a rudimentary `dummy-desktop-agent` all of which use the `webc3.ts` library.
## Notes
- Since this uses Vite, you can modify the code and see it running the browser immediately.
- This currently only supports FDC3 2.0
## TO DO
- Figure out options, setting global
- Fallback strategy in case FDC3 API isn't available (currently promise never resolves)
- Sanitisation of response from the Desktop Agent
6 changes: 1 addition & 5 deletions src/demo/app1.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { load } from '../lib/webc3'

const options = {

};

function createContext(i: number) {
return {
type: "demo.counter",
Expand All @@ -18,7 +14,7 @@ function createContext(i: number) {
* Can be called any number of times.
*/
async function startBroadcasting() {
const fdc3 = await load(options);
const fdc3 = await load();
for (let index = 0; index < 50; index++) {
setTimeout(() => fdc3.broadcast(createContext(index)), index*1000);
}
Expand Down
6 changes: 1 addition & 5 deletions src/demo/app2.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { load } from '../lib/webc3'

const options = {

};

/**
* This demonstrates using the API via a promise
*/
load(options).then(fdc3 => {
load().then(fdc3 => {
console.log("in promise")
const log = document.getElementById("log");
const msg = document.createElement("p");
Expand Down
4 changes: 3 additions & 1 deletion src/demo/implementation.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,6 @@ class DummyDesktopAgent {
}
}

window.fdc3 = new DummyDesktopAgent()
export default (id) => {
return new DummyDesktopAgent();
}
13 changes: 13 additions & 0 deletions src/lib/loaders/load-with-import.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { DesktopAgent } from "@finos/fdc3";
import { APIResponseMessage, FDC3Initialiser } from "../types";

/**
* This loads the script using an import
*/
export function load(resolve: (da: DesktopAgent) => void, data: APIResponseMessage) {
import(data.url).then(ns => {
const init = ns.default as FDC3Initialiser;
const da = init(data.appIdentifier);
resolve(da);
})
}
16 changes: 16 additions & 0 deletions src/lib/loaders/load-with-script.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { DesktopAgent } from "@finos/fdc3";
import { APIResponseMessage } from "../types";

/**
* This loads the script using a script tag, which is meh.
*/
export function load(resolve: (da: DesktopAgent) => void, data: APIResponseMessage) {
const script = document.createElement('script');
script.onload = function () {
console.log(`FDC3 API Initialised ${JSON.stringify(data)}`);
resolve(window.fdc3);
document.head.removeChild(script);
};
script.src=data.url;
document.head.appendChild(script);
}
22 changes: 6 additions & 16 deletions src/lib/strategies/post-message.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import { AppIdentifier, DesktopAgent} from '@finos/fdc3'
import { AppIdentifierResolver, Strategy } from '../types'
import { APIResponseMessage, AppIdentifierResolver, Strategy } from '../types'
import { load } from '../loaders/load-with-import';

const FDC3_API_REQUEST_MESSAGE_TYPE = 'FDC3-API-Request';
const FDC3_API_RESPONSE_MESSAGE_TYPE = 'FDC3-API-Response';

type APIResponseMessage = {
type: string,
url: string,
appIdentifier: AppIdentifier
}

export const strategy : Strategy = {

Expand Down Expand Up @@ -47,17 +43,11 @@ export const strategy : Strategy = {
window.addEventListener("message", (event) => {
const data : APIResponseMessage = event.data ;
if (data.type == FDC3_API_RESPONSE_MESSAGE_TYPE) {
// next, load the javascript into a script
const script = document.createElement('script');
script.onload = function () {
console.log(`FDC3 API Initialised ${JSON.stringify(data)}`);
resolve(window.fdc3);
document.head.removeChild(script);
};
script.src=data.url;
document.head.appendChild(script);
load(resolve, data);
} else {
reject("Incorrect API Response Message");
}
});
}, {once: true});
});

const da = window.opener;
Expand Down
19 changes: 19 additions & 0 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { AppIdentifier, DesktopAgent} from '@finos/fdc3'
* We need to add options here.
*/
export type Options = {
setWindowGlobal: boolean
}

export const DEFAULT_OPTIONS : Options = {
setWindowGlobal: false
}

export type AppIdentifierResolver = (o: Window) => AppIdentifier;
Expand All @@ -13,4 +17,19 @@ export type AppIdentifierResolver = (o: Window) => AppIdentifier;
export type Strategy = {
supply: (url: string, resolver: AppIdentifierResolver) => void
load: (options: Options) => Promise<DesktopAgent>
}

/**
* When writing an FDC3 implementation, this is the shape of the function
* that should be returned by the DesktopAgent's supply url.
*/
export type FDC3Initialiser = (id: AppIdentifier) => DesktopAgent

/**
* This is the object that the desktop agent must get back to the App.
*/
export type APIResponseMessage = {
type: string,
url: string,
appIdentifier: AppIdentifier
}
4 changes: 2 additions & 2 deletions src/lib/webc3.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DesktopAgent} from '@finos/fdc3'
import { strategy } from './strategies/post-message'
import { AppIdentifierResolver } from './types';
import { AppIdentifierResolver, DEFAULT_OPTIONS, Options } from './types';

/**
* This configures the postMessage listener to respond to requests for desktop agent APIs.
Expand All @@ -13,6 +13,6 @@ export function supply(url: string, resolver: AppIdentifierResolver) {
/**
* This return an FDC3 API. Called by Apps.
*/
export function load(options: any) : Promise<DesktopAgent> {
export function load(options: Options = DEFAULT_OPTIONS) : Promise<DesktopAgent> {
return strategy.load(options);
}

0 comments on commit e9e3b0a

Please sign in to comment.