verso-db 0.1.5 → 0.2.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +13 -7
  3. package/dist/BinaryHeap.d.ts +11 -1
  4. package/dist/BinaryHeap.d.ts.map +1 -1
  5. package/dist/BinaryHeap.js +138 -0
  6. package/dist/BinaryHeap.js.map +1 -0
  7. package/dist/Collection.d.ts +30 -4
  8. package/dist/Collection.d.ts.map +1 -1
  9. package/dist/Collection.js +1186 -0
  10. package/dist/Collection.js.map +1 -0
  11. package/dist/HNSWIndex.d.ts +59 -0
  12. package/dist/HNSWIndex.d.ts.map +1 -1
  13. package/dist/HNSWIndex.js +2818 -0
  14. package/dist/HNSWIndex.js.map +1 -0
  15. package/dist/MaxBinaryHeap.d.ts +2 -64
  16. package/dist/MaxBinaryHeap.d.ts.map +1 -1
  17. package/dist/MaxBinaryHeap.js +5 -0
  18. package/dist/MaxBinaryHeap.js.map +1 -0
  19. package/dist/SearchWorker.d.ts +57 -4
  20. package/dist/SearchWorker.d.ts.map +1 -1
  21. package/dist/SearchWorker.js +573 -0
  22. package/dist/SearchWorker.js.map +1 -0
  23. package/dist/VectorDB.d.ts.map +1 -1
  24. package/dist/VectorDB.js +246 -0
  25. package/dist/VectorDB.js.map +1 -0
  26. package/dist/WorkerPool.d.ts +32 -2
  27. package/dist/WorkerPool.d.ts.map +1 -1
  28. package/dist/WorkerPool.js +266 -0
  29. package/dist/WorkerPool.js.map +1 -0
  30. package/dist/backends/JsDistanceBackend.d.ts.map +1 -1
  31. package/dist/backends/JsDistanceBackend.js +163 -0
  32. package/dist/backends/JsDistanceBackend.js.map +1 -0
  33. package/dist/encoding/DeltaEncoder.d.ts +2 -2
  34. package/dist/encoding/DeltaEncoder.d.ts.map +1 -1
  35. package/dist/encoding/DeltaEncoder.js +199 -0
  36. package/dist/encoding/DeltaEncoder.js.map +1 -0
  37. package/dist/errors.js +97 -0
  38. package/dist/errors.js.map +1 -0
  39. package/dist/index.d.ts +3 -3
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +61 -42
  42. package/dist/index.js.map +1 -9
  43. package/dist/presets.js +205 -0
  44. package/dist/presets.js.map +1 -0
  45. package/dist/quantization/ScalarQuantizer.d.ts +0 -34
  46. package/dist/quantization/ScalarQuantizer.d.ts.map +1 -1
  47. package/dist/quantization/ScalarQuantizer.js +346 -0
  48. package/dist/quantization/ScalarQuantizer.js.map +1 -0
  49. package/dist/storage/BatchWriter.js +351 -0
  50. package/dist/storage/BatchWriter.js.map +1 -0
  51. package/dist/storage/BunStorageBackend.d.ts +7 -3
  52. package/dist/storage/BunStorageBackend.d.ts.map +1 -1
  53. package/dist/storage/BunStorageBackend.js +182 -0
  54. package/dist/storage/BunStorageBackend.js.map +1 -0
  55. package/dist/storage/MemoryBackend.js +109 -0
  56. package/dist/storage/MemoryBackend.js.map +1 -0
  57. package/dist/storage/OPFSBackend.d.ts.map +1 -1
  58. package/dist/storage/OPFSBackend.js +325 -0
  59. package/dist/storage/OPFSBackend.js.map +1 -0
  60. package/dist/storage/StorageBackend.js +12 -0
  61. package/dist/storage/StorageBackend.js.map +1 -0
  62. package/dist/storage/WriteAheadLog.js +321 -0
  63. package/dist/storage/WriteAheadLog.js.map +1 -0
  64. package/dist/storage/createStorageBackend.d.ts +4 -0
  65. package/dist/storage/createStorageBackend.d.ts.map +1 -1
  66. package/dist/storage/createStorageBackend.js +119 -0
  67. package/dist/storage/createStorageBackend.js.map +1 -0
  68. package/{src/storage/index.ts → dist/storage/index.js} +7 -27
  69. package/dist/storage/index.js.map +1 -0
  70. package/dist/storage/nodeFsRuntime.d.ts +14 -0
  71. package/dist/storage/nodeFsRuntime.d.ts.map +1 -0
  72. package/dist/storage/nodeFsRuntime.js +105 -0
  73. package/dist/storage/nodeFsRuntime.js.map +1 -0
  74. package/package.json +9 -7
  75. package/src/BinaryHeap.ts +0 -136
  76. package/src/Collection.ts +0 -1262
  77. package/src/HNSWIndex.ts +0 -2894
  78. package/src/MaxBinaryHeap.ts +0 -181
  79. package/src/SearchWorker.ts +0 -264
  80. package/src/VectorDB.ts +0 -319
  81. package/src/WorkerPool.ts +0 -222
  82. package/src/backends/JsDistanceBackend.ts +0 -171
  83. package/src/encoding/DeltaEncoder.ts +0 -236
  84. package/src/errors.ts +0 -110
  85. package/src/index.ts +0 -106
  86. package/src/presets.ts +0 -229
  87. package/src/quantization/ScalarQuantizer.ts +0 -487
  88. package/src/storage/BatchWriter.ts +0 -420
  89. package/src/storage/BunStorageBackend.ts +0 -199
  90. package/src/storage/MemoryBackend.ts +0 -122
  91. package/src/storage/OPFSBackend.ts +0 -348
  92. package/src/storage/StorageBackend.ts +0 -74
  93. package/src/storage/WriteAheadLog.ts +0 -379
  94. package/src/storage/createStorageBackend.ts +0 -137
