@yydb/light-db 0.0.18 → 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.
Files changed (110) hide show
  1. package/dist/api/index.d.ts +4 -9
  2. package/dist/api/index.d.ts.map +1 -1
  3. package/dist/api/index.js +3 -6
  4. package/dist/api/index.js.map +1 -1
  5. package/dist/api/types.d.ts +71 -42
  6. package/dist/api/types.d.ts.map +1 -1
  7. package/dist/api/types.js +5 -3
  8. package/dist/api/types.js.map +1 -1
  9. package/dist/api/wasm-database.d.ts +134 -27
  10. package/dist/api/wasm-database.d.ts.map +1 -1
  11. package/dist/api/wasm-database.js +172 -28
  12. package/dist/api/wasm-database.js.map +1 -1
  13. package/dist/index.d.ts +14 -11
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +14 -11
  16. package/dist/index.js.map +1 -1
  17. package/dist/shared/micro.d.ts +86 -0
  18. package/dist/shared/micro.d.ts.map +1 -0
  19. package/dist/shared/micro.js +194 -0
  20. package/dist/shared/micro.js.map +1 -0
  21. package/dist/shared/udf-types.d.ts +31 -0
  22. package/dist/shared/udf-types.d.ts.map +1 -0
  23. package/dist/shared/udf-types.js +12 -0
  24. package/dist/shared/udf-types.js.map +1 -0
  25. package/package.json +5 -7
  26. package/readme.md +60 -63
  27. package/dist/api/database.d.ts +0 -101
  28. package/dist/api/database.d.ts.map +0 -1
  29. package/dist/api/database.js +0 -149
  30. package/dist/api/database.js.map +0 -1
  31. package/dist/api/schema.d.ts +0 -33
  32. package/dist/api/schema.d.ts.map +0 -1
  33. package/dist/api/schema.js +0 -80
  34. package/dist/api/schema.js.map +0 -1
  35. package/dist/api/transaction.d.ts +0 -26
  36. package/dist/api/transaction.d.ts.map +0 -1
  37. package/dist/api/transaction.js +0 -52
  38. package/dist/api/transaction.js.map +0 -1
  39. package/dist/codec/binary.d.ts +0 -196
  40. package/dist/codec/binary.d.ts.map +0 -1
  41. package/dist/codec/binary.js +0 -342
  42. package/dist/codec/binary.js.map +0 -1
  43. package/dist/codec/checksum.d.ts +0 -21
  44. package/dist/codec/checksum.d.ts.map +0 -1
  45. package/dist/codec/checksum.js +0 -46
  46. package/dist/codec/checksum.js.map +0 -1
  47. package/dist/codec/index.d.ts +0 -12
  48. package/dist/codec/index.d.ts.map +0 -1
  49. package/dist/codec/index.js +0 -10
  50. package/dist/codec/index.js.map +0 -1
  51. package/dist/codec/page.d.ts +0 -114
  52. package/dist/codec/page.d.ts.map +0 -1
  53. package/dist/codec/page.js +0 -225
  54. package/dist/codec/page.js.map +0 -1
  55. package/dist/codec/record.d.ts +0 -62
  56. package/dist/codec/record.d.ts.map +0 -1
  57. package/dist/codec/record.js +0 -82
  58. package/dist/codec/record.js.map +0 -1
  59. package/dist/core/broadcast.d.ts +0 -39
  60. package/dist/core/broadcast.d.ts.map +0 -1
  61. package/dist/core/broadcast.js +0 -54
  62. package/dist/core/broadcast.js.map +0 -1
  63. package/dist/core/checkpoint.d.ts +0 -23
  64. package/dist/core/checkpoint.d.ts.map +0 -1
  65. package/dist/core/checkpoint.js +0 -49
  66. package/dist/core/checkpoint.js.map +0 -1
  67. package/dist/core/engine.d.ts +0 -142
  68. package/dist/core/engine.d.ts.map +0 -1
  69. package/dist/core/engine.js +0 -304
  70. package/dist/core/engine.js.map +0 -1
  71. package/dist/core/index.d.ts +0 -17
  72. package/dist/core/index.d.ts.map +0 -1
  73. package/dist/core/index.js +0 -13
  74. package/dist/core/index.js.map +0 -1
  75. package/dist/core/lease.d.ts +0 -32
  76. package/dist/core/lease.d.ts.map +0 -1
  77. package/dist/core/lease.js +0 -81
  78. package/dist/core/lease.js.map +0 -1
  79. package/dist/core/records.d.ts +0 -49
  80. package/dist/core/records.d.ts.map +0 -1
  81. package/dist/core/records.js +0 -70
  82. package/dist/core/records.js.map +0 -1
  83. package/dist/core/recovery.d.ts +0 -43
  84. package/dist/core/recovery.d.ts.map +0 -1
  85. package/dist/core/recovery.js +0 -99
  86. package/dist/core/recovery.js.map +0 -1
  87. package/dist/core/wal.d.ts +0 -50
  88. package/dist/core/wal.d.ts.map +0 -1
  89. package/dist/core/wal.js +0 -114
  90. package/dist/core/wal.js.map +0 -1
  91. package/dist/storage/StorageAdapter.d.ts +0 -97
  92. package/dist/storage/StorageAdapter.d.ts.map +0 -1
  93. package/dist/storage/StorageAdapter.js +0 -9
  94. package/dist/storage/StorageAdapter.js.map +0 -1
  95. package/dist/storage/index.d.ts +0 -11
  96. package/dist/storage/index.d.ts.map +0 -1
  97. package/dist/storage/index.js +0 -10
  98. package/dist/storage/index.js.map +0 -1
  99. package/dist/storage/indexeddb/IndexedDbStorageAdapter.d.ts +0 -140
  100. package/dist/storage/indexeddb/IndexedDbStorageAdapter.d.ts.map +0 -1
  101. package/dist/storage/indexeddb/IndexedDbStorageAdapter.js +0 -403
  102. package/dist/storage/indexeddb/IndexedDbStorageAdapter.js.map +0 -1
  103. package/dist/storage/memory/MemoryStorageAdapter.d.ts +0 -76
  104. package/dist/storage/memory/MemoryStorageAdapter.d.ts.map +0 -1
  105. package/dist/storage/memory/MemoryStorageAdapter.js +0 -212
  106. package/dist/storage/memory/MemoryStorageAdapter.js.map +0 -1
  107. package/dist/storage/opfs/OpfsStorageAdapter.d.ts +0 -141
  108. package/dist/storage/opfs/OpfsStorageAdapter.d.ts.map +0 -1
  109. package/dist/storage/opfs/OpfsStorageAdapter.js +0 -400
  110. package/dist/storage/opfs/OpfsStorageAdapter.js.map +0 -1
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Host micro registry and definition helpers for `@yydb/light-db`.
3
+ *
4
+ * Mirrors the Node-side `@yydb/yydb` micro contract but speaks to the WASM
5
+ * session's JSON bridge (`registerMicroJson` / `callScalarJson`) instead of
6
+ * the N-API layer. No binary wire protocol is encoded here — Rust owns that.
7
+ */
8
+ /** Map a VOS descriptor onto its wire tag. Throws for unsupported kinds. */
9
+ export function udfWireKind(descriptor) {
10
+ switch (descriptor.kind) {
11
+ case 'i64':
12
+ return 'i64';
13
+ case 'bool':
14
+ return 'bool';
15
+ case 'utf8':
16
+ return 'text';
17
+ default:
18
+ throw new Error(`unsupported micro type descriptor: ${descriptor.kind}`);
19
+ }
20
+ }
21
+ let nextHostId = 1;
22
+ /**
23
+ * Per-session registry for JS functions behind opaque host handles.
24
+ *
25
+ * WASM keeps `hostId + functionId + handleVersion`, never the closure. The
26
+ * WASM session's `setMicroHostInvoker` should call
27
+ * {@link MicroSessionRegistry.invokeFromWire} to route host calls back into
28
+ * author code.
29
+ */
30
+ export class MicroSessionRegistry {
31
+ hostId;
32
+ nextFunctionId = 1;
33
+ byKey = new Map();
34
+ byFunctionId = new Map();
35
+ constructor(hostId = nextHostId++) {
36
+ this.hostId = hostId;
37
+ }
38
+ /** Installs a defined micro into this session registry. */
39
+ register(definition) {
40
+ const key = logicalKey(definition.name, definition.version);
41
+ if (this.byKey.has(key)) {
42
+ throw new Error(`micro already registered: ${definition.name}@${definition.version}`);
43
+ }
44
+ const functionId = String(this.nextFunctionId++);
45
+ const handle = {
46
+ name: definition.name,
47
+ version: definition.version,
48
+ functionId,
49
+ hostId: this.hostId,
50
+ implementationVersion: 1,
51
+ };
52
+ const entry = { handle, definition: definition };
53
+ this.byKey.set(key, entry);
54
+ this.byFunctionId.set(functionId, entry);
55
+ return handle;
56
+ }
57
+ /** Returns a registered micro by opaque host handle. */
58
+ resolve(handle) {
59
+ if (handle.hostId !== this.hostId) {
60
+ return undefined;
61
+ }
62
+ return this.byFunctionId.get(handle.functionId)?.definition;
63
+ }
64
+ /** Invokes a registered micro from a wire `MicroHostInvoke` payload. */
65
+ invokeFromWire(payload) {
66
+ const handle = {
67
+ hostId: payload.hostId,
68
+ functionId: payload.functionId,
69
+ implementationVersion: payload.handleVersion,
70
+ name: '',
71
+ version: 0,
72
+ };
73
+ const definition = this.resolve(handle);
74
+ if (!definition) {
75
+ throw new Error(`micro not found: ${payload.functionId}`);
76
+ }
77
+ const args = definition.args.map((descriptor, index) => wireToBoundary(descriptor, payload.args[index]));
78
+ return boundaryToWire(definition.returns, this.invokeScalar(handle, args));
79
+ }
80
+ /** Direct scalar invocation (host adapter entry point). */
81
+ invokeScalar(handle, args) {
82
+ const definition = this.resolve(handle);
83
+ if (!definition) {
84
+ throw new Error(`micro not found: ${handle.functionId}`);
85
+ }
86
+ if (definition.mode !== 'scalar') {
87
+ throw new Error(`micro ${definition.name} is not scalar mode`);
88
+ }
89
+ if (args.length !== definition.args.length) {
90
+ throw new Error(`micro ${definition.name} arity mismatch: expected ${definition.args.length}, got ${args.length}`);
91
+ }
92
+ definition.args.forEach((descriptor, index) => {
93
+ validateValue(descriptor, args[index], `micro ${definition.name} arg ${index}`);
94
+ });
95
+ const result = definition.fn(...args);
96
+ validateValue(definition.returns, result, `micro ${definition.name} return`);
97
+ return result;
98
+ }
99
+ /** Lists logical names currently registered in this session. */
100
+ list() {
101
+ return [...this.byKey.values()].map((entry) => entry.definition.name).sort();
102
+ }
103
+ }
104
+ /** Build a session-local micro definition without registering it. */
105
+ export function defineMicro(input) {
106
+ if (!input.name.trim()) {
107
+ throw new Error('micro name must not be empty');
108
+ }
109
+ if (!Number.isInteger(input.version) || input.version <= 0) {
110
+ throw new Error('micro version must be a positive integer');
111
+ }
112
+ if (input.effect !== 'pure') {
113
+ throw new Error('TS micro effect must be pure in Phase 1');
114
+ }
115
+ if (!input.deterministic) {
116
+ throw new Error('TS micro must be deterministic in Phase 1');
117
+ }
118
+ if (typeof input.fn !== 'function') {
119
+ throw new Error('micro fn must be a function');
120
+ }
121
+ input.args.forEach((descriptor, index) => {
122
+ assertSupportedDescriptor(descriptor, `micro ${input.name} arg ${index}`);
123
+ });
124
+ assertSupportedDescriptor(input.returns, `micro ${input.name} return`);
125
+ return {
126
+ name: input.name,
127
+ version: input.version,
128
+ args: input.args,
129
+ returns: input.returns,
130
+ effect: input.effect,
131
+ deterministic: input.deterministic,
132
+ mode: input.mode ?? 'scalar',
133
+ placement: 'host',
134
+ fn: input.fn,
135
+ };
136
+ }
137
+ /** Stable 32-byte fingerprint for a logical micro name and version. */
138
+ export function microFingerprint(name, version) {
139
+ const bytes = new Uint8Array(32);
140
+ const seed = `${name}@${version}`;
141
+ for (let index = 0; index < bytes.byteLength; index += 1) {
142
+ bytes[index] = seed.charCodeAt(index % seed.length) & 0xff;
143
+ }
144
+ return bytes;
145
+ }
146
+ function logicalKey(name, version) {
147
+ return `${name}@${version}`;
148
+ }
149
+ function assertSupportedDescriptor(descriptor, label) {
150
+ try {
151
+ udfWireKind(descriptor);
152
+ }
153
+ catch {
154
+ throw new Error(`${label} uses a descriptor outside the Phase-1 micro subset`);
155
+ }
156
+ }
157
+ /** Validate a boundary value against a descriptor. */
158
+ function validateValue(descriptor, value, label) {
159
+ switch (udfWireKind(descriptor)) {
160
+ case 'i64':
161
+ if (typeof value !== 'bigint') {
162
+ throw new Error(`${label} expects VOS \`i64\` (a bigint)`);
163
+ }
164
+ break;
165
+ case 'bool':
166
+ if (typeof value !== 'boolean') {
167
+ throw new Error(`${label} expects VOS \`bool\``);
168
+ }
169
+ break;
170
+ case 'text':
171
+ if (typeof value !== 'string') {
172
+ throw new Error(`${label} expects VOS \`utf8\` (a string)`);
173
+ }
174
+ break;
175
+ }
176
+ }
177
+ /** Convert a wire value (number for i64, string, bool, null) to a boundary value. */
178
+ function wireToBoundary(descriptor, value) {
179
+ if (udfWireKind(descriptor) === 'i64' && typeof value === 'number' && Number.isSafeInteger(value)) {
180
+ return BigInt(value);
181
+ }
182
+ return value;
183
+ }
184
+ /** Boundary value → wire subset; i64 must still fit a JS number. */
185
+ function boundaryToWire(descriptor, value) {
186
+ if (udfWireKind(descriptor) === 'i64' && typeof value === 'bigint') {
187
+ if (value > BigInt(Number.MAX_SAFE_INTEGER) || value < BigInt(Number.MIN_SAFE_INTEGER)) {
188
+ throw new Error(`micro return i64 ${value} does not fit the wire number path`);
189
+ }
190
+ return Number(value);
191
+ }
192
+ return value;
193
+ }
194
+ //# sourceMappingURL=micro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"micro.js","sourceRoot":"","sources":["../../src/shared/micro.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Host micro (UDF) boundary types — browser WASM product subset.
3
+ *
4
+ * Descriptors come straight from `@voml/vos`: `v.i64()`, `v.bool()`, `v.utf8()`.
5
+ * `@yydb/light-db` keeps no scalar descriptor algebra of its own — it simply
6
+ * re-exports the VOS descriptors the Phase-1 UDF boundary accepts.
7
+ *
8
+ * `null` is not a descriptor; it is a value carried by the wire subset.
9
+ * This module is types-only and can be stripped at compile time.
10
+ */
11
+ import type { Infer, TypeDescriptor } from '@voml/vos';
12
+ /** Phase-1 scalar kinds on the YY wire micro path, aligned with `yydb-udf`. */
13
+ export type UdfScalarKind = 'i64' | 'bool' | 'text' | 'null';
14
+ /**
15
+ * VOS descriptors accepted at the Phase-1 host micro boundary.
16
+ *
17
+ * Non-scalar descriptors (`v.optional(…)`, `v.list(…)`, `v.utf16()`, …) are
18
+ * rejected before they reach the wire.
19
+ */
20
+ export type UdfScalarDescriptor = TypeDescriptor<'i64', bigint> | TypeDescriptor<'bool', boolean> | TypeDescriptor<'utf8', string>;
21
+ /** Maps a descriptor tuple to positional boundary value types. */
22
+ export type InferUdfArgs<T extends readonly UdfScalarDescriptor[]> = {
23
+ [K in keyof T]: Infer<T[K]>;
24
+ };
25
+ /** Maps a return descriptor to its boundary value type. */
26
+ export type InferUdfReturn<T extends UdfScalarDescriptor> = Infer<T>;
27
+ /** Session micro effect surface (Phase 1: pure only). */
28
+ export type MicroEffect = 'pure';
29
+ /** Invocation mode — scalar for Phase 1, batch reserved for future. */
30
+ export type MicroInvocationMode = 'scalar' | 'batch';
31
+ //# sourceMappingURL=udf-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"udf-types.d.ts","sourceRoot":"","sources":["../../src/shared/udf-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEvD,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7D;;;;;GAKG;AACH,MAAM,MAAM,mBAAmB,GACzB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,GAC7B,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAErC,kEAAkE;AAClE,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,SAAS,mBAAmB,EAAE,IAAI;KAChE,CAAC,IAAI,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;CAC9B,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,cAAc,CAAC,CAAC,SAAS,mBAAmB,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;AAErE,yDAAyD;AACzD,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC;AAEjC,uEAAuE;AACvE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,OAAO,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Host micro (UDF) boundary types — browser WASM product subset.
3
+ *
4
+ * Descriptors come straight from `@voml/vos`: `v.i64()`, `v.bool()`, `v.utf8()`.
5
+ * `@yydb/light-db` keeps no scalar descriptor algebra of its own — it simply
6
+ * re-exports the VOS descriptors the Phase-1 UDF boundary accepts.
7
+ *
8
+ * `null` is not a descriptor; it is a value carried by the wire subset.
9
+ * This module is types-only and can be stripped at compile time.
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=udf-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"udf-types.js","sourceRoot":"","sources":["../../src/shared/udf-types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@yydb/light-db",
3
- "version": "0.0.18",
4
- "description": "Light DB — browser-native YYDB database written in pure TypeScript",
3
+ "version": "0.1.2",
4
+ "description": "Light DB — browser-native YYDB database backed by Rust WASM (yydb-unknown-wasm32)",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "files": [
@@ -9,9 +9,7 @@
9
9
  ],
10
10
  "scripts": {
11
11
  "build": "tsc",
12
- "typecheck": "tsc --noEmit",
13
- "test": "tsx tests/index.ts",
14
- "test:browser": "tsx tests/browser/run.ts"
12
+ "typecheck": "tsc --noEmit"
15
13
  },
16
14
  "keywords": [
17
15
  "yydb",
@@ -43,7 +41,7 @@
43
41
  "typescript": "^5.3.0"
44
42
  },
45
43
  "dependencies": {
46
- "@voml/vos": "^0.0.1",
47
- "@yydb/yydb-unknown-wasm32": "0.0.18"
44
+ "@voml/vos": "^0.0.5",
45
+ "@yydb/yydb-unknown-wasm32": "0.1.2"
48
46
  }
49
47
  }
