mongo-realtime 2.0.3 → 2.0.4

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 +87 -112
  2. package/package.json +4 -4
package/index.js CHANGED
@@ -41,7 +41,7 @@ class MongoRealtime {
41
41
  /**@type {Record<String, {collection:String,filter: (doc:Object)=>Promise<boolean>}>} */
42
42
  static #streams = {};
43
43
 
44
- /**@type {Record<String, {expiration:Date,result:Record<String,{}> }>} */
44
+ /**@type {Record<String, Record<String,{}>>} */
45
45
  static #data = {};
46
46
 
47
47
  /** @type {[String]} - All DB collections */
@@ -51,6 +51,13 @@ class MongoRealtime {
51
51
 
52
52
  static version = version;
53
53
 
54
+ static #resolvePromise;
55
+ static #rejectPromise;
56
+
57
+ static get(coll) {
58
+ return Object.values(this.#data[coll] ?? {});
59
+ }
60
+
54
61
  static #check(fn, err) {
55
62
  const result = fn();
56
63
  if (!result) {
@@ -138,6 +145,11 @@ class MongoRealtime {
138
145
  cacheDelay = 5,
139
146
  allowDbOperations = true,
140
147
  }) {
148
+ const promise = new Promise((resolve, reject) => {
149
+ this.#resolvePromise = resolve;
150
+ this.#rejectPromise = reject;
151
+ });
152
+
141
153
  this.#log(`MongoRealtime version (${this.version})`, 2);
142
154
 
143
155
  if (this.io) this.io.close();
@@ -148,12 +160,12 @@ class MongoRealtime {
148
160
  this.io = new Server(server);
149
161
  this.connection.once("open", async () => {
150
162
  this.collections = (await this.connection.listCollections()).map(
151
- (c) => c.name
163
+ (c) => c.name,
152
164
  );
153
165
  this.#debugLog(
154
166
  `${this.collections.length} collections found : ${this.collections.join(
155
- ", "
156
- )}`
167
+ ", ",
168
+ )}`,
157
169
  );
158
170
 
159
171
  let pipeline = [];
@@ -184,11 +196,11 @@ class MongoRealtime {
184
196
  if (autoStream == null) collectionsToStream = this.collections;
185
197
  else
186
198
  collectionsToStream = this.collections.filter((c) =>
187
- autoStream.includes(c)
199
+ autoStream.includes(c),
188
200
  );
189
201
  for (let col of collectionsToStream) this.addStream(col, col);
190
202
  this.#debugLog(
191
- `Auto stream on collections : ${collectionsToStream.join(", ")}`
203
+ `Auto stream on collections : ${collectionsToStream.join(", ")}`,
192
204
  );
193
205
 
194
206
  /** Emit listen events on change */
@@ -241,18 +253,17 @@ class MongoRealtime {
241
253
  }
242
254
  });
243
255
  }
244
- for (let k in this.#data) {
245
- if (!k.startsWith(`${coll}-`) || !this.#data[k].result[id]) continue;
246
- switch (change.operationType) {
247
- case "delete":
248
- delete this.#data[k].result[id];
249
- break;
250
- default:
251
- doc._id = id;
252
- this.#data[k].result[id] = doc;
253
- }
256
+ switch (change.operationType) {
257
+ case "delete":
258
+ delete this.#data[coll][id];
259
+ break;
260
+ default:
261
+ doc._id = id;
262
+ this.#data[coll][id] = doc;
254
263
  }
255
264
  });
265
+
266
+ this.#getAllData();
256
267
  });
257
268
 
258
269
  try {
@@ -305,100 +316,43 @@ class MongoRealtime {
305
316
 
306
317
  const stream = this.#streams[streamId];
307
318
  const coll = stream.collection;
308
-
309
- const default_limit = 100;
310
- limit ??= default_limit;
311
- try {
312
- limit = parseInt(limit);
313
- } catch (_) {
314
- limit = default_limit;
315
- }
319
+ const data = this.#data[coll];
316
320
 
317
- reverse = reverse == true;
318
321
  registerId ??= "";
319
- this.#debugLog(
320
- `Socket '${socket.id}' registred for realtime '${coll}:${registerId}'. Limit ${limit}. Reversed ${reverse}`
321
- );
322
-
323
- let total;
324
- const ids = [];
325
-
326
- do {
327
- total = await this.connection.db
328
- .collection(coll)
329
- .estimatedDocumentCount();
330
-
331
- const length = ids.length;
332
- const range = [length, Math.min(total, length + limit)];
333
- const now = new Date();
334
-
335
- let cachedKey = `${coll}-${range}`;
336
-
337
- let cachedResult = this.#data[cachedKey];
338
- if (cachedResult && cachedResult.expiration < now) {
339
- delete this.#data[cachedKey];
340
- }
341
-
342
- cachedResult = this.#data[cachedKey];
343
-
344
- const result = cachedResult
345
- ? Object.values(cachedResult.result)
346
- : await this.connection.db
347
- .collection(coll)
348
- .find({
349
- _id: {
350
- $nin: ids,
351
- },
352
- })
353
- .limit(limit)
354
- .sort({ _id: reverse ? -1 : 1 })
355
- .toArray();
356
-
357
- ids.push(...result.map((d) => d._id));
358
-
359
- const delayInMin = cacheDelay;
360
- const expiration = new Date(now.getTime() + delayInMin * 60 * 1000);
361
- const resultMap = result.reduce((acc, item) => {
362
- item._id = item._id.toString();
363
- acc[item._id] = item;
364
- return acc;
365
- }, {});
366
-
367
- if (!cachedResult) {
368
- this.#data[cachedKey] = {
369
- expiration,
370
- result: resultMap,
371
- };
372
- }
373
-
374
- const filtered = (
375
- await Promise.all(
376
- result.map(async (doc) => {
377
- try {
378
- return {
379
- doc,
380
- ok: await stream.filter(doc),
381
- };
382
- } catch (e) {
383
- return {
384
- doc,
385
- ok: false,
386
- };
387
- }
388
- })
389
- )
322
+ // this.#debugLog(
323
+ // `Socket '${socket.id}' registred for realtime '${coll}:${registerId}'. Limit ${limit}. Reversed ${reverse}`,
324
+ // );
325
+
326
+ let result = Object.values(data);
327
+
328
+ const filtered = (
329
+ await Promise.all(
330
+ result.map(async (doc) => {
331
+ try {
332
+ return {
333
+ doc,
334
+ ok: await stream.filter(doc),
335
+ };
336
+ } catch (e) {
337
+ return {
338
+ doc,
339
+ ok: false,
340
+ };
341
+ }
342
+ }),
390
343
  )
391
- .filter((item) => item.ok)
392
- .map((item) => item.doc);
393
-
394
- const data = {
395
- added: filtered,
344
+ )
345
+ .filter((item) => item.ok)
346
+ .map((item) => item.doc);
347
+
348
+ limit ??= filtered.length;
349
+ for (let i = 0; i < filtered.length; i += limit) {
350
+ socket.emit(`realtime:${streamId}:${registerId}`, {
351
+ added: filtered.slice(i, i + limit),
396
352
  removed: [],
397
- };
398
-
399
- socket.emit(`realtime:${streamId}:${registerId}`, data);
400
- } while (ids.length < total);
401
- }
353
+ });
354
+ }
355
+ },
402
356
  );
403
357
  if (allowDbOperations) {
404
358
  socket.on("realtime:count", async ({ coll, query }, ack) => {
@@ -416,7 +370,7 @@ class MongoRealtime {
416
370
  "realtime:find",
417
371
  async (
418
372
  { coll, query, limit, sortBy, project, one, skip, id },
419
- ack
373
+ ack,
420
374
  ) => {
421
375
  if (!coll) return ack(null);
422
376
  const c = this.connection.db.collection(coll);
@@ -447,14 +401,14 @@ class MongoRealtime {
447
401
 
448
402
  let cursor = c.find(query, options);
449
403
  ack(await cursor.toArray());
450
- }
404
+ },
451
405
  );
452
406
 
453
407
  socket.on(
454
408
  "realtime:update",
455
409
  async (
456
410
  { coll, query, limit, sortBy, project, one, skip, id, update },
457
- ack
411
+ ack,
458
412
  ) => {
459
413
  if (!coll || !notEmpty(update)) return ack(0);
460
414
  const c = this.connection.db.collection(coll);
@@ -462,7 +416,7 @@ class MongoRealtime {
462
416
  if (id) {
463
417
  ack(
464
418
  (await c.updateOne({ _id: toObjectId(id) }, update))
465
- .modifiedCount
419
+ .modifiedCount,
466
420
  );
467
421
  return;
468
422
  }
@@ -488,7 +442,7 @@ class MongoRealtime {
488
442
 
489
443
  let cursor = await c.updateMany(query, update, options);
490
444
  ack(cursor.modifiedCount);
491
- }
445
+ },
492
446
  );
493
447
  }
494
448
 
@@ -499,7 +453,7 @@ class MongoRealtime {
499
453
  if (onSocket) onSocket(socket);
500
454
  });
501
455
 
502
- this.#log(`Initialized`, 1);
456
+ return promise;
503
457
  }
504
458
 
505
459
  /**
@@ -516,6 +470,27 @@ class MongoRealtime {
516
470
  }
517
471
  }
518
472
 
473
+ static #getAllData() {
474
+ const total = this.collections.length;
475
+ for (let coll of this.collections) {
476
+ this.connection.db
477
+ .collection(coll)
478
+ .find()
479
+ .toArray()
480
+ .then((r) => {
481
+ this.#data[coll] = r.reduce((acc, doc) => {
482
+ acc[doc._id] = doc;
483
+ return acc;
484
+ }, {});
485
+
486
+ if (Object.keys(this.#data).length == total) {
487
+ this.#log(`Initialized`, 1);
488
+ this.#resolvePromise(this.#data);
489
+ }
490
+ });
491
+ }
492
+ }
493
+
519
494
  /**
520
495
  * Subscribe to an event
521
496
  *
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "mongo-realtime",
3
- "version": "2.0.3",
3
+ "version": "2.0.4",
4
4
  "main": "index.js",
5
- "scripts": {},
6
5
  "keywords": [
7
6
  "mongo",
8
7
  "mongoose",
@@ -23,5 +22,6 @@
23
22
  "chalk": "^4.1.2",
24
23
  "mongoose": "^8.17.0",
25
24
  "socket.io": "^4.8.1"
26
- }
27
- }
25
+ },
26
+ "scripts": {}
27
+ }