@@ -0,0 +1,321 @@
1
+ /**
2
+ * Write-Ahead Log (WAL) for Incremental Index Updates
3
+ *
4
+ * Provides durability and efficient incremental writes for HNSW index operations.
5
+ * Instead of rewriting the entire index on each update, operations are appended
6
+ * to a log file. The log can be compacted into a full snapshot periodically.
7
+ *
8
+ * Benefits:
9
+ * - Fast appends (no full serialization)
10
+ * - Crash recovery (replay log after restart)
11
+ * - Reduced I/O for frequent updates
12
+ */
13
+ export var WALOperationType;
14
+ (function (WALOperationType) {
15
+ WALOperationType[WALOperationType["ADD_VECTOR"] = 1] = "ADD_VECTOR";
16
+ WALOperationType[WALOperationType["ADD_NEIGHBORS"] = 2] = "ADD_NEIGHBORS";
17
+ WALOperationType[WALOperationType["UPDATE_ENTRY_POINT"] = 3] = "UPDATE_ENTRY_POINT";
18
+ WALOperationType[WALOperationType["CHECKPOINT"] = 4] = "CHECKPOINT";
19
+ })(WALOperationType || (WALOperationType = {}));
20
+ /**
21
+ * WriteAheadLog - Append-only log for incremental index updates
22
+ */
23
+ export class WriteAheadLog {
24
+ storage;
25
+ logKey;
26
+ pendingEntries = [];
27
+ flushThreshold;
28
+ entryCount = 0;
29
+ flushPromise = null;
30
+ /**
31
+ * Create a new WAL
32
+ * @param storage StorageBackend for persistence
33
+ * @param logKey Storage key for the WAL data (e.g., "myindex.wal")
34
+ * @param flushThreshold Number of entries before auto-flush (default: 100)
35
+ */
36
+ constructor(storage, logKey, flushThreshold = 100) {
37
+ this.storage = storage;
38
+ this.logKey = logKey;
39
+ this.flushThreshold = flushThreshold;
40
+ }
41
+ /**
42
+ * Get the WAL storage key
43
+ */
44
+ getKey() {
45
+ return this.logKey;
46
+ }
47
+ /**
48
+ * Check if WAL data exists
49
+ */
50
+ async exists() {
51
+ return this.storage.exists(this.logKey);
52
+ }
53
+ /**
54
+ * Append a vector addition operation to the log
55
+ */
56
+ async appendVector(id, vector) {
57
+ // Format: [id (4 bytes)] [vector length (4 bytes)] [vector data]
58
+ const dataSize = 4 + 4 + vector.length * 4;
59
+ const buffer = new ArrayBuffer(dataSize);
60
+ const view = new DataView(buffer);
61
+ view.setUint32(0, id, true);
62
+ view.setUint32(4, vector.length, true);
63
+ const floatView = new Float32Array(buffer, 8);
64
+ floatView.set(vector);
65
+ const entry = {
66
+ type: WALOperationType.ADD_VECTOR,
67
+ timestamp: Date.now(),
68
+ data: buffer,
69
+ };
70
+ this.pendingEntries.push(entry);
71
+ this.entryCount++;
72
+ if (this.pendingEntries.length >= this.flushThreshold) {
73
+ await this.flush();
74
+ }
75
+ }
76
+ /**
77
+ * Append a neighbor update operation to the log
78
+ */
79
+ async appendNeighbors(nodeId, layer, neighbors) {
80
+ // Format: [nodeId (4)] [layer (4)] [neighborCount (4)] [neighbors...]
81
+ const dataSize = 4 + 4 + 4 + neighbors.length * 4;
82
+ const buffer = new ArrayBuffer(dataSize);
83
+ const view = new DataView(buffer);
84
+ view.setUint32(0, nodeId, true);
85
+ view.setUint32(4, layer, true);
86
+ view.setUint32(8, neighbors.length, true);
87
+ let offset = 12;
88
+ for (const neighbor of neighbors) {
89
+ view.setUint32(offset, neighbor, true);
90
+ offset += 4;
91
+ }
92
+ const entry = {
93
+ type: WALOperationType.ADD_NEIGHBORS,
94
+ timestamp: Date.now(),
95
+ data: buffer,
96
+ };
97
+ this.pendingEntries.push(entry);
98
+ this.entryCount++;
99
+ if (this.pendingEntries.length >= this.flushThreshold) {
100
+ await this.flush();
101
+ }
102
+ }
103
+ /**
104
+ * Append entry point update to the log
105
+ */
106
+ async appendEntryPointUpdate(entryPointId, maxLevel) {
107
+ const buffer = new ArrayBuffer(8);
108
+ const view = new DataView(buffer);
109
+ view.setInt32(0, entryPointId, true);
110
+ view.setInt32(4, maxLevel, true);
111
+ const entry = {
112
+ type: WALOperationType.UPDATE_ENTRY_POINT,
113
+ timestamp: Date.now(),
114
+ data: buffer,
115
+ };
116
+ this.pendingEntries.push(entry);
117
+ this.entryCount++;
118
+ if (this.pendingEntries.length >= this.flushThreshold) {
119
+ await this.flush();
120
+ }
121
+ }
122
+ /**
123
+ * Write a checkpoint marker to the log
124
+ */
125
+ async checkpoint() {
126
+ const buffer = new ArrayBuffer(8);
127
+ const view = new DataView(buffer);
128
+ view.setFloat64(0, Date.now(), true);
129
+ const entry = {
130
+ type: WALOperationType.CHECKPOINT,
131
+ timestamp: Date.now(),
132
+ data: buffer,
133
+ };
134
+ this.pendingEntries.push(entry);
135
+ this.entryCount++;
136
+ await this.flush();
137
+ }
138
+ /**
139
+ * Serialize a WAL entry to bytes
140
+ */
141
+ serializeEntry(entry) {
142
+ // Format: [type (1)] [timestamp (8)] [dataLength (4)] [data...]
143
+ const headerSize = 1 + 8 + 4;
144
+ const totalSize = headerSize + entry.data.byteLength;
145
+ const buffer = new ArrayBuffer(totalSize);
146
+ const view = new DataView(buffer);
147
+ view.setUint8(0, entry.type);
148
+ view.setFloat64(1, entry.timestamp, true);
149
+ view.setUint32(9, entry.data.byteLength, true);
150
+ const dataView = new Uint8Array(buffer, headerSize);
151
+ dataView.set(new Uint8Array(entry.data));
152
+ return new Uint8Array(buffer);
153
+ }
154
+ /**
155
+ * Flush pending entries to storage
156
+ * Uses append for efficient O(1) writes
157
+ */
158
+ async flush() {
159
+ while (true) {
160
+ if (this.flushPromise) {
161
+ await this.flushPromise;
162
+ }
163
+ if (this.pendingEntries.length === 0) {
164
+ return;
165
+ }
166
+ // Capture and clear atomically before async work to avoid losing
167
+ // entries added by concurrent appendVector() calls during the await.
168
+ const toFlush = this.pendingEntries;
169
+ this.pendingEntries = [];
170
+ const currentFlush = this.flushEntries(toFlush);
171
+ this.flushPromise = currentFlush;
172
+ try {
173
+ await currentFlush;
174
+ }
175
+ finally {
176
+ if (this.flushPromise === currentFlush) {
177
+ this.flushPromise = null;
178
+ }
179
+ }
180
+ }
181
+ }
182
+ async flushEntries(toFlush) {
183
+ // Serialize captured entries
184
+ const serializedEntries = toFlush.map(e => this.serializeEntry(e));
185
+ // Calculate total size
186
+ let totalSize = 0;
187
+ for (const entry of serializedEntries) {
188
+ totalSize += entry.length;
189
+ }
190
+ // Combine into single buffer
191
+ const combined = new Uint8Array(totalSize);
192
+ let offset = 0;
193
+ for (const entry of serializedEntries) {
194
+ combined.set(entry, offset);
195
+ offset += entry.length;
196
+ }
197
+ // Append to storage
198
+ try {
199
+ await this.storage.append(this.logKey, combined);
200
+ }
201
+ catch (err) {
202
+ // Restore entries on failure so they aren't lost
203
+ this.pendingEntries = [...toFlush, ...this.pendingEntries];
204
+ throw err;
205
+ }
206
+ }
207
+ /**
208
+ * Read all entries from the WAL
209
+ */
210
+ async readEntries() {
211
+ const data = await this.storage.read(this.logKey);
212
+ if (!data || data.byteLength === 0) {
213
+ return [];
214
+ }
215
+ const buffer = data;
216
+ const view = new DataView(buffer);
217
+ const entries = [];
218
+ const headerSize = 13; // 1 (type) + 8 (timestamp) + 4 (dataLength)
219
+ let offset = 0;
220
+ while (offset < buffer.byteLength) {
221
+ // Check we can read the header
222
+ if (offset + headerSize > buffer.byteLength) {
223
+ console.warn(`WAL: truncated entry header at offset ${offset}, stopping replay`);
224
+ break;
225
+ }
226
+ // Read header
227
+ const type = view.getUint8(offset);
228
+ const timestamp = view.getFloat64(offset + 1, true);
229
+ const dataLength = view.getUint32(offset + 9, true);
230
+ // Validate data length
231
+ if (dataLength > buffer.byteLength - offset - headerSize) {
232
+ console.warn(`WAL: truncated entry data at offset ${offset} (expected ${dataLength} bytes, only ${buffer.byteLength - offset - headerSize} available), stopping replay`);
233
+ break;
234
+ }
235
+ // Validate operation type
236
+ if (type < 1 || type > 4) {
237
+ console.warn(`WAL: unknown operation type ${type} at offset ${offset}, stopping replay`);
238
+ break;
239
+ }
240
+ // Read data
241
+ const entryData = buffer.slice(offset + headerSize, offset + headerSize + dataLength);
242
+ entries.push({ type, timestamp, data: entryData });
243
+ offset += headerSize + dataLength;
244
+ }
245
+ this.entryCount = entries.length + this.pendingEntries.length;
246
+ return entries;
247
+ }
248
+ /**
249
+ * Parse a vector addition entry
250
+ */
251
+ static parseVectorEntry(data) {
252
+ const view = new DataView(data);
253
+ const id = view.getUint32(0, true);
254
+ const vectorLength = view.getUint32(4, true);
255
+ const vector = new Float32Array(data, 8, vectorLength);
256
+ return { id, vector };
257
+ }
258
+ /**
259
+ * Parse a neighbor update entry
260
+ */
261
+ static parseNeighborsEntry(data) {
262
+ const view = new DataView(data);
263
+ const nodeId = view.getUint32(0, true);
264
+ const layer = view.getUint32(4, true);
265
+ const neighborCount = view.getUint32(8, true);
266
+ const neighbors = [];
267
+ for (let i = 0; i < neighborCount; i++) {
268
+ neighbors.push(view.getUint32(12 + i * 4, true));
269
+ }
270
+ return { nodeId, layer, neighbors };
271
+ }
272
+ /**
273
+ * Parse an entry point update entry
274
+ */
275
+ static parseEntryPointEntry(data) {
276
+ const view = new DataView(data);
277
+ return {
278
+ entryPointId: view.getInt32(0, true),
279
+ maxLevel: view.getInt32(4, true),
280
+ };
281
+ }
282
+ /**
283
+ * Get entry count since last compact
284
+ */
285
+ getEntryCount() {
286
+ return this.entryCount;
287
+ }
288
+ /**
289
+ * Clear the WAL (after successful compaction)
290
+ */
291
+ async clear() {
292
+ if (this.flushPromise) {
293
+ await this.flushPromise.catch(() => { });
294
+ }
295
+ // Clear in-memory state first to prevent flush() from writing entries
296
+ // after we truncate the on-disk WAL.
297
+ this.pendingEntries = [];
298
+ this.entryCount = 0;
299
+ if (await this.storage.exists(this.logKey)) {
300
+ await this.storage.write(this.logKey, new Uint8Array(0));
301
+ }
302
+ }
303
+ /**
304
+ * Delete the WAL data
305
+ */
306
+ async delete() {
307
+ if (this.flushPromise) {
308
+ await this.flushPromise.catch(() => { });
309
+ }
310
+ // Clear in-memory state first to prevent race with concurrent appends
311
+ this.pendingEntries = [];
312
+ this.entryCount = 0;
313
+ try {
314
+ await this.storage.delete(this.logKey);
315
+ }
316
+ catch {
317
+ // Key may not exist
318
+ }
319
+ }
320
+ }
321
+ //# sourceMappingURL=WriteAheadLog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WriteAheadLog.js","sourceRoot":"","sources":["../../src/storage/WriteAheadLog.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,10 @@ export interface CreateStorageOptions extends StorageOptions {
12
12
  /** Force a specific storage type */
