mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-14 01:25:37 -05:00
91 lines
2.8 KiB
TypeScript
91 lines
2.8 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { Event } from 'vs/base/common/event';
|
|
import { IChannel, IServerChannel } from 'vs/base/parts/ipc/common/ipc';
|
|
|
|
//
|
|
// Use both `SimpleServiceProxyChannel` and `createSimpleChannelProxy`
|
|
// for a very basic process <=> process communication over methods.
|
|
//
|
|
|
|
export type AddContextToFunctions<Target, Context> = {
|
|
// For every property: IF property is a FUNCTION ADD context as first parameter and original parameters afterwards with same return type, otherwise preserve as is
|
|
[K in keyof Target]: Target[K] extends (...args: any) => any ? (context: Context, ...args: Parameters<Target[K]>) => ReturnType<Target[K]> : Target[K]
|
|
};
|
|
|
|
interface ISimpleChannelProxyContext {
|
|
__$simpleIPCContextMarker: boolean;
|
|
proxyContext: unknown;
|
|
}
|
|
|
|
function serializeContext(proxyContext?: unknown): ISimpleChannelProxyContext | undefined {
|
|
if (proxyContext) {
|
|
return { __$simpleIPCContextMarker: true, proxyContext };
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
function deserializeContext(candidate?: ISimpleChannelProxyContext | undefined): unknown | undefined {
|
|
if (candidate && candidate.__$simpleIPCContextMarker === true) {
|
|
return candidate.proxyContext;
|
|
}
|
|
|
|
return undefined;
|
|
}
|
|
|
|
export class SimpleServiceProxyChannel implements IServerChannel {
|
|
|
|
private service: { [key: string]: unknown };
|
|
|
|
constructor(service: unknown) {
|
|
this.service = service as { [key: string]: unknown };
|
|
}
|
|
|
|
listen<T>(_: unknown, event: string): Event<T> {
|
|
throw new Error(`Events are currently unsupported by SimpleServiceProxyChannel: ${event}`);
|
|
}
|
|
|
|
call(_: unknown, command: string, args?: any[]): Promise<any> {
|
|
const target = this.service[command];
|
|
if (typeof target === 'function') {
|
|
if (Array.isArray(args)) {
|
|
const context = deserializeContext(args[0]);
|
|
if (context) {
|
|
args[0] = context;
|
|
}
|
|
}
|
|
|
|
return target.apply(this.service, args);
|
|
}
|
|
|
|
throw new Error(`Method not found: ${command}`);
|
|
}
|
|
}
|
|
|
|
export function createSimpleChannelProxy<T>(channel: IChannel, context?: unknown): T {
|
|
const serializedContext = serializeContext(context);
|
|
|
|
return new Proxy({}, {
|
|
get(_target, propKey, _receiver) {
|
|
if (typeof propKey === 'string') {
|
|
return function (...args: any[]) {
|
|
let methodArgs: any[];
|
|
if (serializedContext) {
|
|
methodArgs = [context, ...args];
|
|
} else {
|
|
methodArgs = args;
|
|
}
|
|
|
|
return channel.call(propKey, methodArgs);
|
|
};
|
|
}
|
|
|
|
throw new Error(`Unable to provide main channel proxy implementation for: ${String(propKey)}`);
|
|
}
|
|
}) as T;
|
|
}
|