mongo-realtime 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +110 -2
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -35,7 +35,7 @@ class MongoRealtime {
|
|
|
35
35
|
mongoose.connection;
|
|
36
36
|
/** @type {Record<String, [(change:ChangeStreamDocument)=>void]>} */ static #listeners =
|
|
37
37
|
{};
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
static sockets = () => [...this.io.sockets.sockets.values()];
|
|
40
40
|
|
|
41
41
|
/**@type {Record<String, {collection:String,filter: (doc:Object)=>Promise<boolean>}>} */
|
|
@@ -114,6 +114,8 @@ class MongoRealtime {
|
|
|
114
114
|
* @param {[String]} options.watch - Collections to watch. If empty, will watch all collections
|
|
115
115
|
* @param {[String]} options.ignore - Collections to ignore. Can override `watch`
|
|
116
116
|
* @param {bool} options.debug - Enable debug mode
|
|
117
|
+
* @param {number} options.cacheDelay - Cache delay in minutes. Put 0 if no cache
|
|
118
|
+
* @param {number} options.allowDbOperations - If true, you can use find and update operations.
|
|
117
119
|
*
|
|
118
120
|
*/
|
|
119
121
|
static async init({
|
|
@@ -130,6 +132,8 @@ class MongoRealtime {
|
|
|
130
132
|
middlewares = [],
|
|
131
133
|
watch = [],
|
|
132
134
|
ignore = [],
|
|
135
|
+
cacheDelay = 5,
|
|
136
|
+
allowDbOperations = true,
|
|
133
137
|
}) {
|
|
134
138
|
this.#log(`MongoRealtime version (${this.version})`, 2);
|
|
135
139
|
|
|
@@ -350,7 +354,7 @@ class MongoRealtime {
|
|
|
350
354
|
|
|
351
355
|
ids.push(...result.map((d) => d._id));
|
|
352
356
|
|
|
353
|
-
const delayInMin =
|
|
357
|
+
const delayInMin = cacheDelay;
|
|
354
358
|
const expiration = new Date(now.getTime() + delayInMin * 60 * 1000);
|
|
355
359
|
const resultMap = result.reduce((acc, item) => {
|
|
356
360
|
item._id = item._id.toString();
|
|
@@ -397,6 +401,95 @@ class MongoRealtime {
|
|
|
397
401
|
} while (ids.length < total);
|
|
398
402
|
}
|
|
399
403
|
);
|
|
404
|
+
if (allowDbOperations) {
|
|
405
|
+
socket.on("realtime:count", async ({ coll, query }, ack) => {
|
|
406
|
+
if (!coll) return ack(0);
|
|
407
|
+
query ??= {};
|
|
408
|
+
const c = this.connection.db.collection(coll);
|
|
409
|
+
const hasQuery = notEmpty(query);
|
|
410
|
+
const count = hasQuery
|
|
411
|
+
? await c.countDocuments(query)
|
|
412
|
+
: await c.estimatedDocumentCount();
|
|
413
|
+
ack(count);
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
socket.on(
|
|
417
|
+
"realtime:find",
|
|
418
|
+
async (
|
|
419
|
+
{ coll, query, limit, sortBy, project, one, skip, id },
|
|
420
|
+
ack
|
|
421
|
+
) => {
|
|
422
|
+
if (!coll) return ack(null);
|
|
423
|
+
const c = this.connection.db.collection(coll);
|
|
424
|
+
|
|
425
|
+
if (id) {
|
|
426
|
+
ack(await c.findOne({ _id: toObjectId(id) }));
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
query ??= {};
|
|
431
|
+
one = one == true;
|
|
432
|
+
|
|
433
|
+
if (query["_id"]) {
|
|
434
|
+
query["_id"] = toObjectId(query["_id"]);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
const options = {
|
|
438
|
+
sort: sortBy,
|
|
439
|
+
projection: project,
|
|
440
|
+
skip: skip,
|
|
441
|
+
limit: limit,
|
|
442
|
+
};
|
|
443
|
+
|
|
444
|
+
if (one) {
|
|
445
|
+
ack(await c.findOne(query, options));
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
let cursor = c.find(query, options);
|
|
450
|
+
ack(await cursor.toArray());
|
|
451
|
+
}
|
|
452
|
+
);
|
|
453
|
+
|
|
454
|
+
socket.on(
|
|
455
|
+
"realtime:update",
|
|
456
|
+
async (
|
|
457
|
+
{ coll, query, limit, sortBy, project, one, skip, id, update },
|
|
458
|
+
ack
|
|
459
|
+
) => {
|
|
460
|
+
|
|
461
|
+
if (!coll || !notEmpty(update)) return ack(0);
|
|
462
|
+
const c = this.connection.db.collection(coll);
|
|
463
|
+
|
|
464
|
+
if (id) {
|
|
465
|
+
ack((await c.updateOne({ _id: toObjectId(id) }, update)).modifiedCount);
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
query ??= {};
|
|
470
|
+
one = one == true;
|
|
471
|
+
|
|
472
|
+
if (query["_id"]) {
|
|
473
|
+
query["_id"] = toObjectId(query["_id"]);
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const options = {
|
|
477
|
+
sort: sortBy,
|
|
478
|
+
projection: project,
|
|
479
|
+
skip: skip,
|
|
480
|
+
limit: limit,
|
|
481
|
+
};
|
|
482
|
+
|
|
483
|
+
if (one) {
|
|
484
|
+
ack((await c.updateOne(query,update, options)).modifiedCount);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
let cursor = await c.updateMany(query,update, options);
|
|
489
|
+
ack(cursor.modifiedCount);
|
|
490
|
+
}
|
|
491
|
+
);
|
|
492
|
+
}
|
|
400
493
|
|
|
401
494
|
socket.on("disconnect", (r) => {
|
|
402
495
|
if (offSocket) offSocket(socket, r);
|
|
@@ -483,4 +576,19 @@ class MongoRealtime {
|
|
|
483
576
|
}
|
|
484
577
|
}
|
|
485
578
|
|
|
579
|
+
// utils
|
|
580
|
+
function notEmpty(obj) {
|
|
581
|
+
obj ??= {};
|
|
582
|
+
return Object.keys(obj).length > 0;
|
|
583
|
+
}
|
|
584
|
+
/** @param {String} id */
|
|
585
|
+
function toObjectId(id) {
|
|
586
|
+
if (typeof id != "string") return id;
|
|
587
|
+
try {
|
|
588
|
+
return mongoose.Types.ObjectId.createFromHexString(id);
|
|
589
|
+
} catch (_) {
|
|
590
|
+
return new mongoose.Types.ObjectId(id); //use deprecated if fail
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
|
|
486
594
|
module.exports = MongoRealtime;
|