@interopio/desktop 6.6.1 → 6.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +2 -0
- package/desktop.d.ts +74 -5
- package/dist/desktop.browser.js +239 -84
- package/dist/desktop.browser.js.map +1 -1
- package/dist/desktop.browser.min.js +1 -1
- package/dist/desktop.browser.min.js.map +1 -1
- package/dist/desktop.es.js +239 -84
- package/dist/desktop.es.js.map +1 -1
- package/dist/desktop.umd.js +239 -84
- package/dist/desktop.umd.js.map +1 -1
- package/dist/desktop.umd.min.js +1 -1
- package/dist/desktop.umd.min.js.map +1 -1
- package/package.json +8 -4
package/changelog.md
CHANGED
package/desktop.d.ts
CHANGED
|
@@ -6059,9 +6059,9 @@ export declare namespace IOConnectDesktop {
|
|
|
6059
6059
|
/**
|
|
6060
6060
|
* Updates the context of the current or a specified Channel.
|
|
6061
6061
|
* @param data Data object with which to update the Channel context.
|
|
6062
|
-
* @param
|
|
6062
|
+
* @param options The name of the Channel to update, or an object containing the name of the Channel to update and a flag indicating whether the published data is an FDC3 context. If no options are provided, the current Channel will be updated.
|
|
6063
6063
|
*/
|
|
6064
|
-
publish(data: any,
|
|
6064
|
+
publish(data: any, options?: string | PublishOptions): Promise<void>;
|
|
6065
6065
|
|
|
6066
6066
|
/**
|
|
6067
6067
|
* Sets a specified path within the Channel context to the provided value. If the path doesn't exist, it will be created.
|
|
@@ -6240,6 +6240,21 @@ export declare namespace IOConnectDesktop {
|
|
|
6240
6240
|
data: any;
|
|
6241
6241
|
}
|
|
6242
6242
|
|
|
6243
|
+
/**
|
|
6244
|
+
* Options for updating a Channel context with the `publish()` method.
|
|
6245
|
+
*/
|
|
6246
|
+
export interface PublishOptions {
|
|
6247
|
+
/**
|
|
6248
|
+
* The name of the Channel to update. If not provided, the current Channel will be updated.
|
|
6249
|
+
*/
|
|
6250
|
+
name?: string;
|
|
6251
|
+
|
|
6252
|
+
/**
|
|
6253
|
+
* Flag indicating whether the published data is an FDC3 context. If so, it must contain a required `type` property.
|
|
6254
|
+
*/
|
|
6255
|
+
fdc3?: boolean;
|
|
6256
|
+
}
|
|
6257
|
+
|
|
6243
6258
|
/**
|
|
6244
6259
|
* All restrictions applied to a window for publishing or subscribing to Channels.
|
|
6245
6260
|
*/
|
|
@@ -6404,6 +6419,11 @@ export declare namespace IOConnectDesktop {
|
|
|
6404
6419
|
*/
|
|
6405
6420
|
getIntents(handler: IntentHandler): Promise<GetIntentsResult>;
|
|
6406
6421
|
|
|
6422
|
+
/**
|
|
6423
|
+
* Removes all saved Intent handlers for previously raised Intents.
|
|
6424
|
+
*/
|
|
6425
|
+
clearSavedHandlers(): Promise<void>;
|
|
6426
|
+
|
|
6407
6427
|
/**
|
|
6408
6428
|
* API for controlling the Intents Resolver UI app.
|
|
6409
6429
|
*/
|
|
@@ -6456,6 +6476,11 @@ export declare namespace IOConnectDesktop {
|
|
|
6456
6476
|
*/
|
|
6457
6477
|
handlerFilter?: HandlerFilter;
|
|
6458
6478
|
|
|
6479
|
+
/**
|
|
6480
|
+
* Details about the app instance that opened the Intents Resolver UI.
|
|
6481
|
+
*/
|
|
6482
|
+
caller?: ResolverCaller;
|
|
6483
|
+
|
|
6459
6484
|
/**
|
|
6460
6485
|
* Retrieves the title for the search operation. Available only if the `filterHandlers()` method was used to open the Intents Resolver UI and the `title` property of the `HandlerFilter` object was set.
|
|
6461
6486
|
*/
|
|
@@ -6465,18 +6490,51 @@ export declare namespace IOConnectDesktop {
|
|
|
6465
6490
|
* Notifies when a handler for the current Intent is added. Replays already existing handlers.
|
|
6466
6491
|
* @param callback Callback function for handling the event.
|
|
6467
6492
|
*/
|
|
6468
|
-
onHandlerAdded(callback: (handler: ResolverIntentHandler) => void): UnsubscribeFunction;
|
|
6493
|
+
onHandlerAdded(callback: (handler: ResolverIntentHandler, intent: IntentInfo) => void): UnsubscribeFunction;
|
|
6469
6494
|
|
|
6470
6495
|
/**
|
|
6471
6496
|
* Notifies when a handler for the current Intent is removed.
|
|
6472
6497
|
* @param callback Callback function for handling the event.
|
|
6473
6498
|
*/
|
|
6474
|
-
onHandlerRemoved(callback: (removedHandler: ResolverIntentHandler) => void): UnsubscribeFunction;
|
|
6499
|
+
onHandlerRemoved(callback: (removedHandler: ResolverIntentHandler, intent: IntentInfo) => void): UnsubscribeFunction;
|
|
6475
6500
|
|
|
6476
6501
|
/**
|
|
6477
6502
|
* Sends the chosen Intent handler to the app which raised the Intent.
|
|
6478
6503
|
*/
|
|
6479
|
-
sendResponse(handler: ResolverIntentHandler): Promise<IOConnectDesktop.Interop.InvocationResult | undefined>;
|
|
6504
|
+
sendResponse(handler: ResolverIntentHandler, options?: SendResolverResponseOptions): Promise<IOConnectDesktop.Interop.InvocationResult | undefined>;
|
|
6505
|
+
}
|
|
6506
|
+
|
|
6507
|
+
/**
|
|
6508
|
+
* Describes the app instance that opened the Intents Resolver UI.
|
|
6509
|
+
*/
|
|
6510
|
+
export interface ResolverCaller {
|
|
6511
|
+
/**
|
|
6512
|
+
* ID of the Interop instance of the app that opened the Intents Resolver UI.
|
|
6513
|
+
*/
|
|
6514
|
+
id: string;
|
|
6515
|
+
/**
|
|
6516
|
+
* Name of the app that opened the Intents Resolver UI.
|
|
6517
|
+
*/
|
|
6518
|
+
applicationName?: string;
|
|
6519
|
+
/**
|
|
6520
|
+
* Title of the app that opened the Intents Resolver UI.
|
|
6521
|
+
*/
|
|
6522
|
+
applicationTitle?: string;
|
|
6523
|
+
}
|
|
6524
|
+
|
|
6525
|
+
/**
|
|
6526
|
+
* Options for sending the chosen Intent handler to the app that raised the Intent.
|
|
6527
|
+
*/
|
|
6528
|
+
export interface SendResolverResponseOptions {
|
|
6529
|
+
/**
|
|
6530
|
+
* If `true`, the chosen Intent handler will be saved as a handler for the raised Intent. If the handler is saved, the next time the same Intent is raised, the Intents Resolver UI won't open and the saved handler will be used automatically.
|
|
6531
|
+
* @default false
|
|
6532
|
+
*/
|
|
6533
|
+
saveHandler: boolean;
|
|
6534
|
+
/**
|
|
6535
|
+
* Use this property to supply the name of the Intent when the Intents Resolver UI is opened via the `filterHandlers()` method and you want to save the Intent handler for that Intent. If the Intents Resolver UI is opened via the `raise()` method, it isn't necessary to explicitly provide the Intent name here, as specifying an Intent name is mandatory when using the `raise()` method.
|
|
6536
|
+
*/
|
|
6537
|
+
intent?: string;
|
|
6480
6538
|
}
|
|
6481
6539
|
|
|
6482
6540
|
/**
|
|
@@ -6488,6 +6546,11 @@ export declare namespace IOConnectDesktop {
|
|
|
6488
6546
|
*/
|
|
6489
6547
|
applicationName: string;
|
|
6490
6548
|
|
|
6549
|
+
/**
|
|
6550
|
+
* Title of the Intent handler.
|
|
6551
|
+
*/
|
|
6552
|
+
applicationTitle?: string;
|
|
6553
|
+
|
|
6491
6554
|
/**
|
|
6492
6555
|
* Icon of the Intent handler app.
|
|
6493
6556
|
*/
|
|
@@ -6723,6 +6786,12 @@ export declare namespace IOConnectDesktop {
|
|
|
6723
6786
|
* @default false
|
|
6724
6787
|
*/
|
|
6725
6788
|
readonly waitUserResponseIndefinitely?: boolean;
|
|
6789
|
+
|
|
6790
|
+
/**
|
|
6791
|
+
* If `true`, the previously saved Intent handler for this Intent (if any) will be cleared.
|
|
6792
|
+
* @default false
|
|
6793
|
+
*/
|
|
6794
|
+
readonly clearSavedHandler?: boolean;
|
|
6726
6795
|
}
|
|
6727
6796
|
|
|
6728
6797
|
/**
|
package/dist/desktop.browser.js
CHANGED
|
@@ -2933,7 +2933,7 @@
|
|
|
2933
2933
|
}
|
|
2934
2934
|
};
|
|
2935
2935
|
|
|
2936
|
-
var version$1 = "6.
|
|
2936
|
+
var version$1 = "6.4.0";
|
|
2937
2937
|
|
|
2938
2938
|
function prepareConfig$1 (configuration, ext, glue42gd) {
|
|
2939
2939
|
let nodeStartingContext;
|
|
@@ -17573,6 +17573,9 @@
|
|
|
17573
17573
|
channels.handleRestrictionsChanged(restrictions, targetWindowId);
|
|
17574
17574
|
return;
|
|
17575
17575
|
}
|
|
17576
|
+
if (command === "isFdc3DataWrappingSupported") {
|
|
17577
|
+
return { isSupported: true };
|
|
17578
|
+
}
|
|
17576
17579
|
throw new Error(`unknown command ${command}`);
|
|
17577
17580
|
});
|
|
17578
17581
|
const result = await interop.invoke("T42.Channels.Announce", { swId: windowId, instance: interop.instance.instance });
|
|
@@ -17671,8 +17674,7 @@
|
|
|
17671
17674
|
const contextName = this.createContextName(name);
|
|
17672
17675
|
const contextData = await this.contexts.get(contextName);
|
|
17673
17676
|
if (contextData[LATEST_FDC3_TYPE]) {
|
|
17674
|
-
|
|
17675
|
-
return data;
|
|
17677
|
+
return this.getContextWithFdc3Data(contextData);
|
|
17676
17678
|
}
|
|
17677
17679
|
return contextData;
|
|
17678
17680
|
}
|
|
@@ -17751,6 +17753,21 @@
|
|
|
17751
17753
|
}
|
|
17752
17754
|
return fdc3PropsArr[0].split("_").slice(1).join("_");
|
|
17753
17755
|
}
|
|
17756
|
+
getContextWithFdc3Data(channelContext) {
|
|
17757
|
+
const { latest_fdc3_type, ...rest } = channelContext;
|
|
17758
|
+
const parsedType = latest_fdc3_type.split("&").join(".");
|
|
17759
|
+
const fdc3Context = { type: parsedType, ...rest.data[`fdc3_${latest_fdc3_type}`] };
|
|
17760
|
+
delete rest.data[`fdc3_${latest_fdc3_type}`];
|
|
17761
|
+
const context = {
|
|
17762
|
+
name: channelContext.name,
|
|
17763
|
+
meta: channelContext.meta,
|
|
17764
|
+
data: {
|
|
17765
|
+
...rest.data,
|
|
17766
|
+
fdc3: fdc3Context
|
|
17767
|
+
}
|
|
17768
|
+
};
|
|
17769
|
+
return context;
|
|
17770
|
+
}
|
|
17754
17771
|
}
|
|
17755
17772
|
|
|
17756
17773
|
class ChannelsImpl {
|
|
@@ -17780,17 +17797,7 @@
|
|
|
17780
17797
|
}
|
|
17781
17798
|
const id = Utils.generateId();
|
|
17782
17799
|
this.pendingReplays[id] = true;
|
|
17783
|
-
const
|
|
17784
|
-
const restrictionByChannel = await this.getRestrictionsByChannel(context.name);
|
|
17785
|
-
if (restrictionByChannel.read) {
|
|
17786
|
-
callback(data, context, updaterId);
|
|
17787
|
-
}
|
|
17788
|
-
else {
|
|
17789
|
-
this.onRestrictionsChanged(() => {
|
|
17790
|
-
callback(data, context, updaterId);
|
|
17791
|
-
}, id, context.name);
|
|
17792
|
-
}
|
|
17793
|
-
};
|
|
17800
|
+
const wrappedCallback = this.getWrappedSubscribeCallback(callback, id);
|
|
17794
17801
|
if (this.lastUpdate) {
|
|
17795
17802
|
let lastUpdate = Object.assign({}, this.lastUpdate);
|
|
17796
17803
|
setTimeout(async () => {
|
|
@@ -17798,12 +17805,12 @@
|
|
|
17798
17805
|
if (this.lastUpdate) {
|
|
17799
17806
|
lastUpdate = this.lastUpdate;
|
|
17800
17807
|
}
|
|
17801
|
-
|
|
17808
|
+
wrappedCallback(lastUpdate.context.data, lastUpdate.context, lastUpdate.updaterId);
|
|
17802
17809
|
}
|
|
17803
17810
|
delete this.pendingReplays[id];
|
|
17804
17811
|
}, 0);
|
|
17805
17812
|
}
|
|
17806
|
-
const unsub = this.registry.add(this.subsKey,
|
|
17813
|
+
const unsub = this.registry.add(this.subsKey, wrappedCallback);
|
|
17807
17814
|
return () => {
|
|
17808
17815
|
this.pendingReplays[id] = false;
|
|
17809
17816
|
this.pendingRestrictionCallbacks.delete(id);
|
|
@@ -17818,46 +17825,35 @@
|
|
|
17818
17825
|
throw new Error("Please provide the callback as a function!");
|
|
17819
17826
|
}
|
|
17820
17827
|
const id = Utils.generateId();
|
|
17821
|
-
const
|
|
17822
|
-
|
|
17823
|
-
if (restrictionByChannel.read) {
|
|
17824
|
-
callback(data, context, updaterId);
|
|
17825
|
-
}
|
|
17826
|
-
else {
|
|
17827
|
-
this.onRestrictionsChanged(() => {
|
|
17828
|
-
callback(data, context, updaterId);
|
|
17829
|
-
}, id, context.name);
|
|
17830
|
-
}
|
|
17831
|
-
};
|
|
17832
|
-
const unsub = await this.shared.subscribeFor(name, callbackWithPermissionCheck);
|
|
17828
|
+
const wrappedCallback = this.getWrappedSubscribeCallback(callback, id);
|
|
17829
|
+
const unsub = await this.shared.subscribeFor(name, wrappedCallback);
|
|
17833
17830
|
return () => {
|
|
17834
17831
|
this.pendingRestrictionCallbacks.delete(id);
|
|
17835
17832
|
unsub();
|
|
17836
17833
|
};
|
|
17837
17834
|
}
|
|
17838
|
-
async publish(data,
|
|
17835
|
+
async publish(data, options) {
|
|
17839
17836
|
if (typeof data !== "object") {
|
|
17840
17837
|
throw new Error("Please provide the data as an object!");
|
|
17841
17838
|
}
|
|
17842
|
-
if (
|
|
17843
|
-
|
|
17844
|
-
throw new Error("Please provide the name as a string!");
|
|
17845
|
-
}
|
|
17846
|
-
if (!this.shared.isChannel(name)) {
|
|
17847
|
-
return Promise.reject(new Error(`A channel with name: ${name} doesn't exist!`));
|
|
17848
|
-
}
|
|
17849
|
-
if (!(await this.getRestrictionsByChannel(name)).write) {
|
|
17850
|
-
throw new Error(`Window does not have permission to write to channel ${name}`);
|
|
17851
|
-
}
|
|
17852
|
-
return this.shared.updateData(name, data);
|
|
17839
|
+
if (options) {
|
|
17840
|
+
this.validatePublishOptions(options);
|
|
17853
17841
|
}
|
|
17854
|
-
if (
|
|
17842
|
+
if (typeof options === "object") {
|
|
17843
|
+
return this.publishWithOptions(data, options);
|
|
17844
|
+
}
|
|
17845
|
+
const channelName = typeof options === "string" ? options : this.currentContext;
|
|
17846
|
+
if (!channelName) {
|
|
17855
17847
|
throw new Error("Not joined to any channel!");
|
|
17856
17848
|
}
|
|
17857
|
-
if (!
|
|
17849
|
+
if (!this.shared.isChannel(channelName)) {
|
|
17850
|
+
return Promise.reject(new Error(`A channel with name: ${channelName} doesn't exist!`));
|
|
17851
|
+
}
|
|
17852
|
+
const canPublish = (await this.getRestrictionsByChannel(channelName)).write;
|
|
17853
|
+
if (!canPublish) {
|
|
17858
17854
|
throw new Error(`Window does not have permission to write to channel ${this.currentContext}`);
|
|
17859
17855
|
}
|
|
17860
|
-
return this.shared.updateData(
|
|
17856
|
+
return this.shared.updateData(channelName, data);
|
|
17861
17857
|
}
|
|
17862
17858
|
async setPaths(paths, name) {
|
|
17863
17859
|
if (name) {
|
|
@@ -18161,6 +18157,82 @@
|
|
|
18161
18157
|
throw new Error(`path property is not a valid string from the Path Value argument: ${JSON.stringify(path)}`);
|
|
18162
18158
|
}
|
|
18163
18159
|
}
|
|
18160
|
+
validatePublishOptions(options) {
|
|
18161
|
+
if ((typeof options !== "string" && typeof options !== "object") || Array.isArray(options)) {
|
|
18162
|
+
throw new Error("Provide options as a string or an object");
|
|
18163
|
+
}
|
|
18164
|
+
if (typeof options === "object") {
|
|
18165
|
+
this.validatePublishOptionsObject(options);
|
|
18166
|
+
return;
|
|
18167
|
+
}
|
|
18168
|
+
if (options === "string" && !options.length) {
|
|
18169
|
+
throw new Error("Provide options as a non-empty string");
|
|
18170
|
+
}
|
|
18171
|
+
}
|
|
18172
|
+
validatePublishOptionsObject(options) {
|
|
18173
|
+
if (typeof options !== "object" || Array.isArray(options)) {
|
|
18174
|
+
throw new Error("Provide options as an object");
|
|
18175
|
+
}
|
|
18176
|
+
if (options.name && (typeof options.name !== "string" || !options.name.length)) {
|
|
18177
|
+
throw new Error("Provide options.name as a non-empty string");
|
|
18178
|
+
}
|
|
18179
|
+
if (Object.keys(options).includes("fdc3") && typeof options.fdc3 !== "boolean") {
|
|
18180
|
+
throw new Error("Provide options.fdc3 as a boolean");
|
|
18181
|
+
}
|
|
18182
|
+
}
|
|
18183
|
+
async publishWithOptions(data, options) {
|
|
18184
|
+
const channelName = options.name || this.currentContext;
|
|
18185
|
+
if (!this.shared.isChannel(channelName)) {
|
|
18186
|
+
throw new Error(`A channel with name: ${options.name} doesn't exist!`);
|
|
18187
|
+
}
|
|
18188
|
+
if (!channelName) {
|
|
18189
|
+
throw new Error("Cannot publish to channel, because not joined to a channel!");
|
|
18190
|
+
}
|
|
18191
|
+
const canPublish = (await this.getRestrictionsByChannel(channelName)).write;
|
|
18192
|
+
if (!canPublish) {
|
|
18193
|
+
throw new Error(`Window does not have permission to write to channel ${this.currentContext}`);
|
|
18194
|
+
}
|
|
18195
|
+
if (!options.fdc3) {
|
|
18196
|
+
return this.shared.updateData(channelName, data);
|
|
18197
|
+
}
|
|
18198
|
+
return this.publishFdc3Data(channelName, data);
|
|
18199
|
+
}
|
|
18200
|
+
async publishFdc3Data(channelName, data) {
|
|
18201
|
+
var _a;
|
|
18202
|
+
if (typeof data.type !== "string" || !((_a = data.type) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
18203
|
+
throw new Error("Expected a valid FDC3 Context with compulsory 'type' field");
|
|
18204
|
+
}
|
|
18205
|
+
const { type, ...rest } = data;
|
|
18206
|
+
const parsedType = type.split(".").join("&");
|
|
18207
|
+
const fdc3DataToPublish = { [`fdc3_${parsedType}`]: rest };
|
|
18208
|
+
return this.shared.updateData(channelName, fdc3DataToPublish);
|
|
18209
|
+
}
|
|
18210
|
+
getWrappedSubscribeCallback(callback, id) {
|
|
18211
|
+
const wrappedCallback = async (_, context, updaterId) => {
|
|
18212
|
+
const restrictionByChannel = await this.getRestrictionsByChannel(context.name);
|
|
18213
|
+
const channelData = this.getDataWithFdc3Encoding(context);
|
|
18214
|
+
if (restrictionByChannel.read) {
|
|
18215
|
+
callback(channelData, context, updaterId);
|
|
18216
|
+
}
|
|
18217
|
+
else {
|
|
18218
|
+
this.onRestrictionsChanged(() => {
|
|
18219
|
+
callback(channelData, context, updaterId);
|
|
18220
|
+
}, id, context.name);
|
|
18221
|
+
}
|
|
18222
|
+
};
|
|
18223
|
+
return wrappedCallback;
|
|
18224
|
+
}
|
|
18225
|
+
getDataWithFdc3Encoding(context) {
|
|
18226
|
+
const { data, latest_fdc3_type } = context;
|
|
18227
|
+
if (!latest_fdc3_type) {
|
|
18228
|
+
return data;
|
|
18229
|
+
}
|
|
18230
|
+
const parsedType = latest_fdc3_type.split("&").join(".");
|
|
18231
|
+
const latestTypePropName = `fdc3_${latest_fdc3_type}`;
|
|
18232
|
+
const fdc3Data = { type: parsedType, ...data[latestTypePropName] };
|
|
18233
|
+
const { [latestTypePropName]: latestFDC3Type, ...rest } = data;
|
|
18234
|
+
return { ...rest, fdc3: fdc3Data };
|
|
18235
|
+
}
|
|
18164
18236
|
}
|
|
18165
18237
|
|
|
18166
18238
|
function factory$4(contexts, agm, getWindows, logger) {
|
|
@@ -19129,6 +19201,7 @@
|
|
|
19129
19201
|
const DEFAULT_RESOLVER_RESPONSE_TIMEOUT = 60 * 1000;
|
|
19130
19202
|
const INTENT_HANDLER_DEFAULT_PROPS = ["applicationName", "type"];
|
|
19131
19203
|
const INTENTS_RESOLVER_APP_NAME = "intentsResolver";
|
|
19204
|
+
const MAX_SET_TIMEOUT_DELAY = 2147483647;
|
|
19132
19205
|
const DEFAULT_METHOD_RESPONSE_TIMEOUT_MS = 60 * 1000;
|
|
19133
19206
|
const DEFAULT_RAISE_TIMEOUT_MS = 90 * 1000;
|
|
19134
19207
|
const DEFAULT_PICK_HANDLER_BY_TIMEOUT_MS = 90 * 1000;
|
|
@@ -19192,28 +19265,6 @@
|
|
|
19192
19265
|
}
|
|
19193
19266
|
return { isValid: true, ok: handler };
|
|
19194
19267
|
};
|
|
19195
|
-
const validateRaiseIntentsResolverResponse = (responseObj) => {
|
|
19196
|
-
const invalidKey = Object.keys(responseObj).some((key) => key !== "intent" && key !== "handler");
|
|
19197
|
-
if (invalidKey) {
|
|
19198
|
-
return { isValid: false, error: "Response is not a valid object. Expected { intent: string, handler: IntentHandler }" };
|
|
19199
|
-
}
|
|
19200
|
-
if (typeof responseObj.intent !== "string") {
|
|
19201
|
-
return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` };
|
|
19202
|
-
}
|
|
19203
|
-
const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler);
|
|
19204
|
-
return isValid
|
|
19205
|
-
? { isValid: true, ok: { intent: responseObj.intent, handler: responseObj.handler } }
|
|
19206
|
-
: { isValid: false, error };
|
|
19207
|
-
};
|
|
19208
|
-
const validateFilterHandlersResolverResponse = (responseObj) => {
|
|
19209
|
-
if (!responseObj.handler) {
|
|
19210
|
-
return { isValid: false, error: "Response is not a valid object. Expected { handler: IntentHandler }" };
|
|
19211
|
-
}
|
|
19212
|
-
const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler);
|
|
19213
|
-
return isValid
|
|
19214
|
-
? { isValid: true, ok: { handler: responseObj.handler } }
|
|
19215
|
-
: { isValid: false, error };
|
|
19216
|
-
};
|
|
19217
19268
|
const validateIntentRequestTarget = (target) => {
|
|
19218
19269
|
if (!target) {
|
|
19219
19270
|
return;
|
|
@@ -19300,14 +19351,27 @@
|
|
|
19300
19351
|
throw new Error(errorMsg);
|
|
19301
19352
|
}
|
|
19302
19353
|
};
|
|
19303
|
-
const
|
|
19304
|
-
|
|
19354
|
+
const validateResolverResponse = (responseObj) => {
|
|
19355
|
+
var _a, _b;
|
|
19356
|
+
if (typeof responseObj.intent !== "string") {
|
|
19357
|
+
return { isValid: false, error: `Response object has invalid 'intent' key. Expected a string, got ${typeof responseObj.intent}` };
|
|
19358
|
+
}
|
|
19359
|
+
if (((_a = responseObj.userSettings) === null || _a === void 0 ? void 0 : _a.preserveChoice) && typeof ((_b = responseObj.userSettings) === null || _b === void 0 ? void 0 : _b.preserveChoice) !== "boolean") {
|
|
19360
|
+
return { isValid: false, error: `Response object has invalid 'userSettings.preserveChoice' key. Expected a boolean, got ${typeof responseObj.userSettings.preserveChoice}` };
|
|
19361
|
+
}
|
|
19362
|
+
const { isValid, error } = validateIntentHandlerAsResponse(responseObj.handler);
|
|
19363
|
+
return isValid
|
|
19364
|
+
? { isValid: true, ok: responseObj }
|
|
19365
|
+
: { isValid, error };
|
|
19305
19366
|
};
|
|
19306
19367
|
const validateIntentRequest = (request) => {
|
|
19307
19368
|
validateIntentRequestContext(request.context);
|
|
19308
19369
|
validateIntentRequestTarget(request.target);
|
|
19309
19370
|
validateIntentRequestTimeout(request.timeout);
|
|
19310
19371
|
validateWaitUserResponseIndefinitely(request.waitUserResponseIndefinitely);
|
|
19372
|
+
if (typeof request.clearSavedHandler !== "undefined" && typeof request.clearSavedHandler !== "boolean") {
|
|
19373
|
+
throw new Error("Please provide 'clearSavedHandler' as a boolean");
|
|
19374
|
+
}
|
|
19311
19375
|
if (request.handlers) {
|
|
19312
19376
|
request.handlers.forEach((handler) => validateIntentRequestHandler(handler));
|
|
19313
19377
|
}
|
|
@@ -19356,10 +19420,11 @@
|
|
|
19356
19420
|
};
|
|
19357
19421
|
|
|
19358
19422
|
class Intents {
|
|
19359
|
-
constructor(interop, windows, logger, options, appManager) {
|
|
19423
|
+
constructor(interop, windows, logger, options, prefsController, appManager) {
|
|
19360
19424
|
this.interop = interop;
|
|
19361
19425
|
this.windows = windows;
|
|
19362
19426
|
this.logger = logger;
|
|
19427
|
+
this.prefsController = prefsController;
|
|
19363
19428
|
this.appManager = appManager;
|
|
19364
19429
|
this.myIntents = new Set();
|
|
19365
19430
|
this.intentsResolverResponsePromises = {};
|
|
@@ -19401,8 +19466,16 @@
|
|
|
19401
19466
|
}
|
|
19402
19467
|
validateIntentRequest(intentRequest);
|
|
19403
19468
|
await Promise.all(this.unregisterIntentPromises);
|
|
19404
|
-
|
|
19469
|
+
if (intentRequest.clearSavedHandler) {
|
|
19470
|
+
this.logger.trace(`User removes saved handler for intent ${intentRequest.intent}`);
|
|
19471
|
+
await this.removeRememberedHandler(intentRequest.intent);
|
|
19472
|
+
}
|
|
19405
19473
|
const resolverInstance = {};
|
|
19474
|
+
const timeout = intentRequest.waitUserResponseIndefinitely ? MAX_SET_TIMEOUT_DELAY : intentRequest.timeout || DEFAULT_RAISE_TIMEOUT_MS;
|
|
19475
|
+
const resultFromRememberedHandler = await this.checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout);
|
|
19476
|
+
if (resultFromRememberedHandler) {
|
|
19477
|
+
return resultFromRememberedHandler;
|
|
19478
|
+
}
|
|
19406
19479
|
const coreRaiseIntentFn = this.coreRaiseIntent.bind(this, { request: intentRequest, resolverInstance, timeout });
|
|
19407
19480
|
if (intentRequest.waitUserResponseIndefinitely) {
|
|
19408
19481
|
return coreRaiseIntentFn();
|
|
@@ -19603,6 +19676,10 @@
|
|
|
19603
19676
|
this.logger.trace(`Returning intents for handler ${JSON.stringify(handler)}`);
|
|
19604
19677
|
return { intents: intentsWithInfo };
|
|
19605
19678
|
}
|
|
19679
|
+
async clearSavedHandlers() {
|
|
19680
|
+
this.logger.trace("Removing all saved handlers from prefs storage for current app");
|
|
19681
|
+
await this.prefsController.update({ intents: undefined });
|
|
19682
|
+
}
|
|
19606
19683
|
filterHandlersBy(intents, filter) {
|
|
19607
19684
|
const filteredIntentsWithHandlers = intents.filter((intent) => {
|
|
19608
19685
|
if (filter.intent && filter.intent !== intent.name) {
|
|
@@ -19704,7 +19781,7 @@
|
|
|
19704
19781
|
async startResolverApp({ request, method, resolverInstance }) {
|
|
19705
19782
|
var _a, _b, _c, _d;
|
|
19706
19783
|
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intents Resolver UI with app name ${this.intentsResolverAppName} will be used for request: ${JSON.stringify(request)}`);
|
|
19707
|
-
const responseMethodName = await this.registerIntentResolverMethod(
|
|
19784
|
+
const responseMethodName = await this.registerIntentResolverMethod();
|
|
19708
19785
|
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Registered interop method ${responseMethodName}`);
|
|
19709
19786
|
const startContext = this.buildStartContext(method, request, responseMethodName);
|
|
19710
19787
|
const startOptions = await this.buildStartOptions();
|
|
@@ -19723,7 +19800,7 @@
|
|
|
19723
19800
|
? `for intent ${request.intent}`
|
|
19724
19801
|
: `for '${method}' method with filter ${JSON.stringify(request)}`}`
|
|
19725
19802
|
});
|
|
19726
|
-
const handler = await this.handleInstanceResponse(instance.id, method);
|
|
19803
|
+
const handler = await this.handleInstanceResponse({ instanceId: instance.id, caller: startContext.initialCaller, method, request });
|
|
19727
19804
|
return handler;
|
|
19728
19805
|
}
|
|
19729
19806
|
async windowsIdToTitle(id, windowsInfos) {
|
|
@@ -19735,13 +19812,24 @@
|
|
|
19735
19812
|
const title = await (window === null || window === void 0 ? void 0 : window.getTitle());
|
|
19736
19813
|
return title;
|
|
19737
19814
|
}
|
|
19738
|
-
async handleInstanceResponse(instanceId, method) {
|
|
19739
|
-
var _a, _b;
|
|
19815
|
+
async handleInstanceResponse({ instanceId, method, request, caller }) {
|
|
19816
|
+
var _a, _b, _c;
|
|
19740
19817
|
try {
|
|
19741
19818
|
const response = await this.intentsResolverResponsePromises[instanceId].promise;
|
|
19742
|
-
|
|
19819
|
+
const subMessage = method === "raise" ? `for intent ${response.intent} ` : "";
|
|
19820
|
+
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.trace(`Intent handler chosen ${subMessage}: ${JSON.stringify(response.handler)}. Stopping resolver instance with id ${instanceId}`);
|
|
19743
19821
|
this.stopResolverInstance(instanceId);
|
|
19744
19822
|
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.trace(`Instance with id ${instanceId} successfully stopped`);
|
|
19823
|
+
if ((_c = response.userSettings) === null || _c === void 0 ? void 0 : _c.preserveChoice) {
|
|
19824
|
+
await this.saveUserChoice({
|
|
19825
|
+
intent: response.intent,
|
|
19826
|
+
handler: response.handler,
|
|
19827
|
+
filter: method === "filterHandlers"
|
|
19828
|
+
? { applicationNames: request.applicationNames, contextTypes: request.contextTypes, resultType: request.resultType }
|
|
19829
|
+
: undefined,
|
|
19830
|
+
caller
|
|
19831
|
+
});
|
|
19832
|
+
}
|
|
19745
19833
|
return response.handler;
|
|
19746
19834
|
}
|
|
19747
19835
|
catch (error) {
|
|
@@ -19749,14 +19837,14 @@
|
|
|
19749
19837
|
throw new Error(error);
|
|
19750
19838
|
}
|
|
19751
19839
|
}
|
|
19752
|
-
async registerIntentResolverMethod(
|
|
19840
|
+
async registerIntentResolverMethod() {
|
|
19753
19841
|
const methodName = INTENTS_RESOLVER_INTEROP_PREFIX + Utils.generateId();
|
|
19754
|
-
await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId
|
|
19842
|
+
await this.interop.register(methodName, (args, callerId) => this.resolverResponseHandler(args, callerId));
|
|
19755
19843
|
return methodName;
|
|
19756
19844
|
}
|
|
19757
|
-
resolverResponseHandler(args, callerId
|
|
19845
|
+
resolverResponseHandler(args, callerId) {
|
|
19758
19846
|
const { instance } = callerId;
|
|
19759
|
-
const isValid =
|
|
19847
|
+
const isValid = validateResolverResponse(args);
|
|
19760
19848
|
if (!isValid) {
|
|
19761
19849
|
this.logger.trace(`Intent Resolver instance with id ${callerId.instance} sent invalid response. Error: ${isValid.error}`);
|
|
19762
19850
|
this.intentsResolverResponsePromises[instance].reject(isValid.error);
|
|
@@ -19768,7 +19856,15 @@
|
|
|
19768
19856
|
this.cleanUpIntentResolverPromise(instance);
|
|
19769
19857
|
}
|
|
19770
19858
|
buildStartContext(method, request, methodName) {
|
|
19771
|
-
|
|
19859
|
+
var _a;
|
|
19860
|
+
const myAppName = this.interop.instance.application || this.interop.instance.applicationName;
|
|
19861
|
+
const myAppTitle = ((_a = this.appManager.application(myAppName)) === null || _a === void 0 ? void 0 : _a.title) || "";
|
|
19862
|
+
const baseStartContext = {
|
|
19863
|
+
callerId: this.interop.instance.instance,
|
|
19864
|
+
methodName,
|
|
19865
|
+
initialCaller: { id: this.interop.instance.instance, applicationName: myAppName, applicationTitle: myAppTitle },
|
|
19866
|
+
resolverApi: "1.0"
|
|
19867
|
+
};
|
|
19772
19868
|
return method === "raise"
|
|
19773
19869
|
? { ...baseStartContext, intent: request }
|
|
19774
19870
|
: { ...baseStartContext, handlerFilter: request };
|
|
@@ -19956,6 +20052,64 @@
|
|
|
19956
20052
|
}, []);
|
|
19957
20053
|
return intentsWithInfo;
|
|
19958
20054
|
}
|
|
20055
|
+
async removeRememberedHandler(intentName) {
|
|
20056
|
+
var _a;
|
|
20057
|
+
this.logger.trace(`Removing saved handler from prefs storage for intent ${intentName}`);
|
|
20058
|
+
const prefs = await this.prefsController.get();
|
|
20059
|
+
const intentPrefs = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents;
|
|
20060
|
+
if (!intentPrefs) {
|
|
20061
|
+
this.logger.trace("No app prefs found for current app");
|
|
20062
|
+
return;
|
|
20063
|
+
}
|
|
20064
|
+
delete intentPrefs[intentName];
|
|
20065
|
+
const updatedPrefs = {
|
|
20066
|
+
...prefs.data,
|
|
20067
|
+
intents: intentPrefs
|
|
20068
|
+
};
|
|
20069
|
+
await this.prefsController.update(updatedPrefs);
|
|
20070
|
+
this.logger.trace(`Handler saved choice for intent ${intentName} removed successfully`);
|
|
20071
|
+
}
|
|
20072
|
+
async checkForRememberedHandler(intentRequest) {
|
|
20073
|
+
var _a, _b;
|
|
20074
|
+
const prefs = await this.prefsController.get();
|
|
20075
|
+
const prefsForIntent = (_b = (_a = prefs.data) === null || _a === void 0 ? void 0 : _a.intents) === null || _b === void 0 ? void 0 : _b[intentRequest.intent];
|
|
20076
|
+
return prefsForIntent === null || prefsForIntent === void 0 ? void 0 : prefsForIntent.handler;
|
|
20077
|
+
}
|
|
20078
|
+
async checkHandleRaiseWithRememberedHandler(intentRequest, resolverInstance, timeout) {
|
|
20079
|
+
const rememberedHandler = await this.checkForRememberedHandler(intentRequest);
|
|
20080
|
+
if (!rememberedHandler) {
|
|
20081
|
+
return;
|
|
20082
|
+
}
|
|
20083
|
+
const request = {
|
|
20084
|
+
...intentRequest,
|
|
20085
|
+
target: {
|
|
20086
|
+
app: rememberedHandler.applicationName,
|
|
20087
|
+
instance: rememberedHandler.instanceId
|
|
20088
|
+
}
|
|
20089
|
+
};
|
|
20090
|
+
try {
|
|
20091
|
+
const response = await this.coreRaiseIntent({ request, resolverInstance, timeout });
|
|
20092
|
+
return response;
|
|
20093
|
+
}
|
|
20094
|
+
catch (error) {
|
|
20095
|
+
this.logger.trace("Could not raise intent to remembered handler. Removing it from Prefs store");
|
|
20096
|
+
await this.removeRememberedHandler(intentRequest.intent);
|
|
20097
|
+
}
|
|
20098
|
+
}
|
|
20099
|
+
async saveUserChoice({ intent, handler, filter, caller }) {
|
|
20100
|
+
var _a, _b;
|
|
20101
|
+
const prevPrefs = await this.prefsController.get(caller.applicationName);
|
|
20102
|
+
const prevIntentsPrefs = ((_a = prevPrefs === null || prevPrefs === void 0 ? void 0 : prevPrefs.data) === null || _a === void 0 ? void 0 : _a.intents) || {};
|
|
20103
|
+
const prefsToUpdate = {
|
|
20104
|
+
...prevPrefs.data,
|
|
20105
|
+
intents: {
|
|
20106
|
+
...prevIntentsPrefs,
|
|
20107
|
+
[intent]: { handler, filter }
|
|
20108
|
+
}
|
|
20109
|
+
};
|
|
20110
|
+
await this.prefsController.update(prefsToUpdate, { app: caller.applicationName });
|
|
20111
|
+
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Saved user's choice of handler for '${caller.applicationName}' app`);
|
|
20112
|
+
}
|
|
19959
20113
|
}
|
|
19960
20114
|
|
|
19961
20115
|
class FactoryCallInfo {
|
|
@@ -20202,6 +20356,7 @@
|
|
|
20202
20356
|
let _windows;
|
|
20203
20357
|
let _displays;
|
|
20204
20358
|
let _channels;
|
|
20359
|
+
let _prefs;
|
|
20205
20360
|
const _browserEventsDispatcher = new EventsDispatcher(glueConfig);
|
|
20206
20361
|
function createWindows(core) {
|
|
20207
20362
|
if (glueConfig.windows) {
|
|
@@ -20298,7 +20453,7 @@
|
|
|
20298
20453
|
return hotkeysAPI;
|
|
20299
20454
|
}
|
|
20300
20455
|
function createIntents(core) {
|
|
20301
|
-
const intentsAPI = new Intents(core.agm, _windows, core.logger.subLogger("intents"), options, _appManager);
|
|
20456
|
+
const intentsAPI = new Intents(core.agm, _windows, core.logger.subLogger("intents"), options, _prefs, _appManager);
|
|
20302
20457
|
debugLog(intentsAPI);
|
|
20303
20458
|
return intentsAPI;
|
|
20304
20459
|
}
|
|
@@ -20326,9 +20481,9 @@
|
|
|
20326
20481
|
function createPrefs(core) {
|
|
20327
20482
|
var _a, _b;
|
|
20328
20483
|
const appName = (_b = (_a = options.application) !== null && _a !== void 0 ? _a : glue42gd === null || glue42gd === void 0 ? void 0 : glue42gd.applicationName) !== null && _b !== void 0 ? _b : core.interop.instance.application;
|
|
20329
|
-
|
|
20330
|
-
debugLog(
|
|
20331
|
-
return
|
|
20484
|
+
_prefs = new Prefs(appName, core.interop);
|
|
20485
|
+
debugLog(_prefs);
|
|
20486
|
+
return _prefs;
|
|
20332
20487
|
}
|
|
20333
20488
|
function createCookies(core) {
|
|
20334
20489
|
const api = factory$1(core.interop, T42GDExecuteMethod);
|
|
@@ -20357,10 +20512,10 @@
|
|
|
20357
20512
|
{ name: "channels", create: createChannels },
|
|
20358
20513
|
{ name: "hotkeys", create: createHotkeys },
|
|
20359
20514
|
{ name: "displays", create: createDisplaysApi },
|
|
20515
|
+
{ name: "prefs", create: createPrefs },
|
|
20360
20516
|
{ name: "intents", create: createIntents },
|
|
20361
20517
|
{ name: "notifications", create: createNotifications },
|
|
20362
20518
|
{ name: "themes", create: createThemes },
|
|
20363
|
-
{ name: "prefs", create: createPrefs },
|
|
20364
20519
|
{ name: "cookies", create: createCookies }
|
|
20365
20520
|
],
|
|
20366
20521
|
version,
|