@push-rpc/core
Advanced tools
Comparing version 1.6.5 to 1.7.0
@@ -53,2 +53,2 @@ import { RpcSession } from "./RpcSession"; | ||
} | ||
export declare function createRpcClient<R = any>(level: any, createSocket: () => Promise<Socket>, options?: Partial<RpcClientOptions>): Promise<RpcClient<R>>; | ||
export declare function createRpcClient<R = any>(createSocket: () => Promise<Socket>, options?: Partial<RpcClientOptions>): Promise<RpcClient<R>>; |
@@ -223,3 +223,3 @@ "use strict"; | ||
exports.RpcClient = RpcClient; | ||
function createRpcClient(level, createSocket, options) { | ||
function createRpcClient(createSocket, options) { | ||
if (options === void 0) { options = {}; } | ||
@@ -232,3 +232,3 @@ return __awaiter(this, void 0, void 0, function () { | ||
opts = __assign(__assign({}, defaultOptions), options); | ||
session = new RpcSession_1.RpcSession(opts.local, level, { | ||
session = new RpcSession_1.RpcSession(opts.local, { | ||
messageIn: function (data) { return utils_1.safeListener(function () { return opts.listeners.messageIn(data); }); }, | ||
@@ -235,0 +235,0 @@ messageOut: function (data) { return utils_1.safeListener(function () { return opts.listeners.messageOut(data); }); }, |
@@ -17,2 +17,2 @@ import { CallOptions, DataConsumer, LocalTopic, RemoteTopic, TopicImpl } from "./rpc"; | ||
} | ||
export declare function createRemote(level: number, session: RpcSession): any; | ||
export declare function createRemote(session: RpcSession, name?: string): (params: any, callOpts?: any) => Promise<any>; |
@@ -151,45 +151,41 @@ "use strict"; | ||
exports.RemoteTopicImpl = RemoteTopicImpl; | ||
function createRemote(level, session) { | ||
return createRemoteServiceItems(level, function (name) { | ||
// start with method | ||
var remoteItem = function (params, callOpts) { | ||
return session.callRemote(name, params, rpc_1.MessageType.Call, callOpts); | ||
function createRemote(session, name) { | ||
if (name === void 0) { name = ""; } | ||
// start with method | ||
var remoteItem = function (params, callOpts) { | ||
return session.callRemote(name, params, rpc_1.MessageType.Call, callOpts); | ||
}; | ||
// then add topic methods | ||
var remoteTopic = new RemoteTopicImpl(name, session); | ||
// make remoteItem both topic and remoteMethod | ||
var remoteTopicProps = utils_1.getClassMethodNames(remoteTopic); | ||
remoteTopicProps.forEach(function (methodName) { | ||
remoteItem[methodName] = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return remoteTopic[methodName].apply(remoteTopic, args); | ||
}; | ||
var remoteTopic = new RemoteTopicImpl(name, session); | ||
// make remoteItem both topic and remoteMethod | ||
utils_1.getClassMethodNames(remoteTopic).forEach(function (methodName) { | ||
remoteItem[methodName] = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
return remoteTopic[methodName].apply(remoteTopic, args); | ||
}; | ||
}); | ||
return remoteItem; | ||
}); | ||
} | ||
exports.createRemote = createRemote; | ||
function createRemoteServiceItems(level, createServiceItem, prefix) { | ||
if (prefix === void 0) { prefix = ""; } | ||
// then add proxy creating subitems | ||
var cachedItems = {}; | ||
return new Proxy({}, { | ||
get: function (target, name) { | ||
return new Proxy(remoteItem, { | ||
get: function (target, propName) { | ||
// skip internal props | ||
if (typeof name != "string") | ||
return target[name]; | ||
// and other props | ||
if (["then", "toJSON"].indexOf(name) >= 0) | ||
return undefined; | ||
if (!cachedItems[name]) { | ||
var itemName = prefix + name; | ||
if (level > 0) | ||
cachedItems[name] = createRemoteServiceItems(level - 1, createServiceItem, itemName + "/"); | ||
else | ||
cachedItems[name] = createServiceItem(itemName); | ||
if (typeof propName != "string") | ||
return target[propName]; | ||
// skip other system props | ||
if (["then", "catch", "toJSON", "prototype"].includes(propName)) | ||
return target[propName]; | ||
// skip topic methods | ||
if (remoteTopicProps.includes(propName)) | ||
return target[propName]; | ||
if (!cachedItems[propName]) { | ||
cachedItems[propName] = createRemote(session, name ? name + "/" + propName : propName); | ||
} | ||
return cachedItems[name]; | ||
return cachedItems[propName]; | ||
}, | ||
set: function (target, name, value) { | ||
cachedItems[name] = value; | ||
set: function (target, propName, value) { | ||
cachedItems[propName] = value; | ||
return true; | ||
@@ -199,5 +195,6 @@ }, | ||
ownKeys: function () { | ||
return Object.keys(cachedItems); | ||
return __spreadArrays(["prototype"], Object.keys(cachedItems)); | ||
}, | ||
}); | ||
} | ||
exports.createRemote = createRemote; |
@@ -5,16 +5,16 @@ "use strict"; | ||
function getServiceItem(services, name) { | ||
if (!name) { | ||
var names = name.split("/"); | ||
var item = services[names[0]]; | ||
if (!item) { | ||
return { item: null, object: null }; | ||
} | ||
var names = name.split("/"); | ||
var item = services[names[0]]; | ||
if (typeof item == "object") { | ||
if ("getTopicName" in item) | ||
if (names.length == 1) { | ||
if (item) { | ||
return { item: item, object: services }; | ||
if (!item) { | ||
} | ||
else { | ||
return { item: null, object: null }; | ||
} | ||
return getServiceItem(item, names.slice(1).join("/")); | ||
} | ||
return { item: item, object: services }; | ||
return getServiceItem(item, names.slice(1).join("/")); | ||
} | ||
@@ -21,0 +21,0 @@ exports.getServiceItem = getServiceItem; |
@@ -21,3 +21,3 @@ import { CallOptions, MessageType, Middleware, RpcConnectionContext, RpcContext } from "./rpc"; | ||
private delayCalls; | ||
constructor(local: any, remoteLevel: number, listeners: RpcSessionListeners, connectionContext: RpcConnectionContext, localMiddleware: Middleware, remoteMiddleware: Middleware, messageParser: (data: any) => any[], pingSendTimeout: number, keepAliveTimeout: number, callTimeout: number, syncRemoteCalls: boolean, delayCalls: number); | ||
constructor(local: any, listeners: RpcSessionListeners, connectionContext: RpcConnectionContext, localMiddleware: Middleware, remoteMiddleware: Middleware, messageParser: (data: any) => any[], pingSendTimeout: number, keepAliveTimeout: number, callTimeout: number, syncRemoteCalls: boolean, delayCalls: number); | ||
remote: any; | ||
@@ -24,0 +24,0 @@ subscriptions: { |
@@ -64,3 +64,3 @@ "use strict"; | ||
var RpcSession = /** @class */ (function () { | ||
function RpcSession(local, remoteLevel, listeners, connectionContext, localMiddleware, remoteMiddleware, messageParser, pingSendTimeout, keepAliveTimeout, callTimeout, syncRemoteCalls, delayCalls) { | ||
function RpcSession(local, listeners, connectionContext, localMiddleware, remoteMiddleware, messageParser, pingSendTimeout, keepAliveTimeout, callTimeout, syncRemoteCalls, delayCalls) { | ||
var _this = this; | ||
@@ -103,3 +103,3 @@ this.local = local; | ||
}); }; | ||
this.remote = remote_1.createRemote(remoteLevel, this); | ||
this.remote = remote_1.createRemote(this); | ||
} | ||
@@ -491,8 +491,7 @@ RpcSession.prototype.open = function (socket) { | ||
Object.getOwnPropertyNames(remote).forEach(function (key) { | ||
if (typeof remote[key] == "object") { | ||
resubscribeTopics(remote[key]); | ||
} | ||
else { | ||
remote[key].resubscribe(); | ||
} | ||
if (key == "prototype") | ||
return; | ||
// because each item is always a topic; but those that not subscribed will not do a thing on resubscribe | ||
remote[key].resubscribe(); | ||
resubscribeTopics(remote[key]); | ||
}); | ||
@@ -499,0 +498,0 @@ } |
@@ -7,3 +7,2 @@ import { Middleware, RpcConnectionContext } from "./rpc"; | ||
remoteMiddleware?: Middleware; | ||
clientLevel?: number; | ||
messageParser?(data: any): any[]; | ||
@@ -10,0 +9,0 @@ pingSendTimeout?: number; |
@@ -80,3 +80,2 @@ "use strict"; | ||
remoteMiddleware: function (ctx, next, params, messageType) { return next(params); }, | ||
clientLevel: 0, | ||
pingSendTimeout: 40 * 1000, | ||
@@ -144,3 +143,3 @@ keepAliveTimeout: 120 * 1000, | ||
case 5: | ||
session = new RpcSession_1.RpcSession(local, opts.clientLevel, { | ||
session = new RpcSession_1.RpcSession(local, { | ||
messageIn: function (data) { | ||
@@ -201,3 +200,3 @@ return utils_1.safeListener(function () { return opts.listeners.messageIn(remoteId, data, connectionContext); }); | ||
throw new Error("Client " + clientId + " is not connected"); | ||
return remote_1.createRemote(opts.clientLevel, sessions[clientId]); | ||
return remote_1.createRemote(sessions[clientId]); | ||
}, | ||
@@ -204,0 +203,0 @@ isConnected: isConnected, |
{ | ||
"name": "@push-rpc/core", | ||
"version": "1.6.5", | ||
"version": "1.7.0", | ||
"main": "dist/index.js", | ||
@@ -21,3 +21,3 @@ "types": "dist/index.d.ts", | ||
}, | ||
"gitHead": "d8d55880b77e3dd4fbb89342a1174cf74a527eb2" | ||
"gitHead": "780c40760154824bd93ee636fec0855e5e145c03" | ||
} |
@@ -186,3 +186,2 @@ import {RpcSession} from "./RpcSession" | ||
export async function createRpcClient<R = any>( | ||
level, | ||
createSocket: () => Promise<Socket>, | ||
@@ -195,3 +194,2 @@ options: Partial<RpcClientOptions> = {} | ||
opts.local, | ||
level, | ||
{ | ||
@@ -198,0 +196,0 @@ messageIn: data => safeListener(() => opts.listeners.messageIn(data)), |
@@ -1,10 +0,2 @@ | ||
import { | ||
CallOptions, | ||
DataConsumer, | ||
LocalTopic, | ||
MessageType, | ||
Method, | ||
RemoteTopic, | ||
TopicImpl, | ||
} from "./rpc" | ||
import {CallOptions, DataConsumer, LocalTopic, MessageType, RemoteTopic, TopicImpl} from "./rpc" | ||
import {RpcSession} from "./RpcSession" | ||
@@ -107,63 +99,49 @@ import {createMessageId, getClassMethodNames} from "./utils" | ||
export function createRemote(level: number, session: RpcSession) { | ||
return createRemoteServiceItems(level, name => { | ||
// start with method | ||
const remoteItem = (params, callOpts?) => { | ||
return session.callRemote(name, params, MessageType.Call, callOpts) | ||
} | ||
export function createRemote(session: RpcSession, name = "") { | ||
// start with method | ||
const remoteItem = (params, callOpts?) => { | ||
return session.callRemote(name, params, MessageType.Call, callOpts) | ||
} | ||
const remoteTopic = new RemoteTopicImpl(name, session) | ||
// then add topic methods | ||
const remoteTopic = new RemoteTopicImpl(name, session) | ||
// make remoteItem both topic and remoteMethod | ||
getClassMethodNames(remoteTopic).forEach(methodName => { | ||
remoteItem[methodName] = (...args) => remoteTopic[methodName].apply(remoteTopic, args) | ||
}) | ||
return remoteItem | ||
// make remoteItem both topic and remoteMethod | ||
const remoteTopicProps = getClassMethodNames(remoteTopic) | ||
remoteTopicProps.forEach(methodName => { | ||
remoteItem[methodName] = (...args) => remoteTopic[methodName].apply(remoteTopic, args) | ||
}) | ||
} | ||
function createRemoteServiceItems( | ||
level, | ||
createServiceItem: (name) => RemoteTopic<any, any> | Method, | ||
prefix = "" | ||
): any { | ||
// then add proxy creating subitems | ||
const cachedItems = {} | ||
return new Proxy( | ||
{}, | ||
{ | ||
get(target, name) { | ||
// skip internal props | ||
if (typeof name != "string") return target[name] | ||
return new Proxy(remoteItem, { | ||
get(target, propName) { | ||
// skip internal props | ||
if (typeof propName != "string") return target[propName] | ||
// and other props | ||
if (["then", "toJSON"].indexOf(name) >= 0) return undefined | ||
// skip other system props | ||
if (["then", "catch", "toJSON", "prototype"].includes(propName)) return target[propName] | ||
if (!cachedItems[name]) { | ||
const itemName = prefix + name | ||
// skip topic methods | ||
if (remoteTopicProps.includes(propName)) return target[propName] | ||
if (level > 0) | ||
cachedItems[name] = createRemoteServiceItems( | ||
level - 1, | ||
createServiceItem, | ||
itemName + "/" | ||
) | ||
else cachedItems[name] = createServiceItem(itemName) | ||
} | ||
if (!cachedItems[propName]) { | ||
cachedItems[propName] = createRemote(session, name ? name + "/" + propName : propName) | ||
} | ||
return cachedItems[name] | ||
}, | ||
return cachedItems[propName] | ||
}, | ||
set(target, name, value) { | ||
cachedItems[name] = value | ||
return true | ||
}, | ||
set(target, propName, value) { | ||
cachedItems[propName] = value | ||
return true | ||
}, | ||
// Used in resubscribe | ||
ownKeys() { | ||
return Object.keys(cachedItems) | ||
}, | ||
} | ||
) | ||
// Used in resubscribe | ||
ownKeys() { | ||
return ["prototype", ...Object.keys(cachedItems)] | ||
}, | ||
}) | ||
} |
@@ -19,6 +19,2 @@ /** | ||
export function getServiceItem(services: Services, name: string): {item: ServiceItem; object: any} { | ||
if (!name) { | ||
return {item: null, object: null} | ||
} | ||
const names = name.split("/") | ||
@@ -28,13 +24,15 @@ | ||
if (typeof item == "object") { | ||
if ("getTopicName" in item) return {item: item as any, object: services} | ||
if (!item) { | ||
return {item: null, object: null} | ||
} | ||
if (!item) { | ||
if (names.length == 1) { | ||
if (item) { | ||
return {item: item as any, object: services} | ||
} else { | ||
return {item: null, object: null} | ||
} | ||
return getServiceItem(item as Services, names.slice(1).join("/")) | ||
} | ||
return {item, object: services} | ||
return getServiceItem(item as Services, names.slice(1).join("/")) | ||
} | ||
@@ -45,3 +43,8 @@ | ||
export interface RemoteTopic<D, P> { | ||
subscribe(consumer: DataConsumer<D>, params?: P, subscriptionKey?: any, callOpts?: CallOptions): Promise<any> | ||
subscribe( | ||
consumer: DataConsumer<D>, | ||
params?: P, | ||
subscriptionKey?: any, | ||
callOpts?: CallOptions | ||
): Promise<any> | ||
unsubscribe(params?: P, subscriptionKey?: any) | ||
@@ -48,0 +51,0 @@ get(params?: P, callOpts?: CallOptions): Promise<D> |
@@ -27,3 +27,2 @@ import {LocalTopicImpl} from "./local" | ||
private local: any, | ||
remoteLevel: number, | ||
private listeners: RpcSessionListeners, | ||
@@ -40,3 +39,3 @@ private connectionContext: RpcConnectionContext, | ||
) { | ||
this.remote = createRemote(remoteLevel, this) | ||
this.remote = createRemote(this) | ||
} | ||
@@ -459,7 +458,8 @@ | ||
Object.getOwnPropertyNames(remote).forEach(key => { | ||
if (typeof remote[key] == "object") { | ||
resubscribeTopics(remote[key]) | ||
} else { | ||
remote[key].resubscribe() | ||
} | ||
if (key == "prototype") return | ||
// because each item is always a topic; but those that not subscribed will not do a thing on resubscribe | ||
remote[key].resubscribe() | ||
resubscribeTopics(remote[key]) | ||
}) | ||
@@ -466,0 +466,0 @@ } |
@@ -14,3 +14,2 @@ import * as UUID from "uuid-js" | ||
remoteMiddleware?: Middleware | ||
clientLevel?: number | ||
messageParser?(data): any[] | ||
@@ -39,3 +38,2 @@ pingSendTimeout?: number | ||
remoteMiddleware: (ctx, next, params, messageType) => next(params), | ||
clientLevel: 0, | ||
pingSendTimeout: 40 * 1000, | ||
@@ -113,3 +111,2 @@ keepAliveTimeout: 120 * 1000, | ||
local, | ||
opts.clientLevel, | ||
{ | ||
@@ -173,3 +170,3 @@ messageIn: data => | ||
return createRemote(opts.clientLevel, sessions[clientId]) | ||
return createRemote(sessions[clientId]) | ||
}, | ||
@@ -176,0 +173,0 @@ isConnected, |
@@ -37,3 +37,2 @@ import {assert} from "chai" | ||
const rpcClient = await createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -104,3 +103,2 @@ {reconnect: true} | ||
const clientPromise = createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -177,3 +175,2 @@ { | ||
const client = await createRpcClient( | ||
1, | ||
async () => { | ||
@@ -230,3 +227,2 @@ return createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
client = await createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -267,3 +263,2 @@ { | ||
const client = await createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -320,3 +315,2 @@ { | ||
const client = await createRpcClient( | ||
1, | ||
async () => { | ||
@@ -323,0 +317,0 @@ const socket = createNodeWebsocket(`ws://localhost:${TEST_PORT}`) |
@@ -142,2 +142,58 @@ import {assert} from "chai" | ||
}) | ||
it("Non flat remote", async () => { | ||
await startTestServer({ | ||
async hello1() { | ||
return "yes1" | ||
}, | ||
nested: { | ||
async hello2() { | ||
return "yes2" | ||
}, | ||
}, | ||
}) | ||
const client = await createTestClient(0) | ||
assert.equal("yes1", await client.hello1()) | ||
assert.equal("yes2", await client.nested.hello2()) | ||
}) | ||
it("Item not found", async () => { | ||
await startTestServer({ | ||
async hello1() { | ||
return "yes1" | ||
}, | ||
nested: { | ||
async hello2() { | ||
return "yes2" | ||
}, | ||
}, | ||
}) | ||
const client = await createTestClient(0) | ||
try { | ||
await client.hello() | ||
assert.fail("Error expected") | ||
} catch (e) { | ||
assert.include(e.message, "not implemented") | ||
} | ||
try { | ||
await client.nested.hello() | ||
assert.fail("Error expected") | ||
} catch (e) { | ||
assert.include(e.message, "not implemented") | ||
} | ||
try { | ||
await client.nested.nested2.hello() | ||
assert.fail("Error expected") | ||
} catch (e) { | ||
assert.include(e.message, "not implemented") | ||
} | ||
}) | ||
}) |
@@ -52,3 +52,2 @@ import {createRpcClient, createRpcServer, RpcClientOptions, RpcServer} from "../src" | ||
await createRpcClient( | ||
level, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`, protocol), | ||
@@ -55,0 +54,0 @@ options |
@@ -17,3 +17,2 @@ import {assert} from "chai" | ||
const client = await createRpcClient( | ||
0, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -53,3 +52,2 @@ {} | ||
const client = await createRpcClient( | ||
0, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -56,0 +54,0 @@ {} |
@@ -58,3 +58,2 @@ import {assert} from "chai" | ||
const {remote: client} = await createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -83,2 +82,25 @@ { | ||
it("subscribe delivers data after subscription", async () => { | ||
const item = {r: "1"} | ||
await startTestServer({ | ||
test: { | ||
item: new LocalTopicImpl(async () => { | ||
return item | ||
}), | ||
}, | ||
}) | ||
const client = await createTestClient(0) | ||
let receivedItem | ||
await client.test.item.subscribe(() => { | ||
receivedItem = item | ||
}) | ||
await new Promise(resolve => setTimeout(resolve, 50)) | ||
assert.deepEqual(receivedItem, item) | ||
}) | ||
it("resubscribe", async () => { | ||
@@ -98,3 +120,2 @@ const item = {r: "1"} | ||
const client = await createRpcClient( | ||
1, | ||
() => { | ||
@@ -113,3 +134,3 @@ socket = createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
// first notificaiton right after subscription | ||
// first notification right after subscription | ||
await new Promise(resolve => setTimeout(resolve, 50)) | ||
@@ -152,3 +173,3 @@ assert.deepEqual(receivedItem, item) | ||
const {remote: client} = await createRpcClient(1, async () => | ||
const {remote: client} = await createRpcClient(async () => | ||
createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
@@ -207,3 +228,3 @@ ) | ||
const {remote: client} = await createRpcClient(1, async () => | ||
const {remote: client} = await createRpcClient(async () => | ||
createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
@@ -247,3 +268,3 @@ ) | ||
const {remote: client} = await createRpcClient(1, async () => | ||
const {remote: client} = await createRpcClient(async () => | ||
createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
@@ -292,3 +313,2 @@ ) | ||
const {remote: client} = await createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -330,3 +350,3 @@ { | ||
const {remote: client} = await createRpcClient(1, async () => | ||
const {remote: client} = await createRpcClient(async () => | ||
createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
@@ -375,3 +395,3 @@ ) | ||
const {remote: client} = await createRpcClient(1, async () => | ||
const {remote: client} = await createRpcClient(async () => | ||
createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
@@ -417,3 +437,3 @@ ) | ||
const {remote: client} = await createRpcClient(1, async () => | ||
const {remote: client} = await createRpcClient(async () => | ||
createNodeWebsocket(`ws://localhost:${TEST_PORT}`) | ||
@@ -459,3 +479,2 @@ ) | ||
const client = await createRpcClient( | ||
1, | ||
async () => createNodeWebsocket(`ws://localhost:${TEST_PORT}`), | ||
@@ -462,0 +481,0 @@ {reconnect: false} |
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
185882
4913