FDC3 Compliance

Overview

FDC3 aims at developing specific protocols and classifications in order to advance the ability of desktop apps in financial workflows to interoperate in a plug-and-play fashion without prior bilateral agreements.

FDC3 for io.Connect Browser

io.Connect Browser supports fully the FDC3 2.0 standards.

The following sections explain the specifics for running FDC3-compliant apps within io.Connect Browser and using the @interopio/fdc3 library which provides an io.Connect implementation of the FDC3 standards. For more detailed information on the FDC3 standards and APIs, see the FDC3 documentation.

⚠️ Note that the examples in the following sections follow the FDC3 2.0 standard.

FDC3 Implementation

The @interopio/fdc3 library is the io.Connect implementation of the FDC3 standards.

Referencing

To install the @interopio/fdc3 library, execute the following command:

npm install @interopio/fdc3

Reference the library in your app:

import "@interopio/fdc3";

You can also reference it as a script from UNPKG:

<script src="https://unpkg.com/@interopio/fdc3@latest/dist/fdc3.umd.js"></script>

Initialization

The @interopio/fdc3 library can be used only in interop-enabled io.Connect apps - either a Main app with initialized @interopio/browser-platform library, or a Browser Client app with initialized @interopio/browser library. To be able to use functionalities related to the io.Connect Channels and the FDC3 User Channels, the Main app must be initialized with properly defined Channels (see the Channels section).

Initializing the @interopio/fdc3 library in the Main app:

import IOBrowserPlatform from "@interopio/browser-platform";
import "@interopio/fdc3";

const channels = {
    definitions: [
        {
            "name": "Red",
            "meta": {
                "color": "red",
                "fdc3": {
                    "id": "fdc3.channel.1",
                    "displayMetadata": {
                      "name": "Channel 1",
                      "glyph": "1"
                    }
                }
            }
        }
        // You can define as many io.Connect Channels as you need and map them
        // to the default FDC3 User Channels if you want to use them as such.
        // For more io.Connect Channel definitions and mappings, see the "Channels" section.
    ]
};

const config = {
    licenseKey: "my-license-key",
    channels
};

const { io } = await IOBrowserPlatform(config);

// The FDC3 API will now be available as an `fdc3` object injected in the global `window` object.
const info = await fdc3.getInfo();

console.log(`FDC3 provider: ${info.provider}, FDC3 version: ${info.fdc3Version}`);

Initializing the @interopio/fdc3 library in a Browser Client app:

import IOBrowser from "@interopio/browser";
import "@interopio/fdc3";

const io = await IOBrowser();

// The FDC3 API will now be available as an `fdc3` object injected in the global `window` object.
const info = await fdc3.getInfo();

console.log(`FDC3 provider: ${info.provider}, FDC3 version: ${info.fdc3Version}`);

After the @interopio/fdc3 library has been imported and the respective io.Connect library properly initialized, the FDC3 API will be available as an fdc3 object injected in the global window object:

const contextType = "Contact";
const handler = context => console.log(`Context: ${JSON.stringify(context)}`);

await fdc3.addContextListener(contextType, handler);

App Definition

To use your FDC3-compliant app in io.Connect Browser, you must either create an io.Connect app definition for it, or place your already existing FDC3 app definition in any io.Connect Browser app store (local, remote, in-memory, or io.Manager).

io.Connect Definitions

The following example demonstrates providing a minimal io.Connect definition for an interop-enabled app when initializing the @interopio/browser-platform library:

import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applications: {
        local: [
            {
                name: "my-app",
                type: "window",
                title: "My App",
                details: {
                    url: "https://my-domain.com/my-app"
                }
            }
        ]
    }
};

const { io } = await IOBrowserPlatform(config);

The name, type and url properties are required and type must be set to "window". The url property points to the location of the web app.

For more information on configuring your apps for io.Connect Browser, see the Capabilities > App Management > App Definitions section.

FDC3 Definitions

io.Connect Browser supports the FDC3 app definition standard (App Directory or AppD). FDC3 definitions are automatically converted to io.Connect ones, preserving the original FDC3 app definition in a top-level fdc3 property added to the resulting io.Connect app Definition object. You can add FDC3 definitions from any supported io.Connect Browser app store: local, remote, in-memory, or io.Manager.

If you already have an FDC3 definition for your app, you can use the "ioConnect" property of the "hostManifests" top-level key to provide any app settings specific to the io.Connect framework that you want to employ:

{
    "appId": "my-app",
    "title": "My App",
    "type": "web",
    "details": {
        "url": "https://example.com/my-app"
    },
    "hostManifests": {
        "ioConnect": {
            "name": "my-app",
            "type": "window",
            "details": {
                "url": "https://example.com/my-app",

            },
            "customProperties": {
                "includeInWorkspaces": true
            }
        }
    }
}

