@nacho-labs/nachos-embeddings 0.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.
@@ -0,0 +1,153 @@
1
+ /**
2
+ * In-memory vector store with semantic search
3
+ */
4
+ /**
5
+ * In-memory vector store for semantic search
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * const store = new VectorStore();
10
+ *
11
+ * // Add vectors
12
+ * store.add('doc1', embedding1, { content: 'Hello world' });
13
+ * store.add('doc2', embedding2, { content: 'Goodbye world' });
14
+ *
15
+ * // Semantic search
16
+ * const results = store.search(queryEmbedding, { limit: 5 });
17
+ * console.log(results); // [{ id: 'doc1', similarity: 0.95, metadata: {...} }]
18
+ * ```
19
+ */
20
+ export class VectorStore {
21
+ vectors = new Map();
22
+ config;
23
+ constructor(config = {}) {
24
+ this.config = {
25
+ minSimilarity: config.minSimilarity ?? 0.7,
26
+ defaultLimit: config.defaultLimit ?? 10,
27
+ cacheEmbeddings: config.cacheEmbeddings ?? true,
28
+ };
29
+ }
30
+ /**
31
+ * Add a vector to the store
32
+ */
33
+ add(id, vector, metadata) {
34
+ this.vectors.set(id, { id, vector, metadata });
35
+ }
36
+ /**
37
+ * Add multiple vectors in batch
38
+ */
39
+ addBatch(entries) {
40
+ for (const entry of entries) {
41
+ this.add(entry.id, entry.vector, entry.metadata);
42
+ }
43
+ }
44
+ /**
45
+ * Search for similar vectors using cosine similarity
46
+ */
47
+ search(queryVector, options) {
48
+ const results = [];
49
+ const minSim = options?.minSimilarity ?? this.config.minSimilarity;
50
+ const limit = options?.limit ?? this.config.defaultLimit;
51
+ for (const entry of this.vectors.values()) {
52
+ // Apply filter if provided
53
+ if (options?.filter && !options.filter(entry.metadata)) {
54
+ continue;
55
+ }
56
+ const similarity = cosineSimilarity(queryVector, entry.vector);
57
+ if (similarity >= minSim) {
58
+ results.push({
59
+ id: entry.id,
60
+ similarity,
61
+ metadata: entry.metadata,
62
+ });
63
+ }
64
+ }
65
+ // Sort by similarity (descending)
66
+ results.sort((a, b) => b.similarity - a.similarity);
67
+ return results.slice(0, limit);
68
+ }
69
+ /**
70
+ * Get a vector by ID
71
+ */
72
+ get(id) {
73
+ return this.vectors.get(id);
74
+ }
75
+ /**
76
+ * Remove a vector by ID
77
+ */
78
+ remove(id) {
79
+ return this.vectors.delete(id);
80
+ }
81
+ /**
82
+ * Clear all vectors
83
+ */
84
+ clear() {
85
+ this.vectors.clear();
86
+ }
87
+ /**
88
+ * Get number of vectors in store
89
+ */
90
+ size() {
91
+ return this.vectors.size;
92
+ }
93
+ /**
94
+ * Get all vector IDs
95
+ */
96
+ keys() {
97
+ return Array.from(this.vectors.keys());
98
+ }
99
+ /**
100
+ * Export all vectors (for persistence)
101
+ */
102
+ export() {
103
+ return Array.from(this.vectors.values());
104
+ }
105
+ /**
106
+ * Import vectors (from persistence)
107
+ */
108
+ import(entries) {
109
+ for (const entry of entries) {
110
+ this.vectors.set(entry.id, entry);
111
+ }
112
+ }
113
+ }
114
+ /**
115
+ * Calculate cosine similarity between two vectors
116
+ * Returns a value between -1 and 1, where 1 means identical direction
117
+ */
118
+ export function cosineSimilarity(a, b) {
119
+ if (a.length !== b.length) {
120
+ throw new Error(`Vector dimension mismatch: ${a.length} vs ${b.length}`);
121
+ }
122
+ if (a.length === 0) {
123
+ return 0;
124
+ }
125
+ let dotProduct = 0;
126
+ let magnitudeA = 0;
127
+ let magnitudeB = 0;
128
+ for (let i = 0; i < a.length; i++) {
129
+ const aVal = a[i] ?? 0;
130
+ const bVal = b[i] ?? 0;
131
+ dotProduct += aVal * bVal;
132
+ magnitudeA += aVal * aVal;
133
+ magnitudeB += bVal * bVal;
134
+ }
135
+ magnitudeA = Math.sqrt(magnitudeA);
136
+ magnitudeB = Math.sqrt(magnitudeB);
137
+ if (magnitudeA === 0 || magnitudeB === 0) {
138
+ return 0;
139
+ }
140
+ return dotProduct / (magnitudeA * magnitudeB);
141
+ }
142
+ /**
143
+ * Normalize a vector to unit length
144
+ * Useful for storing vectors in a normalized form
145
+ */
146
+ export function normalizeVector(vector) {
147
+ const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0));
148
+ if (magnitude === 0) {
149
+ return vector.slice(); // Return copy
150
+ }
151
+ return vector.map((val) => val / magnitude);
152
+ }
153
+ //# sourceMappingURL=vector-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-store.js","sourceRoot":"","sources":["../src/vector-store.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@nacho-labs/nachos-embeddings",
3
+ "version": "0.1.0",
4
+ "description": "Local, privacy-first vector embeddings and semantic search using Transformers.js",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "scripts": {
20
+ "build": "tsc",
21
+ "dev": "tsc --watch",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "test:coverage": "vitest run --coverage",
25
+ "lint": "eslint \"src/**/*.ts\" \"tests/**/*.ts\"",
26
+ "lint:fix": "eslint \"src/**/*.ts\" \"tests/**/*.ts\" --fix",
27
+ "format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"README.md\"",
28
+ "typecheck": "tsc --noEmit",
29
+ "clean": "rm -rf dist *.tsbuildinfo",
30
+ "prepublishOnly": "npm run build",
31
+ "version:patch": "npm version patch",
32
+ "version:minor": "npm version minor",
33
+ "version:major": "npm version major",
34
+ "publish:npm": "npm publish --access public",
35
+ "release:patch": "npm run version:patch && npm run publish:npm",
36
+ "release:minor": "npm run version:minor && npm run publish:npm",
37
+ "release:major": "npm run version:major && npm run publish:npm"
38
+ },
39
+ "keywords": [
40
+ "embeddings",
41
+ "vector-search",
42
+ "semantic-search",
43
+ "transformers",
44
+ "ml",
45
+ "local",
46
+ "privacy",
47
+ "ai",
48
+ "nlp",
49
+ "similarity"
50
+ ],
51
+ "author": "Nate Richardson <hello@naterichardson.com> (https://naterichardson.com)",
52
+ "license": "MIT",
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ },
56
+ "repository": {
57
+ "type": "git",
58
+ "url": "git+https://github.com/nacho-labs-llc/nachos-embeddings.git"
59
+ },
60
+ "dependencies": {
61
+ "@xenova/transformers": "^2.17.2"
62
+ },
63
+ "devDependencies": {
64
+ "@types/node": "^22.0.0",
65
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
66
+ "@typescript-eslint/parser": "^8.0.0",
67
+ "@vitest/coverage-v8": "^2.0.0",
68
+ "eslint": "^9.0.0",
69
+ "eslint-config-prettier": "^9.0.0",
70
+ "globals": "^15.0.0",
71
+ "prettier": "^3.0.0",
72
+ "typescript": "^5.7.0",
73
+ "vitest": "^2.0.0"
74
+ }
75
+ }