verso-db 0.1.1

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 (68) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/LICENSE +21 -0
  3. package/README.md +252 -0
  4. package/dist/BinaryHeap.d.ts +25 -0
  5. package/dist/BinaryHeap.d.ts.map +1 -0
  6. package/dist/Collection.d.ts +156 -0
  7. package/dist/Collection.d.ts.map +1 -0
  8. package/dist/HNSWIndex.d.ts +357 -0
  9. package/dist/HNSWIndex.d.ts.map +1 -0
  10. package/dist/MaxBinaryHeap.d.ts +63 -0
  11. package/dist/MaxBinaryHeap.d.ts.map +1 -0
  12. package/dist/Storage.d.ts +54 -0
  13. package/dist/Storage.d.ts.map +1 -0
  14. package/dist/VectorDB.d.ts +44 -0
  15. package/dist/VectorDB.d.ts.map +1 -0
  16. package/dist/backends/DistanceBackend.d.ts +5 -0
  17. package/dist/backends/DistanceBackend.d.ts.map +1 -0
  18. package/dist/backends/JsDistanceBackend.d.ts +37 -0
  19. package/dist/backends/JsDistanceBackend.d.ts.map +1 -0
  20. package/dist/encoding/DeltaEncoder.d.ts +61 -0
  21. package/dist/encoding/DeltaEncoder.d.ts.map +1 -0
  22. package/dist/errors.d.ts +58 -0
  23. package/dist/errors.d.ts.map +1 -0
  24. package/dist/index.d.ts +64 -0
  25. package/dist/index.d.ts.map +1 -0
  26. package/dist/index.js +3732 -0
  27. package/dist/presets.d.ts +91 -0
  28. package/dist/presets.d.ts.map +1 -0
  29. package/dist/quantization/ScalarQuantizer.d.ts +114 -0
  30. package/dist/quantization/ScalarQuantizer.d.ts.map +1 -0
  31. package/dist/storage/BatchWriter.d.ts +104 -0
  32. package/dist/storage/BatchWriter.d.ts.map +1 -0
  33. package/dist/storage/BunStorageBackend.d.ts +58 -0
  34. package/dist/storage/BunStorageBackend.d.ts.map +1 -0
  35. package/dist/storage/MemoryBackend.d.ts +44 -0
  36. package/dist/storage/MemoryBackend.d.ts.map +1 -0
  37. package/dist/storage/OPFSBackend.d.ts +59 -0
  38. package/dist/storage/OPFSBackend.d.ts.map +1 -0
  39. package/dist/storage/StorageBackend.d.ts +66 -0
  40. package/dist/storage/StorageBackend.d.ts.map +1 -0
  41. package/dist/storage/WriteAheadLog.d.ts +111 -0
  42. package/dist/storage/WriteAheadLog.d.ts.map +1 -0
  43. package/dist/storage/createStorageBackend.d.ts +40 -0
  44. package/dist/storage/createStorageBackend.d.ts.map +1 -0
  45. package/dist/storage/index.d.ts +30 -0
  46. package/dist/storage/index.d.ts.map +1 -0
  47. package/package.json +98 -0
  48. package/src/BinaryHeap.ts +131 -0
  49. package/src/Collection.ts +695 -0
  50. package/src/HNSWIndex.ts +1839 -0
  51. package/src/MaxBinaryHeap.ts +175 -0
  52. package/src/Storage.ts +435 -0
  53. package/src/VectorDB.ts +109 -0
  54. package/src/backends/DistanceBackend.ts +17 -0
  55. package/src/backends/JsDistanceBackend.ts +227 -0
  56. package/src/encoding/DeltaEncoder.ts +217 -0
  57. package/src/errors.ts +110 -0
  58. package/src/index.ts +138 -0
  59. package/src/presets.ts +229 -0
  60. package/src/quantization/ScalarQuantizer.ts +383 -0
  61. package/src/storage/BatchWriter.ts +336 -0
  62. package/src/storage/BunStorageBackend.ts +161 -0
  63. package/src/storage/MemoryBackend.ts +120 -0
  64. package/src/storage/OPFSBackend.ts +250 -0
  65. package/src/storage/StorageBackend.ts +74 -0
  66. package/src/storage/WriteAheadLog.ts +326 -0
  67. package/src/storage/createStorageBackend.ts +137 -0
  68. package/src/storage/index.ts +53 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WriteAheadLog.d.ts","sourceRoot":"","sources":["../../src/storage/WriteAheadLog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,oBAAY,gBAAgB;IAC1B,UAAU,IAAI;IACd,aAAa,IAAI;IACjB,kBAAkB,IAAI;IACtB,UAAU,IAAI;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,WAAW,CAAC;CACnB;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAkB;IACxC,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,UAAU,CAAa;IAE/B;;;;OAIG;gBACS,QAAQ,EAAE,MAAM,EAAE,cAAc,GAAE,MAAY;IAK1D;;OAEG;IACH,OAAO,IAAI,MAAM;IAIjB;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC;IAKhC;;OAEG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BnE;;OAEG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA8BxF;;OAEG;IACG,sBAAsB,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBnF;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAejC;;OAEG;IACH,OAAO,CAAC,cAAc;IAiBtB;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgC5B;;OAEG;IACG,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;IA4BxC;;OAEG;IACH,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,WAAW,GAAG;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,CAAA;KAAE;IAQhF;;OAEG;IACH,MAAM,CAAC,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE;IAcrG;;OAEG;IACH,MAAM,CAAC,oBAAoB,CAAC,IAAI,EAAE,WAAW,GAAG;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE;IAQ1F;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAS5B;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAS9B"}