For more details on the FDC3 app definition standards, see the FDC3 Application schema.

App Directory

The goal of the FDC3 App Directory (or AppD) REST service is to provide trusted identity for apps. App definitions are provided by one or more App Directory REST services where user entitlements and security can also be handled.

io.Connect Browser supports the FDC3 app definition standard. FDC3 definitions are automatically converted to io.Connect ones, preserving the original FDC3 app definition in a top-level fdc3 property added to the resulting io.Connect app Definition object. You can add FDC3 definitions from any supported io.Connect Browser app store: local, remote, in-memory, or io.Manager.

For more details on the FDC3 app definition standards, see the FDC3 Application schema.

The following example demonstrates how to configure io.Connect Browser to retrieve FDC3 app definitions from a remote app store. Use the remote property of the applications object in the configuration object for the initializing the Main app:

import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applications: {
        remote: {
            url: "http://localhost:3001/v2/apps/",
            pollingInterval: 1000,
            requestTimeout: 5000
        }
    }
};

const { io } = await IOBrowserPlatform(config);

For more details on defining apps and configuring all supported app stores, see the Capabilities > App Management > App Definitions section.

⚠️ Note that any app can connect to remote sources and not only the Main app. The app definitions from all remote sources are then merged by the Main app. The remote sources can supply both io.Connect and FDC3 app definitions. The only requirement for an FDC3 app definition to be usable in io.Connect Browser is to have a valid URL specified.

According to the FDC3 App Directory specifications, the remote store must return app definitions in the following response shape:

{
    "applications": [
        // List of app definition objects.
        {}, {}
    ]
}

For a reference implementation of the FDC3 App Directory, see the Node.js REST Config Example on GitHub.

For more details on using App Directory, see the FDC3 App Directory documentation.

Intents

The FDC3 Intents concept serves the purpose of enabling the creation of cross-app workflows on the desktop. An Intent specifies what action the app can execute and with what data structure it can work. An app declares itself as an Intent handler through configuration or at runtime. Other apps can raise this Intent and provide context data for handling the Intent to the Intent handler app.

Intents can be defined both in the intents top-level key of an io.Connect app definition object, or in the "intents" property of the "interop" top-level key in an FDC3 app definition.

The following example demonstrates how to define an Intent in an io.Connect app definition:

import IOBrowserPlatform from "@interopio/browser-platform";

const config = {
    licenseKey: "my-license-key",
    applications: {
        local: [
            {
                name: "Instrument Chart",
                details: {
                    url: "http://localhost:4242/chart"
                },
                // Intent definitions.
                intents: [
                    {
                        name: "ShowChart",
                        displayName: "Instrument Chart",
                        contexts: ["Instrument"]
                    }
                ]
            }
        ]
    }
};

const { io } = await IOBrowserPlatform(config);
Property Type Description
name string Required. The name of the Intent.
displayName string The display name of the Intent. Can be used in UI elements to visualize the Intent.
contexts string[] The type of predefined data structures with which the app can work (see FDC3 Contexts).

The Intents Resolver UI app allows users to choose an app for handling a raised Intent:

Intents Resolver

For more details on how to enable or disable the Intents Resolver UI, or on how to create your own custom Intents Resolver App, see the Capabilities > Intents > Intents Resolver section.

For more details on using Intents, see the FDC3 Intents API.

Channels

The io.Connect Channels correspond to the FDC3 User Channels. Channels are well-known named context objects that can be represented with colors and names in the UI of an app. They can be controlled programmatically or manually by end users directly from the app UI. This allows users to switch apps from one Channel to another, changing the context data with which they operate. All apps on the same Channel have access to the Channel context and can read or update the data in it as necessary.

To define system Channels, use the channels property of the configuration object for initializing the Main app. Use the following configuration to create io.Connect Channels mapped to the default FDC3 User Channels:

import IOBrowserPlatform from "@interopio/browser-platform";

