websocket-rpc-protocol
Advanced tools
Comparing version
import { Signal } from 'easy-signal'; | ||
export interface Client { | ||
deviceId: string; | ||
online: boolean; | ||
@@ -9,3 +10,3 @@ connected: boolean; | ||
export declare type Unsubscribe = () => void; | ||
export interface ClientAPI { | ||
export interface ClientAPI<T = {}> { | ||
connect(): Promise<void>; | ||
@@ -25,5 +26,10 @@ disconnect(): void; | ||
onChange: Signal<(data: Client) => any>; | ||
onOpen: Signal<(options: { | ||
waitUntil(promise: Promise<any>): void; | ||
}) => any>; | ||
onClose: Signal<() => any>; | ||
onError: Signal<() => any>; | ||
} | ||
export default function createClient<T = {}>(url: string, appVersion: string): ClientAPI & T; | ||
export default function createClient<T = {}>(url: string): ClientAPI<T> & T; | ||
declare type GenericFunction = (...args: any[]) => any; | ||
export {}; |
@@ -6,3 +6,3 @@ import { signal } from 'easy-signal'; | ||
const NOOP = () => { }; | ||
export default function createClient(url, appVersion) { | ||
export default function createClient(url) { | ||
const requests = {}; | ||
@@ -14,2 +14,5 @@ const afterConnectedQueue = []; | ||
const listeners = { 1: signal() }; | ||
const onOpen = signal(); | ||
const onClose = signal(); | ||
const onError = signal(); | ||
let socket; | ||
@@ -26,3 +29,3 @@ let shouldConnect = false; | ||
let paused; // use for testing data drop and sync stability/recovery | ||
let data = { online, connected, authed, serverTimeOffset }; | ||
let data = { deviceId, online, connected, authed, serverTimeOffset }; | ||
window.addEventListener('online', onOnline); | ||
@@ -37,3 +40,3 @@ window.addEventListener('offline', onOffline); | ||
if (online !== data.online || connected !== data.connected || authed !== data.authed || serverTimeOffset !== data.serverTimeOffset) { | ||
onChange.dispatch(data = { online, connected, authed, serverTimeOffset }); | ||
onChange.dispatch(data = { deviceId, online, connected, authed, serverTimeOffset }); | ||
} | ||
@@ -65,3 +68,4 @@ } | ||
} | ||
socket.onerror = () => { | ||
socket.onerror = (event) => { | ||
onError.dispatch(event.error); | ||
reject(); | ||
@@ -71,3 +75,9 @@ closeSocket(); | ||
socket.onopen = async () => { | ||
await send('info', deviceId, appVersion); | ||
const promises = []; | ||
const options = { waitUntil: (promise) => { | ||
promises.push(promise); | ||
} }; | ||
onOpen.dispatch(options); | ||
if (promises.length) | ||
await Promise.all(promises); | ||
if (!connected) { | ||
@@ -94,2 +104,3 @@ connected = true; | ||
} | ||
onClose.dispatch(); | ||
Object.keys(requests).forEach(key => { | ||
@@ -96,0 +107,0 @@ const request = requests[key]; |
@@ -9,2 +9,3 @@ import { signal, Signal } from 'easy-signal'; | ||
export interface Client { | ||
deviceId: string; | ||
online: boolean; | ||
@@ -18,3 +19,3 @@ connected: boolean; | ||
export interface ClientAPI { | ||
export interface ClientAPI<T = {}> { | ||
connect(): Promise<void>; | ||
@@ -34,5 +35,8 @@ disconnect(): void; | ||
onChange: Signal<(data: Client) => any>; | ||
onOpen: Signal<(options: {waitUntil(promise: Promise<any>): void}) => any>; | ||
onClose: Signal<() => any>; | ||
onError: Signal<() => any>; | ||
} | ||
export default function createClient<T = {}>(url: string, appVersion: string): ClientAPI & T { | ||
export default function createClient<T = {}>(url: string): ClientAPI<T> & T { | ||
const requests: {[r: string]: Request} = {}; | ||
@@ -44,2 +48,5 @@ const afterConnectedQueue: Array<Request> = []; | ||
const listeners: {[r: number]: Signal} = {1: signal()}; | ||
const onOpen = signal<(options: {waitUntil(promise: Promise<any>): void}) => any>(); | ||
const onClose = signal<() => any>(); | ||
const onError = signal<(error: Error) => any>(); | ||
@@ -57,3 +64,3 @@ let socket: WebSocket; | ||
let paused: boolean; // use for testing data drop and sync stability/recovery | ||
let data: Client = { online, connected, authed, serverTimeOffset }; | ||
let data: Client = { deviceId, online, connected, authed, serverTimeOffset }; | ||
@@ -71,3 +78,3 @@ window.addEventListener('online', onOnline); | ||
if (online !== data.online || connected !== data.connected || authed !== data.authed || serverTimeOffset !== data.serverTimeOffset) { | ||
onChange.dispatch(data = { online, connected, authed, serverTimeOffset }); | ||
onChange.dispatch(data = { deviceId, online, connected, authed, serverTimeOffset }); | ||
} | ||
@@ -104,3 +111,4 @@ } | ||
socket.onerror = () => { | ||
socket.onerror = (event: ErrorEvent) => { | ||
onError.dispatch(event.error); | ||
reject(); | ||
@@ -111,3 +119,8 @@ closeSocket(); | ||
socket.onopen = async () => { | ||
await send('info', deviceId, appVersion); | ||
const promises = []; | ||
const options = { waitUntil: (promise: Promise<any>) => { | ||
promises.push(promise); | ||
}}; | ||
onOpen.dispatch(options); | ||
if (promises.length) await Promise.all(promises); | ||
if (!connected) { | ||
@@ -135,2 +148,3 @@ connected = true; | ||
} | ||
onClose.dispatch(); | ||
@@ -137,0 +151,0 @@ Object.keys(requests).forEach(key => { |
{ | ||
"name": "websocket-rpc-protocol", | ||
"version": "0.1.5", | ||
"version": "0.1.6", | ||
"description": "A JSON RPC protocol for working over websockets. Sheds the weight of JSON RPC to simplify argument names and adds features.", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -10,2 +10,3 @@ // Exposes an API to a websocket endpoint using the protocol described in PROTOCOL.md | ||
api = await apiFactory(thisApi); | ||
send({ ts: Date.now() }); | ||
preMessages.forEach(processMessage); | ||
@@ -19,3 +20,2 @@ preMessages = null; | ||
} | ||
send({ ts: Date.now(), v: api.getVersion?.() }); | ||
return thisApi; | ||
@@ -22,0 +22,0 @@ function send(data) { |
@@ -24,2 +24,3 @@ import { Signal } from 'easy-signal'; | ||
api = await apiFactory(thisApi); | ||
send({ ts: Date.now() }); | ||
preMessages.forEach(processMessage); | ||
@@ -32,3 +33,2 @@ preMessages = null; | ||
} | ||
send({ ts: Date.now(), v: (api.getVersion as APIMethod)?.() }); | ||
@@ -35,0 +35,0 @@ return thisApi; |
33226
3.6%823
3.91%