package/readme.md CHANGED
@@ -1,98 +1,91 @@
1
1
  # `@yydb/light-db`
2
2
 
3
- **Light DB** is the browser edition of YYDB: a database written in pure TypeScript that stores `.yydb`-style
4
- snapshots, WAL records and checkpoints in browser storage. It has no Node built-ins, no N-API bindings and no WASM in
5
- its runtime path.
3
+ **Light DB** is the browser-native edition of YYDB. A thin TypeScript facade over
4
+ `@yydb/yydb-unknown-wasm32`, which ships the Rust semantic core compiled to
5
+ WebAssembly — same engine as the Node-side `@yydb/yydb`, same OPFS persistence,
6
+ same VOS schema validation, same transaction and UDF semantics.
7
+
8
+ > No Node built-ins. No filesystem paths. No second semantic implementation.
9
+ > One package, one implementation: WASM-backed `Database`.
6
10
 
7
11
  ## Product relationship
8
12
 
9
13
  | Package | Role |
10
14
  |---------|------|
11
- | `@yydb/yydb` | Node product: native Rust engine, N-API, local `.yydb` / `.yydx` files and CLI |
12
- | `@yydb/light-db` | Browser product: pure TypeScript, OPFS / IndexedDB storage, Web APIs, same author surface |
13
- | `@yydb/yydb-client` | Remote wire client for a running `yydb serve` |
14
-
15
- ## Status
16
-
17
- Light DB is a migration of the original `LightDB.ts` engine, rebuilt around a browser-native architecture. The package
18
- ships as a pre-1.0 release of the browser product, so the author surface may still change between patch releases.
19
-
20
- Current coverage:
21
-
22
- - `pnpm test` runs the Node-side runner over codec, adapter and database logic (29 cases).
23
- - `pnpm test:browser` runs the conformance suite in an installed Chrome (16 cases): OPFS persistence across reopen, WAL
24
- recovery, checkpoint truncation, corruption detection, single-writer exclusion, transaction rollback and commit,
25
- schema and close notifications, and two-tab lease and broadcast behaviour.
15
+ | `@yydb/yydb` | Node product: native Rust engine, N-API, local `.yydb` / `.yydx` files, CLI |
16
+ | `@yydb/light-db` | **This package** — browser product: WASM core over OPFS, same author surface |
17
+ | `@yydb/yydb-client` | Remote wire client for a running `yydb serve` (TCP or WebSocket) |
26
18
 
