@push.rocks/smartmongo 2.0.14 → 2.2.0

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 (87) hide show
  1. package/dist_ts/00_commitinfo_data.js +2 -2
  2. package/dist_ts/congodb/congodb.plugins.d.ts +10 -0
  3. package/dist_ts/congodb/congodb.plugins.js +14 -0
  4. package/dist_ts/congodb/engine/AggregationEngine.d.ts +66 -0
  5. package/dist_ts/congodb/engine/AggregationEngine.js +189 -0
  6. package/dist_ts/congodb/engine/IndexEngine.d.ts +77 -0
  7. package/dist_ts/congodb/engine/IndexEngine.js +376 -0
  8. package/dist_ts/congodb/engine/QueryEngine.d.ts +54 -0
  9. package/dist_ts/congodb/engine/QueryEngine.js +271 -0
  10. package/dist_ts/congodb/engine/TransactionEngine.d.ts +85 -0
  11. package/dist_ts/congodb/engine/TransactionEngine.js +287 -0
  12. package/dist_ts/congodb/engine/UpdateEngine.d.ts +47 -0
  13. package/dist_ts/congodb/engine/UpdateEngine.js +461 -0
  14. package/dist_ts/congodb/errors/CongoErrors.d.ts +100 -0
  15. package/dist_ts/congodb/errors/CongoErrors.js +155 -0
  16. package/dist_ts/congodb/index.d.ts +19 -0
  17. package/dist_ts/congodb/index.js +26 -0
  18. package/dist_ts/congodb/server/CommandRouter.d.ts +51 -0
  19. package/dist_ts/congodb/server/CommandRouter.js +132 -0
  20. package/dist_ts/congodb/server/CongoServer.d.ts +95 -0
  21. package/dist_ts/congodb/server/CongoServer.js +227 -0
  22. package/dist_ts/congodb/server/WireProtocol.d.ts +117 -0
  23. package/dist_ts/congodb/server/WireProtocol.js +298 -0
  24. package/dist_ts/congodb/server/handlers/AdminHandler.d.ts +100 -0
  25. package/dist_ts/congodb/server/handlers/AdminHandler.js +568 -0
  26. package/dist_ts/congodb/server/handlers/AggregateHandler.d.ts +31 -0
  27. package/dist_ts/congodb/server/handlers/AggregateHandler.js +277 -0
  28. package/dist_ts/congodb/server/handlers/DeleteHandler.d.ts +8 -0
  29. package/dist_ts/congodb/server/handlers/DeleteHandler.js +83 -0
  30. package/dist_ts/congodb/server/handlers/FindHandler.d.ts +31 -0
  31. package/dist_ts/congodb/server/handlers/FindHandler.js +261 -0
  32. package/dist_ts/congodb/server/handlers/HelloHandler.d.ts +11 -0
  33. package/dist_ts/congodb/server/handlers/HelloHandler.js +62 -0
  34. package/dist_ts/congodb/server/handlers/IndexHandler.d.ts +20 -0
  35. package/dist_ts/congodb/server/handlers/IndexHandler.js +183 -0
  36. package/dist_ts/congodb/server/handlers/InsertHandler.d.ts +8 -0
  37. package/dist_ts/congodb/server/handlers/InsertHandler.js +76 -0
  38. package/dist_ts/congodb/server/handlers/UpdateHandler.d.ts +24 -0
  39. package/dist_ts/congodb/server/handlers/UpdateHandler.js +270 -0
  40. package/dist_ts/congodb/server/handlers/index.d.ts +8 -0
  41. package/dist_ts/congodb/server/handlers/index.js +10 -0
  42. package/dist_ts/congodb/server/index.d.ts +6 -0
  43. package/dist_ts/congodb/server/index.js +7 -0
  44. package/dist_ts/congodb/storage/FileStorageAdapter.d.ts +61 -0
  45. package/dist_ts/congodb/storage/FileStorageAdapter.js +396 -0
  46. package/dist_ts/congodb/storage/IStorageAdapter.d.ts +140 -0
  47. package/dist_ts/congodb/storage/IStorageAdapter.js +2 -0
  48. package/dist_ts/congodb/storage/MemoryStorageAdapter.d.ts +66 -0
  49. package/dist_ts/congodb/storage/MemoryStorageAdapter.js +367 -0
  50. package/dist_ts/congodb/storage/OpLog.d.ts +93 -0
  51. package/dist_ts/congodb/storage/OpLog.js +221 -0
  52. package/dist_ts/congodb/types/interfaces.d.ts +363 -0
  53. package/dist_ts/congodb/types/interfaces.js +2 -0
  54. package/dist_ts/index.d.ts +1 -0
  55. package/dist_ts/index.js +8 -6
  56. package/npmextra.json +17 -7
  57. package/package.json +20 -12
  58. package/readme.hints.md +79 -0
  59. package/readme.md +398 -44
  60. package/ts/00_commitinfo_data.ts +1 -1
  61. package/ts/congodb/congodb.plugins.ts +17 -0
  62. package/ts/congodb/engine/AggregationEngine.ts +283 -0
  63. package/ts/congodb/engine/IndexEngine.ts +479 -0
  64. package/ts/congodb/engine/QueryEngine.ts +301 -0
  65. package/ts/congodb/engine/TransactionEngine.ts +351 -0
  66. package/ts/congodb/engine/UpdateEngine.ts +506 -0
  67. package/ts/congodb/errors/CongoErrors.ts +181 -0
  68. package/ts/congodb/index.ts +37 -0
  69. package/ts/congodb/server/CommandRouter.ts +180 -0
  70. package/ts/congodb/server/CongoServer.ts +298 -0
  71. package/ts/congodb/server/WireProtocol.ts +416 -0
  72. package/ts/congodb/server/handlers/AdminHandler.ts +614 -0
  73. package/ts/congodb/server/handlers/AggregateHandler.ts +342 -0
  74. package/ts/congodb/server/handlers/DeleteHandler.ts +100 -0
  75. package/ts/congodb/server/handlers/FindHandler.ts +301 -0
  76. package/ts/congodb/server/handlers/HelloHandler.ts +78 -0
  77. package/ts/congodb/server/handlers/IndexHandler.ts +207 -0
  78. package/ts/congodb/server/handlers/InsertHandler.ts +91 -0
  79. package/ts/congodb/server/handlers/UpdateHandler.ts +315 -0
  80. package/ts/congodb/server/handlers/index.ts +10 -0
  81. package/ts/congodb/server/index.ts +10 -0
  82. package/ts/congodb/storage/FileStorageAdapter.ts +479 -0
  83. package/ts/congodb/storage/IStorageAdapter.ts +202 -0
  84. package/ts/congodb/storage/MemoryStorageAdapter.ts +443 -0
  85. package/ts/congodb/storage/OpLog.ts +282 -0
  86. package/ts/congodb/types/interfaces.ts +433 -0
  87. package/ts/index.ts +3 -0