const channels = {
    definitions: [
        {
            "name": "Red",
            "meta": {
                "color": "red",
                "fdc3": {
                    "id": "fdc3.channel.1",
                    "displayMetadata": {
                      "name": "Channel 1",
                      "glyph": "1"
                    }
                }
            }
        },
        {
            "name": "Orange",
            "meta": {
                "color": "#fa5a28",
                "fdc3": {
                    "id": "fdc3.channel.2",
                    "displayMetadata": {
                        "name": "Channel 2",
                        "glyph": "2"
                    }
                }
            }
        },
        {
            "name": "Yellow",
            "meta": {
                "color": "#FFE733",
                "fdc3": {
                    "id": "fdc3.channel.3",
                    "displayMetadata": {
                        "name": "Channel 3",
                        "glyph": "3"
                    }
                }
            }
        },
        {
            "name": "Green",
            "meta": {
                "color": "green",
                "fdc3": {
                    "id": "fdc3.channel.4",
                    "displayMetadata": {
                        "name": "Channel 4",
                        "glyph": "4"
                    }
                }
            }
        },
        {
            "name": "Cyan",
            "meta": {
                "color": "#80f3ff",
                "fdc3": {
                    "id": "fdc3.channel.5",
                    "displayMetadata": {
                        "name": "Channel 5",
                        "glyph": "5"
                    }
                }
            }
        }
        {
            "name": "Blue",
            "meta": {
                "fdc3": {
                    "id": "fdc3.channel.6",
                    "displayMetadata": {
                        "name":"Channel 6",
                        "glyph": "6"
                    }
                }
            }
        },
        {
            "name": "Magenta",
            "meta": {
                "color": "#cc338b",
                "fdc3":   {
                    "id": "fdc3.channel.7",
                    "displayMetadata": {
                        "name": "Channel 7",
                        "glyph": "7"
                    }
                }
            }
        },
        {
            "name": "Purple",
            "meta": {
                "color": "#c873ff",
                "fdc3": {
                    "id": "fdc3.channel.8",
                    "displayMetadata": {
                        "name": "Channel 8",
                        "glyph": "8"
                    }
                }
            }
        }
    ]
};

const config = {
    licenseKey: "my-license-key",
    channels
};

const { io } = await IOBrowserPlatform(config);

For more details on defining Channels, see the Capabilities > Data Sharing > Channels section.

Any custom Channel you define must be mapped to an FDC3 User Channel if you want to use it as such.

The @interopio/widget library enables you to add the io.Connect widget to your apps. The widget contains a fully functional Channel Selector UI which enables users to control Channels manually.

For more details on using the io.Connect widget, see the Capabilities > Widget section.

For more details on using User Channels, see the FDC3 User Channels API.

Using FDC3 Contexts in Non-FDC3 Apps

Available since io.Connect Browser 3.4

If you have non-FDC3 interop-enabled apps, they can still use the contexts of FDC3 User Channels via the io.Connect Channels API in order to retrieve, subscribe for, and publish FDC3 context data.

Retrieving FDC3 Context Data

The ChannelContext object utilized by the Channels API methods for retrieving Channel contexts (such as get(), getMy() and list()) will contain an fdc3 property in its data object if FDC3 context data has been published to the Channel. The fdc3 property is an object with a required type property holding the type of the FDC3 context:

const context = await io.channels.get("Red");

// If FDC3 context data has been published to the Channel, the Channel context will contain a `data.fdc3` property.
if (context.data.fdc3) {
    // The `type` property of the `fdc3` object is required.
    const contextType = context.data.fdc3.type;

    console.log(contextType);
};

The get() and getMy() accept an FDC3Options object as an optional argument. You can use this argument to specify the type of the FDC3 context in which you are interested. The methods will resolve with an empty object if FDC3 context data of the specified type isn't available in the Channel:

// Specifying the type of an FDC3 context.
const fdc3Options = { contextType: "fdc3.contact" };

// Retrieving an FDC3 context of a specific type.
const fdc3Context = await io.channels.getMy(fdc3Options);

Subscribing for FDC3 Context Data

The object argument received by the handler provided to the subscribe() or subscribeFor() methods of the Channels API will contain an fdc3 property if FDC3 context data has been published to the Channel to which you have subscribed. The fdc3 property is an object with a required type property holding the type of the FDC3 context:

// The `data` argument received by the callback will have an `fdc3` property
// if FDC3 context data has been published to the Channel.
const handler = (data) => {
    if (data.fdc3) {
        // The `type` property of the `fdc3` object is required.
        const contextType = data.fdc3.type;

        console.log(contextType);
    };
};

const unsubscribe = io.channels.subscribe(handler);

The subscribe() and subscribeFor() methods accept an FDC3Options object as an optional argument. You can use this argument to specify the type of the FDC3 context in which you are interested. The callback passed to the subscribe() and subscribeFor() methods won't be invoked unless FDC3 context data of the specified type is published in the Channel:

// Specifying the type of an FDC3 context.
const fdc3Options = { contextType: "fdc3.contact" };

// Subscribing to an FDC3 context of a specific type.
const handler = (data) => {
    // The `type` property of the `fdc3` object is required.
    const contextType = data.fdc3.type;
    console.log(contextType);
};

const unsubscribe = io.channels.subscribe(handler, fdc3Options);

Publishing FDC3 Context Data

The publish() method of the Channels API accepts also a PublishOptions object as a second optional argument. You can use it to specify the name of the Channel to update and whether the published data is an FDC3 context:

// FDC3 context data to publish.
const data = {
    type: "fdc3.contact",
    name: "John Doe",
    id: {
        email: "john.doe@example.com"
    }
};

const options = {
    name: "Red",
    // Specify that the published data is FDC3 context data.
    fdc3: true
};

await io.channels.publish(data, options);