Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

@deepstream/storage-mongodb

Package Overview
Dependencies
Maintainers
2
Versions
8
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@deepstream/storage-mongodb - npm Package Compare versions

Comparing version
2.0.5
to
2.0.6
+6
-0
CHANGELOG.md

@@ -0,1 +1,7 @@

## [2.0.6] 2020-02-08
### Improvement
Updating dependencies
## [2.0.4] 2019-11-24

@@ -2,0 +8,0 @@

+12
-12
{
"name": "@deepstream/storage-mongodb",
"version": "2.0.5",
"version": "2.0.6",
"description": "Connects deepstream.io to mongodb",

@@ -27,18 +27,18 @@ "main": "dist/src/connector.js",

"@deepstream/types": "^2.0.7",
"mongodb": "~3.3"
"mongodb": "~3.5"
},
"devDependencies": {
"@deepstream/protobuf": "^1.0.1",
"@types/chai": "^4.2.5",
"@types/mocha": "^5.2.7",
"@types/mongodb": "^3.3.11",
"@types/node": "^12.12.12",
"@types/chai": "^4.2.8",
"@types/mocha": "^7.0.1",
"@types/mongodb": "^3.3.15",
"@types/node": "^13.7.0",
"chai": "^4.2.0",
"coveralls": "^3.0.8",
"mocha": "^6.2.2",
"nyc": "^14.1.1",
"ts-node": "^8.5.2",
"tslint": "^5.20.1",
"typescript": "^3.7.2"
"coveralls": "^3.0.9",
"mocha": "^7.0.1",
"nyc": "^15.0.0",
"ts-node": "^8.6.2",
"tslint": "^6.0.0",
"typescript": "^3.7.5"
}
}
export declare const name: string;
export declare const version: string;
export declare const description: string;
export declare const main: string;
export declare const scripts: {
"tsc": string;
"lint": string;
"lint:fix": string;
"test": string;
"coverage": string;
"ci": string;
"docker": string;
};
export declare const repository: {
"type": string;
"url": string;
};
export declare const author: string;
export declare const license: string;
export declare namespace bugs {
export const url: string;
}
export declare const homepage: string;
export declare const dependencies: {
"@deepstream/types": string;
"mongodb": string;
};
export declare const devDependencies: {
"@deepstream/protobuf": string;
"@types/chai": string;
"@types/mocha": string;
"@types/mongodb": string;
"@types/node": string;
"chai": string;
"coveralls": string;
"mocha": string;
"nyc": string;
"ts-node": string;
"tslint": string;
"typescript": string;
};
{
"name": "@deepstream/storage-mongodb",
"version": "2.0.5",
"description": "Connects deepstream.io to mongodb",
"main": "dist/src/connector.js",
"scripts": {
"tsc": "tsc",
"lint": "tslint --project .",
"lint:fix": "npm run lint -- --fix",
"test": "mocha --opts mocha.opts 'test/*.spec.ts'",
"coverage": "nyc mocha --exit",
"ci": "npm run coverage",
"docker": "docker run -p 27017:27017 mongo"
},
"repository": {
"type": "git",
"url": "https://github.com/deepstreamIO/deepstream.io-storage-mongodb.git"
},
"author": "deepstreamHub GmbH",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/deepstreamIO/deepstream.io-storage-mongodb/issues"
},
"homepage": "http://deepstream.io",
"dependencies": {
"@deepstream/types": "^2.0.7",
"mongodb": "~3.3"
},
"devDependencies": {
"@deepstream/protobuf": "^1.0.1",
"@types/chai": "^4.2.5",
"@types/mocha": "^5.2.7",
"@types/mongodb": "^3.3.11",
"@types/node": "^12.12.12",
"chai": "^4.2.0",
"coveralls": "^3.0.8",
"mocha": "^6.2.2",
"nyc": "^14.1.1",
"ts-node": "^8.5.2",
"tslint": "^5.20.1",
"typescript": "^3.7.2"
}
}
import { Collection } from 'mongodb';
import { DeepstreamPlugin, DeepstreamStorage, DeepstreamServices, StorageWriteCallback, StorageReadCallback } from '@deepstream/types';
import { JSONObject } from '@deepstream/protobuf/dist/types/all';
interface MongoOptions {
connectionString: any;
db: string;
defaultCollection: string;
splitChar: string;
}
/**
* Connects deepstream to MongoDb.
*
* Collections, ids and performance
* --------------------------------------------------
* Deepstream treats its storage like a simple key value store. But there are a few things
* we can do to speed it up when using MongoDb. Mainly: using smaller (e.g. more granular) collections and using successive Id's
*
*
* To support multiple collections pass a splitChar setting to this class. This setting specifies a character
* at which keys will be split and ordered into collections. This sounds a bit complicated, but all that means is the following:
*
* Imagine you want to store a few users. Just specify their recordNames as e.g.
*
* user/i4vcg5j1-16n1qrnziuog
* user/i4vcg5x9-a2wc3g9pbhmi
* user/i4vcg74u-21ufhl1qs8fh
*
* and in your options set
*
* { splitChar: '/' }
*
* This way the MongoDB connector will create a 'user' collection the first time
* it encounters this recordName and will subsequently store users in it. This will
* improve the speed of read operations since MongoDb has to look through a smaller
* amount of datasets to find your record
*
* On top of this, it makes sense to use successive ids. MongoDb will optimise collections
* by putting documents with similar ids next to each other. Fortunately, the build-in getUid()
* method of the deepstream client already produces semi-succesive ids. Notice how the first bits of the
* ids (user/i4vcg5) are all the same. These are Base36 encoded timestamps, facilitating almost succesive ordering.
*
* {
* // Optional: Collections for items without a splitChar or if no splitChar is specified. Defaults to 'deepstream_docs'
defaultCollection: <String>,
// Optional: A char that seperates the collection name from the document id. Defaults to null
splitChar: <String>,
// Full connection URL for MongoDb. Format is mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
// More details can be found here: http://docs.mongodb.org/manual/reference/connection-string/
connectionString: <String>
}
*/
export declare class Connector extends DeepstreamPlugin implements DeepstreamStorage {
private options;
private services;
apiVersion?: number | undefined;
description: string;
private splitChar;
private defaultCollection;
private collections;
private logger;
private client;
private db;
constructor(options: MongoOptions, services: DeepstreamServices);
whenReady(): Promise<void>;
/**
* Writes a value to the cache.
*/
set(key: string, version: number, value: JSONObject, callback: StorageWriteCallback): void;
/**
* Retrieves a value from the cache
*/
get(key: string, callback: StorageReadCallback): void;
/**
* Deletes an entry from the cache.
*/
delete(key: string, callback: StorageWriteCallback): void;
deleteBulk(recordNames: string[], callback: StorageWriteCallback): void;
/**
* Determines the document id and the collection
* to use based on the provided key
*
* Creates the collection if it doesn't exist yet.
*
* Since MongoDB Object IDs are adhering to a specified format
* we'll add a new field for the key called ds_key and index the
* collection based on it
*/
getParams(key: string): {
collection: Collection<any>;
id: string;
} | null;
/**
* Returns a MongoConnection object given its name.
* Creates the collection if it doesn't exist yet.
*/
getCollection(collectionName: string): Collection<any>;
}
export default Connector;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const pkg = require("../package.json");
const mongodb_1 = require("mongodb");
const types_1 = require("@deepstream/types");
/**
* Connects deepstream to MongoDb.
*
* Collections, ids and performance
* --------------------------------------------------
* Deepstream treats its storage like a simple key value store. But there are a few things
* we can do to speed it up when using MongoDb. Mainly: using smaller (e.g. more granular) collections and using successive Id's
*
*
* To support multiple collections pass a splitChar setting to this class. This setting specifies a character
* at which keys will be split and ordered into collections. This sounds a bit complicated, but all that means is the following:
*
* Imagine you want to store a few users. Just specify their recordNames as e.g.
*
* user/i4vcg5j1-16n1qrnziuog
* user/i4vcg5x9-a2wc3g9pbhmi
* user/i4vcg74u-21ufhl1qs8fh
*
* and in your options set
*
* { splitChar: '/' }
*
* This way the MongoDB connector will create a 'user' collection the first time
* it encounters this recordName and will subsequently store users in it. This will
* improve the speed of read operations since MongoDb has to look through a smaller
* amount of datasets to find your record
*
* On top of this, it makes sense to use successive ids. MongoDb will optimise collections
* by putting documents with similar ids next to each other. Fortunately, the build-in getUid()
* method of the deepstream client already produces semi-succesive ids. Notice how the first bits of the
* ids (user/i4vcg5) are all the same. These are Base36 encoded timestamps, facilitating almost succesive ordering.
*
* {
* // Optional: Collections for items without a splitChar or if no splitChar is specified. Defaults to 'deepstream_docs'
defaultCollection: <String>,
// Optional: A char that seperates the collection name from the document id. Defaults to null
splitChar: <String>,
// Full connection URL for MongoDb. Format is mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
// More details can be found here: http://docs.mongodb.org/manual/reference/connection-string/
connectionString: <String>
}
*/
class Connector extends types_1.DeepstreamPlugin {
constructor(options, services) {
super();
this.options = options;
this.services = services;
this.description = `MongoDB Storage ${pkg.version} using db ${this.options.db}`;
this.splitChar = this.options.splitChar || '/';
this.defaultCollection = this.options.defaultCollection || 'deepstream_docs';
this.collections = new Map();
this.logger = this.services.logger.getNameSpace('MONGODB');
if (!this.options.connectionString) {
this.logger.fatal(types_1.EVENT.PLUGIN_INITIALIZATION_ERROR, "Missing setting 'connectionString'");
}
this.client = new mongodb_1.MongoClient(options.connectionString, { useUnifiedTopology: true });
this.client.connect();
}
async whenReady() {
this.client = await this.client.connect();
this.db = this.client.db(this.options.db);
}
/**
* Writes a value to the cache.
*/
set(key, version, value, callback) {
const params = this.getParams(key);
if (value instanceof Array) {
value = { ds_list: value };
}
if (params === null) {
callback(`Invalid key ${key}`);
return;
}
value.ds_key = params.id;
value.ds_version = version;
params.collection.updateOne({ ds_key: params.id }, { $set: value }, { upsert: true }, callback);
}
/**
* Retrieves a value from the cache
*/
get(key, callback) {
const params = this.getParams(key);
if (params === null) {
callback(`Invalid key ${key}`);
return;
}
params.collection.findOne({ ds_key: params.id }, (error, doc) => {
if (error) {
// this.logger.error(EVENT.ERROR, 'Error retrieving mongodb entry', { error })
callback('Error getting object');
return;
}
if (doc === null) {
callback(null, -1, null);
return;
}
const version = doc.ds_version;
delete doc._id;
delete doc.ds_key;
delete doc.ds_version;
if (doc.ds_list instanceof Array) {
doc = doc.ds_list;
}
callback(null, version, doc);
});
}
/**
* Deletes an entry from the cache.
*/
delete(key, callback) {
const params = this.getParams(key);
if (params === null) {
callback('Invalid key ' + key);
return;
}
params.collection.deleteOne({ ds_key: params.id }, callback);
}
deleteBulk(recordNames, callback) {
throw new Error('Method not implemented.');
}
/**
* Determines the document id and the collection
* to use based on the provided key
*
* Creates the collection if it doesn't exist yet.
*
* Since MongoDB Object IDs are adhering to a specified format
* we'll add a new field for the key called ds_key and index the
* collection based on it
*/
getParams(key) {
const index = key.indexOf(this.splitChar);
let collectionName;
let id;
if (index === 0) {
return null; // cannot have an empty collection name
}
if (index === -1) {
collectionName = this.defaultCollection;
id = key;
}
else {
collectionName = key.substring(0, index);
id = key.substring(index + 1);
}
return { collection: this.getCollection(collectionName), id };
}
/**
* Returns a MongoConnection object given its name.
* Creates the collection if it doesn't exist yet.
*/
getCollection(collectionName) {
let collection = this.collections.get(collectionName);
if (!collection) {
collection = this.db.collection(collectionName);
collection.createIndex('ds_key'); // this is async
this.collections.set(collectionName, collection);
}
return collection;
}
}
exports.Connector = Connector;
exports.default = Connector;
//# sourceMappingURL=connector.js.map
{"version":3,"file":"connector.js","sourceRoot":"","sources":["../../src/connector.ts"],"names":[],"mappings":"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"}
export declare const config: {
connectionString: string;
db: string;
defaultCollection: string;
splitChar: string;
};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.config = {
connectionString: process.env.MONGODB_CONNECTION_STRING || 'mongodb://127.0.0.1',
db: 'deepstream',
defaultCollection: 'default',
splitChar: '/'
};
//# sourceMappingURL=connection-params.js.map
{"version":3,"file":"connection-params.js","sourceRoot":"","sources":["../../test/connection-params.ts"],"names":[],"mappings":";;AAAa,QAAA,MAAM,GAAG;IACpB,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,qBAAqB;IAChF,EAAE,EAAE,YAAY;IAChB,iBAAiB,EAAE,SAAS;IAC5B,SAAS,EAAE,GAAG;CACf,CAAA"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const connector_1 = require("../src/connector");
const connection_params_1 = require("./connection-params");
describe('the storage connector has the correct structure', () => {
let connector;
before('creates the connector', async () => {
// @ts-ignore
connector = new connector_1.Connector(connection_params_1.config, { logger: { getNameSpace: () => ({
fatal: (e, m) => {
// tslint:disable-next-line
console.error('Fatal exception', e, m);
}
})
} });
await connector.whenReady();
});
it('implements the cache/storage connector interface', () => {
chai_1.expect(typeof connector.description).to.equal('string');
chai_1.expect(typeof connector.deleteBulk).to.equal('function');
// expect(typeof connector.head).to.equal('function')
chai_1.expect(typeof connector.get).to.equal('function');
chai_1.expect(typeof connector.set).to.equal('function');
chai_1.expect(typeof connector.delete).to.equal('function');
});
it('retrieves a non existing value', (done) => {
connector.get('someValue', (error, version, value) => {
chai_1.expect(error).to.equal(null);
chai_1.expect(version).to.equal(-1);
chai_1.expect(value).to.equal(null);
done();
});
});
it('sets a value', (done) => {
connector.set('someValue', 2, { firstname: 'Wolfram' }, (error) => {
chai_1.expect(error).to.equal(null);
done();
});
});
it('retrieves an existing value', (done) => {
connector.get('someValue', (error, version, value) => {
chai_1.expect(error).to.equal(null);
chai_1.expect(version).to.equal(2);
chai_1.expect(value).to.deep.equal({ firstname: 'Wolfram' });
done();
});
});
it('deletes a value', (done) => {
connector.delete('someValue', (error) => {
chai_1.expect(error).to.equal(null);
done();
});
});
it("Can't retrieve a deleted value", (done) => {
connector.get('someValue', (error, version, value) => {
chai_1.expect(error).to.equal(null);
chai_1.expect(version).to.equal(-1);
chai_1.expect(value).to.equal(null);
done();
});
});
});
//# sourceMappingURL=storage-connector.spec.js.map
{"version":3,"file":"storage-connector.spec.js","sourceRoot":"","sources":["../../test/storage-connector.spec.ts"],"names":[],"mappings":"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"}

Sorry, the diff of this file is not supported yet