13
13
  type?: StorageType;
14
14
  }
15
+ /**
16
+ * Detect the current runtime environment
17
+ */
18
+ export declare function detectEnvironment(): 'bun' | 'browser' | 'node' | 'unknown';
15
19
  /**
16
20
  * Create the optimal storage backend for the current environment
17
21
  *
@@ -1 +1 @@
1
- {"version":3,"file":"createStorageBackend.d.ts","sourceRoot":"","sources":["../../src/storage/createStorageBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAKvE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,oCAAoC;IACpC,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAmBD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+ClG;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,WAAW,CAYvD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAajE"}
1
+ {"version":3,"file":"createStorageBackend.d.ts","sourceRoot":"","sources":["../../src/storage/createStorageBackend.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAMvE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE7D,MAAM,WAAW,oBAAqB,SAAQ,cAAc;IAC1D,oCAAoC;IACpC,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,KAAK,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAiB1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+ClG;AAED;;GAEG;AACH,wBAAgB,yBAAyB,IAAI,WAAW,CAYvD;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAajE"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Storage Backend Factory
3
+ *
4
+ * Auto-detects the best storage backend for the current environment:
5
+ * - Bun/Node.js: BunStorageBackend (file system)
6
+ * - Modern browsers: OPFSBackend (Origin Private File System)
7
+ * - Fallback: MemoryBackend (in-memory)
8
+ */
9
+ import { BunStorageBackend } from './BunStorageBackend.js';
10
+ import { MemoryBackend } from './MemoryBackend.js';
11
+ import { OPFSBackend } from './OPFSBackend.js';
12
+ import { StorageError } from '../errors.js';
13
+ /**
14
+ * Detect the current runtime environment
15
+ */
16
+ export function detectEnvironment() {
17
+ // Check for Bun
18
+ if (typeof Bun !== 'undefined') {
19
+ return 'bun';
20
+ }
21
+ // Check for browser
22
+ if (typeof window !== 'undefined' && typeof navigator !== 'undefined') {
23
+ return 'browser';
24
+ }
25
+ // Check for Node.js
26
+ if (typeof process !== 'undefined' && !!process.versions?.node) {
27
+ return 'node';
28
+ }
29
+ return 'unknown';
30
+ }
31
+ /**
32
+ * Create the optimal storage backend for the current environment
33
+ *
34
+ * @param options Configuration options
35
+ * @returns Initialized storage backend
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * // Auto-detect best backend
40
+ * const storage = await createStorageBackend();
41
+ *
42
+ * // Force specific backend
43
+ * const bunStorage = await createStorageBackend({ type: 'bun', path: './data' });
44
+ * const memStorage = await createStorageBackend({ type: 'memory' });
45
+ * ```
46
+ */
47
+ export async function createStorageBackend(options) {
48
+ const type = options?.type ?? 'auto';
49
+ // Force specific backend type
50
+ if (type === 'bun') {
51
+ const backend = new BunStorageBackend(options?.path ?? './vectordb_data');
52
+ await backend.init();
53
+ return backend;
54
+ }
55
+ if (type === 'opfs') {
56
+ if (!OPFSBackend.isAvailable()) {
57
+ throw new StorageError('init', 'OPFS not available in this environment');
58
+ }
59
+ const backend = new OPFSBackend();
60
+ await backend.init();
61
+ return backend;
62
+ }
63
+ if (type === 'memory') {
64
+ return new MemoryBackend();
65
+ }
66
+ // Auto-detect
67
+ const env = detectEnvironment();
68
+ if (env === 'bun' || env === 'node') {
69
+ const backend = new BunStorageBackend(options?.path ?? './vectordb_data');
70
+ await backend.init();
71
+ return backend;
72
+ }
73
+ if (env === 'browser') {
74
+ // Try OPFS first (modern browsers)
75
+ if (OPFSBackend.isAvailable()) {
76
+ try {
77
+ const backend = new OPFSBackend();
78
+ await backend.init();
79
+ return backend;
80
+ }
81
+ catch {
82
+ // Fall through to memory backend
83
+ }
84
+ }
85
+ }
86
+ // Fallback to memory backend
87
+ return new MemoryBackend();
88
+ }
89
+ /**
90
+ * Get the recommended storage type for the current environment
91
+ */
92
+ export function getRecommendedStorageType() {
93
+ const env = detectEnvironment();
94
+ if (env === 'bun' || env === 'node') {
95
+ return 'bun';
96
+ }
97
+ if (env === 'browser' && OPFSBackend.isAvailable()) {
98
+ return 'opfs';
99
+ }
100
+ return 'memory';
101
+ }
102
+ /**
103
+ * Check if a specific storage type is available
104
+ */
105
+ export function isStorageTypeAvailable(type) {
106
+ switch (type) {
107
+ case 'bun':
108
+ return typeof Bun !== 'undefined' || (typeof process !== 'undefined' && !!process.versions?.node);
109
+ case 'opfs':
110
+ return OPFSBackend.isAvailable();
111
+ case 'memory':
112
+ return true;
113
+ case 'auto':
114
+ return true;
115
+ default:
116
+ return false;
117
+ }
118
+ }
119
+ //# sourceMappingURL=createStorageBackend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createStorageBackend.js","sourceRoot":"","sources":["../../src/storage/createStorageBackend.ts"],"names":[],"mappings":"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"}
@@ -20,34 +20,14 @@
20
20
  * await wal.flush();
