Skip to content

Commit

Permalink
All 4 tests passing, 10 sec delay at the end
Browse files Browse the repository at this point in the history
  • Loading branch information
robmoffat committed Jul 17, 2024
1 parent 39279cf commit 24c7033
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 43 deletions.
5 changes: 3 additions & 2 deletions packages/client/src/messaging/MessagePortMessaging.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { AppIdentifier } from "@finos/fdc3"
import { AbstractMessaging } from "@kite9/da-proxy"
import { RegisterableListener } from "@kite9/da-proxy/src/listeners/RegisterableListener"
import { RegisterableListener } from "@kite9/da-proxy"
import { v4 as uuidv4 } from "uuid"
import { exchangePostMessage } from "./exchange"

Expand All @@ -9,6 +9,7 @@ export class MessagePortMessaging extends AbstractMessaging {
private readonly appId: AppIdentifier
private readonly mp: MessagePort
private readonly listeners: Map<string, RegisterableListener> = new Map()
deliveryTimeoutMs: number = 10000

constructor(mp: MessagePort, appId: AppIdentifier) {
super()
Expand Down Expand Up @@ -53,7 +54,7 @@ export class MessagePortMessaging extends AbstractMessaging {
}

exchange<X>(message: object, expectedTypeName: string): Promise<X> {
return exchangePostMessage(this.mp, expectedTypeName, message).then(e => {
return exchangePostMessage(this.mp, expectedTypeName, message, this.deliveryTimeoutMs).then(e => {
return e.data as X
});
}
Expand Down
13 changes: 7 additions & 6 deletions packages/client/src/messaging/exchange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/**
* Perform some generalized action and expect a response back via message ports.
*/
export function exchange(p: MessagePort | Window | BroadcastChannel, toType: string, action: () => void): Promise<MessageEvent> {
export function exchange(p: MessagePort | Window | BroadcastChannel, toType: string, action: () => void, timeoutMs: number): Promise<MessageEvent> {
return new Promise((resolve, reject) => {
var done = false;
const listener = (m: Event) => {
Expand All @@ -21,26 +21,27 @@ export function exchange(p: MessagePort | Window | BroadcastChannel, toType: str
setTimeout(() => {
p.removeEventListener("message", listener);
if (!done) {
console.log(`Rejecting after ${timeoutMs}ms`)
reject(new Error(`Didn't receive response ${toType}"`))
}
}, 60000);
}, timeoutMs);
})
}

export function exchangeForMessagePort(p: MessagePort | Window | BroadcastChannel, toType: string, action: () => void): Promise<MessagePort> {
return exchange(p, toType, action).then(x => {
export function exchangeForMessagePort(p: MessagePort | Window | BroadcastChannel, toType: string, action: () => void, timeoutMs: number): Promise<MessagePort> {
return exchange(p, toType, action, timeoutMs).then(x => {
return x.ports[0]
})
}

/**
* Send a message to on a port and wait for one to come back.
*/
export function exchangePostMessage(p: MessagePort | Window | BroadcastChannel, toType: string, contents: any): Promise<any> {
export function exchangePostMessage(p: MessagePort | Window | BroadcastChannel, toType: string, contents: any, timeoutMs: number): Promise<any> {
return exchange(p, toType, () => {
console.log("Posting message: " + JSON.stringify(contents))
p.postMessage(contents);
})
}, timeoutMs)
}


25 changes: 3 additions & 22 deletions packages/client/src/messaging/message-port.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DesktopAgent } from "@finos/fdc3";
import { BasicDesktopAgent, DefaultChannelSupport, DefaultAppSupport, DefaultIntentSupport, DefaultChannel, DefaultHandshakeSupport } from "@kite9/da-proxy";
import { BasicDesktopAgent, DefaultChannelSupport, DefaultAppSupport, DefaultIntentSupport, DefaultHandshakeSupport, StatefulChannel } from "@kite9/da-proxy";
import { APIResponseMessage, FDC3_PORT_TRANSFER_RESPONSE_TYPE, Options, APIResponseMessageIFrame } from "@kite9/fdc3-common"
import { MessagePortMessaging } from "./MessagePortMessaging";
import { DefaultDesktopAgentIntentResolver } from "../intent-resolution/DefaultDesktopAgentIntentResolver";
Expand All @@ -16,7 +16,7 @@ export async function createDesktopAgentAPI(mp: MessagePort, data: APIResponseMe

const intentResolver = options.intentResolver ?? new DefaultDesktopAgentIntentResolver(data.intentResolver)
const channelSelector = options.channelSelector ?? new DefaultDesktopAgentChannelSelector(data.channelSelector)
const userChannelState = buildUserChannelState(messaging)
const userChannelState = [] as StatefulChannel[] //buildUserChannelState(messaging)

const version = "2.0"
const cs = new DefaultChannelSupport(messaging, userChannelState, null, channelSelector)
Expand Down Expand Up @@ -47,7 +47,7 @@ export async function messagePortInit(event: MessageEvent, options: Options): Pr
"&desktopAgentId=" + encodeURIComponent(iframeData.desktopAgentId));
}

const mp = await exchangeForMessagePort(window, FDC3_PORT_TRANSFER_RESPONSE_TYPE, action) as MessagePort
const mp = await exchangeForMessagePort(window, FDC3_PORT_TRANSFER_RESPONSE_TYPE, action, options.waitForMs!!) as MessagePort
return createDesktopAgentAPI(mp, event.data, options);

} else {
Expand All @@ -67,22 +67,3 @@ function openFrame(url: string): Window {
document.body.appendChild(ifrm)
return ifrm.contentWindow!!
}

function buildUserChannelState(messaging: MessagePortMessaging) {
// TODO: Figure out how to set initial user channels.
// Should probably be in the message from the server.
return [
new DefaultChannel(messaging, "one", "user", {
color: "red",
name: "THE RED CHANNEL"
}),
new DefaultChannel(messaging, "two", "user", {
color: "blue",
name: "THE BLUE CHANNEL"
}),
new DefaultChannel(messaging, "three", "user", {
color: "green",
name: "THE GREEN CHANNEL"
})
]
}
4 changes: 2 additions & 2 deletions packages/client/test/features/desktop-agent-strategy.feature
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ Feature: Different Strategies for Accessing the Desktop Agent
Given Parent Window desktop "da" listens for postMessage events in "{window}", returns direct message response
And we wait for a period of "200" ms
And I call getAgentAPI for a promise result with the following options
| setWindowGlobal | fireFdc3Ready |
| true | true |
| setWindowGlobal | fireFdc3Ready | waitForMs |
| true | true | 3000 |
And I refer to "{result}" as "theAPIPromise"
Then the promise "{theAPIPromise}" should resolve
And I call "{result}" with "getInfo"
Expand Down
26 changes: 15 additions & 11 deletions packages/client/test/support/MockFDC3Server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,27 @@ export const EMBED_URL = "http://localhost:8080/static/da/embed.html"

export type ConnectionDetails = {
externalPort: MessagePort,
channel: MessageChannel,
internalPort: MessagePort
server: DefaultFDC3Server
}

export function buildConnection(world: CustomWorld): ConnectionDetails {
const channel = new MessageChannel()
channel.port2.start()
const mc = new MessageChannel()
const internalPort = mc.port1
const externalPort = mc.port2

internalPort.start()

const dir = new BasicDirectory([dummyInstanceId])
const theServer = new DefaultFDC3Server(new TestServerContext(world, channel.port2), dir, "Client Test Server", {})
channel.port2.onmessage = (event) => {
theServer?.receive(event.data, dummyInstanceId)
}
const theServer = new DefaultFDC3Server(new TestServerContext(world, internalPort as any as MessagePort), dir, "Client Test Server", {})

internalPort.addEventListener("message", (e) => {
theServer?.receive((e as any).data, dummyInstanceId)
})

return {
externalPort: channel.port1,
channel: channel,
externalPort: externalPort as any as MessagePort,
internalPort: internalPort as any as MessagePort,
server: theServer
}
}
Expand All @@ -50,8 +54,8 @@ export class MockFDC3Server {

shutdown() {
this.instances.forEach(i => {
i.channel.port1.close()
i.channel.port2.close()
i.externalPort.close()
i.internalPort.close()
})
}

Expand Down

0 comments on commit 24c7033

Please sign in to comment.