@push.rocks/smartmongo 2.1.0 → 3.0.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 (109) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/index.d.ts +1 -1
  3. package/dist_ts/index.js +3 -3
  4. package/dist_ts/tsmdb/engine/AggregationEngine.js +189 -0
  5. package/dist_ts/tsmdb/engine/IndexEngine.js +376 -0
  6. package/dist_ts/tsmdb/engine/QueryEngine.js +271 -0
  7. package/dist_ts/{congodb → tsmdb}/engine/TransactionEngine.d.ts +1 -1
  8. package/dist_ts/tsmdb/engine/TransactionEngine.js +287 -0
  9. package/dist_ts/tsmdb/engine/UpdateEngine.js +461 -0
  10. package/dist_ts/{congodb/errors/CongoErrors.d.ts → tsmdb/errors/TsmdbErrors.d.ts} +16 -16
  11. package/dist_ts/tsmdb/errors/TsmdbErrors.js +155 -0
  12. package/dist_ts/{congodb → tsmdb}/index.d.ts +4 -4
  13. package/dist_ts/tsmdb/index.js +26 -0
  14. package/dist_ts/{congodb → tsmdb}/server/CommandRouter.d.ts +4 -4
  15. package/dist_ts/tsmdb/server/CommandRouter.js +132 -0
  16. package/dist_ts/{congodb/server/CongoServer.d.ts → tsmdb/server/TsmdbServer.d.ts} +6 -6
  17. package/dist_ts/tsmdb/server/TsmdbServer.js +227 -0
  18. package/dist_ts/{congodb → tsmdb}/server/WireProtocol.d.ts +1 -1
  19. package/dist_ts/tsmdb/server/WireProtocol.js +298 -0
  20. package/dist_ts/{congodb → tsmdb}/server/handlers/AdminHandler.d.ts +1 -1
  21. package/dist_ts/tsmdb/server/handlers/AdminHandler.js +568 -0
  22. package/dist_ts/{congodb → tsmdb}/server/handlers/AggregateHandler.d.ts +1 -1
  23. package/dist_ts/tsmdb/server/handlers/AggregateHandler.js +277 -0
  24. package/dist_ts/{congodb → tsmdb}/server/handlers/DeleteHandler.d.ts +1 -1
  25. package/dist_ts/tsmdb/server/handlers/DeleteHandler.js +83 -0
  26. package/dist_ts/{congodb → tsmdb}/server/handlers/FindHandler.d.ts +1 -1
  27. package/dist_ts/tsmdb/server/handlers/FindHandler.js +261 -0
  28. package/dist_ts/{congodb → tsmdb}/server/handlers/HelloHandler.d.ts +1 -1
  29. package/dist_ts/{congodb → tsmdb}/server/handlers/HelloHandler.js +2 -2
  30. package/dist_ts/{congodb → tsmdb}/server/handlers/IndexHandler.d.ts +1 -1
  31. package/dist_ts/tsmdb/server/handlers/IndexHandler.js +183 -0
  32. package/dist_ts/{congodb → tsmdb}/server/handlers/InsertHandler.d.ts +1 -1
  33. package/dist_ts/tsmdb/server/handlers/InsertHandler.js +76 -0
  34. package/dist_ts/{congodb → tsmdb}/server/handlers/UpdateHandler.d.ts +1 -1
  35. package/dist_ts/tsmdb/server/handlers/UpdateHandler.js +270 -0
  36. package/dist_ts/tsmdb/server/handlers/index.js +10 -0
  37. package/dist_ts/{congodb → tsmdb}/server/index.d.ts +2 -2
  38. package/dist_ts/tsmdb/server/index.js +7 -0
  39. package/dist_ts/{congodb → tsmdb}/storage/FileStorageAdapter.d.ts +2 -2
  40. package/dist_ts/tsmdb/storage/FileStorageAdapter.js +396 -0
  41. package/dist_ts/{congodb → tsmdb}/storage/IStorageAdapter.d.ts +2 -2
  42. package/dist_ts/{congodb → tsmdb}/storage/IStorageAdapter.js +1 -1
  43. package/dist_ts/{congodb → tsmdb}/storage/MemoryStorageAdapter.d.ts +2 -2
  44. package/dist_ts/tsmdb/storage/MemoryStorageAdapter.js +367 -0
  45. package/dist_ts/{congodb → tsmdb}/storage/OpLog.d.ts +1 -1
  46. package/dist_ts/tsmdb/storage/OpLog.js +221 -0
  47. package/dist_ts/tsmdb/tsmdb.plugins.js +14 -0
  48. package/dist_ts/{congodb → tsmdb}/types/interfaces.d.ts +3 -3
  49. package/dist_ts/{congodb → tsmdb}/types/interfaces.js +1 -1
  50. package/package.json +1 -1
  51. package/readme.hints.md +7 -12
  52. package/readme.md +398 -44
  53. package/ts/00_commitinfo_data.ts +1 -1
  54. package/ts/index.ts +2 -2
  55. package/ts/{congodb → tsmdb}/engine/AggregationEngine.ts +1 -1
  56. package/ts/{congodb → tsmdb}/engine/IndexEngine.ts +7 -7
  57. package/ts/{congodb → tsmdb}/engine/QueryEngine.ts +1 -1
  58. package/ts/{congodb → tsmdb}/engine/TransactionEngine.ts +12 -12
  59. package/ts/{congodb → tsmdb}/engine/UpdateEngine.ts +1 -1
  60. package/ts/{congodb/errors/CongoErrors.ts → tsmdb/errors/TsmdbErrors.ts} +34 -34
  61. package/ts/{congodb → tsmdb}/index.ts +7 -7
  62. package/ts/{congodb → tsmdb}/server/CommandRouter.ts +5 -5
  63. package/ts/{congodb/server/CongoServer.ts → tsmdb/server/TsmdbServer.ts} +8 -8
  64. package/ts/{congodb → tsmdb}/server/WireProtocol.ts +1 -1
  65. package/ts/{congodb → tsmdb}/server/handlers/AdminHandler.ts +6 -6
  66. package/ts/{congodb → tsmdb}/server/handlers/AggregateHandler.ts +1 -1
  67. package/ts/{congodb → tsmdb}/server/handlers/DeleteHandler.ts +1 -1
  68. package/ts/{congodb → tsmdb}/server/handlers/FindHandler.ts +1 -1
  69. package/ts/{congodb → tsmdb}/server/handlers/HelloHandler.ts +1 -1
  70. package/ts/{congodb → tsmdb}/server/handlers/IndexHandler.ts +1 -1
  71. package/ts/{congodb → tsmdb}/server/handlers/InsertHandler.ts +1 -1
  72. package/ts/{congodb → tsmdb}/server/handlers/UpdateHandler.ts +1 -1
  73. package/ts/{congodb → tsmdb}/server/index.ts +2 -2
  74. package/ts/{congodb → tsmdb}/storage/FileStorageAdapter.ts +2 -2
  75. package/ts/{congodb → tsmdb}/storage/IStorageAdapter.ts +2 -2
  76. package/ts/{congodb → tsmdb}/storage/MemoryStorageAdapter.ts +2 -2
  77. package/ts/{congodb → tsmdb}/storage/OpLog.ts +1 -1
  78. package/ts/{congodb → tsmdb}/types/interfaces.ts +3 -3
  79. package/dist_ts/congodb/congodb.plugins.js +0 -14
  80. package/dist_ts/congodb/engine/AggregationEngine.js +0 -189
  81. package/dist_ts/congodb/engine/IndexEngine.js +0 -376
  82. package/dist_ts/congodb/engine/QueryEngine.js +0 -271
  83. package/dist_ts/congodb/engine/TransactionEngine.js +0 -287
  84. package/dist_ts/congodb/engine/UpdateEngine.js +0 -461
  85. package/dist_ts/congodb/errors/CongoErrors.js +0 -155
  86. package/dist_ts/congodb/index.js +0 -26
  87. package/dist_ts/congodb/server/CommandRouter.js +0 -132
  88. package/dist_ts/congodb/server/CongoServer.js +0 -227
  89. package/dist_ts/congodb/server/WireProtocol.js +0 -298
  90. package/dist_ts/congodb/server/handlers/AdminHandler.js +0 -568
  91. package/dist_ts/congodb/server/handlers/AggregateHandler.js +0 -277
  92. package/dist_ts/congodb/server/handlers/DeleteHandler.js +0 -83
  93. package/dist_ts/congodb/server/handlers/FindHandler.js +0 -261
  94. package/dist_ts/congodb/server/handlers/IndexHandler.js +0 -183
  95. package/dist_ts/congodb/server/handlers/InsertHandler.js +0 -76
  96. package/dist_ts/congodb/server/handlers/UpdateHandler.js +0 -270
  97. package/dist_ts/congodb/server/handlers/index.js +0 -10
  98. package/dist_ts/congodb/server/index.js +0 -7
  99. package/dist_ts/congodb/storage/FileStorageAdapter.js +0 -396
  100. package/dist_ts/congodb/storage/MemoryStorageAdapter.js +0 -367
  101. package/dist_ts/congodb/storage/OpLog.js +0 -221
  102. /package/dist_ts/{congodb → tsmdb}/engine/AggregationEngine.d.ts +0 -0
  103. /package/dist_ts/{congodb → tsmdb}/engine/IndexEngine.d.ts +0 -0
  104. /package/dist_ts/{congodb → tsmdb}/engine/QueryEngine.d.ts +0 -0
  105. /package/dist_ts/{congodb → tsmdb}/engine/UpdateEngine.d.ts +0 -0
  106. /package/dist_ts/{congodb → tsmdb}/server/handlers/index.d.ts +0 -0
  107. /package/dist_ts/{congodb/congodb.plugins.d.ts → tsmdb/tsmdb.plugins.d.ts} +0 -0
  108. /package/ts/{congodb → tsmdb}/server/handlers/index.ts +0 -0
  109. /package/ts/{congodb/congodb.plugins.ts → tsmdb/tsmdb.plugins.ts} +0 -0
