diff options
Diffstat (limited to 'ts/device/index.ts')
-rw-r--r-- | ts/device/index.ts | 144 |
1 files changed, 79 insertions, 65 deletions
diff --git a/ts/device/index.ts b/ts/device/index.ts index 325007039..825ffe743 100644 --- a/ts/device/index.ts +++ b/ts/device/index.ts @@ -12,24 +12,24 @@ // License for the specific language governing permissions and limitations under // the License. -import objectPath from 'object-path'; -import {Decoder, Encoder} from 'pigweedjs/pw_hdlc'; +import { setPathOnObject } from './object_set'; +import { Decoder, Encoder } from 'pigweedjs/pw_hdlc'; import { Client, Channel, ServiceClient, UnaryMethodStub, MethodStub, - ServerStreamingMethodStub + ServerStreamingMethodStub, } from 'pigweedjs/pw_rpc'; -import {WebSerialTransport} from '../transport/web_serial_transport'; -import {ProtoCollection} from 'pigweedjs/pw_protobuf_compiler'; +import { WebSerialTransport } from '../transport/web_serial_transport'; +import { ProtoCollection } from 'pigweedjs/pw_protobuf_compiler'; -function protoFieldToMethodName(string) { - return string.split("_").map(titleCase).join(""); +function protoFieldToMethodName(fieldName: string) { + return fieldName.split('_').map(titleCase).join(''); } -function titleCase(string) { - return string.charAt(0).toUpperCase() + string.slice(1); +function titleCase(title: string) { + return title.charAt(0).toUpperCase() + title.slice(1); } export class Device { @@ -40,12 +40,13 @@ export class Device { private rpcAddress: number; private nameToMethodArgumentsMap: any; client: Client; - rpcs: any + rpcs: any; constructor( protoCollection: ProtoCollection, transport: WebSerialTransport = new WebSerialTransport(), - rpcAddress: number = 82) { + rpcAddress = 82, + ) { this.transport = transport; this.rpcAddress = rpcAddress; this.protoCollection = protoCollection; @@ -56,9 +57,9 @@ export class Device { new Channel(1, (bytes) => { const hdlcBytes = this.encoder.uiFrame(this.rpcAddress, bytes); this.transport.sendChunk(hdlcBytes); - })]; - this.client = - Client.fromProtoSet(channels, this.protoCollection); + }), + ]; + this.client = Client.fromProtoSet(channels, this.protoCollection); this.setupRpcs(); } @@ -75,34 +76,39 @@ export class Device { }); } - getMethodArguments(fullPath) { + getMethodArguments(fullPath: string) { return this.nameToMethodArgumentsMap[fullPath]; } private setupRpcs() { - let rpcMap = {}; - let channel = this.client.channel(); - let servicesKeys = Array.from(channel.services.keys()); + const rpcMap = {}; + const channel = this.client.channel()!; + const servicesKeys = Array.from(channel.services.keys()); servicesKeys.forEach((serviceKey) => { - objectPath.set(rpcMap, serviceKey, - this.mapServiceMethods(channel.services.get(serviceKey)) + setPathOnObject( + rpcMap, + serviceKey, + this.mapServiceMethods(channel.services.get(serviceKey)!), ); }); this.rpcs = rpcMap; } private mapServiceMethods(service: ServiceClient) { - let methodMap = {}; - let methodKeys = Array.from(service.methodsByName.keys()); + const methodMap: { [index: string]: any } = {}; + const methodKeys = Array.from(service.methodsByName.keys()); methodKeys - .filter((method: any) => - service.methodsByName.get(method) instanceof UnaryMethodStub - || service.methodsByName.get(method) instanceof ServerStreamingMethodStub) - .forEach(key => { - let fn = this.createMethodWrapper( - service.methodsByName.get(key), + .filter( + (method: any) => + service.methodsByName.get(method) instanceof UnaryMethodStub || + service.methodsByName.get(method) instanceof + ServerStreamingMethodStub, + ) + .forEach((key) => { + const fn = this.createMethodWrapper( + service.methodsByName.get(key)!, key, - `${service.name}.${key}` + `${service.name}.${key}`, ); methodMap[key] = fn; }); @@ -112,47 +118,51 @@ export class Device { private createMethodWrapper( realMethod: MethodStub, methodName: string, - fullMethodPath: string) { + fullMethodPath: string, + ) { if (realMethod instanceof UnaryMethodStub) { return this.createUnaryMethodWrapper( realMethod, methodName, - fullMethodPath); - } - else if (realMethod instanceof ServerStreamingMethodStub) { + fullMethodPath, + ); + } else if (realMethod instanceof ServerStreamingMethodStub) { return this.createServerStreamingMethodWrapper( realMethod, methodName, - fullMethodPath); + fullMethodPath, + ); } + throw new Error(`Unknown method: ${realMethod}`); } private createUnaryMethodWrapper( realMethod: UnaryMethodStub, methodName: string, - fullMethodPath: string) { - const requestType = - realMethod.method.descriptor.getInputType().replace(/^\./, ''); + fullMethodPath: string, + ) { + const requestType = realMethod.method.descriptor + .getInputType() + .replace(/^\./, ''); const requestProtoDescriptor = - this.protoCollection.getDescriptorProto(requestType); - const requestFields = requestProtoDescriptor.getFieldList(); + this.protoCollection.getDescriptorProto(requestType)!; + const requestFields = requestProtoDescriptor.getFieldList()!; const functionArguments = requestFields - .map(field => field.getName()) - .concat( - 'return this(arguments);' - ); + .map((field) => field.getName()) + .concat('return this(arguments);'); // We store field names so REPL can show hints in autocomplete using these. - this.nameToMethodArgumentsMap[fullMethodPath] = requestFields - .map(field => field.getName()); + this.nameToMethodArgumentsMap[fullMethodPath] = requestFields.map((field) => + field.getName(), + ); // We create a new JS function dynamically here that takes // proto message fields as arguments and calls the actual RPC method. - let fn = new Function(...functionArguments).bind((args) => { + const fn = new Function(...functionArguments).bind((args: any[]) => { const request = new realMethod.method.requestType(); requestFields.forEach((field, index) => { request[`set${titleCase(field.getName())}`](args[index]); - }) + }); return realMethod.call(request); }); return fn; @@ -161,36 +171,40 @@ export class Device { private createServerStreamingMethodWrapper( realMethod: ServerStreamingMethodStub, methodName: string, - fullMethodPath: string) { - const requestType = realMethod.method.descriptor.getInputType().replace(/^\./, ''); + fullMethodPath: string, + ) { + const requestType = realMethod.method.descriptor + .getInputType() + .replace(/^\./, ''); const requestProtoDescriptor = - this.protoCollection.getDescriptorProto(requestType); + this.protoCollection.getDescriptorProto(requestType)!; const requestFields = requestProtoDescriptor.getFieldList(); const functionArguments = requestFields - .map(field => field.getName()) - .concat( - [ - 'onNext', - 'onComplete', - 'onError', - 'return this(arguments);' - ] - ); + .map((field) => field.getName()) + .concat(['onNext', 'onComplete', 'onError', 'return this(arguments);']); // We store field names so REPL can show hints in autocomplete using these. - this.nameToMethodArgumentsMap[fullMethodPath] = requestFields - .map(field => field.getName()); + this.nameToMethodArgumentsMap[fullMethodPath] = requestFields.map((field) => + field.getName(), + ); // We create a new JS function dynamically here that takes // proto message fields as arguments and calls the actual RPC method. - let fn = new Function(...functionArguments).bind((args) => { + const fn = new Function(...functionArguments).bind((args: any[]) => { const request = new realMethod.method.requestType(); requestFields.forEach((field, index) => { request[`set${protoFieldToMethodName(field.getName())}`](args[index]); - }) + }); const callbacks = Array.from(args).slice(requestFields.length); - // @ts-ignore - return realMethod.invoke(request, callbacks[0], callbacks[1], callbacks[2]); + return realMethod.invoke( + request, + // @ts-ignore + callbacks[0], + // @ts-ignore + callbacks[1], + // @ts-ignore + callbacks[2], + ); }); return fn; } |