@objectstack/driver-memory 4.0.3 → 4.0.5

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/README.md CHANGED
@@ -1,21 +1,102 @@
1
1
  # @objectstack/driver-memory
2
2
 
3
- In-Memory Database access layer for ObjectStack. Supports rich querying capabilities (MongoDB-style operators) on standard JavaScript arrays.
3
+ > In-memory ObjectQL driver for ObjectStack zero-config storage for development, unit tests, Storybook, and browser MSW mocks.
4
4
 
5
- ## Features
5
+ [![npm](https://img.shields.io/npm/v/@objectstack/driver-memory.svg)](https://www.npmjs.com/package/@objectstack/driver-memory)
6
+ [![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
6
7
 
7
- - **NoSQL Syntax**: Supports `$eq`, `$gt`, `$lt`, `$in`, `$and`, `$or` operators.
8
- - **Sorting & Pagination**: Full support for `sort`, `skip`, `limit`.
9
- - **Zero Config**: Perfect for prototyping, testing, and the **MSW Browser Mock**.
10
- - **Stateful**: Preserves data in memory during the session.
8
+ ## Overview
11
9
 
12
- ## Usage
10
+ Implements the `IDataEngine` contract against in-memory `Map`-backed tables. Supports the full ObjectQL surface: MongoDB-style operators (`$eq`, `$ne`, `$gt`, `$lt`, `$gte`, `$lte`, `$in`, `$nin`, `$and`, `$or`, `$not`), sorting, pagination, aggregations, and joins. Optional persistence adapters serialize state to disk (Node) or `localStorage` (browser).
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ pnpm add @objectstack/driver-memory
16
+ ```
17
+
18
+ ## Quick Start
19
+
20
+ ```typescript
21
+ import { ObjectKernel } from '@objectstack/core';
22
+ import memoryPlugin from '@objectstack/driver-memory';
23
+
24
+ const kernel = new ObjectKernel();
25
+ kernel.use(memoryPlugin); // default plugin
26
+ await kernel.bootstrap();
27
+ ```
28
+
29
+ ### Direct instantiation
13
30
 
14
31
  ```typescript
15
32
  import { InMemoryDriver } from '@objectstack/driver-memory';
16
33
 
17
34
  const driver = new InMemoryDriver();
18
35
  await driver.connect();
36
+ ```
37
+
38
+ ### With filesystem persistence (Node)
39
+
40
+ ```typescript
41
+ import { InMemoryDriver, FileSystemPersistenceAdapter } from '@objectstack/driver-memory';
19
42
 
20
- // Used internally by ObjectQL
43
+ const driver = new InMemoryDriver({
44
+ persistence: new FileSystemPersistenceAdapter('./data/snapshot.json'),
45
+ });
46
+ await driver.connect();
21
47
  ```
48
+
49
+ ### With `localStorage` persistence (browser)
50
+
51
+ ```typescript
52
+ import { InMemoryDriver, LocalStoragePersistenceAdapter } from '@objectstack/driver-memory';
53
+
54
+ const driver = new InMemoryDriver({
55
+ persistence: new LocalStoragePersistenceAdapter('objectstack:dev'),
56
+ });
57
+ ```
58
+
59
+ ## Key Exports
60
+
61
+ | Export | Kind | Description |
62
+ |:---|:---|:---|
63
+ | `default` | kernel plugin | Drop-in plugin. |
64
+ | `InMemoryDriver` | class | Driver instance for direct use. |
65
+ | `InMemoryStrategy` | class | Query execution strategy used by ObjectQL. |
66
+ | `FileSystemPersistenceAdapter` | class | Node-only persistence. |
67
+ | `LocalStoragePersistenceAdapter` | class | Browser-only persistence. |
68
+ | `MemoryAnalyticsService` | class | Adds analytics aggregations backed by memory store. |
69
+ | `InMemoryDriverConfig`, `PersistenceAdapterInterface`, `MemoryAnalyticsConfig` | types | Configuration shapes. |
70
+
71
+ ## Configuration
72
+
73
+ | Option | Type | Default | Notes |
74
+ |:---|:---|:---|:---|
75
+ | `persistence` | `PersistenceAdapterInterface?` | `undefined` | Optional snapshot store. |
76
+ | `seed` | `Record<string, any[]>?` | `{}` | Initial rows keyed by object name. |
77
+ | `idStrategy` | `'uuid' \| 'auto'` | `'uuid'` | ID generation strategy. |
78
+
79
+ ## When to use
80
+
81
+ - ✅ Development, unit tests, CI, Storybook.
82
+ - ✅ Browser-only demos pairing with [`@objectstack/plugin-msw`](../plugin-msw).
83
+
84
+ ## When not to use
85
+
86
+ - ❌ Production — data is lost on restart without a persistence adapter; durability/concurrency guarantees are minimal.
87
+ - ❌ Multi-process deployments.
88
+
89
+ ## Related Packages
90
+
91
+ - [`@objectstack/objectql`](../../objectql) — query engine.
92
+ - [`@objectstack/driver-sql`](../driver-sql), [`@objectstack/driver-turso`](../driver-turso) — production drivers.
93
+ - [`@objectstack/plugin-msw`](../plugin-msw) — browser mock API.
94
+
95
+ ## Links
96
+
97
+ - 📖 Docs: <https://objectstack.ai/docs>
98
+ - 📚 API Reference: <https://objectstack.ai/docs/references>
99
+
100
+ ## License
101
+
102
+ Apache-2.0 © ObjectStack
package/dist/index.d.mts CHANGED
@@ -236,6 +236,8 @@ declare class InMemoryDriver implements IDataDriver {
236
236
  flush(): Promise<void>;
237
237
  /**
238
238
  * Detect whether the current runtime is a browser environment.
239
+ * Checks for window, document AND a functional localStorage to avoid
240
+ * false positives in Node.js runtimes that partially polyfill globals.
239
241
  */
240
242
  private isBrowserEnvironment;
241
243
  /**
package/dist/index.d.ts CHANGED
@@ -236,6 +236,8 @@ declare class InMemoryDriver implements IDataDriver {
236
236
  flush(): Promise<void>;
237
237
  /**
238
238
  * Detect whether the current runtime is a browser environment.
239
+ * Checks for window, document AND a functional localStorage to avoid
240
+ * false positives in Node.js runtimes that partially polyfill globals.
239
241
  */
240
242
  private isBrowserEnvironment;
241
243
  /**
package/dist/index.js CHANGED
@@ -1049,9 +1049,12 @@ var _InMemoryDriver = class _InMemoryDriver {
1049
1049
  }
1050
1050
  /**
1051
1051
  * Detect whether the current runtime is a browser environment.
1052
+ * Checks for window, document AND a functional localStorage to avoid
1053
+ * false positives in Node.js runtimes that partially polyfill globals.
1052
1054
  */
1053
1055
  isBrowserEnvironment() {
1054
- return typeof globalThis.localStorage !== "undefined";
1056
+ const g = globalThis;
1057
+ return typeof g.window !== "undefined" && typeof g.document !== "undefined" && typeof g.localStorage?.setItem === "function";
1055
1058
  }
1056
1059
  /**
1057
1060
  * Detect whether the current runtime is a serverless/edge environment.
@@ -1413,7 +1416,20 @@ var MemoryAnalyticsService = class {
1413
1416
  resolveMeasure(cube, measureName) {
1414
1417
  const parts = measureName.split(".");
1415
1418
  const fieldName = parts.length > 1 ? parts[1] : parts[0];
1416
- return cube.measures[fieldName];
1419
+ const direct = cube.measures[fieldName];
1420
+ if (direct) return direct;
1421
+ const aggTypes = ["count", "sum", "avg", "min", "max", "count_distinct"];
1422
+ for (const type of aggTypes) {
1423
+ const suffix = `_${type}`;
1424
+ if (fieldName.endsWith(suffix)) {
1425
+ const baseField = fieldName.slice(0, -suffix.length);
1426
+ const candidate = cube.measures[baseField];
1427
+ if (candidate && candidate.type === type) {
1428
+ return candidate;
1429
+ }
1430
+ }
1431
+ }
1432
+ return void 0;
1417
1433
  }
1418
1434
  resolveDimension(cube, dimensionName) {
1419
1435
  const parts = dimensionName.split(".");