Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@viamrobotics/rpc

Package Overview
Dependencies
Maintainers
1
Versions
47
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@viamrobotics/rpc - npm Package Compare versions

Comparing version 0.1.6 to 0.1.7

3

package.json
{
"name": "@viamrobotics/rpc",
"version": "0.1.6",
"version": "0.1.7",
"license": "MIT",

@@ -10,2 +10,3 @@ "dependencies": {

"devDependencies": {
"set-value": ">=4.0.1",
"@types/google-protobuf": "^3.7.4",

@@ -12,0 +13,0 @@ "ts-loader": "^8.0.14",

@@ -135,8 +135,10 @@ import { grpc } from "@improbable-eng/grpc-web";

let statusCode, statusMessage;
if (trailers.getStatus()) {
statusCode = trailers.getStatus().getCode();
statusMessage = trailers.getStatus().getMessage();
headers.set("grpc-status", trailers.getStatus().getCode());
// this okay?
headers.set("grpc-message", trailers.getStatus().getMessage());
const status = trailers.getStatus();
if (status) {
statusCode = status.getCode();
statusMessage = status.getMessage();
headers.set("grpc-status", `${status.getCode()}`);
if (statusMessage !== undefined) {
headers.set("grpc-message", status.getMessage());
}
} else {

@@ -143,0 +145,0 @@ statusCode = 0;

import { ClientChannel } from "./ClientChannel";
export declare function dial(signalingAddress: string, host: string, rtcConfig?: RTCConfiguration): Promise<ClientChannel>;
interface DialOptions {
disableTrickleICE: boolean;
rtcConfig?: RTCConfiguration;
}
export declare function dial(signalingAddress: string, host: string, opts?: DialOptions): Promise<ClientChannel>;
export {};
import { grpc } from "@improbable-eng/grpc-web";
import { CallRequest, CallResponse } from "proto/rpc/webrtc/v1/signaling_pb";
import { CallRequest, CallResponse, CallUpdateRequest, CallUpdateResponse, ICECandidate } from "proto/rpc/webrtc/v1/signaling_pb";
import { SignalingService } from "proto/rpc/webrtc/v1/signaling_pb_service";
import { ClientChannel } from "./ClientChannel";
import { newPeerConnectionForClient } from "./peer";
import { Code } from "google-rpc/code_pb"
import { Status } from "google-rpc/status_pb"
async function signalCall(signalingAddress: string, host: string, sdp: string): Promise<CallResponse> {
const callRequest = new CallRequest();
callRequest.setSdp(sdp);
let pResolve: (value: CallResponse) => void;
interface DialOptions {
disableTrickleICE: boolean;
rtcConfig?: RTCConfiguration;
}
// TODO(https://github.com/viamrobotics/core/issues/111): figure out decent way to handle reconnect on connection termination
export async function dial(signalingAddress: string, host: string, opts?: DialOptions): Promise<ClientChannel> {
const { pc, dc } = await newPeerConnectionForClient(opts !== undefined && opts.disableTrickleICE, opts?.rtcConfig);
const client = grpc.client(SignalingService.Call, {
host: signalingAddress
})
let uuid = '';
// only send once since exchange may end or ICE may end
let sentDoneOrErrorOnce = false;
const sendError = (err: string) => {
if (sentDoneOrErrorOnce) {
return;
}
sentDoneOrErrorOnce = true;
const callRequestUpdate = new CallUpdateRequest();
callRequestUpdate.setUuid(uuid);
const status = new Status();
status.setCode(Code.UNKNOWN);
status.setMessage(err);
callRequestUpdate.setError(status);
grpc.unary(SignalingService.CallUpdate, {
request: callRequestUpdate,
metadata: {
'rpc-host': host,
},
host: signalingAddress,
onEnd: (output: grpc.UnaryOutput<CallUpdateResponse>) => {
const { status, statusMessage, message } = output;
if (status === grpc.Code.OK && message) {
return;
}
console.error(statusMessage)
}
});
}
const sendDone = () => {
if (sentDoneOrErrorOnce) {
return;
}
sentDoneOrErrorOnce = true;
const callRequestUpdate = new CallUpdateRequest();
callRequestUpdate.setUuid(uuid);
callRequestUpdate.setDone(true);
grpc.unary(SignalingService.CallUpdate, {
request: callRequestUpdate,
metadata: {
'rpc-host': host,
},
host: signalingAddress,
onEnd: (output: grpc.UnaryOutput<CallUpdateResponse>) => {
const { status, statusMessage, message } = output;
if (status === grpc.Code.OK && message) {
return;
}
console.error(statusMessage)
}
});
}
let pResolve: (value: any) => void;
let pReject: (reason?: any) => void;
const result = new Promise<CallResponse>((resolve, reject) => {
let remoteDescSet = new Promise<any>((resolve, reject) => {
pResolve = resolve;
pReject = reject;
})
grpc.unary(SignalingService.Call, {
request: callRequest,
metadata: {
'rpc-host': host,
},
host: signalingAddress,
onEnd: (output: grpc.UnaryOutput<CallResponse>) => {
const { status, statusMessage, message } = output;
if (status === grpc.Code.OK && message) {
pResolve(message);
} else {
pReject(statusMessage);
});
let exchangeDone = false;
if (!opts?.disableTrickleICE) {
// set up offer
const offerDesc = await pc.createOffer();
let iceComplete = false;
pc.onicecandidate = async event => {
await remoteDescSet;
if (exchangeDone) {
return;
}
if (event.candidate === null) {
iceComplete = true;
sendDone();
return;
}
const iProto = iceCandidateToProto(event.candidate);
const callRequestUpdate = new CallUpdateRequest();
callRequestUpdate.setUuid(uuid);
callRequestUpdate.setCandidate(iProto);
grpc.unary(SignalingService.CallUpdate, {
request: callRequestUpdate,
metadata: {
'rpc-host': host,
},
host: signalingAddress,
onEnd: (output: grpc.UnaryOutput<CallUpdateResponse>) => {
const { status, statusMessage, message } = output;
if (status === grpc.Code.OK && message) {
return;
}
if (exchangeDone || iceComplete) {
return;
}
console.error("error sending candidate", statusMessage)
}
});
}
await pc.setLocalDescription(offerDesc);
}
let haveInit = false;
client.onMessage(async (message: CallResponse) => {
if (message.hasInit()) {
if (haveInit) {
sendError("got init stage more than once");
return;
}
const init = message.getInit()!;
haveInit = true;
uuid = message.getUuid();
const remoteSDP = new RTCSessionDescription(JSON.parse(atob(init.getSdp())));
pc.setRemoteDescription(remoteSDP);
pResolve(true);
if (opts?.disableTrickleICE) {
exchangeDone = true;
sendDone();
return;
}
} else if (message.hasUpdate()) {
if (!haveInit) {
sendError("got update stage before init stage");
return;
}
if (message.getUuid() !== uuid) {
sendError(`uuid mismatch; have=${message.getUuid()} want=${uuid}`);
return;
}
const update = message.getUpdate()!;
const cand = iceCandidateFromProto(update.getCandidate()!);
try {
await pc.addIceCandidate(cand);
} catch (e) {
sendError(e);
return;
}
} else {
sendError("unknown CallResponse stage");
return;
}
});
return await result;
}
// TODO(https://github.com/viamrobotics/core/issues/111): figure out decent way to handle reconnect on connection termination
export async function dial(signalingAddress: string, host: string, rtcConfig?: RTCConfiguration): Promise<ClientChannel> {
const { pc, dc } = await newPeerConnectionForClient(rtcConfig);
client.onEnd((status: grpc.Code, statusMessage: string, trailers: grpc.Metadata) => {
if (status === grpc.Code.OK) {
return;
}
console.error(statusMessage);
});
client.start({ 'rpc-host': host })
const callRequest = new CallRequest();
const encodedSDP = btoa(JSON.stringify(pc.localDescription));
const callResponse = await signalCall(signalingAddress, host, encodedSDP);
const remoteSDP = new RTCSessionDescription(JSON.parse(atob(callResponse.getSdp())));
pc.setRemoteDescription(remoteSDP);
callRequest.setSdp(encodedSDP);
if (opts && opts.disableTrickleICE) {
callRequest.setDisableTrickle(opts.disableTrickleICE);
}
client.send(callRequest);
const cc = new ClientChannel(pc, dc);
await cc.ready;
exchangeDone = true;
sendDone();
return cc;
}
function iceCandidateFromProto(i: ICECandidate): RTCIceCandidateInit {
let candidate: RTCIceCandidateInit = {
candidate: i.getCandidate(),
}
if (i.hasSdpMid()) {
candidate.sdpMid = i.getSdpMid();
}
if (i.hasSdpmLineIndex()) {
candidate.sdpMLineIndex = i.getSdpmLineIndex();
}
if (i.hasUsernameFragment()) {
candidate.usernameFragment = i.getUsernameFragment();
}
return candidate;
}
function iceCandidateToProto(i: RTCIceCandidateInit): ICECandidate {
let candidate = new ICECandidate();
candidate.setCandidate(i.candidate!);
if (i.sdpMid) {
candidate.setSdpMid(i.sdpMid);
}
if (i.sdpMLineIndex) {
candidate.setSdpmLineIndex(i.sdpMLineIndex);
}
if (i.usernameFragment) {
candidate.setUsernameFragment(i.usernameFragment);
}
return candidate;
}

@@ -5,3 +5,3 @@ interface ReadyPeer {

}
export declare function newPeerConnectionForClient(rtcConfig?: RTCConfiguration): Promise<ReadyPeer>;
export declare function newPeerConnectionForClient(disableTrickle: boolean, rtcConfig?: RTCConfiguration): Promise<ReadyPeer>;
export {};

@@ -6,3 +6,3 @@ interface ReadyPeer {

export async function newPeerConnectionForClient(rtcConfig?: RTCConfiguration): Promise<ReadyPeer> {
export async function newPeerConnectionForClient(disableTrickle: boolean, rtcConfig?: RTCConfiguration): Promise<ReadyPeer> {
if (!rtcConfig) {

@@ -30,2 +30,13 @@ rtcConfig = {

if (!disableTrickle) {
return Promise.resolve({ pc: peerConnection, dc: dataChannel })
}
// set up offer
const offerDesc = await peerConnection.createOffer();
try {
await peerConnection.setLocalDescription(offerDesc)
} catch (e) {
return Promise.reject(e);
}
peerConnection.onicecandidate = async event => {

@@ -38,10 +49,3 @@ if (event.candidate !== null) {

// set up offer
const offerDesc = await peerConnection.createOffer();
try {
peerConnection.setLocalDescription(offerDesc)
} catch (e) {
console.error(e);
}
return result;
}

@@ -22,5 +22,6 @@ {

"paths": {
"proto/*": ["../../../dist/js/proto/*", "../../dist/js/proto/*"]
"proto/*": ["../../../dist/js/proto/*", "../../dist/js/proto/*"],
"google-rpc/*": ["../../../dist/js/google/rpc/*", "../../dist/js/google/rpc/*"]
}
}
}

@@ -15,2 +15,3 @@ const webpack = require('webpack');

aliases["proto"] = path.resolve(__dirname, '../../dist/js/proto');
aliases["google-rpc"] = path.resolve(__dirname, '../../dist/js/google/rpc');

@@ -29,3 +30,3 @@ module.exports = {

test: /\.ts$/,
include: /src|proto/,
include: /src|proto|google-rpc/,
exclude: /node_modules/,

@@ -32,0 +33,0 @@ loader: "ts-loader"

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc