From d9541d17e5d46131745cf36fa4c8559d9dc7b09c Mon Sep 17 00:00:00 2001 From: Elizabeth Kemerava Date: Fri, 27 Sep 2024 14:19:40 -0400 Subject: [PATCH 1/3] Context Clearing --- docs/api/ref/Channel.md | 95 +++++++++++++++++++++++++++++ docs/api/spec.md | 7 ++- schemas/context/nothing.schema.json | 7 ++- src/api/Channel.ts | 9 +++ 4 files changed, 115 insertions(+), 3 deletions(-) diff --git a/docs/api/ref/Channel.md b/docs/api/ref/Channel.md index 4f949f09d..3c252dfef 100644 --- a/docs/api/ref/Channel.md +++ b/docs/api/ref/Channel.md @@ -36,6 +36,7 @@ interface Channel { broadcast(context: Context): Promise; getCurrentContext(contextType?: string): Promise; addContextListener(contextType: string | null, handler: ContextHandler): Promise; + clearContext(contextType?: string): Promise; //deprecated functions /** @@ -57,6 +58,7 @@ interface IChannel: IIntentResult Task Broadcast(IContext context); Task GetCurrentContext(string? contextType); Task AddContextListener(string? contextType, ContextHandler handler) where T : IContext; + Task ClearContext(string? contextType); } ``` @@ -431,6 +433,99 @@ catch (Exception ex) - [`broadcast`](#broadcast) - [`addContextListener`](#addcontextlistener) +### `clearContext` + + + + +```ts +public clearContext(contextType?: string): Promise; +``` + + + + +```csharp +Task ClearContext(string? contextType); +``` + + + + +Used to clear the specified context type if provided, otherwise, clear all contexts. Desktop Agent MUST update internal context. Any future calls to [`getCurrentContext`](#getcurrentcontext) and any new joiners on that channel (through [`joinUserChannel`](DesktopAgent#joinUserChannel) or [`addContextListener`](DesktopAgent#addContextListener)) will not receive anything for specified context type or all contexts accordingly. +Desktop Agent MUST update all channel listeners subscribed to the [`fdc3.nothing`](../../context/ref/Nothing.md/#nothing) type. If `contextType` is provided, then `subType` will be specified, otherwise, it is ommitted. + + +**Examples:** + +Without specifying a context type: + + + + +```ts +try { + const context = await channel.clearContext(); +} catch (err: ChannelError) { + // handle error +} +``` + + + + +```csharp +try +{ + var context = await channel.ClearContext(); +} +catch (Exception ex) +{ + // handle error +} +``` + + + + +Specifying a context type: + + + + +```ts +try { + const contact = await channel.clearContext('fdc3.contact'); +} catch (err: ChannelError) { + // handler error +} +``` + + + + +```csharp +try +{ + var context = await channel.ClearContext("fdc3.contact"); +} +catch (Exception ex) +{ + // handle error +} +``` + + + + + +**See also:** + +- [`getCurrentContext`](#getcurrentcontext) +- [`addContextListener`](DesktopAgent#addContextListener) +- [`joinUserChannel`](DesktopAgent#joinUserChannel) +- [`fdc3.nothing`](../../context/ref/Nothing.md/#nothing) + ## Deprecated Functions ### `addContextListener` (deprecated) diff --git a/docs/api/spec.md b/docs/api/spec.md index dde1210ba..287e9d9b7 100644 --- a/docs/api/spec.md +++ b/docs/api/spec.md @@ -241,7 +241,7 @@ When raising an intent a specific context is provided as input. The type of the A context type may also be associated with multiple intents. For example, an `fdc3.instrument` could be associated with `ViewChart`, `ViewNews`, `ViewAnalysis` or other intents. -To raise an intent without a context, use the [`fdc3.nothing`](../context/ref/Nothing) context type. This type exists so that applications can explicitly declare that they support raising an intent without a context (when registering an `IntentHandler` or in an App Directory). +To raise an intent without a context, use the [`fdc3.nothing`](../context/ref/Nothing) context type. This type exists so that applications can explicitly declare that they support raising an intent without a context (when registering an `IntentHandler` or in an App Directory). This type is also used when the context is cleared for the channel. If the optional context type is provided when performing [`clearContext`](ref/Channel.md#clearcontext), that type will be recorded in the field `subType` of [`fdc3.nothing`](../context/ref/Nothing) context type. As an alternative to raising a specific intent, you may also raise an unspecified intent with a known context allowing the Desktop Agent or the user (if the intent is ambiguous) to select the appropriate intent and then to raise it with the specified context for resolution. @@ -585,7 +585,7 @@ Apps can join *User channels*. An app can only be joined to one User channel at When an app is joined to a User channel, calls to [`fdc3.broadcast`](ref/DesktopAgent#broadcast) will be routed to that channel and listeners added through [`fdc3.addContextListener`](ref/DesktopAgent#addcontextlistener) will receive context broadcasts from other apps also joined to that channel. If an app is not joined to a User channel [`fdc3.broadcast`](ref/DesktopAgent#broadcast) will be a no-op and handler functions added with [`fdc3.addContextListener`](ref/DesktopAgent#addcontextlistener) will not receive any broadcasts. However, apps can still choose to listen and broadcast to specific channels (both User and App channels) via the methods on the [`Channel`](ref/Channel) class. -When an app joins a User channel, or adds a context listener when already joined to a channel, it will automatically receive the current context for that channel. +When an app joins a User channel, or adds a context listener when already joined to a channel, it will automatically receive the current context for that channel, unless the context was cleared through [`clearContext`](ref/Channel.md#clearcontext). It is possible that a call to join a User channel could be rejected. If for example, the desktop agent wanted to implement controls around what data apps can access. @@ -830,6 +830,9 @@ The [Context specification](../context/spec#assumptions) recommends that complex To facilitate context linking in such situations it is recommended that applications `broadcast` each context type that other apps (listening on a User Channel or App Channel) may wish to process, starting with the simpler types, followed by the complex type. Doing so allows applications to filter the context types they receive by adding listeners for specific context types - but requires that the application broadcasting context make multiple broadcast calls in quick succession when sharing its context. +### Context clearning on channels +Channel interface provides the ability to [`clearContext`](ref/Channel.md#clearcontext) on the channel, either for the specific context type, if provided, or for all contexts on that channel. If provided, the specified type will be recorded in the `subType` field of the [`fdc3.nothing`](../context/ref/Nothing) context type. Once cleared, any subsequent new joiners on the channel, new context listeners on the context or calls to [`getCurrentContext`](ref/Channel.md#getcurrentcontext) will not return anything to the caller. + ### Originating App Metadata Optional metadata about each context message received, including the app that originated the message, SHOULD be provided by the desktop agent implementation to registered context handlers on all types of channel. As this metadata is optional, apps making use of it MUST handle cases where it is not provided. diff --git a/schemas/context/nothing.schema.json b/schemas/context/nothing.schema.json index 2b970c895..f7eaad0b5 100644 --- a/schemas/context/nothing.schema.json +++ b/schemas/context/nothing.schema.json @@ -10,6 +10,10 @@ "properties": { "type": { "const": "fdc3.nothing" + }, + "subtype": { + "type": "string", + "description": "A subtype of the context type. This can be used to provide a specific context which should be cleared, if ommitted, all contexts will be cleared" } } }, @@ -17,7 +21,8 @@ ], "examples": [ { - "type": "fdc3.nothing" + "type": "fdc3.nothing", + "subtype": "fdc3.timeRange" } ] } \ No newline at end of file diff --git a/src/api/Channel.ts b/src/api/Channel.ts index 9eca774b5..091a6f5b1 100644 --- a/src/api/Channel.ts +++ b/src/api/Channel.ts @@ -73,6 +73,15 @@ export interface Channel { */ addContextListener(contextType: string | null, handler: ContextHandler): Promise; + /** + * Provides the ability to clear context from the channel. Subsequent connection to this channel or calls to get current context will not return anything (accounting for contextType if specified). + * + * If a `contextType` is provided, only contexts of that type will be cleared. + * + * If no `contextType` is provided, all contexts will be cleared. + */ + clearContext(contextType?: string): Promise; + /** * @deprecated use `addContextListener(null, handler)` instead of `addContextListener(handler)`. */ From 77e2b610ffbd76edcbf2a3a37312462e325af8bd Mon Sep 17 00:00:00 2001 From: kemerava <52539182+kemerava@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:46:47 -0400 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Kris West --- docs/api/ref/Channel.md | 4 ++-- docs/api/spec.md | 2 +- schemas/context/nothing.schema.json | 8 ++++---- src/api/Channel.ts | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/api/ref/Channel.md b/docs/api/ref/Channel.md index 3c252dfef..390a75138 100644 --- a/docs/api/ref/Channel.md +++ b/docs/api/ref/Channel.md @@ -452,8 +452,8 @@ Task ClearContext(string? contextType); -Used to clear the specified context type if provided, otherwise, clear all contexts. Desktop Agent MUST update internal context. Any future calls to [`getCurrentContext`](#getcurrentcontext) and any new joiners on that channel (through [`joinUserChannel`](DesktopAgent#joinUserChannel) or [`addContextListener`](DesktopAgent#addContextListener)) will not receive anything for specified context type or all contexts accordingly. -Desktop Agent MUST update all channel listeners subscribed to the [`fdc3.nothing`](../../context/ref/Nothing.md/#nothing) type. If `contextType` is provided, then `subType` will be specified, otherwise, it is ommitted. +Used to clear the specified context type if provided, otherwise, clear all context types present in the channel. The Desktop Agent MUST update its internal representation of the context in the channel and ensure that subsequent calls to [`getCurrentContext`](#getcurrentcontext) and any new joiners to that channel (through [`joinUserChannel`](DesktopAgent#joinUserChannel) or [`addContextListener`](DesktopAgent#addContextListener)) will not receive anything for either specified context type or the most recent context until new context has been broadcast to the channel. +Desktop Agents MUST also immediately broadcast the [`fdc3.nothing`](../../context/ref/Nothing.md/#nothing) type, which applications may listen to to be notified of the cleared context. If a `contextType` parameter was provided, then the `contextType` field will be set to that type, otherwise, it is omitted. **Examples:** diff --git a/docs/api/spec.md b/docs/api/spec.md index 287e9d9b7..4a2370173 100644 --- a/docs/api/spec.md +++ b/docs/api/spec.md @@ -831,7 +831,7 @@ The [Context specification](../context/spec#assumptions) recommends that complex To facilitate context linking in such situations it is recommended that applications `broadcast` each context type that other apps (listening on a User Channel or App Channel) may wish to process, starting with the simpler types, followed by the complex type. Doing so allows applications to filter the context types they receive by adding listeners for specific context types - but requires that the application broadcasting context make multiple broadcast calls in quick succession when sharing its context. ### Context clearning on channels -Channel interface provides the ability to [`clearContext`](ref/Channel.md#clearcontext) on the channel, either for the specific context type, if provided, or for all contexts on that channel. If provided, the specified type will be recorded in the `subType` field of the [`fdc3.nothing`](../context/ref/Nothing) context type. Once cleared, any subsequent new joiners on the channel, new context listeners on the context or calls to [`getCurrentContext`](ref/Channel.md#getcurrentcontext) will not return anything to the caller. +Channel interface provides the ability to [`clearContext`](ref/Channel.md#clearcontext) on the channel, either for the specific context type, if provided, or for all contexts on that channel. Applications may listen for the `fdc3.nothing` type, or all context types, to be notified when the context is cleared. If a specific type was cleared, the `subType` field of the [`fdc3.nothing`](../context/ref/Nothing) context type will be set with that type. Once cleared, any apps that join the channel, add new context listeners or call [`getCurrentContext`](ref/Channel.md#getcurrentcontext) will not return anything to the caller (other than the `fdc3.nothing` type indicating that context was cleared) until new context is broadcast to the channel. ### Originating App Metadata diff --git a/schemas/context/nothing.schema.json b/schemas/context/nothing.schema.json index f7eaad0b5..fa69c23c6 100644 --- a/schemas/context/nothing.schema.json +++ b/schemas/context/nothing.schema.json @@ -11,9 +11,9 @@ "type": { "const": "fdc3.nothing" }, - "subtype": { - "type": "string", - "description": "A subtype of the context type. This can be used to provide a specific context which should be cleared, if ommitted, all contexts will be cleared" + "contextType": { + "type": "Context Type", + "description": "A referenced context type name. Used to indicate that a specific context type was cleared, if omitted, all contexts were cleared" } } }, @@ -22,7 +22,7 @@ "examples": [ { "type": "fdc3.nothing", - "subtype": "fdc3.timeRange" + "contextType": "fdc3.timeRange" } ] } \ No newline at end of file diff --git a/src/api/Channel.ts b/src/api/Channel.ts index 091a6f5b1..9b58fc428 100644 --- a/src/api/Channel.ts +++ b/src/api/Channel.ts @@ -74,11 +74,11 @@ export interface Channel { addContextListener(contextType: string | null, handler: ContextHandler): Promise; /** - * Provides the ability to clear context from the channel. Subsequent connection to this channel or calls to get current context will not return anything (accounting for contextType if specified). + * Clears context from the channel, and broadcasts an `fdc3.nothing` context to notify existing listeners that the context was cleared. Listeners added to the channel and calls to [`getCurrentContext`](#getcurrentcontext) will not receive any existing context until new context is broadcast to the channel. * - * If a `contextType` is provided, only contexts of that type will be cleared. + * If a `contextType` is provided, only contexts of that type will be cleared and the `contextType` of the `fdc3.nothing` context will be set to that type name. * - * If no `contextType` is provided, all contexts will be cleared. + * If no `contextType` is provided, all contexts will be cleared and the `contextType` of the `fdc3.nothing` context will be omitted. */ clearContext(contextType?: string): Promise; From a2c348ecbf70adc87a6ebe8c19a929400ad1afec Mon Sep 17 00:00:00 2001 From: kemerava Date: Fri, 4 Oct 2024 09:18:32 -0400 Subject: [PATCH 3/3] Changelog and fixing the name of the field --- CHANGELOG.md | 2 ++ docs/api/spec.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b08ed442..ac123c410 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,12 +12,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). * Added requirement that Standard versions SHOULD avoid the use unions in context and API definitions wherever possible as these can be hard to replicate and MUST avoid unions of primitive types as these can be impossible to replicate in other languages. ([#120](https://github.com/finos/FDC3/pull/1200)) * Added `addEventListener` to the `DesktopAgent` API to provide support for event listener for non-context and non-intent events, including a `userChannelChanged` event ([#1207](https://github.com/finos/FDC3/pull/1207)) * Added an `async` `addEventListener` function to the `PrivateChannel` API to replace the deprecated, synchronous `onAddContextListener`, `onUnsubscribe` and `onDisconnect` functions and to keep consistency with the DesktopAgent API. ([#1305](https://github.com/finos/FDC3/pull/1305)) +* Added `clearContext` function to the `Channel` API, to be able to clear specific or all context types from the channel. ([#1379](https://github.com/finos/FDC3/pull/1379)) ### Changed * `Listener.unsubscribe()` was made async (the return type was changed from `void` to `Promise`) for consistency with the rest of the API. ([#1305](https://github.com/finos/FDC3/pull/1305)) * Added reference materials and supported platforms information for FDC3 in .NET via the [finos/fdc3-dotnet](https://github.com/finos/fdc3-dotnet) project. ([#1108](https://github.com/finos/FDC3/pull/1108)) * The supported platforms page in the FDC3 documentation was moved into the API section as the information it provides all relates to FDC3 Desktop Agent API implementations. ([#1108](https://github.com/finos/FDC3/pull/1108)) +* Enhanced `fdc3.nothing` context type to support optional `contextType` field, refrencing the specific cleared context type. ([#1379](https://github.com/finos/FDC3/pull/1379)) ### Deprecated diff --git a/docs/api/spec.md b/docs/api/spec.md index 4a2370173..6d01dc06b 100644 --- a/docs/api/spec.md +++ b/docs/api/spec.md @@ -831,7 +831,7 @@ The [Context specification](../context/spec#assumptions) recommends that complex To facilitate context linking in such situations it is recommended that applications `broadcast` each context type that other apps (listening on a User Channel or App Channel) may wish to process, starting with the simpler types, followed by the complex type. Doing so allows applications to filter the context types they receive by adding listeners for specific context types - but requires that the application broadcasting context make multiple broadcast calls in quick succession when sharing its context. ### Context clearning on channels -Channel interface provides the ability to [`clearContext`](ref/Channel.md#clearcontext) on the channel, either for the specific context type, if provided, or for all contexts on that channel. Applications may listen for the `fdc3.nothing` type, or all context types, to be notified when the context is cleared. If a specific type was cleared, the `subType` field of the [`fdc3.nothing`](../context/ref/Nothing) context type will be set with that type. Once cleared, any apps that join the channel, add new context listeners or call [`getCurrentContext`](ref/Channel.md#getcurrentcontext) will not return anything to the caller (other than the `fdc3.nothing` type indicating that context was cleared) until new context is broadcast to the channel. +Channel interface provides the ability to [`clearContext`](ref/Channel.md#clearcontext) on the channel, either for the specific context type, if provided, or for all contexts on that channel. Applications may listen for the `fdc3.nothing` type, or all context types, to be notified when the context is cleared. If a specific type was cleared, the `contextType` field of the [`fdc3.nothing`](../context/ref/Nothing) context type will be set with that type. Once cleared, any apps that join the channel, add new context listeners or call [`getCurrentContext`](ref/Channel.md#getcurrentcontext) will not return anything to the caller (other than the `fdc3.nothing` type indicating that context was cleared) until new context is broadcast to the channel. ### Originating App Metadata