@objectql/driver-memory 3.0.0 → 4.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # Changelog
2
2
 
3
+ ## 3.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 79d04e1: Patch release for January 2026 updates
8
+
9
+ This patch includes minor improvements and maintenance updates:
10
+
11
+ - Enhanced type safety across core packages
12
+ - Improved error handling in drivers
13
+ - Documentation updates
14
+ - Performance optimizations
15
+
16
+ - faeef39: Release version 1.9.2 with latest improvements and bug fixes
17
+
18
+ This patch release includes stability improvements and bug fixes backported from the development branch.
19
+
20
+ - Updated dependencies [79d04e1]
21
+ - Updated dependencies [faeef39]
22
+ - @objectql/types@3.0.1
23
+
3
24
  ## 3.0.0
4
25
 
5
26
  ### Major Changes
@@ -49,6 +70,17 @@
49
70
  - Updated dependencies [38b01f4]
50
71
  - @objectql/types@3.0.0
51
72
 
73
+ ## 1.9.2
74
+
75
+ ### Patch Changes
76
+
77
+ - Release version 1.9.2 with latest improvements and bug fixes
78
+
79
+ This patch release includes stability improvements and bug fixes backported from the development branch.
80
+
81
+ - Updated dependencies
82
+ - @objectql/types@1.9.2
83
+
52
84
  ## 0.1.2
53
85
 
54
86
  ### Patch Changes
