nedb-engine 2.2.33__tar.gz → 2.3.333__tar.gz
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.
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/PKG-INFO +52 -3
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/README.md +51 -2
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/pyproject.toml +1 -1
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/__init__.py +1 -1
- nedb_engine-2.3.333/python/nedb/_native.abi3.so +0 -0
- nedb_engine-2.3.333/python/nedb/nedbd-v2 +0 -0
- nedb_engine-2.3.333/python/nedb/nedbd-v2.exe +0 -0
- nedb_engine-2.2.33/python/nedb/_native.abi3.so +0 -0
- nedb_engine-2.2.33/python/nedb/nedbd-v2 +0 -0
- nedb_engine-2.2.33/python/nedb/nedbd-v2.exe +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/.gitignore +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/LICENSE +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/client/node/README.md +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/client/python/README.md +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/examples/mini-chain/README.md +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/autoindex.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/backends/__init__.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/backends/redis_backend.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/cascade.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/concurrent.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/crypto.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/engine.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/index.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/log.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/merkle.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/mongo.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/proof.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/query.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/redis_compat.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/relations.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/resp2.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/server.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/snapshot.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/sql.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/store.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/python/nedb/wrap_redis.py +0 -0
- {nedb_engine-2.2.33 → nedb_engine-2.3.333}/rust/nedb-v2/README.md +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nedb-engine
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.333
|
|
4
4
|
Summary: NEDB — a versioned, self-compressing, time-traveling embedded database (replay-protected, idempotent, relational, searchable) with durable AOF persistence and a server daemon (nedbd).
|
|
5
5
|
Project-URL: Homepage, https://github.com/aiassistsecure/nedb
|
|
6
6
|
Project-URL: Repository, https://github.com/aiassistsecure/nedb
|
|
@@ -41,9 +41,11 @@ One Rust core → ships to **PyPI** and **npm** from a single source.
|
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
## NEDB v2.
|
|
44
|
+
## NEDB v2.3.333 — Production Stable
|
|
45
45
|
|
|
46
|
-
**Current stable: 2.
|
|
46
|
+
**Current stable: 2.3.333** — Cross-platform native wheels shipping `nedbd-v2` binary inside `pip install nedb-engine`. Linux + Windows wheels built on GitHub Actions; macOS arm64 + x86_64 wheels built on Codemagic (M2 Mac Minis). All four platforms publish from one `v*` tag.
|
|
47
|
+
|
|
48
|
+
**New in 2.3.333:** comprehensive documentation for the **NEDB v3 segment/pack object store** (see the v3 section below) — the opt-in append-only storage substrate that took a real itcd chainstate flush from *minutes* to **under 2 seconds**. Engine code is unchanged from 2.3.33, which shipped durable **flush-on-close** (a `Db` persists buffered writes when dropped, matching sled/RocksDB), a **cross-platform Windows-safe id-index** (percent-encodes filesystem-unsafe document ids — link ids, paths), and idempotent object re-writes.
|
|
47
49
|
|
|
48
50
|
NEDB v2 replaces the append-only log (AOF) with a **content-addressed Merkle DAG**. Every document version is an immutable, BLAKE2b-verified object. Nothing is ever overwritten. As of **v2.2.31**, restarts after the first open are **O(1) warm starts** (driven by a `MANIFEST` of `seq` + Merkle head), the **cold scan is deferred** so the daemon accepts connections immediately, and a new **`GET /events` SSE endpoint** streams scan progress + per-write events live.
|
|
49
51
|
|
|
@@ -354,6 +356,52 @@ python3 tests/test_dag_perf.py --n 10000 --reads 100000
|
|
|
354
356
|
|
|
355
357
|
---
|
|
356
358
|
|
|
359
|
+
## NEDB v3 — Segment / Pack Object Store
|
|
360
|
+
|
|
361
|
+
**v3 is an opt-in storage substrate that replaces the loose one-file-per-object layout with append-only *segment packs* — the difference between a chainstate flush that takes *minutes* and one that takes *under two seconds*.** It is **off by default** (byte-for-byte v2), enabled with one flag, and **transparent** to everything above the storage layer: NQL, `AS OF`, `VALID AS OF`, `TRACE`, the BLAKE2b Merkle head, and causal provenance all behave identically.
|
|
362
|
+
|
|
363
|
+
### Why it exists
|
|
364
|
+
|
|
365
|
+
v2 stores every document version as its own content-addressed file at `objects/{hash[:2]}/{hash[2:]}`. That makes writes trivially atomic (write `.tmp` → `rename`) and corruption-proof — but each write costs a file create + `fsync` + rename **plus** a directory B-tree update. At scale that filesystem-metadata churn dominates: on a busy disk it caps sustained writes around **~185/s**, and a batch flush of a few thousand objects degrades into minutes. The bottleneck is the *number of files touched*, not the bytes written.
|
|
366
|
+
|
|
367
|
+
### What it does
|
|
368
|
+
|
|
369
|
+
v3 batches objects into append-only **segment packs** — `objects/segments/seg-NNNNNN.dat` — where each record is `[content_len: u32-LE][content]`. A write appends to the active segment and updates an in-memory `hash → (segment_id, offset, len)` map; a batch commits with a **single `fsync`**. Thousands of per-file syscalls collapse into one sequential append plus one durability point, so **flush cost scales with bytes (sequential I/O), not object-count × syscall overhead.**
|
|
370
|
+
|
|
371
|
+
- **Compaction / pruning** — `compact()` keeps the *live set* (the current version of every document, resolved from the id-index), rewrites those records into fresh segments, and reclaims the superseded/dead versions.
|
|
372
|
+
- **`.idx` sidecars** — each segment carries a sidecar (`NIX1` magic + entry count + fixed 44-byte entries + a BLAKE2b-256 checksum) so reopen rebuilds the in-memory index by reading the sidecar instead of scanning the whole pack. A missing or corrupt sidecar falls back to a full scan-and-heal — slower, never fatal.
|
|
373
|
+
- **Dual-read migration** — opening an existing v2 store in v3 mode is **non-destructive**: old loose objects stay fully readable, and only *new* writes go to segments. No migration step, no downtime, no rewrite.
|
|
374
|
+
- **Durable flush-on-close** — `flush_all()` (and `Db`'s `Drop`) fsync the active segment, matching the flush-on-close contract of sled / RocksDB.
|
|
375
|
+
|
|
376
|
+
### How to enable
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
# Engine / nedbd
|
|
380
|
+
nedbd --dag-v3 --data /var/lib/nedb # or set NEDB_DAG_V3=1
|
|
381
|
+
|
|
382
|
+
# itcd — Bitcoin-fork node embedding NEDB via nedb-ffi
|
|
383
|
+
interchainedd -dagv3 # puts chainstate AND block index on segments
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
The switch is read once, when each database's object store is constructed at open time. Default off → v2 loose objects.
|
|
387
|
+
|
|
388
|
+
### Real-world result
|
|
389
|
+
|
|
390
|
+
itcd (a Bitcoin Core 0.21 fork that replaces LevelDB chainstate with NEDB) syncing on `-dagv3`, measured `FlushStateToDisk` on real chainstate:
|
|
391
|
+
|
|
392
|
+
| Flush (coins → disk) | v3 segment store | v2 loose store |
|
|
393
|
+
|---|---|---|
|
|
394
|
+
| 2,002 coins / 275 kB | **1.93 s** | *minutes* |
|
|
395
|
+
| 2,549 coins / 366 kB | **1.71 s** | *minutes* |
|
|
396
|
+
|
|
397
|
+
Note the *larger* batch finishing *faster* — v3's cost is dominated by the single per-batch `fsync`, not per-coin work, so effective throughput (~1,000–1,500 coins/s here) climbs as batches grow, against the loose store's ~185 writes/s metadata ceiling. The gap only widens as the UTXO set grows: sequential-append cost tracks data volume, while per-file cost compounds with object count.
|
|
398
|
+
|
|
399
|
+
### When to use it
|
|
400
|
+
|
|
401
|
+
Reach for v3 on high-write, large-object-count workloads — blockchain chainstate / block index, event sourcing, high-frequency agent memory. For small or read-mostly stores the loose layout is perfectly fine, which is exactly why v3 stays opt-in.
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
357
405
|
## Architecture
|
|
358
406
|
|
|
359
407
|
```
|
|
@@ -447,6 +495,7 @@ docs/ index.html reference.html SPEC.md
|
|
|
447
495
|
- [x] **Auto-migration** — v1 AOF → v2 DAG on first `--dag` startup
|
|
448
496
|
- [x] **nedb-client** — async Python + TypeScript HTTP client (`pip/npm install nedb-client`)
|
|
449
497
|
- [x] **Intel Mac support** — native wheels for `aarch64` + `x86_64` Apple Darwin
|
|
498
|
+
- [x] **v3 segment/pack object store** — opt-in `--dag-v3`: append-only packs, one fsync per batch, compaction + `.idx` sidecars, non-destructive dual-read (minutes → <2s chainstate flush on itcd)
|
|
450
499
|
- [ ] In-memory DAG mode — `Db::in_memory()` for zero-disk ephemeral sessions
|
|
451
500
|
- [ ] PyO3 + napi-rs bindings updated to v2 DAG API
|
|
452
501
|
- [ ] NEDB Studio DAG mode toggle
|
|
@@ -20,9 +20,11 @@ One Rust core → ships to **PyPI** and **npm** from a single source.
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
-
## NEDB v2.
|
|
23
|
+
## NEDB v2.3.333 — Production Stable
|
|
24
24
|
|
|
25
|
-
**Current stable: 2.
|
|
25
|
+
**Current stable: 2.3.333** — Cross-platform native wheels shipping `nedbd-v2` binary inside `pip install nedb-engine`. Linux + Windows wheels built on GitHub Actions; macOS arm64 + x86_64 wheels built on Codemagic (M2 Mac Minis). All four platforms publish from one `v*` tag.
|
|
26
|
+
|
|
27
|
+
**New in 2.3.333:** comprehensive documentation for the **NEDB v3 segment/pack object store** (see the v3 section below) — the opt-in append-only storage substrate that took a real itcd chainstate flush from *minutes* to **under 2 seconds**. Engine code is unchanged from 2.3.33, which shipped durable **flush-on-close** (a `Db` persists buffered writes when dropped, matching sled/RocksDB), a **cross-platform Windows-safe id-index** (percent-encodes filesystem-unsafe document ids — link ids, paths), and idempotent object re-writes.
|
|
26
28
|
|
|
27
29
|
NEDB v2 replaces the append-only log (AOF) with a **content-addressed Merkle DAG**. Every document version is an immutable, BLAKE2b-verified object. Nothing is ever overwritten. As of **v2.2.31**, restarts after the first open are **O(1) warm starts** (driven by a `MANIFEST` of `seq` + Merkle head), the **cold scan is deferred** so the daemon accepts connections immediately, and a new **`GET /events` SSE endpoint** streams scan progress + per-write events live.
|
|
28
30
|
|
|
@@ -333,6 +335,52 @@ python3 tests/test_dag_perf.py --n 10000 --reads 100000
|
|
|
333
335
|
|
|
334
336
|
---
|
|
335
337
|
|
|
338
|
+
## NEDB v3 — Segment / Pack Object Store
|
|
339
|
+
|
|
340
|
+
**v3 is an opt-in storage substrate that replaces the loose one-file-per-object layout with append-only *segment packs* — the difference between a chainstate flush that takes *minutes* and one that takes *under two seconds*.** It is **off by default** (byte-for-byte v2), enabled with one flag, and **transparent** to everything above the storage layer: NQL, `AS OF`, `VALID AS OF`, `TRACE`, the BLAKE2b Merkle head, and causal provenance all behave identically.
|
|
341
|
+
|
|
342
|
+
### Why it exists
|
|
343
|
+
|
|
344
|
+
v2 stores every document version as its own content-addressed file at `objects/{hash[:2]}/{hash[2:]}`. That makes writes trivially atomic (write `.tmp` → `rename`) and corruption-proof — but each write costs a file create + `fsync` + rename **plus** a directory B-tree update. At scale that filesystem-metadata churn dominates: on a busy disk it caps sustained writes around **~185/s**, and a batch flush of a few thousand objects degrades into minutes. The bottleneck is the *number of files touched*, not the bytes written.
|
|
345
|
+
|
|
346
|
+
### What it does
|
|
347
|
+
|
|
348
|
+
v3 batches objects into append-only **segment packs** — `objects/segments/seg-NNNNNN.dat` — where each record is `[content_len: u32-LE][content]`. A write appends to the active segment and updates an in-memory `hash → (segment_id, offset, len)` map; a batch commits with a **single `fsync`**. Thousands of per-file syscalls collapse into one sequential append plus one durability point, so **flush cost scales with bytes (sequential I/O), not object-count × syscall overhead.**
|
|
349
|
+
|
|
350
|
+
- **Compaction / pruning** — `compact()` keeps the *live set* (the current version of every document, resolved from the id-index), rewrites those records into fresh segments, and reclaims the superseded/dead versions.
|
|
351
|
+
- **`.idx` sidecars** — each segment carries a sidecar (`NIX1` magic + entry count + fixed 44-byte entries + a BLAKE2b-256 checksum) so reopen rebuilds the in-memory index by reading the sidecar instead of scanning the whole pack. A missing or corrupt sidecar falls back to a full scan-and-heal — slower, never fatal.
|
|
352
|
+
- **Dual-read migration** — opening an existing v2 store in v3 mode is **non-destructive**: old loose objects stay fully readable, and only *new* writes go to segments. No migration step, no downtime, no rewrite.
|
|
353
|
+
- **Durable flush-on-close** — `flush_all()` (and `Db`'s `Drop`) fsync the active segment, matching the flush-on-close contract of sled / RocksDB.
|
|
354
|
+
|
|
355
|
+
### How to enable
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
# Engine / nedbd
|
|
359
|
+
nedbd --dag-v3 --data /var/lib/nedb # or set NEDB_DAG_V3=1
|
|
360
|
+
|
|
361
|
+
# itcd — Bitcoin-fork node embedding NEDB via nedb-ffi
|
|
362
|
+
interchainedd -dagv3 # puts chainstate AND block index on segments
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
The switch is read once, when each database's object store is constructed at open time. Default off → v2 loose objects.
|
|
366
|
+
|
|
367
|
+
### Real-world result
|
|
368
|
+
|
|
369
|
+
itcd (a Bitcoin Core 0.21 fork that replaces LevelDB chainstate with NEDB) syncing on `-dagv3`, measured `FlushStateToDisk` on real chainstate:
|
|
370
|
+
|
|
371
|
+
| Flush (coins → disk) | v3 segment store | v2 loose store |
|
|
372
|
+
|---|---|---|
|
|
373
|
+
| 2,002 coins / 275 kB | **1.93 s** | *minutes* |
|
|
374
|
+
| 2,549 coins / 366 kB | **1.71 s** | *minutes* |
|
|
375
|
+
|
|
376
|
+
Note the *larger* batch finishing *faster* — v3's cost is dominated by the single per-batch `fsync`, not per-coin work, so effective throughput (~1,000–1,500 coins/s here) climbs as batches grow, against the loose store's ~185 writes/s metadata ceiling. The gap only widens as the UTXO set grows: sequential-append cost tracks data volume, while per-file cost compounds with object count.
|
|
377
|
+
|
|
378
|
+
### When to use it
|
|
379
|
+
|
|
380
|
+
Reach for v3 on high-write, large-object-count workloads — blockchain chainstate / block index, event sourcing, high-frequency agent memory. For small or read-mostly stores the loose layout is perfectly fine, which is exactly why v3 stays opt-in.
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
336
384
|
## Architecture
|
|
337
385
|
|
|
338
386
|
```
|
|
@@ -426,6 +474,7 @@ docs/ index.html reference.html SPEC.md
|
|
|
426
474
|
- [x] **Auto-migration** — v1 AOF → v2 DAG on first `--dag` startup
|
|
427
475
|
- [x] **nedb-client** — async Python + TypeScript HTTP client (`pip/npm install nedb-client`)
|
|
428
476
|
- [x] **Intel Mac support** — native wheels for `aarch64` + `x86_64` Apple Darwin
|
|
477
|
+
- [x] **v3 segment/pack object store** — opt-in `--dag-v3`: append-only packs, one fsync per batch, compaction + `.idx` sidecars, non-destructive dual-read (minutes → <2s chainstate flush on itcd)
|
|
429
478
|
- [ ] In-memory DAG mode — `Db::in_memory()` for zero-disk ephemeral sessions
|
|
430
479
|
- [ ] PyO3 + napi-rs bindings updated to v2 DAG API
|
|
431
480
|
- [ ] NEDB Studio DAG mode toggle
|
|
@@ -10,7 +10,7 @@ build-backend = "hatchling.build"
|
|
|
10
10
|
|
|
11
11
|
[project]
|
|
12
12
|
name = "nedb-engine"
|
|
13
|
-
version = "2.
|
|
13
|
+
version = "2.3.333"
|
|
14
14
|
description = "NEDB — a versioned, self-compressing, time-traveling embedded database (replay-protected, idempotent, relational, searchable) with durable AOF persistence and a server daemon (nedbd)."
|
|
15
15
|
readme = "README.md"
|
|
16
16
|
requires-python = ">=3.8"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|