nedb-engine 6.1.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)
@@ -31,28 +32,139 @@ One Rust core → ships to **PyPI** and **npm** from a single source.
31
32
 
32
33
  ---
33
34
 
34
- ## What's next — [neSQL](https://github.com/Eth-Interchained/neSQL)
35
+ ## [neSQL](https://github.com/Eth-Interchained/neSQL) — the language this engine speaks
35
36
 
36
- Nobody should have to learn a query language to use a database. NEDB's PostgreSQL
37
- endpoint already answers `psql`, SQLAlchemy Core **and** ORM, asyncpg and
38
- node-postgres against a live store — but it gets there by *translating* SQL into
37
+ Nobody should have to learn a query language to use a database. That sentence cost
38
+ us one.
39
+
40
+ NEDB's PostgreSQL endpoint answers `psql`, SQLAlchemy Core **and** ORM, asyncpg and
41
+ node-postgres against a live store. It used to get there by *translating* SQL into
39
42
  NQL, and a translation can only reach as far as the target language's shape.
40
43
 
41
- **[neSQL](https://github.com/Eth-Interchained/neSQL)** removes the translation.
42
- PostgreSQL's real grammar (`gram.y`, 19,513 lines, 492 keywords, vendored from
43
- 17.4 at [`vendor/postgresql/`](vendor/postgresql/) with its licence intact),
44
- extended with NEDB's temporal and causal clauses. **Two front-ends, one plan.
45
- NQL folded in, not deleted.**
44
+ **neSQL is the name for what replaced that**, and it is exactly as much of an
45
+ addition as it sounds like:
46
+
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
69
+ `FROM`, so the leading keyword partitions the two vocabularies rather than hinting
70
+ at them. A first word in neither is refused *naming both*.
71
+
72
+ This section is not a roadmap. Everything below ships in this release — the
73
+ evaluator with no flag to set, the `nesql` CLI likewise.
46
74
 
