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.
Files changed (2) hide show
  1. package/index.js +110 -2
  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 = 1;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mongo-realtime",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "main": "index.js",
5
5
  "scripts": {},
6
6
  "keywords": [