@push-rpc/next
Advanced tools
Comparing version 2.0.0-beta.4 to 2.0.0
import { RpcContext, Services } from "../rpc.js"; | ||
import { ServicesWithSubscriptions } from "./remote.js"; | ||
import type WebSocket from "ws"; | ||
import { Middleware } from "../utils/middleware.js"; | ||
@@ -15,5 +14,6 @@ export type RpcClient = { | ||
errorDelayMaxDuration: number; | ||
pingInterval: number; | ||
pingInterval: number | null; | ||
subscriptions: boolean; | ||
middleware: Middleware<RpcContext>[]; | ||
connectOnCreate: boolean; | ||
}; | ||
@@ -20,0 +20,0 @@ export declare function consumeServices<S extends Services<S>>(url: string, overrideOptions?: Partial<ConsumeServicesOptions>): Promise<{ |
@@ -14,2 +14,5 @@ "use strict"; | ||
const client = new RpcClientImpl_js_1.RpcClientImpl(url, options); | ||
if (options.connectOnCreate) { | ||
await client.connect(); | ||
} | ||
return { | ||
@@ -25,6 +28,7 @@ client, | ||
errorDelayMaxDuration: 15 * 1000, | ||
pingInterval: 30 * 1000, // should be in-sync with server | ||
pingInterval: null, // if set, should be in-sync with server, ie 30 * 1000 | ||
subscriptions: true, | ||
middleware: [], | ||
connectOnCreate: false, | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -1,2 +0,1 @@ | ||
/// <reference types="ws" /> | ||
import { Services } from "../rpc.js"; | ||
@@ -15,4 +14,5 @@ import { ServicesWithSubscriptions } from "./remote.js"; | ||
_allSubscriptions(): [itemName: string, parameters: unknown[], consumers: (d: unknown) => void][]; | ||
_webSocket(): import("ws") | null; | ||
_webSocket(): WebSocket | null; | ||
createRemote(): ServicesWithSubscriptions<S>; | ||
connect(): Promise<void>; | ||
private call; | ||
@@ -19,0 +19,0 @@ private subscribe; |
@@ -23,7 +23,3 @@ "use strict"; | ||
} | ||
if (this.options.subscriptions) { | ||
this.connection.connect().catch((e) => { | ||
// ignored | ||
}); | ||
} | ||
void this.connection.connect(); | ||
const data = await this.invoke(itemName, rpc_js_1.InvocationType.Subscribe, (...parameters) => this.httpClient.subscribe(itemName, parameters, callOptions?.timeout ?? this.options.callTimeout), parameters); | ||
@@ -55,2 +51,3 @@ this.remoteSubscriptions.subscribe(data, itemName, parameters, consumer); | ||
this.connection = new WebSocketConnection_js_1.WebSocketConnection(url, this.clientId, { | ||
subscriptions: options.subscriptions, | ||
errorDelayMaxDuration: options.errorDelayMaxDuration, | ||
@@ -88,2 +85,5 @@ reconnectDelay: options.reconnectDelay, | ||
} | ||
async connect() { | ||
await this.connection.connect(); | ||
} | ||
invoke(itemName, invocationType, next, parameters) { | ||
@@ -90,0 +90,0 @@ const ctx = { |
@@ -1,2 +0,1 @@ | ||
import type WebSocket from "ws"; | ||
export declare class WebSocketConnection { | ||
@@ -9,5 +8,6 @@ private readonly url; | ||
constructor(url: string, clientId: string, options: { | ||
subscriptions: boolean; | ||
reconnectDelay: number; | ||
errorDelayMaxDuration: number; | ||
pingInterval: number; | ||
pingInterval: number | null; | ||
}, consume: (itemName: string, parameters: unknown[], data: unknown) => void, onConnected: () => void); | ||
@@ -14,0 +14,0 @@ close(): Promise<void>; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -40,3 +17,3 @@ exports.WebSocketConnection = void 0; | ||
this.pingTimeout = null; | ||
this.url = url; | ||
this.url = url.replace(/^https(.*)/, "wss$1").replace(/^http(.*)/, "ws$1"); | ||
this.clientId = clientId; | ||
@@ -47,3 +24,3 @@ } | ||
if (this.socket) { | ||
this.socket.terminate(); | ||
this.socket.close(); | ||
this.socket = null; | ||
@@ -61,4 +38,10 @@ } | ||
connect() { | ||
// no subscriptions support, no need to connect | ||
if (!this.options.subscriptions) { | ||
return Promise.resolve(); | ||
} | ||
// already started connecting | ||
if (this.socket || !this.disconnectedMark) | ||
return Promise.resolve(); | ||
// start connection process | ||
this.disconnectedMark = false; | ||
@@ -79,3 +62,4 @@ return new Promise(async (resolve) => { | ||
onFirstConnection = () => { }; | ||
}, () => { | ||
}, (e) => { | ||
logger_js_1.log.warn("Unable to connect WS", e); | ||
// 2. ... unable to establish connection | ||
@@ -109,6 +93,5 @@ resolve(); | ||
try { | ||
const { WebSocket } = await Promise.resolve().then(() => __importStar(require("ws"))); | ||
const socket = new WebSocket(this.url, this.clientId); | ||
let connected = false; | ||
socket.on("open", () => { | ||
socket.addEventListener("open", () => { | ||
this.socket = socket; | ||
@@ -120,6 +103,6 @@ connected = true; | ||
}); | ||
socket.on("ping", () => { | ||
socket.addEventListener("ping", () => { | ||
this.heartbeat(); | ||
}); | ||
socket.on("close", () => { | ||
socket.addEventListener("close", () => { | ||
this.socket = null; | ||
@@ -133,7 +116,6 @@ if (connected) { | ||
}); | ||
socket.on("error", (e) => { | ||
socket.addEventListener("error", (e) => { | ||
if (!connected) { | ||
reject(e); | ||
} | ||
logger_js_1.log.warn("WS connection error", e.message); | ||
try { | ||
@@ -146,4 +128,4 @@ socket.close(); | ||
}); | ||
socket.on("message", (message) => { | ||
this.receiveSocketMessage(message); | ||
socket.addEventListener("message", (message) => { | ||
this.receiveSocketMessage(message.data); | ||
}); | ||
@@ -160,5 +142,7 @@ } | ||
} | ||
this.pingTimeout = setTimeout(() => { | ||
this.socket?.terminate(); | ||
}, this.options.pingInterval * 1.5); | ||
if (this.options.pingInterval) { | ||
this.pingTimeout = setTimeout(() => { | ||
this.socket?.close(); | ||
}, this.options.pingInterval * 1.5); | ||
} | ||
} | ||
@@ -165,0 +149,0 @@ async receiveSocketMessage(rawMessage) { |
{ | ||
"name": "@push-rpc/next", | ||
"version": "2.0.0-beta.4", | ||
"version": "2.0.0", | ||
"main": "dist/index.js", | ||
@@ -5,0 +5,0 @@ "types": "dist/index.d.ts", |
@@ -26,2 +26,6 @@ ## Glossary | ||
triggers will result in new notifications. Throttling can be used with reducers to aggregate values supplied in | ||
triggers. | ||
triggers. | ||
## Issues / TBDs | ||
- Browser sockets don't have 'ping' event. Need to find a different way to detect connection loss. |
import {RpcContext, Services} from "../rpc.js" | ||
import {ServicesWithSubscriptions} from "./remote.js" | ||
import type WebSocket from "ws" | ||
import {RpcClientImpl} from "./RpcClientImpl.js" | ||
@@ -20,5 +19,6 @@ import {Middleware} from "../utils/middleware.js" | ||
errorDelayMaxDuration: number | ||
pingInterval: number | ||
pingInterval: number | null | ||
subscriptions: boolean | ||
middleware: Middleware<RpcContext>[] | ||
connectOnCreate: boolean | ||
} | ||
@@ -44,2 +44,6 @@ | ||
if (options.connectOnCreate) { | ||
await client.connect() | ||
} | ||
return { | ||
@@ -55,5 +59,6 @@ client, | ||
errorDelayMaxDuration: 15 * 1000, | ||
pingInterval: 30 * 1000, // should be in-sync with server | ||
pingInterval: null, // if set, should be in-sync with server, ie 30 * 1000 | ||
subscriptions: true, | ||
middleware: [], | ||
connectOnCreate: false, | ||
} |
@@ -22,2 +22,3 @@ import {CallOptions, InvocationType, RpcContext, Services} from "../rpc.js" | ||
{ | ||
subscriptions: options.subscriptions, | ||
errorDelayMaxDuration: options.errorDelayMaxDuration, | ||
@@ -76,2 +77,6 @@ reconnectDelay: options.reconnectDelay, | ||
async connect() { | ||
await this.connection.connect() | ||
} | ||
private call = ( | ||
@@ -107,7 +112,3 @@ itemName: string, | ||
if (this.options.subscriptions) { | ||
this.connection.connect().catch((e) => { | ||
// ignored | ||
}) | ||
} | ||
void this.connection.connect() | ||
@@ -114,0 +115,0 @@ const data = await this.invoke( |
@@ -1,2 +0,1 @@ | ||
import type WebSocket from "ws" | ||
import {log} from "../logger.js" | ||
@@ -11,5 +10,6 @@ import {safeParseJson} from "../utils/json.js" | ||
private readonly options: { | ||
subscriptions: boolean | ||
reconnectDelay: number | ||
errorDelayMaxDuration: number | ||
pingInterval: number | ||
pingInterval: number | null | ||
}, | ||
@@ -19,3 +19,3 @@ private readonly consume: (itemName: string, parameters: unknown[], data: unknown) => void, | ||
) { | ||
this.url = url | ||
this.url = url.replace(/^https(.*)/, "wss$1").replace(/^http(.*)/, "ws$1") | ||
this.clientId = clientId | ||
@@ -28,3 +28,3 @@ } | ||
if (this.socket) { | ||
this.socket!.terminate() | ||
this.socket!.close() | ||
this.socket = null | ||
@@ -44,4 +44,11 @@ } | ||
connect() { | ||
// no subscriptions support, no need to connect | ||
if (!this.options.subscriptions) { | ||
return Promise.resolve() | ||
} | ||
// already started connecting | ||
if (this.socket || !this.disconnectedMark) return Promise.resolve() | ||
// start connection process | ||
this.disconnectedMark = false | ||
@@ -68,3 +75,5 @@ | ||
}, | ||
() => { | ||
(e) => { | ||
log.warn("Unable to connect WS", e) | ||
// 2. ... unable to establish connection | ||
@@ -105,4 +114,2 @@ resolve() | ||
try { | ||
const {WebSocket} = await import("ws") | ||
const socket = new WebSocket(this.url, this.clientId) | ||
@@ -112,3 +119,3 @@ | ||
socket.on("open", () => { | ||
socket.addEventListener("open", () => { | ||
this.socket = socket | ||
@@ -123,7 +130,7 @@ connected = true | ||
socket.on("ping", () => { | ||
socket.addEventListener("ping", () => { | ||
this.heartbeat() | ||
}) | ||
socket.on("close", () => { | ||
socket.addEventListener("close", () => { | ||
this.socket = null | ||
@@ -140,3 +147,3 @@ | ||
socket.on("error", (e) => { | ||
socket.addEventListener("error", (e) => { | ||
if (!connected) { | ||
@@ -146,4 +153,2 @@ reject(e) | ||
log.warn("WS connection error", e.message) | ||
try { | ||
@@ -156,4 +161,4 @@ socket.close() | ||
socket.on("message", (message) => { | ||
this.receiveSocketMessage(message) | ||
socket.addEventListener("message", (message) => { | ||
this.receiveSocketMessage(message.data) | ||
}) | ||
@@ -175,8 +180,10 @@ } catch (e) { | ||
this.pingTimeout = setTimeout(() => { | ||
this.socket?.terminate() | ||
}, this.options.pingInterval * 1.5) | ||
if (this.options.pingInterval) { | ||
this.pingTimeout = setTimeout(() => { | ||
this.socket?.close() | ||
}, this.options.pingInterval * 1.5) | ||
} | ||
} | ||
private async receiveSocketMessage(rawMessage: WebSocket.RawData) { | ||
private async receiveSocketMessage(rawMessage: string | ArrayBuffer | Blob) { | ||
try { | ||
@@ -183,0 +190,0 @@ const msg = rawMessage.toString() |
@@ -13,3 +13,6 @@ import { | ||
} from "../src/index.js" | ||
import WebSocket from "ws" | ||
;(global as any).WebSocket = WebSocket | ||
export const TEST_PORT = 5555 | ||
@@ -16,0 +19,0 @@ |
@@ -6,3 +6,4 @@ { | ||
"lib": [ | ||
"es2020" | ||
"es2020", | ||
"DOM" | ||
], | ||
@@ -9,0 +10,0 @@ "declaration": true, |
@@ -6,3 +6,4 @@ { | ||
"lib": [ | ||
"es2020" | ||
"es2020", | ||
"DOM" | ||
], | ||
@@ -9,0 +10,0 @@ "declaration": true, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
188305
4209
1
30