I'm trying to provide a collection having its methods wrapped in fibers for synchronous looking calls.
const Fiber = require('fibers');
const wrapInFiber = require('./wrapInFiber');
let db;
Fiber(function () {
db = wrapInFiber({
url: global.__MONGO_URI__,
config: { useNewUrlParser: true, useUnifiedTopology: true },
databaseName: global.__MONGO_DB_NAME__,
collections: ['users'],
});
console.log('DB', db.users);
}).run();
module.exports.Users = db.users; <-- undefined
Console log outputs the value but db.users
passed to the module.exports
is undefined because either it runs before the fiber is done or rather outside the fiber, I presume? So, how can I pass the value to the module.exports
correctly?
The only remotely close answer is this one which I tried to mimic but failed, maybe because his wrapped function involved no fibers related code unlike mine.
WrapInFiber
just in case. It's adapted from this library.
const Fiber = require('fibers');
const { MongoClient } = require('mongodb');
module.exports = function ({ url, config, databaseName, collections }) {
const Collection = function (db, name) {
this.collection = db.collection(name);
};
Collection.prototype.count = function (query, options) {
query = query || {};
options = options || {};
const fiber = Fiber.current;
this.collection.count(query, options, function (err, records) {
fiber.run(records);
});
return Fiber.yield();
};
Collection.prototype.find = function (query, options) {
query = query || {};
options = options || {};
const fiber = Fiber.current;
this.collection.find(query, options).toArray(function (err, records) {
fiber.run(records);
});
return Fiber.yield();
};
Collection.prototype.findOne = function (query, options) {
return this.find(query, options)[0];
};
Collection.prototype.update = function (query, options) {
const fiber = Fiber.current;
this.collection.update(query, options, function (err, records) {
fiber.run(records);
});
return Fiber.yield();
};
Collection.prototype.insert = function (document) {
const fiber = Fiber.current;
this.collection.insert(document, function (err, records) {
fiber.run(records);
});
return Fiber.yield();
};
Collection.prototype.remove = function (document) {
const fiber = Fiber.current;
this.collection.remove(document, function (err, records) {
fiber.run(records);
});
return Fiber.yield();
};
const fiber = Fiber.current;
MongoClient.connect(url, config, function (err, connection) {
const obj = {
close() {
connection.close();
},
};
const db = connection.db(databaseName);
collections.forEach(function (collectionName) {
obj[collectionName] = new Collection(db, collectionName);
});
fiber.run(obj);
});
return Fiber.yield();
};
While I didn't solve the issues of fibers I managed to solve the initial problem which led to this path of stubbing Meteor collections. All it took was a simple Sinon stub.