@@ -0,0 +1,40 @@
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 type { StorageBackend, StorageOptions } from './StorageBackend';
10
+ export type StorageType = 'auto' | 'bun' | 'opfs' | 'memory';
11
+ export interface CreateStorageOptions extends StorageOptions {
12
+ /** Force a specific storage type */
13
+ type?: StorageType;
14
+ }
15
+ /**
16
+ * Create the optimal storage backend for the current environment
17
+ *
18
+ * @param options Configuration options
19
+ * @returns Initialized storage backend
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * // Auto-detect best backend
24
+ * const storage = await createStorageBackend();
25
+ *
26
+ * // Force specific backend
27
+ * const bunStorage = await createStorageBackend({ type: 'bun', path: './data' });
28
+ * const memStorage = await createStorageBackend({ type: 'memory' });
29
+ * ```
30
+ */
31
+ export declare function createStorageBackend(options?: CreateStorageOptions): Promise<StorageBackend>;
32
+ /**
33
+ * Get the recommended storage type for the current environment
34
+ */
35
+ export declare function getRecommendedStorageType(): StorageType;
36
+ /**
37
+ * Check if a specific storage type is available
38
+ */
39
+ export declare function isStorageTypeAvailable(type: StorageType): boolean;
40
+ //# sourceMappingURL=createStorageBackend.d.ts.map
@@ -0,0 +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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Storage Module
3
+ *
4
+ * Provides pluggable storage backends for vector index persistence.
5
+ * Supports multiple platforms:
6
+ * - Bun/Node.js: File system with Bun.file APIs
7
+ * - Modern browsers: OPFS (Origin Private File System)
8
+ * - Testing/fallback: In-memory storage
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { createStorageBackend, WriteAheadLog } from 'bun-vector-search/storage';
13
+ *
14
+ * // Auto-detect best storage for current environment
15
+ * const storage = await createStorageBackend();
16
+ *
17
+ * // Use WAL for incremental writes
18
+ * const wal = new WriteAheadLog('./index');
19
+ * await wal.appendVector(1, new Float32Array([1, 2, 3]));
20
+ * await wal.flush();
21
+ * ```
22
+ */
23
+ export type { StorageBackend, StorageOptions } from './StorageBackend';
24
+ export { BunStorageBackend } from './BunStorageBackend';
25
+ export { MemoryBackend } from './MemoryBackend';
26
+ export { OPFSBackend } from './OPFSBackend';
27
+ export { createStorageBackend, getRecommendedStorageType, isStorageTypeAvailable, type StorageType, type CreateStorageOptions, } from './createStorageBackend';
28
+ export { WriteAheadLog, WALOperationType, type WALEntry, } from './WriteAheadLog';
29
+ export { BatchWriter, createBatchWriter, type BatchWriterOptions, } from './BatchWriter';
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/storage/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,aAAa,EACb,gBAAgB,EAChB,KAAK,QAAQ,GACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC"}
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "verso-db",
3
+ "version": "0.1.1",
4
+ "description": "High-performance vector search with HNSW indexing for Bun and Browser. 100% recall, 4x memory reduction with Int8 quantization.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "bun": "./src/index.ts"
14
+ },
15
+ "./package.json": "./package.json"
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "src",
20
+ "README.md",
21
+ "LICENSE",
22
+ "CHANGELOG.md"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "scripts": {
28
+ "build": "bun build ./src/index.ts --outdir ./dist --target browser && bun run build:types",
29
+ "build:types": "tsc --emitDeclarationOnly --declaration --outDir ./dist",
30
+ "test": "bun test",
31
+ "test:browser": "vitest --config vitest.browser.config.ts run",
32
+ "test:browser:watch": "vitest --config vitest.browser.config.ts",
33
+ "test:browser:ui": "vitest --config vitest.browser.config.ts --ui",
34
+ "prepublishOnly": "bun run build",
35
+ "bench": "bun run benchmarks/vector_search.bench.ts && bun run benchmarks/hnsw.bench.ts && bun run benchmarks/storage.bench.ts",
36
+ "benchmark:recall": "bun run benchmarks/recall_validation.bench.ts",
37
+ "benchmark:memory": "bun run benchmarks/memory_usage_final.bench.ts",
38
+ "release": "semantic-release",
39
+ "publish:dry": "bunx npm publish --dry-run"
40
+ },
41
+ "keywords": [
42
+ "vector",
43
+ "search",
44
+ "hnsw",
45
+ "embedding",
46
+ "similarity",
47
+ "nearest-neighbor",
48
+ "knn",
49
+ "ann",
50
+ "bun",
51
+ "browser",
52
+ "opfs",
53
+ "rag",
54
+ "ai",
55
+ "machine-learning",
56
+ "typescript"
57
+ ],
58
+ "author": "Brian Sunter",
59
+ "license": "MIT",
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "git+https://github.com/briansunter/verso.git"
63
+ },
64
+ "bugs": {
65
+ "url": "https://github.com/briansunter/verso/issues"
66
+ },
67
+ "homepage": "https://github.com/briansunter/verso#readme",
68
+ "engines": {
69
+ "bun": ">=1.0.0"
70
+ },
71
+ "peerDependencies": {
72
+ "typescript": "^5"
73
+ },
74
+ "devDependencies": {
75
+ "@huggingface/hub": "^2.7.0",
76
+ "@lancedb/lancedb": "^0.22.3",
77
+ "@qdrant/js-client-rest": "^1.16.1",
78
+ "@semantic-release/changelog": "^6.0.3",
79
+ "@semantic-release/commit-analyzer": "^13.0.1",
80
+ "@semantic-release/git": "^10.0.1",
81
+ "@semantic-release/github": "^12.0.2",
82
+ "@semantic-release/npm": "^13.1.3",
83
+ "@semantic-release/release-notes-generator": "^14.1.0",
84
+ "@types/bun": "latest",
85
+ "@vitest/browser": "^4.0.14",
86
+ "@vitest/browser-playwright": "^4.0.14",
87
+ "hnsw": "^1.0.3",
88
+ "hyparquet": "^1.21.1",
89
+ "hyparquet-compressors": "^1.1.1",
90
+ "mitata": "^1.0.34",
91
+ "playwright": "^1.57.0",
92
+ "semantic-release": "^25.0.2",
93
+ "simsimd": "^6.5.5",
94
+ "typescript": "^5.0.0",
95
+ "vitest": "^4.0.14",
96
+ "wabt": "^1.0.39"
97
+ }
98
+ }
@@ -0,0 +1,131 @@
1
+ export class BinaryHeap {
2
+ private ids: Uint32Array;
3
+ private dists: Float32Array;
4
+ private _size: number;
5
+ private capacity: number;
6
+ private lastPoppedValue: number = 0;
7
+
8
+ constructor(capacity: number) {
9
+ this.capacity = capacity;
10
+ this.ids = new Uint32Array(capacity);
11
+ this.dists = new Float32Array(capacity);
12
+ this._size = 0;
13
+ }
14
+
15
+ /**
16
+ * Push an element onto the heap.
17
+ * When at capacity, simply returns without adding (caller manages bounds).
18
+ * This is the correct behavior for HNSW candidate exploration.
19
+ */
20
+ push(id: number, dist: number): void {
21
+ if (this._size >= this.capacity) {
22
+ // At capacity - don't add more elements.
23
+ // The caller is responsible for managing heap bounds.
24
+ return;
25
+ }
26
+
27
+ this.ids[this._size] = id;
28
+ this.dists[this._size] = dist;
29
+ this._size++;
30
+ this.heapifyUp(this._size - 1);
31
+ }
32
+
33
+ pop(): number {
34
+ if (this._size === 0) return -1;
35
+
36
+ const result = this.ids[0];
37
+ this.lastPoppedValue = this.dists[0];
38
+ this._size--;
39
+ if (this._size > 0) {
40
+ this.ids[0] = this.ids[this._size];
41
+ this.dists[0] = this.dists[this._size];
42
+ this.heapifyDown(0);
43
+ }
44
+ return result;
45
+ }
46
+
47
+ peek(): number {
48
+ return this._size > 0 ? this.ids[0] : -1;
49
+ }
50
+
51
+ peekValue(): number {
52
+ return this._size > 0 ? this.dists[0] : Infinity;
53
+ }
54
+
55
+ getLastPoppedValue(): number {
56
+ return this.lastPoppedValue;
57
+ }
58
+
59
+ size(): number {
60
+ return this._size;
61
+ }
62
+
63
+ clear(): void {
64
+ this._size = 0;
65
+ }
66
+
67
+ isEmpty(): boolean {
68
+ return this._size === 0;
69
+ }
70
+
71
+ getCapacity(): number {
72
+ return this.capacity;
73
+ }
74
+
75
+ private heapifyUp(index: number): void {
76
+ // Cache array references to avoid repeated property lookups
77
+ const ids = this.ids;
78
+ const dists = this.dists;
79
+
80
+ while (index > 0) {
81
+ // Use bitwise shift for faster integer division
82
+ const parentIndex = (index - 1) >> 1;
83
+ if (dists[parentIndex] <= dists[index]) break;
84
+
85
+ // Inline swap for performance
86
+ const tmpId = ids[index];
87
+ ids[index] = ids[parentIndex];
88
+ ids[parentIndex] = tmpId;
89
+
90
+ const tmpDist = dists[index];
91
+ dists[index] = dists[parentIndex];
92
+ dists[parentIndex] = tmpDist;
93
+
94
+ index = parentIndex;
95
+ }
96
+ }
97
+
98
+ private heapifyDown(index: number): void {
99
+ // Cache array references to avoid repeated property lookups
100
+ const ids = this.ids;
101
+ const dists = this.dists;
102
+ const size = this._size;
103
+
104
+ while (true) {
105
+ const leftChild = (index << 1) + 1; // 2 * index + 1
106
+ const rightChild = leftChild + 1; // 2 * index + 2
107
+ let smallest = index;
108
+
109
+ if (leftChild < size && dists[leftChild] < dists[smallest]) {
110
+ smallest = leftChild;
111
+ }
112
+
113
+ if (rightChild < size && dists[rightChild] < dists[smallest]) {
114
+ smallest = rightChild;
115
+ }
116
+
117
+ if (smallest === index) break;
118
+
119
+ // Inline swap for performance
120
+ const tmpId = ids[index];
121
+ ids[index] = ids[smallest];
122
+ ids[smallest] = tmpId;
123
+
124
+ const tmpDist = dists[index];
125
+ dists[index] = dists[smallest];
126
+ dists[smallest] = tmpDist;
127
+
128
+ index = smallest;
129
+ }
130
+ }
131
+ }