nedb-engine 7.2.0 → 8.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/README.md CHANGED
@@ -5,7 +5,8 @@
5
5
  **Content-addressed Merkle DAG · Hash-chained · Time-traveling · Bi-temporal · Causally-provable embedded database.**
6
6
 
7
7
  Replay-protected · idempotent · relational · filterable · sortable · searchable · concurrent.
8
- One Rust core → ships to **PyPI** and **npm** from a single source.
8
+ One Rust core → ships to **PyPI**, **npm** and **crates.io** from a single source,
9
+ at the same version on the same tag.
9
10
 
10
11
  [![PyPI](https://img.shields.io/pypi/v/nedb-engine?label=PyPI&color=6366f1)](https://pypi.org/project/nedb-engine/)
11
12
  [![crates.io](https://img.shields.io/crates/v/nedb-engine?label=crates.io&color=f97316)](https://crates.io/crates/nedb-engine)
@@ -40,15 +41,31 @@ NEDB's PostgreSQL endpoint answers `psql`, SQLAlchemy Core **and** ORM, asyncpg
40
41
  node-postgres against a live store. It used to get there by *translating* SQL into
41
42
  NQL, and a translation can only reach as far as the target language's shape.
42
43
 
43
- **neSQL is the name for what replaced that.** PostgreSQL's real grammar (`gram.y`,
44
- 19,513 lines, 492 keywords, vendored from 17.4 at
45
- [`vendor/postgresql/`](vendor/postgresql/) with its licence intact), extended with
46
- NEDB's temporal and causal clauses. **Two front-ends, one plan. NQL folded in, not
47
- deleted.**
44
+ **neSQL is the name for what replaced that**, and it is exactly as much of an
45
+ addition as it sounds like:
48
46
 
49
- **neQL** is the name for the pair — NQL *and* PostgreSQL SQL, one language with two
50
- halves. Which half a statement is read as is decided **structurally**, not guessed:
51
- NQL statements begin `FROM`, and PostgreSQL has no statement form that begins with
47
+ ```
48
+ neSQL = PostgreSQL SQL · inherited whole, not reimplemented
49
+ + NEDB SQL · what a permanent, hash-chained store can answer
50
+ ```
51
+
52
+ **We inherit, then we gain.** The left-hand side is PostgreSQL's real grammar —
53
+ `gram.y`, 19,513 lines and 492 keywords, vendored from 17.4 at
54
+ [`vendor/postgresql/`](vendor/postgresql/) with its licence intact. Not a subset,
55
+ not a lookalike: the definition every other tool in the world was built against.
56
+ If it is valid PostgreSQL and the evaluator can parse it, it runs.
57
+
58
+ The right-hand side is what NEDB adds because it can — `AS OF SYSTEM TIME`,
59
+ `VALID AS OF`, `SEARCH`, `TRACE`, `TRAVERSE`. These are clauses PostgreSQL has no
60
+ spelling for, because a store that overwrites has nothing to point them at. They
61
+ are additions **to** the vendored grammar, never deviations **from** it.
62
+
63
+ So neSQL is not a dialect of SQL that you have to learn around. It is PostgreSQL
64
+ plus the questions a database with permanent memory can be asked. Anything you
65
+ already write keeps working; the new clauses are there when you need them.
66
+
67
+ Which half a statement is read as is decided **structurally**, never guessed:
68
+ NQL's own form begins `FROM`, PostgreSQL has no statement form that begins with
52
69
  `FROM`, so the leading keyword partitions the two vocabularies rather than hinting
53
70
  at them. A first word in neither is refused *naming both*.
54
71
 
@@ -67,7 +84,7 @@ published. The engine you actually install is `nedb-engine`. The
67
84
  [neSQL repository](https://github.com/Eth-Interchained/neSQL) holds the language —
68
85
  both halves of the grammar and the CLI's source, side by side.
69
86
 
70
- ### `nesql` — the CLI, and it speaks neQL
87
+ ### `nesql` — the CLI, and it speaks neSQL
71
88
 
72
89
  Ships in this release, no flag. `nesql` opens a store directly — no daemon, no
73
90
  port — and answers both halves of the language through **one** `query` command:
@@ -202,7 +219,7 @@ the bar for changing that written down.
202
219
 
203
220
  ---
204
221
 
205
- ## New in 3.3.0 — the query language grew up
222
+ ## The query language grew up · *landed in 3.3.0*
206
223
 
207
224
  `WHERE` was six operators wide (`= != > < >= <=`) joined by an implicit `AND`.
208
225
  It now takes a full boolean expression, in **both** engines, and the clauses
@@ -348,11 +365,21 @@ Provenance is selectable like any other column:
348
365
  SELECT _id, _hash, _seq FROM audit ORDER BY _seq;
349
366
  ```
350
367
 
351
- **This is not "NEDB speaks SQL", and the endpoint is careful to say so.** It is
352
- a documented subset of `SELECT` **translated** to NQL — and that word is doing
353
- all the work in this sentence. Every refusal below traces to the same cause:
354
- NQL is the engine's native language, so SQL has to be rewritten into it, and a
355
- rewrite can only ever reach as far as the target language's shape.
368
+ **NEDB speaks SQL. That sentence used to carry a caveat, and no longer does.**
369
+
370
+ For most of this project's life it was true that the endpoint served a
371
+ documented *subset* of `SELECT` **translated** into NQL and every refusal in
372
+ the table below traced to that one cause: a rewrite can only reach as far as the
373
+ target language's shape, and NQL's shape is single-collection with no projection.
374
+
375
+ That translator no longer answers `SELECT`. The evaluator does, for every
376
+ statement it can parse, with nothing to enable. It is kept for writes and for
377
+ anything outside the `SELECT` grammar, which is why a statement it cannot parse
378
+ still gets an answer rather than an error.
379
+
380
+ The table is preserved below as history, because the distinction between "the
381
+ engine could never do this" and "the translator could not reach it" is the whole
382
+ story of how neSQL happened — and only one of those was ever true.
356
383
 
357
384
  | Expressible in NQL | Not expressible there, and why | the evaluator |
358
385
  | --- | --- | --- |
@@ -372,7 +399,7 @@ NEDB is append-only *so that history cannot be discarded* — that is the produc
372
399
  not a gap — and DDL is refused because collections are created by the first write
373
400
  to them. Those answers do not change.
374
401
 
375
- ### Every other row on that table was a translation artefact — and one flag removes them
402
+ ### Every other row on that table was a translation artefact — and they are gone
376
403
 
377
404
  > ### 🆕 [**neSQL**](https://github.com/Eth-Interchained/neSQL) — PostgreSQL's grammar, NEDB's memory
378
405
  >
@@ -521,7 +548,7 @@ SQL `UPDATE`, the prior value is still readable at its original sequence.
521
548
 
522
549
  ---
523
550
 
524
- ## New in 3.2.0 — wrap the databases you already run
551
+ ## Wrap the databases you already run · *landed in 3.2.0*
525
552
 
526
553
  NEDB adds **tamper-evident causal provenance to a database you already have**, in one line, without
527
554
  rip-and-replace. Five adapters, one surface:
@@ -616,7 +643,7 @@ permissive, and the two Python runtime dependencies are BSD and Apache.
616
643
  **Versions 3.0.0 – 3.3.1 stay MIT, irrevocably.** If you already have NEDB at 3.3.1 or earlier, your
617
644
  rights in that copy are untouched. This applies to 4.0.0 and later only.
618
645
 
619
- ### Also in 3.2.0
646
+ ### Also landed in 3.2.0
620
647
 
621
648
  - **A durability defect that pinned every embedded database.** The background flush ticker held a
622
649
  strong `Arc<Db>` in an unconditional loop, so the handle was never dropped: the exclusive data-dir
@@ -636,7 +663,7 @@ rights in that copy are untouched. This applies to 4.0.0 and later only.
636
663
 
637
664
  ---
638
665
 
639
- ## Earlier 2.8.6 durability & recovery
666
+ ## Durability & recovery · *landed in 2.8.6*
640
667
 
641
668
  Three defects found by killing a real engine at every persistence boundary and by filling a real
642
669
  filesystem to zero free blocks. **If you are on 2.8.5 or earlier, upgrade.**
@@ -681,11 +708,11 @@ value. Ten writes drain as nine records. Changing the convention would break exi
681
708
 
682
709
  ---
683
710
 
684
- ## NEDB v3.2.0 Production Stable
711
+ ## Distributionthree aligned distributions, one tag
685
712
 
686
- **Current stable: 3.2.0** — NEDB ships as **three version-aligned distributions** on one tag — `nedb-engine` (flagship), `crypto-database` (verifiable v2/v3 DAG), and `aof-db` (fast append-only) — across npm / PyPI / crates.io with native addons for **macOS (arm64 + x86_64), Linux (x86_64 + aarch64, glibc + musl) and Windows x86_64** (see [**Releasing**](#releasing) below). All native wheels (Linux + Windows on GitHub Actions; macOS on Codemagic M2 Mac Minis) **plus** the universal pure-Python wheel ship from a single `v*` tag, with the `nedbd-v2` binary bundled inside `pip install nedb-engine`.
713
+ NEDB ships as **three version-aligned distributions** on one tag — `nedb-engine` (flagship), `crypto-database` (verifiable v2/v3 DAG), and `aof-db` (fast append-only) — across npm / PyPI / crates.io with native addons for **macOS (arm64 + x86_64), Linux (x86_64 + aarch64, glibc + musl) and Windows x86_64** (see [**Releasing**](#releasing) below). All native wheels (Linux + Windows on GitHub Actions; macOS on Codemagic M2 Mac Minis) **plus** the universal pure-Python wheel ship from a single `v*` tag, with the `nedbd-v2` binary bundled inside `pip install nedb-engine`.
687
714
 
688
- ### New in 2.8.0 Cast: the database understands English
715
+ ### Cast — the database understands English · *landed in 2.8.0*
689
716
 
690
717
  `POST /v1/databases/<name>/cast` turns a short English prompt into NQL, using a **3.33M-parameter model that runs locally on CPU**. No API key, no network call, no per-token bill.
691
718
 
@@ -728,9 +755,9 @@ nedbd --dag --data ./data
728
755
  NEDBD_DAG=1 NEDB_TMK=<32-byte-hex> nedbd --data ./data
729
756
 
730
757
  curl http://127.0.0.1:7070/health
731
- # {"ok":true,"version":"3.2.0","service":"nedbd","engine":"dag","startup_ready":true,"encrypted":true}
758
+ # {"ok":true,"version":"7.2.0","service":"nedbd","engine":"dag","startup_ready":true,"encrypted":true}
732
759
 
733
- # Tail the live event stream (new in v2.2.31)
760
+ # Tail the live event stream (since 2.2.31)
734
761
  curl http://127.0.0.1:7070/events
735
762
  # event: scan data: {"objects":730000,"of":1310703,"rate":21043,"eta_s":28}
736
763
  # event: ready data: {"seq":1310703,"head":"b2:9c14e07a…"}
@@ -754,7 +781,9 @@ curl http://127.0.0.1:7070/events
754
781
 
755
782
  **v1 AOF engine is still shipped and unchanged** — `nedbd` (no flag) runs v1.
756
783
 
757
- **Production status:** [vision.interchained.org](https://vision.interchained.org) is live on v2.2.31 **1,310,703 sequences** indexed in the Vision database, AES-256-GCM encrypted at rest, at block height **620,989**.
784
+ **Production status:** [vision.interchained.org](https://vision.interchained.org) is live — verified reachable 15 Sep 2026.
785
+
786
+ The deployment figures below are a **dated snapshot**, not a live readout: **1,310,703 sequences** indexed, AES-256-GCM encrypted at rest, block height **620,989**, measured on engine **v2.2.31**. The engine version a deployment runs is not exposed on its public surface, so treat the version here as the one those numbers were taken on rather than as what is running today.
758
787
 
759
788
  ---
760
789
 
@@ -987,7 +1016,7 @@ nedbd --dag --data ./data # v2 DAG engine (or NEDBD_DAG=1)
987
1016
  NEDBD_RESP2_PORT=6380 nedbd # also speak RESP2 (redis-cli compatible)
988
1017
  nedbd --log-level 2 # 0=errors 1=requests 2=deploy 3=verbose
989
1018
 
990
- # Live event stream (new in v2.2.31) — SSE: scan progress, ready, per-write head
1019
+ # Live event stream (since 2.2.31) — SSE: scan progress, ready, per-write head
991
1020
  curl http://127.0.0.1:7070/events
992
1021
  ```
993
1022
 
@@ -995,7 +1024,7 @@ curl http://127.0.0.1:7070/events
995
1024
 
996
1025
  Alongside the daemon, `cargo install nedb-engine` ships **`nedb-cli`** — operate on a store directory offline (`head`/`status`/`verify`/`get`/`scan`/`flush`/`repair`/`export`) — and **`nedb-inspector`**, a deterministic checker that warns when a durable open lacks flush-on-exit wiring. Full reference: [**docs/CLI.md**](docs/CLI.md).
997
1026
 
998
- ### Startup modes (v2.2.31)
1027
+ ### Startup modes
999
1028
 
1000
1029
  - **Warm start** — every restart after the first open reads the `MANIFEST` file and restores `seq` + Merkle `head` in **O(1)**. No scan, no replay, independent of dataset size. Boots in milliseconds.
1001
1030
  - **Cold start** — first open of an existing dataset spawns the integrity scan in a background thread *and accepts connections immediately*. Reads serve instantly from the content-addressed DAG; writes return `HTTP 503 startup in progress` until the `startup_ready` gate flips. Progress (objects, rate, ETA) streams over `GET /events`.
@@ -1023,7 +1052,7 @@ curl -X POST :7070/v1/databases -d '{
1023
1052
  "links": [["users:u1","buys","orders:o1"]]
1024
1053
  }}'
1025
1054
 
1026
- # Query — the endpoint speaks neQL: SQL *or* NQL, routed on the first keyword
1055
+ # Query — the endpoint speaks neSQL: SQL *or* NQL, routed on the first keyword
1027
1056
  curl -X POST :7070/v1/databases/shop/query \
1028
1057
  -d '{"nql":"SELECT name FROM users WHERE status = '"'"'active'"'"' ORDER BY name"}'
1029
1058
  # → {"rows":[{"name":"Alice"}],"count":1,"dialect":"sql", ...}
@@ -1034,7 +1063,7 @@ curl -X POST :7070/v1/databases/shop/query \
1034
1063
 
1035
1064
 
1036
1065
  **The field is still called `nql`, and its contents no longer have to be.** This
1037
- endpoint accepts **neQL** — NQL *or* PostgreSQL SQL — and answers with the
1066
+ endpoint accepts **neSQL** — NQL *or* PostgreSQL SQL — and answers with the
1038
1067
  `dialect` it chose. The name is unchanged because every existing HTTP client
1039
1068
  sends it; renaming would break them to gain nothing. Old NQL clients are
1040
1069
  unaffected.
@@ -1046,7 +1075,7 @@ refused *naming both* — never handed to whichever parser seems likelier.
1046
1075
 
1047
1076
  ```bash
1048
1077
  curl -X POST :7070/v1/databases/shop/query -d '{"nql":"GRANT ALL ON users"}'
1049
- # → 400 "GRANT" does not begin a statement in either half of neQL
1078
+ # → 400 "GRANT" does not begin a statement in either half of neSQL
1050
1079
  # NQL statements begin with: FROM
1051
1080
  # SQL statements begin with: SELECT, INSERT, UPDATE, ...
1052
1081
  ```
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.0.0",
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",