@glue42/search-api
Version:
Glue42 Search API
154 lines (118 loc) • 6.42 kB
text/typescript
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Glue42Core } from "@glue42/core";
import { Glue42Search } from "../../search";
import { MAIN_CLIENT_METHOD_NAME, MAIN_PROVIDER_METHOD_NAME } from "../shared/constants";
import { CLIENT_TO_PROVIDER_PROTOCOL_OPERATIONS, ProtocolProviderError, ProtocolProviderInfoRequest, ProtocolProviderInfoResponse, ProtocolQueryCancelRequest, ProtocolSearchCompleted, ProtocolSearchRequest, ProtocolSearchResponse, ProtocolSearchResultsBatch, SEARCH_QUERY_STATUSES } from "../shared/protocol";
import { InteropServerProvider, InteropServerQueryIdentification, PublisherQueryResultBatch, SearchCancelRequest } from "../shared/types";
export class GlueController {
constructor(private readonly glue: Glue42Core.GlueCore) {}
public get myAppName(): string | undefined {
return this.glue.interop.instance.applicationName;
}
public get myInteropId(): string {
return this.glue.interop.instance.instance as string;
}
public async registerMainProviderMethod(handler: (args: any, caller: Glue42Core.Interop.Instance) => Promise<any>): Promise<void> {
const mainMethodStatus = this.checkMyMethodExists(MAIN_PROVIDER_METHOD_NAME);
if (mainMethodStatus.exists) {
return;
}
await this.glue.interop.register(MAIN_PROVIDER_METHOD_NAME, handler);
}
public async registerMainClientMethod(handler: (args: any, caller: Glue42Core.Interop.Instance) => Promise<any>): Promise<void> {
const mainMethodStatus = this.checkMyMethodExists(MAIN_CLIENT_METHOD_NAME);
if (mainMethodStatus.exists) {
return;
}
await this.glue.interop.register(MAIN_CLIENT_METHOD_NAME, handler);
}
public async clearMainProviderMethod(): Promise<void> {
// unregister is async, there is a bug in the typings
await this.glue.interop.unregister(MAIN_PROVIDER_METHOD_NAME);
}
public async sendClientResultsBatch(batch: PublisherQueryResultBatch, clientInstanceId: string, queryId: string): Promise<void> {
const interopArguments: ProtocolSearchResultsBatch = {
items: batch.results,
provider: batch.provider,
queryId,
status: SEARCH_QUERY_STATUSES.inProgress
};
await this.glue.interop.invoke<void>(MAIN_CLIENT_METHOD_NAME, interopArguments, { instance: clientInstanceId });
}
public async sendClientQueueCompleted(clientInstanceId: string, queryId: string): Promise<void> {
const interopArguments: ProtocolSearchCompleted = {
items: [],
queryId,
status: SEARCH_QUERY_STATUSES.done
};
await this.glue.interop.invoke<void>(MAIN_CLIENT_METHOD_NAME, interopArguments, { instance: clientInstanceId });
}
public async sendClientErrorMessage(error: string, clientInstanceId: string, queryId: string, provider: Glue42Search.ProviderData): Promise<void> {
const interopArguments: ProtocolProviderError = {
items: [],
provider,
errorMessage: error,
queryId,
status: SEARCH_QUERY_STATUSES.error
};
await this.glue.interop.invoke<void>(MAIN_CLIENT_METHOD_NAME, interopArguments, { instance: clientInstanceId });
}
public async sendQueryRequest(queryConfig: Glue42Search.QueryConfig, instances: InteropServerProvider[]): Promise<InteropServerQueryIdentification[]> {
if (!instances.length) {
return [];
}
const target = instances.map((inst) => ({ instance: inst.interopId }));
const invokeArgs: ProtocolSearchRequest = {
operation: CLIENT_TO_PROVIDER_PROTOCOL_OPERATIONS.search,
apiVersion: "1",
...queryConfig
};
const response = await this.glue.interop.invoke<ProtocolSearchResponse>(MAIN_PROVIDER_METHOD_NAME, invokeArgs, target);
const allReturned = response.all_return_values || [];
return allReturned.map<InteropServerQueryIdentification>((returnValue) => {
return {
interopId: returnValue.executed_by?.instance as string,
queryId: returnValue.returned.id
};
});
}
public async sendQueryCancelRequest(request: SearchCancelRequest, instance: { instance: string }): Promise<void> {
const args: ProtocolQueryCancelRequest = {
operation: CLIENT_TO_PROVIDER_PROTOCOL_OPERATIONS.cancel,
id: request.id
};
await this.glue.interop.invoke(MAIN_PROVIDER_METHOD_NAME, args, instance);
}
public async getAllProvidersInfo(): Promise<InteropServerProvider[]> {
if (this.glue.interop.methods().every((method) => method.name !== MAIN_PROVIDER_METHOD_NAME)) {
return [];
}
const args: ProtocolProviderInfoRequest = {
operation: CLIENT_TO_PROVIDER_PROTOCOL_OPERATIONS.info
};
const response = await this.glue.interop.invoke<ProtocolProviderInfoResponse>(MAIN_PROVIDER_METHOD_NAME, args, "all");
const allReturned = response.all_return_values || [];
return allReturned.map<InteropServerProvider>((returnValue) => {
const isLegacy = typeof returnValue.returned.apiVersion === "undefined";
const info: ProtocolProviderInfoResponse = isLegacy ? {
supportedTypes: returnValue.returned.supportedTypes,
apiVersion: returnValue.returned.apiVersion,
providers: [{
interopId: returnValue.executed_by?.instance as string,
id: returnValue.executed_by?.instance as string,
name: returnValue.executed_by?.instance as string,
appName: response.executed_by?.application,
types: returnValue.returned.supportedTypes.map((t) => ({ name: t }))
}]
} : returnValue.returned;
return {
interopId: returnValue.executed_by?.instance as string,
info
};
});
}
private checkMyMethodExists(methodName: string): { exists: boolean } {
const myMethods = this.glue.interop.methodsForInstance({ instance: this.glue.interop.instance.instance });
return { exists: myMethods.some((method) => method.name === methodName) };
}
}