Showing preview only (490K chars total). Download the full file or copy to clipboard to get everything.
Repository: Gregivy/simpleddp
Branch: master
Commit: 4bd415ee52e4
Files: 74
Total size: 465.7 KB
Directory structure:
gitextract_hjf1yyvb/
├── .babelrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── core/
│ ├── .babelrc
│ ├── .eslintrc
│ ├── .gitignore
│ ├── .npmignore
│ ├── .npmrc
│ ├── .travis.yml
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ ├── ddp.js
│ │ ├── queue.js
│ │ ├── socket.js
│ │ └── utils.js
│ └── test/
│ ├── e2e/
│ │ ├── connection.js
│ │ ├── methods.js
│ │ └── subscriptions.js
│ ├── server/
│ │ ├── .meteor/
│ │ │ ├── .finished-upgraders
│ │ │ ├── .gitignore
│ │ │ ├── .id
│ │ │ ├── packages
│ │ │ ├── platforms
│ │ │ ├── release
│ │ │ └── versions
│ │ ├── methods.js
│ │ └── publications.js
│ └── unit/
│ ├── ddp.js
│ ├── queue.js
│ ├── socket.js
│ └── utils.js
├── custom_ejson.md
├── docs/
│ ├── ddpCollection.html
│ ├── ddpEventListener.html
│ ├── ddpOnChange.html
│ ├── ddpReactiveCollection.html
│ ├── ddpReactiveDocument.html
│ ├── ddpReducer.html
│ ├── ddpSubscription.html
│ ├── index.html
│ ├── scripts/
│ │ ├── main.js
│ │ └── prettify/
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
│ ├── simpleDDP.html
│ └── styles/
│ ├── main.css
│ ├── prettify-jsdoc.css
│ └── prettify-tomorrow.css
├── jsdoc_conf.json
├── notes.md
├── package.json
├── src/
│ ├── classes/
│ │ ├── ddpCollection.js
│ │ ├── ddpEventListener.js
│ │ ├── ddpOnChange.js
│ │ ├── ddpReactiveCollection.js
│ │ ├── ddpReactiveDocument.js
│ │ ├── ddpReducer.js
│ │ └── ddpSubscription.js
│ ├── helpers/
│ │ ├── fullCopy.js
│ │ └── isequal.js
│ └── simpleddp.js
└── test/
├── test_call.js
├── test_collectionfetch.js
├── test_importexport.js
├── test_onchange.js
├── test_reactive.js
├── test_reactiveone.js
└── test_sub.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .babelrc
================================================
{
"presets": ["env", "stage-0"],
"plugins": [
"add-module-exports"
]
}
================================================
FILE: .gitignore
================================================
.DS_Store
/lib/
/node_modules/
================================================
FILE: .npmignore
================================================
simpleddp.png
/src/
/docs/
================================================
FILE: .travis.yml
================================================
language: node_js
node_js:
- 8
script:
- npm test
================================================
FILE: CHANGELOG.md
================================================
# CHANGELOG
## 2.3.0
* `simpleddp-core` is now a part of `simpleddp`.
* Fixed bug with setting `sort` in `reactive()` method of `ddpCollection` class (see https://github.com/Gregivy/simpleddp/issues/13).
* Added new methods `skip()`, `limit()` for `ddpReactiveCollection` class. Both methods are syntactic sugar for `settings()` method.
* Updated `sub()` method. The returned subscription will be restarted if the same subscription exists and is stopped (see https://github.com/Gregivy/simpleddp/issues/11).
* Updated `connect()` method. The method now supports `maxTimeout` (see https://github.com/Gregivy/simpleddp/issues/18).
* New tests added.
## 2.2.4
* Fixed bug with auto re-subscribing when `clearDataOnReconnection=true` (default).
Pseudo removing messages arrived later than the first subscription. It was causing
possible data loss.
* Fixex bug with resolving `clearData()`.
* Updated `simpleddp-core` package.
* Small changes in plugin system, added event `clientReady`.
## 2.2.3
* Fixed bug with `ddpSubscription.restart` and `ddpSubscription.nosub` when error comes from the server.
## 2.2.2
* Fixed bug with `maxTimeout`.
## 2.2.1
* Fixed bug with `ddpReactiveCollection` sorting. In some cases data array didn't recieve valid updates.
## 2.2.0
* `restartSubsOnConnect` method renamed to `restartSubs`.
* Added property `clearDataOnReconnection` to `simpleDDP` class constructor.
* Docs improvments.
## 2.1.1
* Fixed bug with `ddpSubscription` restart (loosing arguments).
* Fixed rare situation with *ddp* message *removed* arriving before any other.
* API fix.
## 2.1.0
* Fixed dependencies vulnerabilities.
* Added documentation for custom EJSON types.
* Added `maxTimeout` to support the maximum wait for a response from the server to the method call.
## 2.0.2
* Fixed dependencies vulnerabilities.
## 2.0.1
* Fix. If `change` message arrives and no collection is found `simpleddp` acts like it is an `added` message.
## 2.0.0
* Added semantic versioning.
* `call` renamed to `apply`.
* New `call` works like `apply` but accepts parameters for server method as a list of function arguments.
* `subid` property of the subscription object renamed to `subscriptionId`.
* Added `subscribe` method. Works like `sub` but accepts parameters for server publication as a list of function arguments.
## 1.2.3
* Updated `simpleddp-core` package.
## 1.2.2
* Fixed bug with EJSON types.
## 1.2.1
* Updated `simpleddp-core` package.
* Added support for putting method call at the beginning of the requests queue.
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018-2019 Plyushch Gregory (Gregivy)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
[](https://badge.fury.io/js/simpleddp)
[](https://travis-ci.org/Gregivy/simpleddp)
[](https://david-dm.org/gregivy/simpleddp)
[](https://david-dm.org/gregivy/simpleddp#info=devDependencies)
<p align="center">
<img width="300" height="300" src="https://github.com/Gregivy/simpleddp/raw/master/simpleddp.png">
</p>
# SimpleDDP 🥚
The aim of this library is to simplify the process of working with Meteor.js server over DDP protocol using external JS environments (like Node.js, Cordova, Ionic, ReactNative, etc).
It is battle tested 🏰 in production and ready to use 🔨.
If you like this project ⭐ is always welcome.
**Important**
SimpleDDP is written in ES6 and uses modern features like *promises*. Though its precompiled with Babel, your js environment must support ES6 features. So if you are planning to use SimpleDDP be sure that your js environment supports ES6 features or include polyfills yourself (like Babel Polyfill).
Project uses [semantic versioning 2.0.0](https://semver.org/spec/v2.0.0.html).
DDP (protocol) [specification](https://github.com/meteor/meteor/blob/devel/packages/ddp/DDP.md).
## [CHANGE LOG](https://github.com/Gregivy/simpleddp/blob/master/CHANGELOG.md)
## Install
`npm install simpleddp --save`
## [Documentation](https://gregivy.github.io/simpleddp/simpleDDP.html)
## Plugins
* [simpleddp-plugin-login](https://github.com/Gregivy/simpleddp-plugin-login)
## [Adding custom EJSON types](https://github.com/Gregivy/simpleddp/blob/master/custom_ejson.md) ⭐
## Example
First of all you need WebSocket implementation for your node app.
We will use [isomorphic-ws](https://www.npmjs.com/package/isomorphic-ws) package for this
since it works on the client and serverside.
`npm install isomorphic-ws ws --save`
Import/require `simpleDDP`.
```javascript
const simpleDDP = require("simpleddp"); // nodejs
const ws = require("isomorphic-ws");
```
or
```javascript
import simpleDDP from 'simpleDDP'; // ES6
import ws from 'isomorphic-ws';
```
Now you should make a new simpleDDP instance.
```javascript
let opts = {
endpoint: "ws://someserver.com/websocket",
SocketConstructor: ws,
reconnectInterval: 5000
};
const server = new simpleDDP(opts);
```
Connection is not going to be established immediately after you create a simpleDDP instance. If you need to check your connection simply use `server.connected` property which is `true` if you are connected to the server, otherwise it's `false`.
You can also add some events for connection status.
```javascript
server.on('connected', () => {
// do something
});
server.on('disconnected', () => {
// for example show alert to user
});
server.on('error', (e) => {
// global errors from server
});
```
As an alternative you can use a *async/await* style (or `then(...)`).
```javascript
(async ()=>{
await server.connect();
// connection is ready here
})();
```
The next thing we are going to do is subscribing to some publications.
```javascript
let userSub = server.subscribe("user_pub");
let otherSub = server.subscribe("other_pub",'param1',2); // you can specify arguments for subscription
(async ()=>{
await userSub.ready();
let nextSub = server.subscribe("next_pub"); // subscribing after userSub is ready
await nextSub.ready();
//all subs are ready here
})();
```
You can fetch all things you've subscribed for using [server.collection](https://gregivy.github.io/simpleddp/simpleDDP.html#collection) method.
Also you can get reactive data sources (plain js objects which will be automatically updated if something changes on the server).
```javascript
(async ()=>{
// call some method
await server.call('somemethod');
let userSub = server.subscribe("user",userId);
await userSub.ready();
// get non-reactive user object
let user = server.collection('users').filter(user=>user.id==userId).fetch()[0];
// get reactive user object
let userReactiveCursor = server.collection('users').filter(user=>user.id==userId).reactive().one();
let userReactiveObject = userReactiveCursor.data();
// observing the changes
server.collection('users').filter(user=>user.id==userId).onChange(({prev,next})=>{
console.log('previus user data',state.prev);
console.log('next user data',state.next);
});
// observing changes in reactive data source
userReactiveCursor.onChange((newData)=>{
console.log('new user state', newData);
});
let participantsSub = server.subscribe("participants");
await participantsSub.ready();
let reactiveCollection = server.collection('participants').reactive();
// reactive reduce
let reducedReactive = reactiveCollection.reduce((acc,val,i,arr)=>{
if (i<arr.length-1) {
return acc + val.age;
} else {
return (acc + val.age)/arr.length;
}
},0);
// reactive mean age of all participants
let meanAge = reducedReactive.data();
// observing changes in reactive data source
userReactiveCursor.onChange((newData)=>{
console.log('new user state', newData);
});
})();
```
================================================
FILE: core/.babelrc
================================================
{
"presets": ["es2015", "stage-0"],
"env": {
"test": {
"plugins": ["istanbul"]
}
}
}
================================================
FILE: core/.eslintrc
================================================
{
"extends": "eslint:recommended",
"parser": "babel-eslint",
"env": {
"browser": true,
"mocha": true,
"node": true,
"meteor": true
},
"rules": {
"brace-style": [2, "1tbs"],
"comma-spacing": [2, {"before": false, "after": true}],
"computed-property-spacing": [2, "never"],
"indent": [2, 4],
"linebreak-style": [2, "unix"],
"new-cap": [2, {"capIsNew": false}],
"no-console": [0],
"no-multi-spaces": [0],
"no-underscore-dangle": [0],
"object-curly-spacing": [2, "never"],
"one-var": [2, "never"],
"quotes": [2, "double"],
"semi": [2, "always"],
"keyword-spacing": [2],
"space-before-blocks": [2, "always"],
"space-before-function-paren": [2, "always"],
"space-in-parens": [2, "never"],
"strict": [2, "never"]
}
}
================================================
FILE: core/.gitignore
================================================
node_modules/
npm-debug.log
coverage/
.nyc_output
lib/
.DS_Store
================================================
FILE: core/.npmignore
================================================
node_modules/
npm-debug.log
coverage/
================================================
FILE: core/.npmrc
================================================
package-lock=false
================================================
FILE: core/.travis.yml
================================================
language: node_js
node_js:
- 8
script:
- npm run lint
- npm run coverage
- npm run coveralls
# - npm run e2e-test
================================================
FILE: core/CHANGELOG.md
================================================
# 1.0.6
* Pausing message queue prevents holds every out-coming message.
# 1.0.5
* Now disconnect event won't fire on failed reconnecting events.
# 1.0.4
* Now method calls can be put at the beginning of the call queue.
* Pause/continue outcoming ddp messages queue.
* `autoReconnect` value is being saved on disconnect.
# 1.0.3
* Updated `wolfy87-eventemitter` to 5.2.5.
# 1.0.2
* Replaced id checking inside sub method.
# 1.0.1
* Added EJSON support.
* Added message object to connect emit.
* Added session id.
* Added boolean parameter `cleanQueue` to the `DDP` constructor.
Determine whether to clean ddp message queue on disconnect or not.
================================================
FILE: core/LICENSE
================================================
The MIT License (MIT)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
================================================
FILE: core/README.md
================================================
[](https://badge.fury.io/js/simpleddp-core.js)
[](https://travis-ci.org/gregivy/simpleddp-core)
[](https://coveralls.io/r/gregivy/simpleddp-core?branch=master)
[](https://david-dm.org/gregivy/simpleddp-core)
[](https://david-dm.org/gregivy/simpleddp-core#info=devDependencies)
# simpleddp-core
A javascript isomorphic/universal ddp client (successor of [ddp.js](https://github.com/mondora/ddp.js)).
## What is it for?
The purpose of this library is:
- to set up and maintain a ddp connection with a ddp server, freeing the
developer from having to do it on their own
- to give the developer a clear, consistent API to communicate with the ddp
server
## Install
To install ddp.js using `npm`:
npm install ddp.js
or using `yarn`:
yarn add ddp.js
## Example usage
```js
const DDP = require("ddp.js");
const options = {
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: WebSocket
};
const ddp = new DDP(options);
ddp.on("connected", () => {
console.log("Connected");
});
const subId = ddp.sub("mySubscription");
ddp.on("ready", message => {
if (message.subs.includes(subId)) {
console.log("mySubscription ready");
}
});
ddp.on("added", message => {
console.log(message.collection);
});
const myLoginParams = {
user: {
email: "user@example.com"
},
password: "hunter2"
};
const methodId = ddp.method("login", [myLoginParams]);
ddp.on("result", message => {
if (message.id === methodId && !message.error) {
console.log("Logged in!");
}
});
```
## Developing
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.
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.
## 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
- `options` **object** *required*
Available options are:
- `cleanQueue` **boolean** *optional* [default: `false`]: whether to clean ddp message
queue on disconnect or not.
- `endpoint` **string** *required*: the location of the websocket server. Its
format depends on the type of socket you are using.
- `SocketConstructor` **function** *required*: the constructor function that
will be used to construct the socket. Meteor (currently the only DDP server
available) supports websockets and SockJS sockets. So, practically speaking,
this means that on the browser you can use either the browser's native
WebSocket constructor or the SockJS constructor provided by the SockJS
library. On the server you can use whichever library implements the
websocket protocol (e.g. faye-websocket).
- `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.
---
### DDP.method(name, params)
Calls a remote method.
#### Arguments
- `name` **string** *required*: name of the method to call.
- `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
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)
Subscribes to a server publication.
#### Arguments
- `name` **string** *required*: name of the server publication.
- `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
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)
Unsubscribes to a previously-subscribed server publication.
#### Arguments
- `id` **string** *required*: id of the subscription.
#### Returns
The `id` corresponding to the subscription call (not of much use, but I return
it for consistency).
---
### 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
established.
- `disconnected`: emitted with no arguments when the DDP connection drops.
### Subscription events
All the following events are emitted with one argument, the parsed DDP message.
Further details can be found [on the DDP spec
page](https://github.com/meteor/meteor/blob/devel/packages/ddp/DDP.md).
- `ready`
- `nosub`
- `added`
- `changed`
- `removed`
### Method events
All the following events are emitted with one argument, the parsed DDP message.
Further details can be found [on the DDP spec
page](https://github.com/meteor/meteor/blob/devel/packages/ddp/DDP.md).
- `result`
- `updated`
================================================
FILE: core/package.json
================================================
{
"name": "simpleddp-core",
"version": "1.0.6",
"description": "ddp javascript client",
"main": "lib/ddp.js",
"scripts": {
"build": "babel src --out-dir lib",
"clean": "rimraf lib coverage",
"coverage": "nyc --require babel-register --reporter=lcov --include src --all npm test",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"dev": "npm test -- --watch",
"lint": "eslint src test",
"prepare": "npm run clean && npm run build",
"test": "mocha --require babel-register --recursive test/unit",
"start-meteor": "cd test/server/ && meteor",
"e2e-test": "mocha --require babel-register --recursive test/e2e",
"e2e-dev": "npm run e2e-test -- --watch"
},
"repository": {
"type": "git",
"url": "https://github.com/gregivy/simpleddp-core"
},
"keywords": [
"ddp",
"meteor",
"simpleddp",
"core"
],
"author": "Plyushch Gregory <gpoi.mail@gmail.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/gregivy/simpleddp-core/issues"
},
"homepage": "https://github.com/gregivy/simpleddp-core",
"devDependencies": {
"ajv": "^5.5.2",
"babel-cli": "^6.26.0",
"babel-eslint": "^8.0.1",
"babel-plugin-istanbul": "^4.1.5",
"babel-preset-es2015": "^6.24.1",
"babel-preset-stage-0": "^6.24.1",
"babel-register": "^6.26.0",
"chai": "^4.1.2",
"coveralls": "^3.0.0",
"eslint": "^4.9.0",
"faye-websocket": "^0.11.1",
"mocha": "^4.0.1",
"nyc": "^11.2.1",
"sinon": "^4.0.2",
"sinon-chai": "^2.14.0"
},
"dependencies": {
"ejson": "^2.1.2",
"wolfy87-eventemitter": "^5.2.5"
}
}
================================================
FILE: core/src/ddp.js
================================================
import EventEmitter from "wolfy87-eventemitter";
import Queue from "./queue";
import Socket from "./socket";
import {contains, uniqueId} from "./utils";
const DDP_VERSION = "1";
const PUBLIC_EVENTS = [
// Subscription messages
"ready", "nosub", "added", "changed", "removed",
// Method messages
"result", "updated",
// Error messages
"error"
];
const DEFAULT_RECONNECT_INTERVAL = 10000;
export default class DDP extends EventEmitter {
emit () {
setTimeout(super.emit.bind(this, ...arguments), 0);
}
constructor (options) {
super();
this.status = "disconnected";
//DDP session id
this.sessionId = null;
//clean queue on disconnect or not, default to false
this.cleanQueue = (options.cleanQueue === true);
// Default `autoConnect` and `autoReconnect` to true
this.autoConnect = (options.autoConnect !== false);
this.autoReconnect = (options.autoReconnect !== false);
this.autoReconnectUserValue = this.autoReconnect;
this.reconnectInterval = options.reconnectInterval || DEFAULT_RECONNECT_INTERVAL;
this.messageQueue = new Queue(message => {
if (this.status === "connected") {
this.socket.send(message);
return true;
} else {
return false;
}
});
this.socket = new Socket(options.SocketConstructor, options.endpoint);
this.socket.on("open", () => {
// When the socket opens, send the `connect` message
// to establish the DDP connection
let params = {
msg: "connect",
version: DDP_VERSION,
support: [DDP_VERSION]
};
if (this.sessionId) params.session = this.sessionId;
this.socket.send(params);
});
this.socket.on("close", () => {
let oldStatus = this.status;
this.status = "disconnected";
if (this.cleanQueue) this.messageQueue.empty();
if (oldStatus != "disconnected") this.emit("disconnected");
if (this.autoReconnect) {
// Schedule a reconnection
setTimeout(
this.socket.open.bind(this.socket),
this.reconnectInterval
);
}
});
this.socket.on("message:in", message => {
if (message.msg === "connected") {
this.status = "connected";
this.sessionId = message.session ? message.session : null;
this.messageQueue.process();
this.emit("connected", message);
} else if (message.msg === "ping") {
// Reply with a `pong` message to prevent the server from
// closing the connection
this.socket.send({msg: "pong", id: message.id});
} else if (contains(PUBLIC_EVENTS, message.msg)) {
this.emit(message.msg, message);
}
});
if (this.autoConnect) {
this.connect();
}
}
connect () {
this.autoReconnect = this.autoReconnectUserValue;
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.
* Also we should remember autoReconnect value to restore it on connect.
*/
this.autoReconnectUserValue = this.autoReconnect;
this.autoReconnect = false;
this.sessionId = null;
this.socket.close();
}
pauseQueue() {
this.messageQueue.pause();
}
continueQueue() {
this.messageQueue.continue();
}
method (name, params, atBeginning = false) {
const id = uniqueId();
this.messageQueue[atBeginning?'unshift':'push']({
msg: "method",
id: id,
method: name,
params: params
});
return id;
}
sub (name, params, id = uniqueId()) {
this.messageQueue.push({
msg: "sub",
id: id,
name: name,
params: params
});
return id;
}
unsub (id) {
this.messageQueue.push({
msg: "unsub",
id: id
});
return id;
}
}
================================================
FILE: core/src/queue.js
================================================
export default class Queue {
/*
* As the name implies, `consumer` is the (sole) consumer of the queue.
* It gets called with each element of the queue and its return value
* serves as a ack, determining whether the element is removed or not from
* the queue, allowing then subsequent elements to be processed.
*/
constructor (consumer) {
this.consumer = consumer;
this.paused = false;
this.queue = [];
}
pause () {
this.paused = true;
}
continue () {
this.paused = false;
this.process();
}
push (element) {
this.queue.push(element);
this.process();
}
unshift (element) {
this.queue.unshift(element);
this.process();
}
process (opts) {
if (!this.paused && this.queue.length !== 0) {
const ack = this.consumer(this.queue[0]);
if (ack) {
this.queue.shift();
if (!this.paused) this.process();
}
}
}
empty () {
this.queue = [];
}
}
================================================
FILE: core/src/socket.js
================================================
import EventEmitter from "wolfy87-eventemitter";
import EJSON from "ejson";
export default class Socket extends EventEmitter {
constructor (SocketConstructor, endpoint) {
super();
this.SocketConstructor = SocketConstructor;
this.endpoint = endpoint;
this.rawSocket = null;
}
send (object) {
const message = EJSON.stringify(object);
this.rawSocket.send(message);
// Emit a copy of the object, as the listener might mutate it.
this.emit("message:out", EJSON.parse(message));
}
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);
/*
* Calls to `onopen` and `onclose` directly trigger the `open` and
* `close` events on the `Socket` instance.
*/
this.rawSocket.onopen = () => this.emit("open");
this.rawSocket.onclose = () => {
this.rawSocket = null;
this.emit("close");
};
/*
* 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.
if (this.rawSocket && this.rawSocket.onclose)
delete this.rawSocket.onclose;
// Safe to perform even if the socket is already closed
this.rawSocket.close();
this.rawSocket = null;
this.emit("close");
};
/*
* 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;
try {
object = EJSON.parse(message.data);
} catch (ignore) {
// Simply ignore the malformed message and return
return;
}
// Outside the try-catch block as it must only catch EJSON parsing
// errors, not errors that may occur inside a "message:in" event
// handler
this.emit("message:in", object);
};
}
close () {
/*
* Avoid throwing an error if `rawSocket === null`
*/
if (this.rawSocket) {
this.rawSocket.close();
}
}
}
================================================
FILE: core/src/utils.js
================================================
var i = 0;
export function uniqueId () {
return (i++).toString();
}
export function contains (array, element) {
return array.indexOf(element) !== -1;
}
================================================
FILE: core/test/e2e/connection.js
================================================
import chai, {expect} from "chai";
import {Client} from "faye-websocket";
import sinon from "sinon";
import sinonChai from "sinon-chai";
import DDP from "../../src/ddp";
chai.use(sinonChai);
const options = {
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: Client
};
describe("connection", () => {
var ddp = null;
afterEach(done => {
if (ddp) {
ddp.on("disconnected", () => done());
ddp.disconnect();
ddp = null;
} else {
done();
}
});
describe("connecting", () => {
it("a connection is established on instantiation unless `autoConnect === false`", done => {
/*
* The test suceeds when the `connected` event is fired, signaling
* the establishment of the connection.
* If the event is never fired, the test times out and fails.
*/
ddp = new DDP(options);
ddp.on("connected", () => {
done();
});
});
it("a connection is not established on instantiation when `autoConnect === false`", done => {
/*
* The test succeeds if, 1s after the creation of the DDP instance,
* a `connected` event has not been fired.
*/
const ddp = new DDP({
...options,
autoConnect: false
});
const connectedHandler = sinon.spy();
ddp.on("connected", connectedHandler);
setTimeout(() => {
try {
expect(connectedHandler).to.have.callCount(0);
done();
} catch (e) {
done(e);
}
}, 1000);
});
it("a connection can be established manually when `autoConnect === false`", done => {
/*
* The test suceeds when the `connected` event is fired, signaling
* the establishment of the connection.
* If the event is never fired, the test times out and fails.
*/
ddp = new DDP({
...options,
autoConnect: false
});
ddp.connect();
ddp.on("connected", () => {
done();
});
});
it("manually connecting several times doesn't causes multiple simultaneous connections [CASE: `autoConnect === true`]", done => {
/*
* The test suceeds if 1s after having called `connect` several
* times only one connection has been established.
*/
ddp = new DDP(options);
const connectedSpy = sinon.spy();
ddp.connect();
ddp.connect();
ddp.connect();
ddp.connect();
ddp.on("connected", connectedSpy);
setTimeout(() => {
try {
expect(connectedSpy).to.have.callCount(1);
done();
} catch (e) {
done(e);
}
}, 1000);
});
it("manually connecting several times doesn't causes multiple simultaneous connections [CASE: `autoConnect === false`]", done => {
/*
* The test suceeds if 1s after having called `connect` several
* times only one connection has been established.
*/
ddp = new DDP({
...options,
autoConnect: false
});
const connectedSpy = sinon.spy();
ddp.connect();
ddp.connect();
ddp.connect();
ddp.connect();
ddp.on("connected", connectedSpy);
setTimeout(() => {
try {
expect(connectedSpy).to.have.callCount(1);
done();
} catch (e) {
done(e);
}
}, 1000);
});
});
describe("disconnecting", () => {
it("the connection is closed when calling `disconnect`", done => {
/*
* The test suceeds when the `disconnected` event is fired,
* signaling the termination of the connection.
* If the event is never fired, the test times out and fails.
*/
const ddp = new DDP(options);
ddp.on("connected", () => {
ddp.disconnect();
});
ddp.on("disconnected", () => {
done();
});
});
it("calling `disconnect` several times causes no issues", done => {
/*
* The test suceeds if:
* - calling `disconnect` several times doesn't throw, both before
* and after the `disconnected` event has been received
* - one and only one `disconnected` event is fired (check after
* 1s)
*/
const ddp = new DDP(options);
const disconnectSpy = sinon.spy(() => {
try {
ddp.disconnect();
ddp.disconnect();
ddp.disconnect();
ddp.disconnect();
} catch (e) {
done(e);
}
});
ddp.on("connected", () => {
try {
ddp.disconnect();
ddp.disconnect();
ddp.disconnect();
ddp.disconnect();
} catch (e) {
done(e);
}
});
ddp.on("disconnected", disconnectSpy);
setTimeout(() => {
try {
expect(disconnectSpy).to.have.callCount(1);
done();
} catch (e) {
done(e);
}
}, 1000);
});
it("the connection is closed when calling `disconnect` and it's not re-established", done => {
/*
* The test suceeds if, 1s after the `disconnected` event has been
* fired, there hasn't been any reconnection.
*/
const ddp = new DDP({
...options,
reconnectInterval: 10
});
const disconnectOnConnection = sinon.spy(() => {
ddp.disconnect();
});
ddp.on("connected", disconnectOnConnection);
ddp.on("disconnected", () => {
setTimeout(() => {
try {
expect(disconnectOnConnection).to.have.callCount(1);
done();
} catch (e) {
done(e);
}
}, 1000);
});
});
it("the connection is closed and re-established when the server closes the connection, unless `autoReconnect === true`", done => {
/*
* The test suceeds when the `connect` event is fired a second time
* after the client gets disconnected from the server (occurrence
* marked by the `disconnected` event).
* If the event is never fired a second time, the test times out
* and fails.
*/
ddp = new DDP({
...options,
reconnectInterval: 10
});
var callCount = 0;
ddp.on("connected", () => {
callCount += 1;
if (callCount === 1) {
ddp.method("disconnectMe", []);
}
if (callCount === 2) {
done();
}
});
});
it("the connection is closed and _not_ re-established when the server closes the connection and `autoReconnect === false`", done => {
/*
* The test suceeds if, 1s after the `disconnected` event has been
* fired, there hasn't been any reconnection.
*/
const ddp = new DDP({
...options,
reconnectInterval: 10,
autoReconnect: false
});
const disconnectMe = sinon.spy(() => {
ddp.method("disconnectMe", []);
});
ddp.on("connected", disconnectMe);
ddp.on("disconnected", () => {
setTimeout(() => {
try {
expect(disconnectMe).to.have.callCount(1);
done();
} catch (e) {
done(e);
}
}, 1000);
});
});
describe("ddp.js issue #22", () => {
/*
* We need to test that no `uncaughtException`-s are raised. Since
* mocha adds a listener to the `uncaughtException` event which
* causes tests to fail in an unexpected manner, we first remove
* that listener, and then we restore it. Since it's not clear
* _what_ mocha does with that listener, we try to lower the
* meddling impact by doing all of our work inside the `it` block.
*/
it("no issues when sending messages while disconnected / while disconnecting", done => {
/*
* The test suceeds if, 100ms after the `disconnected` event
* has been fired, there haven't been any uncaught exceptions.
*/
const catcher = sinon.spy();
const listeners = process.listeners("uncaughtException");
process.removeAllListeners("uncaughtException");
process.on("uncaughtException", catcher);
const ddp = new DDP({
...options,
autoReconnect: false
});
ddp.on("connected", () => {
ddp.disconnect();
});
const interval = setInterval(() => {
ddp.method("echo", []);
}, 1);
ddp.on("disconnected", () => {
setTimeout(runAssertions, 100);
});
const runAssertions = () => {
clearInterval(interval);
process.removeAllListeners("uncaughtException");
listeners.forEach(listener => {
process.on("uncaughtException", listener);
});
try {
expect(catcher).to.have.callCount(0);
done();
} catch (e) {
done(e);
}
};
});
});
});
});
================================================
FILE: core/test/e2e/methods.js
================================================
import {expect} from "chai";
import {Client} from "faye-websocket";
import DDP from "../../src/ddp";
describe("methods", () => {
describe("calling a method", () => {
const ddp = new DDP({
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: Client
});
after(done => {
ddp.on("disconnected", () => done());
ddp.disconnect();
});
it("invokes the method on the server and gets a `result` message with the response", done => {
/*
* The test suceeds when the `result` message for the echo method
* call is received, and assertions all succeed.
* If the `result` message is never received, the test times out
* and fails. Naturally, the test also fails if assertions fail.
*/
const methodId = ddp.method("echo", [0, 1, 2, 3, 4]);
ddp.on("result", message => {
if (message.id !== methodId || message.error) {
return;
}
try {
expect(message.result).to.deep.equal([0, 1, 2, 3, 4]);
done();
} catch (e) {
done(e);
}
});
});
it("gets an `updated` message", done => {
/*
* The test suceeds when the `updated` message for the echo method
* call is received.
* If the `updated` message is never received, the test times out
* and fails.
*/
const methodId = ddp.method("echo", [0, 1, 2, 3, 4]);
ddp.on("updated", message => {
if (message.methods.indexOf(methodId) !== -1) {
done();
}
});
});
});
});
================================================
FILE: core/test/e2e/subscriptions.js
================================================
import {expect} from "chai";
import {Client} from "faye-websocket";
import DDP from "../../src/ddp";
describe("subscriptions", () => {
describe("subscribing to a publication", () => {
const ddp = new DDP({
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: Client
});
after(done => {
ddp.on("disconnected", () => done());
ddp.disconnect();
});
it("sends a sub call to the server and receives server-sent scubscription events", done => {
/*
* The test suceeds when the `ready` message for the echo
* subscription is received, and assertions all succeed.
* If the `ready` message is never received, the test times out
* and fails. Naturally, the test also fails if assertions fail.
*/
const subId = ddp.sub("echo", [0, 1, 2, 3, 4]);
const collections = {};
ddp.on("added", message => {
collections[message.collection] = {
...collections[message.collection],
[message.id]: {
_id: message.id,
...message.fields
}
};
});
ddp.on("ready", message => {
if (message.subs.indexOf(subId) === -1) {
return;
}
try {
expect(collections).to.deep.equal({
echoParameters: {
"id_0": {_id: "id_0", param: 0},
"id_1": {_id: "id_1", param: 1},
"id_2": {_id: "id_2", param: 2},
"id_3": {_id: "id_3", param: 3},
"id_4": {_id: "id_4", param: 4}
}
});
done();
} catch (e) {
done(e);
}
});
});
});
describe("unsubscribing from a publication", () => {
const ddp = new DDP({
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: Client
});
after(done => {
ddp.on("disconnected", () => done());
ddp.disconnect();
});
it("sends an unsub call to the server and receives a nosub unsubscriptions confirmation event", done => {
/*
* The test suceeds when the `nosub` message for the echo
* subscription is received. If the `nosub` message is never
* received, the test times out and fails.
*/
const subId = ddp.sub("echo", [0, 1, 2, 3, 4]);
ddp.on("ready", message => {
if (message.subs.indexOf(subId) === -1) {
return;
}
ddp.unsub(subId);
});
ddp.on("nosub", message => {
if (message.id !== subId) {
return;
}
done();
});
});
});
describe("getting unsubscribed from a publication", () => {
const ddp = new DDP({
endpoint: "ws://localhost:3000/websocket",
SocketConstructor: Client
});
after(done => {
ddp.on("disconnected", () => done());
ddp.disconnect();
});
it("receives a nosub unsubscriptions event", function (done) {
/*
* The test suceeds when the `nosub` message for the echo
* subscription is received. If the `nosub` message is never
* received, the test times out and fails.
* The server will stop the subscription after about 1s, so there
* is no need to terminate it with an `unsub`. We will however
* increase the test timeout to 3s to account for the delay.
*/
this.timeout(3000);
const subId = ddp.sub("autoTerminating");
var subReady = false;
ddp.on("ready", message => {
if (message.subs.indexOf(subId) !== -1) {
subReady = true;
}
});
ddp.on("nosub", message => {
if (message.id !== subId) {
return;
}
try {
// Ensure the subscription got marked as ready.
expect(subReady).to.equal(true);
done();
} catch (e) {
done(e);
}
});
});
});
});
================================================
FILE: core/test/server/.meteor/.finished-upgraders
================================================
# This file contains information which helps Meteor properly upgrade your
# app when you run 'meteor update'. You should check it into version control
# with your project.
notices-for-0.9.0
notices-for-0.9.1
0.9.4-platform-file
notices-for-facebook-graph-api-2
1.2.0-standard-minifiers-package
1.2.0-meteor-platform-split
1.2.0-cordova-changes
1.2.0-breaking-changes
1.3.0-split-minifiers-package
1.4.0-remove-old-dev-bundle-link
1.4.1-add-shell-server-package
1.4.3-split-account-service-packages
1.5-add-dynamic-import-package
================================================
FILE: core/test/server/.meteor/.gitignore
================================================
local
================================================
FILE: core/test/server/.meteor/.id
================================================
# This file contains a token that is unique to your project.
# Check it into your repository along with the rest of this directory.
# It can be used for purposes such as:
# - ensuring you don't accidentally deploy one app on top of another
# - providing package authors with aggregated statistics
ydh6g2121jjwyqq7agh
================================================
FILE: core/test/server/.meteor/packages
================================================
# Meteor packages used by this project, one per line.
# Check this file (and the other files in this directory) into your repository.
#
# 'meteor add' and 'meteor remove' will edit this file for you,
# but you can also edit it by hand.
meteor-base@1.1.0 # Packages every Meteor app needs to have
mobile-experience@1.0.5 # Packages for a great mobile UX
mongo@1.2.2 # The database Meteor supports right now
blaze-html-templates # Compile .html files into Meteor Blaze views
session@1.1.7 # Client-side reactive dictionary for your app
jquery@1.11.10 # Helpful client-side library
tracker@1.1.3 # Meteor's client-side reactive programming library
es5-shim@4.6.15 # ECMAScript 5 compatibility for older browsers.
standard-minifier-css
standard-minifier-js
shell-server
dynamic-import
================================================
FILE: core/test/server/.meteor/platforms
================================================
server
browser
================================================
FILE: core/test/server/.meteor/release
================================================
METEOR@1.5.2.2
================================================
FILE: core/test/server/.meteor/versions
================================================
allow-deny@1.0.9
autoupdate@1.3.12
babel-compiler@6.20.0
babel-runtime@1.0.1
base64@1.0.10
binary-heap@1.0.10
blaze@2.3.2
blaze-html-templates@1.1.2
blaze-tools@1.0.10
boilerplate-generator@1.2.0
caching-compiler@1.1.9
caching-html-compiler@1.1.2
callback-hook@1.0.10
check@1.2.5
ddp@1.3.1
ddp-client@2.1.3
ddp-common@1.2.9
ddp-server@2.0.2
deps@1.0.12
diff-sequence@1.0.7
dynamic-import@0.1.3
ecmascript@0.8.3
ecmascript-runtime@0.4.1
ecmascript-runtime-client@0.4.3
ecmascript-runtime-server@0.4.1
ejson@1.0.14
es5-shim@4.6.15
geojson-utils@1.0.10
hot-code-push@1.0.4
html-tools@1.0.11
htmljs@1.0.11
http@1.2.12
id-map@1.0.9
jquery@1.11.10
launch-screen@1.1.1
livedata@1.0.18
logging@1.1.19
meteor@1.7.2
meteor-base@1.1.0
minifier-css@1.2.16
minifier-js@2.1.4
minimongo@1.3.3
mobile-experience@1.0.5
mobile-status-bar@1.0.14
modules@0.10.0
modules-runtime@0.8.0
mongo@1.2.2
mongo-dev-server@1.0.1
mongo-id@1.0.6
npm-mongo@2.2.33
observe-sequence@1.0.16
ordered-dict@1.0.9
promise@0.9.0
random@1.0.10
reactive-dict@1.1.9
reactive-var@1.0.11
reload@1.1.11
retry@1.0.9
routepolicy@1.0.12
session@1.1.7
shell-server@0.2.4
spacebars@1.0.15
spacebars-compiler@1.1.3
standard-minifier-css@1.3.5
standard-minifier-js@2.1.2
templating@1.3.2
templating-compiler@1.3.3
templating-runtime@1.3.2
templating-tools@1.1.2
tracker@1.1.3
ui@1.0.13
underscore@1.0.10
url@1.1.0
webapp@1.3.19
webapp-hashing@1.0.9
================================================
FILE: core/test/server/methods.js
================================================
Meteor.methods({
echo: function () {
return _.toArray(arguments);
},
disconnectMe: function () {
this.connection.close();
}
});
================================================
FILE: core/test/server/publications.js
================================================
Meteor.publish("echo", function () {
var self = this;
_.each(arguments, function (param, index) {
self.added("echoParameters", "id_" + index, {param: param});
});
self.ready();
});
Meteor.publish("autoTerminating", function () {
var self = this;
self.added("autoTerminating", "id", {});
self.ready();
setTimeout(function () {
self.stop();
}, 1000);
});
================================================
FILE: core/test/unit/ddp.js
================================================
import chai, {expect} from "chai";
import sinon from "sinon";
import sinonChai from "sinon-chai";
chai.use(sinonChai);
import DDP from "../../src/ddp";
import Socket from "../../src/socket";
class SocketConstructorMock {
send () {}
close () {}
}
const options = {
SocketConstructor: SocketConstructorMock
};
describe("`DDP` class", () => {
describe("`constructor` method", () => {
beforeEach(() => {
sinon.stub(Socket.prototype, "on");
sinon.stub(Socket.prototype, "open");
});
afterEach(() => {
Socket.prototype.on.restore();
Socket.prototype.open.restore();
});
it("instantiates a `Socket`", () => {
const ddp = new DDP(options);
expect(ddp.socket).to.be.an.instanceOf(Socket);
});
it("registers handlers for `socket` events", () => {
const ddp = new DDP(options);
expect(ddp.socket.on).to.have.always.been.calledWithMatch(
sinon.match.string,
sinon.match.func
);
});
it("opens a connection to the server (by calling `socket.open`) unless `options.autoConnect === false`", () => {
const ddp = new DDP(options);
expect(ddp.socket.open).to.have.callCount(1);
});
it("does not open a connection when `options.autoConnect === false`", () => {
const ddp = new DDP({
...options,
autoConnect: false
});
expect(ddp.socket.open).to.have.callCount(0);
});
it("sets the instance `reconnectInterval` to `options.reconnectInterval` if specified", () => {
const ddp = new DDP({
...options,
reconnectInterval: 1,
autoConnect: false
});
expect(ddp.reconnectInterval).to.equal(1);
});
it("sets the instance `reconnectInterval` to a default value if `options.reconnectInterval` is not specified", () => {
const ddp = new DDP({
...options,
autoConnect: false
});
expect(ddp.reconnectInterval).to.equal(10000);
});
});
describe("`method` method", () => {
it("sends a DDP `method` message", () => {
const ddp = new DDP(options);
ddp.messageQueue.push = sinon.spy();
const id = ddp.method("name", ["param"]);
expect(ddp.messageQueue.push).to.have.been.calledWith({
msg: "method",
id: id,
method: "name",
params: ["param"]
});
});
it("returns the method's `id`", () => {
const ddp = new DDP(options);
ddp.messageQueue.push = sinon.spy();
const id = ddp.method("name", ["param"]);
expect(id).to.be.a("string");
});
});
describe("`sub` method", () => {
it("sends a DDP `sub` message", () => {
const ddp = new DDP(options);
ddp.messageQueue.push = sinon.spy();
const id = ddp.sub("name", ["param"]);
expect(ddp.messageQueue.push).to.have.been.calledWith({
msg: "sub",
id: id,
name: "name",
params: ["param"]
});
});
it("returns the sub's `id`", () => {
const ddp = new DDP(options);
ddp.messageQueue.push = sinon.spy();
const id = ddp.sub("name", ["param"]);
expect(id).to.be.a("string");
});
it("generates unique id when not specified", () => {
const ddp = new DDP(options);
var ids = [];
ids.push(ddp.sub("echo", [ 0 ]));
ids.push(ddp.sub("echo", [ 0 ]));
expect(ids[0]).to.be.a("string");
expect(ids[1]).to.be.a("string");
expect(ids[0]).not.to.equal(ids[1]);
});
it("allows manually specifying sub's id", () => {
const ddp = new DDP(options);
const subId = ddp.sub("echo", [ 0 ], "12345");
expect(subId).to.equal("12345");
});
});
describe("`unsub` method", () => {
it("sends a DDP `unsub` message", () => {
const ddp = new DDP(options);
ddp.messageQueue.push = sinon.spy();
const id = ddp.unsub("id");
expect(ddp.messageQueue.push).to.have.been.calledWith({
msg: "unsub",
id: id
});
});
it("returns the sub's `id`", () => {
const ddp = new DDP(options);
ddp.messageQueue.push = sinon.spy();
const id = ddp.unsub("id");
expect(id).to.be.a("string");
expect(id).to.equal("id");
});
});
describe("`connect` method", () => {
beforeEach(() => {
sinon.stub(Socket.prototype, "open");
});
afterEach(() => {
Socket.prototype.open.restore();
});
it("opens the WebSocket connection", () => {
const ddp = new DDP(options);
Socket.prototype.open.reset();
ddp.connect();
expect(ddp.socket.open).to.have.callCount(1);
});
});
describe("`disconnect` method", () => {
beforeEach(() => {
sinon.stub(Socket.prototype, "close");
});
afterEach(() => {
Socket.prototype.close.restore();
});
it("closes the WebSocket connection", () => {
const ddp = new DDP(options);
ddp.disconnect();
expect(ddp.socket.close).to.have.callCount(1);
});
it("sets the `autoReconnect` flag to false", () => {
const ddp = new DDP(options);
ddp.disconnect();
expect(ddp.autoReconnect).to.equal(false);
});
});
describe("`socket` `open` handler", () => {
beforeEach(() => {
sinon.stub(global, "setTimeout").callsFake(fn => fn());
});
afterEach(() => {
global.setTimeout.restore();
});
it("sends the `connect` DDP message", () => {
const ddp = new DDP(options);
ddp.socket.send = sinon.spy();
ddp.socket.emit("open");
expect(ddp.socket.send).to.have.been.calledWith({
msg: "connect",
version: "1",
support: ["1"]
});
});
});
describe("`socket` `close` handler", () => {
beforeEach(() => {
sinon.stub(global, "setTimeout").callsFake(fn => fn());
});
afterEach(() => {
global.setTimeout.restore();
});
it("emits the `disconnected` event if was 'connected'", () => {
const ddp = new DDP(options);
ddp.status = "connected";
ddp.emit = sinon.spy();
ddp.socket.emit("close");
expect(ddp.emit).to.have.been.calledWith("disconnected");
});
it("sets the status to `disconnected`", () => {
const ddp = new DDP(options);
ddp.status = "connected";
ddp.emit = sinon.spy();
ddp.socket.emit("close");
expect(ddp.status).to.equal("disconnected");
});
it("schedules a reconnection unless `options.autoReconnect === false`", () => {
const ddp = new DDP(options);
ddp.socket.open = sinon.spy();
ddp.socket.emit("close");
expect(ddp.socket.open).to.have.callCount(1);
});
it("doesn't schedule a reconnection when `options.autoReconnect === false`", () => {
const ddp = new DDP({
...options,
autoReconnect: false
});
ddp.socket.open = sinon.spy();
ddp.socket.emit("close");
expect(ddp.socket.open).to.have.callCount(0);
});
});
describe("`socket` `message:in` handler", () => {
beforeEach(() => {
sinon.stub(global, "setTimeout").callsFake(fn => fn());
});
afterEach(() => {
global.setTimeout.restore();
});
it("responds to `ping` DDP messages", () => {
const ddp = new DDP(options);
ddp.socket.send = sinon.spy();
ddp.socket.emit("message:in", {
id: "id",
msg: "ping"
});
expect(ddp.socket.send).to.have.been.calledWith({
id: "id",
msg: "pong"
});
});
it("triggers `messageQueue` processing upon connection", () => {
const ddp = new DDP(options);
ddp.emit = sinon.spy();
ddp.messageQueue.process = sinon.spy();
ddp.socket.emit("message:in", {msg: "connected"});
expect(ddp.messageQueue.process).to.have.callCount(1);
});
it("sets the status to `connected` upon connection", () => {
const ddp = new DDP(options);
ddp.emit = sinon.spy();
ddp.socket.emit("message:in", {msg: "connected"});
expect(ddp.status).to.equal("connected");
});
it("emits public DDP messages as events", () => {
const ddp = new DDP(options);
ddp.emit = sinon.spy();
const message = {
id: "id",
msg: "result"
};
ddp.socket.emit("message:in", message);
expect(ddp.emit).to.have.been.calledWith("result", message);
});
it("ignores unknown (or non public) DDP messages", () => {
const ddp = new DDP(options);
ddp.emit = sinon.spy();
const message = {
id: "id",
msg: "not-a-ddp-message"
};
ddp.socket.emit("message:in", message);
expect(ddp.emit).to.have.callCount(0);
});
});
describe("`messageQueue` consumer", () => {
it("acks if `status` is `connected`", () => {
const ddp = new DDP(options);
ddp.status = "connected";
const ack = ddp.messageQueue.consumer({});
expect(ack).to.equal(true);
});
it("doesn't ack if `status` is `disconnected`", () => {
const ddp = new DDP(options);
ddp.status = "disconnected";
const ack = ddp.messageQueue.consumer({});
expect(ack).to.equal(false);
});
});
});
================================================
FILE: core/test/unit/queue.js
================================================
import chai, {expect} from "chai";
import sinon from "sinon";
import sinonChai from "sinon-chai";
chai.use(sinonChai);
import Queue from "../../src/queue";
describe("`Queue` class", () => {
describe("`push` method", () => {
it("adds an element to the queue", () => {
const q = new Queue();
q.process = sinon.spy();
const element = {};
q.push(element);
expect(q.queue).to.include(element);
});
it("triggers processing", () => {
const q = new Queue();
q.process = sinon.spy();
const element = {};
q.push(element);
expect(q.process).to.have.callCount(1);
});
});
describe("`process` method", () => {
it("calls the consumer on each element of the queue", () => {
const consumer = sinon.spy(() => true);
const q = new Queue(consumer);
q.queue = [0, 1, 2];
q.process();
expect(consumer).to.have.been.calledWith(0);
expect(consumer).to.have.been.calledWith(1);
expect(consumer).to.have.been.calledWith(2);
expect(consumer).to.have.callCount(3);
});
it("removes elements from the queue", () => {
const consumer = sinon.spy(() => true);
const q = new Queue(consumer);
q.queue = [0, 1, 2];
q.process();
expect(q.queue.length).to.equal(0);
});
it("doesn't remove elements from the queue if the consumer doesn't ack", () => {
const consumer = sinon.spy(() => false);
const q = new Queue(consumer);
q.queue = [0, 1, 2];
q.process();
expect(consumer).to.have.been.calledWith(0);
expect(consumer).to.have.callCount(1);
expect(q.queue.length).to.equal(3);
});
});
describe("`empty` method", () => {
it("empties the queue", () => {
const q = new Queue();
q.process = sinon.spy();
const element = {};
q.push(element);
expect(q.queue.length).to.equal(1);
q.empty();
expect(q.queue.length).to.equal(0);
});
});
});
================================================
FILE: core/test/unit/socket.js
================================================
import chai, {expect} from "chai";
import sinon from "sinon";
import sinonChai from "sinon-chai";
chai.use(sinonChai);
import Socket from "../../src/socket";
import EJSON from "ejson";
class SocketConstructorMock {
close () {}
send () {}
}
describe("`Socket` class", () => {
describe("`send` method", () => {
it("sends a message through the `rawSocket`", () => {
const socket = new Socket();
socket.rawSocket = {
send: sinon.spy()
};
socket.send({});
expect(socket.rawSocket.send).to.have.callCount(1);
});
it("stringifies the object to send", () => {
const socket = new Socket();
socket.rawSocket = {
send: sinon.spy()
};
const object = {
a: "a"
};
const expectedMessage = EJSON.stringify(object);
socket.send(object);
expect(socket.rawSocket.send).to.have.been.calledWith(expectedMessage);
});
it("emits a `message:out` event", () => {
const socket = new Socket();
socket.rawSocket = {
send: sinon.spy()
};
socket.emit = sinon.spy();
const object = {
a: "a"
};
socket.send(object);
expect(socket.emit).to.have.been.calledWith("message:out", object);
});
});
describe("`open` method", () => {
it("no-op if `rawSocket` is already defined", () => {
const socket = new Socket(SocketConstructorMock);
const rawSocket = {};
socket.rawSocket = rawSocket;
socket.open();
// Test, for instance, that `rawSocket` has not been replaced.
expect(socket.rawSocket).to.equal(rawSocket);
});
it("instantiates a `SocketConstructor`", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
expect(socket.rawSocket).to.be.an.instanceOf(SocketConstructorMock);
});
it("registers handlers for `rawSocket` events", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
expect(socket.rawSocket.onopen).to.be.a("function");
expect(socket.rawSocket.onclose).to.be.a("function");
expect(socket.rawSocket.onerror).to.be.a("function");
expect(socket.rawSocket.onmessage).to.be.a("function");
});
});
describe("`close` method", () => {
it("closes the `rawSocket`", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
socket.rawSocket.close = sinon.spy();
socket.close();
expect(socket.rawSocket.close).to.have.callCount(1);
});
it("doesn't throw if there's no `rawSocket`", () => {
const socket = new Socket(SocketConstructorMock);
const peacemaker = () => {
socket.close();
};
expect(peacemaker).not.to.throw();
});
});
describe("`rawSocket` `onopen` handler", () => {
it("emits an `open` event", () => {
const socket = new Socket(SocketConstructorMock);
const handler = sinon.spy();
socket.on("open", handler);
socket.open();
socket.rawSocket.onopen();
expect(handler).to.have.callCount(1);
});
});
describe("`rawSocket` `onclose` handler", () => {
it("emits a `close` event", () => {
const socket = new Socket(SocketConstructorMock);
const handler = sinon.spy();
socket.on("close", handler);
socket.open();
socket.rawSocket.onclose();
expect(handler).to.have.callCount(1);
});
it("null-s the `rawSocket` property", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
socket.rawSocket.onclose();
expect(socket.rawSocket).to.equal(null);
});
});
describe("`rawSocket` `onerror` handler", () => {
it("closes `rawSocket` (by calling `rawSocket.close`)", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
const rawSocket = socket.rawSocket;
rawSocket.close = sinon.spy();
socket.rawSocket.onerror();
expect(rawSocket.close).to.have.callCount(1);
});
it("de-registers the `rawSocket.onclose` callback", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
const rawSocket = socket.rawSocket;
expect(rawSocket).to.have.property("onclose");
socket.rawSocket.onerror();
expect(rawSocket).not.to.have.property("onclose");
});
it("emits a `close` event", () => {
const socket = new Socket(SocketConstructorMock);
const handler = sinon.spy();
socket.on("close", handler);
socket.open();
socket.rawSocket.onerror();
expect(handler).to.have.callCount(1);
});
it("null-s the `rawSocket` property", () => {
const socket = new Socket(SocketConstructorMock);
socket.open();
socket.rawSocket.onerror();
expect(socket.rawSocket).to.equal(null);
});
});
describe("`rawSocket` `onmessage` handler", () => {
it("parses message data into an object", () => {
const socket = new Socket(SocketConstructorMock);
sinon.stub(EJSON, "parse");
socket.open();
socket.rawSocket.onmessage({data: "message"});
expect(EJSON.parse).to.have.been.calledWith("message");
EJSON.parse.restore();
});
it("ignores malformed messages", () => {
const socket = new Socket(SocketConstructorMock);
sinon.stub(EJSON, "parse").throws();
socket.open();
expect(socket.rawSocket.onmessage).not.to.throw();
EJSON.parse.restore();
});
it("parses correctly EJSON-specific data types", function () {
var socket = new Socket(SocketConstructorMock);
var testDate = new Date();
sinon.stub(EJSON, "parse");
socket.open();
socket.rawSocket.onmessage({data: testDate});
expect(EJSON.parse).to.have.been.calledWith(testDate);
EJSON.parse.restore();
});
it("emits `message:in` events", () => {
const socket = new Socket(SocketConstructorMock);
const handler = sinon.spy();
socket.on("message:in", handler);
socket.open();
socket.rawSocket.onmessage({data: EJSON.stringify({a: "a"})});
expect(handler).to.have.callCount(1);
expect(handler).to.have.been.calledWith({a: "a"});
});
});
});
================================================
FILE: core/test/unit/utils.js
================================================
import {expect} from "chai";
import {contains, uniqueId} from "../../src/utils";
describe("`utils` object", () => {
describe("`contains` function", () => {
it("returns true if the first parameter contains the second parameter", () => {
const array = ["element"];
const element = "element";
expect(contains(array, element)).to.equal(true);
});
it("returns false if the first parameter doesn't contain the second parameter", () => {
const array = ["element"];
const element = "different-element";
expect(contains(array, element)).to.equal(false);
});
});
describe("`uniqueId` function", () => {
it("should return a different string each time it's called", () => {
const ret1 = uniqueId();
const ret2 = uniqueId();
expect(ret1).not.to.equal(ret2);
});
});
});
================================================
FILE: custom_ejson.md
================================================
# Adding custom EJSON types
Adding custom EJSON types is as simple as it is in Meteor.
First install `ejson` package:
`npm install ejson --save`
Import/require `EJSON`.
```javascript
const EJSON = require("ejson"); // nodejs
```
or
```javascript
import EJSON from 'ejson'; // ES6
```
And use method `addType`
```javascript
class Distance {
constructor(value, unit) {
this.value = value;
this.unit = unit;
}
// Convert our type to JSON.
toJSONValue() {
return {
value: this.value,
unit: this.unit
};
}
// Unique type name.
typeName() {
return 'Distance';
}
}
EJSON.addType('Distance', function fromJSONValue(json) {
return new Distance(json.value, json.unit);
});
```
*Don't forget to do the same as above in the server side code!*
[Read more in Meteor Docs](https://docs.meteor.com/api/ejson.html)
## Example, adding Decimal support
`npm install ejson decimal.js --save`
```javascript
// ejson_decimal.js
import EJSON from 'ejson';
import Decimal from 'decimal.js';
Decimal.prototype.typeName = function() {
return 'Decimal';
};
Decimal.prototype.toJSONValue = function () {
return this.toJSON();
};
Decimal.prototype.clone = function () {
return Decimal(this.toString());
};
EJSON.addType('Decimal', function (str) {
return Decimal(str);
});
export { Decimal };
// now you can use Decimal in your method calls, subscriptions
// and all the 'Decimal' data from server will be converted to Decimal object on client
```
## Example, adding MongoId support
`npm install ejson decimal.js --save`
```javascript
// ejson_decimal.js
import EJSON from 'ejson';
class MongoObjectId {
constructor(str) {
this.str = str;
}
// Convert our type to JSON.
toJSONValue() {
return this.value();
}
// Unique type name.
typeName() {
return 'oid';
}
value() {
return this.str;
}
}
EJSON.addType('oid', function fromJSONValue(str) {
return new MongoObjectId(str);
});
export { MongoObjectId };
```
================================================
FILE: docs/ddpCollection.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SimpleDDP Docs</title>
<meta name="description" content="SimpleDDP Docs" />
<meta name="keywords" content="ddp, simpleddp, websocket, meteor" />
<meta name="keyword" content="ddp, simpleddp, websocket, meteor" />
<meta property="og:title" content="SimpleDDP Docs"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png"/>
<meta property="og:site_name" content="SimpleDDP Docs"/>
<meta property="og:url" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/main.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":false,"applicationName":"SimpleDDP","disqus":"","googleAnalytics":"","openGraph":{"title":"SimpleDDP Docs","type":"website","image":"https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png","site_name":"SimpleDDP Docs","url":""},"meta":{"title":"SimpleDDP Docs","description":"SimpleDDP Docs","keyword":"ddp, simpleddp, websocket, meteor"},"linenums":true,"default":{}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html">SimpleDDP</a></h3>
<button id="menuToggle" class="btn btn-link btn-lg menu-toggle">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<div class="search">
<input id="search" type="text" class="form-control input-md" placeholder="Search...">
</div>
<ul class="list">
<li class="item" data-name="ddpCollection">
<span class="title ">
<a href="ddpCollection.html">ddpCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpCollection#exportData"><a href="ddpCollection.html#exportData">exportData</a></li>
<li class="parent " data-name="ddpCollection#fetch"><a href="ddpCollection.html#fetch">fetch</a></li>
<li class="parent " data-name="ddpCollection#filter"><a href="ddpCollection.html#filter">filter</a></li>
<li class="parent " data-name="ddpCollection#importData"><a href="ddpCollection.html#importData">importData</a></li>
<li class="parent " data-name="ddpCollection#onChange"><a href="ddpCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpCollection#reactive"><a href="ddpCollection.html#reactive">reactive</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpEventListener">
<span class="title ">
<a href="ddpEventListener.html">ddpEventListener</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpEventListener#start"><a href="ddpEventListener.html#start">start</a></li>
<li class="parent " data-name="ddpEventListener#stop"><a href="ddpEventListener.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpOnChange">
<span class="title ">
<a href="ddpOnChange.html">ddpOnChange</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpOnChange#start"><a href="ddpOnChange.html#start">start</a></li>
<li class="parent " data-name="ddpOnChange#stop"><a href="ddpOnChange.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveCollection">
<span class="title ">
<a href="ddpReactiveCollection.html">ddpReactiveCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveCollection#_updateReactiveObjects"><a href="ddpReactiveCollection.html#_updateReactiveObjects">_updateReactiveObjects</a></li>
<li class="parent " data-name="ddpReactiveCollection#count"><a href="ddpReactiveCollection.html#count">count</a></li>
<li class="parent " data-name="ddpReactiveCollection#data"><a href="ddpReactiveCollection.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveCollection#map"><a href="ddpReactiveCollection.html#map">map</a></li>
<li class="parent " data-name="ddpReactiveCollection#onChange"><a href="ddpReactiveCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveCollection#one"><a href="ddpReactiveCollection.html#one">one</a></li>
<li class="parent " data-name="ddpReactiveCollection#reduce"><a href="ddpReactiveCollection.html#reduce">reduce</a></li>
<li class="parent " data-name="ddpReactiveCollection#settings"><a href="ddpReactiveCollection.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveCollection#sort"><a href="ddpReactiveCollection.html#sort">sort</a></li>
<li class="parent " data-name="ddpReactiveCollection#start"><a href="ddpReactiveCollection.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveCollection#stop"><a href="ddpReactiveCollection.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveDocument">
<span class="title ">
<a href="ddpReactiveDocument.html">ddpReactiveDocument</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveDocument#data"><a href="ddpReactiveDocument.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveDocument#onChange"><a href="ddpReactiveDocument.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveDocument#settings"><a href="ddpReactiveDocument.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveDocument#start"><a href="ddpReactiveDocument.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveDocument#stop"><a href="ddpReactiveDocument.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReducer">
<span class="title ">
<a href="ddpReducer.html">ddpReducer</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReducer#data"><a href="ddpReducer.html#data">data</a></li>
<li class="parent " data-name="ddpReducer#doReduce"><a href="ddpReducer.html#doReduce">doReduce</a></li>
<li class="parent " data-name="ddpReducer#onChange"><a href="ddpReducer.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReducer#start"><a href="ddpReducer.html#start">start</a></li>
<li class="parent " data-name="ddpReducer#stop"><a href="ddpReducer.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpSubscription">
<span class="title ">
<a href="ddpSubscription.html">ddpSubscription</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpSubscription#isOn"><a href="ddpSubscription.html#isOn">isOn</a></li>
<li class="parent " data-name="ddpSubscription#isReady"><a href="ddpSubscription.html#isReady">isReady</a></li>
<li class="parent " data-name="ddpSubscription#isStopped"><a href="ddpSubscription.html#isStopped">isStopped</a></li>
<li class="parent " data-name="ddpSubscription#nosub"><a href="ddpSubscription.html#nosub">nosub</a></li>
<li class="parent " data-name="ddpSubscription#onNosub"><a href="ddpSubscription.html#onNosub">onNosub</a></li>
<li class="parent " data-name="ddpSubscription#onReady"><a href="ddpSubscription.html#onReady">onReady</a></li>
<li class="parent " data-name="ddpSubscription#ready"><a href="ddpSubscription.html#ready">ready</a></li>
<li class="parent " data-name="ddpSubscription#remove"><a href="ddpSubscription.html#remove">remove</a></li>
<li class="parent " data-name="ddpSubscription#restart"><a href="ddpSubscription.html#restart">restart</a></li>
<li class="parent " data-name="ddpSubscription#start"><a href="ddpSubscription.html#start">start</a></li>
<li class="parent " data-name="ddpSubscription#stop"><a href="ddpSubscription.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="simpleDDP">
<span class="title ">
<a href="simpleDDP.html">simpleDDP</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="simpleDDP#collections"><a href="simpleDDP.html#collections">collections</a></li>
<li class="parent " data-name="simpleDDP#connected"><a href="simpleDDP.html#connected">connected</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="simpleDDP#apply"><a href="simpleDDP.html#apply">apply</a></li>
<li class="parent " data-name="simpleDDP#call"><a href="simpleDDP.html#call">call</a></li>
<li class="parent " data-name="simpleDDP#clearData"><a href="simpleDDP.html#clearData">clearData</a></li>
<li class="parent " data-name="simpleDDP#collection"><a href="simpleDDP.html#collection">collection</a></li>
<li class="parent " data-name="simpleDDP#connect"><a href="simpleDDP.html#connect">connect</a></li>
<li class="parent " data-name="simpleDDP#disconnect"><a href="simpleDDP.html#disconnect">disconnect</a></li>
<li class="parent " data-name="simpleDDP#exportData"><a href="simpleDDP.html#exportData">exportData</a></li>
<li class="parent " data-name="simpleDDP#importData"><a href="simpleDDP.html#importData">importData</a></li>
<li class="parent " data-name="simpleDDP#markAsReady"><a href="simpleDDP.html#markAsReady">markAsReady</a></li>
<li class="parent " data-name="simpleDDP#on"><a href="simpleDDP.html#on">on</a></li>
<li class="parent " data-name="simpleDDP#stopChangeListeners"><a href="simpleDDP.html#stopChangeListeners">stopChangeListeners</a></li>
<li class="parent " data-name="simpleDDP#sub"><a href="simpleDDP.html#sub">sub</a></li>
<li class="parent " data-name="simpleDDP#subscribe"><a href="simpleDDP.html#subscribe">subscribe</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
</ul>
</div>
<div class="main">
<h1 class="page-title" data-filename="ddpCollection.html">Class: ddpCollection</h1>
<section>
<header>
<div class="header content-size">
<h2>ddpCollection
</h2>
<div class="class-description"><p>DDP collection class.</p></div>
</div>
</header>
<article class="content-size">
<div class="container-overview">
<dt>
<div class="nameContainer">
<h4 class="name" id="ddpCollection">
<a class="share-icon" href="#ddpCollection"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
new ddpCollection
</span>
<span class="signature">(name, server)</span>
</h4>
</div>
</dt>
<dd>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>name</code></td>
<td class="type">
<span class="param-type">String</span>
</td>
<td class="description last">
<p>Collection name.</p></td>
</tr>
<tr>
<td class="name"><code>server</code></td>
<td class="type">
<span class="param-type"><a href="simpleDDP.html">simpleDDP</a></span>
</td>
<td class="description last">
<p>simpleDDP instance.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
</div>
<h3 class="subsection-title">Classes</h3>
<dl class="clearfix summary-list list-classes">
<dt class=""><a href="ddpCollection.html">ddpCollection</a></dt>
</dl>
<h3 class="subsection-title">Methods</h3>
<dl class="list-methods">
<dt>
<div class="nameContainer">
<h4 class="name" id="exportData">
<a class="share-icon" href="#exportData"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
exportData
</span>
<span class="signature">(<span class="optional">format</span>)</span><span class="type-signature">string | Object</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Exports data from the collection.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>format</code></td>
<td class="type">
<span class="param-type">string</span>
</td>
<td class="default">
'string'
</td>
<td class="description last">
<span class="optional">optional</span>
<p>If 'string' then returns EJSON string, if 'raw' returns js object.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
string
|
Object
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="fetch">
<a class="share-icon" href="#fetch"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
fetch
</span>
<span class="signature">(<span class="optional">settings</span>)</span><span class="type-signature">Object</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Returns collection data based on filter and on passed settings. Supports skip, limit and sort.
Order is 'filter' then 'sort' then 'skip' then 'limit'.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>settings</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="default">
{skip:0,limit:Infinity,sort:null}
</td>
<td class="description last">
<span class="optional">optional</span>
<p>Skip and limit are numbers or Infinity,
sort is a standard js array sort function.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
Object
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="filter">
<a class="share-icon" href="#filter"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
filter
</span>
<span class="signature">(f)</span><span class="type-signature">this</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Allows to specify specific documents inside the collection for reactive data and fetching.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
<p>Filter function, recieves as arguments object, index and array.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
this
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="importData">
<a class="share-icon" href="#importData"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
importData
</span>
<span class="signature">(data)</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Imports data inside the collection and emits all relevant events.
Both string and JS object types are supported.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>data</code></td>
<td class="type">
<span class="param-type">string</span>
|
<span class="param-type">Object</span>
</td>
<td class="description last">
<p>EJSON string or EJSON or js object.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="onChange">
<a class="share-icon" href="#onChange"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
onChange
</span>
<span class="signature">(f, filter)</span><span class="type-signature">Object</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Returns change observer.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
</td>
</tr>
<tr>
<td class="name"><code>filter</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
</td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-see">See:</dt>
<dd class="tag-see">
<ul>
<li><a href="ddpOnChange.html">ddpOnChange</a></li>
</ul>
</dd>
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
Object
</td>
<td class="description last"><ul>
<li>@see ddpOnChange</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="reactive">
<a class="share-icon" href="#reactive"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
reactive
</span>
<span class="signature">(<span class="optional">settings</span>)</span><span class="type-signature">Object</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Returns reactive collection object.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>settings</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="default">
{skip:0,limit:Infinity,sort:null}
</td>
<td class="description last">
<span class="optional">optional</span>
</td>
</tr>
</tbody>
</table>
<dl class="details">
<dt class="tag-see">See:</dt>
<dd class="tag-see">
<ul>
<li><a href="ddpReactiveCollection.html">ddpReactiveCollection</a></li>
</ul>
</dd>
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
Object
</td>
<td class="description last"><ul>
<li>@see ddpReactiveCollection</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
</dl>
</article>
</section>
<footer class="content-size">
<div class="footer">
Documentation generated by <a target="_blank" href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Wed Aug 07 2019 02:35:33 GMT+0300 (MSK)
</div>
</footer>
</div>
</div>
<script>prettyPrint();</script>
<script src="scripts/main.js"></script>
</body>
</html>
================================================
FILE: docs/ddpEventListener.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SimpleDDP Docs</title>
<meta name="description" content="SimpleDDP Docs" />
<meta name="keywords" content="ddp, simpleddp, websocket, meteor" />
<meta name="keyword" content="ddp, simpleddp, websocket, meteor" />
<meta property="og:title" content="SimpleDDP Docs"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png"/>
<meta property="og:site_name" content="SimpleDDP Docs"/>
<meta property="og:url" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/main.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":false,"applicationName":"SimpleDDP","disqus":"","googleAnalytics":"","openGraph":{"title":"SimpleDDP Docs","type":"website","image":"https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png","site_name":"SimpleDDP Docs","url":""},"meta":{"title":"SimpleDDP Docs","description":"SimpleDDP Docs","keyword":"ddp, simpleddp, websocket, meteor"},"linenums":true,"default":{}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html">SimpleDDP</a></h3>
<button id="menuToggle" class="btn btn-link btn-lg menu-toggle">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<div class="search">
<input id="search" type="text" class="form-control input-md" placeholder="Search...">
</div>
<ul class="list">
<li class="item" data-name="ddpCollection">
<span class="title ">
<a href="ddpCollection.html">ddpCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpCollection#exportData"><a href="ddpCollection.html#exportData">exportData</a></li>
<li class="parent " data-name="ddpCollection#fetch"><a href="ddpCollection.html#fetch">fetch</a></li>
<li class="parent " data-name="ddpCollection#filter"><a href="ddpCollection.html#filter">filter</a></li>
<li class="parent " data-name="ddpCollection#importData"><a href="ddpCollection.html#importData">importData</a></li>
<li class="parent " data-name="ddpCollection#onChange"><a href="ddpCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpCollection#reactive"><a href="ddpCollection.html#reactive">reactive</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpEventListener">
<span class="title ">
<a href="ddpEventListener.html">ddpEventListener</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpEventListener#start"><a href="ddpEventListener.html#start">start</a></li>
<li class="parent " data-name="ddpEventListener#stop"><a href="ddpEventListener.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpOnChange">
<span class="title ">
<a href="ddpOnChange.html">ddpOnChange</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpOnChange#start"><a href="ddpOnChange.html#start">start</a></li>
<li class="parent " data-name="ddpOnChange#stop"><a href="ddpOnChange.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveCollection">
<span class="title ">
<a href="ddpReactiveCollection.html">ddpReactiveCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveCollection#_updateReactiveObjects"><a href="ddpReactiveCollection.html#_updateReactiveObjects">_updateReactiveObjects</a></li>
<li class="parent " data-name="ddpReactiveCollection#count"><a href="ddpReactiveCollection.html#count">count</a></li>
<li class="parent " data-name="ddpReactiveCollection#data"><a href="ddpReactiveCollection.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveCollection#map"><a href="ddpReactiveCollection.html#map">map</a></li>
<li class="parent " data-name="ddpReactiveCollection#onChange"><a href="ddpReactiveCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveCollection#one"><a href="ddpReactiveCollection.html#one">one</a></li>
<li class="parent " data-name="ddpReactiveCollection#reduce"><a href="ddpReactiveCollection.html#reduce">reduce</a></li>
<li class="parent " data-name="ddpReactiveCollection#settings"><a href="ddpReactiveCollection.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveCollection#sort"><a href="ddpReactiveCollection.html#sort">sort</a></li>
<li class="parent " data-name="ddpReactiveCollection#start"><a href="ddpReactiveCollection.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveCollection#stop"><a href="ddpReactiveCollection.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveDocument">
<span class="title ">
<a href="ddpReactiveDocument.html">ddpReactiveDocument</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveDocument#data"><a href="ddpReactiveDocument.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveDocument#onChange"><a href="ddpReactiveDocument.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveDocument#settings"><a href="ddpReactiveDocument.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveDocument#start"><a href="ddpReactiveDocument.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveDocument#stop"><a href="ddpReactiveDocument.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReducer">
<span class="title ">
<a href="ddpReducer.html">ddpReducer</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReducer#data"><a href="ddpReducer.html#data">data</a></li>
<li class="parent " data-name="ddpReducer#doReduce"><a href="ddpReducer.html#doReduce">doReduce</a></li>
<li class="parent " data-name="ddpReducer#onChange"><a href="ddpReducer.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReducer#start"><a href="ddpReducer.html#start">start</a></li>
<li class="parent " data-name="ddpReducer#stop"><a href="ddpReducer.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpSubscription">
<span class="title ">
<a href="ddpSubscription.html">ddpSubscription</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpSubscription#isOn"><a href="ddpSubscription.html#isOn">isOn</a></li>
<li class="parent " data-name="ddpSubscription#isReady"><a href="ddpSubscription.html#isReady">isReady</a></li>
<li class="parent " data-name="ddpSubscription#isStopped"><a href="ddpSubscription.html#isStopped">isStopped</a></li>
<li class="parent " data-name="ddpSubscription#nosub"><a href="ddpSubscription.html#nosub">nosub</a></li>
<li class="parent " data-name="ddpSubscription#onNosub"><a href="ddpSubscription.html#onNosub">onNosub</a></li>
<li class="parent " data-name="ddpSubscription#onReady"><a href="ddpSubscription.html#onReady">onReady</a></li>
<li class="parent " data-name="ddpSubscription#ready"><a href="ddpSubscription.html#ready">ready</a></li>
<li class="parent " data-name="ddpSubscription#remove"><a href="ddpSubscription.html#remove">remove</a></li>
<li class="parent " data-name="ddpSubscription#restart"><a href="ddpSubscription.html#restart">restart</a></li>
<li class="parent " data-name="ddpSubscription#start"><a href="ddpSubscription.html#start">start</a></li>
<li class="parent " data-name="ddpSubscription#stop"><a href="ddpSubscription.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="simpleDDP">
<span class="title ">
<a href="simpleDDP.html">simpleDDP</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="simpleDDP#collections"><a href="simpleDDP.html#collections">collections</a></li>
<li class="parent " data-name="simpleDDP#connected"><a href="simpleDDP.html#connected">connected</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="simpleDDP#apply"><a href="simpleDDP.html#apply">apply</a></li>
<li class="parent " data-name="simpleDDP#call"><a href="simpleDDP.html#call">call</a></li>
<li class="parent " data-name="simpleDDP#clearData"><a href="simpleDDP.html#clearData">clearData</a></li>
<li class="parent " data-name="simpleDDP#collection"><a href="simpleDDP.html#collection">collection</a></li>
<li class="parent " data-name="simpleDDP#connect"><a href="simpleDDP.html#connect">connect</a></li>
<li class="parent " data-name="simpleDDP#disconnect"><a href="simpleDDP.html#disconnect">disconnect</a></li>
<li class="parent " data-name="simpleDDP#exportData"><a href="simpleDDP.html#exportData">exportData</a></li>
<li class="parent " data-name="simpleDDP#importData"><a href="simpleDDP.html#importData">importData</a></li>
<li class="parent " data-name="simpleDDP#markAsReady"><a href="simpleDDP.html#markAsReady">markAsReady</a></li>
<li class="parent " data-name="simpleDDP#on"><a href="simpleDDP.html#on">on</a></li>
<li class="parent " data-name="simpleDDP#stopChangeListeners"><a href="simpleDDP.html#stopChangeListeners">stopChangeListeners</a></li>
<li class="parent " data-name="simpleDDP#sub"><a href="simpleDDP.html#sub">sub</a></li>
<li class="parent " data-name="simpleDDP#subscribe"><a href="simpleDDP.html#subscribe">subscribe</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
</ul>
</div>
<div class="main">
<h1 class="page-title" data-filename="ddpEventListener.html">Class: ddpEventListener</h1>
<section>
<header>
<div class="header content-size">
<h2>ddpEventListener
</h2>
<div class="class-description"><p>DDP event listener class.</p></div>
</div>
</header>
<article class="content-size">
<div class="container-overview">
<dt>
<div class="nameContainer">
<h4 class="name" id="ddpEventListener">
<a class="share-icon" href="#ddpEventListener"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
new ddpEventListener
</span>
<span class="signature">(eventname, f, ddplink)</span>
</h4>
</div>
</dt>
<dd>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>eventname</code></td>
<td class="type">
<span class="param-type">String</span>
</td>
<td class="description last">
<p>Event name.</p></td>
</tr>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
<p>Function to run when event is fired.</p></td>
</tr>
<tr>
<td class="name"><code>ddplink</code></td>
<td class="type">
<span class="param-type"><a href="simpleDDP.html">simpleDDP</a></span>
</td>
<td class="description last">
<p>simpleDDP instance.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
</div>
<h3 class="subsection-title">Classes</h3>
<dl class="clearfix summary-list list-classes">
<dt class=""><a href="ddpEventListener.html">ddpEventListener</a></dt>
</dl>
<h3 class="subsection-title">Methods</h3>
<dl class="list-methods">
<dt>
<div class="nameContainer">
<h4 class="name" id="start">
<a class="share-icon" href="#start"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
start
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Usually you won't need this unless you stopped the @see ddpEventListener.</p>
</div>
<dl class="details">
<dt class="tag-see">See:</dt>
<dd class="tag-see">
<ul>
<li>ddpEventListener starts on creation.</li>
</ul>
</dd>
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="stop">
<a class="share-icon" href="#stop"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
stop
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Stops listening for server <code>event</code> messages.
You can start any stopped @see ddpEventListener at any time using <code>ddpEventListener.start()</code>.</p>
</div>
<dl class="details">
</dl>
</dd>
</dl>
</article>
</section>
<footer class="content-size">
<div class="footer">
Documentation generated by <a target="_blank" href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Wed Aug 07 2019 02:35:33 GMT+0300 (MSK)
</div>
</footer>
</div>
</div>
<script>prettyPrint();</script>
<script src="scripts/main.js"></script>
</body>
</html>
================================================
FILE: docs/ddpOnChange.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SimpleDDP Docs</title>
<meta name="description" content="SimpleDDP Docs" />
<meta name="keywords" content="ddp, simpleddp, websocket, meteor" />
<meta name="keyword" content="ddp, simpleddp, websocket, meteor" />
<meta property="og:title" content="SimpleDDP Docs"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png"/>
<meta property="og:site_name" content="SimpleDDP Docs"/>
<meta property="og:url" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/main.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":false,"applicationName":"SimpleDDP","disqus":"","googleAnalytics":"","openGraph":{"title":"SimpleDDP Docs","type":"website","image":"https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png","site_name":"SimpleDDP Docs","url":""},"meta":{"title":"SimpleDDP Docs","description":"SimpleDDP Docs","keyword":"ddp, simpleddp, websocket, meteor"},"linenums":true,"default":{}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html">SimpleDDP</a></h3>
<button id="menuToggle" class="btn btn-link btn-lg menu-toggle">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<div class="search">
<input id="search" type="text" class="form-control input-md" placeholder="Search...">
</div>
<ul class="list">
<li class="item" data-name="ddpCollection">
<span class="title ">
<a href="ddpCollection.html">ddpCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpCollection#exportData"><a href="ddpCollection.html#exportData">exportData</a></li>
<li class="parent " data-name="ddpCollection#fetch"><a href="ddpCollection.html#fetch">fetch</a></li>
<li class="parent " data-name="ddpCollection#filter"><a href="ddpCollection.html#filter">filter</a></li>
<li class="parent " data-name="ddpCollection#importData"><a href="ddpCollection.html#importData">importData</a></li>
<li class="parent " data-name="ddpCollection#onChange"><a href="ddpCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpCollection#reactive"><a href="ddpCollection.html#reactive">reactive</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpEventListener">
<span class="title ">
<a href="ddpEventListener.html">ddpEventListener</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpEventListener#start"><a href="ddpEventListener.html#start">start</a></li>
<li class="parent " data-name="ddpEventListener#stop"><a href="ddpEventListener.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpOnChange">
<span class="title ">
<a href="ddpOnChange.html">ddpOnChange</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpOnChange#start"><a href="ddpOnChange.html#start">start</a></li>
<li class="parent " data-name="ddpOnChange#stop"><a href="ddpOnChange.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveCollection">
<span class="title ">
<a href="ddpReactiveCollection.html">ddpReactiveCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveCollection#_updateReactiveObjects"><a href="ddpReactiveCollection.html#_updateReactiveObjects">_updateReactiveObjects</a></li>
<li class="parent " data-name="ddpReactiveCollection#count"><a href="ddpReactiveCollection.html#count">count</a></li>
<li class="parent " data-name="ddpReactiveCollection#data"><a href="ddpReactiveCollection.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveCollection#map"><a href="ddpReactiveCollection.html#map">map</a></li>
<li class="parent " data-name="ddpReactiveCollection#onChange"><a href="ddpReactiveCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveCollection#one"><a href="ddpReactiveCollection.html#one">one</a></li>
<li class="parent " data-name="ddpReactiveCollection#reduce"><a href="ddpReactiveCollection.html#reduce">reduce</a></li>
<li class="parent " data-name="ddpReactiveCollection#settings"><a href="ddpReactiveCollection.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveCollection#sort"><a href="ddpReactiveCollection.html#sort">sort</a></li>
<li class="parent " data-name="ddpReactiveCollection#start"><a href="ddpReactiveCollection.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveCollection#stop"><a href="ddpReactiveCollection.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveDocument">
<span class="title ">
<a href="ddpReactiveDocument.html">ddpReactiveDocument</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveDocument#data"><a href="ddpReactiveDocument.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveDocument#onChange"><a href="ddpReactiveDocument.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveDocument#settings"><a href="ddpReactiveDocument.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveDocument#start"><a href="ddpReactiveDocument.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveDocument#stop"><a href="ddpReactiveDocument.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReducer">
<span class="title ">
<a href="ddpReducer.html">ddpReducer</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReducer#data"><a href="ddpReducer.html#data">data</a></li>
<li class="parent " data-name="ddpReducer#doReduce"><a href="ddpReducer.html#doReduce">doReduce</a></li>
<li class="parent " data-name="ddpReducer#onChange"><a href="ddpReducer.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReducer#start"><a href="ddpReducer.html#start">start</a></li>
<li class="parent " data-name="ddpReducer#stop"><a href="ddpReducer.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpSubscription">
<span class="title ">
<a href="ddpSubscription.html">ddpSubscription</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpSubscription#isOn"><a href="ddpSubscription.html#isOn">isOn</a></li>
<li class="parent " data-name="ddpSubscription#isReady"><a href="ddpSubscription.html#isReady">isReady</a></li>
<li class="parent " data-name="ddpSubscription#isStopped"><a href="ddpSubscription.html#isStopped">isStopped</a></li>
<li class="parent " data-name="ddpSubscription#nosub"><a href="ddpSubscription.html#nosub">nosub</a></li>
<li class="parent " data-name="ddpSubscription#onNosub"><a href="ddpSubscription.html#onNosub">onNosub</a></li>
<li class="parent " data-name="ddpSubscription#onReady"><a href="ddpSubscription.html#onReady">onReady</a></li>
<li class="parent " data-name="ddpSubscription#ready"><a href="ddpSubscription.html#ready">ready</a></li>
<li class="parent " data-name="ddpSubscription#remove"><a href="ddpSubscription.html#remove">remove</a></li>
<li class="parent " data-name="ddpSubscription#restart"><a href="ddpSubscription.html#restart">restart</a></li>
<li class="parent " data-name="ddpSubscription#start"><a href="ddpSubscription.html#start">start</a></li>
<li class="parent " data-name="ddpSubscription#stop"><a href="ddpSubscription.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="simpleDDP">
<span class="title ">
<a href="simpleDDP.html">simpleDDP</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="simpleDDP#collections"><a href="simpleDDP.html#collections">collections</a></li>
<li class="parent " data-name="simpleDDP#connected"><a href="simpleDDP.html#connected">connected</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="simpleDDP#apply"><a href="simpleDDP.html#apply">apply</a></li>
<li class="parent " data-name="simpleDDP#call"><a href="simpleDDP.html#call">call</a></li>
<li class="parent " data-name="simpleDDP#clearData"><a href="simpleDDP.html#clearData">clearData</a></li>
<li class="parent " data-name="simpleDDP#collection"><a href="simpleDDP.html#collection">collection</a></li>
<li class="parent " data-name="simpleDDP#connect"><a href="simpleDDP.html#connect">connect</a></li>
<li class="parent " data-name="simpleDDP#disconnect"><a href="simpleDDP.html#disconnect">disconnect</a></li>
<li class="parent " data-name="simpleDDP#exportData"><a href="simpleDDP.html#exportData">exportData</a></li>
<li class="parent " data-name="simpleDDP#importData"><a href="simpleDDP.html#importData">importData</a></li>
<li class="parent " data-name="simpleDDP#markAsReady"><a href="simpleDDP.html#markAsReady">markAsReady</a></li>
<li class="parent " data-name="simpleDDP#on"><a href="simpleDDP.html#on">on</a></li>
<li class="parent " data-name="simpleDDP#stopChangeListeners"><a href="simpleDDP.html#stopChangeListeners">stopChangeListeners</a></li>
<li class="parent " data-name="simpleDDP#sub"><a href="simpleDDP.html#sub">sub</a></li>
<li class="parent " data-name="simpleDDP#subscribe"><a href="simpleDDP.html#subscribe">subscribe</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
</ul>
</div>
<div class="main">
<h1 class="page-title" data-filename="ddpOnChange.html">Class: ddpOnChange</h1>
<section>
<header>
<div class="header content-size">
<h2>ddpOnChange
</h2>
<div class="class-description"><p>DDP change listener class.</p></div>
</div>
</header>
<article class="content-size">
<div class="container-overview">
<dt>
<div class="nameContainer">
<h4 class="name" id="ddpOnChange">
<a class="share-icon" href="#ddpOnChange"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
new ddpOnChange
</span>
<span class="signature">(obj, inst, <span class="optional">listenersArray</span>)</span>
</h4>
</div>
</dt>
<dd>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>obj</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="default">
</td>
<td class="description last">
<p>Describes changes of interest.</p></td>
</tr>
<tr>
<td class="name"><code>inst</code></td>
<td class="type">
<span class="param-type">*</span>
</td>
<td class="default">
</td>
<td class="description last">
<p>Event handler instance.</p></td>
</tr>
<tr>
<td class="name"><code>listenersArray</code></td>
<td class="type">
<span class="param-type"><a href="simpleDDP.html">simpleDDP</a></span>
</td>
<td class="default">
'onChangeFuncs'
</td>
<td class="description last">
<span class="optional">optional</span>
<p>Property name of event handler instance, array of listeners.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
</div>
<h3 class="subsection-title">Classes</h3>
<dl class="clearfix summary-list list-classes">
<dt class=""><a href="ddpOnChange.html">ddpOnChange</a></dt>
</dl>
<h3 class="subsection-title">Methods</h3>
<dl class="list-methods">
<dt>
<div class="nameContainer">
<h4 class="name" id="start">
<a class="share-icon" href="#start"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
start
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Start change listener. This method is being called on instance creation.</p>
</div>
<dl class="details">
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="stop">
<a class="share-icon" href="#stop"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
stop
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Stops change listener.</p>
</div>
<dl class="details">
</dl>
</dd>
</dl>
</article>
</section>
<footer class="content-size">
<div class="footer">
Documentation generated by <a target="_blank" href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Wed Aug 07 2019 02:35:33 GMT+0300 (MSK)
</div>
</footer>
</div>
</div>
<script>prettyPrint();</script>
<script src="scripts/main.js"></script>
</body>
</html>
================================================
FILE: docs/ddpReactiveCollection.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SimpleDDP Docs</title>
<meta name="description" content="SimpleDDP Docs" />
<meta name="keywords" content="ddp, simpleddp, websocket, meteor" />
<meta name="keyword" content="ddp, simpleddp, websocket, meteor" />
<meta property="og:title" content="SimpleDDP Docs"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png"/>
<meta property="og:site_name" content="SimpleDDP Docs"/>
<meta property="og:url" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/main.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":false,"applicationName":"SimpleDDP","disqus":"","googleAnalytics":"","openGraph":{"title":"SimpleDDP Docs","type":"website","image":"https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png","site_name":"SimpleDDP Docs","url":""},"meta":{"title":"SimpleDDP Docs","description":"SimpleDDP Docs","keyword":"ddp, simpleddp, websocket, meteor"},"linenums":true,"default":{}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html">SimpleDDP</a></h3>
<button id="menuToggle" class="btn btn-link btn-lg menu-toggle">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<div class="search">
<input id="search" type="text" class="form-control input-md" placeholder="Search...">
</div>
<ul class="list">
<li class="item" data-name="ddpCollection">
<span class="title ">
<a href="ddpCollection.html">ddpCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpCollection#exportData"><a href="ddpCollection.html#exportData">exportData</a></li>
<li class="parent " data-name="ddpCollection#fetch"><a href="ddpCollection.html#fetch">fetch</a></li>
<li class="parent " data-name="ddpCollection#filter"><a href="ddpCollection.html#filter">filter</a></li>
<li class="parent " data-name="ddpCollection#importData"><a href="ddpCollection.html#importData">importData</a></li>
<li class="parent " data-name="ddpCollection#onChange"><a href="ddpCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpCollection#reactive"><a href="ddpCollection.html#reactive">reactive</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpEventListener">
<span class="title ">
<a href="ddpEventListener.html">ddpEventListener</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpEventListener#start"><a href="ddpEventListener.html#start">start</a></li>
<li class="parent " data-name="ddpEventListener#stop"><a href="ddpEventListener.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpOnChange">
<span class="title ">
<a href="ddpOnChange.html">ddpOnChange</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpOnChange#start"><a href="ddpOnChange.html#start">start</a></li>
<li class="parent " data-name="ddpOnChange#stop"><a href="ddpOnChange.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveCollection">
<span class="title ">
<a href="ddpReactiveCollection.html">ddpReactiveCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveCollection#_updateReactiveObjects"><a href="ddpReactiveCollection.html#_updateReactiveObjects">_updateReactiveObjects</a></li>
<li class="parent " data-name="ddpReactiveCollection#count"><a href="ddpReactiveCollection.html#count">count</a></li>
<li class="parent " data-name="ddpReactiveCollection#data"><a href="ddpReactiveCollection.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveCollection#map"><a href="ddpReactiveCollection.html#map">map</a></li>
<li class="parent " data-name="ddpReactiveCollection#onChange"><a href="ddpReactiveCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveCollection#one"><a href="ddpReactiveCollection.html#one">one</a></li>
<li class="parent " data-name="ddpReactiveCollection#reduce"><a href="ddpReactiveCollection.html#reduce">reduce</a></li>
<li class="parent " data-name="ddpReactiveCollection#settings"><a href="ddpReactiveCollection.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveCollection#sort"><a href="ddpReactiveCollection.html#sort">sort</a></li>
<li class="parent " data-name="ddpReactiveCollection#start"><a href="ddpReactiveCollection.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveCollection#stop"><a href="ddpReactiveCollection.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveDocument">
<span class="title ">
<a href="ddpReactiveDocument.html">ddpReactiveDocument</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveDocument#data"><a href="ddpReactiveDocument.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveDocument#onChange"><a href="ddpReactiveDocument.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveDocument#settings"><a href="ddpReactiveDocument.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveDocument#start"><a href="ddpReactiveDocument.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveDocument#stop"><a href="ddpReactiveDocument.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReducer">
<span class="title ">
<a href="ddpReducer.html">ddpReducer</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReducer#data"><a href="ddpReducer.html#data">data</a></li>
<li class="parent " data-name="ddpReducer#doReduce"><a href="ddpReducer.html#doReduce">doReduce</a></li>
<li class="parent " data-name="ddpReducer#onChange"><a href="ddpReducer.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReducer#start"><a href="ddpReducer.html#start">start</a></li>
<li class="parent " data-name="ddpReducer#stop"><a href="ddpReducer.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpSubscription">
<span class="title ">
<a href="ddpSubscription.html">ddpSubscription</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpSubscription#isOn"><a href="ddpSubscription.html#isOn">isOn</a></li>
<li class="parent " data-name="ddpSubscription#isReady"><a href="ddpSubscription.html#isReady">isReady</a></li>
<li class="parent " data-name="ddpSubscription#isStopped"><a href="ddpSubscription.html#isStopped">isStopped</a></li>
<li class="parent " data-name="ddpSubscription#nosub"><a href="ddpSubscription.html#nosub">nosub</a></li>
<li class="parent " data-name="ddpSubscription#onNosub"><a href="ddpSubscription.html#onNosub">onNosub</a></li>
<li class="parent " data-name="ddpSubscription#onReady"><a href="ddpSubscription.html#onReady">onReady</a></li>
<li class="parent " data-name="ddpSubscription#ready"><a href="ddpSubscription.html#ready">ready</a></li>
<li class="parent " data-name="ddpSubscription#remove"><a href="ddpSubscription.html#remove">remove</a></li>
<li class="parent " data-name="ddpSubscription#restart"><a href="ddpSubscription.html#restart">restart</a></li>
<li class="parent " data-name="ddpSubscription#start"><a href="ddpSubscription.html#start">start</a></li>
<li class="parent " data-name="ddpSubscription#stop"><a href="ddpSubscription.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="simpleDDP">
<span class="title ">
<a href="simpleDDP.html">simpleDDP</a>
</span>
<ul class="members itemMembers">
<span class="subtitle">Members</span>
<li class="parent " data-name="simpleDDP#collections"><a href="simpleDDP.html#collections">collections</a></li>
<li class="parent " data-name="simpleDDP#connected"><a href="simpleDDP.html#connected">connected</a></li>
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="simpleDDP#apply"><a href="simpleDDP.html#apply">apply</a></li>
<li class="parent " data-name="simpleDDP#call"><a href="simpleDDP.html#call">call</a></li>
<li class="parent " data-name="simpleDDP#clearData"><a href="simpleDDP.html#clearData">clearData</a></li>
<li class="parent " data-name="simpleDDP#collection"><a href="simpleDDP.html#collection">collection</a></li>
<li class="parent " data-name="simpleDDP#connect"><a href="simpleDDP.html#connect">connect</a></li>
<li class="parent " data-name="simpleDDP#disconnect"><a href="simpleDDP.html#disconnect">disconnect</a></li>
<li class="parent " data-name="simpleDDP#exportData"><a href="simpleDDP.html#exportData">exportData</a></li>
<li class="parent " data-name="simpleDDP#importData"><a href="simpleDDP.html#importData">importData</a></li>
<li class="parent " data-name="simpleDDP#markAsReady"><a href="simpleDDP.html#markAsReady">markAsReady</a></li>
<li class="parent " data-name="simpleDDP#on"><a href="simpleDDP.html#on">on</a></li>
<li class="parent " data-name="simpleDDP#stopChangeListeners"><a href="simpleDDP.html#stopChangeListeners">stopChangeListeners</a></li>
<li class="parent " data-name="simpleDDP#sub"><a href="simpleDDP.html#sub">sub</a></li>
<li class="parent " data-name="simpleDDP#subscribe"><a href="simpleDDP.html#subscribe">subscribe</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
</ul>
</div>
<div class="main">
<h1 class="page-title" data-filename="ddpReactiveCollection.html">Class: ddpReactiveCollection</h1>
<section>
<header>
<div class="header content-size">
<h2>ddpReactiveCollection
</h2>
<div class="class-description"><p>A reactive collection class.</p></div>
</div>
</header>
<article class="content-size">
<div class="container-overview">
<dt>
<div class="nameContainer">
<h4 class="name" id="ddpReactiveCollection">
<a class="share-icon" href="#ddpReactiveCollection"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
new ddpReactiveCollection
</span>
<span class="signature">(ddpCollection, <span class="optional">skiplimit</span>)</span>
</h4>
</div>
</dt>
<dd>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>ddpCollection</code></td>
<td class="type">
<span class="param-type"><a href="ddpCollection.html">ddpCollection</a></span>
</td>
<td class="default">
</td>
<td class="description last">
<p>Instance of @see ddpCollection class.</p></td>
</tr>
<tr>
<td class="name"><code>skiplimit</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="default">
{skip:0,limit:Infinity}
</td>
<td class="description last">
<span class="optional">optional</span>
<p>Object for declarative reactive collection slicing.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
</div>
<h3 class="subsection-title">Classes</h3>
<dl class="clearfix summary-list list-classes">
<dt class=""><a href="ddpReactiveCollection.html">ddpReactiveCollection</a></dt>
</dl>
<h3 class="subsection-title">Methods</h3>
<dl class="list-methods">
<dt>
<div class="nameContainer">
<h4 class="name" id="_updateReactiveObjects">
<a class="share-icon" href="#_updateReactiveObjects"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
_updateReactiveObjects
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Sends new object state for every associated reactive object.</p>
</div>
<dl class="details">
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="count">
<a class="share-icon" href="#count"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
count
</span>
<span class="signature">()</span><span class="type-signature">Object</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Reactive length of the local collection.</p>
</div>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
Object
</td>
<td class="description last"><ul>
<li>Object with reactive length of the local collection. {result}</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="data">
<a class="share-icon" href="#data"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
data
</span>
<span class="signature">()</span><span class="type-signature">Array</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Returns reactive local collection with applied sorting, skip and limit.
This returned array is being mutated within this class instance.</p>
</div>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
Array
</td>
<td class="description last"><ul>
<li>Local collection with applied sorting, skip and limit.</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="map">
<a class="share-icon" href="#map"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
map
</span>
<span class="signature">(f)</span><span class="type-signature"><a href="ddpReducer.html">ddpReducer</a></span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Maps reactive local collection to another reactive array.
Specified function form <a target="_blank" href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map">https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/map</a>.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
<p>Function that produces an element of the new Array.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<a href="ddpReducer.html">ddpReducer</a>
</td>
<td class="description last"><ul>
<li>Object that allows to get reactive mapped data @see ddpReducer.</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="onChange">
<a class="share-icon" href="#onChange"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
onChange
</span>
<span class="signature">(f)</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Runs a function every time a change occurs.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
<p>Function which recieves new collection at each change.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="one">
<a class="share-icon" href="#one"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
one
</span>
<span class="signature">(<span class="optional">settings</span>)</span><span class="type-signature"><a href="ddpReactiveDocument.html">ddpReactiveDocument</a></span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Returns a reactive object which fields are always the same as the first object in the collection.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>settings</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="default">
{preserve:false}
</td>
<td class="description last">
<span class="optional">optional</span>
<p>Settings for reactive object. Use {preserve:true} if you want to keep object on remove.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<a href="ddpReactiveDocument.html">ddpReactiveDocument</a>
</td>
<td class="description last"><ul>
<li>Object that allows to get reactive object based on reduced reactive local collection @see ddpReactiveDocument.</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="reduce">
<a class="share-icon" href="#reduce"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
reduce
</span>
<span class="signature">(f, initialValue)</span><span class="type-signature"><a href="ddpReducer.html">ddpReducer</a></span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Reduces reactive local collection.
Specified function form <a target="_blank" href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce">https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce</a>.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
<p>Function to execute on each element in the array.</p></td>
</tr>
<tr>
<td class="name"><code>initialValue</code></td>
<td class="type">
<span class="param-type">*</span>
</td>
<td class="description last">
<p>Value to use as the first argument to the first call of the function.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
<a href="ddpReducer.html">ddpReducer</a>
</td>
<td class="description last"><ul>
<li>Object that allows to get reactive object based on reduced reactive local collection @see ddpReducer.</li>
</ul></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="settings">
<a class="share-icon" href="#settings"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
settings
</span>
<span class="signature">(<span class="optional">skiplimit</span>)</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Update ddpReactiveCollection settings.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Default</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>skiplimit</code></td>
<td class="type">
<span class="param-type">Object</span>
</td>
<td class="default">
{skip:0,limit:Infinity}
</td>
<td class="description last">
<span class="optional">optional</span>
<p>Object for declarative reactive collection slicing.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="sort">
<a class="share-icon" href="#sort"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
sort
</span>
<span class="signature">(f)</span><span class="type-signature">this</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Sorts local collection according to specified function.
Specified function form <a target="_blank" href="https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort">https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort</a>.</p>
</div>
<table class="params">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="name"><code>f</code></td>
<td class="type">
<span class="param-type">function</span>
</td>
<td class="description last">
<p>A function used for sorting.</p></td>
</tr>
</tbody>
</table>
<dl class="details">
</dl>
<h5>Returns:</h5>
<table class="params">
<thead>
<tr>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="type">
this
</td>
<td class="description last"></td>
</tr>
</tbody>
</table>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="start">
<a class="share-icon" href="#start"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
start
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Start reactivity. This method is being called on instance creation.
Also starts every associated reactive object.</p>
</div>
<dl class="details">
</dl>
</dd>
<dt>
<div class="nameContainer">
<h4 class="name" id="stop">
<a class="share-icon" href="#stop"><span class="glyphicon glyphicon-link"></span></a>
<span class="">
stop
</span>
<span class="signature">()</span>
</h4>
</div>
</dt>
<dd>
<div class="description">
<p>Stops reactivity. Also stops associated reactive objects.</p>
</div>
<dl class="details">
</dl>
</dd>
</dl>
</article>
</section>
<footer class="content-size">
<div class="footer">
Documentation generated by <a target="_blank" href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.3</a> on Wed Aug 07 2019 02:35:33 GMT+0300 (MSK)
</div>
</footer>
</div>
</div>
<script>prettyPrint();</script>
<script src="scripts/main.js"></script>
</body>
</html>
================================================
FILE: docs/ddpReactiveDocument.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>SimpleDDP Docs</title>
<meta name="description" content="SimpleDDP Docs" />
<meta name="keywords" content="ddp, simpleddp, websocket, meteor" />
<meta name="keyword" content="ddp, simpleddp, websocket, meteor" />
<meta property="og:title" content="SimpleDDP Docs"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content="https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png"/>
<meta property="og:site_name" content="SimpleDDP Docs"/>
<meta property="og:url" content=""/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<script src="scripts/jquery.min.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link href="https://fonts.googleapis.com/css?family=Libre+Franklin:400,700" rel="stylesheet">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/main.css">
<script>
var config = {"monospaceLinks":false,"cleverLinks":false,"applicationName":"SimpleDDP","disqus":"","googleAnalytics":"","openGraph":{"title":"SimpleDDP Docs","type":"website","image":"https://github.com/Gregivy/simpleddp/raw/2.x.x/simpleddp.png","site_name":"SimpleDDP Docs","url":""},"meta":{"title":"SimpleDDP Docs","description":"SimpleDDP Docs","keyword":"ddp, simpleddp, websocket, meteor"},"linenums":true,"default":{}};
</script>
</head>
<body>
<div id="wrap" class="clearfix">
<div class="navigation">
<h3 class="applicationName"><a href="index.html">SimpleDDP</a></h3>
<button id="menuToggle" class="btn btn-link btn-lg menu-toggle">
<span class="glyphicon glyphicon-menu-hamburger"></span>
</button>
<div class="search">
<input id="search" type="text" class="form-control input-md" placeholder="Search...">
</div>
<ul class="list">
<li class="item" data-name="ddpCollection">
<span class="title ">
<a href="ddpCollection.html">ddpCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpCollection#exportData"><a href="ddpCollection.html#exportData">exportData</a></li>
<li class="parent " data-name="ddpCollection#fetch"><a href="ddpCollection.html#fetch">fetch</a></li>
<li class="parent " data-name="ddpCollection#filter"><a href="ddpCollection.html#filter">filter</a></li>
<li class="parent " data-name="ddpCollection#importData"><a href="ddpCollection.html#importData">importData</a></li>
<li class="parent " data-name="ddpCollection#onChange"><a href="ddpCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpCollection#reactive"><a href="ddpCollection.html#reactive">reactive</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpEventListener">
<span class="title ">
<a href="ddpEventListener.html">ddpEventListener</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpEventListener#start"><a href="ddpEventListener.html#start">start</a></li>
<li class="parent " data-name="ddpEventListener#stop"><a href="ddpEventListener.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpOnChange">
<span class="title ">
<a href="ddpOnChange.html">ddpOnChange</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpOnChange#start"><a href="ddpOnChange.html#start">start</a></li>
<li class="parent " data-name="ddpOnChange#stop"><a href="ddpOnChange.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveCollection">
<span class="title ">
<a href="ddpReactiveCollection.html">ddpReactiveCollection</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveCollection#_updateReactiveObjects"><a href="ddpReactiveCollection.html#_updateReactiveObjects">_updateReactiveObjects</a></li>
<li class="parent " data-name="ddpReactiveCollection#count"><a href="ddpReactiveCollection.html#count">count</a></li>
<li class="parent " data-name="ddpReactiveCollection#data"><a href="ddpReactiveCollection.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveCollection#map"><a href="ddpReactiveCollection.html#map">map</a></li>
<li class="parent " data-name="ddpReactiveCollection#onChange"><a href="ddpReactiveCollection.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveCollection#one"><a href="ddpReactiveCollection.html#one">one</a></li>
<li class="parent " data-name="ddpReactiveCollection#reduce"><a href="ddpReactiveCollection.html#reduce">reduce</a></li>
<li class="parent " data-name="ddpReactiveCollection#settings"><a href="ddpReactiveCollection.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveCollection#sort"><a href="ddpReactiveCollection.html#sort">sort</a></li>
<li class="parent " data-name="ddpReactiveCollection#start"><a href="ddpReactiveCollection.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveCollection#stop"><a href="ddpReactiveCollection.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReactiveDocument">
<span class="title ">
<a href="ddpReactiveDocument.html">ddpReactiveDocument</a>
</span>
<ul class="members itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="typedefs itemMembers">
</ul>
<ul class="methods itemMembers">
<span class="subtitle">Methods</span>
<li class="parent " data-name="ddpReactiveDocument#data"><a href="ddpReactiveDocument.html#data">data</a></li>
<li class="parent " data-name="ddpReactiveDocument#onChange"><a href="ddpReactiveDocument.html#onChange">onChange</a></li>
<li class="parent " data-name="ddpReactiveDocument#settings"><a href="ddpReactiveDocument.html#settings">settings</a></li>
<li class="parent " data-name="ddpReactiveDocument#start"><a href="ddpReactiveDocument.html#start">start</a></li>
<li class="parent " data-name="ddpReactiveDocument#stop"><a href="ddpReactiveDocument.html#stop">stop</a></li>
</ul>
<ul class="events itemMembers">
</ul>
</li>
<li class="item" data-name="ddpReducer">
<span class="title ">
<a href="ddpReducer.html">ddpReducer</a>
</span>
<ul class="members itemMembers">
</ul>
<ul cla
gitextract_hjf1yyvb/
├── .babelrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── core/
│ ├── .babelrc
│ ├── .eslintrc
│ ├── .gitignore
│ ├── .npmignore
│ ├── .npmrc
│ ├── .travis.yml
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ ├── ddp.js
│ │ ├── queue.js
│ │ ├── socket.js
│ │ └── utils.js
│ └── test/
│ ├── e2e/
│ │ ├── connection.js
│ │ ├── methods.js
│ │ └── subscriptions.js
│ ├── server/
│ │ ├── .meteor/
│ │ │ ├── .finished-upgraders
│ │ │ ├── .gitignore
│ │ │ ├── .id
│ │ │ ├── packages
│ │ │ ├── platforms
│ │ │ ├── release
│ │ │ └── versions
│ │ ├── methods.js
│ │ └── publications.js
│ └── unit/
│ ├── ddp.js
│ ├── queue.js
│ ├── socket.js
│ └── utils.js
├── custom_ejson.md
├── docs/
│ ├── ddpCollection.html
│ ├── ddpEventListener.html
│ ├── ddpOnChange.html
│ ├── ddpReactiveCollection.html
│ ├── ddpReactiveDocument.html
│ ├── ddpReducer.html
│ ├── ddpSubscription.html
│ ├── index.html
│ ├── scripts/
│ │ ├── main.js
│ │ └── prettify/
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
│ ├── simpleDDP.html
│ └── styles/
│ ├── main.css
│ ├── prettify-jsdoc.css
│ └── prettify-tomorrow.css
├── jsdoc_conf.json
├── notes.md
├── package.json
├── src/
│ ├── classes/
│ │ ├── ddpCollection.js
│ │ ├── ddpEventListener.js
│ │ ├── ddpOnChange.js
│ │ ├── ddpReactiveCollection.js
│ │ ├── ddpReactiveDocument.js
│ │ ├── ddpReducer.js
│ │ └── ddpSubscription.js
│ ├── helpers/
│ │ ├── fullCopy.js
│ │ └── isequal.js
│ └── simpleddp.js
└── test/
├── test_call.js
├── test_collectionfetch.js
├── test_importexport.js
├── test_onchange.js
├── test_reactive.js
├── test_reactiveone.js
└── test_sub.js
SYMBOL INDEX (132 symbols across 16 files)
FILE: core/src/ddp.js
constant DDP_VERSION (line 6) | const DDP_VERSION = "1";
constant PUBLIC_EVENTS (line 7) | const PUBLIC_EVENTS = [
constant DEFAULT_RECONNECT_INTERVAL (line 15) | const DEFAULT_RECONNECT_INTERVAL = 10000;
class DDP (line 17) | class DDP extends EventEmitter {
method emit (line 19) | emit () {
method constructor (line 23) | constructor (options) {
method connect (line 99) | connect () {
method disconnect (line 104) | disconnect () {
method pauseQueue (line 117) | pauseQueue() {
method continueQueue (line 121) | continueQueue() {
method method (line 125) | method (name, params, atBeginning = false) {
method sub (line 136) | sub (name, params, id = uniqueId()) {
method unsub (line 146) | unsub (id) {
FILE: core/src/queue.js
class Queue (line 1) | class Queue {
method constructor (line 10) | constructor (consumer) {
method pause (line 16) | pause () {
method continue (line 20) | continue () {
method push (line 25) | push (element) {
method unshift (line 30) | unshift (element) {
method process (line 35) | process (opts) {
method empty (line 45) | empty () {
FILE: core/src/socket.js
class Socket (line 4) | class Socket extends EventEmitter {
method constructor (line 6) | constructor (SocketConstructor, endpoint) {
method send (line 13) | send (object) {
method open (line 20) | open () {
method close (line 85) | close () {
FILE: core/src/utils.js
function uniqueId (line 2) | function uniqueId () {
function contains (line 6) | function contains (array, element) {
FILE: core/test/unit/ddp.js
class SocketConstructorMock (line 10) | class SocketConstructorMock {
method send (line 11) | send () {}
method close (line 12) | close () {}
FILE: core/test/unit/socket.js
class SocketConstructorMock (line 10) | class SocketConstructorMock {
method close (line 11) | close () {}
method send (line 12) | send () {}
FILE: docs/scripts/prettify/prettify.js
function L (line 2) | function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var...
function M (line 6) | function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.classN...
function B (line 7) | function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}
function x (line 7) | function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(...
function u (line 9) | function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''...
function D (line 12) | function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.clas...
function k (line 15) | function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(...
function C (line 15) | function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-m...
function E (line 15) | function E(a){var m=
function m (line 25) | function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Inf...
FILE: src/classes/ddpCollection.js
class ddpCollection (line 12) | class ddpCollection {
method constructor (line 13) | constructor(name,server) {
method filter (line 26) | filter(f) {
method importData (line 37) | importData(data) {
method exportData (line 60) | exportData(format) {
method fetch (line 77) | fetch(settings) {
method reactive (line 102) | reactive(settings) {
method onChange (line 114) | onChange(f,filter) {
FILE: src/classes/ddpEventListener.js
class ddpEventListener (line 9) | class ddpEventListener {
method constructor (line 10) | constructor(eventname, f, ddplink) {
method stop (line 23) | stop() {
method start (line 35) | start() {
FILE: src/classes/ddpOnChange.js
class ddpOnChange (line 9) | class ddpOnChange {
method constructor (line 10) | constructor(obj,inst,listenersArray = 'onChangeFuncs') {
method stop (line 22) | stop() {
method start (line 34) | start() {
FILE: src/classes/ddpReactiveCollection.js
class ddpReactiveCollection (line 13) | class ddpReactiveCollection {
method constructor (line 14) | constructor(ddpCollectionInstance,settings,filter) {
method _removeItem (line 95) | _removeItem(i) {
method _smartUpdate (line 119) | _smartUpdate(newEl,j) {
method _activateReducer (line 182) | _activateReducer(reducer) {
method _activateReactiveObject (line 191) | _activateReactiveObject(o) {
method _deactivateReducer (line 200) | _deactivateReducer(reducer) {
method _deactivateReactiveObject (line 212) | _deactivateReactiveObject(o) {
method _updateReactiveObjects (line 223) | _updateReactiveObjects() {
method settings (line 235) | settings(settings) {
method skip (line 259) | skip(n) {
method limit (line 269) | limit(n) {
method stop (line 277) | stop() {
method start (line 290) | start() {
method sort (line 307) | sort(f) {
method data (line 323) | data() {
method onChange (line 332) | onChange(f) {
method map (line 343) | map(f) {
method reduce (line 357) | reduce(f,initialValue) {
method count (line 366) | count() {
method one (line 376) | one(settings) {
FILE: src/classes/ddpReactiveDocument.js
class ddpReactiveDocument (line 11) | class ddpReactiveDocument{
method constructor (line 12) | constructor(ddpReactiveCollectionInstance,settings) {
method _update (line 27) | _update(newState) {
method start (line 49) | start() {
method stop (line 61) | stop() {
method data (line 73) | data() {
method onChange (line 82) | onChange(f) {
method settings (line 92) | settings({preserve}) {
FILE: src/classes/ddpReducer.js
class ddpReducer (line 11) | class ddpReducer {
method constructor (line 12) | constructor(ddpReactiveCollectionInstance,reducer,initialValue) {
method doReduce (line 26) | doReduce() {
method start (line 40) | start() {
method stop (line 52) | stop() {
method data (line 64) | data() {
method onChange (line 73) | onChange(f) {
FILE: src/classes/ddpSubscription.js
class ddpSubscription (line 9) | class ddpSubscription {
method constructor (line 10) | constructor(pubname, args, ddplink) {
method onNosub (line 42) | onNosub(f) {
method onReady (line 61) | onReady(f) {
method isReady (line 80) | isReady() {
method isStopped (line 89) | isStopped() {
method ready (line 98) | ready() {
method nosub (line 127) | nosub() {
method isOn (line 153) | isOn() {
method remove (line 161) | remove() {
method stop (line 178) | stop() {
method _getId (line 195) | _getId() {
method start (line 206) | start(args) {
method restart (line 225) | restart(args) {
FILE: src/simpleddp.js
function uniqueIdFuncGen (line 11) | function uniqueIdFuncGen() {
function connectPlugins (line 21) | function connectPlugins(plugins,...places) {
class simpleDDP (line 38) | class simpleDDP {
method constructor (line 58) | constructor(opts,plugins) {
method restartSubs (line 134) | restartSubs() {
method collection (line 148) | collection(name) {
method dispatchAdded (line 157) | dispatchAdded(m) {
method dispatchChanged (line 195) | dispatchChanged(m) {
method dispatchRemoved (line 244) | dispatchRemoved(m) {
method connect (line 273) | connect() {
method disconnect (line 308) | disconnect() {
method apply (line 350) | apply(method,args,atBeginning = false) {
method call (line 388) | call(method,...args) {
method sub (line 400) | sub(pubname,args) {
method subscribe (line 421) | subscribe(pubname, ...args) {
method on (line 441) | on(event,f) {
method stopChangeListeners (line 448) | stopChangeListeners() {
method clearData (line 457) | clearData() {
method importData (line 499) | importData(data) {
method exportData (line 544) | exportData(format) {
method markAsReady (line 558) | markAsReady(subs) {
FILE: test/test_importexport.js
constant EJSON (line 5) | const EJSON = require("ejson");
Condensed preview — 74 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (514K chars).
[
{
"path": ".babelrc",
"chars": 89,
"preview": "{\n \"presets\": [\"env\", \"stage-0\"],\n \"plugins\": [\n \"add-module-exports\"\n ]\n}\n"
},
{
"path": ".gitignore",
"chars": 30,
"preview": ".DS_Store\n/lib/\n/node_modules/"
},
{
"path": ".npmignore",
"chars": 27,
"preview": "simpleddp.png\n/src/\n/docs/\n"
},
{
"path": ".travis.yml",
"chars": 56,
"preview": "language: node_js\n\nnode_js:\n - 8\n\nscript:\n - npm test\n"
},
{
"path": "CHANGELOG.md",
"chars": 2550,
"preview": "# CHANGELOG\n\n## 2.3.0\n\n* `simpleddp-core` is now a part of `simpleddp`.\n* Fixed bug with setting `sort` in `reactive()` "
},
{
"path": "LICENSE",
"chars": 1088,
"preview": "MIT License\n\nCopyright (c) 2018-2019 Plyushch Gregory (Gregivy)\n\nPermission is hereby granted, free of charge, to any pe"
},
{
"path": "README.md",
"chars": 5288,
"preview": "[](https://badge.fury.io/js/simpleddp)\n[\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and"
},
{
"path": "core/README.md",
"chars": 6762,
"preview": "[](https://badge.fury.io/js/simpleddp-core.js)\n[![Build Statu"
},
{
"path": "core/package.json",
"chars": 1638,
"preview": "{\n \"name\": \"simpleddp-core\",\n \"version\": \"1.0.6\",\n \"description\": \"ddp javascript client\",\n \"main\": \"lib/ddp.js\",\n "
},
{
"path": "core/src/ddp.js",
"chars": 4477,
"preview": "import EventEmitter from \"wolfy87-eventemitter\";\nimport Queue from \"./queue\";\nimport Socket from \"./socket\";\nimport {con"
},
{
"path": "core/src/queue.js",
"chars": 1091,
"preview": "export default class Queue {\n\n /*\n * As the name implies, `\u001bconsumer` is the (sole) consumer of the queue.\n *"
},
{
"path": "core/src/socket.js",
"chars": 3489,
"preview": "import EventEmitter from \"wolfy87-eventemitter\";\nimport EJSON from \"ejson\";\n\nexport default class Socket extends EventEm"
},
{
"path": "core/src/utils.js",
"chars": 161,
"preview": "var i = 0;\nexport function uniqueId () {\n return (i++).toString();\n}\n\nexport function contains (array, element) {\n "
},
{
"path": "core/test/e2e/connection.js",
"chars": 10926,
"preview": "import chai, {expect} from \"chai\";\nimport {Client} from \"faye-websocket\";\nimport sinon from \"sinon\";\nimport sinonChai fr"
},
{
"path": "core/test/e2e/methods.js",
"chars": 1867,
"preview": "import {expect} from \"chai\";\nimport {Client} from \"faye-websocket\";\n\nimport DDP from \"../../src/ddp\";\n\ndescribe(\"methods"
},
{
"path": "core/test/e2e/subscriptions.js",
"chars": 4719,
"preview": "import {expect} from \"chai\";\nimport {Client} from \"faye-websocket\";\n\nimport DDP from \"../../src/ddp\";\n\ndescribe(\"subscri"
},
{
"path": "core/test/server/.meteor/.finished-upgraders",
"chars": 530,
"preview": "# This file contains information which helps Meteor properly upgrade your\n# app when you run 'meteor update'. You should"
},
{
"path": "core/test/server/.meteor/.gitignore",
"chars": 6,
"preview": "local\n"
},
{
"path": "core/test/server/.meteor/.id",
"chars": 322,
"preview": "# This file contains a token that is unique to your project.\n# Check it into your repository along with the rest of this"
},
{
"path": "core/test/server/.meteor/packages",
"chars": 887,
"preview": "# Meteor packages used by this project, one per line.\n# Check this file (and the other files in this directory) into you"
},
{
"path": "core/test/server/.meteor/platforms",
"chars": 15,
"preview": "server\nbrowser\n"
},
{
"path": "core/test/server/.meteor/release",
"chars": 15,
"preview": "METEOR@1.5.2.2\n"
},
{
"path": "core/test/server/.meteor/versions",
"chars": 1395,
"preview": "allow-deny@1.0.9\nautoupdate@1.3.12\nbabel-compiler@6.20.0\nbabel-runtime@1.0.1\nbase64@1.0.10\nbinary-heap@1.0.10\nblaze@2.3."
},
{
"path": "core/test/server/methods.js",
"chars": 160,
"preview": "Meteor.methods({\n echo: function () {\n return _.toArray(arguments);\n },\n disconnectMe: function () {\n "
},
{
"path": "core/test/server/publications.js",
"chars": 406,
"preview": "Meteor.publish(\"echo\", function () {\n var self = this;\n _.each(arguments, function (param, index) {\n self.a"
},
{
"path": "core/test/unit/ddp.js",
"chars": 10644,
"preview": "import chai, {expect} from \"chai\";\nimport sinon from \"sinon\";\nimport sinonChai from \"sinon-chai\";\n\nchai.use(sinonChai);\n"
},
{
"path": "core/test/unit/queue.js",
"chars": 2276,
"preview": "import chai, {expect} from \"chai\";\nimport sinon from \"sinon\";\nimport sinonChai from \"sinon-chai\";\n\nchai.use(sinonChai);\n"
},
{
"path": "core/test/unit/socket.js",
"chars": 7115,
"preview": "import chai, {expect} from \"chai\";\nimport sinon from \"sinon\";\nimport sinonChai from \"sinon-chai\";\n\nchai.use(sinonChai);\n"
},
{
"path": "core/test/unit/utils.js",
"chars": 939,
"preview": "import {expect} from \"chai\";\n\nimport {contains, uniqueId} from \"../../src/utils\";\n\ndescribe(\"`utils` object\", () => {\n\n "
},
{
"path": "custom_ejson.md",
"chars": 2003,
"preview": "# Adding custom EJSON types\n\nAdding custom EJSON types is as simple as it is in Meteor.\nFirst install `ejson` package:\n\n"
},
{
"path": "docs/ddpCollection.html",
"chars": 31594,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/ddpEventListener.html",
"chars": 20801,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/ddpOnChange.html",
"chars": 21283,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/ddpReactiveCollection.html",
"chars": 37275,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/ddpReactiveDocument.html",
"chars": 25557,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/ddpReducer.html",
"chars": 24041,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/ddpSubscription.html",
"chars": 35507,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/index.html",
"chars": 22509,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/scripts/main.js",
"chars": 1707,
"preview": "(function(){var e=0;var a;var t=document.getElementById(\"source-code\");if(t){var n=config.linenums;if(n){t=t.getElements"
},
{
"path": "docs/scripts/prettify/Apache-License-2.0.txt",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "docs/scripts/prettify/lang-css.js",
"chars": 861,
"preview": "PR.registerLangHandler(PR.createSimpleLexer([[\"pln\",/^[\\t\\n\\f\\r ]+/,null,\" \\t\\r\\n\f\"]],[[\"str\",/^\"(?:[^\\n\\f\\r\"\\\\]|\\\\(?:\\r"
},
{
"path": "docs/scripts/prettify/prettify.js",
"chars": 13632,
"preview": "var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;\n(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92"
},
{
"path": "docs/simpleDDP.html",
"chars": 56799,
"preview": "<!DOCTYPE html>\n<html>\n<head>\n <meta charset=\"utf-8\">\n <title>SimpleDDP Docs</title>\n \n <meta name=\"descript"
},
{
"path": "docs/styles/main.css",
"chars": 5895,
"preview": "body,html{font-family:'Libre Franklin',sans-serif;background-color:#ecedf1;color:#333}ol,ul{margin:0;padding:0}li{list-s"
},
{
"path": "docs/styles/prettify-jsdoc.css",
"chars": 1535,
"preview": "/* JSDoc prettify.js theme */\n\n/* plain text */\n.pln {\n color: #000000;\n font-weight: normal;\n font-style: normal;\n}\n"
},
{
"path": "docs/styles/prettify-tomorrow.css",
"chars": 2018,
"preview": "/* Tomorrow Theme */\n/* Original theme - https://github.com/chriskempson/tomorrow-theme */\n/* Pretty printing styles. Us"
},
{
"path": "jsdoc_conf.json",
"chars": 1089,
"preview": "{\n \"plugins\": [\n \"plugins/markdown\"\n ],\n \"recurseDepth\": 10,\n \"source\": {\n \"include\": [ \"./src"
},
{
"path": "notes.md",
"chars": 1136,
"preview": "# Notes\n\n## Can websocket messages arrive out-of-order?\n[link](https://stackoverflow.com/questions/11804721/can-websocke"
},
{
"path": "package.json",
"chars": 1305,
"preview": "{\n \"name\": \"simpleddp\",\n \"version\": \"2.3.0\",\n \"description\": \"The aim of this library is to simplify the process of w"
},
{
"path": "src/classes/ddpCollection.js",
"chars": 3511,
"preview": "import { fullCopy } from '../helpers/fullCopy.js';\nimport { ddpOnChange } from './ddpOnChange.js';\nimport { ddpReactiveC"
},
{
"path": "src/classes/ddpEventListener.js",
"chars": 987,
"preview": "/**\n * DDP event listener class.\n * @constructor\n * @param {String} eventname - Event name.\n * @param {Function} f - Fun"
},
{
"path": "src/classes/ddpOnChange.js",
"chars": 978,
"preview": "/**\n * DDP change listener class.\n * @constructor\n * @param {Object} obj - Describes changes of interest.\n * @param {*} "
},
{
"path": "src/classes/ddpReactiveCollection.js",
"chars": 11363,
"preview": "import { ddpReducer } from './ddpReducer.js';\nimport { ddpReactiveDocument } from './ddpReactiveDocument.js';\nimport { d"
},
{
"path": "src/classes/ddpReactiveDocument.js",
"chars": 2436,
"preview": "import { ddpOnChange } from './ddpOnChange.js';\n\n/**\n * A reactive document class.\n * @constructor\n * @param {ddpReactiv"
},
{
"path": "src/classes/ddpReducer.js",
"chars": 1842,
"preview": "import { ddpOnChange } from './ddpOnChange.js';\n\n/**\n * A reducer class for a reactive document.\n * @constructor\n * @par"
},
{
"path": "src/classes/ddpSubscription.js",
"chars": 5316,
"preview": "/**\n * DDP subscription class.\n * @constructor\n * @param {String} pubname - Publication name.\n * @param {Array} args - S"
},
{
"path": "src/helpers/fullCopy.js",
"chars": 72,
"preview": "import cloneDeep from 'clone-deep';\n\nexport const fullCopy = cloneDeep;\n"
},
{
"path": "src/helpers/isequal.js",
"chars": 1774,
"preview": "export const isEqual = function (value, other) {\n\n\t// Get the value type\n\tvar type = Object.prototype.toString.call(valu"
},
{
"path": "src/simpleddp.js",
"chars": 18260,
"preview": "import DDP from '../core';\nimport EJSON from \"ejson\";\n\nimport { isEqual } from './helpers/isequal.js';\nimport { fullCopy"
},
{
"path": "test/test_call.js",
"chars": 1622,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\n\nconst "
},
{
"path": "test/test_collectionfetch.js",
"chars": 1885,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\n\nconst "
},
{
"path": "test/test_importexport.js",
"chars": 4510,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\nconst E"
},
{
"path": "test/test_onchange.js",
"chars": 6169,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\n\nconst "
},
{
"path": "test/test_reactive.js",
"chars": 18707,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\n\nconst "
},
{
"path": "test/test_reactiveone.js",
"chars": 2769,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\n\nconst "
},
{
"path": "test/test_sub.js",
"chars": 4835,
"preview": "const assert = require('chai').assert;\n\nconst simpleDDP = require('../lib/simpleddp');\nconst ws = require(\"ws\");\n\nconst "
}
]
About this extraction
This page contains the full source code of the Gregivy/simpleddp GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 74 files (465.7 KB), approximately 115.3k tokens, and a symbol index with 132 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.