27
19
  ## Usage
28
20
 
29
21
  ```ts
30
- import { LightDbError, openLightDatabase } from '@yydb/light-db';
22
+ import { Database } from '@yydb/light-db';
31
23
 
32
- const db = await openLightDatabase('app');
24
+ const db = await Database.open('app');
33
25
 
34
- await db.ensureSchema('// @yydb-schema-version: 1\nkv users');
35
- await db.put('user:1', new TextEncoder().encode('Ada'));
26
+ // Schema — either raw source or @voml/vos descriptors
27
+ await db.ensureSchema('table Setting { @@id: uuid, key: utf8 }');
28
+ // or: await db.ensureSchema(v.table('Setting', { key: v.text() }));
36
29
 
30
+ await db.put('user:1', new TextEncoder().encode('Ada'));
37
31
  const value = await db.get('user:1');
38
- await db.checkpoint();
32
+
33
+ // VOS read / write
34
+ const users = await db.query('User.all().take(10).collect()');
35
+ await db.execute('INSERT User { @@id: uuid(), name: "Ada" }');
36
+
37
+ // Transactions
38
+ await db.transaction(async (tx) => {
39
+ await tx.put('user:2', new TextEncoder().encode('Grace'));
40
+ await tx.put('user:3', new TextEncoder().encode('Eve'));
41
+ });
42
+
39
43
  await db.close();
40
44
  ```
