publication-server
Advanced tools
Comparing version 1.5.0 to 1.5.1
@@ -188,4 +188,10 @@ publication-client | ||
### Client changelog | ||
See [the server changelog](https://github.com/mixmaxhq/publication-server/blob/master/README.md#server-changelog) for releases pre-1.4.6. | ||
* 1.4.8 Add ES6 `Promise` polyfill | ||
* 1.4.7 Use `lodash.cloneDeep` to ensure that we don't emit direct object references during event emission. | ||
* 1.4.6 Prevent `Subscription#whenReady` from resolving prematurely after the websocket connects; implement `PublicationClient#whenConnected` | ||
[meteor-ddp]: https://github.com/meteor/meteor/blob/devel/packages/ddp/DDP.md |
@@ -9,2 +9,3 @@ 'use strict'; | ||
import Subscription from './Subscription'; | ||
import { Promise } from 'es6-promise'; | ||
@@ -74,2 +75,3 @@ /** | ||
_.each(this._subscriptions, (sub) => { | ||
sub._reset(); | ||
sub._start(); | ||
@@ -95,18 +97,18 @@ }); | ||
switch(msg.msg) { | ||
case 'added': | ||
case 'changed': | ||
case 'removed': | ||
this[`_on${initialTitleCase(msg.msg)}`](msg); | ||
break; | ||
case 'connected': | ||
this._isConnected = true; | ||
this.emit('connected'); | ||
break; | ||
case 'ready': | ||
this.emit('ready', msg); | ||
break; | ||
default: | ||
this.emit(msg.msg, msg); | ||
break; | ||
switch (msg.msg) { | ||
case 'added': | ||
case 'changed': | ||
case 'removed': | ||
this[`_on${initialTitleCase(msg.msg)}`](msg); | ||
break; | ||
case 'connected': | ||
this._isConnected = true; | ||
this.emit('connected'); | ||
break; | ||
case 'ready': | ||
this.emit('ready', msg); | ||
break; | ||
default: | ||
this.emit(msg.msg, msg); | ||
break; | ||
} | ||
@@ -116,3 +118,3 @@ } | ||
/** | ||
* Returns a promise that will be resolved once the the publicated provider | ||
* Returns a promise that will be resolved once the the publication provider | ||
* acknowledges to us that we are `connected`. | ||
@@ -123,3 +125,9 @@ * | ||
whenConnected() { | ||
return this._whenConnected; | ||
return new Promise((resolve) => { | ||
if (this._isConnected) { | ||
resolve(); | ||
} else { | ||
this.once('connected', resolve); | ||
} | ||
}); | ||
} | ||
@@ -246,3 +254,3 @@ | ||
* @returns {Boolean} Whether the client is connected to the server or not. | ||
*/ | ||
*/ | ||
get isConnected() { | ||
@@ -260,2 +268,2 @@ return this._isConnected; | ||
export default PublicationClient; | ||
export default PublicationClient; |
'use struct'; | ||
import _ from 'underscore'; | ||
import cloneDeep from 'lodash.cloneDeep'; | ||
import EventEmitter from 'eventemitter3'; | ||
@@ -36,3 +37,5 @@ | ||
this.emit('added', doc); | ||
// Make sure that we emit a cloned copy, so that no consumer holds a direct | ||
// reference to the underlying document. | ||
this.emit('added', cloneDeep(doc)); | ||
} | ||
@@ -70,3 +73,6 @@ | ||
} | ||
this.emit('changed', doc, changeset); | ||
// Make sure that we emit a cloned copy, so that no consumer holds a direct | ||
// reference to the underlying document. | ||
this.emit('changed', cloneDeep(doc), changeset); | ||
} | ||
@@ -121,2 +127,2 @@ | ||
export default LocalCollection; | ||
export default LocalCollection; |
@@ -6,2 +6,4 @@ 'use strict'; | ||
import { Promise } from 'es6-promise'; | ||
/** | ||
@@ -32,5 +34,2 @@ * A Subscription encapsulates the logic of subscribing to server side | ||
this._params = params; | ||
this._isReady = false; | ||
this._isFailed = false; | ||
this._isStopped = false; | ||
@@ -40,2 +39,4 @@ this._boundOnReady = this._onReady.bind(this); | ||
this._boundOnNoSubPostInit = this._onNoSubPostInitialization.bind(this); | ||
this._reset(); | ||
this._start(); | ||
@@ -45,6 +46,23 @@ } | ||
/** | ||
* Prepare to start the subscription. May be called after starting the subscription without | ||
* having stopped the subscription using `stop`. This is useful if the connection was disconnected | ||
* and we are reconnecting. | ||
*/ | ||
_reset() { | ||
this._isReady = false; | ||
this._isFailed = false; | ||
this._initializationError = null; | ||
this._isStopped = false; | ||
} | ||
/** | ||
* Starts a subscription (sends the initial `sub` message) only once the | ||
* connection is ready. | ||
* | ||
* `_reset` must be called first. | ||
*/ | ||
_start() { | ||
// If we hit this, someone forgot to call `_reset`. | ||
if (this._isReady) throw new Error(`Subscription ${this._id} is already started.`); | ||
if (this._connection._isConnected) { | ||
@@ -192,2 +210,2 @@ this._sendSubMsg(); | ||
export default Subscription; | ||
export default Subscription; |
@@ -14,4 +14,4 @@ 'use strict'; | ||
function isMatch(doc, selector) { | ||
var keys = _.keys(selector), | ||
length = keys.length; | ||
var keys = _.keys(selector); | ||
var length = keys.length; | ||
if (doc === null) return !length; | ||
@@ -30,5 +30,5 @@ var obj = Object(doc); | ||
if (objKeys.length === 1 && objKeys[0] === '$elemMatch') { | ||
var arrayVals = obj[key], | ||
elemMatchQuery = selector[key].$elemMatch, | ||
foundMatch = false; | ||
var arrayVals = obj[key]; | ||
var elemMatchQuery = selector[key].$elemMatch; | ||
var foundMatch = false; | ||
for (var j = 0; j < arrayVals.length; j++) { | ||
@@ -35,0 +35,0 @@ if (isMatch(arrayVals[j], elemMatchQuery)) { |
{ | ||
"name": "publication-server", | ||
"version": "1.5.0", | ||
"version": "1.5.1", | ||
"description": "", | ||
"main": "src/index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"lint": "eslint ." | ||
}, | ||
@@ -22,3 +23,11 @@ "keywords": [ | ||
"uws": "^0.14.1" | ||
} | ||
}, | ||
"devDependencies": { | ||
"eslint": ">=3", | ||
"eslint-config-mixmax": "^0.6.0", | ||
"pre-commit": "^1.2.2" | ||
}, | ||
"pre-commit": [ | ||
"lint" | ||
] | ||
} |
@@ -135,3 +135,7 @@ publication-server | ||
### Changelog | ||
### Server changelog | ||
May contain some client releases pre-1.5.0. | ||
* 1.5.1 Prevent `Subscription#whenReady` from resolving prematurely after the websocket connects; implement `PublicationClient#whenConnected` | ||
* 1.5.0 Use Yarn; fix `uws` dependency after previous versions were unpublished. | ||
@@ -138,0 +142,0 @@ * 1.4.5 `err._publicationName` -> `err.publicationName` |
@@ -127,3 +127,26 @@ 'use strict'; | ||
const name = msg.name; | ||
const params = msg.params; | ||
let params = msg.params; | ||
// Attempt to parse string params, since a JSON array is required. | ||
if (_.isString(params)) { | ||
try { | ||
params = JSON.parse(params); | ||
} catch (err) { | ||
this.send({ | ||
msg: 'error', | ||
reason: 'unable-to-parse-params', | ||
offendingMessage: msg | ||
}); | ||
return; | ||
} | ||
} | ||
if (!_.isArray(params)) { | ||
this.send({ | ||
msg: 'error', | ||
reason: 'invalid-params', | ||
offendingMessage: msg | ||
}); | ||
return; | ||
} | ||
const handler = this.server._subscriptions[name]; | ||
@@ -231,3 +254,3 @@ // If the publication doesn't exist, reply with `nosub`. | ||
this.spark.on('error', (err) => { | ||
this.spark.on('error', () => { | ||
this.stop(); | ||
@@ -242,3 +265,3 @@ }); | ||
reason: 'must-provide-msg-type', | ||
offendingMessage: msg | ||
offendingMessage: data | ||
}); | ||
@@ -256,2 +279,2 @@ return; | ||
module.exports = Session; | ||
module.exports = Session; |
@@ -165,2 +165,2 @@ 'use strict'; | ||
module.exports = Subscription; | ||
module.exports = Subscription; |
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
254527
21
6115
152
3