mongoplusplus 1.0.5 → 1.0.7

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.d.ts CHANGED
@@ -3,142 +3,224 @@ import mongoose = require('mongoose');
3
3
  /**
4
4
  * Mongoplus manages multiple mongoose connections and builds distributed models.
5
5
  *
6
- * Usage example:
7
- * ```js
8
- * const Mongoplus = require('mongoplus');
9
- * const mp = new Mongoplus(['mongodb://host1/db', 'readonly:mongodb://host2/db']);
6
+ * Example:
7
+ * ```ts
8
+ * import Mongoplus from 'mongoplusplus';
9
+ * const mp = new Mongoplus(['mongodb://a/db','readonly:mongodb://b/db']);
10
10
  * await mp.connectToAll();
11
- * const User = mp.buildModel('User', new mp.Schema({ name: String, dbIndex: { type: Number, required: true } }));
12
- * await User.write({ name: 'Alice' });
13
11
  * ```
14
12
  */
15
13
  declare class Mongoplus {
16
- /** Array of connection URIs. Prefix a URI with `readonly:` to mark it read-only. */
14
+ /** Array of connection URIs. Use `readonly:` prefix to mark read-only URIs. */
17
15
  mongoURI: string[];
18
16
  /** All mongoose connections created by `connectToAll`. */
19
17
  allConnections: mongoose.Connection[];
20
- /** Internal rotation index used by `getNextMongoURI`. */
18
+ /** Internal rotation index. */
21
19
  currentIndex: number;
22
- /** Connections that were created from `readonly:` URIs. */
20
+ /** Connections created from `readonly:` URIs. */
23
21
  static readonlydbs: mongoose.Connection[];
24
22
  /** Models corresponding to readonly connections. */
25
23
  static readonlymodels: any[];
26
24
 
27
25
  /**
28
- * Create a Mongoplus manager.
29
- * @param mongoURI - Array of MongoDB URIs. Use `readonly:` prefix for read-only replicas.
26
+ * Create manager with list of URIs.
27
+ * @example
28
+ * const mp = new Mongoplus(['mongodb://a/db','readonly:mongodb://b/db']);
30
29
  */
31
30
  constructor(mongoURI: string[]);
32
31
 
33
- /** Create a mongoose Schema from a plain definition. */
32
+ /**
33
+ * Create a mongoose Schema.
34
+ * @example
35
+ * const schema = mp.Schema({ name: String, dbIndex: { type: Number, required: true } });
36
+ */
34
37
  Schema(schema: mongoose.SchemaDefinition | mongoose.Schema): mongoose.Schema;
35
38
 
36
- /** Add an index to a schema. Delegates to `schema.index(...)`. */
37
- addIndex(schema: mongoose.Schema, indextype: any): any;
39
+ /**
40
+ * Add an index to a schema.
41
+ * @example
42
+ * mp.addIndex(schema, { email: 1 });
43
+ */
44
+ addIndex(schema: mongoose.Schema, indextype: any): void;
38
45
 
39
- /** Return next MongoDB URI in rotation (without `readonly:` prefix). */
46
+ /**
47
+ * Return next MongoDB URI in rotation.
48
+ */
40
49
  getNextMongoURI(): string;
41
50
 
42
51
  /**
43
- * Establish all connections from `mongoURI`. Returns an array of mongoose.Connection.
44
- * Call this before `buildModel`.
52
+ * Establish all connections. Call before `buildModel`.
53
+ * @returns array of `mongoose.Connection`.
45
54
  */
46
55
  connectToAll(): mongoose.Connection[];
47
56
 
48
57
  /**
49
- * Build a distributed model across all connections.
50
- * The provided `schema` must include a required numeric `dbIndex` field.
58
+ * Build a distributed model across all connections. Schema must include `dbIndex`.
59
+ * @example
60
+ * const User = mp.buildModel('User', schema);
51
61
  */
52
62
  buildModel(name: string, schema: mongoose.Schema): MongoModel;
53
63
  }
54
64
 
55
65
  /**
56
- * MongoModel represents the model instances distributed across multiple databases.
57
- * Methods with `InAllDatabase` perform the operation on every connection and return aggregated results.
66
+ * MongoModel wraps per-connection models and exposes multi-DB helpers.
58
67
  */
