@noy-db/to-memory 0.2.0-pre.30 → 0.2.0-pre.31

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { NoydbStore } from '@noy-db/hub';
1
+ import { NoydbStore } from '@noy-db/hub/adapter';
2
2
 
3
3
  /**
4
4
  * **@noy-db/to-memory** — in-memory store for NOYDB (testing and development).
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/index.ts
2
- import { ConflictError } from "@noy-db/hub";
2
+ import { ConflictError } from "@noy-db/hub/adapter";
3
3
  function memory(opts = {}) {
4
4
  const store = /* @__PURE__ */ new Map();
5
5
  const epsilon = opts.clockUncertainty ?? 0;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * **@noy-db/to-memory** — in-memory store for NOYDB (testing and development).\n *\n * Backed by nested `Map` objects: `vault → collection → id → envelope`.\n * Data is lost when the process exits — this store is intentionally\n * non-persistent.\n *\n * ## When to use\n *\n * - **Unit tests** — fast, zero I/O, works in any environment.\n * - **In-memory caching layer** — pair with `routeStore` to keep a hot\n * copy of frequently-read collections in memory while persisting to\n * a durable backend.\n * - **REPL / prototyping** — explore the NOYDB API without setting up\n * a backend.\n *\n * ## Capabilities\n *\n * | Capability | Value |\n * |---|---|\n * | `casAtomic` | `true` — Map operations are synchronous and inherently atomic |\n * | `txAtomic` | `true` — multi-record `tx()` applies every op in a single synchronous burst |\n * | `listVaults` | ✓ — iterates outer Map keys |\n * | `listPage` | ✓ — cursor-based pagination over sorted id list |\n * | `ping` | ✓ — always returns `true` |\n *\n * @packageDocumentation\n */\n\nimport type { NoydbStore, EncryptedEnvelope, VaultSnapshot, TxOp } from '@noy-db/hub'\nimport { ConflictError } from '@noy-db/hub'\n\n/**\n * Create an in-memory adapter backed by nested Maps.\n * No persistence — data is lost when the process exits.\n * Intended for testing and development.\n */\nexport function memory(opts: { clockUncertainty?: number } = {}): NoydbStore {\n // vault -> collection -> id -> envelope\n const store = new Map<string, Map<string, Map<string, EncryptedEnvelope>>>()\n\n // Monotonic store clock — a single-process counter is perfectly ordered.\n // `clockUncertainty` (ε) widens the returned interval to exercise the\n // commit-wait path in deferred numbering; default 0 (exact).\n const epsilon = opts.clockUncertainty ?? 0\n let clock = 0\n\n function getCollection(vault: string, collection: string): Map<string, EncryptedEnvelope> {\n let comp = store.get(vault)\n if (!comp) {\n comp = new Map()\n store.set(vault, comp)\n }\n let coll = comp.get(collection)\n if (!coll) {\n coll = new Map()\n comp.set(collection, coll)\n }\n return coll\n }\n\n return {\n name: 'memory',\n\n // #321 — memory's synchronous Map ops make the expectedVersion check +\n // write atomic, so it can back `vault.sequence()`. Without this the\n // JSDoc's `casAtomic: true` promise was undefined at runtime and\n // `sequence().next()` threw SequenceOfflineError.\n capabilities: {\n casAtomic: true,\n serverWriteTime: true,\n auth: { kind: 'none', required: false, flow: 'static' },\n },\n\n // #322-sibling — authoritative store clock for deferred numbering. A\n // single-process counter is perfectly monotonic; ε widens the interval.\n async getStoreTime() {\n const now = ++clock\n return { earliest: now - epsilon, latest: now + epsilon }\n },\n\n async get(vault, collection, id) {\n return store.get(vault)?.get(collection)?.get(id) ?? null\n },\n\n async put(vault, collection, id, envelope, expectedVersion) {\n const coll = getCollection(vault, collection)\n const existing = coll.get(id)\n\n if (expectedVersion !== undefined && existing) {\n if (existing._v !== expectedVersion) {\n throw new ConflictError(existing._v, `Version conflict: expected ${expectedVersion}, found ${existing._v}`)\n }\n }\n\n coll.set(id, envelope)\n },\n\n async delete(vault, collection, id) {\n store.get(vault)?.get(collection)?.delete(id)\n },\n\n async list(vault, collection) {\n const coll = store.get(vault)?.get(collection)\n return coll ? [...coll.keys()] : []\n },\n\n async loadAll(vault) {\n const comp = store.get(vault)\n const snapshot: VaultSnapshot = {}\n if (comp) {\n for (const [collName, coll] of comp) {\n if (collName.startsWith('_')) continue\n const records: Record<string, EncryptedEnvelope> = {}\n for (const [id, envelope] of coll) {\n records[id] = envelope\n }\n snapshot[collName] = records\n }\n }\n return snapshot\n },\n\n async saveAll(vault, data) {\n const comp = store.get(vault)\n if (comp) {\n for (const key of [...comp.keys()]) {\n if (!key.startsWith('_')) {\n comp.delete(key)\n }\n }\n }\n\n for (const [collName, records] of Object.entries(data)) {\n const coll = getCollection(vault, collName)\n for (const [id, envelope] of Object.entries(records)) {\n coll.set(id, envelope)\n }\n }\n },\n\n async ping() {\n return true\n },\n\n /**\n * Enumerate every top-level vault held by this in-memory\n * store. Used by `Noydb.listAccessibleVaults()`\n * to get the universe of compartments before filtering down to\n * the ones the calling principal can unwrap.\n *\n * Returns the outer Map's keys directly — O(compartments) and\n * cheap. The result is intentionally unsorted; consumers that\n * want a stable order should sort themselves.\n */\n async listVaults() {\n return [...store.keys()]\n },\n\n /**\n * Multi-record atomic transaction.\n *\n * Validates every op's `expectedVersion` against the current Map\n * state, throws `ConflictError` on the first mismatch (nothing\n * written), then applies every put/delete in one synchronous burst\n * — the Map mutations are single-threaded in the JS event loop so\n * no concurrent writer can interleave. Truly atomic.\n */\n async tx(ops: readonly TxOp[]) {\n // Phase 1 — validate every expectedVersion against current state.\n // We read the state ONCE up front; subsequent ops that target the\n // same (vault, coll, id) see the same snapshot, matching the\n // atomicity guarantee callers expect from a storage-layer tx.\n for (const op of ops) {\n if (op.expectedVersion === undefined) continue\n const existing = store.get(op.vault)?.get(op.collection)?.get(op.id)\n const actual = existing?._v ?? 0\n if (actual !== op.expectedVersion) {\n throw new ConflictError(\n actual,\n `tx: ${op.vault}/${op.collection}/${op.id} expected v${op.expectedVersion}, found v${actual}`,\n )\n }\n }\n // Phase 2 — apply every op synchronously. No await between ops =\n // no interleave window.\n for (const op of ops) {\n if (op.type === 'put') {\n if (!op.envelope) {\n throw new Error(`tx: put op for ${op.id} is missing envelope`)\n }\n getCollection(op.vault, op.collection).set(op.id, op.envelope)\n } else {\n store.get(op.vault)?.get(op.collection)?.delete(op.id)\n }\n }\n },\n\n /**\n * Paginate over a collection. Cursor is a numeric offset (as a string)\n * into the sorted id list — same ordering on every call so pages are\n * stable across runs.\n *\n * The default `limit` is 100. Final page returns `nextCursor: null`.\n */\n async listPage(vault, collection, cursor, limit = 100) {\n const coll = store.get(vault)?.get(collection)\n if (!coll) return { items: [], nextCursor: null }\n\n // Sorted ids for stable pagination — Map preserves insertion order\n // but tests rely on lexicographic order across different inserts.\n const ids = [...coll.keys()].sort()\n const start = cursor ? parseInt(cursor, 10) : 0\n const end = Math.min(start + limit, ids.length)\n\n const items: Array<{ id: string; envelope: EncryptedEnvelope }> = []\n for (let i = start; i < end; i++) {\n const id = ids[i]!\n const envelope = coll.get(id)\n if (envelope) items.push({ id, envelope })\n }\n\n return {\n items,\n nextCursor: end < ids.length ? String(end) : null,\n }\n },\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * **@noy-db/to-memory** — in-memory store for NOYDB (testing and development).\n *\n * Backed by nested `Map` objects: `vault → collection → id → envelope`.\n * Data is lost when the process exits — this store is intentionally\n * non-persistent.\n *\n * ## When to use\n *\n * - **Unit tests** — fast, zero I/O, works in any environment.\n * - **In-memory caching layer** — pair with `routeStore` to keep a hot\n * copy of frequently-read collections in memory while persisting to\n * a durable backend.\n * - **REPL / prototyping** — explore the NOYDB API without setting up\n * a backend.\n *\n * ## Capabilities\n *\n * | Capability | Value |\n * |---|---|\n * | `casAtomic` | `true` — Map operations are synchronous and inherently atomic |\n * | `txAtomic` | `true` — multi-record `tx()` applies every op in a single synchronous burst |\n * | `listVaults` | ✓ — iterates outer Map keys |\n * | `listPage` | ✓ — cursor-based pagination over sorted id list |\n * | `ping` | ✓ — always returns `true` |\n *\n * @packageDocumentation\n */\n\nimport type { NoydbStore, EncryptedEnvelope, VaultSnapshot, TxOp } from '@noy-db/hub/adapter'\nimport { ConflictError } from '@noy-db/hub/adapter'\n\n/**\n * Create an in-memory adapter backed by nested Maps.\n * No persistence — data is lost when the process exits.\n * Intended for testing and development.\n */\nexport function memory(opts: { clockUncertainty?: number } = {}): NoydbStore {\n // vault -> collection -> id -> envelope\n const store = new Map<string, Map<string, Map<string, EncryptedEnvelope>>>()\n\n // Monotonic store clock — a single-process counter is perfectly ordered.\n // `clockUncertainty` (ε) widens the returned interval to exercise the\n // commit-wait path in deferred numbering; default 0 (exact).\n const epsilon = opts.clockUncertainty ?? 0\n let clock = 0\n\n function getCollection(vault: string, collection: string): Map<string, EncryptedEnvelope> {\n let comp = store.get(vault)\n if (!comp) {\n comp = new Map()\n store.set(vault, comp)\n }\n let coll = comp.get(collection)\n if (!coll) {\n coll = new Map()\n comp.set(collection, coll)\n }\n return coll\n }\n\n return {\n name: 'memory',\n\n // #321 — memory's synchronous Map ops make the expectedVersion check +\n // write atomic, so it can back `vault.sequence()`. Without this the\n // JSDoc's `casAtomic: true` promise was undefined at runtime and\n // `sequence().next()` threw SequenceOfflineError.\n capabilities: {\n casAtomic: true,\n serverWriteTime: true,\n auth: { kind: 'none', required: false, flow: 'static' },\n },\n\n // #322-sibling — authoritative store clock for deferred numbering. A\n // single-process counter is perfectly monotonic; ε widens the interval.\n async getStoreTime() {\n const now = ++clock\n return { earliest: now - epsilon, latest: now + epsilon }\n },\n\n async get(vault, collection, id) {\n return store.get(vault)?.get(collection)?.get(id) ?? null\n },\n\n async put(vault, collection, id, envelope, expectedVersion) {\n const coll = getCollection(vault, collection)\n const existing = coll.get(id)\n\n if (expectedVersion !== undefined && existing) {\n if (existing._v !== expectedVersion) {\n throw new ConflictError(existing._v, `Version conflict: expected ${expectedVersion}, found ${existing._v}`)\n }\n }\n\n coll.set(id, envelope)\n },\n\n async delete(vault, collection, id) {\n store.get(vault)?.get(collection)?.delete(id)\n },\n\n async list(vault, collection) {\n const coll = store.get(vault)?.get(collection)\n return coll ? [...coll.keys()] : []\n },\n\n async loadAll(vault) {\n const comp = store.get(vault)\n const snapshot: VaultSnapshot = {}\n if (comp) {\n for (const [collName, coll] of comp) {\n if (collName.startsWith('_')) continue\n const records: Record<string, EncryptedEnvelope> = {}\n for (const [id, envelope] of coll) {\n records[id] = envelope\n }\n snapshot[collName] = records\n }\n }\n return snapshot\n },\n\n async saveAll(vault, data) {\n const comp = store.get(vault)\n if (comp) {\n for (const key of [...comp.keys()]) {\n if (!key.startsWith('_')) {\n comp.delete(key)\n }\n }\n }\n\n for (const [collName, records] of Object.entries(data)) {\n const coll = getCollection(vault, collName)\n for (const [id, envelope] of Object.entries(records)) {\n coll.set(id, envelope)\n }\n }\n },\n\n async ping() {\n return true\n },\n\n /**\n * Enumerate every top-level vault held by this in-memory\n * store. Used by `Noydb.listAccessibleVaults()`\n * to get the universe of compartments before filtering down to\n * the ones the calling principal can unwrap.\n *\n * Returns the outer Map's keys directly — O(compartments) and\n * cheap. The result is intentionally unsorted; consumers that\n * want a stable order should sort themselves.\n */\n async listVaults() {\n return [...store.keys()]\n },\n\n /**\n * Multi-record atomic transaction.\n *\n * Validates every op's `expectedVersion` against the current Map\n * state, throws `ConflictError` on the first mismatch (nothing\n * written), then applies every put/delete in one synchronous burst\n * — the Map mutations are single-threaded in the JS event loop so\n * no concurrent writer can interleave. Truly atomic.\n */\n async tx(ops: readonly TxOp[]) {\n // Phase 1 — validate every expectedVersion against current state.\n // We read the state ONCE up front; subsequent ops that target the\n // same (vault, coll, id) see the same snapshot, matching the\n // atomicity guarantee callers expect from a storage-layer tx.\n for (const op of ops) {\n if (op.expectedVersion === undefined) continue\n const existing = store.get(op.vault)?.get(op.collection)?.get(op.id)\n const actual = existing?._v ?? 0\n if (actual !== op.expectedVersion) {\n throw new ConflictError(\n actual,\n `tx: ${op.vault}/${op.collection}/${op.id} expected v${op.expectedVersion}, found v${actual}`,\n )\n }\n }\n // Phase 2 — apply every op synchronously. No await between ops =\n // no interleave window.\n for (const op of ops) {\n if (op.type === 'put') {\n if (!op.envelope) {\n throw new Error(`tx: put op for ${op.id} is missing envelope`)\n }\n getCollection(op.vault, op.collection).set(op.id, op.envelope)\n } else {\n store.get(op.vault)?.get(op.collection)?.delete(op.id)\n }\n }\n },\n\n /**\n * Paginate over a collection. Cursor is a numeric offset (as a string)\n * into the sorted id list — same ordering on every call so pages are\n * stable across runs.\n *\n * The default `limit` is 100. Final page returns `nextCursor: null`.\n */\n async listPage(vault, collection, cursor, limit = 100) {\n const coll = store.get(vault)?.get(collection)\n if (!coll) return { items: [], nextCursor: null }\n\n // Sorted ids for stable pagination — Map preserves insertion order\n // but tests rely on lexicographic order across different inserts.\n const ids = [...coll.keys()].sort()\n const start = cursor ? parseInt(cursor, 10) : 0\n const end = Math.min(start + limit, ids.length)\n\n const items: Array<{ id: string; envelope: EncryptedEnvelope }> = []\n for (let i = start; i < end; i++) {\n const id = ids[i]!\n const envelope = coll.get(id)\n if (envelope) items.push({ id, envelope })\n }\n\n return {\n items,\n nextCursor: end < ids.length ? String(end) : null,\n }\n },\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noy-db/to-memory",
