mongo-realtime 2.0.1 → 2.0.3
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/README.md +6 -4
- package/index.js +45 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -51,17 +51,19 @@ MongoRealtime.init({
|
|
|
51
51
|
offSocket: (socket, reason) => {
|
|
52
52
|
console.log(`Client disconnected: ${socket.id}, reason: ${reason}`);
|
|
53
53
|
},
|
|
54
|
+
}).then(() => {
|
|
55
|
+
// It's better to start the server after the db connection is established
|
|
56
|
+
server.listen(3000, () => {
|
|
57
|
+
console.log("Server listening on port 3000");
|
|
58
|
+
});
|
|
54
59
|
});
|
|
55
60
|
|
|
56
|
-
server.listen(3000, () => {
|
|
57
|
-
console.log("Server started on port 3000");
|
|
58
|
-
});
|
|
59
61
|
```
|
|
60
62
|
|
|
61
63
|
## Breaking Changes since v2.x.x
|
|
62
64
|
|
|
63
65
|
In older versions, streams receive all documents and send them to sockets. This can lead to performance issues with large collections.\
|
|
64
|
-
From version 2.x.x, streams now require a limit (default
|
|
66
|
+
From version 2.x.x, streams now require a limit (default 100 documents) from the client side to avoid overloading the server and network.\
|
|
65
67
|
Receiving streamed docs now works like this:
|
|
66
68
|
|
|
67
69
|
```javascript
|
package/index.js
CHANGED
|
@@ -63,7 +63,7 @@ class MongoRealtime {
|
|
|
63
63
|
|
|
64
64
|
const expr = err ?? (match ? match[1].trim() : src);
|
|
65
65
|
|
|
66
|
-
throw new Error(`MongoRealtime
|
|
66
|
+
throw new Error(`MongoRealtime expects "${expr}"`);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -116,12 +116,15 @@ class MongoRealtime {
|
|
|
116
116
|
* @param {bool} options.debug - Enable debug mode
|
|
117
117
|
* @param {number} options.cacheDelay - Cache delay in minutes. Put 0 if no cache
|
|
118
118
|
* @param {number} options.allowDbOperations - If true, you can use find and update operations.
|
|
119
|
+
* @param {mongoose} options.mongooseInstance - Running mongoose instance
|
|
120
|
+
*
|
|
119
121
|
*
|
|
120
122
|
*/
|
|
121
123
|
static async init({
|
|
122
124
|
dbUri,
|
|
123
125
|
dbOptions,
|
|
124
126
|
server,
|
|
127
|
+
mongooseInstance,
|
|
125
128
|
onDbConnect,
|
|
126
129
|
onDbError,
|
|
127
130
|
authentify,
|
|
@@ -192,42 +195,14 @@ class MongoRealtime {
|
|
|
192
195
|
changeStream.on("change", async (change) => {
|
|
193
196
|
const coll = change.ns.coll;
|
|
194
197
|
const colName = coll.toLowerCase();
|
|
195
|
-
const
|
|
198
|
+
const id = change.documentKey?._id.toString();
|
|
199
|
+
const doc = change.fullDocument ?? { _id: id };
|
|
196
200
|
|
|
197
201
|
this.#debugLog(`Collection '${colName}' changed`);
|
|
198
202
|
|
|
199
203
|
change.col = colName;
|
|
200
204
|
|
|
201
205
|
const type = change.operationType;
|
|
202
|
-
const id = change.documentKey?._id.toString();
|
|
203
|
-
|
|
204
|
-
for (const k in this.#streams) {
|
|
205
|
-
const stream = this.#streams[k];
|
|
206
|
-
if (stream.collection != coll) continue;
|
|
207
|
-
|
|
208
|
-
Promise.resolve(stream.filter(doc)).then((ok) => {
|
|
209
|
-
if (ok) {
|
|
210
|
-
this.io.emit(`realtime:${k}`, {
|
|
211
|
-
results: [doc],
|
|
212
|
-
coll: coll,
|
|
213
|
-
count: 1,
|
|
214
|
-
total: 1,
|
|
215
|
-
remaining: 0,
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
});
|
|
219
|
-
}
|
|
220
|
-
for (let k in this.#data) {
|
|
221
|
-
if (!k.startsWith(`${coll}-`) || !this.#data[k].result[id]) continue;
|
|
222
|
-
doc._id = doc._id.toString();
|
|
223
|
-
switch (change.operationType) {
|
|
224
|
-
case "delete":
|
|
225
|
-
delete this.#data[k].result[id];
|
|
226
|
-
break;
|
|
227
|
-
default:
|
|
228
|
-
this.#data[k].result[id] = doc;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
206
|
|
|
232
207
|
const e_change = "db:change";
|
|
233
208
|
const e_change_type = `db:${type}`;
|
|
@@ -251,12 +226,39 @@ class MongoRealtime {
|
|
|
251
226
|
this.io.emit(e, change);
|
|
252
227
|
this.notifyListeners(e, change);
|
|
253
228
|
}
|
|
229
|
+
|
|
230
|
+
for (const k in this.#streams) {
|
|
231
|
+
const stream = this.#streams[k];
|
|
232
|
+
if (stream.collection != coll) continue;
|
|
233
|
+
|
|
234
|
+
Promise.resolve(stream.filter(doc)).then((ok) => {
|
|
235
|
+
if (ok) {
|
|
236
|
+
const data = { added: [], removed: [] };
|
|
237
|
+
if (change.operationType == "delete") data.removed.push(doc);
|
|
238
|
+
else data.added.push(doc);
|
|
239
|
+
|
|
240
|
+
this.io.emit(`realtime:${k}`, data);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
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
|
+
}
|
|
254
|
+
}
|
|
254
255
|
});
|
|
255
256
|
});
|
|
256
257
|
|
|
257
258
|
try {
|
|
258
259
|
await mongoose.connect(dbUri, dbOptions);
|
|
259
260
|
this.#log(`Connected to db '${mongoose.connection.name}'`, 1);
|
|
261
|
+
if (mongooseInstance) mongooseInstance.connection = mongoose.connection;
|
|
260
262
|
onDbConnect?.call(this, mongoose.connection);
|
|
261
263
|
} catch (error) {
|
|
262
264
|
onDbError?.call(this, error);
|
|
@@ -303,8 +305,8 @@ class MongoRealtime {
|
|
|
303
305
|
|
|
304
306
|
const stream = this.#streams[streamId];
|
|
305
307
|
const coll = stream.collection;
|
|
306
|
-
|
|
307
|
-
const default_limit =
|
|
308
|
+
|
|
309
|
+
const default_limit = 100;
|
|
308
310
|
limit ??= default_limit;
|
|
309
311
|
try {
|
|
310
312
|
limit = parseInt(limit);
|
|
@@ -315,7 +317,7 @@ class MongoRealtime {
|
|
|
315
317
|
reverse = reverse == true;
|
|
316
318
|
registerId ??= "";
|
|
317
319
|
this.#debugLog(
|
|
318
|
-
`Socket ${socket.id} registred for realtime '${coll}:${registerId}'. Limit ${limit}. Reversed ${reverse}`
|
|
320
|
+
`Socket '${socket.id}' registred for realtime '${coll}:${registerId}'. Limit ${limit}. Reversed ${reverse}`
|
|
319
321
|
);
|
|
320
322
|
|
|
321
323
|
let total;
|
|
@@ -390,11 +392,8 @@ class MongoRealtime {
|
|
|
390
392
|
.map((item) => item.doc);
|
|
391
393
|
|
|
392
394
|
const data = {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
count: filtered.length,
|
|
396
|
-
total,
|
|
397
|
-
remaining: total - ids.length,
|
|
395
|
+
added: filtered,
|
|
396
|
+
removed: [],
|
|
398
397
|
};
|
|
399
398
|
|
|
400
399
|
socket.emit(`realtime:${streamId}:${registerId}`, data);
|
|
@@ -457,12 +456,14 @@ class MongoRealtime {
|
|
|
457
456
|
{ coll, query, limit, sortBy, project, one, skip, id, update },
|
|
458
457
|
ack
|
|
459
458
|
) => {
|
|
460
|
-
|
|
461
459
|
if (!coll || !notEmpty(update)) return ack(0);
|
|
462
460
|
const c = this.connection.db.collection(coll);
|
|
463
461
|
|
|
464
|
-
if (id) {
|
|
465
|
-
ack(
|
|
462
|
+
if (id) {
|
|
463
|
+
ack(
|
|
464
|
+
(await c.updateOne({ _id: toObjectId(id) }, update))
|
|
465
|
+
.modifiedCount
|
|
466
|
+
);
|
|
466
467
|
return;
|
|
467
468
|
}
|
|
468
469
|
|
|
@@ -481,11 +482,11 @@ class MongoRealtime {
|
|
|
481
482
|
};
|
|
482
483
|
|
|
483
484
|
if (one) {
|
|
484
|
-
ack((await c.updateOne(query,update, options)).modifiedCount);
|
|
485
|
+
ack((await c.updateOne(query, update, options)).modifiedCount);
|
|
485
486
|
return;
|
|
486
487
|
}
|
|
487
488
|
|
|
488
|
-
let cursor = await c.updateMany(query,update, options);
|
|
489
|
+
let cursor = await c.updateMany(query, update, options);
|
|
489
490
|
ack(cursor.modifiedCount);
|
|
490
491
|
}
|
|
491
492
|
);
|