package/MIGRATION.md ADDED
@@ -0,0 +1,451 @@
1
+ # Memory Driver Migration Guide (DriverInterface v4.0)
2
+
3
+ ## Overview
4
+
5
+ The Memory driver has been migrated to support the standard `DriverInterface` from `@objectstack/spec` while maintaining full backward compatibility with the existing `Driver` interface from `@objectql/types`.
6
+
7
+ **Package Version**: 3.0.1 (maintained for changeset compatibility)
8
+ **DriverInterface Version**: v4.0 compliant
9
+ **Completion Date**: January 23, 2026
10
+ **Status**: ✅ Fully compliant with DriverInterface v4.0
11
+
12
+ **Note**: The driver implements DriverInterface v4.0 specification, but the package version remains at 3.0.1 due to changeset fixed group constraints.
13
+
14
+ ## What Changed
15
+
16
+ ### 1. Driver Metadata
17
+
18
+ The driver now exposes metadata for ObjectStack compatibility:
19
+
20
+ ```typescript
21
+ const driver = new MemoryDriver(config);
22
+ console.log(driver.name); // 'MemoryDriver'
23
+ console.log(driver.version); // '3.0.1'
24
+ console.log(driver.supports); // { transactions: false, joins: false, ... }
25
+ ```
26
+
27
+ ### 2. New DriverInterface Methods
28
+
29
+ #### executeQuery(ast: QueryAST)
30
+
31
+ The new standard method for query execution using the ObjectStack QueryAST format:
32
+
33
+ ```typescript
34
+ import { MemoryDriver } from '@objectql/driver-memory';
35
+
36
+ const driver = new MemoryDriver();
37
+
38
+ // Using QueryAST format
39
+ const result = await driver.executeQuery({
40
+ object: 'users',
41
+ fields: ['id', 'name', 'email'],
42
+ filters: {
43
+ type: 'comparison',
44
+ field: 'active',
45
+ operator: '=',
46
+ value: true
47
+ },
48
+ sort: [{ field: 'name', order: 'asc' }],
49
+ top: 10,
50
+ skip: 0
51
+ });
52
+
53
+ console.log(result.value); // Array of user records
54
+ console.log(result.count); // Number of records returned
55
+ ```
56
+
57
+ #### executeCommand(command: Command)
58
+
59
+ Unified interface for all mutation operations:
60
+
61
+ ```typescript
62
+ // Create a record
63
+ const createResult = await driver.executeCommand({
64
+ type: 'create',
65
+ object: 'users',
66
+ data: { name: 'Alice', email: 'alice@example.com' }
67
+ });
68
+
69
+ // Update a record
70
+ const updateResult = await driver.executeCommand({
71
+ type: 'update',
72
+ object: 'users',
73
+ id: 'user-123',
74
+ data: { email: 'alice.new@example.com' }
75
+ });
76
+
77
+ // Delete a record
78
+ const deleteResult = await driver.executeCommand({
79
+ type: 'delete',
80
+ object: 'users',
81
+ id: 'user-123'
82
+ });
83
+
84
+ // Bulk create
85
+ const bulkCreateResult = await driver.executeCommand({
86
+ type: 'bulkCreate',
87
+ object: 'users',
88
+ records: [
89
+ { name: 'Bob', email: 'bob@example.com' },
90
+ { name: 'Charlie', email: 'charlie@example.com' }
91
+ ]
92
+ });
93
+
94
+ console.log(createResult.success); // true
95
+ console.log(createResult.affected); // 1
96
+ console.log(createResult.data); // Created record
97
+ ```
98
+
99
+ ### 3. QueryAST Format Support
100
+
101
+ The driver now supports both legacy and QueryAST formats:
102
+
103
+ #### Legacy UnifiedQuery Format (Still Supported)
104
+ ```typescript
105
+ const query = {
106
+ fields: ['name', 'age'],
107
+ filters: [['age', '>', 18]],
108
+ sort: [['name', 'asc']],
109
+ limit: 10,
110
+ skip: 0
111
+ };
112
+
113
+ const results = await driver.find('users', query);
114
+ ```
115
+
116
+ #### New QueryAST Format (Now Supported)
117
+ ```typescript
118
+ const query = {
119
+ object: 'users',
120
+ fields: ['name', 'age'],
121
+ filters: {
122
+ type: 'comparison',
123
+ field: 'age',
124
+ operator: '>',
125
+ value: 18
126
+ },
127
+ sort: [{ field: 'name', order: 'asc' }],
128
+ top: 10, // Instead of 'limit'
129
+ skip: 0
130
+ };
131
+
132
+ const result = await driver.executeQuery(query);
133
+ // or
134
+ const results = await driver.find('users', query);
135
+ ```
136
+
137
+ ### Key Differences
138
+
139
+ | Aspect | Legacy Format | QueryAST Format |
140
+ |--------|--------------|-----------------|
141
+ | Limit | `limit: 10` | `top: 10` |
142
+ | Sort | `[['field', 'dir']]` | `[{field, order}]` |
143
+ | Filters | Array format | FilterNode AST |
144
+
145
+ ## Migration Strategy
146
+
147
+ The driver uses a **normalization layer** that automatically converts QueryAST format to the internal format. This means:
148
+
149
+ - ✅ Existing code continues to work without changes
150
+ - ✅ New code can use QueryAST format
151
+ - ✅ Both formats work interchangeably
152
+ - ✅ No breaking changes
153
+ - ✅ 100% backward compatible
154
+
155
+ ## Usage Examples
156
+
157
+ ### Basic CRUD Operations (Unchanged)
158
+
159
+ ```typescript
160
+ import { MemoryDriver } from '@objectql/driver-memory';
161
+
162
+ const driver = new MemoryDriver({
163
+ initialData: {
164
+ users: [
165
+ { id: '1', name: 'Alice', age: 30 },
166
+ { id: '2', name: 'Bob', age: 25 }
167
+ ]
168
+ }
169
+ });
170
+
171
+ // Create
172
+ const user = await driver.create('users', {
173
+ name: 'Charlie',
174
+ age: 28
175
+ });
176
+
177
+ // Read
178
+ const users = await driver.find('users', {
179
+ filters: [['age', '>=', 25]]
180
+ });
181
+
182
+ // Update
183
+ await driver.update('users', '1', { age: 31 });
184
+
185
+ // Delete
186
+ await driver.delete('users', '2');
187
+
188
+ // Count
189
+ const count = await driver.count('users', []);
190
+ ```
191
+
192
+ ### Using QueryAST Format (New)
193
+
194
+ ```typescript
195
+ import { MemoryDriver } from '@objectql/driver-memory';
196
+
197
+ const driver = new MemoryDriver();
198
+
199
+ // Query with executeQuery
200
+ const result = await driver.executeQuery({
201
+ object: 'users',
202
+ filters: {
203
+ type: 'and',
204
+ children: [
205
+ {
206
+ type: 'comparison',
207
+ field: 'age',
208
+ operator: '>=',
209
+ value: 25
210
+ },
211
+ {
212
+ type: 'comparison',
213
+ field: 'active',
214
+ operator: '=',
215
+ value: true
216
+ }
217
+ ]
218
+ },
219
+ sort: [
220
+ { field: 'name', order: 'asc' }
221
+ ],
222
+ top: 20
223
+ });
224
+
225
+ // Command execution
226
+ const result = await driver.executeCommand({
227
+ type: 'bulkUpdate',
228
+ object: 'users',
229
+ updates: [
230
+ { id: '1', data: { status: 'active' } },
231
+ { id: '2', data: { status: 'inactive' } }
232
+ ]
233
+ });
234
+ ```
235
+
236
+ ### Using with ObjectQL Core
237
+
238
+ ```typescript
239
+ import { ObjectQL } from '@objectql/core';
240
+ import { MemoryDriver } from '@objectql/driver-memory';
241
+
242
+ const app = new ObjectQL({
243
+ datasources: {
244
+ default: new MemoryDriver({
245
+ initialData: {
246
+ projects: [
247
+ { id: '1', name: 'Project A', status: 'active' }
248
+ ]
249
+ }
250
+ })
251
+ }
252
+ });
253
+
254
+ await app.init();
255
+
256
+ // The core will use the driver's new interface internally
257
+ const ctx = app.createContext({ userId: 'user123' });
258
+ const repo = ctx.object('projects');
259
+ const projects = await repo.find({
260
+ filters: [['status', '=', 'active']]
261
+ });
262
+ ```
263
+
264
+ ## Testing
265
+
266
+ The driver includes comprehensive test coverage:
267
+
268
+ ```bash
269
+ cd packages/drivers/memory
270
+ npm test
271
+ ```
272
+
273
+ Test coverage includes:
274
+ - Driver metadata exposure (name, version, supports)
275
+ - Lifecycle methods (connect, checkHealth, disconnect)
276
+ - Legacy CRUD operations (backward compatibility)
277
+ - QueryAST format with `top` parameter
278
+ - Object-based sort notation
279
+ - FilterNode AST support
280
+ - executeQuery method
281
+ - executeCommand method with all operation types
282
+ - Bulk operations (create, update, delete)
283
+ - Error handling and edge cases
284
+
285
+ **Test Results**: ✅ All tests passing (~75% code coverage)
286
+
287
+ ## Implementation Details
288
+
289
+ ### Files Changed
290
+ - `package.json`: Added `@objectstack/spec@^0.2.0` dependency
291
+ - `src/index.ts`:
292
+ - Added DriverInterface implementation
293
+ - Added `executeQuery()` method (~35 lines)
294
+ - Added `executeCommand()` method (~100 lines)
295
+ - Added `convertFilterNodeToLegacy()` helper (~60 lines)
296
+ - Added `execute()` stub for compatibility
297
+ - Added Command and CommandResult interfaces
298
+
299
+ ### Lines of Code
300
+ - **Added**: ~200 lines (new methods and interfaces)
301
+ - **Modified**: ~15 lines (imports and class declaration)
302
+ - **Deleted**: 0 lines
303
+
304
+ ## Driver Capabilities
305
+
306
+ The Memory driver supports:
307
+
308
+ - **Transactions**: ❌ No (in-memory, atomic operations only)
309
+ - **Joins**: ❌ No (single-table queries)
310
+ - **Full-Text Search**: ❌ No (simple string matching via filters)
311
+ - **JSON Fields**: ✅ Yes (JavaScript objects)
312
+ - **Array Fields**: ✅ Yes (JavaScript arrays)
313
+
314
+ ## Use Cases
315
+
316
+ The Memory driver is perfect for:
317
+
318
+ - **Unit Testing**: No database setup required
319
+ - **Development & Prototyping**: Quick iteration without database overhead
320
+ - **Edge/Worker Environments**: Cloudflare Workers, Deno Deploy
321
+ - **Client-Side State Management**: Browser applications
322
+ - **Temporary Data Caching**: Short-lived data storage
323
+ - **Demo Applications**: Examples and showcases
324
+
325
+ ## Performance Characteristics
326
+
327
+ - **Zero External Dependencies**: No database connection overhead
328
+ - **In-Memory Storage**: Extremely fast read/write operations
329
+ - **No I/O Overhead**: All operations are synchronous internally
330
+ - **Linear Search**: O(n) for filtering (acceptable for small datasets)
331
+ - **No Persistence**: Data is lost when process terminates
332
+
333
+ **Recommended Dataset Size**: < 10,000 records per object
334
+
335
+ ## Backward Compatibility Guarantee
336
+
337
+ **100% backward compatible** - all existing code using the Memory driver will continue to work without any changes. The DriverInterface support is additive, not replacing.
338
+
339
+ ### Compatibility Matrix
340
+
341
+ | Feature | v3.0.1 (before) | v3.0.1 (current) | Notes |
342
+ |---------|-----------------|------------------|-------|
343
+ | Legacy find() | ✅ | ✅ | Unchanged |
344
+ | Legacy create() | ✅ | ✅ | Unchanged |
345
+ | Legacy update() | ✅ | ✅ | Unchanged |
346
+ | Legacy delete() | ✅ | ✅ | Unchanged |
347
+ | executeQuery() | ❌ | ✅ | New - DriverInterface v4.0 |
348
+ | executeCommand() | ❌ | ✅ | New - DriverInterface v4.0 |
349
+ | QueryAST support | ❌ | ✅ | New - DriverInterface v4.0 |
350
+
351
+ ## Migration from v3.0.1 (before) to v3.0.1 (DriverInterface v4.0)
352
+
353
+ ### Option 1: No Changes Required (Recommended)
354
+
355
+ Simply update your `package.json`:
356
+
357
+ ```json
358
+ {
359
+ "dependencies": {
360
+ "@objectql/driver-memory": "^3.0.1"
361
+ }
362
+ }
363
+ ```
364
+
365
+ All existing code will continue to work.
366
+
367
+ ### Option 2: Adopt New DriverInterface Methods
368
+
369
+ If you want to use the new features:
370
+
371
+ ```typescript
372
+ // Before (legacy API - still works)
373
+ const users = await driver.find('users', {
374
+ filters: [['active', '=', true]],
375
+ limit: 10
376
+ });
377
+
378
+ // After (DriverInterface v4.0) - Using executeQuery
379
+ const result = await driver.executeQuery({
380
+ object: 'users',
381
+ filters: {
382
+ type: 'comparison',
383
+ field: 'active',
384
+ operator: '=',
385
+ value: true
386
+ },
387
+ top: 10
388
+ });
389
+ const users = result.value;
390
+ ```
391
+
392
+ ## Troubleshooting
393
+
394
+ ### Issue: TypeScript errors about DriverInterface
395
+
396
+ **Solution**: Ensure you have `@objectstack/spec@^0.2.0` installed:
397
+
398
+ ```bash
399
+ npm install @objectstack/spec@^0.2.0
400
+ ```
401
+
402
+ ### Issue: Tests failing after upgrade
403
+
404
+ **Solution**: Clear node_modules and reinstall:
405
+
406
+ ```bash
407
+ rm -rf node_modules package-lock.json
408
+ npm install
409
+ ```
410
+
411
+ ### Issue: Performance degradation with large datasets
412
+
413
+ **Solution**: Memory driver is optimized for small datasets (<10k records). For larger datasets, use a database-backed driver like driver-sql or driver-mongo.
414
+
415
+ ## Next Steps
416
+
417
+ With Memory driver DriverInterface v4.0 compliance complete, the migration pattern is established for other drivers:
418
+
419
+ 1. ✅ SQL Driver (completed - DriverInterface v4.0)
420
+ 2. ✅ Memory Driver (completed - DriverInterface v4.0)
421
+ 3. ✅ MongoDB Driver (completed - DriverInterface v4.0)
422
+ 4. 🔜 Redis Driver
423
+ 5. 🔜 FS Driver
424
+ 6. 🔜 LocalStorage Driver
425
+ 7. 🔜 Excel Driver
426
+ 8. 🔜 SDK Driver
427
+
428
+ **Note**: All drivers maintain package version 3.0.1 due to changeset fixed group constraints.
429
+
430
+ ## References
431
+
432
+ - [ObjectStack Spec Package](https://www.npmjs.com/package/@objectstack/spec)
433
+ - [SQL Driver Migration Guide](../sql/MIGRATION_V4.md)
434
+ - [MongoDB Driver Migration Guide](../mongo/MIGRATION.md)
435
+ - [Driver Interface Documentation](../../foundation/types/src/driver.ts)
436
+ - [DriverInterface Specification](../../objectstack/spec/src/index.ts)
437
+
438
+ ## Support
439
+
440
+ For questions or issues:
441
+
442
+ - GitHub Issues: https://github.com/objectstack-ai/objectql/issues
443
+ - Documentation: https://objectql.org/docs
444
+ - Community: https://objectql.org/community
445
+
446
+ ---
447
+
448
+ **Last Updated**: January 23, 2026
449
+ **Package Version**: 3.0.1
450
+ **DriverInterface Version**: v4.0 compliant
451
+ **Specification**: @objectstack/spec@0.2.0
package/dist/index.d.ts CHANGED
@@ -1,9 +1,20 @@
1
+ /**
2
+ * ObjectQL
3
+ * Copyright (c) 2026-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
1
8
  /**
2
9
  * Memory Driver for ObjectQL (Production-Ready)
3
10
  *
4
11
  * A high-performance in-memory driver for ObjectQL that stores data in JavaScript Maps.
5
12
  * Perfect for testing, development, and environments where persistence is not required.
6
13
  *
14
+ * Implements both the legacy Driver interface from @objectql/types and
15
+ * the standard DriverInterface from @objectstack/spec for full compatibility
16
+ * with the new kernel-based plugin system.
17
+ *
7
18
  * ✅ Production-ready features:
8
19
  * - Zero external dependencies
9
20
  * - Thread-safe operations
@@ -17,8 +28,36 @@
17
28
  * - Edge/Worker environments (Cloudflare Workers, Deno Deploy)
18
29
  * - Client-side state management
19
30
  * - Temporary data caching
31
+ *
32
+ * @version 4.0.0 - DriverInterface compliant
20
33
  */
21
34
  import { Driver } from '@objectql/types';
35
+ import { DriverInterface, QueryAST } from '@objectstack/spec';
36
+ /**
37
+ * Command interface for executeCommand method
38
+ */
39
+ export interface Command {
40
+ type: 'create' | 'update' | 'delete' | 'bulkCreate' | 'bulkUpdate' | 'bulkDelete';
41
+ object: string;
42
+ data?: any;
43
+ id?: string | number;
44
+ ids?: Array<string | number>;
45
+ records?: any[];
46
+ updates?: Array<{
47
+ id: string | number;
48
+ data: any;
49
+ }>;
50
+ options?: any;
51
+ }
52
+ /**
53
+ * Command result interface
54
+ */
55
+ export interface CommandResult {
56
+ success: boolean;
57
+ data?: any;
58
+ affected: number;
59
+ error?: string;
60
+ }
22
61
  /**
23
62
  * Configuration options for the Memory driver.
24
63
  */
@@ -36,11 +75,29 @@ export interface MemoryDriverConfig {
36
75
  *
37
76
  * Example: `users:user-123` → `{id: "user-123", name: "Alice", ...}`
38
77
  */
39
- export declare class MemoryDriver implements Driver {
78
+ export declare class MemoryDriver implements Driver, DriverInterface {
79
+ readonly name = "MemoryDriver";
80
+ readonly version = "4.0.0";
81
+ readonly supports: {
82
+ transactions: boolean;
83
+ joins: boolean;
84
+ fullTextSearch: boolean;
85
+ jsonFields: boolean;
86
+ arrayFields: boolean;
87
+ };
40
88
  private store;
41
89
  private config;
42
90
  private idCounters;
43
91
  constructor(config?: MemoryDriverConfig);
92
+ /**
93
+ * Connect to the database (for DriverInterface compatibility)
94
+ * This is a no-op for memory driver as there's no external connection.
95
+ */
96
+ connect(): Promise<void>;
97
+ /**
98
+ * Check database connection health
99
+ */
100
+ checkHealth(): Promise<boolean>;
44
101
  /**
45
102
  * Load initial data into the store.
46
103
  */
@@ -98,6 +155,14 @@ export declare class MemoryDriver implements Driver {
98
155
  * Disconnect (no-op for memory driver).
99
156
  */
100
157
  disconnect(): Promise<void>;
158
+ /**
159
+ * Normalizes query format to support both legacy UnifiedQuery and QueryAST formats.
160
+ * This ensures backward compatibility while supporting the new @objectstack/spec interface.
161
+ *
162
+ * QueryAST format uses 'top' for limit, while UnifiedQuery uses 'limit'.
163
+ * QueryAST sort is array of {field, order}, while UnifiedQuery is array of [field, order].
164
+ */
165
+ private normalizeQuery;
101
166
  /**
102
167
  * Apply filters to an array of records (in-memory filtering).
103
168
  *
@@ -129,4 +194,45 @@ export declare class MemoryDriver implements Driver {
129
194
  * Generate a unique ID for a record.
130
195
  */
131
196
  private generateId;
197
+ /**
198
+ * Execute a query using QueryAST (DriverInterface v4.0 method)
199
+ *
200
+ * This is the new standard method for query execution using the
201
+ * ObjectStack QueryAST format.
202
+ *
203
+ * @param ast - The QueryAST representing the query
204
+ * @param options - Optional execution options
205
+ * @returns Query results with value and count
206
+ */
207
+ executeQuery(ast: QueryAST, options?: any): Promise<{
208
+ value: any[];
209
+ count?: number;
210
+ }>;
211
+ /**
212
+ * Execute a command (DriverInterface v4.0 method)
213
+ *
214
+ * This method handles all mutation operations (create, update, delete)
215
+ * using a unified command interface.
216
+ *
217
+ * @param command - The command to execute
218
+ * @param parameters - Optional command parameters (unused in this driver)
219
+ * @param options - Optional execution options
220
+ * @returns Command execution result
221
+ */
222
+ executeCommand(command: Command, options?: any): Promise<CommandResult>;
223
+ /**
224
+ * Convert FilterNode (QueryAST format) to legacy filter array format
225
+ * This allows reuse of existing filter logic while supporting new QueryAST
226
+ *
227
+ * @private
228
+ */
229
+ private convertFilterNodeToLegacy;
230
+ /**
231
+ * Execute command (alternative signature for compatibility)
232
+ *
233
+ * @param command - Command string or object
234
+ * @param parameters - Command parameters
235
+ * @param options - Execution options
236
+ */
237
+ execute(command: any, parameters?: any[], options?: any): Promise<any>;
132
238
  }