41
45
 
42
- Public data types are browser-native: keys and values use `Uint8Array`, databases are addressed by name rather than by
43
- file path, and every lifecycle call is asynchronous.
44
-
45
46
  ## Author surface
46
47
 
47
48
  ```ts
48
- const db: LightDatabase = await openLightDatabase('app', options);
49
-
50
- await db.schema();
51
- await db.ensureSchema(document);
52
- await db.get(key);
53
- await db.put(key, value);
54
- await db.delete(key);
55
- await db.begin();
56
- await db.commit();
57
- await db.rollback();
58
- await db.checkpoint();
59
- db.stats();
60
- await db.close();
61
- ```
49
+ await db.serverVersion(); // engine version string
50
+ await db.info(); // session diagnostics
62
51
 
63
- `schema()` returns the persisted schema version and document. The document is the single source of truth: a second
64
- `ensureSchema` call must pass the identical document, otherwise it fails with `yydb.schema.conflict`. Keys starting with
65
- `__yydb__/` are reserved for the database.
52
+ await db.getSchema(); // { version, document } | null
53
+ await db.ensureSchema(document); // publish schema
54
+ await db.migrateSchema(source, { renames: [...] });
66
55
 
67
- ## Storage backends
56
+ await db.get(key); // Uint8Array | null
57
+ await db.put(key, value); // value: Uint8Array | string
58
+ await db.delete(key); // void
59
+ await db.scan({ prefix, after, limit });
68
60
 
