eigen-db 4.1.0 → 4.3.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/eigen-db.js CHANGED
@@ -1,113 +1,113 @@
1
- class Q extends Error {
2
- constructor(A) {
3
- super(`Capacity exceeded. Max vectors for this dimension size is ~${A}.`), this.name = "VectorCapacityExceededError";
1
+ class k extends Error {
2
+ constructor(e) {
3
+ super(`Capacity exceeded. Max vectors for this dimension size is ~${e}.`), this.name = "VectorCapacityExceededError";
4
4
  }
5
5
  }
6
- class C {
6
+ class _ {
7
7
  dirHandle = null;
8
8
  dirName;
9
- constructor(A) {
10
- this.dirName = A;
9
+ constructor(e) {
10
+ this.dirName = e;
11
11
  }
12
12
  async getDir() {
13
13
  if (!this.dirHandle) {
14
- const A = await navigator.storage.getDirectory();
15
- this.dirHandle = await A.getDirectoryHandle(this.dirName, { create: !0 });
14
+ const e = await navigator.storage.getDirectory();
15
+ this.dirHandle = await e.getDirectoryHandle(this.dirName, { create: !0 });
16
16
  }
17
17
  return this.dirHandle;
18
18
  }
19
- async readAll(A) {
19
+ async readAll(e) {
20
20
  try {
21
- const r = await (await (await (await this.getDir()).getFileHandle(A)).getFile()).arrayBuffer();
22
- return new Uint8Array(r);
21
+ const n = await (await (await (await this.getDir()).getFileHandle(e)).getFile()).arrayBuffer();
22
+ return new Uint8Array(n);
23
23
  } catch {
24
24
  return new Uint8Array(0);
25
25
  }
26
26
  }
27
- async append(A, e) {
28
- const t = await (await this.getDir()).getFileHandle(A, { create: !0 }), r = await t.createWritable({ keepExistingData: !0 }), o = await t.getFile();
29
- await r.seek(o.size), await r.write(e), await r.close();
27
+ async append(e, t) {
28
+ const s = await (await this.getDir()).getFileHandle(e, { create: !0 }), n = await s.createWritable({ keepExistingData: !0 }), i = await s.getFile();
29
+ await n.seek(i.size), await n.write(t), await n.close();
30
30
  }
31
- async write(A, e) {
32
- const r = await (await (await this.getDir()).getFileHandle(A, { create: !0 })).createWritable({ keepExistingData: !1 });
33
- await r.write(e), await r.close();
31
+ async write(e, t) {
32
+ const n = await (await (await this.getDir()).getFileHandle(e, { create: !0 })).createWritable({ keepExistingData: !1 });
33
+ await n.write(t), await n.close();
34
34
  }
35
35
  async destroy() {
36
36
  await (await navigator.storage.getDirectory()).removeEntry(this.dirName, { recursive: !0 }), this.dirHandle = null;
37
37
  }
38
38
  }
39
- class O {
39
+ class v {
40
40
  files = /* @__PURE__ */ new Map();
41
- async readAll(A) {
42
- const e = this.files.get(A);
43
- if (!e || e.length === 0) return new Uint8Array(0);
44
- const s = e.reduce((o, a) => o + a.byteLength, 0), t = new Uint8Array(s);
45
- let r = 0;
46
- for (const o of e)
47
- t.set(o, r), r += o.byteLength;
48
- return t;
41
+ async readAll(e) {
42
+ const t = this.files.get(e);
43
+ if (!t || t.length === 0) return new Uint8Array(0);
44
+ const r = t.reduce((i, a) => i + a.byteLength, 0), s = new Uint8Array(r);
45
+ let n = 0;
46
+ for (const i of t)
47
+ s.set(i, n), n += i.byteLength;
48
+ return s;
49
49
  }
50
- async append(A, e) {
51
- this.files.has(A) || this.files.set(A, []), this.files.get(A).push(new Uint8Array(e));
50
+ async append(e, t) {
51
+ this.files.has(e) || this.files.set(e, []), this.files.get(e).push(new Uint8Array(t));
52
52
  }
53
- async write(A, e) {
54
- this.files.set(A, [new Uint8Array(e)]);
53
+ async write(e, t) {
54
+ this.files.set(e, [new Uint8Array(t)]);
55
55
  }
56
56
  async destroy() {
57
57
  this.files.clear();
58
58
  }
59
59
  }
60
- function E(n) {
61
- let A = 0;
62
- for (let t = 0; t < n.length; t++)
63
- A += n[t] * n[t];
64
- const e = Math.sqrt(A);
65
- if (e === 0) return;
66
- const s = 1 / e;
67
- for (let t = 0; t < n.length; t++)
68
- n[t] *= s;
60
+ function S(c) {
61
+ let e = 0;
62
+ for (let s = 0; s < c.length; s++)
63
+ e += c[s] * c[s];
64
+ const t = Math.sqrt(e);
65
+ if (t === 0) return;
66
+ const r = 1 / t;
67
+ for (let s = 0; s < c.length; s++)
68
+ c[s] *= r;
69
69
  }
70
- function b(n, A, e, s, t) {
71
- for (let r = 0; r < s; r++) {
72
- let o = 0;
73
- const a = r * t;
74
- for (let i = 0; i < t; i++)
75
- o += n[i] * A[a + i];
76
- e[r] = o;
70
+ function O(c, e, t, r, s) {
71
+ for (let n = 0; n < r; n++) {
72
+ let i = 0;
73
+ const a = n * s;
74
+ for (let o = 0; o < s; o++)
75
+ i += c[o] * e[a + o];
76
+ t[n] = i;
77
77
  }
78
78
  }
79
- const M = new TextEncoder(), D = new TextDecoder();
80
- function S(n) {
81
- const A = n.map((a) => M.encode(a)), e = A.reduce((a, i) => a + 4 + i.byteLength, 0), s = new ArrayBuffer(e), t = new DataView(s), r = new Uint8Array(s);
82
- let o = 0;
83
- for (const a of A)
84
- t.setUint32(o, a.byteLength, !0), o += 4, r.set(a, o), o += a.byteLength;
85
- return r;
79
+ const U = new TextEncoder(), x = new TextDecoder();
80
+ function d(c) {
81
+ const e = c.map((a) => U.encode(a)), t = e.reduce((a, o) => a + 4 + o.byteLength, 0), r = new ArrayBuffer(t), s = new DataView(r), n = new Uint8Array(r);
82
+ let i = 0;
83
+ for (const a of e)
84
+ s.setUint32(i, a.byteLength, !0), i += 4, n.set(a, i), i += a.byteLength;
85
+ return n;
86
86
  }
87
- function k(n) {
88
- const A = [], e = new DataView(n.buffer, n.byteOffset, n.byteLength);
89
- let s = 0;
90
- for (; s < n.byteLength; ) {
91
- const t = e.getUint32(s, !0);
92
- s += 4;
93
- const r = D.decode(n.subarray(s, s + t));
94
- A.push(r), s += t;
95
- }
96
- return A;
87
+ function g(c) {
88
+ const e = [], t = new DataView(c.buffer, c.byteOffset, c.byteLength);
89
+ let r = 0;
90
+ for (; r < c.byteLength; ) {
91
+ const s = t.getUint32(r, !0);
92
+ r += 4;
93
+ const n = x.decode(c.subarray(r, r + s));
94
+ e.push(n), r += s;
95
+ }
96
+ return e;
97
97
  }
98
- const f = 65536, d = 65536;
99
- class v {
98
+ const m = 65536, w = 65536;
99
+ class Q {
100
100
  memory;
101
101
  dimensions;
102
102
  queryOffset;
103
103
  dbOffset;
104
104
  _vectorCount;
105
- constructor(A, e = 0) {
106
- this.dimensions = A, this.queryOffset = 0;
107
- const s = A * 4;
108
- this.dbOffset = Math.ceil(s / f) * f;
109
- const t = e * A * 4, r = this.dbOffset + t, o = Math.max(1, Math.ceil(r / f));
110
- this.memory = new WebAssembly.Memory({ initial: o }), this._vectorCount = e;
105
+ constructor(e, t = 0) {
106
+ this.dimensions = e, this.queryOffset = 0;
107
+ const r = e * 4;
108
+ this.dbOffset = Math.ceil(r / m) * m;
109
+ const s = t * e * 4, n = this.dbOffset + s, i = Math.max(1, Math.ceil(n / m));
110
+ this.memory = new WebAssembly.Memory({ initial: i }), this._vectorCount = t;
111
111
  }
112
112
  /** Current number of vectors stored */
113
113
  get vectorCount() {
@@ -126,45 +126,45 @@ class v {
126
126
  * Accounts for query buffer, DB space, and scores buffer.
127
127
  */
128
128
  get maxVectors() {
129
- const A = d * f - this.dbOffset, e = this.dimensions * 4 + 4;
130
- return Math.floor(A / e);
129
+ const e = w * m - this.dbOffset, t = this.dimensions * 4 + 4;
130
+ return Math.floor(e / t);
131
131
  }
132
132
  /**
133
133
  * Ensures memory is large enough for the current DB + scores buffer.
134
134
  * Calls memory.grow() if needed.
135
135
  */
136
- ensureCapacity(A) {
137
- const e = this._vectorCount + A, s = this.dbOffset + e * this.dimensions * 4 + e * 4, t = this.memory.buffer.byteLength;
138
- if (s > t) {
139
- const r = Math.ceil((s - t) / f);
140
- if (t / f + r > d)
136
+ ensureCapacity(e) {
137
+ const t = this._vectorCount + e, r = this.dbOffset + t * this.dimensions * 4 + t * 4, s = this.memory.buffer.byteLength;
138
+ if (r > s) {
139
+ const n = Math.ceil((r - s) / m);
140
+ if (s / m + n > w)
141
141
  throw new Error("WASM memory limit exceeded");
142
- this.memory.grow(r);
142
+ this.memory.grow(n);
143
143
  }
144
144
  }
145
145
  /**
146
146
  * Write a query vector into the query buffer region.
147
147
  */
148
- writeQuery(A) {
149
- new Float32Array(this.memory.buffer, this.queryOffset, this.dimensions).set(A);
148
+ writeQuery(e) {
149
+ new Float32Array(this.memory.buffer, this.queryOffset, this.dimensions).set(e);
150
150
  }
151
151
  /**
152
152
  * Append vectors to the database region.
153
153
  * Returns the byte offset where the new vectors were written.
154
154
  */
155
- appendVectors(A) {
156
- const e = this.dbOffset + this._vectorCount * this.dimensions * 4;
157
- let s = e;
158
- for (const t of A)
159
- new Float32Array(this.memory.buffer, s, this.dimensions).set(t), s += this.dimensions * 4;
160
- return this._vectorCount += A.length, e;
155
+ appendVectors(e) {
156
+ const t = this.dbOffset + this._vectorCount * this.dimensions * 4;
157
+ let r = t;
158
+ for (const s of e)
159
+ new Float32Array(this.memory.buffer, r, this.dimensions).set(s), r += this.dimensions * 4;
160
+ return this._vectorCount += e.length, t;
161
161
  }
162
162
  /**
163
163
  * Load raw vector bytes directly into the database region.
164
164
  * Used for bulk loading from OPFS.
165
165
  */
166
- loadVectorBytes(A, e) {
167
- new Uint8Array(this.memory.buffer, this.dbOffset, A.byteLength).set(A), this._vectorCount = e;
166
+ loadVectorBytes(e, t) {
167
+ new Uint8Array(this.memory.buffer, this.dbOffset, e.byteLength).set(e), this._vectorCount = t;
168
168
  }
169
169
  /**
170
170
  * Read the scores buffer as a Float32Array view.
@@ -175,16 +175,16 @@ class v {
175
175
  /**
176
176
  * Read the DB region for a specific vector index.
177
177
  */
178
- readVector(A) {
179
- const e = this.dbOffset + A * this.dimensions * 4;
180
- return new Float32Array(this.memory.buffer, e, this.dimensions);
178
+ readVector(e) {
179
+ const t = this.dbOffset + e * this.dimensions * 4;
180
+ return new Float32Array(this.memory.buffer, t, this.dimensions);
181
181
  }
182
182
  /**
183
183
  * Write a vector to a specific slot in the database region.
184
184
  */
185
- writeVector(A, e) {
186
- const s = this.dbOffset + A * this.dimensions * 4;
187
- new Float32Array(this.memory.buffer, s, this.dimensions).set(e);
185
+ writeVector(e, t) {
186
+ const r = this.dbOffset + e * this.dimensions * 4;
187
+ new Float32Array(this.memory.buffer, r, this.dimensions).set(t);
188
188
  }
189
189
  /**
190
190
  * Reset the vector count to zero, logically clearing the database.
@@ -193,57 +193,64 @@ class v {
193
193
  reset() {
194
194
  this._vectorCount = 0;
195
195
  }
196
+ /**
197
+ * Set the vector count after bulk-loading data directly into the DB region.
198
+ * Use when writing raw bytes to the DB region externally (e.g., streaming import).
199
+ */
200
+ setVectorCount(e) {
201
+ this._vectorCount = e;
202
+ }
196
203
  }
197
- function G(n, A, e, s) {
198
- const t = n.length;
199
- if (t === 0) return [];
200
- const r = new Uint32Array(t);
201
- for (let i = 0; i < t; i++) r[i] = i;
202
- r.sort((i, c) => n[c] - n[i]);
203
- const o = Math.min(e, t), a = [];
204
- for (let i = 0; i < o; i++) {
205
- const c = r[i], h = 1 - n[c];
206
- if (s !== void 0 && h > s) break;
207
- a.push({ key: A(c), distance: h });
204
+ function D(c, e, t, r) {
205
+ const s = c.length;
206
+ if (s === 0) return [];
207
+ const n = new Uint32Array(s);
208
+ for (let o = 0; o < s; o++) n[o] = o;
209
+ n.sort((o, h) => c[h] - c[o]);
210
+ const i = Math.min(t, s), a = [];
211
+ for (let o = 0; o < i; o++) {
212
+ const h = n[o], f = c[h];
213
+ if (r !== void 0 && f < r) break;
214
+ a.push({ key: e(h), similarity: f });
208
215
  }
209
216
  return a;
210
217
  }
211
- function x(n, A, e, s) {
212
- const t = n.length;
213
- if (t === 0) return [];
214
- const r = new Uint32Array(t);
215
- for (let a = 0; a < t; a++) r[a] = a;
216
- r.sort((a, i) => n[i] - n[a]);
217
- const o = Math.min(e, t);
218
+ function L(c, e, t, r) {
219
+ const s = c.length;
220
+ if (s === 0) return [];
221
+ const n = new Uint32Array(s);
222
+ for (let a = 0; a < s; a++) n[a] = a;
223
+ n.sort((a, o) => c[o] - c[a]);
224
+ const i = Math.min(t, s);
218
225
  return {
219
226
  [Symbol.iterator]() {
220
227
  let a = 0;
221
228
  return {
222
229
  next() {
223
- if (a >= o) return { done: !0, value: void 0 };
224
- const i = r[a++], c = 1 - n[i];
225
- return s !== void 0 && c > s ? { done: !0, value: void 0 } : {
230
+ if (a >= i) return { done: !0, value: void 0 };
231
+ const o = n[a++], h = c[o];
232
+ return r !== void 0 && h < r ? { done: !0, value: void 0 } : {
226
233
  done: !1,
227
- value: { key: A(i), distance: c }
234
+ value: { key: e(o), similarity: h }
228
235
  };
229
236
  }
230
237
  };
231
238
  }
232
239
  };
233
240
  }
234
- const H = "AGFzbQEAAAABDgJgAn9/AGAFf39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQcaAglub3JtYWxpemUAAApzZWFyY2hfYWxsAAEKgQ4C3wQFAX8EewN9AXsDf/0MAAAAAAAAAAAAAAAAAAAAACED/QwAAAAAAAAAAAAAAAAAAAAAIQT9DAAAAAAAAAAAAAAAAAAAAAAhBf0MAAAAAAAAAAAAAAAAAAAAACEGIAFBcHEhCyABQXxxIQxBACECAkADQCACIAtPDQEgACACQQJ0aiENIAMgDf0ABAAgDf0ABAD95gH95AEhAyAEIA39AAQQIA39AAQQ/eYB/eQBIQQgBSAN/QAEICAN/QAEIP3mAf3kASEFIAYgDf0ABDAgDf0ABDD95gH95AEhBiACQRBqIQIMAAsLIAMgBP3kASAFIAb95AH95AEhAwJAA0AgAiAMTw0BIAAgAkECdGohDSADIA39AAQAIA39AAQA/eYB/eQBIQMgAkEEaiECDAALCyAD/R8AIAP9HwGSIAP9HwIgA/0fA5KSIQcCQANAIAIgAU8NASAAIAJBAnRqIQ0gByANKgIAIA0qAgCUkiEHIAJBAWohAgwACwsgB5EhCCAIQwAAAABbBEAPC0MAAIA/IAiVIQkgCf0TIQpBACECAkADQCACIAtPDQEgACACQQJ0aiENIA0gDf0ABAAgCv3mAf0LBAAgDSAN/QAEECAK/eYB/QsEECANIA39AAQgIAr95gH9CwQgIA0gDf0ABDAgCv3mAf0LBDAgAkEQaiECDAALCwJAA0AgAiAMTw0BIAAgAkECdGohDSANIA39AAQAIAr95gH9CwQAIAJBBGohAgwACwsCQANAIAIgAU8NASAAIAJBAnRqIQ0gDSANKgIAIAmUOAIAIAJBAWohAgwACwsLnQkEAn8MewJ9CX8gBEFwcSEXIARBfHEhGCAEQQJ0IRwgA0F+cSEdQQAhBQJAA0AgBSAdTw0BIAEgBSAcbGohFSAVIBxqIRb9DAAAAAAAAAAAAAAAAAAAAAAhB/0MAAAAAAAAAAAAAAAAAAAAACEI/QwAAAAAAAAAAAAAAAAAAAAAIQn9DAAAAAAAAAAAAAAAAAAAAAAhCv0MAAAAAAAAAAAAAAAAAAAAACEL/QwAAAAAAAAAAAAAAAAAAAAAIQz9DAAAAAAAAAAAAAAAAAAAAAAhDf0MAAAAAAAAAAAAAAAAAAAAACEOQQAhBgJAA0AgBiAXTw0BIAAgBkECdGohGSAVIAZBAnRqIRogFiAGQQJ0aiEbIBn9AAQAIQ8gGf0ABBAhECAZ/QAEICERIBn9AAQwIRIgByAPIBr9AAQA/eYB/eQBIQcgCCAQIBr9AAQQ/eYB/eQBIQggCSARIBr9AAQg/eYB/eQBIQkgCiASIBr9AAQw/eYB/eQBIQogCyAPIBv9AAQA/eYB/eQBIQsgDCAQIBv9AAQQ/eYB/eQBIQwgDSARIBv9AAQg/eYB/eQBIQ0gDiASIBv9AAQw/eYB/eQBIQ4gBkEQaiEGDAALCyAHIAj95AEgCSAK/eQB/eQBIQcgCyAM/eQBIA0gDv3kAf3kASELAkADQCAGIBhPDQEgACAGQQJ0aiEZIBUgBkECdGohGiAWIAZBAnRqIRsgGf0ABAAhDyAHIA8gGv0ABAD95gH95AEhByALIA8gG/0ABAD95gH95AEhCyAGQQRqIQYMAAsLIAf9HwAgB/0fAZIgB/0fAiAH/R8DkpIhEyAL/R8AIAv9HwGSIAv9HwIgC/0fA5KSIRQCQANAIAYgBE8NASAAIAZBAnRqIRkgFSAGQQJ0aiEaIBYgBkECdGohGyATIBkqAgAgGioCAJSSIRMgFCAZKgIAIBsqAgCUkiEUIAZBAWohBgwACwsgAiAFQQJ0aiATOAIAIAIgBUEBakECdGogFDgCACAFQQJqIQUMAAsLIAUgA0kEQCABIAUgHGxqIRX9DAAAAAAAAAAAAAAAAAAAAAAhB/0MAAAAAAAAAAAAAAAAAAAAACEI/QwAAAAAAAAAAAAAAAAAAAAAIQn9DAAAAAAAAAAAAAAAAAAAAAAhCkEAIQYCQANAIAYgF08NASAAIAZBAnRqIRkgFSAGQQJ0aiEaIAcgGf0ABAAgGv0ABAD95gH95AEhByAIIBn9AAQQIBr9AAQQ/eYB/eQBIQggCSAZ/QAEICAa/QAEIP3mAf3kASEJIAogGf0ABDAgGv0ABDD95gH95AEhCiAGQRBqIQYMAAsLIAcgCP3kASAJIAr95AH95AEhBwJAA0AgBiAYTw0BIAAgBkECdGohGSAVIAZBAnRqIRogByAZ/QAEACAa/QAEAP3mAf3kASEHIAZBBGohBgwACwsgB/0fACAH/R8BkiAH/R8CIAf9HwOSkiETAkADQCAGIARPDQEgACAGQQJ0aiEZIBUgBkECdGohGiATIBkqAgAgGioCAJSSIRMgBkEBaiEGDAALCyACIAVBAnRqIBM4AgALCw==";
235
- function p() {
236
- const n = atob(H), A = new Uint8Array(n.length);
237
- for (let e = 0; e < n.length; e++)
238
- A[e] = n.charCodeAt(e);
239
- return A;
241
+ const V = "AGFzbQEAAAABDgJgAn9/AGAFf39/f38AAg8BA2VudgZtZW1vcnkCAAEDAwIAAQcaAglub3JtYWxpemUAAApzZWFyY2hfYWxsAAEKpgQCrQIFAX8BewN9AXsCf/0MAAAAAAAAAAAAAAAAAAAAACEDIAFBfHEhCEEAIQICQANAIAIgCE8NASAAIAJBAnRqIQkgAyAJ/QAEACAJ/QAEAP3mAf3kASEDIAJBBGohAgwACwsgA/0fACAD/R8BkiAD/R8CIAP9HwOSkiEEAkADQCACIAFPDQEgACACQQJ0aiEJIAQgCSoCACAJKgIAlJIhBCACQQFqIQIMAAsLIASRIQUgBUMAAAAAWwRADwtDAACAPyAFlSEGIAb9EyEHQQAhAgJAA0AgAiAITw0BIAAgAkECdGohCSAJIAn9AAQAIAf95gH9CwQAIAJBBGohAgwACwsCQANAIAIgAU8NASAAIAJBAnRqIQkgCSAJKgIAIAaUOAIAIAJBAWohAgwACwsL9AEEAn8BewF9BX8gBEF8cSEKIARBAnQhDUEAIQUCQANAIAUgA08NASABIAUgDWxqIQn9DAAAAAAAAAAAAAAAAAAAAAAhB0EAIQYCQANAIAYgCk8NASAAIAZBAnRqIQsgCSAGQQJ0aiEMIAcgC/0ABAAgDP0ABAD95gH95AEhByAGQQRqIQYMAAsLIAf9HwAgB/0fAZIgB/0fAiAH/R8DkpIhCAJAA0AgBiAETw0BIAAgBkECdGohCyAJIAZBAnRqIQwgCCALKgIAIAwqAgCUkiEIIAZBAWohBgwACwsgAiAFQQJ0aiAIOAIAIAVBAWohBQwACwsL";
242
+ function T() {
243
+ const c = atob(V), e = new Uint8Array(c.length);
244
+ for (let t = 0; t < c.length; t++)
245
+ e[t] = c.charCodeAt(t);
246
+ return e;
240
247
  }
241
- async function F(n, A) {
242
- const e = { env: { memory: A } };
243
- return (await WebAssembly.instantiate(n, e)).instance.exports;
248
+ async function F(c, e) {
249
+ const t = { env: { memory: e } };
250
+ return (await WebAssembly.instantiate(c, t)).instance.exports;
244
251
  }
245
- const B = "vectors.bin", I = "keys.bin";
246
- class w {
252
+ const b = "vectors.bin", E = "keys.bin", C = 1111770949, u = 1, I = 24, z = 65536;
253
+ class M {
247
254
  memoryManager;
248
255
  storage;
249
256
  dimensions;
@@ -255,23 +262,23 @@ class w {
255
262
  slotToKey;
256
263
  /** Whether this instance has been closed */
257
264
  closed = !1;
258
- constructor(A, e, s, t, r, o, a) {
259
- this.memoryManager = A, this.storage = e, this.dimensions = s, this.shouldNormalize = t, this.wasmExports = r, this.keyToSlot = o, this.slotToKey = a;
260
- }
261
- static async open(A) {
262
- const e = A.name ?? "default", s = A.storage ?? new C(e), t = A.normalize !== !1, [r, o] = await Promise.all([s.readAll(B), s.readAll(I)]), a = o.byteLength > 0 ? k(o) : [], i = r.byteLength / (A.dimensions * 4), c = /* @__PURE__ */ new Map(), h = [];
263
- for (let g = 0; g < a.length; g++)
264
- c.set(a[g], g), h[g] = a[g];
265
- const y = new v(A.dimensions, i);
266
- r.byteLength > 0 && y.loadVectorBytes(r, i);
267
- let m = null;
268
- const l = A.wasmBinary !== void 0 ? A.wasmBinary : p();
269
- if (l !== null)
265
+ constructor(e, t, r, s, n, i, a) {
266
+ this.memoryManager = e, this.storage = t, this.dimensions = r, this.shouldNormalize = s, this.wasmExports = n, this.keyToSlot = i, this.slotToKey = a;
267
+ }
268
+ static async open(e) {
269
+ const t = e.storage ?? new v(), r = e.normalize !== !1, [s, n] = await Promise.all([t.readAll(b), t.readAll(E)]), i = n.byteLength > 0 ? g(n) : [], a = s.byteLength / (e.dimensions * 4), o = /* @__PURE__ */ new Map(), h = [];
270
+ for (let A = 0; A < i.length; A++)
271
+ o.set(i[A], A), h[A] = i[A];
272
+ const f = new Q(e.dimensions, a);
273
+ s.byteLength > 0 && f.loadVectorBytes(s, a);
274
+ let l = null;
275
+ const y = e.wasmBinary !== void 0 ? e.wasmBinary : T();
276
+ if (y !== null)
270
277
  try {
271
- m = await F(l, y.memory);
278
+ l = await F(y, f.memory);
272
279
  } catch {
273
280
  }
274
- return new w(y, s, A.dimensions, t, m, c, h);
281
+ return new M(f, t, e.dimensions, r, l, o, h);
275
282
  }
276
283
  /** Total number of key-value pairs in the database */
277
284
  get size() {
@@ -281,94 +288,94 @@ class w {
281
288
  * Set a key-value pair. If the key already exists, its vector is overwritten (last-write-wins).
282
289
  * The value is a number[] or Float32Array of length equal to the configured dimensions.
283
290
  */
284
- set(A, e, s) {
285
- if (this.assertOpen(), e.length !== this.dimensions)
286
- throw new Error(`Vector dimension mismatch: expected ${this.dimensions}, got ${e.length}`);
287
- const t = new Float32Array(e);
288
- (s?.normalize ?? this.shouldNormalize) && this.normalizeVector(t);
289
- const o = this.keyToSlot.get(A);
290
- if (o !== void 0)
291
- this.memoryManager.writeVector(o, t);
291
+ set(e, t, r) {
292
+ if (this.assertOpen(), t.length !== this.dimensions)
293
+ throw new Error(`Vector dimension mismatch: expected ${this.dimensions}, got ${t.length}`);
294
+ const s = new Float32Array(t);
295
+ (r?.normalize ?? this.shouldNormalize) && this.normalizeVector(s);
296
+ const i = this.keyToSlot.get(e);
297
+ if (i !== void 0)
298
+ this.memoryManager.writeVector(i, s);
292
299
  else {
293
300
  if (this.memoryManager.vectorCount + 1 > this.memoryManager.maxVectors)
294
- throw new Q(this.memoryManager.maxVectors);
301
+ throw new k(this.memoryManager.maxVectors);
295
302
  this.memoryManager.ensureCapacity(1);
296
- const i = this.memoryManager.vectorCount;
297
- this.memoryManager.appendVectors([t]), this.keyToSlot.set(A, i), this.slotToKey[i] = A;
303
+ const o = this.memoryManager.vectorCount;
304
+ this.memoryManager.appendVectors([s]), this.keyToSlot.set(e, o), this.slotToKey[o] = e;
298
305
  }
299
306
  }
300
307
  /**
301
308
  * Get the stored vector for a key. Returns undefined if the key does not exist.
302
309
  * Returns a copy of the stored vector as a plain number array.
303
310
  */
304
- get(A) {
311
+ get(e) {
305
312
  this.assertOpen();
306
- const e = this.keyToSlot.get(A);
307
- if (e !== void 0)
308
- return Array.from(this.memoryManager.readVector(e));
313
+ const t = this.keyToSlot.get(e);
314
+ if (t !== void 0)
315
+ return Array.from(this.memoryManager.readVector(t));
309
316
  }
310
317
  /**
311
318
  * Set multiple key-value pairs at once. Last-write-wins applies within the batch.
312
319
  */
313
- setMany(A) {
314
- for (const [e, s] of A)
315
- this.set(e, s);
320
+ setMany(e) {
321
+ for (const [t, r] of e)
322
+ this.set(t, r);
316
323
  }
317
324
  /**
318
325
  * Get vectors for multiple keys. Returns undefined for keys that don't exist.
319
326
  */
320
- getMany(A) {
321
- return A.map((e) => this.get(e));
327
+ getMany(e) {
328
+ return e.map((t) => this.get(t));
322
329
  }
323
- query(A, e) {
330
+ query(e, t) {
324
331
  this.assertOpen();
325
- const s = e?.topK ?? 1 / 0, t = e?.maxDistance, r = e && "iterable" in e && e.iterable;
332
+ const r = t?.topK ?? 1 / 0, s = t?.minSimilarity, n = t && "iterable" in t && t.iterable;
326
333
  if (this.size === 0)
327
334
  return [];
328
- if (A.length !== this.dimensions)
329
- throw new Error(`Query vector dimension mismatch: expected ${this.dimensions}, got ${A.length}`);
330
- const o = new Float32Array(A);
331
- (e?.normalize ?? this.shouldNormalize) && this.normalizeVector(o), this.memoryManager.writeQuery(o), this.memoryManager.ensureCapacity(0);
332
- const i = this.memoryManager.vectorCount, c = this.memoryManager.scoresOffset;
335
+ if (e.length !== this.dimensions)
336
+ throw new Error(`Query vector dimension mismatch: expected ${this.dimensions}, got ${e.length}`);
337
+ const i = new Float32Array(e);
338
+ (t?.normalize ?? this.shouldNormalize) && this.normalizeVector(i), this.memoryManager.writeQuery(i), this.memoryManager.ensureCapacity(0);
339
+ const o = this.memoryManager.vectorCount, h = this.memoryManager.scoresOffset;
333
340
  if (this.wasmExports)
334
341
  this.wasmExports.search_all(
335
342
  this.memoryManager.queryOffset,
336
343
  this.memoryManager.dbOffset,
337
- c,
338
- i,
344
+ h,
345
+ o,
339
346
  this.dimensions
340
347
  );
341
348
  else {
342
- const l = new Float32Array(
349
+ const A = new Float32Array(
343
350
  this.memoryManager.memory.buffer,
344
351
  this.memoryManager.queryOffset,
345
352
  this.dimensions
346
- ), g = new Float32Array(
353
+ ), B = new Float32Array(
347
354
  this.memoryManager.memory.buffer,
348
355
  this.memoryManager.dbOffset,
349
- i * this.dimensions
350
- ), u = new Float32Array(this.memoryManager.memory.buffer, c, i);
351
- b(l, g, u, i, this.dimensions);
356
+ o * this.dimensions
357
+ ), p = new Float32Array(this.memoryManager.memory.buffer, h, o);
358
+ O(A, B, p, o, this.dimensions);
352
359
  }
353
- const h = new Float32Array(this.memoryManager.readScores()), y = this.slotToKey, m = (l) => y[l];
354
- return r ? x(h, m, s, t) : G(h, m, s, t);
360
+ const f = new Float32Array(this.memoryManager.readScores()), l = this.slotToKey, y = (A) => l[A];
361
+ return n ? L(f, y, r, s) : D(f, y, r, s);
355
362
  }
356
363
  /**
357
364
  * Persist the current in-memory state to storage.
358
365
  */
359
366
  async flush() {
360
367
  this.assertOpen();
361
- const A = this.memoryManager.vectorCount, e = new Uint8Array(A * this.dimensions * 4);
362
- if (A > 0) {
363
- const t = new Uint8Array(
368
+ const e = this.memoryManager.vectorCount, t = new Uint8Array(e * this.dimensions * 4);
369
+ if (e > 0) {
370
+ const s = new Uint8Array(
364
371
  this.memoryManager.memory.buffer,
365
372
  this.memoryManager.dbOffset,
366
- A * this.dimensions * 4
373
+ e * this.dimensions * 4
367
374
  );
368
- e.set(t);
375
+ t.set(s);
369
376
  }
370
- const s = S(this.slotToKey);
371
- await Promise.all([this.storage.write(B, e), this.storage.write(I, s)]);
377
+ const r = d(this.slotToKey);
378
+ await Promise.all([this.storage.write(b, t), this.storage.write(E, r)]);
372
379
  }
373
380
  /**
374
381
  * Flush data to storage and release the instance.
@@ -383,27 +390,142 @@ class w {
383
390
  async clear() {
384
391
  this.assertOpen(), this.keyToSlot.clear(), this.slotToKey.length = 0, this.memoryManager.reset(), await this.storage.destroy();
385
392
  }
393
+ /**
394
+ * Export the entire database as a ReadableStream of binary chunks.
395
+ *
396
+ * Format: [Header 24 bytes][Vector data][Keys data]
397
+ * Header: magic(4) + version(4) + dimensions(4) + vectorCount(4) + vectorDataLen(4) + keysDataLen(4)
398
+ *
399
+ * Vectors are streamed in 64KB chunks from WASM memory to avoid large
400
+ * heap allocations.
401
+ */
402
+ async export() {
403
+ this.assertOpen();
404
+ const e = this.memoryManager.vectorCount, t = e * this.dimensions * 4, r = d(this.slotToKey), s = r.byteLength, n = new ArrayBuffer(I), i = new DataView(n);
405
+ i.setUint32(0, C, !0), i.setUint32(4, u, !0), i.setUint32(8, this.dimensions, !0), i.setUint32(12, e, !0), i.setUint32(16, t, !0), i.setUint32(20, s, !0);
406
+ const a = this.memoryManager;
407
+ let o = "header", h = 0;
408
+ return new ReadableStream({
409
+ pull(f) {
410
+ switch (o) {
411
+ case "header":
412
+ f.enqueue(new Uint8Array(n)), o = t > 0 ? "vectors" : s > 0 ? "keys" : "done", o === "done" && f.close();
413
+ break;
414
+ case "vectors": {
415
+ const l = t - h, y = Math.min(l, z), A = new Uint8Array(y);
416
+ A.set(new Uint8Array(a.memory.buffer, a.dbOffset + h, y)), f.enqueue(A), h += y, h >= t && (o = s > 0 ? "keys" : "done", o === "done" && f.close());
417
+ break;
418
+ }
419
+ case "keys":
420
+ f.enqueue(r), o = "done", f.close();
421
+ break;
422
+ }
423
+ }
424
+ });
425
+ }
426
+ /**
427
+ * Import data from a ReadableStream, replacing all existing data.
428
+ * Performs a dimension check against the configured dimensions.
429
+ *
430
+ * Vectors are streamed directly into WASM memory in chunks to avoid
431
+ * large heap allocations.
432
+ */
433
+ async import(e) {
434
+ this.assertOpen();
435
+ const t = new q(e), r = await t.readExact(I), s = new DataView(r.buffer, r.byteOffset, r.byteLength);
436
+ if (s.getUint32(0, !0) !== C)
437
+ throw new Error("Invalid import data: unrecognized format");
438
+ const i = s.getUint32(4, !0);
439
+ if (i !== u)
440
+ throw new Error(`Unsupported import version: expected ${u}, got ${i}`);
441
+ const a = s.getUint32(8, !0);
442
+ if (a !== this.dimensions)
443
+ throw new Error(`Import dimension mismatch: expected ${this.dimensions}, got ${a}`);
444
+ const o = s.getUint32(12, !0), h = s.getUint32(16, !0), f = s.getUint32(20, !0);
445
+ if (this.keyToSlot.clear(), this.slotToKey.length = 0, this.memoryManager.reset(), o > 0) {
446
+ this.memoryManager.ensureCapacity(o);
447
+ let l = 0;
448
+ await t.readChunked(h, (y) => {
449
+ new Uint8Array(this.memoryManager.memory.buffer, this.memoryManager.dbOffset + l, y.byteLength).set(
450
+ y
451
+ ), l += y.byteLength;
452
+ }), this.memoryManager.setVectorCount(o);
453
+ }
454
+ if (f > 0) {
455
+ const l = await t.readExact(f), y = g(l);
456
+ for (let A = 0; A < y.length; A++)
457
+ this.keyToSlot.set(y[A], A), this.slotToKey[A] = y[A];
458
+ }
459
+ t.release();
460
+ }
386
461
  /**
387
462
  * Normalize a vector using WASM (if available) or JS fallback.
388
463
  */
389
- normalizeVector(A) {
464
+ normalizeVector(e) {
390
465
  if (this.wasmExports) {
391
- const e = this.memoryManager.queryOffset;
392
- new Float32Array(this.memoryManager.memory.buffer, e, A.length).set(A), this.wasmExports.normalize(e, A.length);
393
- const s = new Float32Array(this.memoryManager.memory.buffer, e, A.length);
394
- A.set(s);
466
+ const t = this.memoryManager.queryOffset;
467
+ new Float32Array(this.memoryManager.memory.buffer, t, e.length).set(e), this.wasmExports.normalize(t, e.length);
468
+ const r = new Float32Array(this.memoryManager.memory.buffer, t, e.length);
469
+ e.set(r);
395
470
  } else
396
- E(A);
471
+ S(e);
397
472
  }
398
473
  assertOpen() {
399
474
  if (this.closed)
400
475
  throw new Error("VectorDB instance has been closed");
401
476
  }
402
477
  }
478
+ class q {
479
+ reader;
480
+ buffer = new Uint8Array(0);
481
+ constructor(e) {
482
+ this.reader = e.getReader();
483
+ }
484
+ /** Read exactly `n` bytes, accumulating from stream chunks as needed. */
485
+ async readExact(e) {
486
+ if (e === 0) return new Uint8Array(0);
487
+ if (this.buffer.byteLength >= e) {
488
+ const i = this.buffer.subarray(0, e);
489
+ return this.buffer = this.buffer.subarray(e), i;
490
+ }
491
+ const t = [];
492
+ let r = this.buffer.byteLength;
493
+ for (r > 0 && (t.push(this.buffer), this.buffer = new Uint8Array(0)); r < e; ) {
494
+ const { done: i, value: a } = await this.reader.read();
495
+ if (i) throw new Error("Invalid import data: unexpected end of stream");
496
+ t.push(a), r += a.byteLength;
497
+ }
498
+ const s = new Uint8Array(r);
499
+ let n = 0;
500
+ for (const i of t)
501
+ s.set(i, n), n += i.byteLength;
502
+ return r > e ? (this.buffer = s.subarray(e), s.subarray(0, e)) : s;
503
+ }
504
+ /**
505
+ * Read `totalBytes` from the stream in chunks, calling `onChunk` for each.
506
+ * Avoids allocating a single large buffer for the full data.
507
+ */
508
+ async readChunked(e, t) {
509
+ let r = e;
510
+ if (this.buffer.byteLength > 0) {
511
+ const s = Math.min(this.buffer.byteLength, r);
512
+ t(this.buffer.subarray(0, s)), r -= s, this.buffer = this.buffer.subarray(s);
513
+ }
514
+ for (; r > 0; ) {
515
+ const { done: s, value: n } = await this.reader.read();
516
+ if (s) throw new Error("Invalid import data: unexpected end of stream");
517
+ n.byteLength <= r ? (t(n), r -= n.byteLength) : (t(n.subarray(0, r)), this.buffer = n.slice(r), r = 0);
518
+ }
519
+ }
520
+ /** Release the stream reader lock. */
521
+ release() {
522
+ this.reader.releaseLock();
523
+ }
524
+ }
403
525
  export {
404
- w as DB,
405
- O as InMemoryStorageProvider,
406
- C as OPFSStorageProvider,
407
- Q as VectorCapacityExceededError
526
+ M as DB,
527
+ v as InMemoryStorageProvider,
528
+ _ as OPFSStorageProvider,
529
+ k as VectorCapacityExceededError
408
530
  };
409
531
  //# sourceMappingURL=eigen-db.js.map