diff --git a/index.js b/index.js index b3537d5..9819ab1 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ const transports = require('./transports'); function rawr({ transport, timeout = 0, handlers = {}, methods, idGenerator }) { let callId = 0; // eslint-disable-next-line no-param-reassign - methods = methods || handlers; // backwards compat + methods = methods || handlers || {}; // backwards compat const pendingCalls = {}; const methodHandlers = {}; const notificationEvents = new EventEmitter(); @@ -111,6 +111,8 @@ function rawr({ transport, timeout = 0, handlers = {}, methods, idGenerator }) { const testArg = args.pop(); if (testArg && typeof testArg === 'object' && !Array.isArray(testArg)) { config = testArg; + } else { + args.push(testArg); } } return sendMessage(name, args, config || {}); @@ -132,6 +134,28 @@ function rawr({ transport, timeout = 0, handlers = {}, methods, idGenerator }) { } }); + const configurableNotifiersProxy = new Proxy({}, { + get: (target, name) => { + return (...args) => { + let config; + if (args.length) { + const testArg = args.pop(); + if (testArg && typeof testArg === 'object' && !Array.isArray(testArg)) { + config = testArg; + } else { + args.push(testArg); + } + } + const msg = { + jsonrpc: '2.0', + method: name, + params: args + }; + transport.send(msg, config || {}); + }; + } + }); + const notifications = new Proxy({}, { get: (target, name) => { return (callback) => { @@ -148,6 +172,7 @@ function rawr({ transport, timeout = 0, handlers = {}, methods, idGenerator }) { addHandler, notifications, notifiers, + notifiersExt: configurableNotifiersProxy, transport, }; } diff --git a/test/index.js b/test/index.js index 8edfb39..1c3e01f 100644 --- a/test/index.js +++ b/test/index.js @@ -12,14 +12,20 @@ function mockTransports() { a.on('message', (msg) => { a.emit('rpc', msg); }); - a.send = (msg) => { + a.send = (msg, config) => { b.emit('message', msg); + if (config) { + b.emit('config', config); + } }; b.on('message', (msg) => { b.emit('rpc', msg); }); - b.send = (msg) => { + b.send = (msg, config) => { + if (config) { + a.emit('config', config); + } a.emit('message', msg); }; @@ -139,6 +145,46 @@ describe('rawr', () => { clientB.notifiers.doSomething('testing_notification'); }); + it('client should have notifiersExt method', () => { + const { a } = mockTransports(); + const client = rawr({ transport: a }); + client.should.have.property('notifiersExt'); + (typeof client.notifiersExt).should.equal('object'); + }); + + it('client should be able to send a notification with notifiersExt', (done) => { + const { a, b } = mockTransports(); + const clientA = rawr({ transport: a }); + const clientB = rawr({ transport: b }); + + clientA.notifications.ondoSomething((someData) => { + someData.should.equal('testing_notification_ext'); + done(); + }); + + clientB.notifiersExt.doSomething('testing_notification_ext'); + }); + + it('client should pass config to transport when using notifiersExt', (done) => { + const { a, b } = mockTransports(); + const clientA = rawr({ transport: a }); + const clientB = rawr({ transport: b }); + + let receivedConfig = false; + a.on('config', (config) => { + config.should.deep.equal({ postMessageOptions: { transfer: ['test'] } }); + receivedConfig = true; + }); + + clientA.notifications.ondoConfigTest((someData) => { + someData.should.equal('config_test'); + receivedConfig.should.equal(true); + done(); + }); + + clientB.notifiersExt.doConfigTest('config_test', { postMessageOptions: { transfer: ['test'] } }); + }); + it('client should fail on a configured timeout', async () => { const { a, b } = mockTransports(); const clientA = rawr({ transport: a, handlers: { slowFunction, hi } });