@objectql/driver-memory 4.0.1 → 4.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.
@@ -0,0 +1,4 @@
1
+
2
+ > @objectql/driver-memory@4.0.3 build /home/runner/work/objectql/objectql/packages/drivers/memory
3
+ > tsc
4
+
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # Changelog
2
2
 
3
+ ## 4.0.3
4
+
5
+ ### Patch Changes
6
+
7
+ - **Patch Release v4.0.3**
8
+
9
+ This patch release includes infrastructure improvements and development experience enhancements:
10
+ - Refactored dev server setup for improved configuration handling
11
+ - Enhanced example scripts and development workflow
12
+ - Updated build and test infrastructure
13
+ - Improved documentation and developer tools
14
+ - Bug fixes and stability improvements
15
+
16
+ - Updated dependencies
17
+ - @objectql/types@4.0.3
18
+
19
+ ## 4.0.2
20
+
21
+ ### Patch Changes
22
+
23
+ - **Patch Release v4.0.2**
24
+
25
+ This patch release includes:
26
+ - Infrastructure improvements and maintenance updates
27
+ - Enhanced stability and reliability
28
+ - Bug fixes and performance optimizations
29
+
30
+ - Updated dependencies
31
+ - @objectql/types@4.0.2
32
+
3
33
  ## 4.0.1
4
34
 
5
35
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -67,6 +67,27 @@ export interface MemoryDriverConfig {
67
67
  initialData?: Record<string, any[]>;
68
68
  /** Optional: Enable strict mode (throw on missing objects) */
69
69
  strictMode?: boolean;
70
+ /** Optional: Enable persistence to file system */
71
+ persistence?: {
72
+ /** File path to persist data */
73
+ filePath: string;
74
+ /** Auto-save interval in milliseconds (default: 5000) */
75
+ autoSaveInterval?: number;
76
+ };
77
+ /** Optional: Fields to index for faster queries */
78
+ indexes?: Record<string, string[]>;
79
+ }
80
+ /**
81
+ * In-memory transaction
82
+ */
83
+ interface MemoryTransaction {
84
+ id: string;
85
+ snapshot: Map<string, any>;
86
+ operations: Array<{
87
+ type: 'set' | 'delete';
88
+ key: string;
89
+ value?: any;
90
+ }>;
70
91
  }
71
92
  /**
72
93
  * Memory Driver Implementation
@@ -92,9 +113,12 @@ export declare class MemoryDriver implements Driver {
92
113
  queryWindowFunctions: boolean;
93
114
  querySubqueries: boolean;
94
115
  };
95
- private store;
96
- private config;
97
- private idCounters;
116
+ protected store: Map<string, any>;
117
+ protected config: MemoryDriverConfig;
118
+ protected idCounters: Map<string, number>;
119
+ protected transactions: Map<string, MemoryTransaction>;
120
+ protected indexes: Map<string, Map<string, Set<string>>>;
121
+ protected persistenceTimer?: NodeJS.Timeout;
98
122
  constructor(config?: MemoryDriverConfig);
99
123
  /**
100
124
  * Connect to the database (for DriverInterface compatibility)
@@ -108,7 +132,7 @@ export declare class MemoryDriver implements Driver {
108
132
  /**
109
133
  * Load initial data into the store.
110
134
  */
111
- private loadInitialData;
135
+ protected loadInitialData(data: Record<string, any[]>): void;
112
136
  /**
113
137
  * Find multiple records matching the query criteria.
114
138
  * Supports filtering, sorting, pagination, and field projection using Mingo.
@@ -159,9 +183,71 @@ export declare class MemoryDriver implements Driver {
159
183
  */
160
184
  getSize(): number;
161
185
  /**
162
- * Disconnect (no-op for memory driver).
186
+ * Disconnect and cleanup resources.
163
187
  */
164
188
  disconnect(): Promise<void>;
