From 2b20e62cabfd24abce32b2413af6e9272f9337e5 Mon Sep 17 00:00:00 2001 From: Giles Roadnight <10414642+Roaders@users.noreply.github.com> Date: Fri, 19 Jul 2024 15:30:28 +0100 Subject: [PATCH 01/12] Use TS Morph to generate type predicates --- code-generation/generate-type-predicates.ts | 50 ++++++++++++++ code-generation/tsconfig.json | 37 +++++++++++ package-lock.json | 73 +++++++++++++++++++++ package.json | 6 +- 4 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 code-generation/generate-type-predicates.ts create mode 100644 code-generation/tsconfig.json diff --git a/code-generation/generate-type-predicates.ts b/code-generation/generate-type-predicates.ts new file mode 100644 index 000000000..b68424339 --- /dev/null +++ b/code-generation/generate-type-predicates.ts @@ -0,0 +1,50 @@ +import { InterfaceDeclaration, MethodDeclaration, Project, SyntaxKind } from "ts-morph" + +// open a new project with just BrowserTypes as the only source file +const project = new Project(); +const sourceFile = project.addSourceFileAtPath("./src/api/BrowserTypes.ts") + +//get a list of all interfaces in the file +const interfaces = sourceFile.getChildrenOfKind(SyntaxKind.InterfaceDeclaration); + +// get a list of all conversion functions in the Convert class +const convert = sourceFile.getClass("Convert"); +const convertFunctions = (convert?.getChildrenOfKind(SyntaxKind.MethodDeclaration) ?? []).filter(func => func.getReturnType().getText() === "string"); + +// generate a list of Interfaces that have an associated conversion function +const matchedInterfaces = convertFunctions.map(func => { + const valueParameter = func.getParameter("value"); + + const matchingInterface = interfaces.find(interfaceNode => { + return valueParameter?.getType().getText(valueParameter) === interfaceNode.getName(); + }); + + + if(matchingInterface != null) { + return {func, matchingInterface}; + } + + return undefined; +}).filter(((value => value != null) as (value: T | null | undefined) => value is T)); + +// write a type predicate for each matched interface +matchedInterfaces.forEach(matched => writePredicate(matched.matchingInterface, matched.func)); + + +function writePredicate(matchingInterface: InterfaceDeclaration, func: MethodDeclaration): void{ + const predicateName = `is${matchingInterface.getName()}`; + + sourceFile.addStatements(`export function ${predicateName}(value: any): value is ${matchingInterface.getName()} { + try{ + Convert.${func.getName()}(value); + return true; + } catch(e: any){ + return false; + } +}`); + +} + +sourceFile.formatText(); + +project.saveSync(); diff --git a/code-generation/tsconfig.json b/code-generation/tsconfig.json new file mode 100644 index 000000000..7153e3e16 --- /dev/null +++ b/code-generation/tsconfig.json @@ -0,0 +1,37 @@ +{ + // see https://www.typescriptlang.org/tsconfig to better understand tsconfigs + "files": ["generate-type-predicates.ts"], + "compilerOptions": { + "module": "CommonJS", + "lib": ["dom", "esnext"], + "importHelpers": true, + // output .d.ts declaration files for consumers + "declaration": true, + "outDir": "dist", + // output .js.map sourcemap files for consumers + "sourceMap": true, + // match output dir to input dir. e.g. dist/index instead of dist/src/index + "rootDir": "./", + // stricter type-checking for stronger correctness. Recommended by TS + "strict": true, + // linter checks for common issues + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + // noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative + "noUnusedLocals": true, + "noUnusedParameters": true, + // use Node's module resolution algorithm, instead of the legacy TS one + "moduleResolution": "node", + // transpile JSX to React.createElement + "jsx": "react", + // interop between ESM and CJS modules. Recommended by TS + "esModuleInterop": true, + // significant perf increase by skipping checking .d.ts files, particularly those in node_modules. Recommended by TS + "skipLibCheck": true, + // error out if import and file system have a casing mismatch. Recommended by TS + "forceConsistentCasingInFileNames": true, + // `tsdx build` ignores this option, but it is commonly used when type-checking separately with `tsc` + "noEmit": true, + } + } + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index bf8bd2ebf..1fe6e927e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,8 @@ "rimraf": "^5.0.5", "rollup": "4.22.4", "ts-jest": "29.1.2", + "ts-morph": "^23.0.0", + "ts-node": "^10.9.2", "tslib": "^2.0.1", "typescript": "^4.0.3" }, @@ -1898,6 +1900,35 @@ "node": ">= 10" } }, + "node_modules/@ts-morph/common": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.24.0.tgz", + "integrity": "sha512-c1xMmNHWpNselmpIqursHeOHHBTIsJLbB+NuovbTTRCNiTLEr/U9dbJ8qy0jd/O2x5pc3seWuOUN5R2IoOTp8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.2", + "minimatch": "^9.0.4", + "mkdirp": "^3.0.1", + "path-browserify": "^1.0.1" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -3169,6 +3200,13 @@ "node": ">= 0.12.0" } }, + "node_modules/code-block-writer": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/code-block-writer/-/code-block-writer-13.0.1.tgz", + "integrity": "sha512-c5or4P6erEA69TxaxTNcHUNcIn+oyxSRTOWV+pSYF+z4epXqNvwvJ70XPGjPNgue83oAFAPBRQYwpAJ/Hpe/Sg==", + "dev": true, + "license": "MIT" + }, "node_modules/collect-v8-coverage": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", @@ -6690,6 +6728,22 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/moment": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", @@ -7014,6 +7068,13 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, "node_modules/path-equal": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/path-equal/-/path-equal-1.2.5.tgz", @@ -8413,11 +8474,23 @@ } } }, + "node_modules/ts-morph": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/ts-morph/-/ts-morph-23.0.0.tgz", + "integrity": "sha512-FcvFx7a9E8TUe6T3ShihXJLiJOiqyafzFKUO4aqIHDUCIvADdGNShcbc2W5PMr3LerXRv7mafvFZ9lRENxJmug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ts-morph/common": "~0.24.0", + "code-block-writer": "^13.0.1" + } + }, "node_modules/ts-node": { "version": "10.9.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", "dev": true, + "license": "MIT", "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", diff --git a/package.json b/package.json index be3b08bb4..2cc179f6f 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,9 @@ "prepack": "npm run build", "typegen": "cd schemas && node ../s2tQuicktypeUtil.js context ../src/context/ContextTypes.ts", "typegen-browser": "cd schemas && node ../s2tQuicktypeUtil.js api/api.schema.json api/common.schema.json context/context.schema.json api ../src/api/BrowserTypes.ts", - "typegen-bridging": "cd schemas && node ../s2tQuicktypeUtil.js api/api.schema.json api/common.schema.json api/broadcastRequest.schema.json api/findInstancesRequest.schema.json api/findInstancesResponse.schema.json api/findIntentRequest.schema.json api/findIntentResponse.schema.json api/findIntentsByContextRequest.schema.json api/findIntentsByContextResponse.schema.json api/getAppMetadataRequest.schema.json api/getAppMetadataResponse.schema.json api/openRequest.schema.json api/openResponse.schema.json api/raiseIntentRequest.schema.json api/raiseIntentResponse.schema.json api/raiseIntentResultResponse.schema.json context/context.schema.json bridging ../src/bridging/BridgingTypes.ts" + "typegen-bridging": "cd schemas && node ../s2tQuicktypeUtil.js api/api.schema.json api/common.schema.json api/broadcastRequest.schema.json api/findInstancesRequest.schema.json api/findInstancesResponse.schema.json api/findIntentRequest.schema.json api/findIntentResponse.schema.json api/findIntentsByContextRequest.schema.json api/findIntentsByContextResponse.schema.json api/getAppMetadataRequest.schema.json api/getAppMetadataResponse.schema.json api/openRequest.schema.json api/openResponse.schema.json api/raiseIntentRequest.schema.json api/raiseIntentResponse.schema.json api/raiseIntentResultResponse.schema.json context/context.schema.json bridging ../src/bridging/BridgingTypes.ts", + "posttypegen-browser": "npm run generate-type-predicates", + "generate-type-predicates": "ts-node code-generation/generate-type-predicates.ts" }, "husky": { "hooks": { @@ -65,6 +67,8 @@ "rimraf": "^5.0.5", "rollup": "4.22.4", "ts-jest": "29.1.2", + "ts-morph": "^23.0.0", + "ts-node": "^10.9.2", "tslib": "^2.0.1", "typescript": "^4.0.3" }, From 6cf70dcac3096b6104417d613ed87516cacd3592 Mon Sep 17 00:00:00 2001 From: Giles Roadnight <10414642+Roaders@users.noreply.github.com> Date: Tue, 15 Oct 2024 12:33:42 +0100 Subject: [PATCH 02/12] Add union types of different message classes --- code-generation/generate-type-predicates.ts | 16 +- src/api/BrowserTypes.ts | 805 +++++++++++++++++++- src/api/DesktopAgent.ts | 1 - src/context/ContextTypes.ts | 97 ++- 4 files changed, 832 insertions(+), 87 deletions(-) diff --git a/code-generation/generate-type-predicates.ts b/code-generation/generate-type-predicates.ts index b68424339..4d548bf13 100644 --- a/code-generation/generate-type-predicates.ts +++ b/code-generation/generate-type-predicates.ts @@ -30,11 +30,15 @@ const matchedInterfaces = convertFunctions.map(func => { // write a type predicate for each matched interface matchedInterfaces.forEach(matched => writePredicate(matched.matchingInterface, matched.func)); +writeUnionType("RequestMessage", interfaces, "Request"); +writeUnionType("ResponseMessage", interfaces, "Response"); +writeUnionType("EventMessage", interfaces, "Event"); function writePredicate(matchingInterface: InterfaceDeclaration, func: MethodDeclaration): void{ const predicateName = `is${matchingInterface.getName()}`; - sourceFile.addStatements(`export function ${predicateName}(value: any): value is ${matchingInterface.getName()} { + sourceFile.addStatements(` +export function ${predicateName}(value: any): value is ${matchingInterface.getName()} { try{ Convert.${func.getName()}(value); return true; @@ -42,7 +46,17 @@ function writePredicate(matchingInterface: InterfaceDeclaration, func: MethodDec return false; } }`); +} + + + +function writeUnionType(unionName: string, interfaces: InterfaceDeclaration[], nameEndsWith: string): void{ + const matchingInterfaces = interfaces + .map(currentInterface => currentInterface.getName()) + .filter(interfaceName => interfaceName.length > nameEndsWith.length && interfaceName.indexOf(nameEndsWith) === interfaceName.length - nameEndsWith.length); + sourceFile.addStatements(` +export type ${unionName} = ${matchingInterfaces.join(" | ")};`); } sourceFile.formatText(); diff --git a/src/api/BrowserTypes.ts b/src/api/BrowserTypes.ts index 36c6ff536..3cb8616b5 100644 --- a/src/api/BrowserTypes.ts +++ b/src/api/BrowserTypes.ts @@ -123,7 +123,7 @@ export interface AddContextListenerRequestMeta { * purposes but a Desktop Agent should make its own determination of the source of a message * to avoid spoofing. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -226,13 +226,13 @@ export interface AddContextListenerResponse { * Metadata for messages sent by a Desktop Agent to an App in response to an API call */ export interface AddContextListenerResponseMeta { - requestUuid: string; + requestUuid: string; responseUuid: string; /** * Field that represents the source application that the request being responded to was * received from, for debugging purposes. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -242,7 +242,7 @@ export interface AddContextListenerResponseMeta { * unsuccessful. */ export interface AddContextListenerResponsePayload { - error?: PurpleError; + error?: PurpleError; listenerUUID?: string; } @@ -332,7 +332,7 @@ export interface AddEventListenerResponse { * unsuccessful. */ export interface AddEventListenerResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; listenerUUID?: string; } @@ -417,7 +417,7 @@ export interface AddIntentListenerResponse { * unsuccessful. */ export interface AddIntentListenerResponsePayload { - error?: FluffyError; + error?: FluffyError; listenerUUID?: string; [property: string]: any; } @@ -496,13 +496,13 @@ export interface AgentResponseMessage { * Metadata for messages sent by a Desktop Agent to an App in response to an API call */ export interface AgentResponseMessageMeta { - requestUuid: string; + requestUuid: string; responseUuid: string; /** * Field that represents the source application that the request being responded to was * received from, for debugging purposes. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -552,7 +552,7 @@ export interface AppRequestMessageMeta { * purposes but a Desktop Agent should make its own determination of the source of a message * to avoid spoofing. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -923,7 +923,7 @@ export interface CreatePrivateChannelResponse { * unsuccessful. */ export interface CreatePrivateChannelResponsePayload { - error?: PurpleError; + error?: PurpleError; privateChannel?: Channel; } @@ -1343,7 +1343,7 @@ export interface Fdc3UserInterfaceResolvePayload { * An array of AppIntent objects defining the resolution options. */ appIntents: AppIntent[]; - context: Context; + context: Context; } /** @@ -1693,7 +1693,7 @@ export interface FindInstancesResponse { * resulted in an error and including a standardized error message. */ export interface FindInstancesResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIdentifiers?: AppMetadata[]; } @@ -1754,8 +1754,8 @@ export interface FindIntentRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentRequestPayload { - context?: Context; - intent: string; + context?: Context; + intent: string; resultType?: string; } @@ -1794,7 +1794,7 @@ export interface FindIntentResponse { * unsuccessful. */ export interface FindIntentResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIntent?: AppIntent; } @@ -1829,7 +1829,7 @@ export interface FindIntentsByContextRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentsByContextRequestPayload { - context: Context; + context: Context; resultType?: string; } @@ -1868,7 +1868,7 @@ export interface FindIntentsByContextResponse { * unsuccessful. */ export interface FindIntentsByContextResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIntents?: AppIntent[]; } @@ -1940,7 +1940,7 @@ export interface GetAppMetadataResponse { * unsuccessful. */ export interface GetAppMetadataResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appMetadata?: AppMetadata; } @@ -2012,7 +2012,7 @@ export interface GetCurrentChannelResponse { * unsuccessful. */ export interface GetCurrentChannelResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; channel?: Channel | null; } @@ -2170,7 +2170,7 @@ export interface GetInfoResponse { * unsuccessful. */ export interface GetInfoResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; implementationMetadata?: ImplementationMetadata; } @@ -2304,7 +2304,7 @@ export interface GetOrCreateChannelResponse { * unsuccessful. */ export interface GetOrCreateChannelResponsePayload { - error?: PurpleError; + error?: PurpleError; channel?: Channel; } @@ -2375,7 +2375,7 @@ export interface GetUserChannelsResponse { * unsuccessful. */ export interface GetUserChannelsResponsePayload { - error?: PurpleError; + error?: PurpleError; userChannels?: Channel[]; } @@ -2598,7 +2598,7 @@ export interface IntentResultRequestPayload { * The eventUuid value of the intentEvent that the result being sent relates to. */ intentEventUuid: string; - intentResult: IntentResult; + intentResult: IntentResult; /** * The requestUuid value of the raiseIntentRequest that the result being sent relates to. */ @@ -2861,7 +2861,7 @@ export interface OpenResponse { * unsuccessful. */ export interface OpenResponsePayload { - error?: OpenErrorResponsePayload; + error?: OpenErrorResponsePayload; appIdentifier?: AppIdentifier; } @@ -2957,7 +2957,7 @@ export interface PrivateChannelAddEventListenerResponse { * unsuccessful. */ export interface PrivateChannelAddEventListenerResponsePayload { - error?: PurpleError; + error?: PurpleError; listenerUUID?: string; [property: string]: any; } @@ -3250,7 +3250,7 @@ export interface RaiseIntentForContextRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface RaiseIntentForContextRequestPayload { - app?: AppIdentifier; + app?: AppIdentifier; context: Context; } @@ -3389,9 +3389,9 @@ export interface RaiseIntentRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface RaiseIntentRequestPayload { - app?: AppIdentifier; + app?: AppIdentifier; context: Context; - intent: string; + intent: string; } /** @@ -3494,7 +3494,7 @@ export interface RaiseIntentResultResponse { * unsuccessful. */ export interface RaiseIntentResultResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; intentResult?: IntentResult; } @@ -3532,7 +3532,7 @@ export interface WebConnectionProtocol1Hello { */ export interface WebConnectionProtocol1HelloMeta { connectionAttemptUuid: string; - timestamp: Date; + timestamp: Date; } /** @@ -3845,7 +3845,7 @@ export interface WebConnectionProtocolMessage { * Metadata for this connection step message */ export interface WebConnectionProtocolMessageMeta { - timestamp: Date; + timestamp: Date; connectionAttemptUuid?: string; } @@ -4558,7 +4558,7 @@ function transform(val: any, typ: any, getProps: any, key: any = '', parent: any const typ = typs[i]; try { return transform(val, typ, getProps); - } catch (_) {} + } catch (_) { } } return invalidValue(typs, val, key, parent); } @@ -4617,9 +4617,9 @@ function transform(val: any, typ: any, getProps: any, key: any = '', parent: any if (Array.isArray(typ)) return transformEnum(typ, val); if (typeof typ === "object") { return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) - : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) - : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) - : invalidValue(typ, val, key, parent); + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val, key, parent); } // Numbers can be parsed by Date but shouldn't be. if (typ === Date && typeof val !== "number") return transformDate(val); @@ -5861,3 +5861,738 @@ const typeMap: any = { "WCP6Goodbye", ], }; + +export function isAddContextListenerRequest(value: any): value is AddContextListenerRequest { + try { + Convert.addContextListenerRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAddContextListenerResponse(value: any): value is AddContextListenerResponse { + try { + Convert.addContextListenerResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAddEventListenerRequest(value: any): value is AddEventListenerRequest { + try { + Convert.addEventListenerRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAddEventListenerResponse(value: any): value is AddEventListenerResponse { + try { + Convert.addEventListenerResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAddIntentListenerRequest(value: any): value is AddIntentListenerRequest { + try { + Convert.addIntentListenerRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAddIntentListenerResponse(value: any): value is AddIntentListenerResponse { + try { + Convert.addIntentListenerResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAgentEventMessage(value: any): value is AgentEventMessage { + try { + Convert.agentEventMessageToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAgentResponseMessage(value: any): value is AgentResponseMessage { + try { + Convert.agentResponseMessageToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isAppRequestMessage(value: any): value is AppRequestMessage { + try { + Convert.appRequestMessageToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isBroadcastEvent(value: any): value is BroadcastEvent { + try { + Convert.broadcastEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isBroadcastRequest(value: any): value is BroadcastRequest { + try { + Convert.broadcastRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isBroadcastResponse(value: any): value is BroadcastResponse { + try { + Convert.broadcastResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isChannelChangedEvent(value: any): value is ChannelChangedEvent { + try { + Convert.channelChangedEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isContextListenerUnsubscribeRequest(value: any): value is ContextListenerUnsubscribeRequest { + try { + Convert.contextListenerUnsubscribeRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isContextListenerUnsubscribeResponse(value: any): value is ContextListenerUnsubscribeResponse { + try { + Convert.contextListenerUnsubscribeResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isCreatePrivateChannelRequest(value: any): value is CreatePrivateChannelRequest { + try { + Convert.createPrivateChannelRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isCreatePrivateChannelResponse(value: any): value is CreatePrivateChannelResponse { + try { + Convert.createPrivateChannelResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isEventListenerUnsubscribeRequest(value: any): value is EventListenerUnsubscribeRequest { + try { + Convert.eventListenerUnsubscribeRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isEventListenerUnsubscribeResponse(value: any): value is EventListenerUnsubscribeResponse { + try { + Convert.eventListenerUnsubscribeResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceChannels(value: any): value is Fdc3UserInterfaceChannels { + try { + Convert.fdc3UserInterfaceChannelsToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceChannelSelected(value: any): value is Fdc3UserInterfaceChannelSelected { + try { + Convert.fdc3UserInterfaceChannelSelectedToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceDrag(value: any): value is Fdc3UserInterfaceDrag { + try { + Convert.fdc3UserInterfaceDragToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceHandshake(value: any): value is Fdc3UserInterfaceHandshake { + try { + Convert.fdc3UserInterfaceHandshakeToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceHello(value: any): value is Fdc3UserInterfaceHello { + try { + Convert.fdc3UserInterfaceHelloToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceMessage(value: any): value is Fdc3UserInterfaceMessage { + try { + Convert.fdc3UserInterfaceMessageToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceResolve(value: any): value is Fdc3UserInterfaceResolve { + try { + Convert.fdc3UserInterfaceResolveToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceResolveAction(value: any): value is Fdc3UserInterfaceResolveAction { + try { + Convert.fdc3UserInterfaceResolveActionToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFdc3UserInterfaceRestyle(value: any): value is Fdc3UserInterfaceRestyle { + try { + Convert.fdc3UserInterfaceRestyleToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFindInstancesRequest(value: any): value is FindInstancesRequest { + try { + Convert.findInstancesRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFindInstancesResponse(value: any): value is FindInstancesResponse { + try { + Convert.findInstancesResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFindIntentRequest(value: any): value is FindIntentRequest { + try { + Convert.findIntentRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFindIntentResponse(value: any): value is FindIntentResponse { + try { + Convert.findIntentResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFindIntentsByContextRequest(value: any): value is FindIntentsByContextRequest { + try { + Convert.findIntentsByContextRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isFindIntentsByContextResponse(value: any): value is FindIntentsByContextResponse { + try { + Convert.findIntentsByContextResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetAppMetadataRequest(value: any): value is GetAppMetadataRequest { + try { + Convert.getAppMetadataRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetAppMetadataResponse(value: any): value is GetAppMetadataResponse { + try { + Convert.getAppMetadataResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetCurrentChannelRequest(value: any): value is GetCurrentChannelRequest { + try { + Convert.getCurrentChannelRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetCurrentChannelResponse(value: any): value is GetCurrentChannelResponse { + try { + Convert.getCurrentChannelResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetCurrentContextRequest(value: any): value is GetCurrentContextRequest { + try { + Convert.getCurrentContextRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetCurrentContextResponse(value: any): value is GetCurrentContextResponse { + try { + Convert.getCurrentContextResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetInfoRequest(value: any): value is GetInfoRequest { + try { + Convert.getInfoRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetInfoResponse(value: any): value is GetInfoResponse { + try { + Convert.getInfoResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetOrCreateChannelRequest(value: any): value is GetOrCreateChannelRequest { + try { + Convert.getOrCreateChannelRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetOrCreateChannelResponse(value: any): value is GetOrCreateChannelResponse { + try { + Convert.getOrCreateChannelResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetUserChannelsRequest(value: any): value is GetUserChannelsRequest { + try { + Convert.getUserChannelsRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isGetUserChannelsResponse(value: any): value is GetUserChannelsResponse { + try { + Convert.getUserChannelsResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isHeartbeatAcknowledgementRequest(value: any): value is HeartbeatAcknowledgementRequest { + try { + Convert.heartbeatAcknowledgementRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isHeartbeatEvent(value: any): value is HeartbeatEvent { + try { + Convert.heartbeatEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isIntentEvent(value: any): value is IntentEvent { + try { + Convert.intentEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isIntentListenerUnsubscribeRequest(value: any): value is IntentListenerUnsubscribeRequest { + try { + Convert.intentListenerUnsubscribeRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isIntentListenerUnsubscribeResponse(value: any): value is IntentListenerUnsubscribeResponse { + try { + Convert.intentListenerUnsubscribeResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isIntentResultRequest(value: any): value is IntentResultRequest { + try { + Convert.intentResultRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isIntentResultResponse(value: any): value is IntentResultResponse { + try { + Convert.intentResultResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isJoinUserChannelRequest(value: any): value is JoinUserChannelRequest { + try { + Convert.joinUserChannelRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isJoinUserChannelResponse(value: any): value is JoinUserChannelResponse { + try { + Convert.joinUserChannelResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isLeaveCurrentChannelRequest(value: any): value is LeaveCurrentChannelRequest { + try { + Convert.leaveCurrentChannelRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isLeaveCurrentChannelResponse(value: any): value is LeaveCurrentChannelResponse { + try { + Convert.leaveCurrentChannelResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isOpenRequest(value: any): value is OpenRequest { + try { + Convert.openRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isOpenResponse(value: any): value is OpenResponse { + try { + Convert.openResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelAddEventListenerRequest(value: any): value is PrivateChannelAddEventListenerRequest { + try { + Convert.privateChannelAddEventListenerRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelAddEventListenerResponse(value: any): value is PrivateChannelAddEventListenerResponse { + try { + Convert.privateChannelAddEventListenerResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelDisconnectRequest(value: any): value is PrivateChannelDisconnectRequest { + try { + Convert.privateChannelDisconnectRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelDisconnectResponse(value: any): value is PrivateChannelDisconnectResponse { + try { + Convert.privateChannelDisconnectResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelOnAddContextListenerEvent(value: any): value is PrivateChannelOnAddContextListenerEvent { + try { + Convert.privateChannelOnAddContextListenerEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelOnDisconnectEvent(value: any): value is PrivateChannelOnDisconnectEvent { + try { + Convert.privateChannelOnDisconnectEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelOnUnsubscribeEvent(value: any): value is PrivateChannelOnUnsubscribeEvent { + try { + Convert.privateChannelOnUnsubscribeEventToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelUnsubscribeEventListenerRequest(value: any): value is PrivateChannelUnsubscribeEventListenerRequest { + try { + Convert.privateChannelUnsubscribeEventListenerRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isPrivateChannelUnsubscribeEventListenerResponse(value: any): value is PrivateChannelUnsubscribeEventListenerResponse { + try { + Convert.privateChannelUnsubscribeEventListenerResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isRaiseIntentForContextRequest(value: any): value is RaiseIntentForContextRequest { + try { + Convert.raiseIntentForContextRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isRaiseIntentForContextResponse(value: any): value is RaiseIntentForContextResponse { + try { + Convert.raiseIntentForContextResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isRaiseIntentRequest(value: any): value is RaiseIntentRequest { + try { + Convert.raiseIntentRequestToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isRaiseIntentResponse(value: any): value is RaiseIntentResponse { + try { + Convert.raiseIntentResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isRaiseIntentResultResponse(value: any): value is RaiseIntentResultResponse { + try { + Convert.raiseIntentResultResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol1Hello(value: any): value is WebConnectionProtocol1Hello { + try { + Convert.webConnectionProtocol1HelloToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol2LoadURL(value: any): value is WebConnectionProtocol2LoadURL { + try { + Convert.webConnectionProtocol2LoadURLToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol3Handshake(value: any): value is WebConnectionProtocol3Handshake { + try { + Convert.webConnectionProtocol3HandshakeToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol4ValidateAppIdentity(value: any): value is WebConnectionProtocol4ValidateAppIdentity { + try { + Convert.webConnectionProtocol4ValidateAppIdentityToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol5ValidateAppIdentityFailedResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentityFailedResponse { + try { + Convert.webConnectionProtocol5ValidateAppIdentityFailedResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol5ValidateAppIdentitySuccessResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentitySuccessResponse { + try { + Convert.webConnectionProtocol5ValidateAppIdentitySuccessResponseToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocol6Goodbye(value: any): value is WebConnectionProtocol6Goodbye { + try { + Convert.webConnectionProtocol6GoodbyeToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export function isWebConnectionProtocolMessage(value: any): value is WebConnectionProtocolMessage { + try { + Convert.webConnectionProtocolMessageToJson(value); + return true; + } catch (e: any) { + return false; + } +} + +export type RequestMessage = AddContextListenerRequest | AddEventListenerRequest | AddIntentListenerRequest | BroadcastRequest | ContextListenerUnsubscribeRequest | CreatePrivateChannelRequest | EventListenerUnsubscribeRequest | FindInstancesRequest | FindIntentRequest | FindIntentsByContextRequest | GetAppMetadataRequest | GetCurrentChannelRequest | GetCurrentContextRequest | GetInfoRequest | GetOrCreateChannelRequest | GetUserChannelsRequest | HeartbeatAcknowledgementRequest | IntentListenerUnsubscribeRequest | IntentResultRequest | JoinUserChannelRequest | LeaveCurrentChannelRequest | OpenRequest | PrivateChannelAddEventListenerRequest | PrivateChannelDisconnectRequest | PrivateChannelUnsubscribeEventListenerRequest | RaiseIntentForContextRequest | RaiseIntentRequest; + +export type ResponseMessage = AddContextListenerResponse | AddEventListenerResponse | AddIntentListenerResponse | BroadcastResponse | ContextListenerUnsubscribeResponse | CreatePrivateChannelResponse | EventListenerUnsubscribeResponse | FindInstancesResponse | FindIntentResponse | FindIntentsByContextResponse | GetAppMetadataResponse | GetCurrentChannelResponse | GetCurrentContextResponse | GetInfoResponse | GetOrCreateChannelResponse | GetUserChannelsResponse | IntentListenerUnsubscribeResponse | IntentResultResponse | JoinUserChannelResponse | LeaveCurrentChannelResponse | OpenResponse | PrivateChannelAddEventListenerResponse | PrivateChannelDisconnectResponse | PrivateChannelUnsubscribeEventListenerResponse | RaiseIntentForContextResponse | RaiseIntentResponse | RaiseIntentResultResponse | WebConnectionProtocol5ValidateAppIdentityFailedResponse | WebConnectionProtocol5ValidateAppIdentitySuccessResponse; + +export type EventMessage = BroadcastEvent | ChannelChangedEvent | HeartbeatEvent | IntentEvent | PrivateChannelOnAddContextListenerEvent | PrivateChannelOnDisconnectEvent | PrivateChannelOnUnsubscribeEvent; diff --git a/src/api/DesktopAgent.ts b/src/api/DesktopAgent.ts index 8d9edbdd9..3691ae3f6 100644 --- a/src/api/DesktopAgent.ts +++ b/src/api/DesktopAgent.ts @@ -13,7 +13,6 @@ import { ImplementationMetadata } from './ImplementationMetadata'; import { PrivateChannel } from './PrivateChannel'; import { AppIdentifier } from './AppIdentifier'; import { AppMetadata } from './AppMetadata'; -import { DesktopAgentDetails } from './GetAgent'; import { Intent } from '../intents/Intents'; import { ContextType } from '../context/ContextType'; import { EventHandler, FDC3EventTypes } from './Events'; diff --git a/src/context/ContextTypes.ts b/src/context/ContextTypes.ts index f1b809287..8c4f68f75 100644 --- a/src/context/ContextTypes.ts +++ b/src/context/ContextTypes.ts @@ -207,7 +207,7 @@ export interface Chart { } /** - * financial instrument that relates to the definition of this product + * A financial instrument that relates to the definition of this product * * * @@ -235,7 +235,7 @@ export interface InstrumentElement { * interoperability between disparate data sources. This is especially useful when using an * `id` field that is not globally unique. */ - market?: SearchCriteriaMarket; + market?: OrganizationMarket; /** * An optional human-readable name for the instrument */ @@ -304,7 +304,7 @@ export interface PurpleInstrumentIdentifiers { * interoperability between disparate data sources. This is especially useful when using an * `id` field that is not globally unique. */ -export interface SearchCriteriaMarket { +export interface OrganizationMarket { /** * https://www.bloomberg.com/ */ @@ -663,7 +663,7 @@ export interface ChatRoomObject { /** * Identifier(s) for the chat - currently unstandardized */ - id: { [key: string]: any }; + id: { [key: string]: string }; /** * Display name for the chat room */ @@ -702,7 +702,7 @@ export interface ChatRoom { /** * Identifier(s) for the chat - currently unstandardized */ - id: { [key: string]: any }; + id: { [key: string]: string }; /** * Display name for the chat room */ @@ -734,7 +734,7 @@ export interface ChatSearchCriteria { * * Empty search criteria can be supported to allow resetting of filters. */ - criteria: SearchCriteria[]; + criteria: Array; type: "fdc3.chat.searchCriteria"; id?: { [key: string]: any }; name?: string; @@ -742,26 +742,23 @@ export interface ChatSearchCriteria { } /** - * An individual criteria against which to match chat messages, based on an FDC3 context or - * free-text string. - * - * financial instrument that relates to the definition of this product + * A financial instrument that relates to the definition of this product * * * * A financial instrument from any asset class. * - * The contact that initiated the interaction - * - * A person contact that can be engaged with through email, calling, messaging, CMS, etc. - * * An entity that can be used when referencing private companies and other organizations * where a specific instrument is not available or desired e.g. CRM and News workflows. * * It is valid to include extra properties and metadata as part of the organization payload, * but the minimum requirement is for at least one specified identifier to be provided. + * + * The contact that initiated the interaction + * + * A person contact that can be engaged with through email, calling, messaging, CMS, etc. */ -export interface SearchCriteria { +export interface OrganizationObject { /** * Any combination of instrument identifiers can be used together to resolve ambiguity, or * for a better match. Not all applications will use the same instrument identifiers, which @@ -777,9 +774,9 @@ export interface SearchCriteria { * fields, define a property that makes it clear what the value represents. Doing so will * make interpretation easier for the developers of target applications. * - * Identifiers that relate to the Contact represented by this context - * * Identifiers for the organization, at least one must be provided. + * + * Identifiers that relate to the Contact represented by this context */ id: Identifiers; /** @@ -787,16 +784,16 @@ export interface SearchCriteria { * interoperability between disparate data sources. This is especially useful when using an * `id` field that is not globally unique. */ - market?: SearchCriteriaMarket; + market?: OrganizationMarket; /** * An optional human-readable name for the instrument * - * An optional human-readable name for the contact - * * An optional human-readable name of the organization + * + * An optional human-readable name for the contact */ name?: string; - type: SearchCriteriaType; + type: TentacledInteractionType; [property: string]: any; } @@ -815,9 +812,9 @@ export interface SearchCriteria { * fields, define a property that makes it clear what the value represents. Doing so will * make interpretation easier for the developers of target applications. * - * Identifiers that relate to the Contact represented by this context - * * Identifiers for the organization, at least one must be provided. + * + * Identifiers that relate to the Contact represented by this context */ export interface Identifiers { /** @@ -831,9 +828,9 @@ export interface Identifiers { /** * https://www.factset.com/ * - * FactSet Permanent Identifier representing the contact - * * FactSet Permanent Identifier representing the organization + * + * FactSet Permanent Identifier representing the contact */ FDS_ID?: string; /** @@ -862,10 +859,6 @@ export interface Identifiers { * Unstandardized stock tickers */ ticker?: string; - /** - * The email address for the contact - */ - email?: string; /** * The Legal Entity Identifier (LEI) is a 20-character, alpha-numeric code based on the ISO * 17442 standard developed by the International Organization for Standardization (ISO). It @@ -873,6 +866,10 @@ export interface Identifiers { * legal entities participating in financial transactions. */ LEI?: string; + /** + * The email address for the contact + */ + email?: string; [property: string]: any; } @@ -882,7 +879,7 @@ export interface Identifiers { * `interactionType` SHOULD be one of `'Instant Message'`, `'Email'`, `'Call'`, or * `'Meeting'` although other string values are permitted. */ -export type SearchCriteriaType = "fdc3.instrument" | "fdc3.contact" | "fdc3.organization"; +export type TentacledInteractionType = "fdc3.instrument" | "fdc3.organization" | "fdc3.contact"; /** * Free text to be used for a keyword search @@ -1583,7 +1580,7 @@ export interface ProductObject { */ id: { [key: string]: string }; /** - * financial instrument that relates to the definition of this product + * A financial instrument that relates to the definition of this product */ instrument?: InstrumentElement; /** @@ -1860,7 +1857,7 @@ export interface Product { */ id: { [key: string]: string }; /** - * financial instrument that relates to the definition of this product + * A financial instrument that relates to the definition of this product */ instrument?: InstrumentElement; /** @@ -2510,9 +2507,9 @@ const typeMap: any = { ], "any"), "InstrumentElement": o([ { json: "id", js: "id", typ: r("PurpleInstrumentIdentifiers") }, - { json: "market", js: "market", typ: u(undefined, r("SearchCriteriaMarket")) }, + { json: "market", js: "market", typ: u(undefined, r("OrganizationMarket")) }, { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: r("InstrumentType") }, + { json: "type", js: "type", typ: r("PurpleInteractionType") }, ], "any"), "PurpleInstrumentIdentifiers": o([ { json: "BBG", js: "BBG", typ: u(undefined, "") }, @@ -2525,7 +2522,7 @@ const typeMap: any = { { json: "SEDOL", js: "SEDOL", typ: u(undefined, "") }, { json: "ticker", js: "ticker", typ: u(undefined, "") }, ], "any"), - "SearchCriteriaMarket": o([ + "OrganizationMarket": o([ { json: "BBG", js: "BBG", typ: u(undefined, "") }, { json: "COUNTRY_ISOALPHA2", js: "COUNTRY_ISOALPHA2", typ: u(undefined, "") }, { json: "MIC", js: "MIC", typ: u(undefined, "") }, @@ -2556,7 +2553,7 @@ const typeMap: any = { "ContactElement": o([ { json: "id", js: "id", typ: r("PurpleContactIdentifiers") }, { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: r("ContactType") }, + { json: "type", js: "type", typ: r("FluffyInteractionType") }, ], "any"), "PurpleContactIdentifiers": o([ { json: "email", js: "email", typ: u(undefined, "") }, @@ -2602,30 +2599,30 @@ const typeMap: any = { { json: "name", js: "name", typ: u(undefined, "") }, ], "any"), "ChatRoomObject": o([ - { json: "id", js: "id", typ: m("any") }, + { json: "id", js: "id", typ: m("") }, { json: "name", js: "name", typ: u(undefined, "") }, { json: "providerName", js: "providerName", typ: "" }, { json: "type", js: "type", typ: r("ChatRoomType") }, { json: "url", js: "url", typ: u(undefined, "") }, ], "any"), "ChatRoom": o([ - { json: "id", js: "id", typ: m("any") }, + { json: "id", js: "id", typ: m("") }, { json: "name", js: "name", typ: u(undefined, "") }, { json: "providerName", js: "providerName", typ: "" }, { json: "type", js: "type", typ: r("ChatRoomType") }, { json: "url", js: "url", typ: u(undefined, "") }, ], "any"), "ChatSearchCriteria": o([ - { json: "criteria", js: "criteria", typ: a(r("SearchCriteria")) }, + { json: "criteria", js: "criteria", typ: a(u(r("OrganizationObject"), "")) }, { json: "type", js: "type", typ: r("ChatSearchCriteriaType") }, { json: "id", js: "id", typ: u(undefined, m("any")) }, { json: "name", js: "name", typ: u(undefined, "") }, ], "any"), - "SearchCriteria": o([ + "OrganizationObject": o([ { json: "id", js: "id", typ: r("Identifiers") }, - { json: "market", js: "market", typ: u(undefined, r("SearchCriteriaMarket")) }, + { json: "market", js: "market", typ: u(undefined, r("OrganizationMarket")) }, { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: r("SearchCriteriaType") }, + { json: "type", js: "type", typ: r("TentacledInteractionType") }, ], "any"), "Identifiers": o([ { json: "BBG", js: "BBG", typ: u(undefined, "") }, @@ -2637,13 +2634,13 @@ const typeMap: any = { { json: "RIC", js: "RIC", typ: u(undefined, "") }, { json: "SEDOL", js: "SEDOL", typ: u(undefined, "") }, { json: "ticker", js: "ticker", typ: u(undefined, "") }, - { json: "email", js: "email", typ: u(undefined, "") }, { json: "LEI", js: "LEI", typ: u(undefined, "") }, + { json: "email", js: "email", typ: u(undefined, "") }, ], "any"), "Contact": o([ { json: "id", js: "id", typ: r("FluffyContactIdentifiers") }, { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: r("ContactType") }, + { json: "type", js: "type", typ: r("FluffyInteractionType") }, ], "any"), "FluffyContactIdentifiers": o([ { json: "email", js: "email", typ: u(undefined, "") }, @@ -2701,7 +2698,7 @@ const typeMap: any = { { json: "id", js: "id", typ: r("FluffyInstrumentIdentifiers") }, { json: "market", js: "market", typ: u(undefined, r("PurpleMarket")) }, { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: r("InstrumentType") }, + { json: "type", js: "type", typ: r("PurpleInteractionType") }, ], "any"), "FluffyInstrumentIdentifiers": o([ { json: "BBG", js: "BBG", typ: u(undefined, "") }, @@ -2805,7 +2802,7 @@ const typeMap: any = { "Organization": o([ { json: "id", js: "id", typ: r("OrganizationIdentifiers") }, { json: "name", js: "name", typ: u(undefined, "") }, - { json: "type", js: "type", typ: r("OrganizationType") }, + { json: "type", js: "type", typ: r("StickyInteractionType") }, ], "any"), "OrganizationIdentifiers": o([ { json: "FDS_ID", js: "FDS_ID", typ: u(undefined, "") }, @@ -2884,7 +2881,7 @@ const typeMap: any = { "ActionType": [ "fdc3.action", ], - "InstrumentType": [ + "PurpleInteractionType": [ "fdc3.instrument", ], "TimeRangeType": [ @@ -2905,7 +2902,7 @@ const typeMap: any = { "ChartType": [ "fdc3.chart", ], - "ContactType": [ + "FluffyInteractionType": [ "fdc3.contact", ], "ContactListType": [ @@ -2927,7 +2924,7 @@ const typeMap: any = { "ChatMessageType": [ "fdc3.chat.message", ], - "SearchCriteriaType": [ + "TentacledInteractionType": [ "fdc3.contact", "fdc3.instrument", "fdc3.organization", @@ -2966,7 +2963,7 @@ const typeMap: any = { "OrderListType": [ "fdc3.orderList", ], - "OrganizationType": [ + "StickyInteractionType": [ "fdc3.organization", ], "PositionType": [ From 17d0a2043c0a67d3a3b72b588a077799e2ddb0be Mon Sep 17 00:00:00 2001 From: Julianna Langston Date: Tue, 12 Nov 2024 11:37:36 -0500 Subject: [PATCH 03/12] Move addon package to toolbox/fdc3-for-web/reference-ui --- package.json | 2 +- packages/addon/src/intent_resolver_orig.js | 160 ------------------ .../fdc3-for-web/reference-ui}/.gitignore | 0 .../fdc3-for-web/reference-ui}/index.html | 0 .../fdc3-for-web/reference-ui}/package.json | 2 +- .../public/channel_selector.html | 0 .../reference-ui}/public/intent_resolver.html | 0 .../reference-ui}/src/channel_selector.ts | 0 .../reference-ui}/src/intent_resolver.ts | 4 +- .../fdc3-for-web/reference-ui}/src/main.ts | 14 -- .../fdc3-for-web/reference-ui}/src/style.css | 0 .../reference-ui}/src/vite-env.d.ts | 0 .../fdc3-for-web/reference-ui}/tsconfig.json | 0 .../fdc3-for-web/reference-ui}/vite.config.ts | 0 14 files changed, 4 insertions(+), 178 deletions(-) delete mode 100644 packages/addon/src/intent_resolver_orig.js rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/.gitignore (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/index.html (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/package.json (89%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/public/channel_selector.html (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/public/intent_resolver.html (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/src/channel_selector.ts (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/src/intent_resolver.ts (98%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/src/main.ts (93%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/src/style.css (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/src/vite-env.d.ts (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/tsconfig.json (100%) rename {packages/addon => toolbox/fdc3-for-web/reference-ui}/vite.config.ts (100%) diff --git a/package.json b/package.json index 124279137..f066b92f7 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "report": "nyc report --reporter json-summary --report-dir nyc-coverage-report --exclude-after-remap false --temp-dir coverage", "lint": "npm run lint --workspaces --if-present", "syncpack": "npm exec syncpack fix-mismatches --types 'local'", - "dev": "concurrently \"cd toolbox/fdc3-workbench && npm run dev\" \"cd toolbox/fdc3-for-web/demo && npm run dev\"" + "dev": "concurrently \"cd toolbox/fdc3-workbench && npm run dev\" \"cd toolbox/fdc3-for-web/reference-ui && npm run dev\" \"cd toolbox/fdc3-for-web/demo && npm run dev\"" }, "prettier": { "semi": true, diff --git a/packages/addon/src/intent_resolver_orig.js b/packages/addon/src/intent_resolver_orig.js deleted file mode 100644 index b97d75086..000000000 --- a/packages/addon/src/intent_resolver_orig.js +++ /dev/null @@ -1,160 +0,0 @@ -const setup = (data, callback) => { - document.body.setAttribute("data-visible", "true"); - document.getElementById("displayContext").textContent = data.context ?? "*"; - console.log("setup: ", data); - const intentSelect = document.getElementById("displayIntent"); - data.intents.forEach(({intent, displayName}) => { - const option = document.createElement("option"); - option.textContent = displayName; - option.value = intent; - intentSelect.appendChild(option); - }); - intentSelect.addEventListener("change", (e) => fillList(data.options[e.target.value], e.target.value, callback)); - fillList(data.options[intentSelect.value], intentSelect.value, callback); - - const tabs = Array.from(document.querySelectorAll("[role='tab']")) - tabs.forEach((tab) => { - tab.addEventListener("click", () => { - // Remove selected state from every tab - tabs.forEach((t) => { - t.setAttribute("aria-selected", "false"); - }); - // Hide lists - Array.from(document.querySelectorAll(".list")).forEach((elem) => { - elem.setAttribute("data-visible", "false"); - }); - - tab.setAttribute("aria-selected", "true"); - const listRef = tab.getAttribute("data-list-ref"); - document.getElementById(listRef).setAttribute("data-visible", "true"); - }); - }); - - document.getElementById("cancel").addEventListener("click", () => { - callback({ - type: "Fdc3UserInterfaceResolveAction", - action: "cancel" - }); - }) -} - -const fillList = ({apps, openApps}, intent, callback) => { - const newList = document.getElementById('new-list'); - newList.innerHTML = ''; - apps.forEach(({ appId, title, icon }) => { - const node = document.createElement('div'); - node.setAttribute('tabIndex', '0'); - node.setAttribute("data-appId", appId); - - const span = document.createElement("span"); - span.textContent = title; - - const img = document.createElement("img"); - if(icon?.src){ - img.src = icon.src; - }else{ - img.style.opacity = 0; - } - - node.appendChild(img); - node.appendChild(span); - - node.addEventListener('mouseenter', () => callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - intent, - action: "hover", - newOrOpen: "new" - })); - node.addEventListener('click', () => { - callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - intent, - action: "click", - newOrOpen: "new" - }); - callback({ - type: "Fdc3UserInterfaceResolve", - appId, - intent, - newOrOpen: "new" - }); - }); - - newList.appendChild(node); - }); - document.getElementById("count-new-apps").textContent = `(${apps.length})`; - - const openList = document.getElementById('open-list'); - openList.innerHTML = ''; - openApps.forEach(({ appId, title, windowId }) => { - const appd = apps.find((app) => app.appId === appId); - const node = document.createElement('div'); - node.setAttribute('tabIndex', '0'); - node.setAttribute("data-appId", appId); - - const span = document.createElement("span"); - span.textContent = title; - - const img = document.createElement("img"); - if(appd.icon?.src){ - img.src = appd.icon.src; - }else{ - img.style.opacity = 0; - } - - node.appendChild(img); - node.appendChild(span); - - node.addEventListener('mouseenter', () => callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - windowId, - intent, - action: "hover", - newOrOpen: "open" - })); - node.addEventListener('click', () => { - callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - windowId, - intent, - action: "click", - newOrOpen: "open" - }); - callback({ - type: "Fdc3UserInterfaceResolve", - appId, - intent, - windowId, - newOrOpen: "open" - }) - }); - - openList.appendChild(node); - }); - document.getElementById("count-open-apps").textContent = `(${openApps.length})`; -}; - -// STEP 1B: Receive port from parent -// we may not know the origin of the parent in advance so disabling this check -// this might be improved if it s possible to get the origin of the parent window (cross-domain) and only respond to that -// nosemgrep: javascript.browser.security.insufficient-postmessage-origin-validation.insufficient-postmessage-origin-validation -window.addEventListener('message', ({ origin, ports }) => { - //only accept a port from the window we are embedded in: - if(window.location.ancestorOrigins.contains(origin)){ - // STEP 3B: Receive channel data from parent - ports[0].onmessage = ({ data }) => { - setup(data, msg => { - // STEP 4A: Send user selection information to parent - ports[0].postMessage(msg); - }); - }; - // STEP 2A: Send confirmation over port to parent - ports[0].postMessage({type: 'Fdc3UserInterfaceHandshake'}); - } else { - console.warn(`Ignoring postMessage from unknonw (non-ancestor) origin: ${origin}`); - } -}); diff --git a/packages/addon/.gitignore b/toolbox/fdc3-for-web/reference-ui/.gitignore similarity index 100% rename from packages/addon/.gitignore rename to toolbox/fdc3-for-web/reference-ui/.gitignore diff --git a/packages/addon/index.html b/toolbox/fdc3-for-web/reference-ui/index.html similarity index 100% rename from packages/addon/index.html rename to toolbox/fdc3-for-web/reference-ui/index.html diff --git a/packages/addon/package.json b/toolbox/fdc3-for-web/reference-ui/package.json similarity index 89% rename from packages/addon/package.json rename to toolbox/fdc3-for-web/reference-ui/package.json index 86db653ee..f21fccf17 100644 --- a/packages/addon/package.json +++ b/toolbox/fdc3-for-web/reference-ui/package.json @@ -1,5 +1,5 @@ { - "name": "addon", + "name": "fdc3-for-web-reference-ui", "private": true, "version": "2.1.1", "type": "module", diff --git a/packages/addon/public/channel_selector.html b/toolbox/fdc3-for-web/reference-ui/public/channel_selector.html similarity index 100% rename from packages/addon/public/channel_selector.html rename to toolbox/fdc3-for-web/reference-ui/public/channel_selector.html diff --git a/packages/addon/public/intent_resolver.html b/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html similarity index 100% rename from packages/addon/public/intent_resolver.html rename to toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html diff --git a/packages/addon/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts similarity index 100% rename from packages/addon/src/channel_selector.ts rename to toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts diff --git a/packages/addon/src/intent_resolver.ts b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts similarity index 98% rename from packages/addon/src/intent_resolver.ts rename to toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts index f8f0c92b2..1fcc03eae 100644 --- a/packages/addon/src/intent_resolver.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts @@ -116,7 +116,7 @@ const fillList = (ai: AppIntent[], intent: string, callback: (s: IframeResolveAc const openList = document.getElementById('open-list')!! openList.innerHTML = ''; - openApps.forEach(({ appId, title, icons, instanceId }) => { + openApps.forEach(({ appId, title, icons }) => { const node = document.createElement('div'); node.setAttribute('tabIndex', '0'); node.setAttribute("data-appId", appId); @@ -163,7 +163,7 @@ window.addEventListener("load", () => { myPort.onmessage = ({data}) => { console.debug("Received message: ", data); switch(data.type){ - case Fdc3UserInterfaceHandshake": { + case "Fdc3UserInterfaceHandshake": { break; } case "iframeResolve": { diff --git a/packages/addon/src/main.ts b/toolbox/fdc3-for-web/reference-ui/src/main.ts similarity index 93% rename from packages/addon/src/main.ts rename to toolbox/fdc3-for-web/reference-ui/src/main.ts index 2fe1e415e..cdf263e30 100644 --- a/packages/addon/src/main.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/main.ts @@ -81,20 +81,6 @@ const recommendedChannels = [ const exampleResolverData: ResolverIntents = { type: "ResolverIntents", appIntents: [ - { - apps: [{ - appId: "chartiq", - description: "Chart IQ is the most powerful charting library on the market", - icons: [{ - src: "https://res.cloudinary.com/apideck/image/upload/v1561415965/catalog/chartiq/icon128x128.jpg" - }], - title: "ChartIQ" - }], - intent: { - name: "ViewChart", - displayName: "View Chart" - } - }, { apps: [{ appId: "trading-view-chart", diff --git a/packages/addon/src/style.css b/toolbox/fdc3-for-web/reference-ui/src/style.css similarity index 100% rename from packages/addon/src/style.css rename to toolbox/fdc3-for-web/reference-ui/src/style.css diff --git a/packages/addon/src/vite-env.d.ts b/toolbox/fdc3-for-web/reference-ui/src/vite-env.d.ts similarity index 100% rename from packages/addon/src/vite-env.d.ts rename to toolbox/fdc3-for-web/reference-ui/src/vite-env.d.ts diff --git a/packages/addon/tsconfig.json b/toolbox/fdc3-for-web/reference-ui/tsconfig.json similarity index 100% rename from packages/addon/tsconfig.json rename to toolbox/fdc3-for-web/reference-ui/tsconfig.json diff --git a/packages/addon/vite.config.ts b/toolbox/fdc3-for-web/reference-ui/vite.config.ts similarity index 100% rename from packages/addon/vite.config.ts rename to toolbox/fdc3-for-web/reference-ui/vite.config.ts From 637afb3836c58efd1dce18b19b5665da7f40e996 Mon Sep 17 00:00:00 2001 From: Julianna Langston Date: Tue, 12 Nov 2024 12:11:51 -0500 Subject: [PATCH 04/12] Update build steps --- package.json | 1 + .../reference-ui/src/channel_selector.ts | 10 +++++----- .../reference-ui/src/intent_resolver.ts | 14 +++++--------- toolbox/fdc3-for-web/reference-ui/src/main.ts | 3 +-- toolbox/fdc3-for-web/reference-ui/vite.config.ts | 3 +++ 5 files changed, 15 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index f066b92f7..20d5c9f69 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "packages/fdc3-get-agent", "packages/fdc3", "toolbox/fdc3-for-web/demo", + "toolbox/fdc3-for-web/reference-ui", "toolbox/fdc3-workbench" ], "scripts": { diff --git a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts index 5968a277c..ab6698f60 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts @@ -49,11 +49,11 @@ window.addEventListener("load", () => { myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); switch (data.type) { - case "iframeHandshake": { + case "IframeHandshake": { collapse(); break; } - case "fdc3UserInterfaceChannels": { + case "Fdc3UserInterfaceChannels": { logo.removeEventListener("click", expand); const { userChannels, selected } = data.payload as IframeChannelsPayload; fillChannels(userChannels, selected, (channelStr) => { @@ -74,7 +74,7 @@ window.addEventListener("load", () => { }; parent.postMessage({ - type: "fdc3UserInterfaceHello", + type: "Fdc3UserInterfaceHello", payload: { initialCSS: { width: `${8 * 4}px`, @@ -92,7 +92,7 @@ window.addEventListener("load", () => { const expand = () => { document.body.setAttribute("data-expanded", "true"); myPort.postMessage({ - type: "fdc3UserInterfaceRestyle", + type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { width: `100%`, @@ -109,7 +109,7 @@ window.addEventListener("load", () => { const collapse = () => { myPort.postMessage({ - type: "fdc3UserInterfaceRestyle", + type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { width: `${8 * 4}px`, diff --git a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts index 1fcc03eae..70df2bc76 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts @@ -6,8 +6,6 @@ const setup = (data: IframeResolvePayload, callback: (s: IframeResolveActionPayl document.body.setAttribute("data-visible", "true"); document.querySelector("dialog")?.showModal(); - console.log("setup data:", data); - const intentSelect = document.getElementById("displayIntent") as HTMLSelectElement const justIntents = data.appIntents.map(({intent}) => intent) @@ -51,8 +49,6 @@ const setup = (data: IframeResolvePayload, callback: (s: IframeResolveActionPayl action: "cancel" }); }); - - console.log(document.body); } function createIcon(icons: Icon[] | undefined): HTMLElement { @@ -166,9 +162,9 @@ window.addEventListener("load", () => { case "Fdc3UserInterfaceHandshake": { break; } - case "iframeResolve": { + case "IframeResolve": { myPort.postMessage({ - type: "iframeRestyle", + type: "IframeRestyle", payload: { updatedCSS: { width: "100%", @@ -183,12 +179,12 @@ window.addEventListener("load", () => { setup(data.payload, (s) => { document.querySelector("dialog")?.close(); myPort.postMessage({ - type: "iframeResolveAction", + type: "IframeResolveAction", payload: s }); myPort.postMessage({ - type: "fdc3UserInterfaceRestyle", + type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { width: "0", @@ -203,7 +199,7 @@ window.addEventListener("load", () => { }; parent.postMessage({ - type: "fdc3UserInterfaceHello", + type: "Fdc3UserInterfaceHello", payload: { initialCSS: { width: "0", diff --git a/toolbox/fdc3-for-web/reference-ui/src/main.ts b/toolbox/fdc3-for-web/reference-ui/src/main.ts index cdf263e30..88d2d4cb6 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/main.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/main.ts @@ -1,4 +1,3 @@ -import { ResolverIntents } from "@kite9/fdc3-common"; import "./style.css"; // Channel data @@ -78,7 +77,7 @@ const recommendedChannels = [ ]; // Example resolver data -const exampleResolverData: ResolverIntents = { +const exampleResolverData = { type: "ResolverIntents", appIntents: [ { diff --git a/toolbox/fdc3-for-web/reference-ui/vite.config.ts b/toolbox/fdc3-for-web/reference-ui/vite.config.ts index cd4d40fc9..7ce5ba6a5 100644 --- a/toolbox/fdc3-for-web/reference-ui/vite.config.ts +++ b/toolbox/fdc3-for-web/reference-ui/vite.config.ts @@ -3,4 +3,7 @@ import { defineConfig } from "vite"; // https://vitejs.dev/config/ export default defineConfig({ server: { port: 4000 }, + build: { + outDir: "../../../website/static/ui" + } }); From b950c1ffe53730132938ee593456b4d9ad1397e7 Mon Sep 17 00:00:00 2001 From: Julianna Langston Date: Tue, 12 Nov 2024 12:18:49 -0500 Subject: [PATCH 05/12] Update package import --- package-lock.json | 19 ++++++++++++++++--- .../fdc3-for-web/reference-ui/package.json | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0d086fb68..71cea8675 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "packages/fdc3-get-agent", "packages/fdc3", "toolbox/fdc3-for-web/demo", + "toolbox/fdc3-for-web/reference-ui", "toolbox/fdc3-workbench" ], "dependencies": { @@ -3344,7 +3345,6 @@ "node_modules/@kite9/fdc3-common": { "version": "2.2.0-beta.6", "integrity": "sha512-JQa8WVXWIpHQRMt9CFsxqjfrw2Rq4tVUT8R6r2cJAg1y1Ns+zmpclo/bGi3DVqFyd5PfOEbbiAER/1ll0PXb3A==", - "dev": true, "dependencies": { "@kite9/fdc3": "2.2.0-beta.6" } @@ -3352,7 +3352,6 @@ "node_modules/@kite9/fdc3-common/node_modules/@kite9/fdc3": { "version": "2.2.0-beta.6", "integrity": "sha512-F/fC4Ayp3uBzhBs4x5rp8n4/JSbuGaAHdrfrm/HTipDqsQKdQon4uZsNdMK6USTX1gnpFVy8luSnIddFJey12g==", - "dev": true, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.14.1" } @@ -3363,7 +3362,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -7820,6 +7818,10 @@ "node": ">=10" } }, + "node_modules/fdc3-for-web-reference-ui": { + "resolved": "toolbox/fdc3-for-web/reference-ui", + "link": true + }, "node_modules/fdc3-workbench": { "resolved": "toolbox/fdc3-workbench", "link": true @@ -17075,6 +17077,17 @@ "uuid": "^9.0.1" } }, + "toolbox/fdc3-for-web/reference-ui": { + "name": "fdc3-for-web-reference-ui", + "version": "2.1.1", + "dependencies": { + "@kite9/fdc3-common": "2.2.0-beta.6" + }, + "devDependencies": { + "typescript": "^5.3.2", + "vite": "^5.2.0" + } + }, "toolbox/fdc3-workbench": { "version": "2.2.0-beta.29", "license": "Apache-2.0", diff --git a/toolbox/fdc3-for-web/reference-ui/package.json b/toolbox/fdc3-for-web/reference-ui/package.json index f21fccf17..047b932a6 100644 --- a/toolbox/fdc3-for-web/reference-ui/package.json +++ b/toolbox/fdc3-for-web/reference-ui/package.json @@ -14,6 +14,6 @@ "vite": "^5.2.0" }, "dependencies": { - "@kite9/fdc3": "2.1.1" + "@kite9/fdc3-common": "2.2.0-beta.6" } } \ No newline at end of file From b36f95310c0594f5b448639a78293d5e3665a807 Mon Sep 17 00:00:00 2001 From: Julianna Langston Date: Wed, 13 Nov 2024 10:23:38 -0500 Subject: [PATCH 06/12] CR changes --- toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts | 4 ++-- toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts | 4 ++-- toolbox/fdc3-for-web/reference-ui/vite.config.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts index ab6698f60..8696b53af 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts @@ -49,7 +49,7 @@ window.addEventListener("load", () => { myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); switch (data.type) { - case "IframeHandshake": { + case "Fdc3UserInterfaceHandshake ": { collapse(); break; } @@ -58,7 +58,7 @@ window.addEventListener("load", () => { const { userChannels, selected } = data.payload as IframeChannelsPayload; fillChannels(userChannels, selected, (channelStr) => { myPort.postMessage({ - type: "fdc3UserInterfaceSelected", + type: "Fdc3UserInterfaceSelected", payload: { selected: channelStr || null } diff --git a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts index 70df2bc76..3c01cd23e 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts @@ -162,7 +162,7 @@ window.addEventListener("load", () => { case "Fdc3UserInterfaceHandshake": { break; } - case "IframeResolve": { + case "Fdc3UserInterfaceResolve": { myPort.postMessage({ type: "IframeRestyle", payload: { @@ -179,7 +179,7 @@ window.addEventListener("load", () => { setup(data.payload, (s) => { document.querySelector("dialog")?.close(); myPort.postMessage({ - type: "IframeResolveAction", + type: "Fdc3UserInterfaceResolveAction", payload: s }); diff --git a/toolbox/fdc3-for-web/reference-ui/vite.config.ts b/toolbox/fdc3-for-web/reference-ui/vite.config.ts index 7ce5ba6a5..5942d7800 100644 --- a/toolbox/fdc3-for-web/reference-ui/vite.config.ts +++ b/toolbox/fdc3-for-web/reference-ui/vite.config.ts @@ -4,6 +4,6 @@ import { defineConfig } from "vite"; export default defineConfig({ server: { port: 4000 }, build: { - outDir: "../../../website/static/ui" + outDir: "../../../website/static/reference-ui" } }); From 12e474f3f7f188d78b54f161f08018b0ac0d36ca Mon Sep 17 00:00:00 2001 From: Julianna Langston Date: Wed, 13 Nov 2024 10:38:10 -0500 Subject: [PATCH 07/12] Update message typings --- .../reference-ui/src/channel_selector.ts | 23 ++++++----- .../reference-ui/src/intent_resolver.ts | 41 ++++++++++++------- 2 files changed, 39 insertions(+), 25 deletions(-) diff --git a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts index 8696b53af..fa130c657 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts @@ -1,6 +1,5 @@ import { IframeChannelsPayload, Channel } from "@kite9/fdc3-common"; - - +import { Fdc3UserInterfaceHello, Fdc3UserInterfaceRestyle } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; const fillChannels = (data: Channel[], selected: string | null, messageClickedChannel: (s: string | null) => void) => { const list = document.getElementById('list')!!; @@ -73,9 +72,10 @@ window.addEventListener("load", () => { } }; - parent.postMessage({ + const helloMessage: Fdc3UserInterfaceHello = { type: "Fdc3UserInterfaceHello", payload: { + implementationDetails: "", initialCSS: { width: `${8 * 4}px`, height: `${8 * 5}px`, @@ -87,28 +87,30 @@ window.addEventListener("load", () => { } } - }, "*", [mc.port2]); + } + parent.postMessage(helloMessage, "*", [mc.port2]); const expand = () => { document.body.setAttribute("data-expanded", "true"); - myPort.postMessage({ + const restyleMessage: Fdc3UserInterfaceRestyle = { type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { width: `100%`, height: `100%`, - top: 0, - left: 0, + top: "0", + left: "0", zIndex: "1000", "z-index": "1000", position: "fixed" } } - }); + } + myPort.postMessage(restyleMessage); } const collapse = () => { - myPort.postMessage({ + const restyleMessage: Fdc3UserInterfaceRestyle = { type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { @@ -121,7 +123,8 @@ window.addEventListener("load", () => { position: "fixed" } } - }); + } + myPort.postMessage(restyleMessage); // If you immediately change to the logo, before the iframe has a chance to finish restyling, // you see a flicker of a giant, colored logo. diff --git a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts index 3c01cd23e..e8c4590b0 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts @@ -1,8 +1,14 @@ import { Icon } from "@kite9/fdc3"; import { AppIntent } from "@kite9/fdc3"; -import { IframeResolveActionPayload, IframeResolvePayload } from "@kite9/fdc3-common"; +import { BrowserTypes } from "@kite9/fdc3-schema"; -const setup = (data: IframeResolvePayload, callback: (s: IframeResolveActionPayload) => void) => { +type Fdc3UserInterfaceHello = BrowserTypes.Fdc3UserInterfaceHello; +type Fdc3UserInterfaceRestyle = BrowserTypes.Fdc3UserInterfaceRestyle; +type Fdc3UserInterfaceResolve = BrowserTypes.Fdc3UserInterfaceResolve; +type Fdc3UserInterfaceResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction; + + +const setup = (data: Fdc3UserInterfaceResolve["payload"], callback: (payload: Fdc3UserInterfaceResolveAction["payload"]) => void) => { document.body.setAttribute("data-visible", "true"); document.querySelector("dialog")?.showModal(); @@ -62,7 +68,7 @@ function createIcon(icons: Icon[] | undefined): HTMLElement { return img } -const fillList = (ai: AppIntent[], intent: string, callback: (s: IframeResolveActionPayload) => void) => { +const fillList = (ai: AppIntent[], intent: string, callback: (payload: Fdc3UserInterfaceResolveAction["payload"]) => void) => { const allApps = ai.flatMap(a => a.apps) const openApps = allApps.filter(a => a.instanceId) const newApps = allApps.filter(a => !a.instanceId) @@ -163,8 +169,8 @@ window.addEventListener("load", () => { break; } case "Fdc3UserInterfaceResolve": { - myPort.postMessage({ - type: "IframeRestyle", + const restyleMessage: Fdc3UserInterfaceRestyle = { + type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { width: "100%", @@ -174,16 +180,18 @@ window.addEventListener("load", () => { position: "fixed" } } - }); + } + myPort.postMessage(restyleMessage); - setup(data.payload, (s) => { + setup(data.payload, (payload) => { document.querySelector("dialog")?.close(); - myPort.postMessage({ + const resolveAction: Fdc3UserInterfaceResolveAction = { type: "Fdc3UserInterfaceResolveAction", - payload: s - }); + payload + } + myPort.postMessage(resolveAction); - myPort.postMessage({ + const restyleMessage: Fdc3UserInterfaceRestyle = { type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: { @@ -191,21 +199,24 @@ window.addEventListener("load", () => { height: "0" } } - }); + } + + myPort.postMessage(restyleMessage); }) } } }; - parent.postMessage({ + const helloMessage: Fdc3UserInterfaceHello = { type: "Fdc3UserInterfaceHello", payload: { + implementationDetails: "", initialCSS: { width: "0", height: "0" } } - }, "*", [mc.port2]); - + } + parent.postMessage(helloMessage, "*", [mc.port2]); }); \ No newline at end of file From 9de15089bece567638c15dbf3c500c8b5b0f6b99 Mon Sep 17 00:00:00 2001 From: Rob Moffat Date: Thu, 14 Nov 2024 12:18:36 +0000 Subject: [PATCH 08/12] Merged Giles' change --- .../fdc3-schema/generated/api/BrowserTypes.ts | 805 +++++++++++++++++- packages/fdc3-schema/package.json | 4 +- 2 files changed, 772 insertions(+), 37 deletions(-) diff --git a/packages/fdc3-schema/generated/api/BrowserTypes.ts b/packages/fdc3-schema/generated/api/BrowserTypes.ts index 98d3ef495..513f7f9b2 100644 --- a/packages/fdc3-schema/generated/api/BrowserTypes.ts +++ b/packages/fdc3-schema/generated/api/BrowserTypes.ts @@ -114,7 +114,7 @@ export interface WebConnectionProtocol1Hello { */ export interface WebConnectionProtocol1HelloMeta { connectionAttemptUuid: string; - timestamp: Date; + timestamp: Date; } /** @@ -603,7 +603,7 @@ export interface WebConnectionProtocolMessage { * Metadata for a Web Connection Protocol message. */ export interface ConnectionStepMetadata { - timestamp: Date; + timestamp: Date; connectionAttemptUuid?: string; } @@ -648,7 +648,7 @@ export interface AddContextListenerRequestMeta { * purposes but a Desktop Agent should make its own determination of the source of a message * to avoid spoofing. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -751,13 +751,13 @@ export interface AddContextListenerResponse { * Metadata for messages sent by a Desktop Agent to an app in response to an API call. */ export interface AddContextListenerResponseMeta { - requestUuid: string; + requestUuid: string; responseUuid: string; /** * Field that represents the source application that the request being responded to was * received from, for debugging purposes. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -767,7 +767,7 @@ export interface AddContextListenerResponseMeta { * unsuccessful. */ export interface AddContextListenerResponsePayload { - error?: PurpleError; + error?: PurpleError; listenerUUID?: string; } @@ -857,7 +857,7 @@ export interface AddEventListenerResponse { * unsuccessful. */ export interface AddEventListenerResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; listenerUUID?: string; } @@ -942,7 +942,7 @@ export interface AddIntentListenerResponse { * unsuccessful. */ export interface AddIntentListenerResponsePayload { - error?: FluffyError; + error?: FluffyError; listenerUUID?: string; [property: string]: any; } @@ -1021,13 +1021,13 @@ export interface AgentResponseMessage { * Metadata for messages sent by a Desktop Agent to an app in response to an API call. */ export interface AgentResponseMessageMeta { - requestUuid: string; + requestUuid: string; responseUuid: string; /** * Field that represents the source application that the request being responded to was * received from, for debugging purposes. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -1077,7 +1077,7 @@ export interface AppRequestMessageMeta { * purposes but a Desktop Agent should make its own determination of the source of a message * to avoid spoofing. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -1448,7 +1448,7 @@ export interface CreatePrivateChannelResponse { * unsuccessful. */ export interface CreatePrivateChannelResponsePayload { - error?: PurpleError; + error?: PurpleError; privateChannel?: Channel; } @@ -1868,7 +1868,7 @@ export interface Fdc3UserInterfaceResolvePayload { * An array of AppIntent objects defining the resolution options. */ appIntents: AppIntent[]; - context: Context; + context: Context; } /** @@ -2098,7 +2098,7 @@ export interface FindInstancesResponse { * resulted in an error and including a standardized error message. */ export interface FindInstancesResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIdentifiers?: AppMetadata[]; } @@ -2159,8 +2159,8 @@ export interface FindIntentRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentRequestPayload { - context?: Context; - intent: string; + context?: Context; + intent: string; resultType?: string; } @@ -2199,7 +2199,7 @@ export interface FindIntentResponse { * unsuccessful. */ export interface FindIntentResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIntent?: AppIntent; } @@ -2234,7 +2234,7 @@ export interface FindIntentsByContextRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentsByContextRequestPayload { - context: Context; + context: Context; resultType?: string; } @@ -2273,7 +2273,7 @@ export interface FindIntentsByContextResponse { * unsuccessful. */ export interface FindIntentsByContextResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIntents?: AppIntent[]; } @@ -2345,7 +2345,7 @@ export interface GetAppMetadataResponse { * unsuccessful. */ export interface GetAppMetadataResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appMetadata?: AppMetadata; } @@ -2417,7 +2417,7 @@ export interface GetCurrentChannelResponse { * unsuccessful. */ export interface GetCurrentChannelResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; channel?: Channel | null; } @@ -2575,7 +2575,7 @@ export interface GetInfoResponse { * unsuccessful. */ export interface GetInfoResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; implementationMetadata?: ImplementationMetadata; } @@ -2651,7 +2651,7 @@ export interface GetOrCreateChannelResponse { * unsuccessful. */ export interface GetOrCreateChannelResponsePayload { - error?: PurpleError; + error?: PurpleError; channel?: Channel; } @@ -2722,7 +2722,7 @@ export interface GetUserChannelsResponse { * unsuccessful. */ export interface GetUserChannelsResponsePayload { - error?: PurpleError; + error?: PurpleError; userChannels?: Channel[]; } @@ -2945,7 +2945,7 @@ export interface IntentResultRequestPayload { * The eventUuid value of the intentEvent that the result being sent relates to. */ intentEventUuid: string; - intentResult: IntentResult; + intentResult: IntentResult; /** * The requestUuid value of the raiseIntentRequest that the result being sent relates to. */ @@ -3208,7 +3208,7 @@ export interface OpenResponse { * unsuccessful. */ export interface OpenResponsePayload { - error?: OpenErrorResponsePayload; + error?: OpenErrorResponsePayload; appIdentifier?: AppIdentifier; } @@ -3304,7 +3304,7 @@ export interface PrivateChannelAddEventListenerResponse { * unsuccessful. */ export interface PrivateChannelAddEventListenerResponsePayload { - error?: PurpleError; + error?: PurpleError; listenerUUID?: string; [property: string]: any; } @@ -3597,7 +3597,7 @@ export interface RaiseIntentForContextRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface RaiseIntentForContextRequestPayload { - app?: AppIdentifier; + app?: AppIdentifier; context: Context; } @@ -3736,9 +3736,9 @@ export interface RaiseIntentRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface RaiseIntentRequestPayload { - app?: AppIdentifier; + app?: AppIdentifier; context: Context; - intent: string; + intent: string; } /** @@ -3841,7 +3841,7 @@ export interface RaiseIntentResultResponse { * unsuccessful. */ export interface RaiseIntentResultResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; intentResult?: IntentResult; } @@ -4554,7 +4554,7 @@ function transform(val: any, typ: any, getProps: any, key: any = '', parent: any const typ = typs[i]; try { return transform(val, typ, getProps); - } catch (_) {} + } catch (_) { } } return invalidValue(typs, val, key, parent); } @@ -4613,9 +4613,9 @@ function transform(val: any, typ: any, getProps: any, key: any = '', parent: any if (Array.isArray(typ)) return transformEnum(typ, val); if (typeof typ === "object") { return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) - : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) - : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) - : invalidValue(typ, val, key, parent); + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val, key, parent); } // Numbers can be parsed by Date but shouldn't be. if (typ === Date && typeof val !== "number") return transformDate(val); @@ -5857,3 +5857,738 @@ const typeMap: any = { "raiseIntentResultResponse", ], }; + +export function isWebConnectionProtocol1Hello(value: any): value is WebConnectionProtocol1Hello { + try { + Convert.webConnectionProtocol1HelloToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocol2LoadURL(value: any): value is WebConnectionProtocol2LoadURL { + try { + Convert.webConnectionProtocol2LoadURLToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocol3Handshake(value: any): value is WebConnectionProtocol3Handshake { + try { + Convert.webConnectionProtocol3HandshakeToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocol4ValidateAppIdentity(value: any): value is WebConnectionProtocol4ValidateAppIdentity { + try { + Convert.webConnectionProtocol4ValidateAppIdentityToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocol5ValidateAppIdentityFailedResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentityFailedResponse { + try { + Convert.webConnectionProtocol5ValidateAppIdentityFailedResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocol5ValidateAppIdentitySuccessResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentitySuccessResponse { + try { + Convert.webConnectionProtocol5ValidateAppIdentitySuccessResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocol6Goodbye(value: any): value is WebConnectionProtocol6Goodbye { + try { + Convert.webConnectionProtocol6GoodbyeToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isWebConnectionProtocolMessage(value: any): value is WebConnectionProtocolMessage { + try { + Convert.webConnectionProtocolMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAddContextListenerRequest(value: any): value is AddContextListenerRequest { + try { + Convert.addContextListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAddContextListenerResponse(value: any): value is AddContextListenerResponse { + try { + Convert.addContextListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAddEventListenerRequest(value: any): value is AddEventListenerRequest { + try { + Convert.addEventListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAddEventListenerResponse(value: any): value is AddEventListenerResponse { + try { + Convert.addEventListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAddIntentListenerRequest(value: any): value is AddIntentListenerRequest { + try { + Convert.addIntentListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAddIntentListenerResponse(value: any): value is AddIntentListenerResponse { + try { + Convert.addIntentListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAgentEventMessage(value: any): value is AgentEventMessage { + try { + Convert.agentEventMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAgentResponseMessage(value: any): value is AgentResponseMessage { + try { + Convert.agentResponseMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isAppRequestMessage(value: any): value is AppRequestMessage { + try { + Convert.appRequestMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isBroadcastEvent(value: any): value is BroadcastEvent { + try { + Convert.broadcastEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isBroadcastRequest(value: any): value is BroadcastRequest { + try { + Convert.broadcastRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isBroadcastResponse(value: any): value is BroadcastResponse { + try { + Convert.broadcastResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isChannelChangedEvent(value: any): value is ChannelChangedEvent { + try { + Convert.channelChangedEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isContextListenerUnsubscribeRequest(value: any): value is ContextListenerUnsubscribeRequest { + try { + Convert.contextListenerUnsubscribeRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isContextListenerUnsubscribeResponse(value: any): value is ContextListenerUnsubscribeResponse { + try { + Convert.contextListenerUnsubscribeResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isCreatePrivateChannelRequest(value: any): value is CreatePrivateChannelRequest { + try { + Convert.createPrivateChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isCreatePrivateChannelResponse(value: any): value is CreatePrivateChannelResponse { + try { + Convert.createPrivateChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isEventListenerUnsubscribeRequest(value: any): value is EventListenerUnsubscribeRequest { + try { + Convert.eventListenerUnsubscribeRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isEventListenerUnsubscribeResponse(value: any): value is EventListenerUnsubscribeResponse { + try { + Convert.eventListenerUnsubscribeResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceChannelSelected(value: any): value is Fdc3UserInterfaceChannelSelected { + try { + Convert.fdc3UserInterfaceChannelSelectedToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceChannels(value: any): value is Fdc3UserInterfaceChannels { + try { + Convert.fdc3UserInterfaceChannelsToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceDrag(value: any): value is Fdc3UserInterfaceDrag { + try { + Convert.fdc3UserInterfaceDragToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceHandshake(value: any): value is Fdc3UserInterfaceHandshake { + try { + Convert.fdc3UserInterfaceHandshakeToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceHello(value: any): value is Fdc3UserInterfaceHello { + try { + Convert.fdc3UserInterfaceHelloToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceMessage(value: any): value is Fdc3UserInterfaceMessage { + try { + Convert.fdc3UserInterfaceMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceResolve(value: any): value is Fdc3UserInterfaceResolve { + try { + Convert.fdc3UserInterfaceResolveToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceResolveAction(value: any): value is Fdc3UserInterfaceResolveAction { + try { + Convert.fdc3UserInterfaceResolveActionToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFdc3UserInterfaceRestyle(value: any): value is Fdc3UserInterfaceRestyle { + try { + Convert.fdc3UserInterfaceRestyleToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFindInstancesRequest(value: any): value is FindInstancesRequest { + try { + Convert.findInstancesRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFindInstancesResponse(value: any): value is FindInstancesResponse { + try { + Convert.findInstancesResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFindIntentRequest(value: any): value is FindIntentRequest { + try { + Convert.findIntentRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFindIntentResponse(value: any): value is FindIntentResponse { + try { + Convert.findIntentResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFindIntentsByContextRequest(value: any): value is FindIntentsByContextRequest { + try { + Convert.findIntentsByContextRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isFindIntentsByContextResponse(value: any): value is FindIntentsByContextResponse { + try { + Convert.findIntentsByContextResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetAppMetadataRequest(value: any): value is GetAppMetadataRequest { + try { + Convert.getAppMetadataRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetAppMetadataResponse(value: any): value is GetAppMetadataResponse { + try { + Convert.getAppMetadataResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetCurrentChannelRequest(value: any): value is GetCurrentChannelRequest { + try { + Convert.getCurrentChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetCurrentChannelResponse(value: any): value is GetCurrentChannelResponse { + try { + Convert.getCurrentChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetCurrentContextRequest(value: any): value is GetCurrentContextRequest { + try { + Convert.getCurrentContextRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetCurrentContextResponse(value: any): value is GetCurrentContextResponse { + try { + Convert.getCurrentContextResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetInfoRequest(value: any): value is GetInfoRequest { + try { + Convert.getInfoRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetInfoResponse(value: any): value is GetInfoResponse { + try { + Convert.getInfoResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetOrCreateChannelRequest(value: any): value is GetOrCreateChannelRequest { + try { + Convert.getOrCreateChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetOrCreateChannelResponse(value: any): value is GetOrCreateChannelResponse { + try { + Convert.getOrCreateChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetUserChannelsRequest(value: any): value is GetUserChannelsRequest { + try { + Convert.getUserChannelsRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isGetUserChannelsResponse(value: any): value is GetUserChannelsResponse { + try { + Convert.getUserChannelsResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isHeartbeatAcknowledgementRequest(value: any): value is HeartbeatAcknowledgementRequest { + try { + Convert.heartbeatAcknowledgementRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isHeartbeatEvent(value: any): value is HeartbeatEvent { + try { + Convert.heartbeatEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isIntentEvent(value: any): value is IntentEvent { + try { + Convert.intentEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isIntentListenerUnsubscribeRequest(value: any): value is IntentListenerUnsubscribeRequest { + try { + Convert.intentListenerUnsubscribeRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isIntentListenerUnsubscribeResponse(value: any): value is IntentListenerUnsubscribeResponse { + try { + Convert.intentListenerUnsubscribeResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isIntentResultRequest(value: any): value is IntentResultRequest { + try { + Convert.intentResultRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isIntentResultResponse(value: any): value is IntentResultResponse { + try { + Convert.intentResultResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isJoinUserChannelRequest(value: any): value is JoinUserChannelRequest { + try { + Convert.joinUserChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isJoinUserChannelResponse(value: any): value is JoinUserChannelResponse { + try { + Convert.joinUserChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isLeaveCurrentChannelRequest(value: any): value is LeaveCurrentChannelRequest { + try { + Convert.leaveCurrentChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isLeaveCurrentChannelResponse(value: any): value is LeaveCurrentChannelResponse { + try { + Convert.leaveCurrentChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isOpenRequest(value: any): value is OpenRequest { + try { + Convert.openRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isOpenResponse(value: any): value is OpenResponse { + try { + Convert.openResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelAddEventListenerRequest(value: any): value is PrivateChannelAddEventListenerRequest { + try { + Convert.privateChannelAddEventListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelAddEventListenerResponse(value: any): value is PrivateChannelAddEventListenerResponse { + try { + Convert.privateChannelAddEventListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelDisconnectRequest(value: any): value is PrivateChannelDisconnectRequest { + try { + Convert.privateChannelDisconnectRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelDisconnectResponse(value: any): value is PrivateChannelDisconnectResponse { + try { + Convert.privateChannelDisconnectResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelOnAddContextListenerEvent(value: any): value is PrivateChannelOnAddContextListenerEvent { + try { + Convert.privateChannelOnAddContextListenerEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelOnDisconnectEvent(value: any): value is PrivateChannelOnDisconnectEvent { + try { + Convert.privateChannelOnDisconnectEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelOnUnsubscribeEvent(value: any): value is PrivateChannelOnUnsubscribeEvent { + try { + Convert.privateChannelOnUnsubscribeEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelUnsubscribeEventListenerRequest(value: any): value is PrivateChannelUnsubscribeEventListenerRequest { + try { + Convert.privateChannelUnsubscribeEventListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isPrivateChannelUnsubscribeEventListenerResponse(value: any): value is PrivateChannelUnsubscribeEventListenerResponse { + try { + Convert.privateChannelUnsubscribeEventListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isRaiseIntentForContextRequest(value: any): value is RaiseIntentForContextRequest { + try { + Convert.raiseIntentForContextRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isRaiseIntentForContextResponse(value: any): value is RaiseIntentForContextResponse { + try { + Convert.raiseIntentForContextResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isRaiseIntentRequest(value: any): value is RaiseIntentRequest { + try { + Convert.raiseIntentRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isRaiseIntentResponse(value: any): value is RaiseIntentResponse { + try { + Convert.raiseIntentResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export function isRaiseIntentResultResponse(value: any): value is RaiseIntentResultResponse { + try { + Convert.raiseIntentResultResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export type RequestMessage = AddContextListenerRequest | AddEventListenerRequest | AddIntentListenerRequest | BroadcastRequest | ContextListenerUnsubscribeRequest | CreatePrivateChannelRequest | EventListenerUnsubscribeRequest | FindInstancesRequest | FindIntentRequest | FindIntentsByContextRequest | GetAppMetadataRequest | GetCurrentChannelRequest | GetCurrentContextRequest | GetInfoRequest | GetOrCreateChannelRequest | GetUserChannelsRequest | HeartbeatAcknowledgementRequest | IntentListenerUnsubscribeRequest | IntentResultRequest | JoinUserChannelRequest | LeaveCurrentChannelRequest | OpenRequest | PrivateChannelAddEventListenerRequest | PrivateChannelDisconnectRequest | PrivateChannelUnsubscribeEventListenerRequest | RaiseIntentForContextRequest | RaiseIntentRequest; + +export type ResponseMessage = WebConnectionProtocol5ValidateAppIdentityFailedResponse | WebConnectionProtocol5ValidateAppIdentitySuccessResponse | AddContextListenerResponse | AddEventListenerResponse | AddIntentListenerResponse | BroadcastResponse | ContextListenerUnsubscribeResponse | CreatePrivateChannelResponse | EventListenerUnsubscribeResponse | FindInstancesResponse | FindIntentResponse | FindIntentsByContextResponse | GetAppMetadataResponse | GetCurrentChannelResponse | GetCurrentContextResponse | GetInfoResponse | GetOrCreateChannelResponse | GetUserChannelsResponse | IntentListenerUnsubscribeResponse | IntentResultResponse | JoinUserChannelResponse | LeaveCurrentChannelResponse | OpenResponse | PrivateChannelAddEventListenerResponse | PrivateChannelDisconnectResponse | PrivateChannelUnsubscribeEventListenerResponse | RaiseIntentForContextResponse | RaiseIntentResponse | RaiseIntentResultResponse; + +export type EventMessage = BroadcastEvent | ChannelChangedEvent | HeartbeatEvent | IntentEvent | PrivateChannelOnAddContextListenerEvent | PrivateChannelOnDisconnectEvent | PrivateChannelOnUnsubscribeEvent; diff --git a/packages/fdc3-schema/package.json b/packages/fdc3-schema/package.json index efc9f94a9..4d609bab5 100644 --- a/packages/fdc3-schema/package.json +++ b/packages/fdc3-schema/package.json @@ -19,9 +19,9 @@ "scripts": { "clean": "rimraf dist && rimraf generated", "mkdirs": "mkdirp generated/api && mkdirp generated/bridging", - "generate": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run lint", + "generate-old": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run lint", "generate-type-predicates": "ts-node code-generation/generate-type-predicates.ts", - "generate-new": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run generate-type-predicates && npm run lint", + "generate": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run generate-type-predicates && npm run lint", "build": "npm run generate && tsc --module es2022", "lint": "eslint generated/ --fix", "test": "npm run generate && tsc", From 469d7dae166155c5c66d0ef7187fa5aa111659ee Mon Sep 17 00:00:00 2001 From: Rob Moffat Date: Thu, 14 Nov 2024 13:09:57 +0000 Subject: [PATCH 09/12] Converted to constants for all Fdc3UserInterface type usages --- package-lock.json | 1 - package.json | 2 +- .../generated/context/ContextTypes.ts | 2 +- .../src/ui/AbstractUIComponent.ts | 8 +- .../ui/DefaultDesktopAgentChannelSelector.ts | 5 +- .../ui/DefaultDesktopAgentIntentResolver.ts | 5 +- .../step-definitions/intent-resolver.steps.ts | 5 +- .../fdc3-get-agent/test/support/FrameTypes.ts | 13 +- .../generate-type-predicates.ts | 14 +- .../fdc3-schema/generated/api/BrowserTypes.ts | 243 ++++++++++++++++++ .../demo/src/client/ui/channel-selector.ts | 19 +- .../demo/src/client/ui/intent-resolver.ts | 17 +- .../fdc3-for-web/reference-ui/package.json | 2 +- .../reference-ui/src/channel_selector.ts | 46 ++-- .../reference-ui/src/intent_resolver.ts | 67 +++-- toolbox/fdc3-for-web/reference-ui/src/main.ts | 197 -------------- 16 files changed, 350 insertions(+), 296 deletions(-) delete mode 100644 toolbox/fdc3-for-web/reference-ui/src/main.ts diff --git a/package-lock.json b/package-lock.json index 18876cb08..5b94e2954 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17160,7 +17160,6 @@ } }, "toolbox/fdc3-for-web/reference-ui": { - "name": "fdc3-for-web-reference-ui", "version": "2.1.1", "dependencies": { "@kite9/fdc3-common": "2.2.0-beta.6" diff --git a/package.json b/package.json index 20d5c9f69..d610bd202 100644 --- a/package.json +++ b/package.json @@ -26,8 +26,8 @@ "toolbox/fdc3-for-web/fdc3-web-impl", "packages/fdc3-get-agent", "packages/fdc3", - "toolbox/fdc3-for-web/demo", "toolbox/fdc3-for-web/reference-ui", + "toolbox/fdc3-for-web/demo", "toolbox/fdc3-workbench" ], "scripts": { diff --git a/packages/fdc3-context/generated/context/ContextTypes.ts b/packages/fdc3-context/generated/context/ContextTypes.ts index 8324b91c8..794687e52 100644 --- a/packages/fdc3-context/generated/context/ContextTypes.ts +++ b/packages/fdc3-context/generated/context/ContextTypes.ts @@ -119,7 +119,7 @@ export type ActionType = "broadcast" | "raiseIntent"; export interface AppIdentifier { /** * The unique application identifier located within a specific application directory - * instance. An example of an appId might be 'app@sub.root' + * instance. An example of an appId might be 'app@sub.root'. */ appId: string; /** diff --git a/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts b/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts index bb2b24071..bdae57256 100644 --- a/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts +++ b/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts @@ -1,4 +1,4 @@ -import { Fdc3UserInterfaceHello, InitialCSS, UpdatedCSS } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, Fdc3UserInterfaceHello, InitialCSS, UpdatedCSS } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; import { Connectable } from "@kite9/fdc3-standard"; export interface CSSPositioning { [key: string]: string } @@ -57,7 +57,7 @@ export abstract class AbstractUIComponent implements Connectable { async setupMessagePort(port: MessagePort): Promise { port.addEventListener("message", (e) => { const data = e.data - if (data.type == 'Fdc3UserInterfaceRestyle') { + if (data.type == FDC3_USER_INTERFACE_RESTYLE_TYPE) { // console.log(`Restyling ${JSON.stringify(data.payload)}`) const css = data.payload.updatedCSS this.themeContainer(css) @@ -67,14 +67,14 @@ export abstract class AbstractUIComponent implements Connectable { async messagePortReady(port: MessagePort) { // tells the iframe it can start posting - port.postMessage({ type: "Fdc3UserInterfaceHandshake" }) + port.postMessage({ type: FDC3_USER_INTERFACE_HANDSHAKE_TYPE }) } private awaitHello(): Promise { return new Promise((resolve, _reject) => { const ml = (e: MessageEvent) => { // console.log("Received UI Message: " + JSON.stringify(e.data)) - if ((e.source == this.iframe?.contentWindow) && (e.data.type == 'Fdc3UserInterfaceHello')) { + if ((e.source == this.iframe?.contentWindow) && (e.data.type == FDC3_USER_INTERFACE_HELLO_TYPE)) { const helloData = e.data as Fdc3UserInterfaceHello if (helloData.payload.initialCSS) { this.themeContainer(helloData.payload.initialCSS) diff --git a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts index faf0e849d..89593adee 100644 --- a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts +++ b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts @@ -2,6 +2,7 @@ import { Channel } from "@kite9/fdc3-standard"; import { ChannelSelector } from "@kite9/fdc3-standard" import { AbstractUIComponent } from "./AbstractUIComponent"; import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type Fdc3UserInterfaceChannels = BrowserTypes.Fdc3UserInterfaceChannels type Fdc3UserInterfaceChannelSelected = BrowserTypes.Fdc3UserInterfaceChannelSelected @@ -25,7 +26,7 @@ export class DefaultDesktopAgentChannelSelector extends AbstractUIComponent impl this.port = port port.addEventListener("message", (e) => { - if (e.data.type == 'Fdc3UserInterfaceChannelSelected') { + if (e.data.type == FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE) { const choice = e.data as Fdc3UserInterfaceChannelSelected if (this.callback) { this.callback(choice.payload.selected) @@ -37,7 +38,7 @@ export class DefaultDesktopAgentChannelSelector extends AbstractUIComponent impl updateChannel(channelId: string | null, availableChannels: Channel[]): void { // also send to the iframe this.port!!.postMessage({ - type: 'Fdc3UserInterfaceChannels', + type: FDC3_USER_INTERFACE_CHANNELS_TYPE, payload: { selected: channelId, userChannels: availableChannels.map(ch => { diff --git a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts index f0c1910aa..d8f5272ee 100644 --- a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts +++ b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts @@ -3,6 +3,7 @@ import { IntentResolver, IntentResolutionChoice } from '@kite9/fdc3-standard' import { AbstractUIComponent } from "./AbstractUIComponent"; import { BrowserTypes } from "@kite9/fdc3-schema"; import { Context } from "@kite9/fdc3-context"; +import { FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESOLVE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type Fdc3UserInterfaceResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction type Fdc3UserInterfaceResolve = BrowserTypes.Fdc3UserInterfaceResolve @@ -26,7 +27,7 @@ export class DefaultDesktopAgentIntentResolver extends AbstractUIComponent imple this.port.addEventListener("message", (e) => { console.log("Got resolve action") - if (e.data.type == 'Fdc3UserInterfaceResolveAction') { + if (e.data.type == FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE) { const choice = e.data as Fdc3UserInterfaceResolveAction if ((choice.payload.action == 'click') && (this.pendingResolve)) { this.pendingResolve({ @@ -49,7 +50,7 @@ export class DefaultDesktopAgentIntentResolver extends AbstractUIComponent imple this.port?.postMessage({ - type: 'Fdc3UserInterfaceResolve', + type: FDC3_USER_INTERFACE_RESOLVE_TYPE, payload: { appIntents, context diff --git a/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts b/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts index 2bc2cc7e1..cb5963dce 100644 --- a/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts +++ b/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts @@ -3,6 +3,7 @@ import { CustomWorld } from "../world"; import { handleResolve } from "@kite9/testing"; import { DefaultDesktopAgentIntentResolver } from "../../src/ui/DefaultDesktopAgentIntentResolver"; import { INTENT_RESPOLVER_URL } from "../support/MockFDC3Server"; +import { FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; const contextMap: Record = { @@ -76,7 +77,7 @@ Given('The intent resolver sends an intent selection message', async function (t const port = handleResolve("{document.iframes[0].messageChannels[0].port2}", this) port.postMessage({ - type: 'Fdc3UserInterfaceResolveAction', + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: 'click', appIdentifier: { @@ -91,7 +92,7 @@ Given('The intent resolver cancels the intent selection message', async function const port = handleResolve("{document.iframes[0].messageChannels[0].port2}", this) port.postMessage({ - type: 'Fdc3UserInterfaceResolveAction', + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: 'cancel' } diff --git a/packages/fdc3-get-agent/test/support/FrameTypes.ts b/packages/fdc3-get-agent/test/support/FrameTypes.ts index 1a2094267..443998425 100644 --- a/packages/fdc3-get-agent/test/support/FrameTypes.ts +++ b/packages/fdc3-get-agent/test/support/FrameTypes.ts @@ -2,6 +2,7 @@ import { CustomWorld } from "../world" import { MockWindow } from "./MockWindow" import { CHANNEL_SELECTOR_URL, EMBED_URL, INTENT_RESPOLVER_URL } from "./MockFDC3Server" import { BrowserTypes } from "@kite9/fdc3-schema" +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes" type Fdc3UserInterfaceHello = BrowserTypes.Fdc3UserInterfaceHello type WebConnectionProtocol3Handshake = BrowserTypes.WebConnectionProtocol3Handshake @@ -38,7 +39,7 @@ export function handleChannelSelectorComms(_value: string, parent: MockWindow, s parent.dispatchEvent({ type: "message", data: { - type: "Fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: { "width": "100px" @@ -52,10 +53,10 @@ export function handleChannelSelectorComms(_value: string, parent: MockWindow, s connection.port2.onmessage = (e) => { - if (e.data.type == 'Fdc3UserInterfaceHandshake') { + if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { setTimeout(() => { connection.port2.postMessage({ - type: 'Fdc3UserInterfaceRestyle', + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { css: { "width": "100px" @@ -79,7 +80,7 @@ export function handleIntentResolverComms(_value: string, parent: MockWindow, so parent.dispatchEvent({ type: "message", data: { - type: "Fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: { "width": "100px" @@ -92,10 +93,10 @@ export function handleIntentResolverComms(_value: string, parent: MockWindow, so } as any as Event) connection.port2.onmessage = (e) => { - if (e.type == 'Fdc3UserInterfaceHandshake') { + if (e.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { setTimeout(() => { connection.port2.postMessage({ - type: 'Fdc3UserInterfaceRestyle', + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { css: { "width": "100px" diff --git a/packages/fdc3-schema/code-generation/generate-type-predicates.ts b/packages/fdc3-schema/code-generation/generate-type-predicates.ts index ef8d13301..1ed5801a4 100644 --- a/packages/fdc3-schema/code-generation/generate-type-predicates.ts +++ b/packages/fdc3-schema/code-generation/generate-type-predicates.ts @@ -28,7 +28,10 @@ const matchedInterfaces = convertFunctions.map(func => { }).filter(((value => value != null) as (value: T | null | undefined) => value is T)); // write a type predicate for each matched interface -matchedInterfaces.forEach(matched => writePredicate(matched.matchingInterface, matched.func)); +matchedInterfaces.forEach(matched => { + writePredicate(matched.matchingInterface, matched.func) + writeTypeConstant(matched.matchingInterface) +}); writeUnionType("RequestMessage", interfaces, "Request"); writeUnionType("ResponseMessage", interfaces, "Response"); @@ -48,6 +51,13 @@ export function ${predicateName}(value: any): value is ${matchingInterface.getNa }`); } +function writeTypeConstant(matchingInterface: InterfaceDeclaration): void { + + sourceFile.addStatements(` + export const ${matchingInterface.getName().replaceAll(/([A-Z])/g, '_$1').toUpperCase().substring(1)}_TYPE = "${matchingInterface.getName()}"; + `); + +} function writeUnionType(unionName: string, interfaces: InterfaceDeclaration[], nameEndsWith: string): void { @@ -56,7 +66,7 @@ function writeUnionType(unionName: string, interfaces: InterfaceDeclaration[], n .filter(interfaceName => interfaceName.length > nameEndsWith.length && interfaceName.indexOf(nameEndsWith) === interfaceName.length - nameEndsWith.length); sourceFile.addStatements(` -export type ${unionName} = ${matchingInterfaces.join(" | ")};`); + export type ${unionName} = ${matchingInterfaces.join(" | ")}; `); } sourceFile.formatText(); diff --git a/packages/fdc3-schema/generated/api/BrowserTypes.ts b/packages/fdc3-schema/generated/api/BrowserTypes.ts index 513f7f9b2..a924b0bdf 100644 --- a/packages/fdc3-schema/generated/api/BrowserTypes.ts +++ b/packages/fdc3-schema/generated/api/BrowserTypes.ts @@ -5867,6 +5867,8 @@ export function isWebConnectionProtocol1Hello(value: any): value is WebConnectio } } +export const WEB_CONNECTION_PROTOCOL1_HELLO_TYPE = "WebConnectionProtocol1Hello"; + export function isWebConnectionProtocol2LoadURL(value: any): value is WebConnectionProtocol2LoadURL { try { Convert.webConnectionProtocol2LoadURLToJson(value); @@ -5876,6 +5878,8 @@ export function isWebConnectionProtocol2LoadURL(value: any): value is WebConnect } } +export const WEB_CONNECTION_PROTOCOL2_LOAD_U_R_L_TYPE = "WebConnectionProtocol2LoadURL"; + export function isWebConnectionProtocol3Handshake(value: any): value is WebConnectionProtocol3Handshake { try { Convert.webConnectionProtocol3HandshakeToJson(value); @@ -5885,6 +5889,8 @@ export function isWebConnectionProtocol3Handshake(value: any): value is WebConne } } +export const WEB_CONNECTION_PROTOCOL3_HANDSHAKE_TYPE = "WebConnectionProtocol3Handshake"; + export function isWebConnectionProtocol4ValidateAppIdentity(value: any): value is WebConnectionProtocol4ValidateAppIdentity { try { Convert.webConnectionProtocol4ValidateAppIdentityToJson(value); @@ -5894,6 +5900,8 @@ export function isWebConnectionProtocol4ValidateAppIdentity(value: any): value i } } +export const WEB_CONNECTION_PROTOCOL4_VALIDATE_APP_IDENTITY_TYPE = "WebConnectionProtocol4ValidateAppIdentity"; + export function isWebConnectionProtocol5ValidateAppIdentityFailedResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentityFailedResponse { try { Convert.webConnectionProtocol5ValidateAppIdentityFailedResponseToJson(value); @@ -5903,6 +5911,8 @@ export function isWebConnectionProtocol5ValidateAppIdentityFailedResponse(value: } } +export const WEB_CONNECTION_PROTOCOL5_VALIDATE_APP_IDENTITY_FAILED_RESPONSE_TYPE = "WebConnectionProtocol5ValidateAppIdentityFailedResponse"; + export function isWebConnectionProtocol5ValidateAppIdentitySuccessResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentitySuccessResponse { try { Convert.webConnectionProtocol5ValidateAppIdentitySuccessResponseToJson(value); @@ -5912,6 +5922,8 @@ export function isWebConnectionProtocol5ValidateAppIdentitySuccessResponse(value } } +export const WEB_CONNECTION_PROTOCOL5_VALIDATE_APP_IDENTITY_SUCCESS_RESPONSE_TYPE = "WebConnectionProtocol5ValidateAppIdentitySuccessResponse"; + export function isWebConnectionProtocol6Goodbye(value: any): value is WebConnectionProtocol6Goodbye { try { Convert.webConnectionProtocol6GoodbyeToJson(value); @@ -5921,6 +5933,8 @@ export function isWebConnectionProtocol6Goodbye(value: any): value is WebConnect } } +export const WEB_CONNECTION_PROTOCOL6_GOODBYE_TYPE = "WebConnectionProtocol6Goodbye"; + export function isWebConnectionProtocolMessage(value: any): value is WebConnectionProtocolMessage { try { Convert.webConnectionProtocolMessageToJson(value); @@ -5930,6 +5944,8 @@ export function isWebConnectionProtocolMessage(value: any): value is WebConnecti } } +export const WEB_CONNECTION_PROTOCOL_MESSAGE_TYPE = "WebConnectionProtocolMessage"; + export function isAddContextListenerRequest(value: any): value is AddContextListenerRequest { try { Convert.addContextListenerRequestToJson(value); @@ -5939,6 +5955,8 @@ export function isAddContextListenerRequest(value: any): value is AddContextList } } +export const ADD_CONTEXT_LISTENER_REQUEST_TYPE = "AddContextListenerRequest"; + export function isAddContextListenerResponse(value: any): value is AddContextListenerResponse { try { Convert.addContextListenerResponseToJson(value); @@ -5948,6 +5966,8 @@ export function isAddContextListenerResponse(value: any): value is AddContextLis } } +export const ADD_CONTEXT_LISTENER_RESPONSE_TYPE = "AddContextListenerResponse"; + export function isAddEventListenerRequest(value: any): value is AddEventListenerRequest { try { Convert.addEventListenerRequestToJson(value); @@ -5957,6 +5977,8 @@ export function isAddEventListenerRequest(value: any): value is AddEventListener } } +export const ADD_EVENT_LISTENER_REQUEST_TYPE = "AddEventListenerRequest"; + export function isAddEventListenerResponse(value: any): value is AddEventListenerResponse { try { Convert.addEventListenerResponseToJson(value); @@ -5966,6 +5988,8 @@ export function isAddEventListenerResponse(value: any): value is AddEventListene } } +export const ADD_EVENT_LISTENER_RESPONSE_TYPE = "AddEventListenerResponse"; + export function isAddIntentListenerRequest(value: any): value is AddIntentListenerRequest { try { Convert.addIntentListenerRequestToJson(value); @@ -5975,6 +5999,8 @@ export function isAddIntentListenerRequest(value: any): value is AddIntentListen } } +export const ADD_INTENT_LISTENER_REQUEST_TYPE = "AddIntentListenerRequest"; + export function isAddIntentListenerResponse(value: any): value is AddIntentListenerResponse { try { Convert.addIntentListenerResponseToJson(value); @@ -5984,6 +6010,8 @@ export function isAddIntentListenerResponse(value: any): value is AddIntentListe } } +export const ADD_INTENT_LISTENER_RESPONSE_TYPE = "AddIntentListenerResponse"; + export function isAgentEventMessage(value: any): value is AgentEventMessage { try { Convert.agentEventMessageToJson(value); @@ -5993,6 +6021,8 @@ export function isAgentEventMessage(value: any): value is AgentEventMessage { } } +export const AGENT_EVENT_MESSAGE_TYPE = "AgentEventMessage"; + export function isAgentResponseMessage(value: any): value is AgentResponseMessage { try { Convert.agentResponseMessageToJson(value); @@ -6002,6 +6032,8 @@ export function isAgentResponseMessage(value: any): value is AgentResponseMessag } } +export const AGENT_RESPONSE_MESSAGE_TYPE = "AgentResponseMessage"; + export function isAppRequestMessage(value: any): value is AppRequestMessage { try { Convert.appRequestMessageToJson(value); @@ -6011,6 +6043,8 @@ export function isAppRequestMessage(value: any): value is AppRequestMessage { } } +export const APP_REQUEST_MESSAGE_TYPE = "AppRequestMessage"; + export function isBroadcastEvent(value: any): value is BroadcastEvent { try { Convert.broadcastEventToJson(value); @@ -6020,6 +6054,8 @@ export function isBroadcastEvent(value: any): value is BroadcastEvent { } } +export const BROADCAST_EVENT_TYPE = "BroadcastEvent"; + export function isBroadcastRequest(value: any): value is BroadcastRequest { try { Convert.broadcastRequestToJson(value); @@ -6029,6 +6065,8 @@ export function isBroadcastRequest(value: any): value is BroadcastRequest { } } +export const BROADCAST_REQUEST_TYPE = "BroadcastRequest"; + export function isBroadcastResponse(value: any): value is BroadcastResponse { try { Convert.broadcastResponseToJson(value); @@ -6038,6 +6076,8 @@ export function isBroadcastResponse(value: any): value is BroadcastResponse { } } +export const BROADCAST_RESPONSE_TYPE = "BroadcastResponse"; + export function isChannelChangedEvent(value: any): value is ChannelChangedEvent { try { Convert.channelChangedEventToJson(value); @@ -6047,6 +6087,8 @@ export function isChannelChangedEvent(value: any): value is ChannelChangedEvent } } +export const CHANNEL_CHANGED_EVENT_TYPE = "ChannelChangedEvent"; + export function isContextListenerUnsubscribeRequest(value: any): value is ContextListenerUnsubscribeRequest { try { Convert.contextListenerUnsubscribeRequestToJson(value); @@ -6056,6 +6098,8 @@ export function isContextListenerUnsubscribeRequest(value: any): value is Contex } } +export const CONTEXT_LISTENER_UNSUBSCRIBE_REQUEST_TYPE = "ContextListenerUnsubscribeRequest"; + export function isContextListenerUnsubscribeResponse(value: any): value is ContextListenerUnsubscribeResponse { try { Convert.contextListenerUnsubscribeResponseToJson(value); @@ -6065,6 +6109,8 @@ export function isContextListenerUnsubscribeResponse(value: any): value is Conte } } +export const CONTEXT_LISTENER_UNSUBSCRIBE_RESPONSE_TYPE = "ContextListenerUnsubscribeResponse"; + export function isCreatePrivateChannelRequest(value: any): value is CreatePrivateChannelRequest { try { Convert.createPrivateChannelRequestToJson(value); @@ -6074,6 +6120,8 @@ export function isCreatePrivateChannelRequest(value: any): value is CreatePrivat } } +export const CREATE_PRIVATE_CHANNEL_REQUEST_TYPE = "CreatePrivateChannelRequest"; + export function isCreatePrivateChannelResponse(value: any): value is CreatePrivateChannelResponse { try { Convert.createPrivateChannelResponseToJson(value); @@ -6083,6 +6131,8 @@ export function isCreatePrivateChannelResponse(value: any): value is CreatePriva } } +export const CREATE_PRIVATE_CHANNEL_RESPONSE_TYPE = "CreatePrivateChannelResponse"; + export function isEventListenerUnsubscribeRequest(value: any): value is EventListenerUnsubscribeRequest { try { Convert.eventListenerUnsubscribeRequestToJson(value); @@ -6092,6 +6142,8 @@ export function isEventListenerUnsubscribeRequest(value: any): value is EventLis } } +export const EVENT_LISTENER_UNSUBSCRIBE_REQUEST_TYPE = "EventListenerUnsubscribeRequest"; + export function isEventListenerUnsubscribeResponse(value: any): value is EventListenerUnsubscribeResponse { try { Convert.eventListenerUnsubscribeResponseToJson(value); @@ -6101,6 +6153,8 @@ export function isEventListenerUnsubscribeResponse(value: any): value is EventLi } } +export const EVENT_LISTENER_UNSUBSCRIBE_RESPONSE_TYPE = "EventListenerUnsubscribeResponse"; + export function isFdc3UserInterfaceChannelSelected(value: any): value is Fdc3UserInterfaceChannelSelected { try { Convert.fdc3UserInterfaceChannelSelectedToJson(value); @@ -6110,6 +6164,8 @@ export function isFdc3UserInterfaceChannelSelected(value: any): value is Fdc3Use } } +export const FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE = "Fdc3UserInterfaceChannelSelected"; + export function isFdc3UserInterfaceChannels(value: any): value is Fdc3UserInterfaceChannels { try { Convert.fdc3UserInterfaceChannelsToJson(value); @@ -6119,6 +6175,8 @@ export function isFdc3UserInterfaceChannels(value: any): value is Fdc3UserInterf } } +export const FDC3_USER_INTERFACE_CHANNELS_TYPE = "Fdc3UserInterfaceChannels"; + export function isFdc3UserInterfaceDrag(value: any): value is Fdc3UserInterfaceDrag { try { Convert.fdc3UserInterfaceDragToJson(value); @@ -6128,6 +6186,8 @@ export function isFdc3UserInterfaceDrag(value: any): value is Fdc3UserInterfaceD } } +export const FDC3_USER_INTERFACE_DRAG_TYPE = "Fdc3UserInterfaceDrag"; + export function isFdc3UserInterfaceHandshake(value: any): value is Fdc3UserInterfaceHandshake { try { Convert.fdc3UserInterfaceHandshakeToJson(value); @@ -6137,6 +6197,8 @@ export function isFdc3UserInterfaceHandshake(value: any): value is Fdc3UserInter } } +export const FDC3_USER_INTERFACE_HANDSHAKE_TYPE = "Fdc3UserInterfaceHandshake"; + export function isFdc3UserInterfaceHello(value: any): value is Fdc3UserInterfaceHello { try { Convert.fdc3UserInterfaceHelloToJson(value); @@ -6146,6 +6208,8 @@ export function isFdc3UserInterfaceHello(value: any): value is Fdc3UserInterface } } +export const FDC3_USER_INTERFACE_HELLO_TYPE = "Fdc3UserInterfaceHello"; + export function isFdc3UserInterfaceMessage(value: any): value is Fdc3UserInterfaceMessage { try { Convert.fdc3UserInterfaceMessageToJson(value); @@ -6155,6 +6219,8 @@ export function isFdc3UserInterfaceMessage(value: any): value is Fdc3UserInterfa } } +export const FDC3_USER_INTERFACE_MESSAGE_TYPE = "Fdc3UserInterfaceMessage"; + export function isFdc3UserInterfaceResolve(value: any): value is Fdc3UserInterfaceResolve { try { Convert.fdc3UserInterfaceResolveToJson(value); @@ -6164,6 +6230,8 @@ export function isFdc3UserInterfaceResolve(value: any): value is Fdc3UserInterfa } } +export const FDC3_USER_INTERFACE_RESOLVE_TYPE = "Fdc3UserInterfaceResolve"; + export function isFdc3UserInterfaceResolveAction(value: any): value is Fdc3UserInterfaceResolveAction { try { Convert.fdc3UserInterfaceResolveActionToJson(value); @@ -6173,6 +6241,8 @@ export function isFdc3UserInterfaceResolveAction(value: any): value is Fdc3UserI } } +export const FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE = "Fdc3UserInterfaceResolveAction"; + export function isFdc3UserInterfaceRestyle(value: any): value is Fdc3UserInterfaceRestyle { try { Convert.fdc3UserInterfaceRestyleToJson(value); @@ -6182,6 +6252,8 @@ export function isFdc3UserInterfaceRestyle(value: any): value is Fdc3UserInterfa } } +export const FDC3_USER_INTERFACE_RESTYLE_TYPE = "Fdc3UserInterfaceRestyle"; + export function isFindInstancesRequest(value: any): value is FindInstancesRequest { try { Convert.findInstancesRequestToJson(value); @@ -6191,6 +6263,8 @@ export function isFindInstancesRequest(value: any): value is FindInstancesReques } } +export const FIND_INSTANCES_REQUEST_TYPE = "FindInstancesRequest"; + export function isFindInstancesResponse(value: any): value is FindInstancesResponse { try { Convert.findInstancesResponseToJson(value); @@ -6200,6 +6274,8 @@ export function isFindInstancesResponse(value: any): value is FindInstancesRespo } } +export const FIND_INSTANCES_RESPONSE_TYPE = "FindInstancesResponse"; + export function isFindIntentRequest(value: any): value is FindIntentRequest { try { Convert.findIntentRequestToJson(value); @@ -6209,6 +6285,8 @@ export function isFindIntentRequest(value: any): value is FindIntentRequest { } } +export const FIND_INTENT_REQUEST_TYPE = "FindIntentRequest"; + export function isFindIntentResponse(value: any): value is FindIntentResponse { try { Convert.findIntentResponseToJson(value); @@ -6218,6 +6296,8 @@ export function isFindIntentResponse(value: any): value is FindIntentResponse { } } +export const FIND_INTENT_RESPONSE_TYPE = "FindIntentResponse"; + export function isFindIntentsByContextRequest(value: any): value is FindIntentsByContextRequest { try { Convert.findIntentsByContextRequestToJson(value); @@ -6227,6 +6307,8 @@ export function isFindIntentsByContextRequest(value: any): value is FindIntentsB } } +export const FIND_INTENTS_BY_CONTEXT_REQUEST_TYPE = "FindIntentsByContextRequest"; + export function isFindIntentsByContextResponse(value: any): value is FindIntentsByContextResponse { try { Convert.findIntentsByContextResponseToJson(value); @@ -6236,6 +6318,8 @@ export function isFindIntentsByContextResponse(value: any): value is FindIntents } } +export const FIND_INTENTS_BY_CONTEXT_RESPONSE_TYPE = "FindIntentsByContextResponse"; + export function isGetAppMetadataRequest(value: any): value is GetAppMetadataRequest { try { Convert.getAppMetadataRequestToJson(value); @@ -6245,6 +6329,8 @@ export function isGetAppMetadataRequest(value: any): value is GetAppMetadataRequ } } +export const GET_APP_METADATA_REQUEST_TYPE = "GetAppMetadataRequest"; + export function isGetAppMetadataResponse(value: any): value is GetAppMetadataResponse { try { Convert.getAppMetadataResponseToJson(value); @@ -6254,6 +6340,8 @@ export function isGetAppMetadataResponse(value: any): value is GetAppMetadataRes } } +export const GET_APP_METADATA_RESPONSE_TYPE = "GetAppMetadataResponse"; + export function isGetCurrentChannelRequest(value: any): value is GetCurrentChannelRequest { try { Convert.getCurrentChannelRequestToJson(value); @@ -6263,6 +6351,8 @@ export function isGetCurrentChannelRequest(value: any): value is GetCurrentChann } } +export const GET_CURRENT_CHANNEL_REQUEST_TYPE = "GetCurrentChannelRequest"; + export function isGetCurrentChannelResponse(value: any): value is GetCurrentChannelResponse { try { Convert.getCurrentChannelResponseToJson(value); @@ -6272,6 +6362,8 @@ export function isGetCurrentChannelResponse(value: any): value is GetCurrentChan } } +export const GET_CURRENT_CHANNEL_RESPONSE_TYPE = "GetCurrentChannelResponse"; + export function isGetCurrentContextRequest(value: any): value is GetCurrentContextRequest { try { Convert.getCurrentContextRequestToJson(value); @@ -6281,6 +6373,8 @@ export function isGetCurrentContextRequest(value: any): value is GetCurrentConte } } +export const GET_CURRENT_CONTEXT_REQUEST_TYPE = "GetCurrentContextRequest"; + export function isGetCurrentContextResponse(value: any): value is GetCurrentContextResponse { try { Convert.getCurrentContextResponseToJson(value); @@ -6290,6 +6384,8 @@ export function isGetCurrentContextResponse(value: any): value is GetCurrentCont } } +export const GET_CURRENT_CONTEXT_RESPONSE_TYPE = "GetCurrentContextResponse"; + export function isGetInfoRequest(value: any): value is GetInfoRequest { try { Convert.getInfoRequestToJson(value); @@ -6299,6 +6395,8 @@ export function isGetInfoRequest(value: any): value is GetInfoRequest { } } +export const GET_INFO_REQUEST_TYPE = "GetInfoRequest"; + export function isGetInfoResponse(value: any): value is GetInfoResponse { try { Convert.getInfoResponseToJson(value); @@ -6308,6 +6406,8 @@ export function isGetInfoResponse(value: any): value is GetInfoResponse { } } +export const GET_INFO_RESPONSE_TYPE = "GetInfoResponse"; + export function isGetOrCreateChannelRequest(value: any): value is GetOrCreateChannelRequest { try { Convert.getOrCreateChannelRequestToJson(value); @@ -6317,6 +6417,8 @@ export function isGetOrCreateChannelRequest(value: any): value is GetOrCreateCha } } +export const GET_OR_CREATE_CHANNEL_REQUEST_TYPE = "GetOrCreateChannelRequest"; + export function isGetOrCreateChannelResponse(value: any): value is GetOrCreateChannelResponse { try { Convert.getOrCreateChannelResponseToJson(value); @@ -6326,6 +6428,8 @@ export function isGetOrCreateChannelResponse(value: any): value is GetOrCreateCh } } +export const GET_OR_CREATE_CHANNEL_RESPONSE_TYPE = "GetOrCreateChannelResponse"; + export function isGetUserChannelsRequest(value: any): value is GetUserChannelsRequest { try { Convert.getUserChannelsRequestToJson(value); @@ -6335,6 +6439,8 @@ export function isGetUserChannelsRequest(value: any): value is GetUserChannelsRe } } +export const GET_USER_CHANNELS_REQUEST_TYPE = "GetUserChannelsRequest"; + export function isGetUserChannelsResponse(value: any): value is GetUserChannelsResponse { try { Convert.getUserChannelsResponseToJson(value); @@ -6344,6 +6450,8 @@ export function isGetUserChannelsResponse(value: any): value is GetUserChannelsR } } +export const GET_USER_CHANNELS_RESPONSE_TYPE = "GetUserChannelsResponse"; + export function isHeartbeatAcknowledgementRequest(value: any): value is HeartbeatAcknowledgementRequest { try { Convert.heartbeatAcknowledgementRequestToJson(value); @@ -6353,6 +6461,8 @@ export function isHeartbeatAcknowledgementRequest(value: any): value is Heartbea } } +export const HEARTBEAT_ACKNOWLEDGEMENT_REQUEST_TYPE = "HeartbeatAcknowledgementRequest"; + export function isHeartbeatEvent(value: any): value is HeartbeatEvent { try { Convert.heartbeatEventToJson(value); @@ -6362,6 +6472,8 @@ export function isHeartbeatEvent(value: any): value is HeartbeatEvent { } } +export const HEARTBEAT_EVENT_TYPE = "HeartbeatEvent"; + export function isIntentEvent(value: any): value is IntentEvent { try { Convert.intentEventToJson(value); @@ -6371,6 +6483,8 @@ export function isIntentEvent(value: any): value is IntentEvent { } } +export const INTENT_EVENT_TYPE = "IntentEvent"; + export function isIntentListenerUnsubscribeRequest(value: any): value is IntentListenerUnsubscribeRequest { try { Convert.intentListenerUnsubscribeRequestToJson(value); @@ -6380,6 +6494,8 @@ export function isIntentListenerUnsubscribeRequest(value: any): value is IntentL } } +export const INTENT_LISTENER_UNSUBSCRIBE_REQUEST_TYPE = "IntentListenerUnsubscribeRequest"; + export function isIntentListenerUnsubscribeResponse(value: any): value is IntentListenerUnsubscribeResponse { try { Convert.intentListenerUnsubscribeResponseToJson(value); @@ -6389,6 +6505,8 @@ export function isIntentListenerUnsubscribeResponse(value: any): value is Intent } } +export const INTENT_LISTENER_UNSUBSCRIBE_RESPONSE_TYPE = "IntentListenerUnsubscribeResponse"; + export function isIntentResultRequest(value: any): value is IntentResultRequest { try { Convert.intentResultRequestToJson(value); @@ -6398,6 +6516,8 @@ export function isIntentResultRequest(value: any): value is IntentResultRequest } } +export const INTENT_RESULT_REQUEST_TYPE = "IntentResultRequest"; + export function isIntentResultResponse(value: any): value is IntentResultResponse { try { Convert.intentResultResponseToJson(value); @@ -6407,6 +6527,8 @@ export function isIntentResultResponse(value: any): value is IntentResultRespons } } +export const INTENT_RESULT_RESPONSE_TYPE = "IntentResultResponse"; + export function isJoinUserChannelRequest(value: any): value is JoinUserChannelRequest { try { Convert.joinUserChannelRequestToJson(value); @@ -6416,6 +6538,8 @@ export function isJoinUserChannelRequest(value: any): value is JoinUserChannelRe } } +export const JOIN_USER_CHANNEL_REQUEST_TYPE = "JoinUserChannelRequest"; + export function isJoinUserChannelResponse(value: any): value is JoinUserChannelResponse { try { Convert.joinUserChannelResponseToJson(value); @@ -6425,6 +6549,8 @@ export function isJoinUserChannelResponse(value: any): value is JoinUserChannelR } } +export const JOIN_USER_CHANNEL_RESPONSE_TYPE = "JoinUserChannelResponse"; + export function isLeaveCurrentChannelRequest(value: any): value is LeaveCurrentChannelRequest { try { Convert.leaveCurrentChannelRequestToJson(value); @@ -6434,6 +6560,8 @@ export function isLeaveCurrentChannelRequest(value: any): value is LeaveCurrentC } } +export const LEAVE_CURRENT_CHANNEL_REQUEST_TYPE = "LeaveCurrentChannelRequest"; + export function isLeaveCurrentChannelResponse(value: any): value is LeaveCurrentChannelResponse { try { Convert.leaveCurrentChannelResponseToJson(value); @@ -6443,6 +6571,8 @@ export function isLeaveCurrentChannelResponse(value: any): value is LeaveCurrent } } +export const LEAVE_CURRENT_CHANNEL_RESPONSE_TYPE = "LeaveCurrentChannelResponse"; + export function isOpenRequest(value: any): value is OpenRequest { try { Convert.openRequestToJson(value); @@ -6452,6 +6582,8 @@ export function isOpenRequest(value: any): value is OpenRequest { } } +export const OPEN_REQUEST_TYPE = "OpenRequest"; + export function isOpenResponse(value: any): value is OpenResponse { try { Convert.openResponseToJson(value); @@ -6461,6 +6593,8 @@ export function isOpenResponse(value: any): value is OpenResponse { } } +export const OPEN_RESPONSE_TYPE = "OpenResponse"; + export function isPrivateChannelAddEventListenerRequest(value: any): value is PrivateChannelAddEventListenerRequest { try { Convert.privateChannelAddEventListenerRequestToJson(value); @@ -6470,6 +6604,8 @@ export function isPrivateChannelAddEventListenerRequest(value: any): value is Pr } } +export const PRIVATE_CHANNEL_ADD_EVENT_LISTENER_REQUEST_TYPE = "PrivateChannelAddEventListenerRequest"; + export function isPrivateChannelAddEventListenerResponse(value: any): value is PrivateChannelAddEventListenerResponse { try { Convert.privateChannelAddEventListenerResponseToJson(value); @@ -6479,6 +6615,8 @@ export function isPrivateChannelAddEventListenerResponse(value: any): value is P } } +export const PRIVATE_CHANNEL_ADD_EVENT_LISTENER_RESPONSE_TYPE = "PrivateChannelAddEventListenerResponse"; + export function isPrivateChannelDisconnectRequest(value: any): value is PrivateChannelDisconnectRequest { try { Convert.privateChannelDisconnectRequestToJson(value); @@ -6488,6 +6626,8 @@ export function isPrivateChannelDisconnectRequest(value: any): value is PrivateC } } +export const PRIVATE_CHANNEL_DISCONNECT_REQUEST_TYPE = "PrivateChannelDisconnectRequest"; + export function isPrivateChannelDisconnectResponse(value: any): value is PrivateChannelDisconnectResponse { try { Convert.privateChannelDisconnectResponseToJson(value); @@ -6497,6 +6637,8 @@ export function isPrivateChannelDisconnectResponse(value: any): value is Private } } +export const PRIVATE_CHANNEL_DISCONNECT_RESPONSE_TYPE = "PrivateChannelDisconnectResponse"; + export function isPrivateChannelOnAddContextListenerEvent(value: any): value is PrivateChannelOnAddContextListenerEvent { try { Convert.privateChannelOnAddContextListenerEventToJson(value); @@ -6506,6 +6648,8 @@ export function isPrivateChannelOnAddContextListenerEvent(value: any): value is } } +export const PRIVATE_CHANNEL_ON_ADD_CONTEXT_LISTENER_EVENT_TYPE = "PrivateChannelOnAddContextListenerEvent"; + export function isPrivateChannelOnDisconnectEvent(value: any): value is PrivateChannelOnDisconnectEvent { try { Convert.privateChannelOnDisconnectEventToJson(value); @@ -6515,6 +6659,8 @@ export function isPrivateChannelOnDisconnectEvent(value: any): value is PrivateC } } +export const PRIVATE_CHANNEL_ON_DISCONNECT_EVENT_TYPE = "PrivateChannelOnDisconnectEvent"; + export function isPrivateChannelOnUnsubscribeEvent(value: any): value is PrivateChannelOnUnsubscribeEvent { try { Convert.privateChannelOnUnsubscribeEventToJson(value); @@ -6524,6 +6670,8 @@ export function isPrivateChannelOnUnsubscribeEvent(value: any): value is Private } } +export const PRIVATE_CHANNEL_ON_UNSUBSCRIBE_EVENT_TYPE = "PrivateChannelOnUnsubscribeEvent"; + export function isPrivateChannelUnsubscribeEventListenerRequest(value: any): value is PrivateChannelUnsubscribeEventListenerRequest { try { Convert.privateChannelUnsubscribeEventListenerRequestToJson(value); @@ -6533,6 +6681,8 @@ export function isPrivateChannelUnsubscribeEventListenerRequest(value: any): val } } +export const PRIVATE_CHANNEL_UNSUBSCRIBE_EVENT_LISTENER_REQUEST_TYPE = "PrivateChannelUnsubscribeEventListenerRequest"; + export function isPrivateChannelUnsubscribeEventListenerResponse(value: any): value is PrivateChannelUnsubscribeEventListenerResponse { try { Convert.privateChannelUnsubscribeEventListenerResponseToJson(value); @@ -6542,6 +6692,8 @@ export function isPrivateChannelUnsubscribeEventListenerResponse(value: any): va } } +export const PRIVATE_CHANNEL_UNSUBSCRIBE_EVENT_LISTENER_RESPONSE_TYPE = "PrivateChannelUnsubscribeEventListenerResponse"; + export function isRaiseIntentForContextRequest(value: any): value is RaiseIntentForContextRequest { try { Convert.raiseIntentForContextRequestToJson(value); @@ -6551,6 +6703,8 @@ export function isRaiseIntentForContextRequest(value: any): value is RaiseIntent } } +export const RAISE_INTENT_FOR_CONTEXT_REQUEST_TYPE = "RaiseIntentForContextRequest"; + export function isRaiseIntentForContextResponse(value: any): value is RaiseIntentForContextResponse { try { Convert.raiseIntentForContextResponseToJson(value); @@ -6560,6 +6714,8 @@ export function isRaiseIntentForContextResponse(value: any): value is RaiseInten } } +export const RAISE_INTENT_FOR_CONTEXT_RESPONSE_TYPE = "RaiseIntentForContextResponse"; + export function isRaiseIntentRequest(value: any): value is RaiseIntentRequest { try { Convert.raiseIntentRequestToJson(value); @@ -6569,6 +6725,8 @@ export function isRaiseIntentRequest(value: any): value is RaiseIntentRequest { } } +export const RAISE_INTENT_REQUEST_TYPE = "RaiseIntentRequest"; + export function isRaiseIntentResponse(value: any): value is RaiseIntentResponse { try { Convert.raiseIntentResponseToJson(value); @@ -6578,6 +6736,8 @@ export function isRaiseIntentResponse(value: any): value is RaiseIntentResponse } } +export const RAISE_INTENT_RESPONSE_TYPE = "RaiseIntentResponse"; + export function isRaiseIntentResultResponse(value: any): value is RaiseIntentResultResponse { try { Convert.raiseIntentResultResponseToJson(value); @@ -6587,8 +6747,91 @@ export function isRaiseIntentResultResponse(value: any): value is RaiseIntentRes } } +export const RAISE_INTENT_RESULT_RESPONSE_TYPE = "RaiseIntentResultResponse"; + export type RequestMessage = AddContextListenerRequest | AddEventListenerRequest | AddIntentListenerRequest | BroadcastRequest | ContextListenerUnsubscribeRequest | CreatePrivateChannelRequest | EventListenerUnsubscribeRequest | FindInstancesRequest | FindIntentRequest | FindIntentsByContextRequest | GetAppMetadataRequest | GetCurrentChannelRequest | GetCurrentContextRequest | GetInfoRequest | GetOrCreateChannelRequest | GetUserChannelsRequest | HeartbeatAcknowledgementRequest | IntentListenerUnsubscribeRequest | IntentResultRequest | JoinUserChannelRequest | LeaveCurrentChannelRequest | OpenRequest | PrivateChannelAddEventListenerRequest | PrivateChannelDisconnectRequest | PrivateChannelUnsubscribeEventListenerRequest | RaiseIntentForContextRequest | RaiseIntentRequest; export type ResponseMessage = WebConnectionProtocol5ValidateAppIdentityFailedResponse | WebConnectionProtocol5ValidateAppIdentitySuccessResponse | AddContextListenerResponse | AddEventListenerResponse | AddIntentListenerResponse | BroadcastResponse | ContextListenerUnsubscribeResponse | CreatePrivateChannelResponse | EventListenerUnsubscribeResponse | FindInstancesResponse | FindIntentResponse | FindIntentsByContextResponse | GetAppMetadataResponse | GetCurrentChannelResponse | GetCurrentContextResponse | GetInfoResponse | GetOrCreateChannelResponse | GetUserChannelsResponse | IntentListenerUnsubscribeResponse | IntentResultResponse | JoinUserChannelResponse | LeaveCurrentChannelResponse | OpenResponse | PrivateChannelAddEventListenerResponse | PrivateChannelDisconnectResponse | PrivateChannelUnsubscribeEventListenerResponse | RaiseIntentForContextResponse | RaiseIntentResponse | RaiseIntentResultResponse; export type EventMessage = BroadcastEvent | ChannelChangedEvent | HeartbeatEvent | IntentEvent | PrivateChannelOnAddContextListenerEvent | PrivateChannelOnDisconnectEvent | PrivateChannelOnUnsubscribeEvent; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts b/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts index 8f355e528..7446046d1 100644 --- a/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts +++ b/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts @@ -1,4 +1,5 @@ import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE, FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type IframeChannels = BrowserTypes.Fdc3UserInterfaceChannels type IframeRestyle = BrowserTypes.Fdc3UserInterfaceRestyle @@ -10,7 +11,7 @@ var channelId: string | null = null const DEFAULT_COLLAPSED_CSS = { position: "fixed", - zIndex: 1000, + zIndex: "1000", right: "10px", bottom: "10px", width: "50px", @@ -19,11 +20,11 @@ const DEFAULT_COLLAPSED_CSS = { const DEFAULT_EXPANDED_CSS = { position: "fixed", - 'z-index': 1000, + zIndex: "1000", right: "10px", bottom: "10px", width: "450px", - 'max-height': "600px", + maxHeight: "600px", transition: "all 0.5s ease-out allow-discrete" } @@ -40,7 +41,7 @@ window.addEventListener("load", () => { parent.postMessage({ - type: "fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: DEFAULT_COLLAPSED_CSS, implementationDetails: "Demo Channel Selector v1.0" @@ -49,15 +50,15 @@ window.addEventListener("load", () => { function changeSize(expanded: boolean) { document.body.setAttribute("data-expanded", "" + expanded); - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: expanded ? DEFAULT_EXPANDED_CSS : DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: expanded ? DEFAULT_EXPANDED_CSS : DEFAULT_COLLAPSED_CSS } } as IframeRestyle) } myPort.addEventListener("message", (e) => { console.log(e.data.type) - if (e.data.type == 'iframeHandshake') { + if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { // ok, port is ready, send the iframe position detials - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) - } else if (e.data.type == 'fdc3UserInterfaceChannels') { + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + } else if (e.data.type == FDC3_USER_INTERFACE_CHANNELS_TYPE) { const details = e.data as IframeChannels console.log(JSON.stringify("CHANNEL DETAILS: " + JSON.stringify(details))) channels = details.payload.userChannels @@ -86,7 +87,7 @@ window.addEventListener("load", () => { a.onclick = () => { changeSize(false) channelId = channel.id - myPort.postMessage({ type: "fdc3UserInterfaceSelected", payload: { selected: channel.id } }) + myPort.postMessage({ type: FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, payload: { selected: channel.id } }) } }) diff --git a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts index d78df4957..80662280c 100644 --- a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts +++ b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts @@ -1,5 +1,6 @@ import { AppIdentifier } from "@kite9/fdc3-standard"; import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type IframeResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction type IframeResolvePayload = BrowserTypes.Fdc3UserInterfaceResolvePayload @@ -8,7 +9,7 @@ type IframeHello = BrowserTypes.Fdc3UserInterfaceHello const DEFAULT_COLLAPSED_CSS = { position: "fixed", - zIndex: 1000, + zIndex: "1000", right: "0", bottom: "0", width: "0", @@ -17,7 +18,7 @@ const DEFAULT_COLLAPSED_CSS = { const DEFAULT_EXPANDED_CSS = { position: "fixed", - 'z-index': 1000, + zIndex: "1000", left: "10%", top: "10%", right: "10%", @@ -34,7 +35,7 @@ window.addEventListener("load", () => { const list = document.getElementById("intent-list")!! parent.postMessage({ - type: "fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: DEFAULT_COLLAPSED_CSS, implementationDetails: "Demo Intent Resolver v1.0" @@ -42,11 +43,11 @@ window.addEventListener("load", () => { } as any as IframeHello, "*", [mc.port2]); function callback(intent: string | null, app: AppIdentifier | null) { - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) if (intent && app) { myPort.postMessage({ - type: "Fdc3UserInterfaceResolveAction", + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: "click", appIdentifier: app, @@ -55,7 +56,7 @@ window.addEventListener("load", () => { } as IframeResolveAction) } else { myPort.postMessage({ - type: "Fdc3UserInterfaceResolveAction", + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: "cancel" } @@ -65,9 +66,9 @@ window.addEventListener("load", () => { myPort.addEventListener("message", (e) => { if (e.data.type == 'iframeHandshake') { - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) } else if (e.data.type == 'iframeResolve') { - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_EXPANDED_CSS } } as IframeRestyle) + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_EXPANDED_CSS } } as IframeRestyle) Array.from(list.children).forEach(i => i.remove()) const details = e.data.payload as IframeResolvePayload details.appIntents.forEach(intent => { diff --git a/toolbox/fdc3-for-web/reference-ui/package.json b/toolbox/fdc3-for-web/reference-ui/package.json index 047b932a6..cc1f0cbb3 100644 --- a/toolbox/fdc3-for-web/reference-ui/package.json +++ b/toolbox/fdc3-for-web/reference-ui/package.json @@ -14,6 +14,6 @@ "vite": "^5.2.0" }, "dependencies": { - "@kite9/fdc3-common": "2.2.0-beta.6" + "@kite9/fdc3": "2.2.0-beta.29" } } \ No newline at end of file diff --git a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts index fa130c657..7f1fbbb9e 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts @@ -1,5 +1,5 @@ import { IframeChannelsPayload, Channel } from "@kite9/fdc3-common"; -import { Fdc3UserInterfaceHello, Fdc3UserInterfaceRestyle } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, Fdc3UserInterfaceHello, Fdc3UserInterfaceRestyle, isFdc3UserInterfaceChannels, isFdc3UserInterfaceHandshake } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; const fillChannels = (data: Channel[], selected: string | null, messageClickedChannel: (s: string | null) => void) => { const list = document.getElementById('list')!!; @@ -47,33 +47,29 @@ window.addEventListener("load", () => { myPort.start(); myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); - switch (data.type) { - case "Fdc3UserInterfaceHandshake ": { - collapse(); - break; - } - case "Fdc3UserInterfaceChannels": { - logo.removeEventListener("click", expand); - const { userChannels, selected } = data.payload as IframeChannelsPayload; - fillChannels(userChannels, selected, (channelStr) => { - myPort.postMessage({ - type: "Fdc3UserInterfaceSelected", - payload: { - selected: channelStr || null - } - }); - collapse(); + + if (isFdc3UserInterfaceHandshake(data)) { + collapse(); + } else if (isFdc3UserInterfaceChannels(data)) { + logo.removeEventListener("click", expand); + const { userChannels, selected } = data.payload as IframeChannelsPayload; + fillChannels(userChannels, selected, (channelStr) => { + myPort.postMessage({ + type: FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, + payload: { + selected: channelStr || null + } }); - const selectedChannel = userChannels.find((c) => c.id === selected); - logo.style.fill = selectedChannel?.displayMetadata?.color ?? "white"; - logo.addEventListener("click", expand); - break; - } + collapse(); + }); + const selectedChannel = userChannels.find((c) => c.id === selected); + logo.style.fill = selectedChannel?.displayMetadata?.color ?? "white"; + logo.addEventListener("click", expand); } }; const helloMessage: Fdc3UserInterfaceHello = { - type: "Fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { implementationDetails: "", initialCSS: { @@ -93,7 +89,7 @@ window.addEventListener("load", () => { const expand = () => { document.body.setAttribute("data-expanded", "true"); const restyleMessage: Fdc3UserInterfaceRestyle = { - type: "Fdc3UserInterfaceRestyle", + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: { width: `100%`, @@ -111,7 +107,7 @@ window.addEventListener("load", () => { const collapse = () => { const restyleMessage: Fdc3UserInterfaceRestyle = { - type: "Fdc3UserInterfaceRestyle", + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: { width: `${8 * 4}px`, diff --git a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts index e8c4590b0..a19b59924 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts @@ -1,6 +1,7 @@ import { Icon } from "@kite9/fdc3"; import { AppIntent } from "@kite9/fdc3"; import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, isFdc3UserInterfaceResolve } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; type Fdc3UserInterfaceHello = BrowserTypes.Fdc3UserInterfaceHello; type Fdc3UserInterfaceRestyle = BrowserTypes.Fdc3UserInterfaceRestyle; @@ -14,7 +15,7 @@ const setup = (data: Fdc3UserInterfaceResolve["payload"], callback: (payload: Fd const intentSelect = document.getElementById("displayIntent") as HTMLSelectElement - const justIntents = data.appIntents.map(({intent}) => intent) + const justIntents = data.appIntents.map(({ intent }) => intent) const doneIntents = new Set() justIntents.forEach(({ name, displayName }) => { @@ -162,54 +163,50 @@ window.addEventListener("load", () => { const mc = new MessageChannel(); const myPort = mc.port1; myPort.start(); - myPort.onmessage = ({data}) => { + myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); - switch(data.type){ - case "Fdc3UserInterfaceHandshake": { - break; + if (isFdc3UserInterfaceResolve(data)) { + const restyleMessage: Fdc3UserInterfaceRestyle = { + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, + payload: { + updatedCSS: { + width: "100%", + height: "100%", + top: "0", + left: "0", + position: "fixed" + } + } } - case "Fdc3UserInterfaceResolve": { + myPort.postMessage(restyleMessage); + + setup(data.payload, (payload) => { + document.querySelector("dialog")?.close(); + const resolveAction: Fdc3UserInterfaceResolveAction = { + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, + payload + } + myPort.postMessage(resolveAction); + const restyleMessage: Fdc3UserInterfaceRestyle = { - type: "Fdc3UserInterfaceRestyle", + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: { - width: "100%", - height: "100%", - top: "0", - left: "0", - position: "fixed" + width: "0", + height: "0" } } } - myPort.postMessage(restyleMessage); - - setup(data.payload, (payload) => { - document.querySelector("dialog")?.close(); - const resolveAction: Fdc3UserInterfaceResolveAction = { - type: "Fdc3UserInterfaceResolveAction", - payload - } - myPort.postMessage(resolveAction); - - const restyleMessage: Fdc3UserInterfaceRestyle = { - type: "Fdc3UserInterfaceRestyle", - payload: { - updatedCSS: { - width: "0", - height: "0" - } - } - } - myPort.postMessage(restyleMessage); + myPort.postMessage(restyleMessage); - }) - } + }) } + }; const helloMessage: Fdc3UserInterfaceHello = { - type: "Fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { implementationDetails: "", initialCSS: { diff --git a/toolbox/fdc3-for-web/reference-ui/src/main.ts b/toolbox/fdc3-for-web/reference-ui/src/main.ts deleted file mode 100644 index 88d2d4cb6..000000000 --- a/toolbox/fdc3-for-web/reference-ui/src/main.ts +++ /dev/null @@ -1,197 +0,0 @@ -import "./style.css"; - -// Channel data -const recommendedChannels = [ - { - id: 'fdc3.channel.1', - type: 'user', - displayMetadata: { - name: 'Channel 1', - color: 'red', - glyph: '1', - }, - }, - { - id: 'fdc3.channel.2', - type: 'user', - displayMetadata: { - name: 'Channel 2', - color: 'orange', - glyph: '2', - }, - }, - { - id: 'fdc3.channel.3', - type: 'user', - displayMetadata: { - name: 'Channel 3', - color: 'yellow', - glyph: '3', - }, - }, - { - id: 'fdc3.channel.4', - type: 'user', - displayMetadata: { - name: 'Channel 4', - color: 'green', - glyph: '4', - }, - }, - { - id: 'fdc3.channel.5', - type: 'user', - displayMetadata: { - name: 'Channel 5', - color: 'cyan', - glyph: '5', - }, - }, - { - id: 'fdc3.channel.6', - type: 'user', - displayMetadata: { - name: 'Channel 6', - color: 'blue', - glyph: '6', - }, - }, - { - id: 'fdc3.channel.7', - type: 'user', - displayMetadata: { - name: 'Channel 7', - color: 'magenta', - glyph: '7', - }, - }, - { - id: 'fdc3.channel.8', - type: 'user', - displayMetadata: { - name: 'Channel 8', - color: 'purple', - glyph: '8', - }, - }, -]; - -// Example resolver data -const exampleResolverData = { - type: "ResolverIntents", - appIntents: [ - { - apps: [{ - appId: "trading-view-chart", - description: "TradingView is a social network for traders and investors on Stock, Futures and Forex markets!", - icons: [{ - src: "https://apps.connectifi-interop.com/tradingviewChart/icon.png" - }], - title: "TradingView Chart" - }, { - appId: "adaptabledemo", - instanceId: "324587329238y7r59824", - description: "AdapTable is a powerful data grid with a range of advanced features", - icons: [{ - src: "https://apps.connectifi-interop.com/adaptableDemo/icon.png" - }], - title: "AdapTable" - }], - intent: { - name: "ViewInstrument", - displayName: "View Instrument" - }, - }], - source: { - appId: "fdc3-demo", - instanceId: "fdc3-demo-instance" - } -}; - -let selected = recommendedChannels[2].id; -let expanded = true; - -const openChannelIframe = (e: MouseEvent) => { - const channel = new MessageChannel(); - - // STEP 2B: Receive confirmation over port from iframe - channel.port1.onmessage = ({ data }) => { - switch (data.type) { - - // User clicked on one of the channels in the channel selector - // @ts-ignore: Explicit fall-through to Fdc3UserInterfaceHandshake - case "Fdc3UserInterfaceChannelSelected": { - // STEP 4B: Receive user selection information from iframe - selected = data.channel; - } - - // Handshake completed. Send channel data to iframe - case "Fdc3UserInterfaceHandshake": { - // STEP 3A: Send channel data to iframe - channel.port1.postMessage({ - type: "Fdc3UserInterfaceChannels", - channels: recommendedChannels, - selected - }); - break; - } - - } - - }; - - const {target} = e; - if(target) (target as HTMLButtonElement).disabled = true; - - const iframe = document.querySelector("#channel-iframe")!; - iframe.parentElement?.setAttribute("data-visible", "true"); - - const resizeButton = document.getElementById("dimensions-btn-channel")!; - resizeButton.setAttribute("data-visible", "true"); - resizeButton.addEventListener("click", () => { - expanded = !expanded; - channel.port1.postMessage({ type: "Fdc3UserInterfaceChannelResize", expanded }) - iframe.setAttribute("data-expanded", `${expanded}`); - resizeButton.textContent = expanded ? "Collapse" : "Expand"; - }); - - // STEP 1A: Send port to iframe - iframe.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); -}; - -const openResolverIframe = (e: MouseEvent )=> { - const channel = new MessageChannel(); - - // STEP 2B: Receive confirmation over port from iframe - channel.port1.onmessage = ({ data }) => { - switch (data.type) { - case "Fdc3UserInterfaceHandshake": { - // STEP 3A: Send channel data to iframe - channel.port1.postMessage(exampleResolverData); - break; - } - case "Fdc3UserInterfaceResolveAction": - case "Fdc3UserInterfaceResolve": { - // STEP 4B: Receive user selection information from iframe - - // TODO - prettyPrintJson dependency is not referenced, re-enable when added - // document.getElementById('resolver-user-selection')!.innerHTML = prettyPrintJson.toHtml(data); - break; - } - } - - }; - const {target} = e; - if(target) (target as HTMLButtonElement).disabled = true; - - const iframe = document.querySelector("#resolver-iframe"); - iframe!.parentElement?.setAttribute("data-visible", "true"); - - // STEP 1A: Send port to iframe - iframe!.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); -}; - -window.addEventListener('load', () => { - document.getElementById('send-btn-channel')!.addEventListener('click', openChannelIframe); - document.getElementById('send-btn-resolver')!.addEventListener('click', openResolverIframe); -}); From 84bab84e7c7837ca5e242ec20cb29d6a5137b006 Mon Sep 17 00:00:00 2001 From: Rob Moffat Date: Thu, 14 Nov 2024 15:12:49 +0000 Subject: [PATCH 10/12] Renumbered ports for consistency, added in UI choice again --- .../demo/src/client/da/dummy-desktop-agent.ts | 23 +- .../fdc3-for-web/demo/src/client/da/embed.ts | 11 +- .../demo/src/client/ui/intent-resolver.ts | 6 +- toolbox/fdc3-for-web/demo/src/server/main.ts | 4 +- toolbox/fdc3-for-web/demo/static/da/appd.json | 14 +- toolbox/fdc3-for-web/reference-ui/src/main.ts | 198 ++++++++++++++++++ .../fdc3-for-web/reference-ui/vite.config.ts | 4 +- toolbox/fdc3-workbench/vite.config.ts | 2 +- 8 files changed, 240 insertions(+), 22 deletions(-) create mode 100644 toolbox/fdc3-for-web/reference-ui/src/main.ts diff --git a/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts b/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts index 8ece10b2b..7c2f372c8 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts @@ -36,9 +36,21 @@ function getApproach(): Approach { return out; } -enum UI { DEFAULT, DEMO } +export enum UI { DEFAULT, DEMO } + +export const UI_URLS = { + [UI.DEMO]: { + intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", + channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + }, + [UI.DEFAULT]: { + // TODO: REPLACE WITH FDC3.FINOS.ORG URLS AFTER GO-LIVE + intentResolverUrl: "http://localhost:4002/intent-resolver.html", + channelSelectorUrl: "http://localhost:4002/channel-selector.html", + } +} -function getUi(): UI { +function getUIKey(): UI { const cb = document.getElementById("ui") as HTMLInputElement; const val = cb.value var out: UI = UI[val as keyof typeof UI]; //Works with --noImplicitAny @@ -104,7 +116,7 @@ window.addEventListener("load", () => { timestamp: new Date() }, payload: { - iframeUrl: window.location.origin + `/static/da/embed.html?connectionAttemptUuid=${data.meta.connectionAttemptUuid}&desktopAgentId=${desktopAgentUUID}&instanceId=${instance?.instanceId}` + iframeUrl: window.location.origin + `/static/da/embed.html?connectionAttemptUuid=${data.meta.connectionAttemptUuid}&desktopAgentId=${desktopAgentUUID}&instanceId=${instance?.instanceId}&UI=${getUIKey()}` } } as WebConnectionProtocol2LoadURL, origin) } else { @@ -114,6 +126,8 @@ window.addEventListener("load", () => { socket.emit(APP_HELLO, desktopAgentUUID, instance.instanceId) + const ui = UI_URLS[getUIKey()] + // sned the other end of the channel to the app source.postMessage({ type: 'WCP3Handshake', @@ -123,8 +137,7 @@ window.addEventListener("load", () => { }, payload: { fdc3Version: "2.2", - intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", - channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + ...ui } }, origin, [channel.port1]) } diff --git a/toolbox/fdc3-for-web/demo/src/client/da/embed.ts b/toolbox/fdc3-for-web/demo/src/client/da/embed.ts index 19ae26ae6..86540a9b2 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/embed.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/embed.ts @@ -1,6 +1,7 @@ import { io } from "socket.io-client" import { link } from "./util"; import { APP_HELLO } from "../../message-types"; +import { UI, UI_URLS } from "./dummy-desktop-agent"; const appWindow = window.parent; @@ -33,6 +34,11 @@ function getDeskopAgentId(): string { return id } +function getUIKey(): UI { + const ui = getQueryVariable("UI") + return parseInt(ui) as UI +} + window.addEventListener("load", () => { @@ -47,6 +53,8 @@ window.addEventListener("load", () => { socket.emit(APP_HELLO, desktopAgentUUID, source) + const ui = UI_URLS[getUIKey()] + // sned the other end of the channel to the app appWindow.postMessage({ type: 'WCP3Handshake', @@ -56,8 +64,7 @@ window.addEventListener("load", () => { }, payload: { fdc3Version: "2.2", - intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", - channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + ...ui } }, "*", [channel.port1]) diff --git a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts index 80662280c..8fb1a58b5 100644 --- a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts +++ b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts @@ -1,6 +1,6 @@ import { AppIdentifier } from "@kite9/fdc3-standard"; import { BrowserTypes } from "@kite9/fdc3-schema"; -import { FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type IframeResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction type IframeResolvePayload = BrowserTypes.Fdc3UserInterfaceResolvePayload @@ -65,9 +65,9 @@ window.addEventListener("load", () => { } myPort.addEventListener("message", (e) => { - if (e.data.type == 'iframeHandshake') { + if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) - } else if (e.data.type == 'iframeResolve') { + } else if (e.data.type == FDC3_USER_INTERFACE_RESTYLE_TYPE) { myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_EXPANDED_CSS } } as IframeRestyle) Array.from(list.children).forEach(i => i.remove()) const details = e.data.payload as IframeResolvePayload diff --git a/toolbox/fdc3-for-web/demo/src/server/main.ts b/toolbox/fdc3-for-web/demo/src/server/main.ts index bc1fa6f05..fa0855d1c 100644 --- a/toolbox/fdc3-for-web/demo/src/server/main.ts +++ b/toolbox/fdc3-for-web/demo/src/server/main.ts @@ -10,8 +10,8 @@ app.get("/iframe", (_, res) => { }); -const httpServer = ViteExpress.listen(app, 8095, () => - console.log("Server is listening on port 8095..."), +const httpServer = ViteExpress.listen(app, 4000, () => + console.log("Server is listening on port 4000. Head to http://localhost:4000/static/da/index.html"), ); const io = new Server(httpServer) diff --git a/toolbox/fdc3-for-web/demo/static/da/appd.json b/toolbox/fdc3-for-web/demo/static/da/appd.json index 96fea5108..9219d0487 100644 --- a/toolbox/fdc3-for-web/demo/static/da/appd.json +++ b/toolbox/fdc3-for-web/demo/static/da/appd.json @@ -7,7 +7,7 @@ "description": "App will connect to the desktop agent and broadcast on the red channel when you hit the button", "type": "web", "details": { - "url": "http://localhost:8095/static/app1/index.html" + "url": "http://localhost:4000/static/app1/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -21,7 +21,7 @@ "description": "App will connect to the desktop agent on startup and listen to messages on the red channel", "type": "web", "details": { - "url": "http://localhost:8095/static/app2/index.html" + "url": "http://localhost:4000/static/app2/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -35,7 +35,7 @@ "description": "App creates two APIs to the desktop agent, broadcasts in one and listens in the other.", "type": "web", "details": { - "url": "http://localhost:8095/static/app3/index.html" + "url": "http://localhost:4000/static/app3/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -63,7 +63,7 @@ "description": "Listens for the ViewNews intent only", "type": "web", "details": { - "url": "http://localhost:8095/static/app4/index.html" + "url": "http://localhost:4000/static/app4/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -89,7 +89,7 @@ "description": "Listens for the ViewNews intent only", "type": "web", "details": { - "url": "http://localhost:8095/static/app5/index.html" + "url": "http://localhost:4000/static/app5/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -121,7 +121,7 @@ "description": "App asks for the result of a ViewQuote intent", "type": "web", "details": { - "url": "http://localhost:8095/static/app6/index.html" + "url": "http://localhost:4000/static/app6/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -135,7 +135,7 @@ "description": "App asks for the result of a ViewNews intent", "type": "web", "details": { - "url": "http://localhost:8095/static/app7/index.html" + "url": "http://localhost:4000/static/app7/index.html" }, "hostManifests": {}, "version": "1.0.0", diff --git a/toolbox/fdc3-for-web/reference-ui/src/main.ts b/toolbox/fdc3-for-web/reference-ui/src/main.ts new file mode 100644 index 000000000..eee97452c --- /dev/null +++ b/toolbox/fdc3-for-web/reference-ui/src/main.ts @@ -0,0 +1,198 @@ +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE, FDC3_USER_INTERFACE_HANDSHAKE_TYPE } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; +import "./style.css"; + +// Channel data +const recommendedChannels = [ + { + id: 'fdc3.channel.1', + type: 'user', + displayMetadata: { + name: 'Channel 1', + color: 'red', + glyph: '1', + }, + }, + { + id: 'fdc3.channel.2', + type: 'user', + displayMetadata: { + name: 'Channel 2', + color: 'orange', + glyph: '2', + }, + }, + { + id: 'fdc3.channel.3', + type: 'user', + displayMetadata: { + name: 'Channel 3', + color: 'yellow', + glyph: '3', + }, + }, + { + id: 'fdc3.channel.4', + type: 'user', + displayMetadata: { + name: 'Channel 4', + color: 'green', + glyph: '4', + }, + }, + { + id: 'fdc3.channel.5', + type: 'user', + displayMetadata: { + name: 'Channel 5', + color: 'cyan', + glyph: '5', + }, + }, + { + id: 'fdc3.channel.6', + type: 'user', + displayMetadata: { + name: 'Channel 6', + color: 'blue', + glyph: '6', + }, + }, + { + id: 'fdc3.channel.7', + type: 'user', + displayMetadata: { + name: 'Channel 7', + color: 'magenta', + glyph: '7', + }, + }, + { + id: 'fdc3.channel.8', + type: 'user', + displayMetadata: { + name: 'Channel 8', + color: 'purple', + glyph: '8', + }, + }, +]; + +// Example resolver data +const exampleResolverData = { + type: "ResolverIntents", + appIntents: [ + { + apps: [{ + appId: "trading-view-chart", + description: "TradingView is a social network for traders and investors on Stock, Futures and Forex markets!", + icons: [{ + src: "https://apps.connectifi-interop.com/tradingviewChart/icon.png" + }], + title: "TradingView Chart" + }, { + appId: "adaptabledemo", + instanceId: "324587329238y7r59824", + description: "AdapTable is a powerful data grid with a range of advanced features", + icons: [{ + src: "https://apps.connectifi-interop.com/adaptableDemo/icon.png" + }], + title: "AdapTable" + }], + intent: { + name: "ViewInstrument", + displayName: "View Instrument" + }, + }], + source: { + appId: "fdc3-demo", + instanceId: "fdc3-demo-instance" + } +}; + +let selected = recommendedChannels[2].id; +let expanded = true; + +const openChannelIframe = (e: MouseEvent) => { + const channel = new MessageChannel(); + + // STEP 2B: Receive confirmation over port from iframe + channel.port1.onmessage = ({ data }) => { + switch (data.type) { + + // User clicked on one of the channels in the channel selector + // @ts-ignore: Explicit fall-through to Fdc3UserInterfaceHandshake + case FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE: { + // STEP 4B: Receive user selection information from iframe + selected = data.channel; + } + + // Handshake completed. Send channel data to iframe + case FDC3_USER_INTERFACE_HANDSHAKE_TYPE: { + // STEP 3A: Send channel data to iframe + channel.port1.postMessage({ + type: FDC3_USER_INTERFACE_CHANNELS_TYPE, + channels: recommendedChannels, + selected + }); + break; + } + + } + + }; + + const { target } = e; + if (target) (target as HTMLButtonElement).disabled = true; + + const iframe = document.querySelector("#channel-iframe")!; + iframe.parentElement?.setAttribute("data-visible", "true"); + + const resizeButton = document.getElementById("dimensions-btn-channel")!; + resizeButton.setAttribute("data-visible", "true"); + resizeButton.addEventListener("click", () => { + expanded = !expanded; + channel.port1.postMessage({ type: "Fdc3UserInterfaceChannelResize", expanded }) + iframe.setAttribute("data-expanded", `${expanded}`); + resizeButton.textContent = expanded ? "Collapse" : "Expand"; + }); + + // STEP 1A: Send port to iframe + iframe.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); +}; + +const openResolverIframe = (e: MouseEvent) => { + const channel = new MessageChannel(); + + // STEP 2B: Receive confirmation over port from iframe + channel.port1.onmessage = ({ data }) => { + switch (data.type) { + case "Fdc3UserInterfaceHandshake": { + // STEP 3A: Send channel data to iframe + channel.port1.postMessage(exampleResolverData); + break; + } + case "Fdc3UserInterfaceResolveAction": + case "Fdc3UserInterfaceResolve": { + // STEP 4B: Receive user selection information from iframe + + // TODO - prettyPrintJson dependency is not referenced, re-enable when added + // document.getElementById('resolver-user-selection')!.innerHTML = prettyPrintJson.toHtml(data); + break; + } + } + + }; + const { target } = e; + if (target) (target as HTMLButtonElement).disabled = true; + + const iframe = document.querySelector("#resolver-iframe"); + iframe!.parentElement?.setAttribute("data-visible", "true"); + + // STEP 1A: Send port to iframe + iframe!.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); +}; + +window.addEventListener('load', () => { + document.getElementById('send-btn-channel')!.addEventListener('click', openChannelIframe); + document.getElementById('send-btn-resolver')!.addEventListener('click', openResolverIframe); +}); \ No newline at end of file diff --git a/toolbox/fdc3-for-web/reference-ui/vite.config.ts b/toolbox/fdc3-for-web/reference-ui/vite.config.ts index 5942d7800..cbce46b87 100644 --- a/toolbox/fdc3-for-web/reference-ui/vite.config.ts +++ b/toolbox/fdc3-for-web/reference-ui/vite.config.ts @@ -2,8 +2,8 @@ import { defineConfig } from "vite"; // https://vitejs.dev/config/ export default defineConfig({ - server: { port: 4000 }, + server: { port: 4002 }, build: { - outDir: "../../../website/static/reference-ui" + outDir: "dist" } }); diff --git a/toolbox/fdc3-workbench/vite.config.ts b/toolbox/fdc3-workbench/vite.config.ts index bdd86f646..635920097 100644 --- a/toolbox/fdc3-workbench/vite.config.ts +++ b/toolbox/fdc3-workbench/vite.config.ts @@ -22,5 +22,5 @@ export default defineConfig({ targets: ["defaults", "not IE 11"], }), ], - server: { port: 3000 }, + server: { port: 4001 }, }); From 3cbbb89c9750d695f97587a1b5d1c77443ec2b78 Mon Sep 17 00:00:00 2001 From: Rob Moffat Date: Thu, 14 Nov 2024 15:33:48 +0000 Subject: [PATCH 11/12] Fixed demo UI using new FDC3 UI Constants --- .../src/listeners/HeartbeatListener.ts | 2 +- .../demo/src/client/da/dummy-desktop-agent.ts | 16 ++-------------- .../fdc3-for-web/demo/src/client/da/embed.ts | 3 +-- toolbox/fdc3-for-web/demo/src/client/da/util.ts | 17 +++++++++++++++-- .../demo/src/client/ui/intent-resolver.ts | 4 ++-- toolbox/fdc3-for-web/demo/static/da/appd.json | 4 ++-- 6 files changed, 23 insertions(+), 23 deletions(-) diff --git a/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts b/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts index 4786a1361..6ff5b4836 100644 --- a/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts +++ b/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts @@ -27,7 +27,7 @@ export class HeartbeatListener implements RegisterableListener { heartbeatEventUuid: (_m as HeartbeatEvent).meta.eventUuid } } as HeartbeatAcknowledgementRequest) - console.log("Heartbeat acknowledged") + //console.log("Heartbeat acknowledged") } async register(): Promise { diff --git a/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts b/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts index 7c2f372c8..f76850030 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts @@ -5,7 +5,7 @@ import { DemoServerContext } from "./DemoServerContext"; import { FDC3_2_1_JSONDirectory } from "./FDC3_2_1_JSONDirectory"; import { AppRegistration, DefaultFDC3Server, DirectoryApp, ServerContext } from "@kite9/fdc3-web-impl"; import { ChannelState, ChannelType } from "@kite9/fdc3-web-impl/src/handlers/BroadcastHandler"; -import { link } from "./util"; +import { link, UI, UI_URLS } from "./util"; import { BrowserTypes } from "@kite9/fdc3-schema"; type WebConnectionProtocol2LoadURL = BrowserTypes.WebConnectionProtocol2LoadURL @@ -36,19 +36,7 @@ function getApproach(): Approach { return out; } -export enum UI { DEFAULT, DEMO } - -export const UI_URLS = { - [UI.DEMO]: { - intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", - channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", - }, - [UI.DEFAULT]: { - // TODO: REPLACE WITH FDC3.FINOS.ORG URLS AFTER GO-LIVE - intentResolverUrl: "http://localhost:4002/intent-resolver.html", - channelSelectorUrl: "http://localhost:4002/channel-selector.html", - } -} + function getUIKey(): UI { const cb = document.getElementById("ui") as HTMLInputElement; diff --git a/toolbox/fdc3-for-web/demo/src/client/da/embed.ts b/toolbox/fdc3-for-web/demo/src/client/da/embed.ts index 86540a9b2..2b25c4976 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/embed.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/embed.ts @@ -1,7 +1,6 @@ import { io } from "socket.io-client" -import { link } from "./util"; +import { link, UI, UI_URLS } from "./util"; import { APP_HELLO } from "../../message-types"; -import { UI, UI_URLS } from "./dummy-desktop-agent"; const appWindow = window.parent; diff --git a/toolbox/fdc3-for-web/demo/src/client/da/util.ts b/toolbox/fdc3-for-web/demo/src/client/da/util.ts index cedf0af40..be2c6e723 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/util.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/util.ts @@ -2,15 +2,28 @@ import { InstanceID } from "@kite9/fdc3-web-impl" import { Socket } from "socket.io-client" import { FDC3_APP_EVENT, FDC3_DA_EVENT } from "../../message-types" +export enum UI { DEFAULT, DEMO } + +export const UI_URLS = { + [UI.DEMO]: { + intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", + channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + }, + [UI.DEFAULT]: { + // TODO: REPLACE WITH FDC3.FINOS.ORG URLS AFTER GO-LIVE + intentResolverUrl: "http://localhost:4002/intent-resolver.html", + channelSelectorUrl: "http://localhost:4002/channel-selector.html", + } +} export function link(socket: Socket, channel: MessageChannel, source: InstanceID) { socket.on(FDC3_DA_EVENT, (data: any, to: InstanceID) => { - console.log(`DA Sent ${JSON.stringify(data)} from socket`) + //console.log(`DA Sent ${JSON.stringify(data)} from socket`) channel.port2.postMessage(data) }) channel.port2.onmessage = function (event) { - console.log(`App Sent ${JSON.stringify(event.data)} from message port`) + //console.log(`App Sent ${JSON.stringify(event.data)} from message port`) socket.emit(FDC3_APP_EVENT, event.data, source) } } diff --git a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts index 8fb1a58b5..c37bd9edb 100644 --- a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts +++ b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts @@ -1,6 +1,6 @@ import { AppIdentifier } from "@kite9/fdc3-standard"; import { BrowserTypes } from "@kite9/fdc3-schema"; -import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESOLVE_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type IframeResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction type IframeResolvePayload = BrowserTypes.Fdc3UserInterfaceResolvePayload @@ -67,7 +67,7 @@ window.addEventListener("load", () => { myPort.addEventListener("message", (e) => { if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) - } else if (e.data.type == FDC3_USER_INTERFACE_RESTYLE_TYPE) { + } else if (e.data.type == FDC3_USER_INTERFACE_RESOLVE_TYPE) { myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_EXPANDED_CSS } } as IframeRestyle) Array.from(list.children).forEach(i => i.remove()) const details = e.data.payload as IframeResolvePayload diff --git a/toolbox/fdc3-for-web/demo/static/da/appd.json b/toolbox/fdc3-for-web/demo/static/da/appd.json index 9219d0487..1178bf7d9 100644 --- a/toolbox/fdc3-for-web/demo/static/da/appd.json +++ b/toolbox/fdc3-for-web/demo/static/da/appd.json @@ -46,10 +46,10 @@ "appId": "workbench", "name": "FDC3 Workbench", "title": "FDC3 Workbench", - "description": "Part of the WebFDC3 Demo - Port of the FDC3 Workbench. Must be started separately on localhost:3000", + "description": "Part of the WebFDC3 Demo - Port of the FDC3 Workbench. Must be started separately on localhost:4001", "type": "web", "details": { - "url": "http://localhost:3000/toolbox/fdc3-workbench/" + "url": "http://localhost:4001/toolbox/fdc3-workbench/" }, "hostManifests": {}, "version": "1.0.0", From 8942cd3c5b2e6e82fd0e8eaac55775282ffb225c Mon Sep 17 00:00:00 2001 From: Rob Moffat Date: Fri, 15 Nov 2024 13:43:28 +0000 Subject: [PATCH 12/12] Got alternative UI components working --- packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts | 2 +- toolbox/fdc3-for-web/demo/src/client/da/util.ts | 4 ++-- .../fdc3-for-web/reference-ui/public/intent_resolver.html | 1 - toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts | 7 ++++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts b/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts index bdae57256..91708b09e 100644 --- a/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts +++ b/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts @@ -67,7 +67,7 @@ export abstract class AbstractUIComponent implements Connectable { async messagePortReady(port: MessagePort) { // tells the iframe it can start posting - port.postMessage({ type: FDC3_USER_INTERFACE_HANDSHAKE_TYPE }) + port.postMessage({ type: FDC3_USER_INTERFACE_HANDSHAKE_TYPE, payload: {} }) } private awaitHello(): Promise { diff --git a/toolbox/fdc3-for-web/demo/src/client/da/util.ts b/toolbox/fdc3-for-web/demo/src/client/da/util.ts index be2c6e723..716c256b5 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/util.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/util.ts @@ -11,8 +11,8 @@ export const UI_URLS = { }, [UI.DEFAULT]: { // TODO: REPLACE WITH FDC3.FINOS.ORG URLS AFTER GO-LIVE - intentResolverUrl: "http://localhost:4002/intent-resolver.html", - channelSelectorUrl: "http://localhost:4002/channel-selector.html", + intentResolverUrl: "http://localhost:4002/intent_resolver.html", + channelSelectorUrl: "http://localhost:4002/channel_selector.html", } } diff --git a/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html b/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html index 9c56f9112..b090ad3d5 100644 --- a/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html +++ b/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html @@ -15,7 +15,6 @@ scrollbar-color: #ace; border-radius: 8px; width: fit-content; - position: fixed; bottom: 4px; right: 0; diff --git a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts index 7f1fbbb9e..951dc4f41 100644 --- a/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts @@ -1,5 +1,5 @@ import { IframeChannelsPayload, Channel } from "@kite9/fdc3-common"; -import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, Fdc3UserInterfaceHello, Fdc3UserInterfaceRestyle, isFdc3UserInterfaceChannels, isFdc3UserInterfaceHandshake } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE, FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, Fdc3UserInterfaceHello, Fdc3UserInterfaceRestyle, isFdc3UserInterfaceChannels, isFdc3UserInterfaceHandshake } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; const fillChannels = (data: Channel[], selected: string | null, messageClickedChannel: (s: string | null) => void) => { const list = document.getElementById('list')!!; @@ -48,9 +48,9 @@ window.addEventListener("load", () => { myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); - if (isFdc3UserInterfaceHandshake(data)) { + if (data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { collapse(); - } else if (isFdc3UserInterfaceChannels(data)) { + } else if (data.type == FDC3_USER_INTERFACE_CHANNELS_TYPE) { logo.removeEventListener("click", expand); const { userChannels, selected } = data.payload as IframeChannelsPayload; fillChannels(userChannels, selected, (channelStr) => { @@ -64,6 +64,7 @@ window.addEventListener("load", () => { }); const selectedChannel = userChannels.find((c) => c.id === selected); logo.style.fill = selectedChannel?.displayMetadata?.color ?? "white"; + console.log("Adding event listener") logo.addEventListener("click", expand); } };