3
- "version": "0.2.0-pre.30",
3
+ "version": "0.2.0-pre.31",
4
4
  "description": "In-memory adapter for noy-db — ideal for testing, development, and ephemeral workloads",
5
5
  "license": "MIT",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
@@ -17,17 +17,10 @@
17
17
  "sideEffects": false,
18
18
  "exports": {
19
19
  ".": {
20
- "import": {
21
- "types": "./dist/index.d.ts",
22
- "default": "./dist/index.js"
23
- },
24
- "require": {
25
- "types": "./dist/index.d.cts",
26
- "default": "./dist/index.cjs"
27
- }
20
+ "types": "./dist/index.d.ts",
21
+ "default": "./dist/index.js"
28
22
  }
29
23
  },
30
- "main": "./dist/index.cjs",
31
24
  "module": "./dist/index.js",
32
25
  "types": "./dist/index.d.ts",
33
26
  "files": [
@@ -36,14 +29,14 @@
36
29
  "LICENSE"
37
30
  ],
38
31
  "engines": {
39
- "node": ">=18.0.0"
32
+ "node": ">=22.0.0"
40
33
  },
41
34
  "peerDependencies": {
42
- "@noy-db/hub": "0.2.0-pre.30"
35
+ "@noy-db/hub": "0.2.0-pre.31"
43
36
  },
