Skip to content

Commit 96596f0

Browse files
committed
Added stuff from FDC3 project for demo -- ready to demo
1 parent 7a7b7aa commit 96596f0

24 files changed

+2193
-63
lines changed

package-lock.json

+31-47
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@
1818
"vite": "^5.0.2"
1919
},
2020
"dependencies": {
21-
"@kite9/fdc3": "2.2.0-beta.23",
22-
"@kite9/fdc3-web-impl": "2.2.0-beta.23",
21+
"@kite9/fdc3": "2.2.0-beta.24",
2322
"@types/react-dom": "^18.2.25",
2423
"@types/uuid": "^9.0.8",
2524
"@types/ws": "^8.5.10",

src/app/util.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { InstanceID } from "@kite9/fdc3-web-impl"
1+
import { InstanceID } from "../ftw/ServerContext"
22
import { Socket } from "socket.io-client"
33
import { FDC3_APP_EVENT, FDC3_DA_EVENT } from "../server/da/message-types"
44

src/client/appd/appd.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Icon } from "../icon/icon";
33
import { getServerState } from "../state/ServerState";
44
import * as styles from "./styles.module.css";
55
import { Popup, PopupButton } from "../popups/popup";
6-
import { DirectoryApp } from "@kite9/fdc3-web-impl";
6+
import { DirectoryApp } from "../../ftw/directory/DirectoryInterface";
77
import { getAppState } from "../state/AppState";
88

99
const DEFAULT_ICON = "/static/icons/control/choose-app.svg";

src/client/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Frame } from "./frame/frame";
22
import { createRoot } from "react-dom/client";
3-
import { getClientState } from "./state/clientState";
3+
import { getClientState } from "./state/ClientState";
44
import { getAppState } from "./state/AppState";
55
import "../../static/fonts/DM_Sans/DM_Sans.css";
66
import { getServerState } from "./state/ServerState";

src/client/state/AppState.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { BrowserTypes } from "@kite9/fdc3";
22
import { getClientState } from "./ClientState"
33
import { getServerState } from "./ServerState"
4-
import { DirectoryApp } from "@kite9/fdc3-web-impl";
4+
import { DirectoryApp } from "../../ftw/directory/DirectoryInterface";
55
import { v4 as uuid } from 'uuid'
66

77
type WebConnectionProtocol1Hello = BrowserTypes.WebConnectionProtocol1Hello

src/client/state/ServerState.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { DirectoryApp } from "@kite9/fdc3-web-impl";
1+
import { DirectoryApp } from "../../ftw";
22
import { getClientState } from "./ClientState";
33
import { DA_DIRECTORY_LISTING, DA_HELLO, DA_REGISTER_APP_LAUNCH, DesktopAgentDirectoryListingArgs, DesktopAgentHelloArgs, DesktopAgentRegisterAppLaunchArgs, SAIL_APP_OPEN, SAIL_CHANNEL_CHANGE, SAIL_INTENT_RESOLVE, SailAppOpenArgs, SailChannelChangeArgs, SailIntentResolveArgs } from "../../server/da/message-types";
44
import { io, Socket } from "socket.io-client"
@@ -20,7 +20,7 @@ export interface ServerState {
2020

2121
getApplications(): Promise<DirectoryApp[]>
2222

23-
setAppChannel(instanceId: string, channel: string): Promise<void>
23+
setUserChannel(instanceId: string, channel: string): Promise<void>
2424

2525
intentChosen(ai: AppIdentifier | null, intent: string | null): Promise<void>
2626
}
@@ -83,7 +83,7 @@ class ServerStateImpl implements ServerState {
8383
})
8484
}
8585

