Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

ddp.js

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ddp.js - npm Package Compare versions

Comparing version 1.1.0 to 2.0.0

.babelrc

16

CHANGELOG.md

@@ -1,3 +0,14 @@

##1.1.0 (July 11, 2015)
## 2.0.0 (February 12, 2016)
Distribute as individual modules in `lib` instead of bundle in `dist`.
Added method to disconnect.
Added options to control auto-connect and auto-reconnect behaviour. As it turns
out they could indeed be useful, for instance when one wants to simulate a
connection scenario (e.g. in stress tests) and needs to have fine-grained
control on the lifecycle of the connection.
## 1.1.0 (July 11, 2015)
Moved the code to use ES6. In the process, I also refactored it a bit to use

@@ -15,5 +26,4 @@ less "exotic" patterns, but there _should be_ no breaking changes to the public

## 1.0.0 (January 11, 2015)
##1.0.0 (January 11, 2015)
The library has been rewritten from scratch and its scope somewhat reduced. The

@@ -20,0 +30,0 @@ purpose of the rewrite, other than simplification, was to implement better

50

package.json
{
"name": "ddp.js",
"version": "1.1.0",
"version": "2.0.0",
"description": "ddp javascript client",
"main": "dist/ddp.js",
"main": "lib/ddp.js",
"scripts": {
"build": "gulp build",
"build": "babel src --out-dir lib",
"clean": "rimraf lib coverage",
"coverage": "babel-node $(npm bin)/isparta cover $(npm bin)/_mocha -- --recursive test/unit",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"dev": "gulp",
"lint": "eslint src/",
"test": "istanbul cover _mocha --report lcovonly -- -R spec --compilers js:babel/register"
"dev": "npm test -- --watch",
"lint": "eslint src test",
"prepublish": "npm run clean && npm run build",
"test": "mocha --compilers js:babel-core/register --recursive test/unit",
"start-meteor": "cd test/server/ && meteor",
"e2e-test": "mocha --compilers js:babel-core/register --recursive test/e2e",
"e2e-dev": "npm run e2e-test -- --watch"
},

@@ -29,22 +35,20 @@ "repository": {

"devDependencies": {
"babel": "^5.6.14",
"babel-core": "^5.6.17",
"babel-loader": "^5.3.1",
"chai": "^3.0.0",
"coveralls": "^2.11.2",
"eslint": "^0.24.1",
"gulp": "^3.9.0",
"gulp-eslint": "^0.15.0",
"gulp-spawn-mocha": "^2.2.1",
"gulp-util": "^3.0.6",
"istanbul": "^0.3.17",
"mocha": "^2.2.5",
"node-libs-browser": "^0.5.2",
"sinon": "^1.15.4",
"sinon-chai": "^2.8.0",
"webpack": "^1.10.1"
"babel-cli": "^6.5.1",
"babel-core": "^6.5.1",
"babel-eslint": "^4.1.8",
"babel-loader": "^6.2.2",
"babel-preset-es2015": "^6.5.0",
"babel-preset-stage-0": "^6.5.0",
"chai": "^3.5.0",
"coveralls": "^2.11.6",
"eslint": "^1.10.3",
"faye-websocket": "^0.10.0",
"isparta": "^4.0.0",
"mocha": "^2.4.5",
"sinon": "^1.17.3",
"sinon-chai": "^2.8.0"
},
"dependencies": {
"wolfy87-eventemitter": "^4.2.11"
"wolfy87-eventemitter": "^4.3.0"
}
}

@@ -0,1 +1,2 @@

[![npm version](https://badge.fury.io/js/ddp.js.svg)](https://badge.fury.io/js/ddp.js)
[![Build Status](https://travis-ci.org/mondora/ddp.js.svg?branch=master)](https://travis-ci.org/mondora/ddp.js)

@@ -6,13 +7,8 @@ [![Coverage Status](https://img.shields.io/coveralls/mondora/ddp.js.svg)](https://coveralls.io/r/mondora/ddp.js?branch=master)

#WARNING
Breaking changes from ~0.6.0 to >=1.0.0, [read the
CHANGELOG](https://github.com/mondora/ddp.js/blob/master/CHANGELOG.md) for more
info.
# ddp.js
#ddp.js
A javascript isomorphic/universal ddp client.
A javascript isomorphic ddp client.
## What is it for?
##What is it for?
The purpose of this library is:

@@ -25,37 +21,31 @@

##Install
## Install
Via npm
npm install ddp.js
Or via bower
## Example usage
bower install ddp.js
##Example usage
```javascript
var DDP = require("ddp.js");
var options = {
endpoint: "http://localhost:3000/websocket",
```js
const DDP = require("ddp.js");
const options = {
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: WebSocket
};
var ddp = new DDP(options);
const ddp = new DDP(options);
ddp.on("connected", function () {
ddp.on("connected", () => {
console.log("Connected");
});
var subId = ddp.sub("mySubscription");
ddp.on("ready", function (message) {
if (message.id === subId) {
const subId = ddp.sub("mySubscription");
ddp.on("ready", message => {
if (message.subs.includes(subId)) {
console.log("mySubscription ready");
}
});
ddp.on("added", function (message) {
ddp.on("added", message => {
console.log(message.collection);
});
var myLoginParams = {
const myLoginParams = {
user: {

@@ -66,4 +56,4 @@ email: "user@example.com"

};
var methodId = ddp.method("login", [myLoginParams]);
ddp.on("result", function (message) {
const methodId = ddp.method("login", [myLoginParams]);
ddp.on("result", message => {
if (message.id === methodId && !message.error) {

@@ -75,15 +65,21 @@ console.log("Logged in!");

##Tests
## Developing
`npm test` to run tests. Coverage reports are generated in the `coverage/`
directory.
After cloning the repository, install `npm` dependencies with `npm install`.
Run `npm test` to run unit tests, or `npm run dev` to have `mocha` re-run your
tests when source or test files change.
##Public API
To run e2e tests, first [install meteor](https://www.meteor.com/install). Then,
start the meteor server with `npm run start-meteor`. Finally, run
`npm run e2e-test` to run the e2e test suite, or `npm run e2e-dev` to have
`mocha` re-run the suite when source or test files change.
###new DDP(options)
## Public API
### new DDP(options)
Creates a new DDP instance. After being constructed, the instance will
establish a connection with the DDP server and will try to maintain it open.
####Arguments
#### Arguments

@@ -105,4 +101,15 @@ - `options` **object** *required*

####Returns
- `autoConnect` **boolean** *optional* [default: `true`]: whether to establish
the connection to the server upon instantiation. When `false`, one can
manually establish the connection with the `connect` method.
- `autoReconnect` **boolean** *optional* [default: `true`]: whether to try to
reconnect to the server when the socket connection closes, unless the closing
was initiated by a call to the `disconnect` method.
- `reconnectInterval` **number** *optional* [default: 10000]: the interval in ms
between reconnection attempts.
#### Returns
A new DDP instance, which is also an `EventEmitter` instance.

@@ -112,45 +119,74 @@

###DDP.method(name, params)
### DDP.method(name, params)
Calls a remote method.
####Arguments
#### Arguments
- `name` **string** *required*: name of the method to call.
- `params` **array** *required*: parameters to pass to the remote method. Pass
an empty array if you do not wish to pass any parameters.
- `params` **array** *required*: array of parameters to pass to the remote
method. Pass an empty array if you do not wish to pass any parameters.
####Returns
#### Returns
The unique `id` (string) corresponding to the method call.
#### Example usage
Server code:
```js
Meteor.methods({
myMethod (param_0, param_1, param_2) {
/* ... */
}
});
```
Client code:
```js
const methodCallId = ddp.method("myMethod", [param_0, param_1, param_2]);
```
---
###DDP.sub(name, params)
### DDP.sub(name, params)
Subscribes to a server publication.
####Arguments
#### Arguments
- `name` **string** *required*: name of the server publication.
- `params` **array** *required*: parameters to pass to the server publish
function. Pass an empty array if you do not wish to pass any parameters.
- `params` **array** *required*: array of parameters to pass to the server
publish function. Pass an empty array if you do not wish to pass any
parameters.
####Returns
#### Returns
The unique `id` (string) corresponding to the subscription call.
#### Example usage
Server code:
```js
Meteor.publish("myPublication", (param_0, param_1, param_2) {
/* ... */
});
```
Client code:
```js
const subscriptionId = ddp.sub("myPublication", [param_0, param_1, param_2]);
```
---
###DDP.unsub(id)
### DDP.unsub(id)
Unsubscribes to a previously-subscribed server publication.
####Arguments
#### Arguments
- `id` **string** *required*: id of the subscription.
####Returns
#### Returns

@@ -160,6 +196,38 @@ The `id` corresponding to the subscription call (not of much use, but I return

##Public events
---
###Connection events
### DDP.connect()
Connects to the ddp server. The method is called automatically by the class
constructor if the `autoConnect` option is set to `true` (default behaviour).
So there generally should be no need for the developer to call the method
themselves.
#### Arguments
None
#### Returns
None
---
### DDP.disconnect()
Disconnects from the ddp server by closing the `WebSocket` connection. You can
listen on the `disconnected` event to be notified of the disconnection.
#### Arguments
None
#### Returns
None
## Public events
### Connection events
- `connected`: emitted with no arguments when the DDP connection is

@@ -170,3 +238,3 @@ established.

###Subscription events
### Subscription events

@@ -183,3 +251,3 @@ All the following events are emitted with one argument, the parsed DDP message.

###Method events
### Method events

@@ -186,0 +254,0 @@ All the following events are emitted with one argument, the parsed DDP message.

@@ -15,3 +15,3 @@ import EventEmitter from "wolfy87-eventemitter";

];
const RECONNECT_INTERVAL = 10000;
const DEFAULT_RECONNECT_INTERVAL = 10000;

@@ -21,6 +21,3 @@ export default class DDP extends EventEmitter {

emit () {
var args = arguments;
setTimeout(() => {
super.emit.apply(this, args);
}, 0);
setTimeout(super.emit.bind(this, ...arguments), 0);
}

@@ -34,3 +31,8 @@

this.messageQueue = new Queue((message) => {
// Default `autoConnect` and `autoReconnect` to true
this.autoConnect = (options.autoConnect !== false);
this.autoReconnect = (options.autoReconnect !== false);
this.reconnectInterval = options.reconnectInterval || DEFAULT_RECONNECT_INTERVAL;
this.messageQueue = new Queue(message => {
if (this.status === "connected") {

@@ -60,7 +62,12 @@ this.socket.send(message);

this.emit("disconnected");
// Schedule a reconnection
setTimeout(this.socket.connect.bind(this.socket), RECONNECT_INTERVAL);
if (this.autoReconnect) {
// Schedule a reconnection
setTimeout(
this.socket.open.bind(this.socket),
this.reconnectInterval
);
}
});
this.socket.on("message:in", (message) => {
this.socket.on("message:in", message => {
if (message.msg === "connected") {

@@ -79,8 +86,24 @@ this.status = "connected";

this.socket.connect();
if (this.autoConnect) {
this.connect();
}
}
connect () {
this.socket.open();
}
disconnect () {
/*
* If `disconnect` is called, the caller likely doesn't want the
* the instance to try to auto-reconnect. Therefore we set the
* `autoReconnect` flag to false.
*/
this.autoReconnect = false;
this.socket.close();
}
method (name, params) {
var id = uniqueId();
const id = uniqueId();
this.messageQueue.push({

@@ -96,3 +119,3 @@ msg: "method",

sub (name, params) {
var id = uniqueId();
const id = uniqueId();
this.messageQueue.push({

@@ -99,0 +122,0 @@ msg: "sub",

@@ -21,11 +21,9 @@ export default class Queue {

process () {
setTimeout(() => {
if (this.queue.length !== 0) {
var ack = this.consumer(this.queue[0]);
if (ack) {
this.queue.shift();
this.process();
}
if (this.queue.length !== 0) {
const ack = this.consumer(this.queue[0]);
if (ack) {
this.queue.shift();
this.process();
}
}, 0);
}
}

@@ -32,0 +30,0 @@

@@ -6,6 +6,3 @@ import EventEmitter from "wolfy87-eventemitter";

emit () {
var args = arguments;
setTimeout(() => {
super.emit.apply(this, args);
}, 0);
setTimeout(super.emit.bind(this, ...arguments), 0);
}

@@ -17,6 +14,7 @@

this.endpoint = endpoint;
this.rawSocket = null;
}
send (object) {
var message = JSON.stringify(object);
const message = JSON.stringify(object);
this.rawSocket.send(message);

@@ -27,16 +25,51 @@ // Emit a copy of the object, as the listener might mutate it.

connect () {
open () {
/*
* Makes `open` a no-op if there's already a `rawSocket`. This avoids
* memory / socket leaks if `open` is called twice (e.g. by a user
* calling `ddp.connect` twice) without properly disposing of the
* socket connection. `rawSocket` gets automatically set to `null` only
* when it goes into a closed or error state. This way `rawSocket` is
* disposed of correctly: the socket connection is closed, and the
* object can be garbage collected.
*/
if (this.rawSocket) {
return;
}
this.rawSocket = new this.SocketConstructor(this.endpoint);
/*
* The `open`, `error` and `close` events are simply proxy-ed to `_socket`.
* The `message` event is instead parsed into a js object (if possible) and
* then passed as a parameter of the `message:in` event
* Calls to `onopen` and `onclose` directly trigger the `open` and
* `close` events on the `Socket` instance.
*/
this.rawSocket.onopen = () => this.emit("open");
this.rawSocket.onerror = (error) => this.emit("error", error);
this.rawSocket.onclose = () => this.emit("close");
this.rawSocket.onmessage = (message) => {
this.rawSocket.onclose = () => {
this.emit("close");
this.rawSocket = null;
};
/*
* Calls to `onerror` trigger the `close` event on the `Socket`
* instance, and cause the `rawSocket` object to be disposed of.
* Since it's not clear what conditions could cause the error and if
* it's possible to recover from it, we prefer to always close the
* connection (if it isn't already) and dispose of the socket object.
*/
this.rawSocket.onerror = () => {
// It's not clear what the socket lifecycle is when errors occurr.
// Hence, to avoid the `close` event to be emitted twice, before
// manually closing the socket we de-register the `onclose`
// callback.
delete this.rawSocket.onclose;
// Safe to perform even if the socket is already closed
this.rawSocket.close();
this.emit("close");
this.rawSocket = null;
};
/*
* Calls to `onmessage` trigger a `message:in` event on the `Socket`
* instance only once the message (first parameter to `onmessage`) has
* been successfully parsed into a javascript object.
*/
this.rawSocket.onmessage = message => {
var object;

@@ -50,3 +83,4 @@ try {

// Outside the try-catch block as it must only catch JSON parsing
// errors, not errors that may occur inside a "message:in" event handler
// errors, not errors that may occur inside a "message:in" event
// handler
this.emit("message:in", object);

@@ -57,2 +91,11 @@ };

close () {
/*
* Avoid throwing an error if `rawSocket === null`
*/
if (this.rawSocket) {
this.rawSocket.close();
}
}
}
var i = 0;
export function uniqueId () {

@@ -4,0 +3,0 @@ return (i++).toString();

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

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc