diff --git a/package.json b/package.json index 519c6e2..9cbe0b8 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,7 @@ "mocha": "^3.0.2", "node-fetch": "^1.6.3", "nodemon": "^1.11.0", - "rimraf": "^2.6.0", + "rimraf": "^2.6.1", "sinon": "^2.2.0", "sinon-chai": "^2.8.0", "ts-node": "^2.0.0", @@ -70,6 +70,7 @@ "ws": "^1.1.1" }, "dependencies": { - "deepmerge": "^1.3.2" + "deepmerge": "^1.3.2", + "json-stringify-safe": "^5.0.1" } } diff --git a/src/wire/Socket.spec.ts b/src/wire/Socket.spec.ts index fa956f1..18ccd23 100644 --- a/src/wire/Socket.spec.ts +++ b/src/wire/Socket.spec.ts @@ -226,6 +226,21 @@ describe('socket', () => { }); }); + it('handles circular references', () => { + const params: any = { + foo: 'bar', + }; + params.bar = params; + ws.on('message', payload => { + assertAndReplyTo(payload); + }); + + return socket.execute('hello', params) + .then(res => { + expect(res).to.equal('hi'); + }); + }); + it('emits a method sent to it', done => { ws.send(JSON.stringify(METHOD)); socket.on('method', (method: Method) => { diff --git a/src/wire/Socket.ts b/src/wire/Socket.ts index 78c756e..5aa8acb 100644 --- a/src/wire/Socket.ts +++ b/src/wire/Socket.ts @@ -7,6 +7,8 @@ import { resolveOn } from '../util'; import { Method, Packet, PacketState, Reply } from './packets'; import { ExponentialReconnectionPolicy, IReconnectionPolicy } from './reconnection'; +import stringify = require('json-stringify-safe'); //tslint:disable-line + /** * Close codes that are deemed to be recoverable by the reconnection policy */ @@ -339,7 +341,8 @@ export class InteractiveSocket extends EventEmitter { } private sendRaw(packet: any) { - const data = JSON.stringify(packet); + // Replace circular references with nothing. + const data = stringify(packet, null, 0, () => {/** */}); const payload = data; this.emit('send', payload); diff --git a/types/json-stringify-safe.d.ts b/types/json-stringify-safe.d.ts new file mode 100644 index 0000000..4ff9e08 --- /dev/null +++ b/types/json-stringify-safe.d.ts @@ -0,0 +1,10 @@ +declare module 'json-stringify-safe' { + function stringify( + obj: object, + replacer?: (number | string)[] | null, + space?: string | number, + decycler: (key:string, value: any) => any + ): string + + export = stringify; +}