44
37
  "devDependencies": {
45
38
  "@noy-db/test-adapter-conformance": "0.0.0",
46
- "@noy-db/hub": "0.2.0-pre.30"
39
+ "@noy-db/hub": "0.2.0-pre.31"
47
40
  },
48
41
  "keywords": [
49
42
  "noy-db",
package/dist/index.cjs DELETED
@@ -1,190 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- memory: () => memory
24
- });
25
- module.exports = __toCommonJS(index_exports);
26
- var import_hub = require("@noy-db/hub");
27
- function memory(opts = {}) {
28
- const store = /* @__PURE__ */ new Map();
29
- const epsilon = opts.clockUncertainty ?? 0;
30
- let clock = 0;
31
- function getCollection(vault, collection) {
32
- let comp = store.get(vault);
33
- if (!comp) {
34
- comp = /* @__PURE__ */ new Map();
35
- store.set(vault, comp);
36
- }
37
- let coll = comp.get(collection);
38
- if (!coll) {
39
- coll = /* @__PURE__ */ new Map();
40
- comp.set(collection, coll);
41
- }
42
- return coll;
43
- }
44
- return {
45
- name: "memory",
46
- // #321 — memory's synchronous Map ops make the expectedVersion check +
47
- // write atomic, so it can back `vault.sequence()`. Without this the
48
- // JSDoc's `casAtomic: true` promise was undefined at runtime and
49
- // `sequence().next()` threw SequenceOfflineError.
50
- capabilities: {
51
- casAtomic: true,
52
- serverWriteTime: true,
53
- auth: { kind: "none", required: false, flow: "static" }
54
- },
55
- // #322-sibling — authoritative store clock for deferred numbering. A
56
- // single-process counter is perfectly monotonic; ε widens the interval.
57
- async getStoreTime() {
58
- const now = ++clock;
59
- return { earliest: now - epsilon, latest: now + epsilon };
60
- },
61
- async get(vault, collection, id) {
62
- return store.get(vault)?.get(collection)?.get(id) ?? null;
63
- },
64
- async put(vault, collection, id, envelope, expectedVersion) {
65
- const coll = getCollection(vault, collection);
66
- const existing = coll.get(id);
67
- if (expectedVersion !== void 0 && existing) {
68
- if (existing._v !== expectedVersion) {
69
- throw new import_hub.ConflictError(existing._v, `Version conflict: expected ${expectedVersion}, found ${existing._v}`);
70
- }
71
- }
72
- coll.set(id, envelope);
73
- },
74
- async delete(vault, collection, id) {
75
- store.get(vault)?.get(collection)?.delete(id);
76
- },
77
- async list(vault, collection) {
78
- const coll = store.get(vault)?.get(collection);
79
- return coll ? [...coll.keys()] : [];
80
- },
81
- async loadAll(vault) {
82
- const comp = store.get(vault);
83
- const snapshot = {};
84
- if (comp) {
85
- for (const [collName, coll] of comp) {
86
- if (collName.startsWith("_")) continue;
87
- const records = {};
88
- for (const [id, envelope] of coll) {
89
- records[id] = envelope;
90
- }
91
- snapshot[collName] = records;
92
- }
93
- }
94
- return snapshot;
95
- },
96
- async saveAll(vault, data) {
97
- const comp = store.get(vault);
98
- if (comp) {
99
- for (const key of [...comp.keys()]) {
100
- if (!key.startsWith("_")) {
101
- comp.delete(key);
102
- }
103
- }
104
- }
105
- for (const [collName, records] of Object.entries(data)) {
106
- const coll = getCollection(vault, collName);
107
- for (const [id, envelope] of Object.entries(records)) {
108
- coll.set(id, envelope);
109
- }
110
- }
111
- },
112
- async ping() {
113
- return true;
114
- },
115
- /**
116
- * Enumerate every top-level vault held by this in-memory
117
- * store. Used by `Noydb.listAccessibleVaults()`
118
- * to get the universe of compartments before filtering down to
119
- * the ones the calling principal can unwrap.
120
- *
121
- * Returns the outer Map's keys directly — O(compartments) and
122
- * cheap. The result is intentionally unsorted; consumers that
123
- * want a stable order should sort themselves.
124
- */
125
- async listVaults() {
126
- return [...store.keys()];
127
- },
128
- /**
129
- * Multi-record atomic transaction.
130
- *
131
- * Validates every op's `expectedVersion` against the current Map
132
- * state, throws `ConflictError` on the first mismatch (nothing
133
- * written), then applies every put/delete in one synchronous burst
134
- * — the Map mutations are single-threaded in the JS event loop so
135
- * no concurrent writer can interleave. Truly atomic.
136
- */
137
- async tx(ops) {
138
- for (const op of ops) {
139
- if (op.expectedVersion === void 0) continue;
140
- const existing = store.get(op.vault)?.get(op.collection)?.get(op.id);
141
- const actual = existing?._v ?? 0;
142
- if (actual !== op.expectedVersion) {
143
- throw new import_hub.ConflictError(
144
- actual,
145
- `tx: ${op.vault}/${op.collection}/${op.id} expected v${op.expectedVersion}, found v${actual}`
146
- );
147
- }
148
- }
149
- for (const op of ops) {
150
- if (op.type === "put") {
151
- if (!op.envelope) {
152
- throw new Error(`tx: put op for ${op.id} is missing envelope`);
153
- }
154
- getCollection(op.vault, op.collection).set(op.id, op.envelope);
155
- } else {
156
- store.get(op.vault)?.get(op.collection)?.delete(op.id);
157
- }
158
- }
159
- },
160
- /**
161
- * Paginate over a collection. Cursor is a numeric offset (as a string)
162
- * into the sorted id list — same ordering on every call so pages are
163
- * stable across runs.
164
- *
165
- * The default `limit` is 100. Final page returns `nextCursor: null`.
166
- */
167
- async listPage(vault, collection, cursor, limit = 100) {
168
- const coll = store.get(vault)?.get(collection);
169
- if (!coll) return { items: [], nextCursor: null };
170
- const ids = [...coll.keys()].sort();
171
- const start = cursor ? parseInt(cursor, 10) : 0;
172
- const end = Math.min(start + limit, ids.length);
173
- const items = [];
174
- for (let i = start; i < end; i++) {
175
- const id = ids[i];
176
- const envelope = coll.get(id);
177
- if (envelope) items.push({ id, envelope });
178
- }
179
- return {
180
- items,
181
- nextCursor: end < ids.length ? String(end) : null
182
- };
183
- }
184
- };
185
- }
186
- // Annotate the CommonJS export names for ESM import in node:
187
- 0 && (module.exports = {
188
- memory
189
- });
190
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * **@noy-db/to-memory** — in-memory store for NOYDB (testing and development).\n *\n * Backed by nested `Map` objects: `vault → collection → id → envelope`.\n * Data is lost when the process exits — this store is intentionally\n * non-persistent.\n *\n * ## When to use\n *\n * - **Unit tests** — fast, zero I/O, works in any environment.\n * - **In-memory caching layer** — pair with `routeStore` to keep a hot\n * copy of frequently-read collections in memory while persisting to\n * a durable backend.\n * - **REPL / prototyping** — explore the NOYDB API without setting up\n * a backend.\n *\n * ## Capabilities\n *\n * | Capability | Value |\n * |---|---|\n * | `casAtomic` | `true` — Map operations are synchronous and inherently atomic |\n * | `txAtomic` | `true` — multi-record `tx()` applies every op in a single synchronous burst |\n * | `listVaults` | ✓ — iterates outer Map keys |\n * | `listPage` | ✓ — cursor-based pagination over sorted id list |\n * | `ping` | ✓ — always returns `true` |\n *\n * @packageDocumentation\n */\n\nimport type { NoydbStore, EncryptedEnvelope, VaultSnapshot, TxOp } from '@noy-db/hub'\nimport { ConflictError } from '@noy-db/hub'\n\n/**\n * Create an in-memory adapter backed by nested Maps.\n * No persistence — data is lost when the process exits.\n * Intended for testing and development.\n */\nexport function memory(opts: { clockUncertainty?: number } = {}): NoydbStore {\n // vault -> collection -> id -> envelope\n const store = new Map<string, Map<string, Map<string, EncryptedEnvelope>>>()\n\n // Monotonic store clock — a single-process counter is perfectly ordered.\n // `clockUncertainty` (ε) widens the returned interval to exercise the\n // commit-wait path in deferred numbering; default 0 (exact).\n const epsilon = opts.clockUncertainty ?? 0\n let clock = 0\n\n function getCollection(vault: string, collection: string): Map<string, EncryptedEnvelope> {\n let comp = store.get(vault)\n if (!comp) {\n comp = new Map()\n store.set(vault, comp)\n }\n let coll = comp.get(collection)\n if (!coll) {\n coll = new Map()\n comp.set(collection, coll)\n }\n return coll\n }\n\n return {\n name: 'memory',\n\n // #321 — memory's synchronous Map ops make the expectedVersion check +\n // write atomic, so it can back `vault.sequence()`. Without this the\n // JSDoc's `casAtomic: true` promise was undefined at runtime and\n // `sequence().next()` threw SequenceOfflineError.\n capabilities: {\n casAtomic: true,\n serverWriteTime: true,\n auth: { kind: 'none', required: false, flow: 'static' },\n },\n\n // #322-sibling — authoritative store clock for deferred numbering. A\n // single-process counter is perfectly monotonic; ε widens the interval.\n async getStoreTime() {\n const now = ++clock\n return { earliest: now - epsilon, latest: now + epsilon }\n },\n\n async get(vault, collection, id) {\n return store.get(vault)?.get(collection)?.get(id) ?? null\n },\n\n async put(vault, collection, id, envelope, expectedVersion) {\n const coll = getCollection(vault, collection)\n const existing = coll.get(id)\n\n if (expectedVersion !== undefined && existing) {\n if (existing._v !== expectedVersion) {\n throw new ConflictError(existing._v, `Version conflict: expected ${expectedVersion}, found ${existing._v}`)\n }\n }\n\n coll.set(id, envelope)\n },\n\n async delete(vault, collection, id) {\n store.get(vault)?.get(collection)?.delete(id)\n },\n\n async list(vault, collection) {\n const coll = store.get(vault)?.get(collection)\n return coll ? [...coll.keys()] : []\n },\n\n async loadAll(vault) {\n const comp = store.get(vault)\n const snapshot: VaultSnapshot = {}\n if (comp) {\n for (const [collName, coll] of comp) {\n if (collName.startsWith('_')) continue\n const records: Record<string, EncryptedEnvelope> = {}\n for (const [id, envelope] of coll) {\n records[id] = envelope\n }\n snapshot[collName] = records\n }\n }\n return snapshot\n },\n\n async saveAll(vault, data) {\n const comp = store.get(vault)\n if (comp) {\n for (const key of [...comp.keys()]) {\n if (!key.startsWith('_')) {\n comp.delete(key)\n }\n }\n }\n\n for (const [collName, records] of Object.entries(data)) {\n const coll = getCollection(vault, collName)\n for (const [id, envelope] of Object.entries(records)) {\n coll.set(id, envelope)\n }\n }\n },\n\n async ping() {\n return true\n },\n\n /**\n * Enumerate every top-level vault held by this in-memory\n * store. Used by `Noydb.listAccessibleVaults()`\n * to get the universe of compartments before filtering down to\n * the ones the calling principal can unwrap.\n *\n * Returns the outer Map's keys directly — O(compartments) and\n * cheap. The result is intentionally unsorted; consumers that\n * want a stable order should sort themselves.\n */\n async listVaults() {\n return [...store.keys()]\n },\n\n /**\n * Multi-record atomic transaction.\n *\n * Validates every op's `expectedVersion` against the current Map\n * state, throws `ConflictError` on the first mismatch (nothing\n * written), then applies every put/delete in one synchronous burst\n * — the Map mutations are single-threaded in the JS event loop so\n * no concurrent writer can interleave. Truly atomic.\n */\n async tx(ops: readonly TxOp[]) {\n // Phase 1 — validate every expectedVersion against current state.\n // We read the state ONCE up front; subsequent ops that target the\n // same (vault, coll, id) see the same snapshot, matching the\n // atomicity guarantee callers expect from a storage-layer tx.\n for (const op of ops) {\n if (op.expectedVersion === undefined) continue\n const existing = store.get(op.vault)?.get(op.collection)?.get(op.id)\n const actual = existing?._v ?? 0\n if (actual !== op.expectedVersion) {\n throw new ConflictError(\n actual,\n `tx: ${op.vault}/${op.collection}/${op.id} expected v${op.expectedVersion}, found v${actual}`,\n )\n }\n }\n // Phase 2 — apply every op synchronously. No await between ops =\n // no interleave window.\n for (const op of ops) {\n if (op.type === 'put') {\n if (!op.envelope) {\n throw new Error(`tx: put op for ${op.id} is missing envelope`)\n }\n getCollection(op.vault, op.collection).set(op.id, op.envelope)\n } else {\n store.get(op.vault)?.get(op.collection)?.delete(op.id)\n }\n }\n },\n\n /**\n * Paginate over a collection. Cursor is a numeric offset (as a string)\n * into the sorted id list — same ordering on every call so pages are\n * stable across runs.\n *\n * The default `limit` is 100. Final page returns `nextCursor: null`.\n */\n async listPage(vault, collection, cursor, limit = 100) {\n const coll = store.get(vault)?.get(collection)\n if (!coll) return { items: [], nextCursor: null }\n\n // Sorted ids for stable pagination — Map preserves insertion order\n // but tests rely on lexicographic order across different inserts.\n const ids = [...coll.keys()].sort()\n const start = cursor ? parseInt(cursor, 10) : 0\n const end = Math.min(start + limit, ids.length)\n\n const items: Array<{ id: string; envelope: EncryptedEnvelope }> = []\n for (let i = start; i < end; i++) {\n const id = ids[i]!\n const envelope = coll.get(id)\n if (envelope) items.push({ id, envelope })\n }\n\n return {\n items,\n nextCursor: end < ids.length ? String(end) : null,\n }\n },\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts DELETED
@@ -1,41 +0,0 @@
1
- import { NoydbStore } from '@noy-db/hub';
2
-
3
- /**
4
- * **@noy-db/to-memory** — in-memory store for NOYDB (testing and development).
5
- *
6
- * Backed by nested `Map` objects: `vault → collection → id → envelope`.
7
- * Data is lost when the process exits — this store is intentionally
8
- * non-persistent.
9
- *
10
- * ## When to use
11
- *
12
- * - **Unit tests** — fast, zero I/O, works in any environment.
13
- * - **In-memory caching layer** — pair with `routeStore` to keep a hot
14
- * copy of frequently-read collections in memory while persisting to
15
- * a durable backend.
16
- * - **REPL / prototyping** — explore the NOYDB API without setting up
17
- * a backend.
18
- *
19
- * ## Capabilities
20
- *
21
- * | Capability | Value |
22
- * |---|---|
23
- * | `casAtomic` | `true` — Map operations are synchronous and inherently atomic |
24
- * | `txAtomic` | `true` — multi-record `tx()` applies every op in a single synchronous burst |
25
- * | `listVaults` | ✓ — iterates outer Map keys |
26
- * | `listPage` | ✓ — cursor-based pagination over sorted id list |
27
- * | `ping` | ✓ — always returns `true` |
28
- *
29
- * @packageDocumentation
30
- */
31
-
32
- /**
33
- * Create an in-memory adapter backed by nested Maps.
34
- * No persistence — data is lost when the process exits.
35
- * Intended for testing and development.
36
- */
37
- declare function memory(opts?: {
38
- clockUncertainty?: number;
39
- }): NoydbStore;
40
-
41
- export { memory };