59
68
  declare class MongoModel {
60
- /** Array of mongoose models (one per connection). */
69
+ /** Per-connection mongoose Model instances. */
61
70
  model: any[];
62
71
  /** Read-only model references. */
63
72
  readonlydbs: any[];
64
- /** Original schema used to create the models. */
73
+ /** Original schema. */
65
74
  s: mongoose.Schema;
66
- /** Rotation index for `write` balancing. */
75
+ /** Rotation index for `write`. */
67
76
  static currentIndex: number;
68
77
 
69
78
  /**
70
- * @param model - array of mongoose Model instances (one per connection)
71
- * @param s - mongoose Schema used to create models
72
- * @param readonlydbs - list of models that are read-only
79
+ * Construct a MongoModel.
80
+ * @example
81
+ * const mm = new MongoModel([M1,M2], schema, [M2]);
73
82
  */
74
83
  constructor(model: any[], s: mongoose.Schema, readonlydbs: any[]);
75
84
 
76
- /** Find matching documents in all databases.
77
- * @param filter - mongoose filter
78
- * @param chain - optional chaining options (skip, limit, sort)
85
+ /**
86
+ * Run `find` on every DB and return aggregated results with timing.
87
+ * @example
88
+ * const { results, totalTime } = await User.findInAllDatabase({ active: true });
79
89
  */
80
90
  findInAllDatabase(filter: any, chain?: any): Promise<any>;
81
91
 
82
- /** Run aggregation pipeline on all databases. */
92
+ /**
93
+ * Run aggregation pipeline on every DB and return aggregated results.
94
+ * @example
95
+ * await User.aggregateInAllDatabase([{ $match: { age: { $gt: 18 } } }]);
96
+ */
83
97
  aggregateInAllDatabase(filter: any, chain?: any): Promise<any>;
84
98
 
85
- /** Write the same document to all writable databases. Returns an array of saved docs. */
99
+ /**
100
+ * Write the same document to all writable DBs. Returns saved docs array.
101
+ * @example
102
+ * await User.writeInAllDatabase({ name: 'Alice' });
103
+ */
86
104
  writeInAllDatabase(data: any): Promise<any[]>;
87
105
 
88
- /** Update one matching document across all databases. */
106
+ /**
107
+ * Update one matching document across all DBs.
108
+ * @example
109
+ * await User.UpdateOneInAllDatabase({ active: false }, { active: true });
110
+ */
89
111
  UpdateOneInAllDatabase(filter: any, update: any): Promise<any>;
90
112
 
91
- /** Update by id across all databases. */
113
+ /**
114
+ * Update by id across all DBs.
115
+ * @example
116
+ * await User.UpdateByIdInAllDatabase(id, { name: 'Bob' });
117
+ */
92
118
  UpdateByIdInAllDatabase(id: any, update: any): Promise<any>;
93
119
 
94
- /** Find by id in all DBs and delete. */
120
+ /**
121
+ * Find by id in all DBs and delete.
122
+ * @example
123
+ * await User.findByIdInAllDatabaseAndDelete(id);
124
+ */
95
125
  findByIdInAllDatabaseAndDelete(id: any): Promise<any>;
96
126
 
97
- /** Find one in all DBs and delete. */
127
+ /**
128
+ * Find one in all DBs and delete.
129
+ * @example
130
+ * await User.findOneInAllDatabaseAndDelete({ email: 'x@example.com' });
131
+ */
98
132
  findOneInAllDatabaseAndDelete(filter: any): Promise<any>;
99
133
 
100
- /** Write a single document using round-robin balancing across writable DBs. */
134
+ /**
135
+ * Delete many documents matching `filter` in all databases and return aggregated results.
136
+ * @example
137
+ * await User.finManyInAllDatabaseAndDelete({ expired: true });
138
+ */
139
+ findManyInAllDatabaseAndDelete(filter: any): Promise<any>;
140
+
141
+ /**
142
+ * Write a single document using round-robin balancing across writable DBs.
143
+ * @example
144
+ * const saved = await User.write({ name: 'Charlie' });
145
+ */
101
146
  write(data: any): Promise<any>;
102
147
 
103
148
  /**
104
149
  * Perform efficient bulk upserts across writable DBs.
105
- * @param data - array of objects to upsert
106
- * @param options - optional settings: `batchSize` and `concurrentBatches`
150
+ * @example
151
+ * await User.bulkWrite([{ id: '1', name: 'A' }], { batchSize: 500 });
107
152
  */
108
153
  bulkWrite(data: any[], options?: { batchSize?: number; concurrentBatches?: boolean }): Promise<any[]>;
109
154
 
110
- /** Find a single document on a specific DB index. */
155
+ /**
156
+ * Find a single document on a specific DB index.
157
+ * @example
158
+ * await User.findOne(0, { email: 'x' });
159
+ */
111
160
  findOne(dbIndex: number, filter: any, chain?: any): Promise<any>;
112
161
 
113
- /** Find documents on a specific DB index. */
162
+ /**
163
+ * Find documents on a specific DB index.
164
+ * @example
165
+ * await User.find(1, { active: true }, { limit: 10 });
166
+ */
114
167
  find(dbIndex: number, filter: any, chain?: any): Promise<any>;
115
168
 
116
- /** Find by id on a specific DB index. */
169
+ /**
170
+ * Find by id on a specific DB index.
171
+ * @example
172
+ * await User.findById(0, id);
173
+ */
117
174
  findById(dbIndex: number, filter: any, chain?: any): Promise<any>;
118
175
 
119
- /** Find by id and update on a specific DB index. */
176
+ /**
177
+ * Find by id and update on a specific DB index.
178
+ * @example
179
+ * await User.findByIdAndUpdate(0, id, { name: 'New' });
180
+ */
120
181
  findByIdAndUpdate(dbIndex: number, id: any, update: any): Promise<any>;
121
182
 
122
- /** Find by id and delete on a specific DB index. */
183
+ /**
184
+ * Find by id and delete on a specific DB index.
185
+ * @example
186
+ * await User.findByIdAndDelete(1, id);
187
+ */
123
188
  findByIdAndDelete(dbIndex: number, id: any, update?: any): Promise<any>;
124
189
 
125
- /** Find one and update on a specific DB index. */
190
+ /**
191
+ * Find one and update on a specific DB index.
192
+ * @example
193
+ * await User.findOneAndUpdate(0, { email: 'x' }, { active: false });
194
+ */
126
195
  findOneAndUpdate(dbIndex: number, filter: any, update: any): Promise<any>;
127
196
 
128
- /** Run aggregation on a specific DB index. */
197
+ /**
198
+ * Run aggregation on a specific DB index.
199
+ * @example
200
+ * await User.aggregate(0, [{ $group: { _id: '$country', count: { $sum: 1 } } }]);
201
+ */
129
202
  aggregate(dbIndex: number, filter: any): Promise<any>;
130
203
 
131
- /** Watch change stream on a specific DB index. */
204
+ /**
205
+ * Watch change stream on a specific DB index.
206
+ * @example
207
+ * const stream = User.watch(0);
208
+ */
132
209
  watch(dbIndex: number): any;
133
210
 
134
- /** Return the next model and its index for round-robin writes. */
211
+ /**
212
+ * Return the next model and its index for round-robin writes.
213
+ * @example
214
+ * const [model, idx] = User.getNextModel();
215
+ */
135
216
  getNextModel(): [any, number];
136
217
 
137
- /** Internal runner to execute many queries concurrently and return results with timing. */
218
+ /**
219
+ * Internal runner to execute many queries concurrently and return results with timing.
220
+ */
138
221
  runLargeComputations(computationPairs: any[]): Promise<{ results: any[]; totalTime: number }>;
139
222
  }
