verso-db 0.1.2 → 0.1.4

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 (3) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/index.js +32 -345
  3. package/package.json +4 -3
package/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ ## [0.1.4](https://github.com/briansunter/verso/compare/v0.1.3...v0.1.4) (2025-12-29)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * build target bun for Node.js compatibility ([901f1c3](https://github.com/briansunter/verso/commit/901f1c3ea6ce848389b91d8630c9674202201d48))
7
+
8
+ ## [0.1.3](https://github.com/briansunter/verso/compare/v0.1.2...v0.1.3) (2025-12-29)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * reorder exports for Bun compatibility ([13f7aeb](https://github.com/briansunter/verso/commit/13f7aebb555063c6dd52c5433a18eca916b2fb84))
14
+
1
15
  ## [0.1.2](https://github.com/briansunter/verso/compare/v0.1.1...v0.1.2) (2025-12-29)
2
16
 
3
17
 
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ // @bun
1
2
  // src/backends/JsDistanceBackend.ts
2
3
  class JsDistanceBackend {
3
4
  batchL2(base, dim, ids, query, out) {
@@ -1865,7 +1866,7 @@ class HNSWIndex {
1865
1866
  return {
1866
1867
  enabled: true,
1867
1868
  vectorCount,
1868
- memoryReduction: `${reduction}x (${(float32Size / 1024 / 1024).toFixed(1)}MB ${(int8Size / 1024 / 1024).toFixed(1)}MB)`,
1869
+ memoryReduction: `${reduction}x (${(float32Size / 1024 / 1024).toFixed(1)}MB \u2192 ${(int8Size / 1024 / 1024).toFixed(1)}MB)`,
1869
1870
  expectedSpeedup: "3-4x for distance calculations"
1870
1871
  };
1871
1872
  }
@@ -1879,329 +1880,9 @@ class HNSWIndex {
1879
1880
  }
1880
1881
 
1881
1882
  // src/Collection.ts
1882
- var {mkdir} = (() => ({}));
1883
+ import { mkdir } from "fs/promises";
1884
+ import * as path from "path";
1883
1885
 
1884
- // node:path
1885
- function assertPath(path) {
1886
- if (typeof path !== "string")
1887
- throw TypeError("Path must be a string. Received " + JSON.stringify(path));
1888
- }
1889
- function normalizeStringPosix(path, allowAboveRoot) {
1890
- var res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, code;
1891
- for (var i = 0;i <= path.length; ++i) {
1892
- if (i < path.length)
1893
- code = path.charCodeAt(i);
1894
- else if (code === 47)
1895
- break;
1896
- else
1897
- code = 47;
1898
- if (code === 47) {
1899
- if (lastSlash === i - 1 || dots === 1)
1900
- ;
1901
- else if (lastSlash !== i - 1 && dots === 2) {
1902
- if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 || res.charCodeAt(res.length - 2) !== 46) {
1903
- if (res.length > 2) {
1904
- var lastSlashIndex = res.lastIndexOf("/");
1905
- if (lastSlashIndex !== res.length - 1) {
1906
- if (lastSlashIndex === -1)
1907
- res = "", lastSegmentLength = 0;
1908
- else
1909
- res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/");
1910
- lastSlash = i, dots = 0;
1911
- continue;
1912
- }
1913
- } else if (res.length === 2 || res.length === 1) {
1914
- res = "", lastSegmentLength = 0, lastSlash = i, dots = 0;
1915
- continue;
1916
- }
1917
- }
1918
- if (allowAboveRoot) {
1919
- if (res.length > 0)
1920
- res += "/..";
1921
- else
1922
- res = "..";
1923
- lastSegmentLength = 2;
1924
- }
1925
- } else {
1926
- if (res.length > 0)
1927
- res += "/" + path.slice(lastSlash + 1, i);
1928
- else
1929
- res = path.slice(lastSlash + 1, i);
1930
- lastSegmentLength = i - lastSlash - 1;
1931
- }
1932
- lastSlash = i, dots = 0;
1933
- } else if (code === 46 && dots !== -1)
1934
- ++dots;
1935
- else
1936
- dots = -1;
1937
- }
1938
- return res;
1939
- }
1940
- function _format(sep, pathObject) {
1941
- var dir = pathObject.dir || pathObject.root, base = pathObject.base || (pathObject.name || "") + (pathObject.ext || "");
1942
- if (!dir)
1943
- return base;
1944
- if (dir === pathObject.root)
1945
- return dir + base;
1946
- return dir + sep + base;
1947
- }
1948
- function resolve() {
1949
- var resolvedPath = "", resolvedAbsolute = false, cwd;
1950
- for (var i = arguments.length - 1;i >= -1 && !resolvedAbsolute; i--) {
1951
- var path;
1952
- if (i >= 0)
1953
- path = arguments[i];
1954
- else {
1955
- if (cwd === undefined)
1956
- cwd = process.cwd();
1957
- path = cwd;
1958
- }
1959
- if (assertPath(path), path.length === 0)
1960
- continue;
1961
- resolvedPath = path + "/" + resolvedPath, resolvedAbsolute = path.charCodeAt(0) === 47;
1962
- }
1963
- if (resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute), resolvedAbsolute)
1964
- if (resolvedPath.length > 0)
1965
- return "/" + resolvedPath;
1966
- else
1967
- return "/";
1968
- else if (resolvedPath.length > 0)
1969
- return resolvedPath;
1970
- else
1971
- return ".";
1972
- }
1973
- function normalize(path) {
1974
- if (assertPath(path), path.length === 0)
1975
- return ".";
1976
- var isAbsolute = path.charCodeAt(0) === 47, trailingSeparator = path.charCodeAt(path.length - 1) === 47;
1977
- if (path = normalizeStringPosix(path, !isAbsolute), path.length === 0 && !isAbsolute)
1978
- path = ".";
1979
- if (path.length > 0 && trailingSeparator)
1980
- path += "/";
1981
- if (isAbsolute)
1982
- return "/" + path;
1983
- return path;
1984
- }
1985
- function isAbsolute(path) {
1986
- return assertPath(path), path.length > 0 && path.charCodeAt(0) === 47;
1987
- }
1988
- function join() {
1989
- if (arguments.length === 0)
1990
- return ".";
1991
- var joined;
1992
- for (var i = 0;i < arguments.length; ++i) {
1993
- var arg = arguments[i];
1994
- if (assertPath(arg), arg.length > 0)
1995
- if (joined === undefined)
1996
- joined = arg;
1997
- else
1998
- joined += "/" + arg;
1999
- }
2000
- if (joined === undefined)
2001
- return ".";
2002
- return normalize(joined);
2003
- }
2004
- function relative(from, to) {
2005
- if (assertPath(from), assertPath(to), from === to)
2006
- return "";
2007
- if (from = resolve(from), to = resolve(to), from === to)
2008
- return "";
2009
- var fromStart = 1;
2010
- for (;fromStart < from.length; ++fromStart)
2011
- if (from.charCodeAt(fromStart) !== 47)
2012
- break;
2013
- var fromEnd = from.length, fromLen = fromEnd - fromStart, toStart = 1;
2014
- for (;toStart < to.length; ++toStart)
2015
- if (to.charCodeAt(toStart) !== 47)
2016
- break;
2017
- var toEnd = to.length, toLen = toEnd - toStart, length = fromLen < toLen ? fromLen : toLen, lastCommonSep = -1, i = 0;
2018
- for (;i <= length; ++i) {
2019
- if (i === length) {
2020
- if (toLen > length) {
2021
- if (to.charCodeAt(toStart + i) === 47)
2022
- return to.slice(toStart + i + 1);
2023
- else if (i === 0)
2024
- return to.slice(toStart + i);
2025
- } else if (fromLen > length) {
2026
- if (from.charCodeAt(fromStart + i) === 47)
2027
- lastCommonSep = i;
2028
- else if (i === 0)
2029
- lastCommonSep = 0;
2030
- }
2031
- break;
2032
- }
2033
- var fromCode = from.charCodeAt(fromStart + i), toCode = to.charCodeAt(toStart + i);
2034
- if (fromCode !== toCode)
2035
- break;
2036
- else if (fromCode === 47)
2037
- lastCommonSep = i;
2038
- }
2039
- var out = "";
2040
- for (i = fromStart + lastCommonSep + 1;i <= fromEnd; ++i)
2041
- if (i === fromEnd || from.charCodeAt(i) === 47)
2042
- if (out.length === 0)
2043
- out += "..";
2044
- else
2045
- out += "/..";
2046
- if (out.length > 0)
2047
- return out + to.slice(toStart + lastCommonSep);
2048
- else {
2049
- if (toStart += lastCommonSep, to.charCodeAt(toStart) === 47)
2050
- ++toStart;
2051
- return to.slice(toStart);
2052
- }
2053
- }
2054
- function _makeLong(path) {
2055
- return path;
2056
- }
2057
- function dirname(path) {
2058
- if (assertPath(path), path.length === 0)
2059
- return ".";
2060
- var code = path.charCodeAt(0), hasRoot = code === 47, end = -1, matchedSlash = true;
2061
- for (var i = path.length - 1;i >= 1; --i)
2062
- if (code = path.charCodeAt(i), code === 47) {
2063
- if (!matchedSlash) {
2064
- end = i;
2065
- break;
2066
- }
2067
- } else
2068
- matchedSlash = false;
2069
- if (end === -1)
2070
- return hasRoot ? "/" : ".";
2071
- if (hasRoot && end === 1)
2072
- return "//";
2073
- return path.slice(0, end);
2074
- }
2075
- function basename(path, ext) {
2076
- if (ext !== undefined && typeof ext !== "string")
2077
- throw TypeError('"ext" argument must be a string');
2078
- assertPath(path);
2079
- var start = 0, end = -1, matchedSlash = true, i;
2080
- if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {
2081
- if (ext.length === path.length && ext === path)
2082
- return "";
2083
- var extIdx = ext.length - 1, firstNonSlashEnd = -1;
2084
- for (i = path.length - 1;i >= 0; --i) {
2085
- var code = path.charCodeAt(i);
2086
- if (code === 47) {
2087
- if (!matchedSlash) {
2088
- start = i + 1;
2089
- break;
2090
- }
2091
- } else {
2092
- if (firstNonSlashEnd === -1)
2093
- matchedSlash = false, firstNonSlashEnd = i + 1;
2094
- if (extIdx >= 0)
2095
- if (code === ext.charCodeAt(extIdx)) {
2096
- if (--extIdx === -1)
2097
- end = i;
2098
- } else
2099
- extIdx = -1, end = firstNonSlashEnd;
2100
- }
2101
- }
2102
- if (start === end)
2103
- end = firstNonSlashEnd;
2104
- else if (end === -1)
2105
- end = path.length;
2106
- return path.slice(start, end);
2107
- } else {
2108
- for (i = path.length - 1;i >= 0; --i)
2109
- if (path.charCodeAt(i) === 47) {
2110
- if (!matchedSlash) {
2111
- start = i + 1;
2112
- break;
2113
- }
2114
- } else if (end === -1)
2115
- matchedSlash = false, end = i + 1;
2116
- if (end === -1)
2117
- return "";
2118
- return path.slice(start, end);
2119
- }
2120
- }
2121
- function extname(path) {
2122
- assertPath(path);
2123
- var startDot = -1, startPart = 0, end = -1, matchedSlash = true, preDotState = 0;
2124
- for (var i = path.length - 1;i >= 0; --i) {
2125
- var code = path.charCodeAt(i);
2126
- if (code === 47) {
2127
- if (!matchedSlash) {
2128
- startPart = i + 1;
2129
- break;
2130
- }
2131
- continue;
2132
- }
2133
- if (end === -1)
2134
- matchedSlash = false, end = i + 1;
2135
- if (code === 46) {
2136
- if (startDot === -1)
2137
- startDot = i;
2138
- else if (preDotState !== 1)
2139
- preDotState = 1;
2140
- } else if (startDot !== -1)
2141
- preDotState = -1;
2142
- }
2143
- if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1)
2144
- return "";
2145
- return path.slice(startDot, end);
2146
- }
2147
- function format(pathObject) {
2148
- if (pathObject === null || typeof pathObject !== "object")
2149
- throw TypeError('The "pathObject" argument must be of type Object. Received type ' + typeof pathObject);
2150
- return _format("/", pathObject);
2151
- }
2152
- function parse(path) {
2153
- assertPath(path);
2154
- var ret = { root: "", dir: "", base: "", ext: "", name: "" };
2155
- if (path.length === 0)
2156
- return ret;
2157
- var code = path.charCodeAt(0), isAbsolute2 = code === 47, start;
2158
- if (isAbsolute2)
2159
- ret.root = "/", start = 1;
2160
- else
2161
- start = 0;
2162
- var startDot = -1, startPart = 0, end = -1, matchedSlash = true, i = path.length - 1, preDotState = 0;
2163
- for (;i >= start; --i) {
2164
- if (code = path.charCodeAt(i), code === 47) {
2165
- if (!matchedSlash) {
2166
- startPart = i + 1;
2167
- break;
2168
- }
2169
- continue;
2170
- }
2171
- if (end === -1)
2172
- matchedSlash = false, end = i + 1;
2173
- if (code === 46) {
2174
- if (startDot === -1)
2175
- startDot = i;
2176
- else if (preDotState !== 1)
2177
- preDotState = 1;
2178
- } else if (startDot !== -1)
2179
- preDotState = -1;
2180
- }
2181
- if (startDot === -1 || end === -1 || preDotState === 0 || preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {
2182
- if (end !== -1)
2183
- if (startPart === 0 && isAbsolute2)
2184
- ret.base = ret.name = path.slice(1, end);
2185
- else
2186
- ret.base = ret.name = path.slice(startPart, end);
2187
- } else {
2188
- if (startPart === 0 && isAbsolute2)
2189
- ret.name = path.slice(1, startDot), ret.base = path.slice(1, end);
2190
- else
2191
- ret.name = path.slice(startPart, startDot), ret.base = path.slice(startPart, end);
2192
- ret.ext = path.slice(startDot, end);
2193
- }
2194
- if (startPart > 0)
2195
- ret.dir = path.slice(0, startPart - 1);
2196
- else if (isAbsolute2)
2197
- ret.dir = "/";
2198
- return ret;
2199
- }
2200
- var sep = "/";
2201
- var delimiter = ":";
2202
- var posix = ((p) => (p.posix = p, p))({ resolve, normalize, isAbsolute, join, relative, _makeLong, dirname, basename, extname, format, parse, sep, delimiter, win32: null, posix: null });
2203
-
2204
- // src/Collection.ts
2205
1886
  class Collection {
2206
1887
  name;
2207
1888
  dimension;
@@ -2222,9 +1903,9 @@ class Collection {
2222
1903
  this.metric = config.metric || "cosine";
2223
1904
  this.M = config.M || 16;
2224
1905
  this.efConstruction = config.efConstruction || 200;
2225
- this.indexPath = join(collectionPath, `${name}.hnsw`);
2226
- this.metaPath = join(collectionPath, `${name}.meta`);
2227
- this.deletedPath = join(collectionPath, `${name}.deleted`);
1906
+ this.indexPath = path.join(collectionPath, `${name}.hnsw`);
1907
+ this.metaPath = path.join(collectionPath, `${name}.meta`);
1908
+ this.deletedPath = path.join(collectionPath, `${name}.deleted`);
2228
1909
  this.hnsw = new HNSWIndex(config.dimension, this.metric, this.M, this.efConstruction);
2229
1910
  this.idMap = new Map;
2230
1911
  this.idReverseMap = new Map;
@@ -2542,7 +2223,7 @@ class Collection {
2542
2223
  return this.deletedIds.has(numericId);
2543
2224
  }
2544
2225
  async saveToDisk() {
2545
- const dirPath = dirname(this.indexPath);
2226
+ const dirPath = path.dirname(this.indexPath);
2546
2227
  await mkdir(dirPath, { recursive: true }).catch(() => {});
2547
2228
  await this.hnsw.saveToFile(this.indexPath);
2548
2229
  const metaLines = [];
@@ -2638,8 +2319,13 @@ class Collection {
2638
2319
  }
2639
2320
  }
2640
2321
 
2322
+ // src/VectorDB.ts
2323
+ import * as path3 from "path";
2324
+
2641
2325
  // src/storage/BunStorageBackend.ts
2642
- var {mkdir: mkdir2, readdir, unlink, rm, appendFile} = (() => ({}));
2326
+ import { mkdir as mkdir2, readdir, unlink, rm, appendFile } from "fs/promises";
2327
+ import * as path2 from "path";
2328
+
2643
2329
  class BunStorageBackend {
2644
2330
  type = "bun";
2645
2331
  basePath;
@@ -2654,7 +2340,7 @@ class BunStorageBackend {
2654
2340
  this.dirCache.add(dir);
2655
2341
  }
2656
2342
  getFullPath(key) {
2657
- return join(this.basePath, key);
2343
+ return path2.join(this.basePath, key);
2658
2344
  }
2659
2345
  async init() {
2660
2346
  await mkdir2(this.basePath, { recursive: true }).catch(() => {});
@@ -2669,12 +2355,12 @@ class BunStorageBackend {
2669
2355
  }
2670
2356
  async write(key, data) {
2671
2357
  const fullPath = this.getFullPath(key);
2672
- await this.ensureDir(dirname(fullPath));
2358
+ await this.ensureDir(path2.dirname(fullPath));
2673
2359
  await Bun.write(fullPath, data);
2674
2360
  }
2675
2361
  async append(key, data) {
2676
2362
  const fullPath = this.getFullPath(key);
2677
- await this.ensureDir(dirname(fullPath));
2363
+ await this.ensureDir(path2.dirname(fullPath));
2678
2364
  const appendData = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
2679
2365
  await appendFile(fullPath, appendData);
2680
2366
  }
@@ -2694,8 +2380,8 @@ class BunStorageBackend {
2694
2380
  try {
2695
2381
  const entries = await readdir(searchPath, { recursive: true });
2696
2382
  return entries.map((entry) => {
2697
- const fullPath = join(searchPath, entry);
2698
- return relative(this.basePath, fullPath);
2383
+ const fullPath = path2.join(searchPath, entry);
2384
+ return path2.relative(this.basePath, fullPath);
2699
2385
  });
2700
2386
  } catch {
2701
2387
  return [];
@@ -2754,7 +2440,7 @@ class VectorDB {
2754
2440
  if (this.collections.has(name)) {
2755
2441
  throw new Error(`Collection ${name} already exists`);
2756
2442
  }
2757
- const collectionPath = join(this.storagePath, name);
2443
+ const collectionPath = path3.join(this.storagePath, name);
2758
2444
  await this.storageBackend.mkdir(name);
2759
2445
  const collection = new Collection(name, config, collectionPath);
2760
2446
  await collection.init();
@@ -2955,9 +2641,9 @@ class MemoryBackend {
2955
2641
  }
2956
2642
  return keys;
2957
2643
  }
2958
- async mkdir(path) {
2959
- this.directories.add(path);
2960
- const parts = path.split("/");
2644
+ async mkdir(path4) {
2645
+ this.directories.add(path4);
2646
+ const parts = path4.split("/");
2961
2647
  for (let i = 1;i <= parts.length; i++) {
2962
2648
  this.directories.add(parts.slice(0, i).join("/"));
2963
2649
  }
@@ -3031,9 +2717,9 @@ class OPFSBackend {
3031
2717
  return null;
3032
2718
  }
3033
2719
  }
3034
- async getDirectoryHandle(path, create = false) {
2720
+ async getDirectoryHandle(path4, create = false) {
3035
2721
  await this.ensureInitialized();
3036
- const parts = path.split("/").filter((p) => p !== "");
2722
+ const parts = path4.split("/").filter((p) => p !== "");
3037
2723
  let currentDir = this.root;
3038
2724
  for (const part of parts) {
3039
2725
  try {
@@ -3138,9 +2824,9 @@ class OPFSBackend {
3138
2824
  await listDir(dir, basePath);
3139
2825
  return results;
3140
2826
  }
3141
- async mkdir(path) {
2827
+ async mkdir(path4) {
3142
2828
  await this.ensureInitialized();
3143
- await this.getDirectoryHandle(path, true);
2829
+ await this.getDirectoryHandle(path4, true);
3144
2830
  }
3145
2831
  async clear() {
3146
2832
  await this.ensureInitialized();
@@ -3222,7 +2908,8 @@ function isStorageTypeAvailable(type) {
3222
2908
  }
3223
2909
  }
3224
2910
  // src/storage/WriteAheadLog.ts
3225
- var {appendFile: appendFile2, mkdir: mkdir3, unlink: unlink2} = (() => ({}));
2911
+ import { appendFile as appendFile2, mkdir as mkdir3, unlink as unlink2 } from "fs/promises";
2912
+ import * as path4 from "path";
3226
2913
  var WALOperationType;
3227
2914
  ((WALOperationType2) => {
3228
2915
  WALOperationType2[WALOperationType2["ADD_VECTOR"] = 1] = "ADD_VECTOR";
@@ -3344,7 +3031,7 @@ class WriteAheadLog {
3344
3031
  combined.set(entry, offset);
3345
3032
  offset += entry.length;
3346
3033
  }
3347
- const dir = dirname(this.logPath);
3034
+ const dir = path4.dirname(this.logPath);
3348
3035
  await mkdir3(dir, { recursive: true }).catch(() => {});
3349
3036
  await appendFile2(this.logPath, combined);
3350
3037
  this.pendingEntries = [];
@@ -3655,11 +3342,11 @@ class CollectionExistsError extends VectorDBError {
3655
3342
  class StorageError extends VectorDBError {
3656
3343
  operation;
3657
3344
  path;
3658
- constructor(operation, message, path) {
3345
+ constructor(operation, message, path5) {
3659
3346
  super(`Storage ${operation} failed: ${message}`, "STORAGE_ERROR");
3660
3347
  this.name = "StorageError";
3661
3348
  this.operation = operation;
3662
- this.path = path;
3349
+ this.path = path5;
3663
3350
  }
3664
3351
  }
3665
3352
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "verso-db",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "High-performance vector search with HNSW indexing for Bun and Browser. 100% recall, 4x memory reduction with Int8 quantization.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -9,8 +9,9 @@
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/index.d.ts",
12
+ "bun": "./src/index.ts",
12
13
  "import": "./dist/index.js",
13
- "bun": "./src/index.ts"
14
+ "default": "./dist/index.js"
14
15
  },
15
16
  "./package.json": "./package.json"
16
17
  },
@@ -25,7 +26,7 @@
25
26
  "access": "public"
26
27
  },
27
28
  "scripts": {
28
- "build": "bun build ./src/index.ts --outdir ./dist --target browser && bun run build:types",
29
+ "build": "bun build ./src/index.ts --outdir ./dist --target bun && bun run build:types",
29
30
  "build:types": "tsc --emitDeclarationOnly --declaration --outDir ./dist",
30
31
  "test": "bun test",
31
32
  "test:browser": "vitest --config vitest.browser.config.ts run",