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

@relaypro/sdk

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@relaypro/sdk - npm Package Compare versions

Comparing version 1.0.2 to 1.1.0

CHANGELOG.md

2

dist/constants.d.ts
export declare const PORT: number;
export declare const HEARTBEAT: number;
export declare const STRICT_PATH: string;
export declare const TIMEOUT = 5000;
export declare const REFRESH_TIMEOUT = 45000;
export declare const NOTIFICATION_TIMEOUT = 60000;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.REFRESH_TIMEOUT = exports.TIMEOUT = exports.STRICT_PATH = exports.HEARTBEAT = exports.PORT = void 0;
exports.NOTIFICATION_TIMEOUT = exports.REFRESH_TIMEOUT = exports.TIMEOUT = exports.HEARTBEAT = exports.PORT = void 0;
exports.PORT = process.env.PORT ? parseInt(process.env.PORT) : 8080;
exports.HEARTBEAT = process.env.HEARTBEAT ? parseInt(process.env.HEARTBEAT) : 30000;
exports.STRICT_PATH = process.env.STRICT_PATH ?? `1`;
exports.TIMEOUT = 5000;
exports.REFRESH_TIMEOUT = 45000;
exports.NOTIFICATION_TIMEOUT = 60000;
export declare enum Event {
ERROR = "error",
START = "start",
STOP = "stop",
BUTTON = "button",
TIMER = "timer",
NOTIFICATION = "notification",
INCIDENT = "incident",
PROMPT_START = "prompt_start",
CALL_RINGING = "call_ringing",
CALL_CONNECTED = "call_connected",

@@ -12,2 +17,6 @@ CALL_DISCONNECTED = "call_disconnected",

}
export declare enum CallDirection {
INBOUND = "inbound",
OUTBOUND = "outbound"
}
export declare enum Button {

@@ -44,2 +53,3 @@ ACTION = "action",

ID = "id",
TYPE = "type",
ADDRESS = "address",

@@ -55,2 +65,9 @@ COORDINATES = "latlong",

}
export declare enum DeviceType {
RELAY = "relay",
RELAY2 = "relay2",
RELAY_APP = "relay_app",
ROIP = "roip",
DASH = "dash"
}
export declare enum Notification {

@@ -62,1 +79,24 @@ BROADCAST = "broadcast",

}
export declare enum IncidentStatus {
RESOLVED = "resolved",
CANCELLED = "cancelled"
}
export declare enum NotificationPriority {
NORMAL = "normal",
HIGH = "high",
CRITICAL = "critical"
}
export declare enum NotificationSound {
DEFAULT = "default",
SOS = "sos"
}
export declare enum TimerType {
TIMEOUT = "timeout",
INTERVAL = "interval"
}
export declare enum TimeoutType {
MILLISECONDS = "ms",
SECONDS = "secs",
MINUTES = "mins",
HOURS = "hrs"
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Notification = exports.DeviceInfoField = exports.DeviceInfoQuery = exports.Language = exports.Taps = exports.Button = exports.Event = void 0;
exports.TimeoutType = exports.TimerType = exports.NotificationSound = exports.NotificationPriority = exports.IncidentStatus = exports.Notification = exports.DeviceType = exports.DeviceInfoField = exports.DeviceInfoQuery = exports.Language = exports.Taps = exports.Button = exports.CallDirection = exports.Event = void 0;
var Event;
(function (Event) {
Event["ERROR"] = "error";
Event["START"] = "start";
Event["STOP"] = "stop";
Event["BUTTON"] = "button";
Event["TIMER"] = "timer";
Event["NOTIFICATION"] = "notification";
Event["INCIDENT"] = "incident";
Event["PROMPT_START"] = "prompt_start";
Event["CALL_RINGING"] = "call_ringing";
Event["CALL_CONNECTED"] = "call_connected";

@@ -16,2 +21,7 @@ Event["CALL_DISCONNECTED"] = "call_disconnected";

})(Event = exports.Event || (exports.Event = {}));
var CallDirection;
(function (CallDirection) {
CallDirection["INBOUND"] = "inbound";
CallDirection["OUTBOUND"] = "outbound";
})(CallDirection = exports.CallDirection || (exports.CallDirection = {}));
var Button;

@@ -52,2 +62,3 @@ (function (Button) {

DeviceInfoQuery["ID"] = "id";
DeviceInfoQuery["TYPE"] = "type";
DeviceInfoQuery["ADDRESS"] = "address";

@@ -64,2 +75,10 @@ DeviceInfoQuery["COORDINATES"] = "latlong";

})(DeviceInfoField = exports.DeviceInfoField || (exports.DeviceInfoField = {}));
var DeviceType;
(function (DeviceType) {
DeviceType["RELAY"] = "relay";
DeviceType["RELAY2"] = "relay2";
DeviceType["RELAY_APP"] = "relay_app";
DeviceType["ROIP"] = "roip";
DeviceType["DASH"] = "dash";
})(DeviceType = exports.DeviceType || (exports.DeviceType = {}));
var Notification;

@@ -72,1 +91,29 @@ (function (Notification) {

})(Notification = exports.Notification || (exports.Notification = {}));
var IncidentStatus;
(function (IncidentStatus) {
IncidentStatus["RESOLVED"] = "resolved";
IncidentStatus["CANCELLED"] = "cancelled";
})(IncidentStatus = exports.IncidentStatus || (exports.IncidentStatus = {}));
var NotificationPriority;
(function (NotificationPriority) {
NotificationPriority["NORMAL"] = "normal";
NotificationPriority["HIGH"] = "high";
NotificationPriority["CRITICAL"] = "critical";
})(NotificationPriority = exports.NotificationPriority || (exports.NotificationPriority = {}));
var NotificationSound;
(function (NotificationSound) {
NotificationSound["DEFAULT"] = "default";
NotificationSound["SOS"] = "sos";
})(NotificationSound = exports.NotificationSound || (exports.NotificationSound = {}));
var TimerType;
(function (TimerType) {
TimerType["TIMEOUT"] = "timeout";
TimerType["INTERVAL"] = "interval";
})(TimerType = exports.TimerType || (exports.TimerType = {}));
var TimeoutType;
(function (TimeoutType) {
TimeoutType["MILLISECONDS"] = "ms";
TimeoutType["SECONDS"] = "secs";
TimeoutType["MINUTES"] = "mins";
TimeoutType["HOURS"] = "hrs";
})(TimeoutType = exports.TimeoutType || (exports.TimeoutType = {}));

@@ -1,25 +0,31 @@

import WebSocket from 'ws';
import * as enums from './enums';
import { LedIndex, ButtonEvent, Call, ConnectedCall, DisconnectedCall, FailedCall, NotificationEvent, Options, ReceivedCall, Relay, StartedCall, Workflow } from './types';
import { BaseCall, ButtonEvent, ConnectedCall, DisconnectedCall, FailedCall, ReceivedCall, StartedCall, NotificationEvent, NotificationOptions, IncidentEvent, LocalWebSocket, Options, Relay, Workflow, LedIndex, LedEffect, LedInfo, PlaceCall, Prompt, RingingCall, RegisterRequest } from './types';
declare const Event: typeof enums.Event, Language: typeof enums.Language;
export * from './enums';
interface WorkflowEvents {
[Event.START]: (event: Record<string, never>) => void;
[Event.BUTTON]: (event: ButtonEvent) => void;
[Event.TIMER]: (event: Record<string, never>) => void;
[Event.NOTIFICATION]: (event: NotificationEvent) => void;
[Event.CALL_CONNECTED]: (event: ConnectedCall) => void;
[Event.CALL_DISCONNECTED]: (event: DisconnectedCall) => void;
[Event.CALL_FAILED]: (event: FailedCall) => void;
[Event.CALL_RECEIVED]: (event: ReceivedCall) => void;
[Event.CALL_START_REQUEST]: (event: StartedCall) => void;
}
declare type WorkflowEventHandlers = {
[Event.ERROR]?: (error: Error) => Promise<void>;
[Event.START]?: (event: Record<string, never>) => Promise<void>;
[Event.STOP]?: (event: Record<string, never>) => Promise<void>;
[Event.BUTTON]?: (event: ButtonEvent) => Promise<void>;
[Event.TIMER]?: (event: Record<`name`, string>) => Promise<void>;
[Event.NOTIFICATION]?: (event: NotificationEvent) => Promise<void>;
[Event.INCIDENT]?: (event: IncidentEvent) => Promise<void>;
[Event.PROMPT_START]?: (event: Prompt) => Promise<void>;
[Event.CALL_RINGING]?: (event: RingingCall) => Promise<void>;
[Event.CALL_CONNECTED]?: (event: ConnectedCall) => Promise<void>;
[Event.CALL_DISCONNECTED]?: (event: DisconnectedCall) => Promise<void>;
[Event.CALL_FAILED]?: (event: FailedCall) => Promise<void>;
[Event.CALL_RECEIVED]?: (event: ReceivedCall) => Promise<void>;
[Event.CALL_START_REQUEST]?: (event: StartedCall) => Promise<void>;
};
declare const createWorkflow: (fn: Workflow) => Workflow;
declare class RelayEventAdapter {
private websocket;
private emitter;
constructor(websocket: WebSocket);
on<U extends keyof WorkflowEvents>(event: U, listener: WorkflowEvents[U]): void;
off<U extends keyof WorkflowEvents>(event: U, listener: WorkflowEvents[U]): void;
private workQueue;
private handlers;
constructor(websocket: LocalWebSocket);
on<U extends keyof WorkflowEventHandlers>(event: U, listener: WorkflowEventHandlers[U]): void;
off<U extends keyof WorkflowEventHandlers>(event: U): void;
private onClose;
private onError;
private onMessage;

@@ -30,4 +36,9 @@ private _send;

private _call;
say(text: string, lang?: enums.Language): Promise<void>;
play(filename: string): Promise<void>;
setTimer(type: enums.TimerType, name: string, timeout: number | undefined, timeout_type: enums.TimeoutType): Promise<void>;
clearTimer(name: string): Promise<void>;
restartDevice(): Promise<void>;
powerDownDevice(): Promise<void>;
say(text: string, lang?: enums.Language): Promise<string>;
play(filename: string): Promise<string>;
stopPlayback(id?: string | string[]): Promise<void>;
translate(text: string, from?: enums.Language, to?: enums.Language): Promise<string>;

@@ -39,5 +50,6 @@ vibrate(pattern: number[]): Promise<void>;

rainbow(rotations?: number): Promise<void>;
rotate(): Promise<void>;
flash(): Promise<void>;
breathe(): Promise<void>;
rotate(color?: string): Promise<void>;
flash(color?: string): Promise<void>;
breathe(color?: string): Promise<void>;
ledAction(effect: LedEffect, args: LedInfo): Promise<void>;
private _getDeviceInfo;

@@ -52,12 +64,15 @@ getDeviceName(): Promise<string>;

getDeviceBattery(refresh: boolean): Promise<number>;
getDeviceType(): Promise<enums.DeviceType>;
private setDeviceInfo;
setDeviceName(name: string): Promise<void>;
setDeviceChannel(channel: string): Promise<void>;
setChannel(name: string, target: string[]): Promise<void>;
placeCall(call: Call): Promise<void>;
private _buildCallIdRequestOrThrow;
answerCall(callRequest: string | Call): Promise<void>;
hangupCall(callRequest: string | Call): Promise<void>;
setDeviceMode(mode: `panic` | `alarm` | `none`): Promise<void>;
setChannel(name: string, target: string[], { suppressTTS, disableHomeChannel }?: {
suppressTTS?: boolean;
disableHomeChannel?: false;
}): Promise<void>;
setVar(name: string, value: string): Promise<void>;
set(obj: Record<string, string>, value?: string): Promise<void>;
unsetVar(name: string): Promise<void>;
unset(names: string | string[]): Promise<void>;
getVar(name: string, defaultValue?: undefined): Promise<string>;

@@ -68,5 +83,7 @@ get(names: string | string[]): Promise<string | string[]>;

private _sendNotification;
broadcast(text: string, target: string[]): Promise<void>;
notify(text: string, target: string[]): Promise<void>;
alert(name: string, text: string, target: string[]): Promise<void>;
broadcast(name: string, text: string, target: string[], pushOptions?: NotificationOptions): Promise<void>;
cancelBroadcast(name: string, target: string[]): Promise<void>;
notify(name: string, text: string, target: string[], pushOptions?: NotificationOptions): Promise<void>;
cancelNotify(name: string, target: string[]): Promise<void>;
alert(name: string, text: string, target: string[], pushOptions?: NotificationOptions): Promise<void>;
cancelAlert(name: string, target: string[]): Promise<void>;

@@ -81,2 +98,7 @@ listen(phrases?: never[], { transcribe, alt_lang, timeout }?: {

terminate(): Promise<void>;
private _buildCallIdRequestOrThrow;
placeCall(call: PlaceCall): Promise<void>;
answerCall(callRequest: string | BaseCall): Promise<void>;
hangupCall(callRequest: string | BaseCall): Promise<void>;
register(request: RegisterRequest): Promise<void>;
}

@@ -83,0 +105,0 @@ declare const initializeRelaySdk: (options?: Options) => Relay;

@@ -5,7 +5,7 @@ "use strict";

const tslib_1 = require("tslib");
const ws_1 = tslib_1.__importDefault(require("ws"));
const events_1 = tslib_1.__importDefault(require("events"));
const ws_1 = tslib_1.__importStar(require("ws"));
const enums = tslib_1.__importStar(require("./enums"));
const utils_1 = require("./utils");
const constants_1 = require("./constants");
const queue_1 = tslib_1.__importDefault(require("./queue"));
const { Event, Language, DeviceInfoQuery, DeviceInfoField, Notification, } = enums;

@@ -24,3 +24,3 @@ tslib_1.__exportStar(require("./enums"), exports);

});
Object.defineProperty(this, "emitter", {
Object.defineProperty(this, "workQueue", {
enumerable: true,

@@ -31,20 +31,47 @@ configurable: true,

});
Object.defineProperty(this, "handlers", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
console.log(`creating event adapter`);
this.emitter = new events_1.default.EventEmitter();
this.workQueue = new queue_1.default();
this.websocket = websocket;
this.websocket.on(`close`, this.onClose.bind(this));
this.websocket.on(`error`, this.onError.bind(this));
this.websocket.on(`message`, this.onMessage.bind(this));
}
on(event, listener) {
this.emitter?.on(event, listener);
this.off(event);
this.handlers[event] = listener;
}
off(event, listener) {
this.emitter?.off(event, listener);
off(event) {
const { [event]: handler, ...rest } = this.handlers;
if (handler) {
this.handlers = rest;
}
}
async onClose() {
onClose() {
this.websocket = null;
}
onError(error) {
this.workQueue?.enqueue(async () => {
if (this.handlers?.[Event.ERROR]) {
try {
await this.handlers?.[Event.ERROR]?.(error);
}
catch (err) {
console.log(`\`error\` handler failed`);
console.error(err);
}
}
else { // if no handler, log
console.error(error);
}
});
}
onMessage(msg) {
const message = utils_1.safeParse(msg);
if (this.emitter && message?._type && !message?._id) { // not interested in response events (marked by correlation id)
if (this.workQueue && message?._type && !message?._id) { // not interested in response events (marked by correlation id)
const eventNameParts = message._type.match(WORKFLOW_EVENT_REGEX);

@@ -54,3 +81,11 @@ if (eventNameParts?.[1]) {

const { _type, ...args } = message;
this.emitter.emit(eventNameParts?.[1], args);
this.workQueue?.enqueue(async () => {
const event = eventNameParts?.[1];
try {
await this.handlers?.[event]?.(args);
}
catch (err) {
this.onError(err);
}
});
}

@@ -73,4 +108,8 @@ else {

return new Promise((resolve, reject) => {
if (!this.websocket) {
reject(`websocket-not-connected`);
if (!(this.websocket?.isAlive && this.websocket?.readyState === ws_1.OPEN)) {
console.error({
isAlive: this.websocket?.isAlive,
readyState: this.websocket?.readyState,
});
reject(new Error(`websocket-not-connected`));
return;

@@ -86,3 +125,3 @@ }

if (err) {
reject(`failed-to-send`);
reject(new Error(`failed-to-send`));
}

@@ -101,3 +140,3 @@ else {

this.websocket?.off?.(`message`, responseListener);
reject(`failed-to-receive-response-timeout`);
reject(new Error(`failed-to-receive-response-timeout`));
}, timeout);

@@ -116,3 +155,3 @@ const responseListener = (msg) => {

else if (_type === `wf_api_error_response`) {
reject(event?.error);
reject(new Error(event?.error ?? `Unknown error`));
}

@@ -136,8 +175,33 @@ else {

}
async setTimer(type, name, timeout = 60, timeout_type) {
await this._cast(`set_timer`, { type, name, timeout, timeout_type });
}
async clearTimer(name) {
await this._cast(`clear_timer`, { name });
}
async restartDevice() {
await this._cast(`device_power_off`, { restart: true });
}
async powerDownDevice() {
await this._cast(`device_power_off`, { restart: false });
}
async say(text, lang = Language.ENGLISH) {
await this._cast(`say`, { text, lang });
const { id } = (await this._call(`say`, { text, lang }));
return id;
}
async play(filename) {
await this._cast(`play`, { filename });
const { id } = (await this._call(`play`, { filename }));
return id;
}
async stopPlayback(id) {
if (Array.isArray(id)) {
await this._cast(`stop_playback`, { ids: id });
}
else if (typeof id === `string`) {
await this._cast(`stop_playback`, { ids: [id] });
}
else {
await this._cast(`stop_playback`, {});
}
}
async translate(text, from = Language.ENGLISH, to = Language.SPANISH) {

@@ -151,22 +215,25 @@ const { text: translatedText } = (await this._call(`translate`, { text, from_lang: from, to_lang: to }));

async switchLedOn(led, color) {
await this._cast(`set_led`, { effect: `static`, args: { colors: { [`${led}`]: color } } });
await this.ledAction(`static`, { colors: { [`${led}`]: color } });
}
async switchAllLedOn(color) {
await this._cast(`set_led`, { effect: `static`, args: { colors: { ring: color } } });
await this.ledAction(`static`, { colors: { ring: color } });
}
async switchAllLedOff() {
await this._cast(`set_led`, { effect: `off`, args: {} });
await this.ledAction(`off`, {});
}
async rainbow(rotations = -1) {
await this._cast(`set_led`, { effect: `rainbow`, args: { rotations } });
await this.ledAction(`rainbow`, { rotations });
}
async rotate() {
await this._cast(`set_led`, { effect: `rotate`, args: { rotations: -1, colors: { [`1`]: `FFFFFF` } } });
async rotate(color = `FFFFFF`) {
await this.ledAction(`rotate`, { rotations: -1, colors: { [`1`]: color } });
}
async flash() {
await this._cast(`set_led`, { effect: `flash`, args: { count: -1, colors: { ring: `0000FF` } } });
async flash(color = `0000FF`) {
await this.ledAction(`flash`, { count: -1, colors: { ring: color } });
}
async breathe() {
await this._cast(`set_led`, { effect: `breathe`, args: { count: -1, colors: { ring: `0000FF` } } });
async breathe(color = `0000FF`) {
await this.ledAction(`breathe`, { count: -1, colors: { ring: color } });
}
async ledAction(effect, args) {
await this._cast(`set_led`, { effect, args });
}
async _getDeviceInfo(query, refresh = false) {

@@ -200,2 +267,5 @@ const response = await this._call(`get_device_info`, { query, refresh }, refresh ? constants_1.REFRESH_TIMEOUT : constants_1.TIMEOUT);

}
async getDeviceType() {
return await this._getDeviceInfo(DeviceInfoQuery.TYPE);
}
async setDeviceInfo(field, value) {

@@ -210,30 +280,8 @@ await this._cast(`set_device_info`, { field, value });

}
async setChannel(name, target) {
await this._cast(`set_channel`, { channel_name: name, target });
async setDeviceMode(mode, target) {
await this._cast(`set_device_mode`, { mode, target });
}
async placeCall(call) {
await this._call(`call`, call);
async setChannel(name, target, { suppressTTS = false, disableHomeChannel = false } = {}) {
await this._cast(`set_channel`, { channel_name: name, target, suppress_tts: suppressTTS, disable_home_channel: disableHomeChannel });
}
_buildCallIdRequestOrThrow(arg) {
if (typeof arg === `string`) {
return { call_id: arg };
}
else if (typeof arg === `object`) {
if (typeof arg.call_id === `string`) {
return { call_id: arg.call_id };
}
else {
throw new Error(`missing required parameter`);
}
}
else {
throw new Error(`invalid argument type`);
}
}
async answerCall(callRequest) {
await this._call(`answer`, this._buildCallIdRequestOrThrow(callRequest));
}
async hangupCall(callRequest) {
await this._call(`hangup`, this._buildCallIdRequestOrThrow(callRequest));
}
async setVar(name, value) {

@@ -251,2 +299,13 @@ await this._cast(`set_var`, { name, value });

}
async unsetVar(name) {
await this._cast(`unset_var`, { name });
}
async unset(names) {
if (Array.isArray(names)) {
Promise.all(names.map(name => this.unsetVar(name)));
}
else {
return this.unsetVar(names);
}
}
async getVar(name, defaultValue = undefined) {

@@ -270,14 +329,20 @@ const { value } = (await this._call(`get_var`, { name }) ?? defaultValue);

}
async _sendNotification(type, text, target, name) {
await this._cast(`notification`, { type, name, text, target });
async _sendNotification(type, text, target, name, pushOptions) {
await this._cast(`notification`, { type, name, text, target, push_opts: pushOptions }, constants_1.NOTIFICATION_TIMEOUT);
}
async broadcast(text, target) {
await this._sendNotification(Notification.BROADCAST, text, target);
async broadcast(name, text, target, pushOptions) {
await this._sendNotification(Notification.BROADCAST, text, target, name, pushOptions);
}
async notify(text, target) {
await this._sendNotification(Notification.NOTIFY, text, target);
async cancelBroadcast(name, target) {
await this._sendNotification(Notification.CANCEL, undefined, target, name);
}
async alert(name, text, target) {
await this._sendNotification(Notification.ALERT, text, target, name);
async notify(name, text, target, pushOptions) {
await this._sendNotification(Notification.NOTIFY, text, target, name, pushOptions);
}
async cancelNotify(name, target) {
await this._sendNotification(Notification.CANCEL, undefined, target, name);
}
async alert(name, text, target, pushOptions) {
await this._sendNotification(Notification.ALERT, text, target, name, pushOptions);
}
async cancelAlert(name, target) {

@@ -303,4 +368,32 @@ await this._sendNotification(Notification.CANCEL, undefined, target, name);

async terminate() {
await this._send(`terminate`);
await this._cast(`terminate`);
}
_buildCallIdRequestOrThrow(arg) {
if (typeof arg === `string`) {
return { call_id: arg };
}
else if (typeof arg === `object`) {
if (typeof arg.call_id === `string`) {
return { call_id: arg.call_id };
}
else {
throw new Error(`missing required parameter`);
}
}
else {
throw new Error(`invalid argument type`);
}
}
async placeCall(call) {
await this._cast(`call`, call);
}
async answerCall(callRequest) {
await this._cast(`answer`, this._buildCallIdRequestOrThrow(callRequest));
}
async hangupCall(callRequest) {
await this._cast(`hangup`, this._buildCallIdRequestOrThrow(callRequest));
}
async register(request) {
await this._cast(`register`, request);
}
}

@@ -325,7 +418,9 @@ const DEFAULT_WORKFLOW = `__default_relay_workflow__`;

if (request.url) {
const shouldEnforceStrictPaths = (options.STRICT_PATH ?? constants_1.STRICT_PATH) === `1`;
const path = request.url.slice(1);
const hasDefaultWorkflow = workflows?.has(DEFAULT_WORKFLOW);
const hasNamedWorkflow = workflows?.has(path);
return (shouldEnforceStrictPaths ? hasNamedWorkflow : hasDefaultWorkflow) ?? false;
if (path) {
return !!workflows?.has(path);
}
else {
return !!workflows?.has(DEFAULT_WORKFLOW);
}
}

@@ -382,3 +477,3 @@ else {

}
else if (typeof path === `string`) {
else if (typeof path === `string` && typeof workflow === `function`) {
const strippedPath = path.replace(/^\/+/, ``);

@@ -391,5 +486,2 @@ workflows.set(strippedPath, workflow);

}
else {
console.error(`workflows is not initialized`);
}
}

@@ -396,0 +488,0 @@ };

interface Params {
max?: number;
}
declare type fn = {
declare type work = {
(): PromiseLike<void>;

@@ -14,4 +14,4 @@ };

private execute;
enqueue(fn: fn): void;
enqueue(fn: work): void;
}
export {};

@@ -29,2 +29,3 @@ "use strict";

next() {
// console.log(`${this.queue.length} : ${this.numActive} : ${this.max}`)
if (this.queue.length) {

@@ -42,3 +43,5 @@ if (this.numActive < this.max) {

if (typeof obj?.then === `function`) {
resolve();
obj.then(() => {
resolve();
});
}

@@ -45,0 +48,0 @@ }).finally(() => {

@@ -5,9 +5,20 @@ /// <reference types="node" />

import WebSocket from 'ws';
import { Button, Taps } from './enums';
import { Button, CallDirection, IncidentStatus, NotificationPriority, NotificationSound, Taps } from './enums';
import { RelayEventAdapter } from './index';
export declare type LedIndex = `ring` | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | `1` | `2` | `3` | `4` | `5` | `6` | `7` | `8` | `9` | `10` | `11` | `12` | `13` | `14` | `15` | `16`;
export interface Msg {
export declare type LedEffect = `off` | `breathe` | `flash` | `rotate` | `rainbow` | `static`;
export declare type LedInfo = {
rotations?: number;
count?: number;
duration?: number;
repeat_delay?: number;
pattern_repeats?: number;
colors?: {
[K in LedIndex]?: string;
};
};
export declare type Msg = {
_id: string;
_type: string;
error?: unknown;
error?: string;
button?: string;

@@ -19,11 +30,10 @@ taps?: string;

notification_state?: string;
}
export interface Options {
STRICT_PATH?: string;
};
export declare type Options = {
server?: http.Server | https.Server;
}
export interface LocalWebSocket extends WebSocket {
};
export declare type LocalWebSocket = WebSocket & {
connectionId: string;
isAlive: boolean;
}
};
export interface Workflow {

@@ -35,7 +45,13 @@ (relay: RelayEventAdapter): void;

}
export interface ButtonEvent {
export declare type ButtonEvent = {
button: Button;
taps: Taps;
}
export interface NotificationState {
};
export declare type NotificationOptions = {
priority: NotificationPriority;
title: string;
body: string;
sound: NotificationSound;
};
export declare type NotificationState = {
acknowledged: string[];

@@ -45,4 +61,4 @@ created: string[];

timed_out: string[];
}
export interface NotificationEvent {
};
export declare type NotificationEvent = {
source: string;

@@ -52,22 +68,37 @@ event: string;

notification_state: NotificationState;
}
export interface BaseCall {
};
export declare type RegisterRequest = {
uri?: string;
password?: string;
expires?: number;
};
export declare type BaseCall = {
call_id: string;
}
export interface StartedCall extends BaseCall {
};
export declare type StartedCall = BaseCall & {
device_id: string;
device_name: string;
}
export interface ReceivedCall extends StartedCall {
direction: string;
}
export interface ConnectedCall extends ReceivedCall {
};
export declare type PlaceCall = Partial<Omit<StartedCall, `call_id`>>;
export declare type ReceivedCall = StartedCall & {
start_time_epoch: number;
direction: CallDirection;
};
export declare type RingingCall = ReceivedCall;
export declare type ConnectedCall = ReceivedCall & {
connect_time_epoch: number;
}
export interface DisconnectedCall extends ConnectedCall {
};
export declare type DisconnectedCall = ConnectedCall & {
reason: string;
end_time_epoch: number;
}
};
export declare type FailedCall = DisconnectedCall;
export declare type Call = StartedCall | ReceivedCall | ConnectedCall | DisconnectedCall | FailedCall;
export declare type IncidentEvent = {
type: IncidentStatus;
incident_id: string;
reason: string;
};
export declare type Prompt = {
id: string;
};
{
"name": "@relaypro/sdk",
"version": "1.0.2",
"version": "1.1.0",
"description": "Workflow SDK Relay on Node.js",

@@ -19,7 +19,9 @@ "license": "MIT",

"scripts": {
"test": "mocha --exit test/*",
"test": "nyc mocha --exit test/*",
"release": "np",
"build": "del-cli dist && tsc",
"build:check": "tsc --noEmit",
"prepare": "npm run build"
"prepare": "npm run build",
"concat-doc": "mkdir -p concat-docs && npx concat-md --toc --decrease-title-levels --dir-name-as-title docs > concat-docs/relay-js.md",
"doc-sync": "node ./scripts/doc-sync.mjs"
},

@@ -30,25 +32,31 @@ "files": [

"dependencies": {
"tslib": "2.1.0",
"ws": "7.4.3"
"tslib": "2.2.0",
"ws": "7.4.6"
},
"devDependencies": {
"@types/chai": "4.2.15",
"@types/mocha": "8.2.1",
"@types/node": "14.14.22",
"@types/ws": "7.4.0",
"@typescript-eslint/eslint-plugin": "4.15.2",
"@typescript-eslint/parser": "4.15.2",
"chai": "4.3.0",
"@types/chai": "4.2.18",
"@types/mocha": "8.2.2",
"@types/node": "15.6.1",
"@types/ws": "7.4.4",
"@typescript-eslint/eslint-plugin": "4.26.0",
"@typescript-eslint/parser": "4.26.0",
"chai": "4.3.4",
"chai-as-promised": "7.1.1",
"concat-md": "0.3.5",
"del-cli": "3.0.1",
"eslint": "7.20.0",
"eslint-config-standard": "16.0.2",
"eslint": "7.27.0",
"eslint-config-standard": "16.0.3",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-mocha": "8.0.0",
"eslint-plugin-import": "2.23.4",
"eslint-plugin-mocha": "9.0.0",
"eslint-plugin-node": "11.1.0",
"eslint-plugin-promise": "4.3.1",
"mocha": "8.3.0",
"np": "7.4.0",
"ts-node": "9.1.1",
"typescript": "4.1.3"
"eslint-plugin-promise": "5.1.0",
"got": "11.8.2",
"mocha": "8.4.0",
"np": "7.5.0",
"nyc": "15.1.0",
"ts-node": "10.0.0",
"typedoc": "0.20.36",
"typedoc-plugin-markdown": "3.9.0",
"typescript": "4.3.2"
},

@@ -58,3 +66,6 @@ "types": "dist/index.d.ts",

"access": "public"
},
"sdk": {
"commitHash": "4af2916d3c2babe59f0e879c1dcfcfcb6eb827c3"
}
}

@@ -0,1 +1,3 @@

@relaypro/sdk / [Exports](modules.md)
# relay-js

@@ -8,3 +10,3 @@

```bash
npm install @relaypro/sdk
npm install @relaypro/sdk
```

@@ -14,4 +16,6 @@

The following code snippet demonstrates a very simple "Hello World" workflow. However, it does show some of the power that is available through the Relay SDK.
```javascript
import relay from 'relay-js'
import { relay, Event } from '@relaypro/sdk'

@@ -21,5 +25,9 @@ const app = relay()

app.workflow(`helloworld`, workflow => {
workflow.on(`start`, async () => {
workflow.say(`This is a default workflow`)
workflow.terminate()
workflow.on(Event.START, async () => {
const greeting = await relay.get(`greeting`)
const name = await relay.getDeviceName()
await relay.say(`What is your name ?`)
const user = await relay.listen()
await relay.say(`Hello ${user}! ${greeting} ${name}`)
await relay.terminate()
})

@@ -29,6 +37,40 @@ })

Features demonstrated here:
* When the workflow is triggered, the `start` event is emitted and the registered start callback
function is called.
* A configuration variable `greeting` is retrieved as is the triggering device's name.
* The workflow then uses text-to-speech to prompt the user for their name.
* The workflow awaits for a response from the device user.
* The workflow then again uses text-to-speech to reply with a dynamic message.
* Finally, the workflow is terminated and the device is returned to its original state.
In this sample, a workflow callback function is registered with the name `helloworld`. This value
of `helloworld` is used to map a WebSocket connection at the path `ws://yourhost:port/helloworld`
to the registered workflow callback function.
It is also possible to register a "default" workflow at path `/` by providing the workflow callback
function as the first parameter:
```javascript
app.workflow(wf => {
wf.on(Event.START, async () => {
// handle start event
})
})
```
## API
The Relay JS SDK covers a broad set of use cases. Explore the various actions that can be performed
in workflow event callbacks:
* [Relay](classes/relayeventadapter.md)
## Workflow Registration
To register your workflow on a Relay device see https://api-docs.relaypro.com/docs/register-workflows
More thorough documentation on how toregister your workflow on a Relay device
can be found at https://api-docs.relaypro.com/docs/register-workflows
In order to configure

@@ -41,3 +83,4 @@ ## Development

npm install
npm test
npm run build
npm run test
```

@@ -44,0 +87,0 @@

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