@libredb/libredb 0.0.2 → 0.0.3
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 +12 -0
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +4 -2
- package/dist/lens/catalog.d.ts +13 -0
- package/dist/lens/catalog.js +15 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -272,6 +272,18 @@ registry.get("logs");
|
|
|
272
272
|
|
|
273
273
|
The catalog lives under a reserved key prefix that sorts below all user data, so its entries never appear in a `kv`, `doc`, or `table` scan — and no user row leaks into the registry. `kv` namespaces are deliberately not cataloged: `kv` is the raw layer with full keyspace access.
|
|
274
274
|
|
|
275
|
+
A tool that renders the raw `kv` layer (so it sees everything, including the catalog) should hide those engine-internal keys. Rather than hardcode the byte layout, import the contract: `isReservedKey(key)` is true for any key in the reserved namespace, and `RESERVED_MARKER` / `CATALOG_PREFIX` are the underlying constants if you need to build a range.
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
import { open, kv, isReservedKey } from "libredb";
|
|
279
|
+
|
|
280
|
+
const db = open();
|
|
281
|
+
// ... user writes through doc/table, which also write catalog entries ...
|
|
282
|
+
|
|
283
|
+
const visible = kv(db).range("", "").toArray().filter((e) => !isReservedKey(e.key));
|
|
284
|
+
// only user keys; catalog entries (under the reserved marker) are filtered out
|
|
285
|
+
```
|
|
286
|
+
|
|
275
287
|
## Reliability — deterministic simulation testing
|
|
276
288
|
|
|
277
289
|
Durability is the trust-critical promise: a transaction that returns has been fsync'd, and a crash can only ever damage the last, un-fsync'd record. LibreDB proves this with **deterministic simulation testing (DST)** — the WAL's crash/recovery path is tortured under a seeded, in-memory simulated filesystem. The kernel reaches the disk only through an injectable FS seam (`open({ path, fs })`), so a test can run the real engine on a `SimFS` that crashes on command, tears the un-fsync'd tail at a seeded point, and injects CRC corruption or short reads.
|
package/dist/core.d.ts
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* and discards any record a crash left half-written.
|
|
21
21
|
*/
|
|
22
22
|
/** The LibreDB package version. Kept in sync with package.json. */
|
|
23
|
-
export declare const version = "0.0.
|
|
23
|
+
export declare const version = "0.0.3";
|
|
24
24
|
/**
|
|
25
25
|
* A key in the kernel: an immutable sequence of bytes.
|
|
26
26
|
*
|
package/dist/core.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
*/
|
|
22
22
|
import { closeSync, fsyncSync, openSync, readFileSync, statSync, truncateSync, writeSync, } from "node:fs";
|
|
23
23
|
/** The LibreDB package version. Kept in sync with package.json. */
|
|
24
|
-
export const version = "0.0.
|
|
24
|
+
export const version = "0.0.3";
|
|
25
25
|
/**
|
|
26
26
|
* Compare two keys by unsigned byte-lexicographic order: the first differing
|
|
27
27
|
* byte decides, and if one key is a prefix of the other the shorter sorts
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* documents). The kernel's byte-level internals (and each lens's private codec)
|
|
7
7
|
* stay unexported on purpose — the lens is the usable face. The relational lens
|
|
8
8
|
* ({@link table}) completes the trio. {@link catalog} reads the registry of
|
|
9
|
-
* namespaces a database holds, so a tool can render faithful per-kind views
|
|
9
|
+
* namespaces a database holds, so a tool can render faithful per-kind views;
|
|
10
|
+
* {@link isReservedKey} (with {@link RESERVED_MARKER} / {@link CATALOG_PREFIX})
|
|
11
|
+
* lets a raw-KV tool hide engine-internal keys instead of hardcoding the layout.
|
|
10
12
|
*/
|
|
11
13
|
export { version, open } from "./core.ts";
|
|
12
14
|
export type { Database, OpenOptions } from "./core.ts";
|
|
@@ -16,6 +18,6 @@ export { doc } from "./lens/document.ts";
|
|
|
16
18
|
export type { DocCollection, Doc, DocEntry, JsonValue } from "./lens/document.ts";
|
|
17
19
|
export { table } from "./lens/relational.ts";
|
|
18
20
|
export type { Table, TableSchema, Row, ColumnType, Query } from "./lens/relational.ts";
|
|
19
|
-
export { catalog } from "./lens/catalog.ts";
|
|
21
|
+
export { catalog, isReservedKey, CATALOG_PREFIX, RESERVED_MARKER } from "./lens/catalog.ts";
|
|
20
22
|
export type { CatalogEntry, CatalogRegistry } from "./lens/catalog.ts";
|
|
21
23
|
export type { Result, WriteResult } from "./lens/types.ts";
|
package/dist/index.js
CHANGED
|
@@ -6,10 +6,12 @@
|
|
|
6
6
|
* documents). The kernel's byte-level internals (and each lens's private codec)
|
|
7
7
|
* stay unexported on purpose — the lens is the usable face. The relational lens
|
|
8
8
|
* ({@link table}) completes the trio. {@link catalog} reads the registry of
|
|
9
|
-
* namespaces a database holds, so a tool can render faithful per-kind views
|
|
9
|
+
* namespaces a database holds, so a tool can render faithful per-kind views;
|
|
10
|
+
* {@link isReservedKey} (with {@link RESERVED_MARKER} / {@link CATALOG_PREFIX})
|
|
11
|
+
* lets a raw-KV tool hide engine-internal keys instead of hardcoding the layout.
|
|
10
12
|
*/
|
|
11
13
|
export { version, open } from "./core.js";
|
|
12
14
|
export { kv } from "./lens/kv.js";
|
|
13
15
|
export { doc } from "./lens/document.js";
|
|
14
16
|
export { table } from "./lens/relational.js";
|
|
15
|
-
export { catalog } from "./lens/catalog.js";
|
|
17
|
+
export { catalog, isReservedKey, CATALOG_PREFIX, RESERVED_MARKER } from "./lens/catalog.js";
|
package/dist/lens/catalog.d.ts
CHANGED
|
@@ -27,6 +27,19 @@ export declare const CATALOG_PREFIX = "\0libredb:catalog:";
|
|
|
27
27
|
* layer with full keyspace access (DESIGN.md section 6.3).
|
|
28
28
|
*/
|
|
29
29
|
export declare function assertUserName(name: string): void;
|
|
30
|
+
/**
|
|
31
|
+
* Whether `key` lies in LibreDB's reserved internal namespace — that is, whether
|
|
32
|
+
* it begins with the {@link RESERVED_MARKER}. This is the public contract a tool
|
|
33
|
+
* that renders RAW key-value data (e.g. the LibreDB Studio provider) uses to HIDE
|
|
34
|
+
* engine-internal keys: the catalog today, and any further reserved sub-namespace
|
|
35
|
+
* added under the marker later. Testing the marker rather than the specific
|
|
36
|
+
* {@link CATALOG_PREFIX} is deliberate — a tool that depends on this stays correct
|
|
37
|
+
* if the reserved namespace grows, so it never has to track the byte layout.
|
|
38
|
+
*
|
|
39
|
+
* {@link assertUserName} guarantees no user namespace name begins with the marker,
|
|
40
|
+
* so this predicate partitions reserved keys from user keys with no overlap.
|
|
41
|
+
*/
|
|
42
|
+
export declare function isReservedKey(key: string): boolean;
|
|
30
43
|
/**
|
|
31
44
|
* The lens a cataloged namespace belongs to, plus (for a relational table) its
|
|
32
45
|
* schema — the otherwise-unrecoverable interpretation a cold-opening tool needs
|
package/dist/lens/catalog.js
CHANGED
|
@@ -52,6 +52,21 @@ export function assertUserName(name) {
|
|
|
52
52
|
throw new Error(`libredb: namespace name ${JSON.stringify(name)} may not start with the reserved catalog marker (U+0000)`);
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Whether `key` lies in LibreDB's reserved internal namespace — that is, whether
|
|
57
|
+
* it begins with the {@link RESERVED_MARKER}. This is the public contract a tool
|
|
58
|
+
* that renders RAW key-value data (e.g. the LibreDB Studio provider) uses to HIDE
|
|
59
|
+
* engine-internal keys: the catalog today, and any further reserved sub-namespace
|
|
60
|
+
* added under the marker later. Testing the marker rather than the specific
|
|
61
|
+
* {@link CATALOG_PREFIX} is deliberate — a tool that depends on this stays correct
|
|
62
|
+
* if the reserved namespace grows, so it never has to track the byte layout.
|
|
63
|
+
*
|
|
64
|
+
* {@link assertUserName} guarantees no user namespace name begins with the marker,
|
|
65
|
+
* so this predicate partitions reserved keys from user keys with no overlap.
|
|
66
|
+
*/
|
|
67
|
+
export function isReservedKey(key) {
|
|
68
|
+
return key.startsWith(RESERVED_MARKER);
|
|
69
|
+
}
|
|
55
70
|
const utf8 = new TextEncoder();
|
|
56
71
|
const fromUtf8 = new TextDecoder();
|
|
57
72
|
/** The kernel key for one namespace's catalog entry: the reserved prefix plus
|
package/package.json
CHANGED