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.
- package/CHANGELOG.md +14 -0
- package/dist/index.js +32 -345
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
2959
|
-
this.directories.add(
|
|
2960
|
-
const parts =
|
|
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(
|
|
2720
|
+
async getDirectoryHandle(path4, create = false) {
|
|
3035
2721
|
await this.ensureInitialized();
|
|
3036
|
-
const parts =
|
|
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(
|
|
2827
|
+
async mkdir(path4) {
|
|
3142
2828
|
await this.ensureInitialized();
|
|
3143
|
-
await this.getDirectoryHandle(
|
|
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
|
-
|
|
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,
|
|
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 =
|
|
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.
|
|
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
|
-
"
|
|
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
|
|
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",
|