nedb-engine 7.2.0 → 8.8.8

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/index.d.ts CHANGED
@@ -1,64 +1,64 @@
1
- // nedb-engine — public type surface.
2
- //
3
- // Runtime behavior (durable-mode auto-flush-on-exit) is added by the wrapper in
4
- // index.js; the type surface is exactly the generated native binding's.
5
- export * from './native';
6
-
7
- // ── wrap adapter family (wrap/*.js) ─────────────────────────────────────────
8
-
9
- /** Options accepted by every wrap_* constructor. */
10
- export interface WrapOptions {
11
- /** Logical database name (default "default"). */
12
- dbName?: string;
13
- /** HTTP nedbd server (v1 AOF, `--dag` v2, `--dag-v3` v3). Overrides embedded DAG. */
14
- nedbdUrl?: string;
15
- /** Bearer token for nedbd (NEDBD_TOKEN on the server). */
16
- nedbdToken?: string;
17
- /** Durable DAG store directory (embedded mode). */
18
- dagPath?: string;
19
- /** 64-hex TMK → AES-256-GCM at-rest encryption (embedded DAG mode). */
20
- dagTmk?: string;
21
- /** Explicit NedbCore class (testing / custom builds). */
22
- native?: unknown;
23
- }
24
-
25
- /** The `.nedb` attribute — full NEDB layer-2 API. */
26
- export interface NedbSurface {
27
- register(pattern: string, collection: string, opts?: {
28
- idExtractor?: (key: string) => string;
29
- valueParser?: (raw: unknown) => Record<string, unknown>;
30
- valueType?: 'string' | 'hash' | 'json';
31
- }): NedbSurface;
32
- backfill(opts?: { pattern?: string; collection?: string; batchSize?: number }): number;
33
- shadowWrites: boolean;
34
- readonly engineKind: 'dag-embedded' | 'nedbd-http' | 'aof-embedded';
35
-
36
- put(coll: string, id: string, doc: Record<string, unknown>): Record<string, unknown>;
37
- get(coll: string, id: string, asOf?: number): Record<string, unknown> | null;
38
- query(nql: string): Array<Record<string, unknown>>;
39
- createIndex(coll: string, field: string, kind?: string): void;
40
- delete(coll: string, id: string): void;
41
- link(frm: string, rel: string, to: string): void;
42
- unlink(frm: string, rel: string, to: string): void;
43
- neighbors(frm: string, rel: string, asOf?: number): string[];
44
- inbound(to: string, rel: string, asOf?: number): string[];
45
- verify(): boolean;
46
- readonly head: string;
47
- readonly seq: number;
48
- checkpoint(): string;
49
- /** DAG-native: latest node (null on non-DAG backends). */
50
- tip(): Record<string, unknown> | null;
51
- /** DAG-native: changefeed page, after_seq exclusive. */
52
- since(afterSeq: number | bigint, limit?: number): {
53
- nodes: Array<Record<string, unknown>>; from_seq: number; to_seq: number;
54
- head_seq: number; has_more: boolean;
55
- };
56
- /** DAG-native: replication readiness. */
57
- scanStatus(): { scan_complete: boolean; tip_seq: number; indexed_count: number; [k: string]: unknown };
58
- }
59
-
60
- export declare function wrapRedis<T extends object = object>(client: T, opts?: WrapOptions): T & { nedb: NedbSurface };
61
- export declare function wrapSqlite<T extends object = object>(conn: T, opts?: WrapOptions): T & { nedb: NedbSurface };
62
- export declare function wrapMysql<T extends object = object>(conn: T, opts?: WrapOptions): T & { nedb: NedbSurface };
63
- export declare function wrapPg<T extends object = object>(conn: T, opts?: WrapOptions): T & { nedb: NedbSurface };
64
- export declare function wrapMongo<T extends object = object>(client: T, opts?: WrapOptions): T & { nedb: NedbSurface };
1
+ // nedb-engine — public type surface.
2
+ //
3
+ // Runtime behavior (durable-mode auto-flush-on-exit) is added by the wrapper in
4
+ // index.js; the type surface is exactly the generated native binding's.
5
+ export * from './native';
6
+
7
+ // ── wrap adapter family (wrap/*.js) ─────────────────────────────────────────
8
+
9
+ /** Options accepted by every wrap_* constructor. */
10
+ export interface WrapOptions {
11
+ /** Logical database name (default "default"). */
12
+ dbName?: string;
13
+ /** HTTP nedbd server (v1 AOF, `--dag` v2, `--dag-v3` v3). Overrides embedded DAG. */
14
+ nedbdUrl?: string;
15
+ /** Bearer token for nedbd (NEDBD_TOKEN on the server). */
16
+ nedbdToken?: string;
17
+ /** Durable DAG store directory (embedded mode). */
18
+ dagPath?: string;
19
+ /** 64-hex TMK → AES-256-GCM at-rest encryption (embedded DAG mode). */
20
+ dagTmk?: string;
21
+ /** Explicit NedbCore class (testing / custom builds). */
22
+ native?: unknown;
23
+ }
24
+
25
+ /** The `.nedb` attribute — full NEDB layer-2 API. */
26
+ export interface NedbSurface {
27
+ register(pattern: string, collection: string, opts?: {
28
+ idExtractor?: (key: string) => string;
29
+ valueParser?: (raw: unknown) => Record<string, unknown>;
30
+ valueType?: 'string' | 'hash' | 'json';
31
+ }): NedbSurface;
32
+ backfill(opts?: { pattern?: string; collection?: string; batchSize?: number }): number;
33
+ shadowWrites: boolean;
34
+ readonly engineKind: 'dag-embedded' | 'nedbd-http' | 'aof-embedded';
35
+
36
+ put(coll: string, id: string, doc: Record<string, unknown>): Record<string, unknown>;
37
+ get(coll: string, id: string, asOf?: number): Record<string, unknown> | null;
38
+ query(nql: string): Array<Record<string, unknown>>;
39
+ createIndex(coll: string, field: string, kind?: string): void;
40
+ delete(coll: string, id: string): void;
41
+ link(frm: string, rel: string, to: string): void;
42
+ unlink(frm: string, rel: string, to: string): void;
43
+ neighbors(frm: string, rel: string, asOf?: number): string[];
44
+ inbound(to: string, rel: string, asOf?: number): string[];
45
+ verify(): boolean;
46
+ readonly head: string;
47
+ readonly seq: number;
48
+ checkpoint(): string;
49
+ /** DAG-native: latest node (null on non-DAG backends). */
50
+ tip(): Record<string, unknown> | null;
51
+ /** DAG-native: changefeed page, after_seq exclusive. */
52
+ since(afterSeq: number | bigint, limit?: number): {
53
+ nodes: Array<Record<string, unknown>>; from_seq: number; to_seq: number;
54
+ head_seq: number; has_more: boolean;
55
+ };
56
+ /** DAG-native: replication readiness. */
57
+ scanStatus(): { scan_complete: boolean; tip_seq: number; indexed_count: number; [k: string]: unknown };
58
+ }
59
+
60
+ export declare function wrapRedis<T extends object = object>(client: T, opts?: WrapOptions): T & { nedb: NedbSurface };
61
+ export declare function wrapSqlite<T extends object = object>(conn: T, opts?: WrapOptions): T & { nedb: NedbSurface };
62
+ export declare function wrapMysql<T extends object = object>(conn: T, opts?: WrapOptions): T & { nedb: NedbSurface };
63
+ export declare function wrapPg<T extends object = object>(conn: T, opts?: WrapOptions): T & { nedb: NedbSurface };
64
+ export declare function wrapMongo<T extends object = object>(client: T, opts?: WrapOptions): T & { nedb: NedbSurface };
package/index.js CHANGED
@@ -1,84 +1,84 @@
1
- // SPDX-FileCopyrightText: 2026 INTERCHAINED LLC
2
- // SPDX-License-Identifier: BUSL-1.1
3
- // NEDB · © 2026 INTERCHAINED LLC × Eth-Interchained × Vex (Claude Opus 5)
4
-
5
- 'use strict';
6
- // nedb-engine — durable-mode auto-flush-on-exit wrapper.
7
- //
8
- // The native addon (generated napi binding in ./native.js) exposes `NedbCore`.
9
- // A durable `NedbCore.open(path)` buffers writes in the engine's id-index WAL and
10
- // only makes them durable on `flush()`; a hard exit (Ctrl+C, `SIGTERM` from an
11
- // orchestrator, `pm2 stop`) that never runs an explicit flush would lose writes
12
- // staged since the last flush.
13
- //
14
- // We close that gap the libuv-cooperative way — `process.on('SIGINT'|'SIGTERM'
15
- // |'exit', () => db.flush())` — NOT a C-level signal handler inside the addon,
16
- // which would clobber libuv's own signal machinery. In-memory databases
17
- // (`new NedbCore()`) are never armed; there is nothing to flush.
18
- //
19
- // Escape hatch: set NEDB_NO_EXIT_FLUSH=1 to leave signal handling entirely to
20
- // the host app (it can still call `db.flush()` itself).
21
- //
22
- // © INTERCHAINED LLC × Vex (Interchained AI fleet: GLM · Claude · Opus · Fable · GPT-6)
23
- const native = require('./native.js');
24
-
25
- const Native = native.NedbCore;
26
-
27
- // The napi class defines `open` as a NON-writable, NON-configurable static, so the
28
- // 2.5.x wrapper's `NedbCore.open = …` threw ("Cannot assign to read only property")
29
- // — and CI's `napi build` was overwriting this file with the generated loader
30
- // anyway, so the published package never carried the wrapper at all. Both fixed
31
- // in 2.8.5: wrap by SUBCLASS (an own static on the subclass shadows the parent's),
32
- // build with `--js native.js` so this file survives, and gate the publish on
33
- // `NedbCore.__exitFlushWrapped` (see test/durability.test.mjs).
34
- let NedbCore = Native;
35
- if (Native && typeof Native.open === 'function' && !Native.__exitFlushWrapped) {
36
- // Durable handles opened in this process. Strong refs: a durable DB is meant to
37
- // live for the process, and we must be able to flush it on the way out.
38
- const live = new Set();
39
- let armed = false;
40
-
41
- const flushAll = () => {
42
- for (const db of live) {
43
- try {
44
- db.flush();
45
- } catch (_) {
46
- // Best-effort on shutdown — never throw out of an exit handler.
47
- }
48
- }
49
- };
50
-
51
- const arm = () => {
52
- if (armed || process.env.NEDB_NO_EXIT_FLUSH) return;
53
- armed = true;
54
- // 'exit' fires on normal termination; handlers must be synchronous, and
55
- // db.flush() is a synchronous native call — so this is safe and sufficient
56
- // for clean exits and uncaught-exception exits.
57
- process.on('exit', flushAll);
58
- // Registering a SIGINT/SIGTERM listener SUPPRESSES Node's default
59
- // termination, so once we listen we own the exit: flush, then terminate with
60
- // the conventional 128+signum status.
61
- const onSignal = (signum) => () => {
62
- flushAll();
63
- process.exit(128 + signum);
64
- };
65
- process.on('SIGINT', onSignal(2));
66
- process.on('SIGTERM', onSignal(15));
67
- };
68
-
69
- NedbCore = class NedbCore extends Native {
70
- static open(path) {
71
- const db = Native.open(path);
72
- live.add(db);
73
- arm();
74
- return db;
75
- }
76
- };
77
- // Mark so a re-require (or a wrapped re-export) never double-wraps.
78
- Object.defineProperty(NedbCore, '__exitFlushWrapped', { value: true, enumerable: false });
79
- }
80
-
81
- module.exports = { ...native, NedbCore };
82
- // Explicit named re-export so ESM `import { NedbCore } from 'nedb-engine'` (used
83
- // by the test suite) resolves the class through cjs-module-lexer.
84
- module.exports.NedbCore = NedbCore;
1
+ // SPDX-FileCopyrightText: 2026 INTERCHAINED LLC
2
+ // SPDX-License-Identifier: BUSL-1.1
3
+ // NEDB · © 2026 INTERCHAINED LLC × Eth-Interchained × Vex (Claude Opus 5)
4
+
5
+ 'use strict';
6
+ // nedb-engine — durable-mode auto-flush-on-exit wrapper.
7
+ //
8
+ // The native addon (generated napi binding in ./native.js) exposes `NedbCore`.
9
+ // A durable `NedbCore.open(path)` buffers writes in the engine's id-index WAL and
10
+ // only makes them durable on `flush()`; a hard exit (Ctrl+C, `SIGTERM` from an
11
+ // orchestrator, `pm2 stop`) that never runs an explicit flush would lose writes
12
+ // staged since the last flush.
13
+ //
14
+ // We close that gap the libuv-cooperative way — `process.on('SIGINT'|'SIGTERM'
15
+ // |'exit', () => db.flush())` — NOT a C-level signal handler inside the addon,
16
+ // which would clobber libuv's own signal machinery. In-memory databases
17
+ // (`new NedbCore()`) are never armed; there is nothing to flush.
18
+ //
19
+ // Escape hatch: set NEDB_NO_EXIT_FLUSH=1 to leave signal handling entirely to
20
+ // the host app (it can still call `db.flush()` itself).
21
+ //
22
+ // © INTERCHAINED LLC × Vex (Interchained AI fleet: GLM · Claude · Opus · Fable · GPT-6)
23
+ const native = require('./native.js');
24
+
25
+ const Native = native.NedbCore;
26
+
27
+ // The napi class defines `open` as a NON-writable, NON-configurable static, so the
28
+ // 2.5.x wrapper's `NedbCore.open = …` threw ("Cannot assign to read only property")
29
+ // — and CI's `napi build` was overwriting this file with the generated loader
30
+ // anyway, so the published package never carried the wrapper at all. Both fixed
31
+ // in 2.8.5: wrap by SUBCLASS (an own static on the subclass shadows the parent's),
32
+ // build with `--js native.js` so this file survives, and gate the publish on
33
+ // `NedbCore.__exitFlushWrapped` (see test/durability.test.mjs).
34
+ let NedbCore = Native;
35
+ if (Native && typeof Native.open === 'function' && !Native.__exitFlushWrapped) {
36
+ // Durable handles opened in this process. Strong refs: a durable DB is meant to
37
+ // live for the process, and we must be able to flush it on the way out.
38
+ const live = new Set();
39
+ let armed = false;
40
+
41
+ const flushAll = () => {
42
+ for (const db of live) {
43
+ try {
44
+ db.flush();
45
+ } catch (_) {
46
+ // Best-effort on shutdown — never throw out of an exit handler.
47
+ }
48
+ }
49
+ };
50
+
51
+ const arm = () => {
52
+ if (armed || process.env.NEDB_NO_EXIT_FLUSH) return;
53
+ armed = true;
54
+ // 'exit' fires on normal termination; handlers must be synchronous, and
55
+ // db.flush() is a synchronous native call — so this is safe and sufficient
56
+ // for clean exits and uncaught-exception exits.
57
+ process.on('exit', flushAll);
58
+ // Registering a SIGINT/SIGTERM listener SUPPRESSES Node's default
59
+ // termination, so once we listen we own the exit: flush, then terminate with
60
+ // the conventional 128+signum status.
61
+ const onSignal = (signum) => () => {
62
+ flushAll();
63
+ process.exit(128 + signum);
64
+ };
65
+ process.on('SIGINT', onSignal(2));
66
+ process.on('SIGTERM', onSignal(15));
67
+ };
68
+
69
+ NedbCore = class NedbCore extends Native {
70
+ static open(path) {
71
+ const db = Native.open(path);
72
+ live.add(db);
73
+ arm();
74
+ return db;
75
+ }
76
+ };
77
+ // Mark so a re-require (or a wrapped re-export) never double-wraps.
78
+ Object.defineProperty(NedbCore, '__exitFlushWrapped', { value: true, enumerable: false });
79
+ }
80
+
81
+ module.exports = { ...native, NedbCore };
82
+ // Explicit named re-export so ESM `import { NedbCore } from 'nedb-engine'` (used
83
+ // by the test suite) resolves the class through cjs-module-lexer.
84
+ module.exports.NedbCore = NedbCore;
package/native.d.ts CHANGED
@@ -28,7 +28,31 @@ export declare class NedbCore {
28
28
  unlink(frm: string, rel: string, to: string): void
29
29
  get(coll: string, id: string): string | null
30
30
  getAsOf(coll: string, id: string, asOf: bigint): string | null
31
+ /**
32
+ * Run **neSQL** — PostgreSQL SQL, or NQL. The parameter keeps its
33
+ * `nqlStr` name because existing callers pass it; what CHANGED is what
34
+ * it accepts.
35
+ *
36
+ * This was NQL-only, and an earlier version of this comment defended
37
+ * that as avoiding the risk of widening an existing method. Wrong twice:
38
+ * routing is STRUCTURAL and TOTAL (NQL begins `FROM`; PostgreSQL has no
39
+ * `FROM`-initial statement), so there is no ambiguity to introduce — and
40
+ * SQL is the FRONT DOOR. A binding that answered `SELECT who FROM orders`
41
+ * with "expected keyword FROM" would reproduce, one layer down, the exact
42
+ * "NEDB does not understand SQL" experience neSQL exists to end.
43
+ */
31
44
  query(nqlStr: string): Array<string>
45
+ /**
46
+ * `query()` under the language's own name. One implementation; `query`
47
+ * delegates here.
48
+ *
49
+ * Routing comes from `nedb_engine::nesql::route`, the SAME function the
50
+ * `nesql` CLI and `POST /query` use. Three front doors, one decision about
51
+ * what a statement means.
52
+ */
53
+ nesql(statement: string): Array<string>
54
+ /** Which half of neSQL a statement is written in: `"nql"` or `"sql"`. */
55
+ nesqlDialect(statement: string): string
32
56
  neighbors(frm: string, rel: string): Array<string>
33
57
  neighborsAsOf(frm: string, rel: string, asOf: bigint): Array<string>
34
58
  inbound(to: string, rel: string): Array<string>
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/nesql.js ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env node
2
+ // SPDX-FileCopyrightText: 2026 INTERCHAINED LLC
3
+ // SPDX-License-Identifier: BUSL-1.1
4
+ // NEDB · © 2026 INTERCHAINED LLC × Eth-Interchained × Vex (Claude Opus 5)
5
+
6
+ // nesql — thin platform shim that locates and spawns the prebuilt neSQL CLI
7
+ // binary for the current platform/arch.
8
+ //
9
+ // The binaries ship alongside this file in the npm package root, using the
10
+ // same naming convention as nedbd-v2 so the release workflow stages both the
11
+ // same way:
12
+ //
13
+ // Linux x64 -> nesql-linux-x64
14
+ // Windows x64 -> nesql-win-x64.exe
15
+ // macOS arm64 -> nesql-darwin-arm64
16
+ // macOS x64 -> nesql-darwin-x64
17
+ //
18
+ // # The exit code is the contract
19
+ //
20
+ // `nesql` distinguishes 0 success / 1 failure / 2 usage / 3 could-not-determine
21
+ // / 4 not found / 5 unsupported, and callers script against those. So this shim
22
+ // propagates the child's code EXACTLY and never substitutes one of its own for
23
+ // a successful spawn. `npx nesql …` has to be indistinguishable from invoking
24
+ // the binary, or the codes stop meaning anything.
25
+ //
26
+ // A shim failure — unsupported platform, missing binary — exits 5
27
+ // (unsupported), which is the CLI's own word for "this build cannot do that".
28
+ // Exiting 1 would claim the command ran and failed.
29
+
30
+ "use strict";
31
+
32
+ const { spawn } = require("child_process");
33
+ const path = require("path");
34
+ const fs = require("fs");
35
+
36
+ const SUPPORTED = {
37
+ "linux-x64": "nesql-linux-x64",
38
+ "win32-x64": "nesql-win-x64.exe",
39
+ "darwin-arm64": "nesql-darwin-arm64",
40
+ "darwin-x64": "nesql-darwin-x64",
41
+ };
42
+
43
+ function main() {
44
+ const key = `${process.platform}-${process.arch}`;
45
+ const name = SUPPORTED[key];
46
+
47
+ if (!name) {
48
+ process.stderr.write(
49
+ `nesql: unsupported platform/arch: ${key}\n` +
50
+ `Supported: ${Object.keys(SUPPORTED).join(", ")}\n` +
51
+ `Build from source instead: cargo install nesql\n`
52
+ );
53
+ process.exit(5);
54
+ }
55
+
56
+ const binPath = path.join(__dirname, name);
57
+ if (!fs.existsSync(binPath)) {
58
+ process.stderr.write(
59
+ `nesql: the prebuilt binary is missing for this platform.\n` +
60
+ ` expected: ${binPath}\n` +
61
+ ` platform: ${key}\n\n` +
62
+ `This nedb-engine install did not include it. Fixes:\n` +
63
+ ` npm install --force nedb-engine\n` +
64
+ ` cargo install nesql # builds from source, any platform\n`
65
+ );
66
+ process.exit(5);
67
+ }
68
+
69
+ const child = spawn(binPath, process.argv.slice(2), { stdio: "inherit" });
70
+
71
+ child.on("error", (err) => {
72
+ // Named rather than swallowed: a spawn failure and a non-zero exit from a
73
+ // binary that DID run are different diagnoses, and collapsing them sends
74
+ // the reader looking in the wrong place.
75
+ process.stderr.write(`nesql: failed to execute ${binPath}: ${err.message}\n`);
76
+ process.exit(5);
77
+ });
78
+
79
+ child.on("exit", (code, signal) => {
80
+ if (signal) {
81
+ // Reproduce the signal death rather than translating it to a number,
82
+ // so a Ctrl-C through npx behaves like a Ctrl-C to the binary.
83
+ process.kill(process.pid, signal);
84
+ return;
85
+ }
86
+ process.exit(code === null ? 5 : code);
87
+ });
88
+ }
89
+
90
+ main();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nedb-engine",
3
- "version": "7.2.0",
3
+ "version": "8.8.8",
4
4
  "description": "NEDB \u2014 hash-chained, time-traveling, bi-temporal embedded database with Rust native core. SQL, Redis, MongoDB adapters. Causal Write Provenance. RESP2 wire protocol.",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -14,7 +14,8 @@
14
14
  "bin": {
15
15
  "nedbd-v2": "./nedbd-v2.js",
16
16
  "nedbdv2": "./nedbd-v2.js",
17
- "nedb-inspector": "./nedb-inspector.mjs"
17
+ "nedb-inspector": "./nedb-inspector.mjs",
18
+ "nesql": "./nesql.js"
18
19
  },
19
20
  "files": [
20
21
  "index.js",
@@ -29,7 +30,9 @@
29
30
  "test/smoke.mjs",
30
31
  "test/durability.test.mjs",
31
32
  "README.md",
32
- "LICENSE"
33
+ "LICENSE",
34
+ "nesql.js",
35
+ "nesql-*"
33
36
  ],
34
37
  "license": "BUSL-1.1",
35
38
  "homepage": "https://github.com/aiassistsecure/nedb#readme",