69
- | Adapter | Use |
70
- |---------|-----|
71
- | `OpfsStorageAdapterFactory` | Default. Origin Private File System, positional reads and writes, atomic snapshot publication |
72
- | `IndexedDbStorageAdapterFactory` | Compatibility backend for hosts without OPFS |
73
- | `MemoryStorageBackend` | Tests and throwaway sessions |
61
+ await db.batch([{ key, value }, ...]);
62
+ await db.compareExchange(key, expected, replacement);
74
63
 
75
- `StorageAdapter` is the only platform boundary. Transactions, recovery and checkpoint semantics live in `core`, so
76
- backends implement files, not database behaviour.
64
+ await db.begin(); await db.commit(); await db.rollback();
65
+ await db.transaction(async (tx) => { ... });
77
66
 
78
- ## Concurrency
67
+ await db.query(source); // VOS read pipeline → typed rows[]
68
+ await db.execute(source); // VOS write program
79
69
 
80
- A writer holds a session-scoped `Web Locks` lease. A second tab that opens the same database fails with
81
- `yydb.lease.unavailable` and `retryable: true` instead of silently writing alongside the first one. When a lock manager
82
- is missing the call fails the same way; it never degrades to multiple writers.
70
+ await db.registerMicro(body); // host UDF wire-format registration
71
+ await db.callScalar(body); // host UDF invocation
72
+ await db.setMicroHostInvoker(fn); // JS → Rust UDF bridge
83
73
 