21
21
  * ```
22
22
  */
23
-
24
- // Storage backend interface and types
25
- export type { StorageBackend, StorageOptions } from './StorageBackend';
26
-
27
23
  // Storage backend implementations
28
- export { BunStorageBackend } from './BunStorageBackend';
29
- export { MemoryBackend } from './MemoryBackend';
30
- export { OPFSBackend } from './OPFSBackend';
31
-
24
+ export { BunStorageBackend } from './BunStorageBackend.js';
25
+ export { MemoryBackend } from './MemoryBackend.js';
26
+ export { OPFSBackend } from './OPFSBackend.js';
32
27
  // Factory function and utilities
33
- export {
34
- createStorageBackend,
35
- getRecommendedStorageType,
36
- isStorageTypeAvailable,
37
- type StorageType,
38
- type CreateStorageOptions,
39
- } from './createStorageBackend';
40
-
28
+ export { createStorageBackend, getRecommendedStorageType, isStorageTypeAvailable, } from './createStorageBackend.js';
41
29
  // Write-ahead log for incremental updates
42
- export {
43
- WriteAheadLog,
44
- WALOperationType,
45
- type WALEntry,
46
- } from './WriteAheadLog';
47
-
30
+ export { WriteAheadLog, WALOperationType, } from './WriteAheadLog.js';
48
31
  // Batch write coalescing for reduced I/O
49
- export {
50
- BatchWriter,
51
- createBatchWriter,
52
- type BatchWriterOptions,
53
- } from './BatchWriter';
32
+ export { BatchWriter, createBatchWriter, } from './BatchWriter.js';
33
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,kCAAkC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,iCAAiC;AACjC,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,GAGvB,MAAM,wBAAwB,CAAC;AAEhC,0CAA0C;AAC1C,OAAO,EACL,aAAa,EACb,gBAAgB,GAEjB,MAAM,iBAAiB,CAAC;AAEzB,yCAAyC;AACzC,OAAO,EACL,WAAW,EACX,iBAAiB,GAElB,MAAM,eAAe,CAAC"}
@@ -0,0 +1,14 @@
1
+ export declare function resolveBasePath(basePath: string): string;
2
+ export declare function resolveStoragePath(basePath: string, key: string): string;
3
+ export declare function dirname(fullPath: string): string;
4
+ export declare function ensureDir(dir: string): Promise<void>;
5
+ export declare function read(fullPath: string): Promise<ArrayBuffer | null>;
6
+ export declare function writeAtomic(fullPath: string, data: ArrayBuffer | Uint8Array): Promise<void>;
7
+ export declare function append(fullPath: string, data: ArrayBuffer | Uint8Array): Promise<void>;
8
+ export declare function deleteFile(fullPath: string): Promise<void>;
9
+ export declare function exists(fullPath: string): Promise<boolean>;
10
+ export declare function list(basePath: string, searchPath: string): Promise<string[]>;
11
+ export declare function clear(basePath: string): Promise<string>;
12
+ export declare function size(fullPath: string): Promise<number>;
13
+ export declare function stream(fullPath: string): ReadableStream<Uint8Array>;
14
+ //# sourceMappingURL=nodeFsRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeFsRuntime.d.ts","sourceRoot":"","sources":["../../src/storage/nodeFsRuntime.ts"],"names":[],"mappings":"AAMA,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOxE;AAED,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAsB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE1D;AAED,wBAAsB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAUxE;AAED,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5F;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQhE;AAED,wBAAsB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAU/D;AAED,wBAAsB,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAelF;AAED,wBAAsB,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAK7D;AAED,wBAAsB,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAU5D;AAED,wBAAgB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAEnE"}
@@ -0,0 +1,105 @@
1
+ import { mkdir, readdir, unlink, rm, appendFile, rename, readFile, writeFile, stat } from 'node:fs/promises';
2
+ import { createReadStream } from 'node:fs';
3
+ import * as path from 'node:path';
4
+ import { Readable } from 'node:stream';
5
+ import { StorageError } from '../errors.js';
6
+ export function resolveBasePath(basePath) {
7
+ return path.resolve(basePath);
8
+ }
9
+ export function resolveStoragePath(basePath, key) {
10
+ const fullPath = path.resolve(basePath, key);
11
+ const resolvedBase = resolveBasePath(basePath);
12
+ if (!fullPath.startsWith(resolvedBase + path.sep) && fullPath !== resolvedBase) {
13
+ throw new StorageError('validate', `Path traversal detected: key '${key}' resolves outside storage directory`);
14
+ }
15
+ return fullPath;
16
+ }
17
+ export function dirname(fullPath) {
18
+ return path.dirname(fullPath);
19
+ }
20
+ export async function ensureDir(dir) {
21
+ await mkdir(dir, { recursive: true });
22
+ }
23
+ export async function read(fullPath) {
24
+ try {
25
+ const data = await readFile(fullPath);
26
+ return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
27
+ }
28
+ catch (err) {
29
+ if (err?.code === 'ENOENT') {
30
+ return null;
31
+ }
32
+ throw err;
33
+ }
34
+ }
35
+ export async function writeAtomic(fullPath, data) {
36
+ const tmpPath = fullPath + '.tmp';
37
+ await writeFile(tmpPath, data instanceof ArrayBuffer ? new Uint8Array(data) : data);
38
+ await rename(tmpPath, fullPath);
39
+ }
40
+ export async function append(fullPath, data) {
41
+ const appendData = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
42
+ await appendFile(fullPath, appendData);
43
+ }
44
+ export async function deleteFile(fullPath) {
45
+ try {
46
+ await unlink(fullPath);
47
+ }
48
+ catch (err) {
49
+ if (err?.code !== 'ENOENT') {
50
+ throw err;
51
+ }
52
+ }
53
+ }
54
+ export async function exists(fullPath) {
55
+ try {
56
+ await stat(fullPath);
57
+ return true;
58
+ }
59
+ catch (err) {
60
+ if (err?.code === 'ENOENT') {
61
+ return false;
62
+ }
63
+ throw err;
64
+ }
65
+ }
66
+ export async function list(basePath, searchPath) {
67
+ try {
68
+ const entries = await readdir(searchPath, { recursive: true, withFileTypes: true });
69
+ const resolvedBase = resolveBasePath(basePath);
70
+ const results = [];
71
+ for (const entry of entries) {
72
+ if (!entry.isFile())
73
+ continue;
74
+ const entryDir = entry.parentPath ?? entry.path ?? searchPath;
75
+ const fullPath = path.join(entryDir, entry.name);
76
+ results.push(path.relative(resolvedBase, fullPath));
77
+ }
78
+ return results;
79
+ }
80
+ catch {
81
+ return [];
82
+ }
83
+ }
84
+ export async function clear(basePath) {
85
+ const resolvedBase = resolveBasePath(basePath);
86
+ await rm(resolvedBase, { recursive: true, force: true }).catch(() => { });
87
+ await mkdir(resolvedBase, { recursive: true }).catch(() => { });
88
+ return resolvedBase;
89
+ }
90
+ export async function size(fullPath) {
91
+ try {
92
+ const stats = await stat(fullPath);
93
+ return stats.size;
94
+ }
95
+ catch (err) {
96
+ if (err?.code === 'ENOENT') {
97
+ return 0;
98
+ }
99
+ throw err;
100
+ }
101
+ }
102
+ export function stream(fullPath) {
103
+ return Readable.toWeb(createReadStream(fullPath));
104
+ }
105
+ //# sourceMappingURL=nodeFsRuntime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nodeFsRuntime.js","sourceRoot":"","sources":["../../src/storage/nodeFsRuntime.ts"],"names":[],"mappings":"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"}