aboutsummaryrefslogtreecommitdiff
path: root/ts/device/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'ts/device/index.ts')
-rw-r--r--ts/device/index.ts144
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;
}