84
- `BroadcastChannel` carries `commit`, `schema` and `close` events so other same-origin contexts can discard stale views
85
- and retry after the lease is released. `listenDatabaseEvents(name, handler)` subscribes without opening the database.
74
+ await db.checkpoint(); // fold WAL into main file
75
+ await db.close();
76
+ ```
77
+
78
+ Data types are browser-native: keys are strings, values are `Uint8Array`,
79
+ databases are addressed by name (no file paths), and every lifecycle call is
80
+ `async`.
86
81
 
87
82
  ## Layout
88
83
 
89
84
  | Path | Role |
90
85
  |------|------|
91
- | `src/api/` | Public database, transaction, schema and shared types |
92
- | `src/core/` | Records, WAL, checkpoint, recovery, writer lease and broadcast |
93
- | `src/storage/` | `StorageAdapter` plus OPFS, IndexedDB and memory backends |
94
- | `src/codec/` | Page, snapshot and WAL record encoding over `Uint8Array` |
95
- | `src/errors/` | Stable `yydb.*` error codes |
86
+ | `src/api/wasm-database.ts` | Main {@link Database} facade over WASM sessions |
87
+ | `src/api/types.ts` | Public type contract (SchemaVersion, ScanRow, LightDatabase, …) |
88
+ | `src/errors/` | Stable `yydb.*` error codes and envelope parsing |
96
89
 
97
90
  ## Errors
98
91
 
@@ -107,4 +100,8 @@ and retry after the lease is released. `listenDatabaseEvents(name, handler)` sub
107
100
  | `yydb.lease.unavailable` | Writer lease is held elsewhere or Web Locks is missing (retryable) |
108
101
  | `yydb.quota.exceeded` | Browser storage quota is exhausted |
109
102
 
110
- [YYDB overview](https://github.com/yy-database/yydb.rs)
103
+ ## See also
104
+
105
+ - [YYDB overview](https://github.com/yy-database/yydb)
106
+ - [@yydb/yydb-unknown-wasm32](https://github.com/yy-database/yydb/tree/dev/projects/packages/yydb-unknown-wasm32) — the Rust semantic core
107
+ - [Project structure](https://github.com/yy-database/yydb/tree/dev/projects/packages/homepage/documentation/zh-hans)
@@ -1,101 +0,0 @@
1
- /**
2
- * Schema 版本与文档。
3
- *
4
- * 共享类型:纯 TS {@link Database} 与 WASM {@link WasmDatabase} 都使用同一版本模型。
5
- */
6
- export interface SchemaVersion {
7
- version: number;
8
- document: string;
9
- }
10
- /** One row from a scan. */
11
- export interface ScanRow {
12
- key: string;
13
- value: Uint8Array;
14
- }
15
- /** Options for scan. */
16
- export interface ScanOptions {
17
- prefix?: string;
18
- after?: string | null;
19
- limit?: number;
20
- }
21
- /** One batch change. */
22
- export interface BatchChange {
23
- key: string;
24
- value: Uint8Array | string | null;
25
- }
26
- /** Options for migrateSchema. */
27
- export interface MigrateOptions {
28
- renames?: ReadonlyArray<{
29
- fromType: string;
30
- toType: string;
31
- } | {
32
- type: string;
33
- fromField: string;
34
- toField: string;
35
- }>;
36
- }
37
- /** 打开浏览器 WASM 数据库的选项。 */
38
- export interface OpenOptions {
39
- /** 使用内存 session(测试专用;默认使用 OPFS 持久 session)。 */
40
- memory?: boolean;
41
- }
42
- import type { CheckpointResult, StorageEngineStats } from '../core/engine.js';
43
- import type { LightDatabase, LightDatabaseOptions } from './types.js';
44
- /**
45
- * 浏览器可用的纯 TS 数据库实现。
46
- *
47
- * 与 Node 侧 `@yydb/yydb` 的 {@link Database} 同构:宿主靠 import 来源区分:
48
- *
49
- * ```ts
50
- * import { Database } from '@yydb/yydb'; // Node 原生
51
- * import { Database } from '@yydb/light-db'; // 浏览器纯 TS(本文件)
52
- * ```
53
- *
54
- * 完全不依赖 WASM;OPFS 持久化、WAL 恢复、检查点、事务都在 TypeScript 内完成。
55
- *
56
- * 默认后端是 `OpfsStorageAdapterFactory`;通过 `options.storage` 可以显式指定。
57
- */
58
- export declare class Database implements LightDatabase {
59
- /** 数据库名 */
60
- readonly name: string;
61
- private readonly engine;
62
- private readonly transaction;
63
- private constructor();
64
- /**
65
- * 打开数据库
66
- * @param name 数据库名
67
- * @param options 打开选项
68
- */
69
- static open(name: string, options?: LightDatabaseOptions): Promise<Database>;
70
- /** 读取已持久化的 schema */
71
- schema(): Promise<SchemaVersion | null>;
72
- /**
73
- * 声明 schema 文档
74
- *
75
- * 文档是唯一真相:首次写入后,重复调用必须传入完全相同的文档。
76
- */
77
- ensureSchema(document: string): Promise<void>;
78
- /** 读取键 */
79
- get(key: string): Promise<Uint8Array | null>;
80
- /** 写入键 */
81
- put(key: string, value: Uint8Array): Promise<void>;
82
- /** 删除键 */
83
- delete(key: string): Promise<boolean>;
84
- /** 开始事务 */
85
- begin(): Promise<void>;
86
- /** 提交事务 */
87
- commit(): Promise<void>;
88
- /** 回滚事务 */
89
- rollback(): Promise<void>;
90
- /** 执行检查点 */
91
- checkpoint(): Promise<CheckpointResult>;
92
- /** 统计信息 */
93
- stats(): StorageEngineStats;
94
- /** 关闭数据库 */
95
- close(): Promise<void>;
96
- /**
97
- * 校验用户键
98
- */
99
- private assertUserKey;
100
- }
101
- //# sourceMappingURL=database.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/api/database.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,2BAA2B;AAC3B,MAAM,WAAW,OAAO;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;CACrB;AAED,wBAAwB;AACxB,MAAM,WAAW,WAAW;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAwB;AACxB,MAAM,WAAW,WAAW;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,GAAG,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,iCAAiC;AACjC,MAAM,WAAW,cAAc;IAC3B,OAAO,CAAC,EAAE,aAAa,CACjB;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GACpC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CACzD,CAAC;CACL;AAED,yBAAyB;AACzB,MAAM,WAAW,WAAW;IACxB,+CAA+C;IAC/C,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAOD,OAAO,KAAK,EAAE,gBAAgB,EAAwB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAMpG,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAKtE;;;;;;;;;;;;;GAaG;AACH,qBAAa,QAAS,YAAW,aAAa;IAC1C,WAAW;IACX,SAAgB,IAAI,EAAE,MAAM,CAAC;IAE7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAE1C,OAAO;IAMP;;;;OAIG;WACiB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAmB7F,qBAAqB;IACR,MAAM,IAAI,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAKpD;;;;OAIG;IACU,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAmB1D,UAAU;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIzD,UAAU;IACG,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/D,UAAU;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlD,WAAW;IACE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAInC,WAAW;IACE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIpC,WAAW;IACE,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAItC,YAAY;IACC,UAAU,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAIpD,WAAW;IACJ,KAAK,IAAI,kBAAkB;IAIlC,YAAY;IACC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC;;OAEG;IACH,OAAO,CAAC,aAAa;CAWxB"}