@@ -0,0 +1,376 @@
1
+ import * as plugins from '../congodb.plugins.js';
2
+ import { CongoDuplicateKeyError, CongoIndexError } from '../errors/CongoErrors.js';
3
+ import { QueryEngine } from './QueryEngine.js';
4
+ /**
5
+ * Index engine for managing indexes and query optimization
6
+ */
7
+ export class IndexEngine {
8
+ dbName;
9
+ collName;
10
+ storage;
11
+ indexes = new Map();
12
+ initialized = false;
13
+ constructor(dbName, collName, storage) {
14
+ this.dbName = dbName;
15
+ this.collName = collName;
16
+ this.storage = storage;
17
+ }
18
+ /**
19
+ * Initialize indexes from storage
20
+ */
21
+ async initialize() {
22
+ if (this.initialized)
23
+ return;
24
+ const storedIndexes = await this.storage.getIndexes(this.dbName, this.collName);
25
+ const documents = await this.storage.findAll(this.dbName, this.collName);
26
+ for (const indexSpec of storedIndexes) {
27
+ const indexData = {
28
+ name: indexSpec.name,
29
+ key: indexSpec.key,
30
+ unique: indexSpec.unique || false,
31
+ sparse: indexSpec.sparse || false,
32
+ expireAfterSeconds: indexSpec.expireAfterSeconds,
33
+ entries: new Map(),
34
+ };
35
+ // Build index entries
36
+ for (const doc of documents) {
37
+ const keyValue = this.extractKeyValue(doc, indexSpec.key);
38
+ if (keyValue !== null || !indexData.sparse) {
39
+ const keyStr = JSON.stringify(keyValue);
40
+ if (!indexData.entries.has(keyStr)) {
41
+ indexData.entries.set(keyStr, new Set());
42
+ }
43
+ indexData.entries.get(keyStr).add(doc._id.toHexString());
44
+ }
45
+ }
46
+ this.indexes.set(indexSpec.name, indexData);
47
+ }
48
+ this.initialized = true;
49
+ }
50
+ /**
51
+ * Create a new index
52
+ */
53
+ async createIndex(key, options) {
54
+ await this.initialize();
55
+ // Generate index name if not provided
56
+ const name = options?.name || this.generateIndexName(key);
57
+ // Check if index already exists
58
+ if (this.indexes.has(name)) {
59
+ return name;
60
+ }
61
+ // Create index data structure
62
+ const indexData = {
63
+ name,
64
+ key: key,
65
+ unique: options?.unique || false,
66
+ sparse: options?.sparse || false,
67
+ expireAfterSeconds: options?.expireAfterSeconds,
68
+ entries: new Map(),
69
+ };
70
+ // Build index from existing documents
71
+ const documents = await this.storage.findAll(this.dbName, this.collName);
72
+ for (const doc of documents) {
73
+ const keyValue = this.extractKeyValue(doc, key);
74
+ if (keyValue === null && indexData.sparse) {
75
+ continue;
76
+ }
77
+ const keyStr = JSON.stringify(keyValue);
78
+ if (indexData.unique && indexData.entries.has(keyStr)) {
79
+ throw new CongoDuplicateKeyError(`E11000 duplicate key error index: ${this.dbName}.${this.collName}.$${name}`, key, keyValue);
80
+ }
81
+ if (!indexData.entries.has(keyStr)) {
82
+ indexData.entries.set(keyStr, new Set());
83
+ }
84
+ indexData.entries.get(keyStr).add(doc._id.toHexString());
85
+ }
86
+ // Store index
87
+ this.indexes.set(name, indexData);
88
+ await this.storage.saveIndex(this.dbName, this.collName, name, {
89
+ key,
90
+ unique: options?.unique,
91
+ sparse: options?.sparse,
92
+ expireAfterSeconds: options?.expireAfterSeconds,
93
+ });
94
+ return name;
95
+ }
96
+ /**
97
+ * Drop an index
98
+ */
99
+ async dropIndex(name) {
100
+ await this.initialize();
101
+ if (name === '_id_') {
102
+ throw new CongoIndexError('cannot drop _id index');
103
+ }
104
+ if (!this.indexes.has(name)) {
105
+ throw new CongoIndexError(`index not found: ${name}`);
106
+ }
107
+ this.indexes.delete(name);
108
+ await this.storage.dropIndex(this.dbName, this.collName, name);
109
+ }
110
+ /**
111
+ * Drop all indexes except _id
112
+ */
113
+ async dropAllIndexes() {
114
+ await this.initialize();
115
+ const names = Array.from(this.indexes.keys()).filter(n => n !== '_id_');
116
+ for (const name of names) {
117
+ this.indexes.delete(name);
118
+ await this.storage.dropIndex(this.dbName, this.collName, name);
119
+ }
120
+ }
121
+ /**
122
+ * List all indexes
123
+ */
124
+ async listIndexes() {
125
+ await this.initialize();
126
+ return Array.from(this.indexes.values()).map(idx => ({
127
+ v: 2,
128
+ key: idx.key,
129
+ name: idx.name,
130
+ unique: idx.unique || undefined,
131
+ sparse: idx.sparse || undefined,
132
+ expireAfterSeconds: idx.expireAfterSeconds,
133
+ }));
134
+ }
135
+ /**
136
+ * Check if an index exists
137
+ */
138
+ async indexExists(name) {
139
+ await this.initialize();
140
+ return this.indexes.has(name);
141
+ }
142
+ /**
143
+ * Update index entries after document insert
144
+ */
145
+ async onInsert(doc) {
146
+ await this.initialize();
147
+ for (const [name, indexData] of this.indexes) {
148
+ const keyValue = this.extractKeyValue(doc, indexData.key);
149
+ if (keyValue === null && indexData.sparse) {
150
+ continue;
151
+ }
152
+ const keyStr = JSON.stringify(keyValue);
153
+ // Check unique constraint
154
+ if (indexData.unique) {
155
+ const existing = indexData.entries.get(keyStr);
156
+ if (existing && existing.size > 0) {
157
+ throw new CongoDuplicateKeyError(`E11000 duplicate key error collection: ${this.dbName}.${this.collName} index: ${name}`, indexData.key, keyValue);
158
+ }
159
+ }
160
+ if (!indexData.entries.has(keyStr)) {
161
+ indexData.entries.set(keyStr, new Set());
162
+ }
163
+ indexData.entries.get(keyStr).add(doc._id.toHexString());
164
+ }
165
+ }
166
+ /**
167
+ * Update index entries after document update
168
+ */
169
+ async onUpdate(oldDoc, newDoc) {
170
+ await this.initialize();
171
+ for (const [name, indexData] of this.indexes) {
172
+ const oldKeyValue = this.extractKeyValue(oldDoc, indexData.key);
173
+ const newKeyValue = this.extractKeyValue(newDoc, indexData.key);
174
+ const oldKeyStr = JSON.stringify(oldKeyValue);
175
+ const newKeyStr = JSON.stringify(newKeyValue);
176
+ // Remove old entry if key changed
177
+ if (oldKeyStr !== newKeyStr) {
178
+ if (oldKeyValue !== null || !indexData.sparse) {
179
+ const oldSet = indexData.entries.get(oldKeyStr);
180
+ if (oldSet) {
181
+ oldSet.delete(oldDoc._id.toHexString());
182
+ if (oldSet.size === 0) {
183
+ indexData.entries.delete(oldKeyStr);
184
+ }
185
+ }
186
+ }
187
+ // Add new entry
188
+ if (newKeyValue !== null || !indexData.sparse) {
189
+ // Check unique constraint
190
+ if (indexData.unique) {
191
+ const existing = indexData.entries.get(newKeyStr);
192
+ if (existing && existing.size > 0) {
193
+ throw new CongoDuplicateKeyError(`E11000 duplicate key error collection: ${this.dbName}.${this.collName} index: ${name}`, indexData.key, newKeyValue);
194
+ }
195
+ }
196
+ if (!indexData.entries.has(newKeyStr)) {
197
+ indexData.entries.set(newKeyStr, new Set());
198
+ }
199
+ indexData.entries.get(newKeyStr).add(newDoc._id.toHexString());
200
+ }
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Update index entries after document delete
206
+ */
207
+ async onDelete(doc) {
208
+ await this.initialize();
209
+ for (const indexData of this.indexes.values()) {
210
+ const keyValue = this.extractKeyValue(doc, indexData.key);
211
+ if (keyValue === null && indexData.sparse) {
212
+ continue;
213
+ }
214
+ const keyStr = JSON.stringify(keyValue);
215
+ const set = indexData.entries.get(keyStr);
216
+ if (set) {
217
+ set.delete(doc._id.toHexString());
218
+ if (set.size === 0) {
219
+ indexData.entries.delete(keyStr);
220
+ }
221
+ }
222
+ }
223
+ }
224
+ /**
225
+ * Find the best index for a query
226
+ */
227
+ selectIndex(filter) {
228
+ if (!filter || Object.keys(filter).length === 0) {
229
+ return null;
230
+ }
231
+ // Get filter fields
232
+ const filterFields = new Set(this.getFilterFields(filter));
233
+ // Score each index
234
+ let bestIndex = null;
235
+ let bestScore = 0;
236
+ for (const [name, indexData] of this.indexes) {
237
+ const indexFields = Object.keys(indexData.key);
238
+ let score = 0;
239
+ // Count how many index fields are in the filter
240
+ for (const field of indexFields) {
241
+ if (filterFields.has(field)) {
242
+ score++;
243
+ }
244
+ else {
245
+ break; // Index fields must be contiguous
246
+ }
247
+ }
248
+ // Prefer unique indexes
249
+ if (indexData.unique && score > 0) {
250
+ score += 0.5;
251
+ }
252
+ if (score > bestScore) {
253
+ bestScore = score;
254
+ bestIndex = { name, data: indexData };
255
+ }
256
+ }
257
+ return bestIndex;
258
+ }
259
+ /**
260
+ * Use index to find candidate document IDs
261
+ */
262
+ async findCandidateIds(filter) {
263
+ await this.initialize();
264
+ const index = this.selectIndex(filter);
265
+ if (!index)
266
+ return null;
267
+ // Try to use the index for equality matches
268
+ const indexFields = Object.keys(index.data.key);
269
+ const equalityValues = {};
270
+ for (const field of indexFields) {
271
+ const filterValue = this.getFilterValue(filter, field);
272
+ if (filterValue === undefined)
273
+ break;
274
+ // Only use equality matches for index lookup
275
+ if (typeof filterValue === 'object' && filterValue !== null) {
276
+ if (filterValue.$eq !== undefined) {
277
+ equalityValues[field] = filterValue.$eq;
278
+ }
279
+ else if (filterValue.$in !== undefined) {
280
+ // Handle $in with multiple lookups
281
+ const results = new Set();
282
+ for (const val of filterValue.$in) {
283
+ equalityValues[field] = val;
284
+ const keyStr = JSON.stringify(this.buildKeyValue(equalityValues, index.data.key));
285
+ const ids = index.data.entries.get(keyStr);
286
+ if (ids) {
287
+ for (const id of ids) {
288
+ results.add(id);
289
+ }
290
+ }
291
+ }
292
+ return results;
293
+ }
294
+ else {
295
+ break; // Non-equality operator, stop here
296
+ }
297
+ }
298
+ else {
299
+ equalityValues[field] = filterValue;
300
+ }
301
+ }
302
+ if (Object.keys(equalityValues).length === 0) {
303
+ return null;
304
+ }
305
+ const keyStr = JSON.stringify(this.buildKeyValue(equalityValues, index.data.key));
306
+ return index.data.entries.get(keyStr) || new Set();
307
+ }
308
+ // ============================================================================
309
+ // Helper Methods
310
+ // ============================================================================
311
+ generateIndexName(key) {
312
+ return Object.entries(key)
313
+ .map(([field, dir]) => `${field}_${dir}`)
314
+ .join('_');
315
+ }
316
+ extractKeyValue(doc, key) {
317
+ const values = [];
318
+ for (const field of Object.keys(key)) {
319
+ const value = QueryEngine.getNestedValue(doc, field);
320
+ values.push(value === undefined ? null : value);
321
+ }
322
+ // For single-field index, return the value directly
323
+ if (values.length === 1) {
324
+ return values[0];
325
+ }
326
+ return values;
327
+ }
328
+ buildKeyValue(values, key) {
329
+ const result = [];
330
+ for (const field of Object.keys(key)) {
331
+ result.push(values[field] !== undefined ? values[field] : null);
332
+ }
333
+ if (result.length === 1) {
334
+ return result[0];
335
+ }
336
+ return result;
337
+ }
338
+ getFilterFields(filter, prefix = '') {
339
+ const fields = [];
340
+ for (const [key, value] of Object.entries(filter)) {
341
+ if (key.startsWith('$')) {
342
+ // Logical operator
343
+ if (key === '$and' || key === '$or' || key === '$nor') {
344
+ for (const subFilter of value) {
345
+ fields.push(...this.getFilterFields(subFilter, prefix));
346
+ }
347
+ }
348
+ }
349
+ else {
350
+ const fullKey = prefix ? `${prefix}.${key}` : key;
351
+ fields.push(fullKey);
352
+ // Check for nested filters
353
+ if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
354
+ const subKeys = Object.keys(value);
355
+ if (subKeys.length > 0 && !subKeys[0].startsWith('$')) {
356
+ fields.push(...this.getFilterFields(value, fullKey));
357
+ }
358
+ }
359
+ }
360
+ }
361
+ return fields;
362
+ }
363
+ getFilterValue(filter, field) {
364
+ // Handle dot notation
365
+ const parts = field.split('.');
366
+ let current = filter;
367
+ for (const part of parts) {
368
+ if (current === null || current === undefined) {
369
+ return undefined;
370
+ }
371
+ current = current[part];
372
+ }
373
+ return current;
374
+ }
375
+ }
376
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSW5kZXhFbmdpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb25nb2RiL2VuZ2luZS9JbmRleEVuZ2luZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHVCQUF1QixDQUFDO0FBU2pELE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNuRixPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFlL0M7O0dBRUc7QUFDSCxNQUFNLE9BQU8sV0FBVztJQUNkLE1BQU0sQ0FBUztJQUNmLFFBQVEsQ0FBUztJQUNqQixPQUFPLENBQWtCO0lBQ3pCLE9BQU8sR0FBNEIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUM3QyxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBRTVCLFlBQVksTUFBYyxFQUFFLFFBQWdCLEVBQUUsT0FBd0I7UUFDcEUsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7UUFDekIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDekIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSyxDQUFDLFVBQVU7UUFDZCxJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTztRQUU3QixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ2hGLE1BQU0sU0FBUyxHQUFHLE1BQU0sSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFekUsS0FBSyxNQUFNLFNBQVMsSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUN0QyxNQUFNLFNBQVMsR0FBZTtnQkFD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
@@ -0,0 +1,54 @@
1
+ import type { Document, IStoredDocument, ISortSpecification } from '../types/interfaces.js';
2
+ /**
3
+ * Query engine using mingo for MongoDB-compatible query matching
4
+ */
5
+ export declare class QueryEngine {
6
+ /**
7
+ * Filter documents by a MongoDB query filter
8
+ */
9
+ static filter(documents: IStoredDocument[], filter: Document): IStoredDocument[];
10
+ /**
11
+ * Test if a single document matches a filter
12
+ */
13
+ static matches(document: Document, filter: Document): boolean;
14
+ /**
15
+ * Find a single document matching the filter
16
+ */
17
+ static findOne(documents: IStoredDocument[], filter: Document): IStoredDocument | null;
18
+ /**
19
+ * Sort documents by a sort specification
20
+ */
21
+ static sort(documents: IStoredDocument[], sort: ISortSpecification): IStoredDocument[];
22
+ /**
23
+ * Apply projection to documents
24
+ */
25
+ static project(documents: IStoredDocument[], projection: Document): Document[];
26
+ /**
27
+ * Get distinct values for a field
28
+ */
29
+ static distinct(documents: IStoredDocument[], field: string, filter?: Document): any[];
30
+ /**
31
+ * Normalize sort direction to 1 or -1
32
+ */
33
+ private static normalizeDirection;
34
+ /**
35
+ * Get a nested value from an object using dot notation
36
+ */
37
+ static getNestedValue(obj: any, path: string): any;
38
+ /**
39
+ * Set a nested value in an object using dot notation
40
+ */
41
+ private static setNestedValue;
42
+ /**
43
+ * Delete a nested value from an object using dot notation
44
+ */
45
+ private static deleteNestedValue;
46
+ /**
47
+ * Compare two values for sorting
48
+ */
49
+ private static compareValues;
50
+ /**
51
+ * Convert a value to a comparable form (for distinct)
52
+ */
53
+ private static toComparable;
54
+ }