86-
async setAppChannel(instanceId: string): Promise<void> {
86+
async setUserChannel(instanceId: string): Promise<void> {
8787
const userSessionId = getClientState().getUserSessionID()
8888
await fetch("/setAppChannel", {
8989
method: "POST",

src/client/state/clientState.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { ChannelState, DirectoryApp } from "@kite9/fdc3-web-impl"
1+
import { ChannelState, DirectoryApp } from "../../ftw/directory/DirectoryInterface";
22
import { GridStackPosition } from "gridstack"
33
import { v4 as uuidv4 } from 'uuid';
44
import { DesktopAgentHelloArgs } from "../../server/da/message-types";
55
import { AppIntent, Context, DisplayMetadata } from "@kite9/fdc3";
6-
import { ChannelType } from "@kite9/fdc3-web-impl/dist/src/handlers/BroadcastHandler";
6+
import { ChannelType } from "../../ftw/handlers/BroadcastHandler";
77
import { getServerState } from "./ServerState";
88

99
const STORAGE_KEY = "sail-client-state"
@@ -147,7 +147,7 @@ abstract class AbstractClientState implements ClientState {
147147
x: -1,
148148
y: -1,
149149
w: 6,
150-
h: 4,
150+
h: 8,
151151
title: detail.title,
152152
tabId: this.activeTabId,
153153
panelId: instanceId,

src/ftw/BasicFDC3Server.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { FDC3Server } from "./FDC3Server";
2+
import { InstanceID, ServerContext } from "./ServerContext";
3+
import { BroadcastHandler, ChannelState } from "./handlers/BroadcastHandler";
4+
import { IntentHandler } from "./handlers/IntentHandler";
5+
import { Directory } from "./directory/DirectoryInterface";
6+
import { OpenHandler } from "./handlers/OpenHandler";
7+
import { BrowserTypes } from "@kite9/fdc3-schema";
8+
import { HeartbeatHandler } from "./handlers/HeartbeatHandler";
9+
10+
type AppRequestMessage = BrowserTypes.AppRequestMessage
11+
type WebConnectionProtocol4ValidateAppIdentity = BrowserTypes.WebConnectionProtocol4ValidateAppIdentity
12+
13+
export interface MessageHandler {
14+
15+
/**
16+
* Handles an AgentRequestMessage from the messaging source
17+
*/
18+
accept(msg: any, sc: ServerContext<any>, from: InstanceID): void
19+
20+
shutdown(): void
21+
}
22+
23+
/**
24+
* This defers all functionality to either MessageHandler's or the ServerContext objects.
25+
*/
26+
export class BasicFDC3Server implements FDC3Server {
27+
28+
private handlers: MessageHandler[]
29+
private sc: ServerContext<any>
30+
31+
constructor(handlers: MessageHandler[], sc: ServerContext<any>) {
32+
this.handlers = handlers
33+
this.sc = sc;
34+
}
35+
36+
receive(message: AppRequestMessage | WebConnectionProtocol4ValidateAppIdentity, from: InstanceID): void {
37+
// this.sc.log(`MessageReceived: \n ${JSON.stringify(message, null, 2)}`)
38+
this.handlers.forEach(h => h.accept(message, this.sc, from))
39+
}
40+
41+
shutdown(): void {
42+
this.handlers.forEach(h => h.shutdown())
43+
}
44+
}
45+
46+
export class DefaultFDC3Server extends BasicFDC3Server {
47+
48+
constructor(sc: ServerContext<any>, directory: Directory, userChannels: ChannelState[], heartbeats: boolean, intentTimeoutMs: number = 20000, openHandlerTimeoutMs: number = 3000) {
49+
const handlers: MessageHandler[] = [
50+
new BroadcastHandler(userChannels),
51+
new IntentHandler(directory, intentTimeoutMs),
52+
new OpenHandler(directory, openHandlerTimeoutMs),
53+
]
54+
55+
if (heartbeats) {
56+
handlers.push(new HeartbeatHandler(openHandlerTimeoutMs / 4, openHandlerTimeoutMs / 2, openHandlerTimeoutMs))
57+
}
58+
59+
super(handlers, sc)
60+
}
61+
}

src/ftw/FDC3Server.ts

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { InstanceID } from "./ServerContext";
2+
import { BrowserTypes } from "@kite9/fdc3-schema";
3+
4+
type AppRequestMessage = BrowserTypes.AppRequestMessage
5+
6+
export interface FDC3Server {
7+
8+
/**
9+
* Receive an incoming message
10+
*/
11+
receive(message: AppRequestMessage, from: InstanceID): void
12+
13+
}

src/ftw/ServerContext.ts

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
import { AppIntent, AppIdentifier } from "@kite9/fdc3-standard";
2+
import { Context } from "@kite9/fdc3-context";
3+
4+
5+
/**
6+
* This is a unique, long, unguessable string that identifies a particular instance of an app.
7+
* All messages arriving at the desktop agent will have this UUID attached to them.
8+
* It is important that this is unguessable as it is a "password" of sorts used to
9+
* identify the app between reconnections.
10+
*/
11+
export type InstanceID = string
12+
13+
/**
14+
* Handles messaging to apps and opening apps
15+
*/
16+
export interface ServerContext<X extends AppIdentifier> {
17+
18+
/**
19+
* UUID for outgoing message
20+
*/
21+
createUUID(): string;
22+
23+
/**
24+
* Post an outgoing message to a particular app
25+
*/
26+
post(message: object, instanceId: InstanceID): Promise<void>
27+
28+
/**
29+
* Post an outgoing message to a particular app
30+
*/
31+
post(message: object, instanceId: InstanceID): Promise<void>
32+
33+
/**
34+
* Opens a new instance of an application.
35+
* Promise completes once the application window is opened
36+
*/
37+
open(appId: string): Promise<InstanceID>
38+
39+
/**
40+
* Registers a particular instance id with a given app id
41+
*/
42+
setInstanceDetails(uuid: InstanceID, details: X): void
43+
44+
/**
45+
* Returns the UUID for a particular instance of an app.
46+
* This is used in situations where an app is reconnecting to the same desktop agent.
47+
*/
48+
getInstanceDetails(uuid: InstanceID): X | undefined
49+
50+
/**
51+
* Registers an app as connected to the desktop agent.
52+
*/
53+
setAppConnected(app: AppIdentifier): Promise<void>
54+
55+
/**
56+
* Unregisters the app as connected to the desktop agent.
57+
*/
58+
setAppDisconnected(app: AppIdentifier): Promise<void>
59+
60+
/**
61+
* Returns the list of apps open and connected to FDC3 at the current time.
62+
* Note, it is the implementor's job to ensure this list is
63+
* up-to-date in the event of app crashes or disconnections.
64+
*/
65+
getConnectedApps(): Promise<AppIdentifier[]>
66+
67+
/**
68+
* Helper function for determining if an app is currently open and connected to the da
69+
*/
70+
isAppConnected(app: AppIdentifier): Promise<boolean>
71+
72+
/**
73+
* Allows you to write a log message somewhere
74+
*/
75+
log(message: string): void
76+
77+
/**
78+
* Name of the provider of this desktop agent server
79+
*/
80+
provider(): string
81+
82+
/**
83+
* Version of the provider of this desktop agent server
84+
*/
85+
providerVersion(): string
86+
87+
/**
88+
* Supported version of the FDC3 API of the desktop agent server.
89+
*/
90+
fdc3Version(): string
91+
92+
/**
93+
* This is called prior to returning intents to the client. It is a
94+
* an opportunity for the server to either present an intent resolver
95+
* or otherwise mess with the availble intents, or do nothing.
96+
*/
97+
narrowIntents(appIntents: AppIntent[], context: Context): Promise<AppIntent[]>
98+
}

0 commit comments

Comments
 (0)