@yydb/yydb 0.1.1 → 0.1.2
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 +23 -3
- package/dist/api/database.d.ts +253 -27
- package/dist/api/database.js +307 -129
- package/dist/cli/cli.js +28 -1
- package/dist/cli/info-cmd.js +30 -1
- package/dist/cli/verify-cmd.d.ts +11 -0
- package/dist/cli/verify-cmd.js +73 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/native/binding.d.ts +67 -0
- package/dist/shared/errors.d.ts +132 -0
- package/dist/shared/errors.js +154 -0
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -17,10 +17,15 @@ For a wire client only (renderer or an app that already runs `yydb serve`), use
|
|
|
17
17
|
| Import | Runtime | Role |
|
|
18
18
|
|--------|---------|------|
|
|
19
19
|
| `@yydb/yydb` | Node | `Database.open`, micro helpers, VOS re-exports |
|
|
20
|
-
| `@yydb/yydb/cli` | Node | CLI (`version`, `init`, `info`, `serve`) |
|
|
20
|
+
| `@yydb/yydb/cli` | Node | CLI (`version`, `init`, `info`, `verify`, `serve`) |
|
|
21
21
|
|
|
22
22
|
Node.js 18+.
|
|
23
23
|
|
|
24
|
+
```bash
|
|
25
|
+
npm install @yydb/yydb
|
|
26
|
+
npx yydb version
|
|
27
|
+
```
|
|
28
|
+
|
|
24
29
|
Schema truth lives in the `.yydb` file via `ensureSchema` and VOS documents.
|
|
25
30
|
|
|
26
31
|
## Example
|
|
@@ -65,6 +70,21 @@ await db.close();
|
|
|
65
70
|
`OpenOptions`: `cli` (explicit CLI script path), `port` (preferred loopback port), `serveArgs` (extra `yydb serve`
|
|
66
71
|
arguments). `binary` is a deprecated alias for `cli`.
|
|
67
72
|
|
|
73
|
+
### Prepared statements
|
|
74
|
+
|
|
75
|
+
`db.prepare` parses and lowers a VOS query once; the plan stays in a native thread-local registry and re-executes
|
|
76
|
+
with different bindings.
|
|
77
|
+
|
|
78
|
+
```ts
|
|
79
|
+
const stmt = await db.prepare('User.all().take($limit).collect()');
|
|
80
|
+
const rows = await stmt.execute({ limit: 100 });
|
|
81
|
+
const more = await stmt.execute({ limit: 50 });
|
|
82
|
+
stmt.close();
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`stmt.parameters` lists the expected bindings, and `stmt.info` exposes the read/write sets and source fingerprint.
|
|
86
|
+
Missing, extra, or mistyped parameters raise `YydbError` with code `yydb.query.bind`.
|
|
87
|
+
|
|
68
88
|
The native binding exposes additive operations (`schemaVersion`, `schemaDocument`, `recordCount`, `journalMode`,
|
|
69
89
|
`checkpoint`, `walFrameCount`, `get`, `put`); the CLI composes commands from them.
|
|
70
90
|
|
|
@@ -73,7 +93,7 @@ The native binding exposes additive operations (`schemaVersion`, `schemaDocument
|
|
|
73
93
|
| Need | Package |
|
|
74
94
|
|------|---------|
|
|
75
95
|
| Node embedded engine and CLI (this package) | **`@yydb/yydb`** |
|
|
76
|
-
| Browser
|
|
96
|
+
| Browser engine (pure TS and WASM sessions) | **`@yydb/light-db`** |
|
|
77
97
|
| Wire client only | [`@yydb/yydb-client`](https://www.npmjs.com/package/@yydb/yydb-client) |
|
|
78
98
|
| In-process Rust embed | [`yydb`](https://crates.io/crates/yydb) |
|
|
79
99
|
| Agent skills (wire protocol) | [`@yydb/yydb-skills`](https://www.npmjs.com/package/@yydb/yydb-skills) |
|
|
@@ -83,4 +103,4 @@ endpoint.
|
|
|
83
103
|
|
|
84
104
|
The managed engine listens on `127.0.0.1` with no authentication — keep the endpoint private.
|
|
85
105
|
|
|
86
|
-
[YYDB overview](https://github.com/yy-database/yydb
|
|
106
|
+
[YYDB overview](https://github.com/yy-database/yydb) · [User guides](https://github.com/yy-database/yydb/tree/dev/projects/packages/homepage/documentation/zh-hans)
|
package/dist/api/database.d.ts
CHANGED
|
@@ -1,50 +1,276 @@
|
|
|
1
|
+
import { type EmittableItem } from '@voml/vos';
|
|
1
2
|
import { defineMicro as buildMicro, type DefinedMicro, type MicroHandle } from '../shared/micro.js';
|
|
3
|
+
import { loadNative, type NativeStatement as NativeStatementHandle } from '../native/binding.js';
|
|
2
4
|
import type { UdfScalarDescriptor } from '../shared/udf-types.js';
|
|
3
|
-
|
|
5
|
+
/** Published schema metadata. */
|
|
6
|
+
export interface SchemaVersion {
|
|
7
|
+
version: number;
|
|
8
|
+
document: string;
|
|
9
|
+
}
|
|
10
|
+
/** Options for opening a local YYDB file. */
|
|
4
11
|
export interface OpenOptions {
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
/** Create parent directories when missing (default: true). */
|
|
13
|
+
mkdir?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/** One row from a {@link Database.scan}. */
|
|
16
|
+
export interface ScanRow {
|
|
17
|
+
key: string;
|
|
18
|
+
value: Uint8Array;
|
|
19
|
+
}
|
|
20
|
+
/** Options for {@link Database.scan}. */
|
|
21
|
+
export interface ScanOptions {
|
|
22
|
+
/** Include this prefix in every returned key; default `""` returns everything. */
|
|
23
|
+
prefix?: string;
|
|
24
|
+
/** Exclusive continuation cursor from a previous scan's last row; default `null` starts fresh. */
|
|
25
|
+
after?: string | null;
|
|
26
|
+
/** Max rows returned per call; default `1000`. */
|
|
27
|
+
limit?: number;
|
|
28
|
+
}
|
|
29
|
+
/** One change in a {@link Database.batch}. Use `null` to delete. */
|
|
30
|
+
export interface BatchChange {
|
|
31
|
+
key: string;
|
|
32
|
+
value: Uint8Array | string | null;
|
|
33
|
+
}
|
|
34
|
+
/** Options for {@link Database.migrateSchema}. */
|
|
35
|
+
export interface MigrateOptions {
|
|
36
|
+
/** Rename entries — `fromType`/`toType` updates a type name; `type`/`fromField`/`toField` updates one field. */
|
|
37
|
+
renames?: ReadonlyArray<{
|
|
38
|
+
fromType: string;
|
|
39
|
+
toType: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: string;
|
|
42
|
+
fromField: string;
|
|
43
|
+
toField: string;
|
|
44
|
+
}>;
|
|
45
|
+
}
|
|
46
|
+
/** One consistency finding from {@link Database.doctor}. */
|
|
47
|
+
export interface DoctorIssue {
|
|
48
|
+
severity: 'warn' | 'error';
|
|
49
|
+
code: string;
|
|
50
|
+
message: string;
|
|
51
|
+
key_hint?: string | null;
|
|
52
|
+
}
|
|
53
|
+
/** Per-namespace usage snapshot from {@link Database.doctor}. */
|
|
54
|
+
export interface DoctorNamespaceStats {
|
|
55
|
+
prefix: string;
|
|
56
|
+
record_count: number;
|
|
57
|
+
bytes_used: number;
|
|
58
|
+
object_bytes: number;
|
|
59
|
+
quota_max_bytes?: number | null;
|
|
60
|
+
ttl_expired_pending: number;
|
|
61
|
+
}
|
|
62
|
+
/** Read-only consistency report. */
|
|
63
|
+
export interface DoctorReport {
|
|
64
|
+
file_path?: string | null;
|
|
65
|
+
last_commit_sequence: number;
|
|
66
|
+
last_checkpoint_sequence: number;
|
|
67
|
+
checkpoint_lag_records: number;
|
|
68
|
+
wal_bytes_uncheckpointed: number;
|
|
69
|
+
orphan_object_count: number;
|
|
70
|
+
namespaces: DoctorNamespaceStats[];
|
|
71
|
+
issues: DoctorIssue[];
|
|
72
|
+
}
|
|
73
|
+
/** Summary of a v0 `.yydx` compaction pass. */
|
|
74
|
+
export interface CompactReport {
|
|
75
|
+
checkpointed: boolean;
|
|
76
|
+
orphans_reclaimed: number;
|
|
77
|
+
}
|
|
78
|
+
/** Declared type for a prepared statement parameter slot. */
|
|
79
|
+
export type SlotType = 'any' | 'bool' | 'i64' | 'text' | 'null';
|
|
80
|
+
/** One named parameter descriptor on a {@link Statement}. */
|
|
81
|
+
export interface ParameterDescriptor {
|
|
82
|
+
/** Canonical parameter name (no leading `$`). */
|
|
83
|
+
name: string;
|
|
84
|
+
/** Positional slot index within the bound-value slice (0-based). */
|
|
85
|
+
index: number;
|
|
86
|
+
/** Declared slot type; narrowed from surrounding context when possible. */
|
|
87
|
+
slotTy: SlotType;
|
|
88
|
+
/** Number of times this parameter appears in the source. */
|
|
89
|
+
usageCount: number;
|
|
90
|
+
}
|
|
91
|
+
/** Whether a prepared statement is a read pipeline or a write program. */
|
|
92
|
+
export type QueryKind = 'Read' | 'Write';
|
|
93
|
+
/** Metadata about a prepared statement — useful for logging and cache keys. */
|
|
94
|
+
export interface StatementInfo {
|
|
95
|
+
statementId: string;
|
|
96
|
+
queryKind: QueryKind;
|
|
97
|
+
parameters: ParameterDescriptor[];
|
|
98
|
+
readSet: string[];
|
|
99
|
+
writeSet: string[];
|
|
100
|
+
sourceFingerprint: string;
|
|
101
|
+
source: string;
|
|
13
102
|
}
|
|
14
103
|
/**
|
|
15
|
-
*
|
|
16
|
-
*
|
|
104
|
+
* A pre-parsed, pre-lowered VOS query plan.
|
|
105
|
+
*
|
|
106
|
+
* Created by {@link Database.prepare}. The actual lowered op tree lives on
|
|
107
|
+
* the native side in a thread-local registry keyed by `statementId`; this
|
|
108
|
+
* class is a thin JS handle. Bind parameters and re-execute via
|
|
109
|
+
* {@link Statement.execute} without re-parsing or re-lowering the source.
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* const stmt = await db.prepare('User.all().take($limit).collect()');
|
|
113
|
+
* const rows = await stmt.execute({ limit: 100 });
|
|
114
|
+
* // re-execute with different bind
|
|
115
|
+
* const rows2 = await stmt.execute({ limit: 50 });
|
|
116
|
+
* // release when done
|
|
117
|
+
* stmt.close();
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
export declare class Statement {
|
|
121
|
+
private readonly native;
|
|
122
|
+
private readonly db;
|
|
123
|
+
private closed;
|
|
124
|
+
constructor(native: NativeStatementHandle, db: unknown);
|
|
125
|
+
/** The fingerprint-prefixed unique id for this statement. */
|
|
126
|
+
get statementId(): string;
|
|
127
|
+
/** Parameter descriptors — empty array when the statement takes no parameters. */
|
|
128
|
+
get parameters(): ParameterDescriptor[];
|
|
129
|
+
/** Full statement metadata. */
|
|
130
|
+
get info(): StatementInfo;
|
|
131
|
+
/** Whether this statement has been closed and can no longer execute. */
|
|
132
|
+
get isClosed(): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Execute this prepared statement with optional named parameter bindings.
|
|
135
|
+
*
|
|
136
|
+
* Missing parameters, extraneous parameters or mistyped parameters raise
|
|
137
|
+
* `YydbError` with code `yydb.query.bind`.
|
|
138
|
+
*
|
|
139
|
+
* @param params Named parameter values — keys match the parameter names
|
|
140
|
+
* in the VOS source (`$name` → `{ name: value }`). Omit when the statement
|
|
141
|
+
* takes no parameters.
|
|
142
|
+
*/
|
|
143
|
+
execute<T = Record<string, unknown>>(params?: Record<string, unknown>): Promise<T[]>;
|
|
144
|
+
/** Release this statement's plan from the native registry. */
|
|
145
|
+
close(): void;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Transaction-local handle passed to {@link Database.transaction} callbacks.
|
|
149
|
+
* All CRUD methods forward to the underlying native handle while the
|
|
150
|
+
* transaction is in flight. Commit/rollback are owned by {@link Database}.
|
|
151
|
+
*/
|
|
152
|
+
export declare class TransactionHandle {
|
|
153
|
+
private readonly native;
|
|
154
|
+
constructor(native: ReturnType<ReturnType<typeof loadNative>['Database']['open']>);
|
|
155
|
+
get(key: string): Promise<Uint8Array | null>;
|
|
156
|
+
put(key: string, value: Uint8Array | string): Promise<void>;
|
|
157
|
+
delete(key: string): Promise<void>;
|
|
158
|
+
scan(options?: ScanOptions): Promise<ScanRow[]>;
|
|
159
|
+
batch(changes: readonly BatchChange[]): Promise<void>;
|
|
160
|
+
compareExchange(key: string, expected: Uint8Array | string | null, replacement: Uint8Array | string | null): Promise<boolean>;
|
|
161
|
+
query<T = Record<string, unknown>>(source: string): Promise<T[]>;
|
|
162
|
+
execute(source: string): Promise<void>;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Node-facing YYDB local database handle.
|
|
166
|
+
*
|
|
167
|
+
* Directly owns a native `yydb::Connection` via the Node-API binding. No
|
|
168
|
+
* child process, no loopback TCP, no wire protocol in the hot path.
|
|
17
169
|
*/
|
|
18
170
|
export declare class Database {
|
|
19
171
|
readonly path: string;
|
|
20
|
-
readonly
|
|
21
|
-
private client;
|
|
22
|
-
private child;
|
|
172
|
+
private readonly native;
|
|
23
173
|
private readonly microRegistry;
|
|
24
174
|
private constructor();
|
|
175
|
+
/** Open (create when missing) the database at `dbPath`. */
|
|
176
|
+
static open(dbPath: string, options?: OpenOptions): Promise<Database>;
|
|
177
|
+
/** Engine version string (same as `yydb --version`). */
|
|
178
|
+
serverVersion(): string;
|
|
179
|
+
/** Basic diagnostics: path, schema, record count, journal mode. */
|
|
180
|
+
info(): string;
|
|
181
|
+
/** Published schema metadata, or `null` before the first schema. */
|
|
182
|
+
getSchema(): Promise<{
|
|
183
|
+
version: number;
|
|
184
|
+
document: string;
|
|
185
|
+
} | null>;
|
|
25
186
|
/**
|
|
26
|
-
*
|
|
187
|
+
* Validate and publish a VOS schema document.
|
|
188
|
+
*
|
|
189
|
+
* Accepts either a raw `.vos` source string, one `@voml/vos` descriptor
|
|
190
|
+
* (`v.table()`, `v.class()`) or a list of descriptors. When descriptors
|
|
191
|
+
* are supplied, they are rendered to source via `emitSource` first.
|
|
27
192
|
*/
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
info(): Promise<string>;
|
|
31
|
-
getSchema(): Promise<import("@yydb/yydb-client").SchemaVersion | null>;
|
|
32
|
-
ensureSchema(version: number, document: string): Promise<void>;
|
|
193
|
+
ensureSchema(...input: [string] | [string, ...EmittableItem[]] | EmittableItem[]): Promise<void>;
|
|
194
|
+
/** Read one record, or `null` when the key is absent. */
|
|
33
195
|
get(key: string): Promise<Uint8Array | null>;
|
|
196
|
+
/** Insert or replace one record. */
|
|
34
197
|
put(key: string, value: Uint8Array | string): Promise<void>;
|
|
198
|
+
/** Delete one record by key. Silently succeeds when the key is absent. */
|
|
199
|
+
delete(key: string): Promise<void>;
|
|
200
|
+
/** List key/value pairs in lexical order. `prefix` defaults to `""` (all keys). */
|
|
201
|
+
scan(options?: ScanOptions): Promise<ScanRow[]>;
|
|
202
|
+
/** Atomically write or delete many keys in one call. */
|
|
203
|
+
batch(changes: readonly BatchChange[]): Promise<void>;
|
|
204
|
+
/**
|
|
205
|
+
* Compare-and-swap: replace or delete `key` only when its current value
|
|
206
|
+
* exactly equals `expected`. Both `expected` and `replacement` may be
|
|
207
|
+
* `null` (meaning absent / delete). Returns `true` when the swap applied.
|
|
208
|
+
*/
|
|
209
|
+
compareExchange(key: string, expected: Uint8Array | string | null, replacement: Uint8Array | string | null): Promise<boolean>;
|
|
210
|
+
/** Fold the WAL into the main file and truncate the sidecar. */
|
|
211
|
+
checkpoint(): Promise<void>;
|
|
212
|
+
/** Checkpoint then copy a self-contained `.yydb` main file to `dest`. */
|
|
213
|
+
backup(dest: string): Promise<void>;
|
|
214
|
+
/** Copy main + WAL + SHM without checkpoint; opening `dest` replays the WAL tail. */
|
|
215
|
+
backupWithWal(dest: string): Promise<void>;
|
|
216
|
+
/** Run read-only consistency probes against the database. */
|
|
217
|
+
doctor(): Promise<DoctorReport>;
|
|
218
|
+
/** Fold WAL + reclaim orphan blobs (`.yydx` layouts only). */
|
|
219
|
+
compactYydx(): Promise<CompactReport>;
|
|
220
|
+
/**
|
|
221
|
+
* Run `fn` inside an explicit transaction. The transaction commits on
|
|
222
|
+
* normal return and rolls back on throw. Nested calls are not supported.
|
|
223
|
+
*
|
|
224
|
+
* ```ts
|
|
225
|
+
* await db.transaction(async (tx) => {
|
|
226
|
+
* await tx.put('a', '1');
|
|
227
|
+
* await tx.put('b', '2');
|
|
228
|
+
* });
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
transaction<T>(fn: (tx: TransactionHandle) => Promise<T>): Promise<T>;
|
|
232
|
+
/**
|
|
233
|
+
* Prepare a VOS read pipeline into a reusable query plan.
|
|
234
|
+
*
|
|
235
|
+
* Returns a {@link Statement} handle. The actual lowered op tree lives
|
|
236
|
+
* on the native side in a thread-local registry — you can call
|
|
237
|
+
* `statement.execute({ paramName: value })` cheaply multiple times
|
|
238
|
+
* without re-parsing or re-lowering the source.
|
|
239
|
+
*
|
|
240
|
+
* Prepare requires no schema binding; plan building is a pure parse +
|
|
241
|
+
* lower pass. Execute still needs `ensureSchema` first.
|
|
242
|
+
*
|
|
243
|
+
* ```ts
|
|
244
|
+
* const stmt = await db.prepare('User.all().take($limit).collect()');
|
|
245
|
+
* const rows = await stmt.execute({ limit: 100 });
|
|
246
|
+
* const rows2 = await stmt.execute({ limit: 50 });
|
|
247
|
+
* stmt.close();
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
prepare(source: string): Promise<Statement>;
|
|
251
|
+
/** Execute a VOS read pipeline and return typed rows. */
|
|
252
|
+
query<T = Record<string, unknown>>(source: string): Promise<T[]>;
|
|
253
|
+
/** Execute a VOS write program. */
|
|
254
|
+
execute(source: string): Promise<void>;
|
|
35
255
|
/**
|
|
36
|
-
*
|
|
37
|
-
*
|
|
256
|
+
* Publish a new schema version, migrating existing records when their
|
|
257
|
+
* shape no longer matches.
|
|
258
|
+
*
|
|
259
|
+
* Accepts raw `.vos` source or `@voml/vos` descriptors (same as
|
|
260
|
+
* {@link Database.ensureSchema}). Use `renames` to tell the engine which
|
|
261
|
+
* old type/field names map to the new ones — records that would otherwise
|
|
262
|
+
* look structurally unrelated get preserved.
|
|
38
263
|
*/
|
|
264
|
+
migrateSchema(documentOrSource: string | EmittableItem, ...rest: (EmittableItem | MigrateOptions)[]): Promise<void>;
|
|
265
|
+
/** Build a typed session-local micro definition (without registering). */
|
|
39
266
|
defineMicro<TArgs extends readonly UdfScalarDescriptor[], TReturn extends UdfScalarDescriptor>(definition: Parameters<typeof buildMicro<TArgs, TReturn>>[0]): DefinedMicro<TArgs, TReturn>;
|
|
40
267
|
/**
|
|
41
|
-
* Install a
|
|
42
|
-
*
|
|
43
|
-
* session-local and never written to `.yydb`.
|
|
268
|
+
* Install a session-local host micro into both the local registry and the
|
|
269
|
+
* native engine. Host micros never persist across processes.
|
|
44
270
|
*/
|
|
45
271
|
registerMicro<TArgs extends readonly UdfScalarDescriptor[], TReturn extends UdfScalarDescriptor>(definition: DefinedMicro<TArgs, TReturn>): Promise<MicroHandle>;
|
|
46
|
-
/** Invoke a registered scalar UDF on the
|
|
272
|
+
/** Invoke a registered scalar UDF on the native engine. */
|
|
47
273
|
callScalar(name: string, version: number, args: readonly (string | number | boolean | null)[]): Promise<string | number | boolean | null>;
|
|
48
|
-
/**
|
|
274
|
+
/** Release the native handle (best-effort; the engine also drops on GC). */
|
|
49
275
|
close(): Promise<void>;
|
|
50
276
|
}
|