@@ -1,4 +1,4 @@
1
- import type * as plugins from '../congodb.plugins.js';
1
+ import type * as plugins from '../tsmdb.plugins.js';
2
2
 
3
3
  // ============================================================================
4
4
  // Document Types
@@ -14,7 +14,7 @@ export interface WithId<TSchema> {
14
14
  // Client Options
15
15
  // ============================================================================
16
16
 
17
- export interface ICongoClientOptions {
17
+ export interface ITsmdbClientOptions {
18
18
  /** Storage adapter type: 'memory' or 'file' */
19
19
  storageType?: 'memory' | 'file';
20
20
  /** Path for file-based storage */
@@ -30,7 +30,7 @@ export interface ICongoClientOptions {
30
30
  // ============================================================================
31
31
 
32
32
  export interface IParsedConnectionString {
33
- protocol: 'congo';
33
+ protocol: 'tsmdb';
34
34
  storageType: 'memory' | 'file';
35
35
  options: {
36
36
  persist?: string;
@@ -1,14 +0,0 @@
1
- // @push.rocks scope
2
- import * as smartfs from '@push.rocks/smartfs';
3
- import * as smartpath from '@push.rocks/smartpath';
4
- import * as smartpromise from '@push.rocks/smartpromise';
5
- import * as smartrx from '@push.rocks/smartrx';
6
- export { smartfs, smartpath, smartpromise, smartrx };
7
- // thirdparty
8
- import * as bson from 'bson';
9
- import * as mingo from 'mingo';
10
- export { bson, mingo };
11
- // Re-export commonly used mingo classes
12
- export { Query } from 'mingo';
13
- export { Aggregator } from 'mingo';
14
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZ29kYi5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvY29uZ29kYi9jb25nb2RiLnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFDL0MsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRCxPQUFPLEtBQUssWUFBWSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sS0FBSyxPQUFPLE1BQU0scUJBQXFCLENBQUM7QUFFL0MsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxDQUFDO0FBRXJELGFBQWE7QUFDYixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEtBQUssS0FBSyxNQUFNLE9BQU8sQ0FBQztBQUUvQixPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDO0FBRXZCLHdDQUF3QztBQUN4QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBQzlCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxPQUFPLENBQUMifQ==
@@ -1,189 +0,0 @@
1
- import * as plugins from '../congodb.plugins.js';
2
- // Import mingo Aggregator
3
- import { Aggregator } from 'mingo';
4
- /**
5
- * Aggregation engine using mingo for MongoDB-compatible aggregation pipeline execution
6
- */
7
- export class AggregationEngine {
8
- /**
9
- * Execute an aggregation pipeline on a collection of documents
10
- */
11
- static aggregate(documents, pipeline, options) {
12
- if (!pipeline || pipeline.length === 0) {
13
- return documents;
14
- }
15
- // Create mingo aggregator with the pipeline
16
- const aggregator = new Aggregator(pipeline, {
17
- collation: options?.collation,
18
- });
19
- // Run the aggregation
20
- const result = aggregator.run(documents);
21
- return Array.isArray(result) ? result : [];
22
- }
23
- /**
24
- * Execute aggregation and return an iterator for lazy evaluation
25
- */
26
- static *aggregateIterator(documents, pipeline, options) {
27
- const aggregator = new Aggregator(pipeline, {
28
- collation: options?.collation,
29
- });
30
- // Get the cursor from mingo
31
- const cursor = aggregator.stream(documents);
32
- for (const doc of cursor) {
33
- yield doc;
34
- }
35
- }
36
- /**
37
- * Execute a $lookup stage manually (for cross-collection lookups)
38
- * This is used when the lookup references another collection in the same database
39
- */
40
- static executeLookup(documents, lookupSpec, foreignCollection) {
41
- const { localField, foreignField, as } = lookupSpec;
42
- return documents.map(doc => {
43
- const localValue = this.getNestedValue(doc, localField);
44
- const matches = foreignCollection.filter(foreignDoc => {
45
- const foreignValue = this.getNestedValue(foreignDoc, foreignField);
46
- return this.valuesMatch(localValue, foreignValue);
47
- });
48
- return {
49
- ...doc,
50
- [as]: matches,
51
- };
52
- });
53
- }
54
- /**
55
- * Execute a $graphLookup stage manually
56
- */
57
- static executeGraphLookup(documents, graphLookupSpec, foreignCollection) {
58
- const { startWith, connectFromField, connectToField, as, maxDepth = 10, depthField, restrictSearchWithMatch, } = graphLookupSpec;
59
- return documents.map(doc => {
60
- const startValue = typeof startWith === 'string' && startWith.startsWith('$')
61
- ? this.getNestedValue(doc, startWith.slice(1))
62
- : startWith;
63
- const results = [];
64
- const visited = new Set();
65
- const queue = [];
66
- // Initialize with start value(s)
67
- const startValues = Array.isArray(startValue) ? startValue : [startValue];
68
- for (const val of startValues) {
69
- queue.push({ value: val, depth: 0 });
70
- }
71
- while (queue.length > 0) {
72
- const { value, depth } = queue.shift();
73
- if (depth > maxDepth)
74
- continue;
75
- const valueKey = JSON.stringify(value);
76
- if (visited.has(valueKey))
77
- continue;
78
- visited.add(valueKey);
79
- // Find matching documents
80
- for (const foreignDoc of foreignCollection) {
81
- const foreignValue = this.getNestedValue(foreignDoc, connectToField);
82
- if (this.valuesMatch(value, foreignValue)) {
83
- // Check restrictSearchWithMatch
84
- if (restrictSearchWithMatch) {
85
- const matchQuery = new plugins.mingo.Query(restrictSearchWithMatch);
86
- if (!matchQuery.test(foreignDoc))
87
- continue;
88
- }
89
- const resultDoc = depthField
90
- ? { ...foreignDoc, [depthField]: depth }
91
- : { ...foreignDoc };
92
- // Avoid duplicates in results
93
- const docKey = foreignDoc._id.toHexString();
94
- if (!results.some(r => r._id?.toHexString?.() === docKey)) {
95
- results.push(resultDoc);
96
- // Add connected values to queue
97
- const nextValue = this.getNestedValue(foreignDoc, connectFromField);
98
- if (nextValue !== undefined) {
99
- const nextValues = Array.isArray(nextValue) ? nextValue : [nextValue];
100
- for (const nv of nextValues) {
101
- queue.push({ value: nv, depth: depth + 1 });
102
- }
103
- }
104
- }
105
- }
106
- }
107
- }
108
- return {
109
- ...doc,
110
- [as]: results,
111
- };
112
- });
113
- }
114
- /**
115
- * Execute a $facet stage manually
116
- */
117
- static executeFacet(documents, facetSpec) {
118
- const result = {};
119
- for (const [facetName, pipeline] of Object.entries(facetSpec)) {
120
- result[facetName] = this.aggregate(documents, pipeline);
121
- }
122
- return result;
123
- }
124
- /**
125
- * Execute a $unionWith stage
126
- */
127
- static executeUnionWith(documents, otherDocuments, pipeline) {
128
- let unionDocs = otherDocuments;
129
- if (pipeline && pipeline.length > 0) {
130
- unionDocs = this.aggregate(otherDocuments, pipeline);
131
- }
132
- return [...documents, ...unionDocs];
133
- }
134
- /**
135
- * Execute a $merge stage (output to another collection)
136
- * Returns the documents that would be inserted/updated
137
- */
138
- static prepareMerge(documents, mergeSpec) {
139
- const onField = mergeSpec.on || '_id';
140
- const whenMatched = mergeSpec.whenMatched || 'merge';
141
- const whenNotMatched = mergeSpec.whenNotMatched || 'insert';
142
- return {
143
- toInsert: [],
144
- toUpdate: [],
145
- onField,
146
- whenMatched,
147
- whenNotMatched,
148
- };
149
- }
150
- // ============================================================================
151
- // Helper Methods
152
- // ============================================================================
153
- static getNestedValue(obj, path) {
154
- const parts = path.split('.');
155
- let current = obj;
156
- for (const part of parts) {
157
- if (current === null || current === undefined) {
158
- return undefined;
159
- }
160
- current = current[part];
161
- }
162
- return current;
163
- }
164
- static valuesMatch(a, b) {
165
- if (a === b)
166
- return true;
167
- // Handle ObjectId comparison
168
- if (a instanceof plugins.bson.ObjectId && b instanceof plugins.bson.ObjectId) {
169
- return a.equals(b);
170
- }
171
- // Handle array contains check
172
- if (Array.isArray(a)) {
173
- return a.some(item => this.valuesMatch(item, b));
174
- }
175
- if (Array.isArray(b)) {
176
- return b.some(item => this.valuesMatch(a, item));
177
- }
178
- // Handle Date comparison
179
- if (a instanceof Date && b instanceof Date) {
180
- return a.getTime() === b.getTime();
181
- }
182
- // Handle object comparison
183
- if (typeof a === 'object' && typeof b === 'object' && a !== null && b !== null) {
184
- return JSON.stringify(a) === JSON.stringify(b);
185
- }
186
- return false;
187
- }
188
- }
189
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQWdncmVnYXRpb25FbmdpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90cy9jb25nb2RiL2VuZ2luZS9BZ2dyZWdhdGlvbkVuZ2luZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLHVCQUF1QixDQUFDO0FBR2pELDBCQUEwQjtBQUMxQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRW5DOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQUM1Qjs7T0FFRztJQUNILE1BQU0sQ0FBQyxTQUFTLENBQ2QsU0FBNEIsRUFDNUIsUUFBb0IsRUFDcEIsT0FBMkI7UUFFM0IsSUFBSSxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFFRCw0Q0FBNEM7UUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsUUFBUSxFQUFFO1lBQzFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBZ0I7U0FDckMsQ0FBQyxDQUFDO1FBRUgsc0JBQXNCO1FBQ3RCLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFekMsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM3QyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsQ0FBQyxpQkFBaUIsQ0FDdkIsU0FBNEIsRUFDNUIsUUFBb0IsRUFDcEIsT0FBMkI7UUFFM0IsTUFBTSxVQUFVLEdBQUcsSUFBSSxVQUFVLENBQUMsUUFBUSxFQUFFO1lBQzFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsU0FBZ0I7U0FDckMsQ0FBQyxDQUFDO1FBRUgsNEJBQTRCO1FBQzVCLE1BQU0sTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFNUMsS0FBSyxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUN6QixNQUFNLEdBQUcsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLGFBQWEsQ0FDbEIsU0FBNEIsRUFDNUIsVUFLQyxFQUNELGlCQUFvQztRQUVwQyxNQUFNLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsR0FBRyxVQUFVLENBQUM7UUFFcEQsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3pCLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sT0FBTyxHQUFHLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRTtnQkFDcEQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7Z0JBQ25FLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLEVBQUUsWUFBWSxDQUFDLENBQUM7WUFDcEQsQ0FBQyxDQUFDLENBQUM7WUFFSCxPQUFPO2dCQUNMLEdBQUcsR0FBRztnQkFDTixDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU87YUFDZCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsa0JBQWtCLENBQ3ZCLFNBQTRCLEVBQzVCLGVBU0MsRUFDRCxpQkFBb0M7UUFFcEMsTUFBTSxFQUNKLFNBQVMsRUFDVCxnQkFBZ0IsRUFDaEIsY0FBYyxFQUNkLEVBQUUsRUFDRixRQUFRLEdBQUcsRUFBRSxFQUNiLFVBQVUsRUFDVix1QkFBdUIsR0FDeEIsR0FBRyxlQUFlLENBQUM7UUFFcEIsT0FBTyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ3pCLE1BQU0sVUFBVSxHQUFHLE9BQU8sU0FBUyxLQUFLLFFBQVEsSUFBSSxTQUFTLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQztnQkFDM0UsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlDLENBQUMsQ0FBQyxTQUFTLENBQUM7WUFFZCxNQUFNLE9BQU8sR0FBZSxFQUFFLENBQUM7WUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztZQUNsQyxNQUFNLEtBQUssR0FBeUMsRUFBRSxDQUFDO1lBRXZELGlDQUFpQztZQUNqQyxNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDMUUsS0FBSyxNQUFNLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQztnQkFDOUIsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDdkMsQ0FBQztZQUVELE9BQU8sS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDeEIsTUFBTSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsR0FBRyxLQUFLLENBQUMsS0FBSyxFQUFHLENBQUM7Z0JBQ3hDLElBQUksS0FBSyxHQUFHLFFBQVE7b0JBQUUsU0FBUztnQkFFL0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQztvQkFBRSxTQUFTO2dCQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUV0QiwwQkFBMEI7Z0JBQzFCLEtBQUssTUFBTSxVQUFVLElBQUksaUJBQWlCLEVBQUUsQ0FBQztvQkFDM0MsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLEVBQUUsY0FBYyxDQUFDLENBQUM7b0JBRXJFLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLEVBQUUsQ0FBQzt3QkFDMUMsZ0NBQWdDO3dCQUNoQyxJQUFJLHVCQUF1QixFQUFFLENBQUM7NEJBQzVCLE1BQU0sVUFBVSxHQUFHLElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQzs0QkFDcEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO2dDQUFFLFNBQVM7d0JBQzdDLENBQUM7d0JBRUQsTUFBTSxTQUFTLEdBQUcsVUFBVTs0QkFDMUIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxVQUFVLEVBQUUsQ0FBQyxVQUFVLENBQUMsRUFBRSxLQUFLLEVBQUU7NEJBQ3hDLENBQUMsQ0FBQyxFQUFFLEdBQUcsVUFBVSxFQUFFLENBQUM7d0JBRXRCLDhCQUE4Qjt3QkFDOUIsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQzt3QkFDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLFdBQVcsRUFBRSxFQUFFLEtBQUssTUFBTSxDQUFDLEVBQUUsQ0FBQzs0QkFDMUQsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzs0QkFFeEIsZ0NBQWdDOzRCQUNoQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDOzRCQUNwRSxJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQ0FDNUIsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO2dDQUN0RSxLQUFLLE1BQU0sRUFBRSxJQUFJLFVBQVUsRUFBRSxDQUFDO29DQUM1QixLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7Z0NBQzlDLENBQUM7NEJBQ0gsQ0FBQzt3QkFDSCxDQUFDO29CQUNILENBQUM7Z0JBQ0gsQ0FBQztZQUNILENBQUM7WUFFRCxPQUFPO2dCQUNMLEdBQUcsR0FBRztnQkFDTixDQUFDLEVBQUUsQ0FBQyxFQUFFLE9BQU87YUFDZCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNLENBQUMsWUFBWSxDQUNqQixTQUE0QixFQUM1QixTQUFxQztRQUVyQyxNQUFNLE1BQU0sR0FBYSxFQUFFLENBQUM7UUFFNUIsS0FBSyxNQUFNLENBQUMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQztZQUM5RCxNQUFNLENBQUMsU0FBUyxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDMUQsQ0FBQztRQUVELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sQ0FBQyxnQkFBZ0IsQ0FDckIsU0FBNEIsRUFDNUIsY0FBaUMsRUFDakMsUUFBcUI7UUFFckIsSUFBSSxTQUFTLEdBQWUsY0FBYyxDQUFDO1FBQzNDLElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDcEMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFDRCxPQUFPLENBQUMsR0FBRyxTQUFTLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLFlBQVksQ0FDakIsU0FBcUIsRUFDckIsU0FLQztRQVFELE1BQU0sT0FBTyxHQUFHLFNBQVMsQ0FBQyxFQUFFLElBQUksS0FBSyxDQUFDO1FBQ3RDLE1BQU0sV0FBVyxHQUFHLFNBQVMsQ0FBQyxXQUFXLElBQUksT0FBTyxDQUFDO1FBQ3JELE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxjQUFjLElBQUksUUFBUSxDQUFDO1FBRTVELE9BQU87WUFDTCxRQUFRLEVBQUUsRUFBRTtZQUNaLFFBQVEsRUFBRSxFQUFFO1lBQ1osT0FBTztZQUNQLFdBQVc7WUFDWCxjQUFjO1NBQ2YsQ0FBQztJQUNKLENBQUM7SUFFRCwrRUFBK0U7SUFDL0UsaUJBQWlCO0lBQ2pCLCtFQUErRTtJQUV2RSxNQUFNLENBQUMsY0FBYyxDQUFDLEdBQVEsRUFBRSxJQUFZO1FBQ2xELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDOUIsSUFBSSxPQUFPLEdBQUcsR0FBRyxDQUFDO1FBRWxCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsSUFBSSxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDOUMsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUIsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7SUFFTyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQU0sRUFBRSxDQUFNO1FBQ3ZDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLElBQUksQ0FBQztRQUV6Qiw2QkFBNkI7UUFDN0IsSUFBSSxDQUFDLFlBQVksT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxZQUFZLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDN0UsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JCLENBQUM7UUFFRCw4QkFBOEI7UUFDOUIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDckIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUNuRCxDQUFDO1FBRUQseUJBQXlCO1FBQ3pCLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUM7WUFDM0MsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JDLENBQUM7UUFFRCwyQkFBMkI7UUFDM0IsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQy9FLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7Q0FDRiJ9
@@ -1,376 +0,0 @@
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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