47
75
  [![neSQL on PyPI](https://img.shields.io/pypi/v/nesql?label=nesql%20·%20PyPI&color=a855f7)](https://pypi.org/project/nesql/)
48
76
  [![neSQL on crates.io](https://img.shields.io/crates/v/nesql?label=nesql%20·%20crates.io&color=a855f7)](https://crates.io/crates/nesql)
49
77
  [![neSQL on npm](https://img.shields.io/npm/v/nesql-engine?label=nesql-engine%20·%20npm&color=a855f7)](https://www.npmjs.com/package/nesql-engine)
50
78
 
51
- ### Available now, opt-in: `NEDBD_SQL_ENGINE=1`
79
+ Those three badges read **0.0.1** next to an engine at 6.1.0, and that is
80
+ deliberate rather than neglected. They are **reserved names**: each package loads,
81
+ reports the vendored PostgreSQL release, and answers `is_release() == false`,
82
+ because a package that imports cleanly and then lies is worse than one that is not
83
+ published. The engine you actually install is `nedb-engine`. The
84
+ [neSQL repository](https://github.com/Eth-Interchained/neSQL) holds the language —
85
+ both halves of the grammar and the CLI's source, side by side.
86
+
87
+ ### `nesql` — the CLI, and it speaks neSQL
88
+
89
+ Ships in this release, no flag. `nesql` opens a store directly — no daemon, no
90
+ port — and answers both halves of the language through **one** `query` command:
91
+
92
+ ```console
93
+ $ nesql --db ./store query "SELECT who, total FROM orders ORDER BY total DESC"
94
+ {"who":"globex","total":250,...}
95
+ {"who":"acme","total":100,...}
96
+ (2 rows)
97
+
98
+ $ nesql --db ./store query "FROM orders WHERE total > 150"
99
+ {"who":"globex","total":250,...}
100
+ (1 rows, 1 scanned)
101
+ ```
102
+
103
+ Same command, two dialects, routed on the leading keyword. `--nql` / `--sql`
104
+ force one when you want *that dialect's* error rather than a routing error —
105
+ `query --nql "SELECT 1"` tells you `expected keyword FROM`, which is the useful
106
+ answer when you are debugging why something was rejected.
107
+
108
+ It is built for scripts as much as for people. `--json` emits exactly one JSON
109
+ object on stdout — engine diagnostics go to stderr, so a pipe stays clean — and
110
+ the exit code carries the verdict:
111
+
112
+ | | |
113
+ | --- | --- |
114
+ | `0` | success — the thing was done, or the check ran and passed |
115
+ | `1` | failure — the operation ran and did not succeed |
116
+ | `2` | usage — the command line was not understood, or was ambiguous |
117
+ | `3` | **could not determine** — the check could not run (history pruned) |
118
+ | `4` | not found |
119
+ | `5` | unsupported — a version or format this build does not know |
120
+
121
+ **`3` is the one that matters.** A pruned history is not a corrupt one, and an
122
+ operator who cannot tell those apart will either ignore a real alarm or panic at
123
+ a routine one. `root verify` reports the stored record and the recomputation as
124
+ two independent facts and never collapses them:
125
+
126
+ ```console
127
+ $ nesql --db ./store root verify
128
+ at_seq 2
129
+ root_record valid
130
+ recomputation matches
131
+ exit 0
132
+ ```
133
+
134
+ `root_record valid` / `recomputation unavailable` with exit 3 is a pruned store
135
+ answering honestly. Only `recomputation DIFFERS` means something is wrong.
136
+
137
+ The rest of the surface: `status`, `log`, `inspect` (a collection, a document, a
138
+ sequence, or a persisted root — named by kind, because a bare `42` could be
139
+ `seq:42` or `root:42` and the CLI refuses to pick), `diff`, immutable `tag`,
140
+ `branch`, `merge` with first-class conflicts, and `grammar` / `constitution`,
141
+ which publish the command surface and the engine's guarantees with digests you
142
+ can compare across builds.
143
+
144
+ ```console
145
+ $ nesql constitution
146
+ engine 6.1.0
147
+ nesql 6.1.0
148
+ verdict compatible with gaps
149
+ nql grammar ef0f1696... (agrees — same grammar this build compiled against)
150
+ ```
52
151
 
53
- The SQL engine is in this release and it is **off by default**. Turn it on and a
54
- user collection is answered by a real SQL evaluator instead of a translation —
55
- every one of these works, and every one is refused *by name* without it:
152
+ ### One evaluator, no flag
153
+
154
+ The SQL evaluator answers **every `SELECT` it can parse** user collections
155
+ included, with nothing to turn on. `NEDBD_SQL_ENGINE` is gone; a deployment
156
+ still exporting it is told the variable is inert rather than left believing it
157
+ holds a switch.
158
+
159
+ It used to be opt-in, and the honest reason it is not any more is that the two
160
+ sides were never two correct answers. `SELECT who FROM orders` returned
161
+ `who, total, _id, _hash, _seq, _coll` on the translator, because NQL has no
162
+ projection to translate a column list into. A flag whose positions give
163
+ different answers to the same correct SQL is not a parity switch.
164
+
165
+ What did not change is the fallthrough, which was never the flag: a statement
166
+ the evaluator cannot **parse** still goes to the translator, and that is how
167
+ every write is served.
56
168
 
57
169
  ```sql
58
170
  SELECT o._id, d.name FROM orders o JOIN drivers d ON o.driver = d._id;
@@ -91,11 +203,10 @@ the other. `AS OF SYSTEM TIME`, `VALID AS OF` and `SEARCH` are **unreserved
91
203
  keywords**: a collection aliased `search`, or a column named `valid`, keeps
92
204
  working exactly as before.
93
205
 
94
- **Why it is opt-in rather than the default**, stated plainly because the reason
95
- is the interesting part. A parity harness runs the same corpus through both
96
- engines and asserts identical answers — 44 checks, in CI, and it is what earns
97
- the flag being flipped rather than a benchmark. It already found two real
98
- divergences: `SELECT *` returned its columns in a different order on each
206
+ **What earned the flag's removal**, stated plainly because the reason is the
207
+ interesting part. A parity harness runs the same corpus through both paths and
208
+ asserts identical answers — 44 checks, in CI and it is that, rather than a
209
+ benchmark, that earned it. It found two real divergences: `SELECT *` returned its columns in a different order on each
99
210
  engine, and the SQL evaluator built its column list from the **first row alone**,
100
211
  so a field only later documents carried silently did not appear at all.
101
212
 
@@ -108,7 +219,7 @@ the bar for changing that written down.
108
219
 
109
220
  ---
110
221
 
111
- ## New in 3.3.0 — the query language grew up
222
+ ## The query language grew up · *landed in 3.3.0*
112
223
 
113
224
  `WHERE` was six operators wide (`= != > < >= <=`) joined by an implicit `AND`.
114
225
  It now takes a full boolean expression, in **both** engines, and the clauses
@@ -254,13 +365,23 @@ Provenance is selectable like any other column:
254
365
  SELECT _id, _hash, _seq FROM audit ORDER BY _seq;
255
366
  ```
256
367
 
257
- **This is not "NEDB speaks SQL", and the endpoint is careful to say so.** It is
258
- a documented subset of `SELECT` **translated** to NQL — and that word is doing
259
- all the work in this sentence. Every refusal below traces to the same cause:
260
- NQL is the engine's native language, so SQL has to be rewritten into it, and a
261
- 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.
262
379
 
263
- | Supported on the default path | Refused there, with the reason | `NEDBD_SQL_ENGINE=1` |
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.
383
+
384
+ | Expressible in NQL | Not expressible there, and why | the evaluator |
264
385
  | --- | --- | --- |
265
386
  | `*`, a column list, `COUNT(*)`, `SUM`/`AVG`/`MIN`/`MAX(col)` | `JOIN` — NQL is single-collection | ✅ **works** (nested-loop + hash) |
266
387
  | `WHERE` — the whole NQL predicate surface | subqueries, `UNION`, window functions | ✅ **subqueries, `EXISTS`, `UNION`/`INTERSECT`/`EXCEPT` work**; window functions arrive with the grammar |
@@ -278,7 +399,7 @@ NEDB is append-only *so that history cannot be discarded* — that is the produc
278
399
  not a gap — and DDL is refused because collections are created by the first write
279
400
  to them. Those answers do not change.
280
401
 
281
- ### 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
282
403
 
283
404
  > ### 🆕 [**neSQL**](https://github.com/Eth-Interchained/neSQL) — PostgreSQL's grammar, NEDB's memory
284
405
  >
@@ -286,7 +407,7 @@ to them. Those answers do not change.
286
407
  > nested-loop and hash joins, subqueries, `EXISTS`, quantified comparisons, set
287
408
  > operations, `array_agg(x ORDER BY y)` and derived tables for some time — they
288
409
  > were simply unreachable *through a translator*, because the translator's
289
- > target was NQL. Set `NEDBD_SQL_ENGINE=1` and they are reachable.
410
+ > target was NQL. They are reachable now, with nothing to set.
290
411
  >
291
412
  > neSQL vendors PostgreSQL's **real grammar** — `gram.y`, 19,513 lines and 492
292
413
  > keywords, from 17.4, licence intact — and extends it with the clauses NEDB
@@ -427,7 +548,7 @@ SQL `UPDATE`, the prior value is still readable at its original sequence.
427
548
 
428
549
  ---
429
550
 
430
- ## New in 3.2.0 — wrap the databases you already run
551
+ ## Wrap the databases you already run · *landed in 3.2.0*
431
552
 
432
553
  NEDB adds **tamper-evident causal provenance to a database you already have**, in one line, without
433
554
  rip-and-replace. Five adapters, one surface:
@@ -522,7 +643,7 @@ permissive, and the two Python runtime dependencies are BSD and Apache.
522
643
  **Versions 3.0.0 – 3.3.1 stay MIT, irrevocably.** If you already have NEDB at 3.3.1 or earlier, your
523
644
  rights in that copy are untouched. This applies to 4.0.0 and later only.
524
645
 
525
- ### Also in 3.2.0
646
+ ### Also landed in 3.2.0
526
647
 
527
648
  - **A durability defect that pinned every embedded database.** The background flush ticker held a
528
649
  strong `Arc<Db>` in an unconditional loop, so the handle was never dropped: the exclusive data-dir
@@ -542,7 +663,7 @@ rights in that copy are untouched. This applies to 4.0.0 and later only.
542
663
 
543
664
  ---
544
665
 
545
- ## Earlier 2.8.6 durability & recovery
666
+ ## Durability & recovery · *landed in 2.8.6*
546
667
 
547
668
  Three defects found by killing a real engine at every persistence boundary and by filling a real
548
669
  filesystem to zero free blocks. **If you are on 2.8.5 or earlier, upgrade.**
@@ -587,11 +708,11 @@ value. Ten writes drain as nine records. Changing the convention would break exi
587
708
 
588
709
  ---
589
710
 
590
- ## NEDB v3.2.0 Production Stable
711
+ ## Distributionthree aligned distributions, one tag
591
712
 
592
- **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`.
593
714
 
594
- ### New in 2.8.0 Cast: the database understands English
715
+ ### Cast — the database understands English · *landed in 2.8.0*
595
716
 
596
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.
597
718
 
@@ -634,9 +755,9 @@ nedbd --dag --data ./data
634
755
  NEDBD_DAG=1 NEDB_TMK=<32-byte-hex> nedbd --data ./data
635
756
 
636
757
  curl http://127.0.0.1:7070/health
637
- # {"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}
638
759
 
639
- # Tail the live event stream (new in v2.2.31)
760
+ # Tail the live event stream (since 2.2.31)
640
761
  curl http://127.0.0.1:7070/events
641
762
  # event: scan data: {"objects":730000,"of":1310703,"rate":21043,"eta_s":28}
642
763
  # event: ready data: {"seq":1310703,"head":"b2:9c14e07a…"}
@@ -660,7 +781,9 @@ curl http://127.0.0.1:7070/events
660
781
 
661
782
  **v1 AOF engine is still shipped and unchanged** — `nedbd` (no flag) runs v1.
662
783
 
663
- **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.
664
787
 
665
788
  ---
666
789
 
@@ -893,7 +1016,7 @@ nedbd --dag --data ./data # v2 DAG engine (or NEDBD_DAG=1)
893
1016
  NEDBD_RESP2_PORT=6380 nedbd # also speak RESP2 (redis-cli compatible)
894
1017
  nedbd --log-level 2 # 0=errors 1=requests 2=deploy 3=verbose
895
1018
 
896
- # 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
897
1020
  curl http://127.0.0.1:7070/events
898
1021
  ```
899
1022
 
@@ -901,7 +1024,7 @@ curl http://127.0.0.1:7070/events
901
1024
 
902
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).
903
1026
 
904
- ### Startup modes (v2.2.31)
1027
+ ### Startup modes
905
1028
 
906
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.
907
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`.
@@ -929,9 +1052,38 @@ curl -X POST :7070/v1/databases -d '{
929
1052
  "links": [["users:u1","buys","orders:o1"]]
930
1053
  }}'
931
1054
 
932
- # Query (full NQL including time-travel and bi-temporal)
1055
+ # Query the endpoint speaks neSQL: SQL *or* NQL, routed on the first keyword
1056
+ curl -X POST :7070/v1/databases/shop/query \
1057
+ -d '{"nql":"SELECT name FROM users WHERE status = '"'"'active'"'"' ORDER BY name"}'
1058
+ # → {"rows":[{"name":"Alice"}],"count":1,"dialect":"sql", ...}
1059
+
933
1060
  curl -X POST :7070/v1/databases/shop/query \
934
1061
  -d '{"nql":"FROM users WHERE status = \"active\" ORDER BY name ASC"}'
1062
+ # → {"rows":[...],"count":1,"dialect":"nql", ...}
1063
+
1064
+
1065
+ **The field is still called `nql`, and its contents no longer have to be.** This
1066
+ endpoint accepts **neSQL** — NQL *or* PostgreSQL SQL — and answers with the
1067
+ `dialect` it chose. The name is unchanged because every existing HTTP client
1068
+ sends it; renaming would break them to gain nothing. Old NQL clients are
1069
+ unaffected.
1070
+
1071
+ Routing is **structural, not guessed**. NQL statements begin `FROM`; PostgreSQL
1072
+ has no statement form that begins with `FROM`, so the leading keyword partitions
1073
+ the two vocabularies rather than hinting at them. A first word in neither is
1074
+ refused *naming both* — never handed to whichever parser seems likelier.
1075
+
1076
+ ```bash
1077
+ curl -X POST :7070/v1/databases/shop/query -d '{"nql":"GRANT ALL ON users"}'
1078
+ # → 400 "GRANT" does not begin a statement in either half of neSQL
1079
+ # NQL statements begin with: FROM
1080
+ # SQL statements begin with: SELECT, INSERT, UPDATE, ...
1081
+ ```
1082
+
1083
+ It is the **same router** `nesql query` uses — `nedb_engine::neql::route`, which
1084
+ the CLI re-exports rather than copies. Two implementations of that decision
1085
+ would let the daemon and the CLI disagree about what a statement *means*, which
1086
+ is worse than disagreeing about a result: nothing looks broken when it happens.
935
1087
 
936
1088
  # Verify the hash chain
937
1089
  curl :7070/v1/databases/shop/verify
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": "6.1.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",