Skip to content

Commit 5930503

Browse files
authored
Merge pull request #375 from ChartIQ/#361-raiseIntent-without-a-context
Support raise Intent without a context
2 parents e39f258 + d11aeef commit 5930503

File tree

12 files changed

+122
-10
lines changed

12 files changed

+122
-10
lines changed

docs/api/ref/DesktopAgent.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ raiseIntent(intent: string, context: Context, app?: TargetApp): Promise<IntentRe
378378
```
379379
Raises a specific intent against a target app.
380380

381-
The desktop agent will resolve the correct app to target based on the provided intent name and context data.
381+
The desktop agent will resolve the correct app to target based on the provided intent name and context data type. If you wish to raise an Intent without a context, use the `fdc3.nothing` context type. This type exists so that apps can explicitly declare support for raising an intent without context.
382382

383383
If multiple matching apps are found, the user may be presented with an app picker.
384384
Alternatively, the specific app to target can also be provided (if known).
@@ -398,6 +398,9 @@ await fdc3.raiseIntent("StartChat", context, appIntent.apps[0].name);
398398

399399
// or use the metadata of the app to fully describe the target app for the intent
400400
await fdc3.raiseIntent("StartChat", context, appIntent.apps[0]);
401+
402+
//Raise an intent without a context by using the null context type
403+
await fdc3.raiseIntent("StartChat", {type: "fdc3.nothing"});
401404
```
402405
#### See also
403406
* [`Context`](Types#context)
@@ -415,8 +418,9 @@ Finds and raises an intent against a target app based purely on context data.
415418

416419
The desktop agent will resolve the correct app to target based on the provided context.
417420

418-
This is similar to calling `findIntentsByContext`, and then raising an intent against one of the returned apps, except in this case
419-
the desktop agent has the opportunity to provide the user with a richer selection interface where they can choose the intent and target app.
421+
This is similar to calling `findIntentsByContext`, and then raising an intent against one of
422+
the returned apps, except in this case the desktop agent has the opportunity to provide the
423+
user with a richer selection interface where they can choose the intent and target app.
420424

421425
Returns an `IntentResolution` object with a handle to the app that responded to the selected intent.
422426

docs/api/spec.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ When raising an Intent a specific context may be provided. The type of the provi
103103

104104
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. In addition to raising a specific intent, you can raise an Intent for a specific Context allowing the Desktop Agent or the user (if the Intent is ambiguous) to select the appropriate Intent for the selected Context and then to raise that Intent for resolution.
105105

106+
To raise an Intent without a context, use the `fdc3.nothing` context type. This type exists so that applications can explicitly declare that they support raising an intent without a context (when registering an Intent listener or in an App Directory).
107+
106108
#### Intent Resolution
107109
Raising an Intent will return a Promise-type object that will resolve/reject based on a number of factors.
108110

@@ -143,14 +145,14 @@ For example, to raise a specific Intent:
143145

144146
```js
145147
try {
146-
const result = await fdc3.raiseIntent('StageOrder');
148+
const result = await fdc3.raiseIntent('StageOrder', context);
147149
}
148150
catch (er){
149151
console.log(er.message);
150152
}
151153
```
152154

153-
or to raise an Intent for a specific context:
155+
or to raise an unspecified Intent for a specific context, where the user will select an intent from a resolver dialog:
154156
```js
155157
try {
156158
const result = await fdc3.raiseIntentForContext(context);
@@ -182,7 +184,7 @@ Intents represent a contract with expected behavior if an app asserts that it su
182184

183185
It is expected that App Directories will also curate listed apps and ensure that they are complying with declared intents.
184186

185-
Like FDC3 Context Data, the Intent schemas need to be versioned. Desktop Agents will be responsible to declare which version of the Intent schema they are using. Applications may also assert a specific version requirement when raising an Intent. Version negotation may be supported by a given Desktop Agent.
187+
Like FDC3 Context Data, the Intent schemas need to be versioned. Desktop Agents will be responsible to declare which version of the Intent schema they are using. Applications may also assert a specific version requirement when raising an Intent. Version negotation may be supported by a given Desktop Agent.
186188

187189
### Send/broadcast Context
188190
On the financial desktop, applications often want to broadcast context to any number of applications. Context sharing needs to support concepts of different groupings of applications as well as data privacy concerns. Each Desktop Agent will have its own rules for supporting these features. However, a Desktop Agent should ensure that context messages broadcast to a channel by an application joined to it should not be delivered back to that same application.
@@ -201,7 +203,7 @@ if (fdc3.getInfo && versionIsAtLeast(fdc3.getInfo(), '1.2')) {
201203
```
202204

203205
## Resolvers
204-
Intents functionality is dependent on resolver functionality to map the intent to a specific App. This will often require end-user input. Resolution can either be performed by the Desktop Agent (raising UI to pick the desired App for the intent) or by the app launching the intent - in which case the calling App will handle the resolution itself (using the findIntents API below) and then invoke an explicit Intent object.
206+
Intents functionality is dependent on resolver functionality to map the intent to a specific App. This will often require end-user input. Resolution can either be performed by the Desktop Agent (raising UI to pick the desired App for the Intent, or both an Intent and App for a context) or by the app launching the intent - in which case the calling App will handle the resolution itself (using the findIntents API below) and then invoke an explicit Intent object.
205207

206208
## Context Channels
207209

docs/context/ref/Nothing.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
id: Nothing
3+
sidebar_label: Nothing
4+
title: Nothing
5+
hide_title: true
6+
---
7+
# `Nothing`
8+
9+
A type that explicitly represents a lack of context.
10+
11+
Notes:
12+
13+
- Intended to be used in situations where no context is desired.
14+
- For example:
15+
- Raising an Intent without context (e.g. opening a blank order form, or chat
16+
interface without a contact selected).
17+
- Resetting context on a channel (e.g. when context is used to set a filter in
18+
other applications a null context might release the filter).
19+
- An explicit representation of a Null or empty context allows apps to declare support for
20+
a lack of context, for example in their Intent metadata in an app directory.
21+
22+
## Type
23+
24+
`fdc3.nothing`
25+
26+
## Schema
27+
28+
https://fdc3.finos.org/schemas/next/nothing.schema.json
29+
30+
## Example
31+
32+
```js
33+
const nullContext = {
34+
type: 'fdc3.nothing'
35+
}
36+
37+
fdc3.joinChannel('groupA')
38+
fdc3.broadcast(nullContext)
39+
```

docs/context/spec.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ The following are standard FDC3 context types.
111111
- __fdc3.position__
112112
- [Financial Objects Specification](https://fo.finos.org/docs/objects/position)
113113
- [schema](/schemas/next/position.schema.json)
114+
- __fdc3.nothing
115+
- Explicit representation of a lack of context
116+
- [schema](/schemas/next/nothing.schema.json)
114117

115118
__Note:__ The below examples show how the base context data interface can be used to define specific context data objects. It is not the purpose of the specification at this stage to define standard representations for objects. It establishes the framework in which such definitions could be created.
116119

@@ -265,4 +268,11 @@ __Note:__ The below examples show how the base context data interface can be use
265268
}
266269
```
267270

271+
#### Nothing
272+
```json
273+
{
274+
"type": "fdc3.nothing",
275+
}
276+
```
277+
268278

docs/intents/overview.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,21 @@ const intentsAndApps = await fdc3.findIntentsByContext({
5656
}
5757
});
5858
```
59+
60+
## Using Intents without a context
61+
As the [Desktop Agent API](api/ref/DesktopAgent) and [App Directory](app-directory/overview) both
62+
require a context to specified whereever Intents are used, using an Intent without a context is
63+
achieved through the use of an explcit `null` context type `fdc3.nothing`. By using an explicit type
64+
to represent a lack of context we allow applicaitons to declare their support for a lack of
65+
context.
66+
67+
```javascript
68+
const intentsAndApps = await fdc3.findIntentsByContext({
69+
type: "fdc3.nothing",
70+
});
71+
72+
const result = await fdc3.raiseIntent("StartChat", {
73+
type: "fdc3.nothing"
74+
});
75+
```
76+

src/api/DesktopAgent.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ export interface DesktopAgent {
122122
* await fdc3.raiseIntent("StartChat", context, appIntent.apps[0].name);
123123
* //or use one of the AppMetadata objects returned in the AppIntent object's 'apps' array
124124
* await fdc3.raiseIntent("StartChat", context, appMetadata);
125+
* //Raise an intent without a context by using the null context type
126+
* await fdc3.raiseIntent("StartChat", {type: "fdc3.nothing"});
125127
* ```
126128
*/
127129
raiseIntent(intent: string, context: Context, app?: TargetApp): Promise<IntentResolution>;

src/context/ContextType.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export enum ContextTypes {
66
Organization = 'fdc3.organization',
77
Portfolio = 'fdc3.portfolio',
88
Position = 'fdc3.position',
9+
Nothing = 'fdc3.nothing',
910
}
1011

1112
export type ContextType = ContextTypes | string;

src/context/ContextTypes.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// To parse this data:
22
//
3-
// import { Convert, Context, Contact, ContactList, Instrument, InstrumentList, Country, Organization, Portfolio, Position } from "./file";
3+
// import { Convert, Context, Contact, ContactList, Instrument, InstrumentList, Country, Organization, Portfolio, Position, Nothing } from "./file";
44
//
55
// const context = Convert.toContext(json);
66
// const contact = Convert.toContact(json);
@@ -11,6 +11,7 @@
1111
// const organization = Convert.toOrganization(json);
1212
// const portfolio = Convert.toPortfolio(json);
1313
// const position = Convert.toPosition(json);
14+
// const nothing = Convert.toNothing(json);
1415
//
1516
// These functions will throw an error if the JSON doesn't
1617
// match the expected interface, even if the JSON is valid.
@@ -102,6 +103,10 @@ export interface Position {
102103
name?: string;
103104
}
104105

106+
export interface Nothing {
107+
type: string;
108+
}
109+
105110
// Converts JSON strings to/from your types
106111
// and asserts the results of JSON.parse at runtime
107112
export class Convert {
@@ -176,6 +181,14 @@ export class Convert {
176181
public static positionToJson(value: Position): string {
177182
return JSON.stringify(uncast(value, r('Position')), null, 2);
178183
}
184+
185+
public static toNothing(json: string): Nothing {
186+
return cast(JSON.parse(json), r('Nothing'));
187+
}
188+
189+
public static nothingToJson(value: Nothing): string {
190+
return JSON.stringify(uncast(value, r('Nothing')), null, 2);
191+
}
179192
}
180193

181194
function invalidValue(typ: any, val: any, key: any = ''): never {
@@ -427,4 +440,5 @@ const typeMap: any = {
427440
],
428441
'any'
429442
),
443+
Nothing: o([{ json: 'type', js: 'type', typ: '' }], 'any'),
430444
};

src/context/schemas.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@
77
"Country": ["https://fdc3.finos.org/schemas/next/country.schema.json"],
88
"Organization": ["https://fdc3.finos.org/schemas/next/organization.schema.json"],
99
"Portfolio": ["https://fdc3.finos.org/schemas/next/portfolio.schema.json"],
10-
"Position": ["https://fdc3.finos.org/schemas/next/position.schema.json"]
10+
"Position": ["https://fdc3.finos.org/schemas/next/position.schema.json"],
11+
"Nothing": ["https://fdc3.finos.org/schemas/next/nothing.schema.json"]
1112
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://fdc3.finos.org/schemas/next/nothing.schema.json",
4+
"type": "object",
5+
"title": "Nothing",
6+
"allOf": [{ "$ref": "context.schema.json#" }],
7+
"properties": {
8+
"type": { "const": "fdc3.nothing" }
9+
}
10+
}

website/sidebars.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@
5757
"context/ref/Organization",
5858
"context/ref/Country",
5959
"context/ref/Position",
60-
"context/ref/Portfolio"
60+
"context/ref/Portfolio",
61+
"context/ref/Nothing"
6162
]
6263
}
6364
],
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json-schema.org/draft-07/schema#",
3+
"$id": "https://fdc3.finos.org/schemas/next/nothing.schema.json",
4+
"type": "object",
5+
"title": "Nothing",
6+
"allOf": [{ "$ref": "context.schema.json#" }],
7+
"properties": {
8+
"type": { "const": "fdc3.nothing" }
9+
}
10+
}

0 commit comments

Comments
 (0)