189
+ /**
190
+ * Perform aggregation operations using Mingo
191
+ * @param objectName - The object type to aggregate
192
+ * @param pipeline - MongoDB-style aggregation pipeline
193
+ * @param options - Optional query options
194
+ * @returns Aggregation results
195
+ *
196
+ * @example
197
+ * // Group by status and count
198
+ * const results = await driver.aggregate('orders', [
199
+ * { $match: { status: 'completed' } },
200
+ * { $group: { _id: '$customer', totalAmount: { $sum: '$amount' } } }
201
+ * ]);
202
+ *
203
+ * @example
204
+ * // Calculate average with filter
205
+ * const results = await driver.aggregate('products', [
206
+ * { $match: { category: 'electronics' } },
207
+ * { $group: { _id: null, avgPrice: { $avg: '$price' } } }
208
+ * ]);
209
+ */
210
+ aggregate(objectName: string, pipeline: any[], options?: any): Promise<any[]>;
211
+ /**
212
+ * Begin a new transaction
213
+ * @returns Transaction object that can be passed to other methods
214
+ */
215
+ beginTransaction(): Promise<any>;
216
+ /**
217
+ * Commit a transaction
218
+ * @param transaction - Transaction object returned by beginTransaction()
219
+ */
220
+ commitTransaction(transaction: any): Promise<void>;
221
+ /**
222
+ * Rollback a transaction
223
+ * @param transaction - Transaction object returned by beginTransaction()
224
+ */
225
+ rollbackTransaction(transaction: any): Promise<void>;
226
+ /**
227
+ * Set up persistence to file system
228
+ * @private
229
+ */
230
+ protected setupPersistence(): void;
231
+ /**
232
+ * Save current state to disk
233
+ * @private
234
+ */
235
+ protected saveToDisk(): void;
236
+ /**
237
+ * Build indexes for faster queries
238
+ * @private
239
+ */
240
+ protected buildIndexes(indexConfig: Record<string, string[]>): void;
241
+ /**
242
+ * Update index when a record is created or updated
243
+ * @private
244
+ */
245
+ protected updateIndex(objectName: string, recordId: string, record: any): void;
246
+ /**
247
+ * Remove record from indexes
248
+ * @private
249
+ */
250
+ protected removeFromIndex(objectName: string, recordId: string): void;
165
251
  /**
166
252
  * Normalizes query format to support both legacy UnifiedQuery and QueryAST formats.
167
253
  * This ensures backward compatibility while supporting the new @objectstack/spec interface.
@@ -169,43 +255,53 @@ export declare class MemoryDriver implements Driver {
169
255
  * QueryAST format uses 'top' for limit, while UnifiedQuery uses 'limit'.
170
256
  * QueryAST sort is array of {field, order}, while UnifiedQuery is array of [field, order].
171
257
  */
172
- private normalizeQuery;
173
258
  /**
174
259
  * Convert ObjectQL filters to MongoDB query format for Mingo.
175
260
  *
176
- * Supports ObjectQL filter format:
177
- * [
178
- * ['field', 'operator', value],
179
- * 'or',
180
- * ['field2', 'operator', value2]
181
- * ]
261
+ * Supports both:
262
+ * 1. Legacy ObjectQL filter format (array):
263
+ * [['field', 'operator', value], 'or', ['field2', 'operator', value2']]
264
+ * 2. New FilterCondition format (object - already MongoDB-like):
265
+ * { $and: [{ field: { $eq: value }}, { field2: { $gt: value2 }}] }
182
266
  *
183
267
  * Converts to MongoDB query format:
184
268
  * { $or: [{ field: { $operator: value }}, { field2: { $operator: value2 }}] }
185
269
  */
186
- private convertToMongoQuery;
270
+ /**
271
+ * Convert ObjectQL filter format to MongoDB query format.
272
+ * Supports three input formats:
273
+ *
274
+ * 1. AST Comparison Node: { type: 'comparison', field: string, operator: string, value: any }
275
+ * 2. AST Logical Node: { type: 'logical', operator: 'and' | 'or', conditions: Node[] }
276
+ * 3. Legacy Array Format: [field, operator, value, 'and', field2, operator2, value2]
277
+ * 4. MongoDB Format: { field: value } or { field: { $eq: value } } (passthrough)
278
+ *
279
+ * @param filters - Filter in any supported format
280
+ * @returns MongoDB query object
281
+ */
282
+ protected convertToMongoQuery(filters?: any[] | Record<string, any>): Record<string, any>;
187
283
  /**
188
284
  * Convert a single ObjectQL condition to MongoDB operator format.
189
285
  */
190
- private convertConditionToMongo;
286
+ protected convertConditionToMongo(field: string, operator: string, value: any): Record<string, any> | null;
191
287
  /**
192
288
  * Escape special regex characters to prevent ReDoS and ensure literal matching.
193
289
  * This is crucial for security when using user input in regex patterns.
194
290
  */
195
- private escapeRegex;
291
+ protected escapeRegex(str: string): string;
196
292
  /**
197
293
  * Apply manual sorting to an array of records.
198
294
  * This is used instead of Mingo's sort to avoid CJS build issues.
199
295
  */
200
- private applyManualSort;
296
+ protected applyManualSort(records: any[], sort: any[]): any[];
201
297
  /**
202
298
  * Project specific fields from a document.
203
299
  */
204
- private projectFields;
300
+ protected projectFields(doc: any, fields: string[]): any;
205
301
  /**
206
302
  * Generate a unique ID for a record.
207
303
  */
208
- private generateId;
304
+ protected generateId(objectName: string): string;
209
305
  /**
210
306
  * Execute a query using QueryAST (DriverInterface v4.0 method)
211
307
  *
@@ -232,13 +328,6 @@ export declare class MemoryDriver implements Driver {
232
328
  * @returns Command execution result
233
329
  */
234
330
  executeCommand(command: Command, options?: any): Promise<CommandResult>;
235
- /**
236
- * Convert FilterNode (QueryAST format) to legacy filter array format
237
- * This allows reuse of existing filter logic while supporting new QueryAST
238
- *
239
- * @private
240
- */
241
- private convertFilterNodeToLegacy;
242
331
  /**
243
332
  * Execute command (alternative signature for compatibility)
244
333
  *