140
-
141
- declare namespace Mongoplus { }
142
-
143
- export = Mongoplus;
144
-
223
+ declare namespace Mongoplus {
224
+ export { MongoModel };
225
+ }
226
+ export = Mongoplus;
package/mongoplus.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const mongoose = require('mongoose');
2
+ const { performance } = require('perf_hooks');
2
3
  class Mongoplus {
3
4
  constructor(mongoURI) {
4
5
 
@@ -104,19 +105,15 @@ class MongoModel {
104
105
  async writeInAllDatabase(data) {
105
106
  data["dbIndex"] = -1
106
107
  const dynamicComputationPromises = [];
107
- modellist = this.model
108
- //this.readonlydbs.forEach((i)=>{modellist.splice(i,1,null)})
109
-
108
+ const promises = [];
110
109
  for (let i = 0; i < this.model.length; i++) {
111
110
  if (Mongoplus.readonlymodels.includes(this.model[i])) continue;
112
- var x = new this.model[i](data)
113
-
114
- dynamicComputationPromises.push(await x.save());
115
-
116
-
111
+ const docData = Object.assign({}, data, { dbIndex: i });
112
+ const x = new this.model[i](docData);
113
+ promises.push(x.save());
117
114
  }
118
115
 
119
- return [].concat(dynamicComputationPromises);
116
+ return Promise.all(promises);
120
117
 
121
118
  }
122
119
  //==================
@@ -161,6 +158,16 @@ class MongoModel {
161
158
  return await this.runLargeComputations(dynamicComputationPromises);
162
159
 
163
160
  }
161
+ /**
162
+ * Delete many documents matching `filter` in all databases and return aggregated results.
163
+ */
164
+ async findManyInAllDatabaseAndDelete(filter) {
165
+ const dynamicComputationPromises = [];
166
+ this.model.forEach((modelRef) => {
167
+ dynamicComputationPromises.push({ fn: modelRef.deleteMany.bind(modelRef), params: [filter], chain: {} });
168
+ });
169
+ return await this.runLargeComputations(dynamicComputationPromises);
170
+ }
164
171
  //=======================
165
172
  async write(data) {
166
173
 
@@ -169,9 +176,7 @@ class MongoModel {
169
176
  data["dbIndex"] = MongoModel.currentIndex;
170
177
  MongoModel.currentIndex = (MongoModel.currentIndex + 1) % this.model.length;
171
178
  if (Mongoplus.readonlymodels.includes(currentModel)) {
172
- this.write(data)
173
- //("This model is readonly");
174
-
179
+ return await this.write(data);
175
180
  }
176
181
 
177
182
 
@@ -346,7 +351,7 @@ class MongoModel {
346
351
  var currentModel = this.model[dbIndex]
347
352
 
348
353
  if (chain.skip && chain.limit && chain.sort) {
349
- currentModel.findOne(filter).skip(chain.skip).limit(chain.limit).sort(chain.sort)
354
+ return currentModel.findOne(filter).skip(chain.skip).limit(chain.limit).sort(chain.sort)
350
355
  } else if (chain.skip && chain.limit) {
351
356
  return currentModel.findOne(filter).skip(chain.skip).limit(chain.limit)
352
357
  }
@@ -473,4 +478,9 @@ class MongoModel {
473
478
  }
474
479
  }
475
480
 
481
+ // Attach named export and default for interoperability
482
+ Mongoplus.MongoModel = MongoModel;
476
483
  module.exports = Mongoplus;
484
+ module.exports.default = Mongoplus;
485
+ module.exports.MongoModel = MongoModel;
486
+ exports.MongoModel = MongoModel;
package/package.json CHANGED
@@ -1,9 +1,10 @@
1
1
  {
2
2
  "name": "mongoplusplus",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "load balancing of read and write operations across multiple MongoDB servers ",
5
5
  "main": "mongoplus.js",
6
6
  "types": "index.d.ts",
7
+ "type": "commonjs",
7
8
  "scripts": {
8
9
  "test": "echo \"Error: no test specified\" && exit 1"
9
10
  },
@@ -50,5 +51,13 @@
50
51
  "devDependencies": {
51
52
  "@types/node": "^24.10.1",
52
53
  "typescript": "^5.9.3"
54
+ },
55
+ "exports": {
56
+ ".": {
57
+ "require": "./mongoplus.js",
58
+ "default": "./mongoplus.js",
59
+ "types": "./index.d.ts"
60
+ },
61
+ "./package.json": "./package.json"
53
62
  }
54
63
  }
package/tsconfig.json CHANGED
@@ -6,6 +6,7 @@
6
6
  "esModuleInterop": true,
7
7
  "skipLibCheck": true,
8
8
  "forceConsistentCasingInFileNames": true,
9
+ "allowSyntheticDefaultImports": true,
9
10
  "types": [
10
11
  "node"
11
12
  ]