@samyok/annoy 1.0.0 → 1.1.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.
- package/dist/index.d.mts +29 -0
- package/dist/index.d.ts +5 -4
- package/dist/index.js +119 -100
- package/dist/index.mjs +95 -0
- package/dist/test.d.mts +2 -0
- package/dist/test.d.ts +2 -1
- package/dist/test.js +211 -138
- package/dist/test.mjs +228 -0
- package/package.json +18 -5
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type Metric = "angular" | "euclidean" | "manhattan" | "dot";
|
|
2
|
+
interface NearestNeighborsResult {
|
|
3
|
+
neighbors: number[];
|
|
4
|
+
distances: number[];
|
|
5
|
+
}
|
|
6
|
+
declare class AnnoyIndex {
|
|
7
|
+
private index;
|
|
8
|
+
constructor(f: number, metric?: Metric);
|
|
9
|
+
addItem(index: number, vector: number[]): void;
|
|
10
|
+
build(numTrees: number, numThreads?: number): void;
|
|
11
|
+
unbuild(): void;
|
|
12
|
+
save(filename: string, prefault?: boolean): void;
|
|
13
|
+
load(filename: string, prefault?: boolean): void;
|
|
14
|
+
unload(): void;
|
|
15
|
+
getDistance(i: number, j: number): number;
|
|
16
|
+
getNnsByItem(item: number, n: number, searchK: number, includeDistances: true): NearestNeighborsResult;
|
|
17
|
+
getNnsByItem(item: number, n: number, searchK?: number, includeDistances?: false): number[];
|
|
18
|
+
getNnsByVector(vector: number[], n: number, searchK: number, includeDistances: true): NearestNeighborsResult;
|
|
19
|
+
getNnsByVector(vector: number[], n: number, searchK?: number, includeDistances?: false): number[];
|
|
20
|
+
getNItems(): number;
|
|
21
|
+
getNTrees(): number;
|
|
22
|
+
getItem(item: number): number[];
|
|
23
|
+
setSeed(seed: number): void;
|
|
24
|
+
onDiskBuild(filename: string): void;
|
|
25
|
+
verbose(v: boolean): void;
|
|
26
|
+
getF(): number;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { AnnoyIndex, type Metric, type NearestNeighborsResult, AnnoyIndex as default };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type Metric = "angular" | "euclidean" | "manhattan" | "dot";
|
|
2
|
+
interface NearestNeighborsResult {
|
|
3
3
|
neighbors: number[];
|
|
4
4
|
distances: number[];
|
|
5
5
|
}
|
|
6
|
-
|
|
6
|
+
declare class AnnoyIndex {
|
|
7
7
|
private index;
|
|
8
8
|
constructor(f: number, metric?: Metric);
|
|
9
9
|
addItem(index: number, vector: number[]): void;
|
|
@@ -25,4 +25,5 @@ export declare class AnnoyIndex {
|
|
|
25
25
|
verbose(v: boolean): void;
|
|
26
26
|
getF(): number;
|
|
27
27
|
}
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
export { AnnoyIndex, type Metric, type NearestNeighborsResult, AnnoyIndex as default };
|
package/dist/index.js
CHANGED
|
@@ -1,103 +1,122 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
AnnoyIndex: () => AnnoyIndex,
|
|
34
|
+
default: () => index_default
|
|
17
35
|
});
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return result;
|
|
36
|
+
module.exports = __toCommonJS(index_exports);
|
|
37
|
+
var import_module = require("module");
|
|
38
|
+
var path = __toESM(require("path"));
|
|
39
|
+
var _require = (0, import_module.createRequire)(__filename);
|
|
40
|
+
var addon = _require(
|
|
41
|
+
path.join(__dirname, "..", "build", "Release", "annoy.node")
|
|
42
|
+
);
|
|
43
|
+
var AnnoyIndex = class {
|
|
44
|
+
constructor(f, metric = "angular") {
|
|
45
|
+
const constructors = {
|
|
46
|
+
angular: addon.AnnoyIndexAngular,
|
|
47
|
+
euclidean: addon.AnnoyIndexEuclidean,
|
|
48
|
+
manhattan: addon.AnnoyIndexManhattan,
|
|
49
|
+
dot: addon.AnnoyIndexDotProduct
|
|
33
50
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
getNItems()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
getNTrees()
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
getItem(item)
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
setSeed(seed)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
onDiskBuild(filename)
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
verbose(v)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
getF()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
exports
|
|
51
|
+
const Ctor = constructors[metric];
|
|
52
|
+
if (!Ctor) {
|
|
53
|
+
throw new Error(
|
|
54
|
+
`Unknown metric "${metric}". Use: angular, euclidean, manhattan, dot`
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
this.index = new Ctor(f);
|
|
58
|
+
}
|
|
59
|
+
addItem(index, vector) {
|
|
60
|
+
this.index.addItem(index, vector);
|
|
61
|
+
}
|
|
62
|
+
build(numTrees, numThreads = -1) {
|
|
63
|
+
this.index.build(numTrees, numThreads);
|
|
64
|
+
}
|
|
65
|
+
unbuild() {
|
|
66
|
+
this.index.unbuild();
|
|
67
|
+
}
|
|
68
|
+
save(filename, prefault = false) {
|
|
69
|
+
this.index.save(filename, prefault);
|
|
70
|
+
}
|
|
71
|
+
load(filename, prefault = false) {
|
|
72
|
+
this.index.load(filename, prefault);
|
|
73
|
+
}
|
|
74
|
+
unload() {
|
|
75
|
+
this.index.unload();
|
|
76
|
+
}
|
|
77
|
+
getDistance(i, j) {
|
|
78
|
+
return this.index.getDistance(i, j);
|
|
79
|
+
}
|
|
80
|
+
getNnsByItem(item, n, searchK = -1, includeDistances = false) {
|
|
81
|
+
return this.index.getNnsByItem(
|
|
82
|
+
item,
|
|
83
|
+
n,
|
|
84
|
+
searchK,
|
|
85
|
+
includeDistances
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
getNnsByVector(vector, n, searchK = -1, includeDistances = false) {
|
|
89
|
+
return this.index.getNnsByVector(
|
|
90
|
+
vector,
|
|
91
|
+
n,
|
|
92
|
+
searchK,
|
|
93
|
+
includeDistances
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
getNItems() {
|
|
97
|
+
return this.index.getNItems();
|
|
98
|
+
}
|
|
99
|
+
getNTrees() {
|
|
100
|
+
return this.index.getNTrees();
|
|
101
|
+
}
|
|
102
|
+
getItem(item) {
|
|
103
|
+
return this.index.getItem(item);
|
|
104
|
+
}
|
|
105
|
+
setSeed(seed) {
|
|
106
|
+
this.index.setSeed(seed);
|
|
107
|
+
}
|
|
108
|
+
onDiskBuild(filename) {
|
|
109
|
+
this.index.onDiskBuild(filename);
|
|
110
|
+
}
|
|
111
|
+
verbose(v) {
|
|
112
|
+
this.index.verbose(v);
|
|
113
|
+
}
|
|
114
|
+
getF() {
|
|
115
|
+
return this.index.getF();
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
var index_default = AnnoyIndex;
|
|
119
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
120
|
+
0 && (module.exports = {
|
|
121
|
+
AnnoyIndex
|
|
122
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// node_modules/tsup/assets/esm_shims.js
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
5
|
+
var getDirname = () => path.dirname(getFilename());
|
|
6
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
|
+
var __filename = /* @__PURE__ */ getFilename();
|
|
8
|
+
|
|
9
|
+
// src/index.ts
|
|
10
|
+
import { createRequire } from "module";
|
|
11
|
+
import * as path2 from "path";
|
|
12
|
+
var _require = createRequire(__filename);
|
|
13
|
+
var addon = _require(
|
|
14
|
+
path2.join(__dirname, "..", "build", "Release", "annoy.node")
|
|
15
|
+
);
|
|
16
|
+
var AnnoyIndex = class {
|
|
17
|
+
constructor(f, metric = "angular") {
|
|
18
|
+
const constructors = {
|
|
19
|
+
angular: addon.AnnoyIndexAngular,
|
|
20
|
+
euclidean: addon.AnnoyIndexEuclidean,
|
|
21
|
+
manhattan: addon.AnnoyIndexManhattan,
|
|
22
|
+
dot: addon.AnnoyIndexDotProduct
|
|
23
|
+
};
|
|
24
|
+
const Ctor = constructors[metric];
|
|
25
|
+
if (!Ctor) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`Unknown metric "${metric}". Use: angular, euclidean, manhattan, dot`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
this.index = new Ctor(f);
|
|
31
|
+
}
|
|
32
|
+
addItem(index, vector) {
|
|
33
|
+
this.index.addItem(index, vector);
|
|
34
|
+
}
|
|
35
|
+
build(numTrees, numThreads = -1) {
|
|
36
|
+
this.index.build(numTrees, numThreads);
|
|
37
|
+
}
|
|
38
|
+
unbuild() {
|
|
39
|
+
this.index.unbuild();
|
|
40
|
+
}
|
|
41
|
+
save(filename, prefault = false) {
|
|
42
|
+
this.index.save(filename, prefault);
|
|
43
|
+
}
|
|
44
|
+
load(filename, prefault = false) {
|
|
45
|
+
this.index.load(filename, prefault);
|
|
46
|
+
}
|
|
47
|
+
unload() {
|
|
48
|
+
this.index.unload();
|
|
49
|
+
}
|
|
50
|
+
getDistance(i, j) {
|
|
51
|
+
return this.index.getDistance(i, j);
|
|
52
|
+
}
|
|
53
|
+
getNnsByItem(item, n, searchK = -1, includeDistances = false) {
|
|
54
|
+
return this.index.getNnsByItem(
|
|
55
|
+
item,
|
|
56
|
+
n,
|
|
57
|
+
searchK,
|
|
58
|
+
includeDistances
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
getNnsByVector(vector, n, searchK = -1, includeDistances = false) {
|
|
62
|
+
return this.index.getNnsByVector(
|
|
63
|
+
vector,
|
|
64
|
+
n,
|
|
65
|
+
searchK,
|
|
66
|
+
includeDistances
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
getNItems() {
|
|
70
|
+
return this.index.getNItems();
|
|
71
|
+
}
|
|
72
|
+
getNTrees() {
|
|
73
|
+
return this.index.getNTrees();
|
|
74
|
+
}
|
|
75
|
+
getItem(item) {
|
|
76
|
+
return this.index.getItem(item);
|
|
77
|
+
}
|
|
78
|
+
setSeed(seed) {
|
|
79
|
+
this.index.setSeed(seed);
|
|
80
|
+
}
|
|
81
|
+
onDiskBuild(filename) {
|
|
82
|
+
this.index.onDiskBuild(filename);
|
|
83
|
+
}
|
|
84
|
+
verbose(v) {
|
|
85
|
+
this.index.verbose(v);
|
|
86
|
+
}
|
|
87
|
+
getF() {
|
|
88
|
+
return this.index.getF();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var index_default = AnnoyIndex;
|
|
92
|
+
export {
|
|
93
|
+
AnnoyIndex,
|
|
94
|
+
index_default as default
|
|
95
|
+
};
|
package/dist/test.d.mts
ADDED
package/dist/test.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
export { }
|
package/dist/test.js
CHANGED
|
@@ -1,171 +1,244 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
})
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
|
|
25
|
+
// src/index.ts
|
|
26
|
+
var import_module = require("module");
|
|
27
|
+
var path = __toESM(require("path"));
|
|
28
|
+
var _require = (0, import_module.createRequire)(__filename);
|
|
29
|
+
var addon = _require(
|
|
30
|
+
path.join(__dirname, "..", "build", "Release", "annoy.node")
|
|
31
|
+
);
|
|
32
|
+
var AnnoyIndex = class {
|
|
33
|
+
constructor(f, metric = "angular") {
|
|
34
|
+
const constructors = {
|
|
35
|
+
angular: addon.AnnoyIndexAngular,
|
|
36
|
+
euclidean: addon.AnnoyIndexEuclidean,
|
|
37
|
+
manhattan: addon.AnnoyIndexManhattan,
|
|
38
|
+
dot: addon.AnnoyIndexDotProduct
|
|
33
39
|
};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
const DIMS = 40;
|
|
40
|
-
const NUM_ITEMS = 1000;
|
|
41
|
-
const NUM_TREES = 10;
|
|
42
|
-
const tmpFile = path.join(__dirname, "..", "test_index.ann");
|
|
43
|
-
let passed = 0;
|
|
44
|
-
let failed = 0;
|
|
45
|
-
function assert(condition, msg) {
|
|
46
|
-
if (condition) {
|
|
47
|
-
passed++;
|
|
48
|
-
console.log(` PASS: ${msg}`);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
failed++;
|
|
52
|
-
console.error(` FAIL: ${msg}`);
|
|
40
|
+
const Ctor = constructors[metric];
|
|
41
|
+
if (!Ctor) {
|
|
42
|
+
throw new Error(
|
|
43
|
+
`Unknown metric "${metric}". Use: angular, euclidean, manhattan, dot`
|
|
44
|
+
);
|
|
53
45
|
}
|
|
46
|
+
this.index = new Ctor(f);
|
|
47
|
+
}
|
|
48
|
+
addItem(index, vector) {
|
|
49
|
+
this.index.addItem(index, vector);
|
|
50
|
+
}
|
|
51
|
+
build(numTrees, numThreads = -1) {
|
|
52
|
+
this.index.build(numTrees, numThreads);
|
|
53
|
+
}
|
|
54
|
+
unbuild() {
|
|
55
|
+
this.index.unbuild();
|
|
56
|
+
}
|
|
57
|
+
save(filename, prefault = false) {
|
|
58
|
+
this.index.save(filename, prefault);
|
|
59
|
+
}
|
|
60
|
+
load(filename, prefault = false) {
|
|
61
|
+
this.index.load(filename, prefault);
|
|
62
|
+
}
|
|
63
|
+
unload() {
|
|
64
|
+
this.index.unload();
|
|
65
|
+
}
|
|
66
|
+
getDistance(i, j) {
|
|
67
|
+
return this.index.getDistance(i, j);
|
|
68
|
+
}
|
|
69
|
+
getNnsByItem(item, n, searchK = -1, includeDistances = false) {
|
|
70
|
+
return this.index.getNnsByItem(
|
|
71
|
+
item,
|
|
72
|
+
n,
|
|
73
|
+
searchK,
|
|
74
|
+
includeDistances
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
getNnsByVector(vector, n, searchK = -1, includeDistances = false) {
|
|
78
|
+
return this.index.getNnsByVector(
|
|
79
|
+
vector,
|
|
80
|
+
n,
|
|
81
|
+
searchK,
|
|
82
|
+
includeDistances
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
getNItems() {
|
|
86
|
+
return this.index.getNItems();
|
|
87
|
+
}
|
|
88
|
+
getNTrees() {
|
|
89
|
+
return this.index.getNTrees();
|
|
90
|
+
}
|
|
91
|
+
getItem(item) {
|
|
92
|
+
return this.index.getItem(item);
|
|
93
|
+
}
|
|
94
|
+
setSeed(seed) {
|
|
95
|
+
this.index.setSeed(seed);
|
|
96
|
+
}
|
|
97
|
+
onDiskBuild(filename) {
|
|
98
|
+
this.index.onDiskBuild(filename);
|
|
99
|
+
}
|
|
100
|
+
verbose(v) {
|
|
101
|
+
this.index.verbose(v);
|
|
102
|
+
}
|
|
103
|
+
getF() {
|
|
104
|
+
return this.index.getF();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// src/test.ts
|
|
109
|
+
var fs = __toESM(require("fs"));
|
|
110
|
+
var path2 = __toESM(require("path"));
|
|
111
|
+
var DIMS = 40;
|
|
112
|
+
var NUM_ITEMS = 1e3;
|
|
113
|
+
var NUM_TREES = 10;
|
|
114
|
+
var tmpFile = path2.join(__dirname, "..", "test_index.ann");
|
|
115
|
+
var passed = 0;
|
|
116
|
+
var failed = 0;
|
|
117
|
+
function assert(condition, msg) {
|
|
118
|
+
if (condition) {
|
|
119
|
+
passed++;
|
|
120
|
+
console.log(` PASS: ${msg}`);
|
|
121
|
+
} else {
|
|
122
|
+
failed++;
|
|
123
|
+
console.error(` FAIL: ${msg}`);
|
|
124
|
+
}
|
|
54
125
|
}
|
|
55
126
|
function randomVector(dims) {
|
|
56
|
-
|
|
127
|
+
return Array.from({ length: dims }, () => Math.random() * 2 - 1);
|
|
57
128
|
}
|
|
58
129
|
function cleanup() {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
130
|
+
try {
|
|
131
|
+
fs.unlinkSync(tmpFile);
|
|
132
|
+
} catch {
|
|
133
|
+
}
|
|
63
134
|
}
|
|
64
135
|
console.log("=== annoy-node test suite ===\n");
|
|
65
|
-
// Test 1: Basic build and query (Angular)
|
|
66
136
|
console.log("Test 1: Build and query (Angular)");
|
|
67
137
|
{
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
138
|
+
const index = new AnnoyIndex(DIMS, "angular");
|
|
139
|
+
for (let i = 0; i < NUM_ITEMS; i++) {
|
|
140
|
+
index.addItem(i, randomVector(DIMS));
|
|
141
|
+
}
|
|
142
|
+
index.build(NUM_TREES);
|
|
143
|
+
assert(index.getNItems() === NUM_ITEMS, `getNItems() === ${NUM_ITEMS}`);
|
|
144
|
+
assert(index.getNTrees() === NUM_TREES, `getNTrees() === ${NUM_TREES}`);
|
|
145
|
+
assert(index.getF() === DIMS, `getF() === ${DIMS}`);
|
|
146
|
+
const neighbors = index.getNnsByItem(0, 10);
|
|
147
|
+
assert(Array.isArray(neighbors), "getNnsByItem returns array");
|
|
148
|
+
assert(neighbors.length === 10, "returns 10 neighbors");
|
|
149
|
+
assert(neighbors[0] === 0, "nearest neighbor of item 0 is itself");
|
|
80
150
|
}
|
|
81
|
-
// Test 2: Include distances
|
|
82
151
|
console.log("\nTest 2: Include distances");
|
|
83
152
|
{
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
153
|
+
const index = new AnnoyIndex(DIMS, "angular");
|
|
154
|
+
for (let i = 0; i < 100; i++) {
|
|
155
|
+
index.addItem(i, randomVector(DIMS));
|
|
156
|
+
}
|
|
157
|
+
index.build(NUM_TREES);
|
|
158
|
+
const result = index.getNnsByItem(0, 5, -1, true);
|
|
159
|
+
assert(
|
|
160
|
+
"neighbors" in result && "distances" in result,
|
|
161
|
+
"result has neighbors and distances"
|
|
162
|
+
);
|
|
163
|
+
assert(result.neighbors.length === 5, "5 neighbors returned");
|
|
164
|
+
assert(result.distances.length === 5, "5 distances returned");
|
|
165
|
+
assert(result.distances[0] === 0, "distance to self is 0");
|
|
94
166
|
}
|
|
95
|
-
// Test 3: getNnsByVector
|
|
96
167
|
console.log("\nTest 3: getNnsByVector");
|
|
97
168
|
{
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
169
|
+
const index = new AnnoyIndex(DIMS, "euclidean");
|
|
170
|
+
const vectors = [];
|
|
171
|
+
for (let i = 0; i < 100; i++) {
|
|
172
|
+
const v = randomVector(DIMS);
|
|
173
|
+
vectors.push(v);
|
|
174
|
+
index.addItem(i, v);
|
|
175
|
+
}
|
|
176
|
+
index.build(NUM_TREES);
|
|
177
|
+
const result = index.getNnsByVector(vectors[0], 5);
|
|
178
|
+
assert(Array.isArray(result), "getNnsByVector returns array");
|
|
179
|
+
assert(result[0] === 0, "closest to vector[0] is item 0");
|
|
109
180
|
}
|
|
110
|
-
// Test 4: Save and load
|
|
111
181
|
console.log("\nTest 4: Save and load");
|
|
112
182
|
{
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
183
|
+
cleanup();
|
|
184
|
+
const index = new AnnoyIndex(DIMS, "angular");
|
|
185
|
+
for (let i = 0; i < 100; i++) {
|
|
186
|
+
index.addItem(i, randomVector(DIMS));
|
|
187
|
+
}
|
|
188
|
+
index.build(NUM_TREES);
|
|
189
|
+
index.save(tmpFile);
|
|
190
|
+
const loaded = new AnnoyIndex(DIMS, "angular");
|
|
191
|
+
loaded.load(tmpFile);
|
|
192
|
+
assert(loaded.getNItems() === 100, "loaded index has 100 items");
|
|
193
|
+
assert(loaded.getNTrees() === NUM_TREES, `loaded index has ${NUM_TREES} trees`);
|
|
194
|
+
const item = loaded.getItem(0);
|
|
195
|
+
assert(item.length === DIMS, `getItem returns vector of length ${DIMS}`);
|
|
196
|
+
cleanup();
|
|
127
197
|
}
|
|
128
|
-
// Test 5: getDistance
|
|
129
198
|
console.log("\nTest 5: getDistance");
|
|
130
199
|
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
200
|
+
const index = new AnnoyIndex(DIMS, "euclidean");
|
|
201
|
+
const v = randomVector(DIMS);
|
|
202
|
+
index.addItem(0, v);
|
|
203
|
+
index.addItem(1, v);
|
|
204
|
+
index.build(1);
|
|
205
|
+
const dist = index.getDistance(0, 1);
|
|
206
|
+
assert(Math.abs(dist) < 1e-6, `distance between identical vectors is ~0 (got ${dist})`);
|
|
138
207
|
}
|
|
139
|
-
// Test 6: All metrics
|
|
140
208
|
console.log("\nTest 6: All metrics");
|
|
141
209
|
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
index.build(5);
|
|
149
|
-
const nn = index.getNnsByItem(0, 5);
|
|
150
|
-
assert(nn.length === 5, `${metric}: returns 5 neighbors`);
|
|
210
|
+
const metrics = ["angular", "euclidean", "manhattan", "dot"];
|
|
211
|
+
for (const metric of metrics) {
|
|
212
|
+
const index = new AnnoyIndex(DIMS, metric);
|
|
213
|
+
for (let i = 0; i < 50; i++) {
|
|
214
|
+
index.addItem(i, randomVector(DIMS));
|
|
151
215
|
}
|
|
216
|
+
index.build(5);
|
|
217
|
+
const nn = index.getNnsByItem(0, 5);
|
|
218
|
+
assert(nn.length === 5, `${metric}: returns 5 neighbors`);
|
|
219
|
+
}
|
|
152
220
|
}
|
|
153
|
-
// Test 7: setSeed reproducibility
|
|
154
221
|
console.log("\nTest 7: setSeed reproducibility");
|
|
155
222
|
{
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
idx.addItem(i, vectors[i]);
|
|
162
|
-
}
|
|
163
|
-
idx.build(5);
|
|
164
|
-
return idx.getNnsByItem(0, 10);
|
|
223
|
+
let buildWithSeed = function(seed) {
|
|
224
|
+
const idx = new AnnoyIndex(DIMS, "angular");
|
|
225
|
+
idx.setSeed(seed);
|
|
226
|
+
for (let i = 0; i < 100; i++) {
|
|
227
|
+
idx.addItem(i, vectors[i]);
|
|
165
228
|
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
229
|
+
idx.build(5);
|
|
230
|
+
return idx.getNnsByItem(0, 10);
|
|
231
|
+
};
|
|
232
|
+
buildWithSeed2 = buildWithSeed;
|
|
233
|
+
const vectors = Array.from({ length: 100 }, () => randomVector(DIMS));
|
|
234
|
+
const r1 = buildWithSeed(42);
|
|
235
|
+
const r2 = buildWithSeed(42);
|
|
236
|
+
assert(
|
|
237
|
+
JSON.stringify(r1) === JSON.stringify(r2),
|
|
238
|
+
"same seed produces same results"
|
|
239
|
+
);
|
|
169
240
|
}
|
|
170
|
-
|
|
241
|
+
var buildWithSeed2;
|
|
242
|
+
console.log(`
|
|
243
|
+
=== Results: ${passed} passed, ${failed} failed ===`);
|
|
171
244
|
process.exit(failed > 0 ? 1 : 0);
|
package/dist/test.mjs
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
// node_modules/tsup/assets/esm_shims.js
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
5
|
+
var getDirname = () => path.dirname(getFilename());
|
|
6
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
|
+
var __filename = /* @__PURE__ */ getFilename();
|
|
8
|
+
|
|
9
|
+
// src/index.ts
|
|
10
|
+
import { createRequire } from "module";
|
|
11
|
+
import * as path2 from "path";
|
|
12
|
+
var _require = createRequire(__filename);
|
|
13
|
+
var addon = _require(
|
|
14
|
+
path2.join(__dirname, "..", "build", "Release", "annoy.node")
|
|
15
|
+
);
|
|
16
|
+
var AnnoyIndex = class {
|
|
17
|
+
constructor(f, metric = "angular") {
|
|
18
|
+
const constructors = {
|
|
19
|
+
angular: addon.AnnoyIndexAngular,
|
|
20
|
+
euclidean: addon.AnnoyIndexEuclidean,
|
|
21
|
+
manhattan: addon.AnnoyIndexManhattan,
|
|
22
|
+
dot: addon.AnnoyIndexDotProduct
|
|
23
|
+
};
|
|
24
|
+
const Ctor = constructors[metric];
|
|
25
|
+
if (!Ctor) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`Unknown metric "${metric}". Use: angular, euclidean, manhattan, dot`
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
this.index = new Ctor(f);
|
|
31
|
+
}
|
|
32
|
+
addItem(index, vector) {
|
|
33
|
+
this.index.addItem(index, vector);
|
|
34
|
+
}
|
|
35
|
+
build(numTrees, numThreads = -1) {
|
|
36
|
+
this.index.build(numTrees, numThreads);
|
|
37
|
+
}
|
|
38
|
+
unbuild() {
|
|
39
|
+
this.index.unbuild();
|
|
40
|
+
}
|
|
41
|
+
save(filename, prefault = false) {
|
|
42
|
+
this.index.save(filename, prefault);
|
|
43
|
+
}
|
|
44
|
+
load(filename, prefault = false) {
|
|
45
|
+
this.index.load(filename, prefault);
|
|
46
|
+
}
|
|
47
|
+
unload() {
|
|
48
|
+
this.index.unload();
|
|
49
|
+
}
|
|
50
|
+
getDistance(i, j) {
|
|
51
|
+
return this.index.getDistance(i, j);
|
|
52
|
+
}
|
|
53
|
+
getNnsByItem(item, n, searchK = -1, includeDistances = false) {
|
|
54
|
+
return this.index.getNnsByItem(
|
|
55
|
+
item,
|
|
56
|
+
n,
|
|
57
|
+
searchK,
|
|
58
|
+
includeDistances
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
getNnsByVector(vector, n, searchK = -1, includeDistances = false) {
|
|
62
|
+
return this.index.getNnsByVector(
|
|
63
|
+
vector,
|
|
64
|
+
n,
|
|
65
|
+
searchK,
|
|
66
|
+
includeDistances
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
getNItems() {
|
|
70
|
+
return this.index.getNItems();
|
|
71
|
+
}
|
|
72
|
+
getNTrees() {
|
|
73
|
+
return this.index.getNTrees();
|
|
74
|
+
}
|
|
75
|
+
getItem(item) {
|
|
76
|
+
return this.index.getItem(item);
|
|
77
|
+
}
|
|
78
|
+
setSeed(seed) {
|
|
79
|
+
this.index.setSeed(seed);
|
|
80
|
+
}
|
|
81
|
+
onDiskBuild(filename) {
|
|
82
|
+
this.index.onDiskBuild(filename);
|
|
83
|
+
}
|
|
84
|
+
verbose(v) {
|
|
85
|
+
this.index.verbose(v);
|
|
86
|
+
}
|
|
87
|
+
getF() {
|
|
88
|
+
return this.index.getF();
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
// src/test.ts
|
|
93
|
+
import * as fs from "fs";
|
|
94
|
+
import * as path3 from "path";
|
|
95
|
+
var DIMS = 40;
|
|
96
|
+
var NUM_ITEMS = 1e3;
|
|
97
|
+
var NUM_TREES = 10;
|
|
98
|
+
var tmpFile = path3.join(__dirname, "..", "test_index.ann");
|
|
99
|
+
var passed = 0;
|
|
100
|
+
var failed = 0;
|
|
101
|
+
function assert(condition, msg) {
|
|
102
|
+
if (condition) {
|
|
103
|
+
passed++;
|
|
104
|
+
console.log(` PASS: ${msg}`);
|
|
105
|
+
} else {
|
|
106
|
+
failed++;
|
|
107
|
+
console.error(` FAIL: ${msg}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function randomVector(dims) {
|
|
111
|
+
return Array.from({ length: dims }, () => Math.random() * 2 - 1);
|
|
112
|
+
}
|
|
113
|
+
function cleanup() {
|
|
114
|
+
try {
|
|
115
|
+
fs.unlinkSync(tmpFile);
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
console.log("=== annoy-node test suite ===\n");
|
|
120
|
+
console.log("Test 1: Build and query (Angular)");
|
|
121
|
+
{
|
|
122
|
+
const index = new AnnoyIndex(DIMS, "angular");
|
|
123
|
+
for (let i = 0; i < NUM_ITEMS; i++) {
|
|
124
|
+
index.addItem(i, randomVector(DIMS));
|
|
125
|
+
}
|
|
126
|
+
index.build(NUM_TREES);
|
|
127
|
+
assert(index.getNItems() === NUM_ITEMS, `getNItems() === ${NUM_ITEMS}`);
|
|
128
|
+
assert(index.getNTrees() === NUM_TREES, `getNTrees() === ${NUM_TREES}`);
|
|
129
|
+
assert(index.getF() === DIMS, `getF() === ${DIMS}`);
|
|
130
|
+
const neighbors = index.getNnsByItem(0, 10);
|
|
131
|
+
assert(Array.isArray(neighbors), "getNnsByItem returns array");
|
|
132
|
+
assert(neighbors.length === 10, "returns 10 neighbors");
|
|
133
|
+
assert(neighbors[0] === 0, "nearest neighbor of item 0 is itself");
|
|
134
|
+
}
|
|
135
|
+
console.log("\nTest 2: Include distances");
|
|
136
|
+
{
|
|
137
|
+
const index = new AnnoyIndex(DIMS, "angular");
|
|
138
|
+
for (let i = 0; i < 100; i++) {
|
|
139
|
+
index.addItem(i, randomVector(DIMS));
|
|
140
|
+
}
|
|
141
|
+
index.build(NUM_TREES);
|
|
142
|
+
const result = index.getNnsByItem(0, 5, -1, true);
|
|
143
|
+
assert(
|
|
144
|
+
"neighbors" in result && "distances" in result,
|
|
145
|
+
"result has neighbors and distances"
|
|
146
|
+
);
|
|
147
|
+
assert(result.neighbors.length === 5, "5 neighbors returned");
|
|
148
|
+
assert(result.distances.length === 5, "5 distances returned");
|
|
149
|
+
assert(result.distances[0] === 0, "distance to self is 0");
|
|
150
|
+
}
|
|
151
|
+
console.log("\nTest 3: getNnsByVector");
|
|
152
|
+
{
|
|
153
|
+
const index = new AnnoyIndex(DIMS, "euclidean");
|
|
154
|
+
const vectors = [];
|
|
155
|
+
for (let i = 0; i < 100; i++) {
|
|
156
|
+
const v = randomVector(DIMS);
|
|
157
|
+
vectors.push(v);
|
|
158
|
+
index.addItem(i, v);
|
|
159
|
+
}
|
|
160
|
+
index.build(NUM_TREES);
|
|
161
|
+
const result = index.getNnsByVector(vectors[0], 5);
|
|
162
|
+
assert(Array.isArray(result), "getNnsByVector returns array");
|
|
163
|
+
assert(result[0] === 0, "closest to vector[0] is item 0");
|
|
164
|
+
}
|
|
165
|
+
console.log("\nTest 4: Save and load");
|
|
166
|
+
{
|
|
167
|
+
cleanup();
|
|
168
|
+
const index = new AnnoyIndex(DIMS, "angular");
|
|
169
|
+
for (let i = 0; i < 100; i++) {
|
|
170
|
+
index.addItem(i, randomVector(DIMS));
|
|
171
|
+
}
|
|
172
|
+
index.build(NUM_TREES);
|
|
173
|
+
index.save(tmpFile);
|
|
174
|
+
const loaded = new AnnoyIndex(DIMS, "angular");
|
|
175
|
+
loaded.load(tmpFile);
|
|
176
|
+
assert(loaded.getNItems() === 100, "loaded index has 100 items");
|
|
177
|
+
assert(loaded.getNTrees() === NUM_TREES, `loaded index has ${NUM_TREES} trees`);
|
|
178
|
+
const item = loaded.getItem(0);
|
|
179
|
+
assert(item.length === DIMS, `getItem returns vector of length ${DIMS}`);
|
|
180
|
+
cleanup();
|
|
181
|
+
}
|
|
182
|
+
console.log("\nTest 5: getDistance");
|
|
183
|
+
{
|
|
184
|
+
const index = new AnnoyIndex(DIMS, "euclidean");
|
|
185
|
+
const v = randomVector(DIMS);
|
|
186
|
+
index.addItem(0, v);
|
|
187
|
+
index.addItem(1, v);
|
|
188
|
+
index.build(1);
|
|
189
|
+
const dist = index.getDistance(0, 1);
|
|
190
|
+
assert(Math.abs(dist) < 1e-6, `distance between identical vectors is ~0 (got ${dist})`);
|
|
191
|
+
}
|
|
192
|
+
console.log("\nTest 6: All metrics");
|
|
193
|
+
{
|
|
194
|
+
const metrics = ["angular", "euclidean", "manhattan", "dot"];
|
|
195
|
+
for (const metric of metrics) {
|
|
196
|
+
const index = new AnnoyIndex(DIMS, metric);
|
|
197
|
+
for (let i = 0; i < 50; i++) {
|
|
198
|
+
index.addItem(i, randomVector(DIMS));
|
|
199
|
+
}
|
|
200
|
+
index.build(5);
|
|
201
|
+
const nn = index.getNnsByItem(0, 5);
|
|
202
|
+
assert(nn.length === 5, `${metric}: returns 5 neighbors`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
console.log("\nTest 7: setSeed reproducibility");
|
|
206
|
+
{
|
|
207
|
+
let buildWithSeed = function(seed) {
|
|
208
|
+
const idx = new AnnoyIndex(DIMS, "angular");
|
|
209
|
+
idx.setSeed(seed);
|
|
210
|
+
for (let i = 0; i < 100; i++) {
|
|
211
|
+
idx.addItem(i, vectors[i]);
|
|
212
|
+
}
|
|
213
|
+
idx.build(5);
|
|
214
|
+
return idx.getNnsByItem(0, 10);
|
|
215
|
+
};
|
|
216
|
+
buildWithSeed2 = buildWithSeed;
|
|
217
|
+
const vectors = Array.from({ length: 100 }, () => randomVector(DIMS));
|
|
218
|
+
const r1 = buildWithSeed(42);
|
|
219
|
+
const r2 = buildWithSeed(42);
|
|
220
|
+
assert(
|
|
221
|
+
JSON.stringify(r1) === JSON.stringify(r2),
|
|
222
|
+
"same seed produces same results"
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
var buildWithSeed2;
|
|
226
|
+
console.log(`
|
|
227
|
+
=== Results: ${passed} passed, ${failed} failed ===`);
|
|
228
|
+
process.exit(failed > 0 ? 1 : 0);
|
package/package.json
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@samyok/annoy",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Native Node.js bindings for Spotify's Annoy — fast approximate nearest neighbor search",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.mts",
|
|
12
|
+
"default": "./dist/index.mjs"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
7
20
|
"scripts": {
|
|
8
21
|
"install": "node-gyp rebuild",
|
|
9
22
|
"build:native": "node-gyp rebuild",
|
|
10
|
-
"build:ts": "
|
|
23
|
+
"build:ts": "tsup",
|
|
11
24
|
"build": "npm run build:native && npm run build:ts",
|
|
12
|
-
"test": "npm run build:ts && node dist/test.js",
|
|
25
|
+
"test": "npm run build:ts && node dist/test.js && node --input-type=module -e \"import('./dist/test.mjs')\"",
|
|
13
26
|
"prepublishOnly": "npm run build:ts"
|
|
14
27
|
},
|
|
15
28
|
"keywords": [
|
|
@@ -42,11 +55,11 @@
|
|
|
42
55
|
"devDependencies": {
|
|
43
56
|
"@types/node": "^25.7.0",
|
|
44
57
|
"node-gyp": "^11.2.0",
|
|
58
|
+
"tsup": "^8.5.1",
|
|
45
59
|
"typescript": "^5.8.3"
|
|
46
60
|
},
|
|
47
61
|
"files": [
|
|
48
|
-
"dist
|
|
49
|
-
"dist/**/*.d.ts",
|
|
62
|
+
"dist",
|
|
50
63
|
"src/addon.cc",
|
|
51
64
|
"deps/annoy/src/annoylib.h",
|
|
52
65
|
"deps/annoy/src/kissrandom.h",
|