taladb 0.7.10 → 0.8.2

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.
@@ -84,6 +84,7 @@ var WorkerProxy = class {
84
84
  constructor(port) {
85
85
  this.pending = /* @__PURE__ */ new Map();
86
86
  this.nextId = 1;
87
+ this.dead = null;
87
88
  this.port = port;
88
89
  this.port.onmessage = (e) => {
89
90
  const { id, result, error } = e.data;
@@ -97,12 +98,23 @@ var WorkerProxy = class {
97
98
  this.port.start?.();
98
99
  }
99
100
  send(op, args = {}) {
101
+ if (this.dead) return Promise.reject(this.dead);
100
102
  return new Promise((resolve, reject) => {
101
103
  const id = this.nextId++;
102
104
  this.pending.set(id, { resolve, reject });
103
105
  this.port.postMessage({ id, op, ...args });
104
106
  });
105
107
  }
108
+ /**
109
+ * Reject every in-flight request and refuse new ones. Called when the
110
+ * worker errors or is terminated — without this, pending promises would
111
+ * hang forever (awaiting callers deadlock).
112
+ */
113
+ abort(reason) {
114
+ this.dead = reason;
115
+ for (const [, p] of this.pending) p.reject(reason);
116
+ this.pending.clear();
117
+ }
106
118
  };
107
119
  function makePoller(findFn, callback) {
108
120
  let active = true;
@@ -129,6 +141,9 @@ async function createBrowserDB(dbName, config) {
129
141
  const workerUrl = new URL("@taladb/web/worker/taladb.worker.js", import.meta.url);
130
142
  const worker = new Worker(workerUrl, { type: "module", name: "taladb" });
131
143
  const proxy = new WorkerProxy(worker);
144
+ worker.onerror = (e) => {
145
+ proxy.abort(new Error(`taladb worker error: ${e.message ?? "unknown"}`));
146
+ };
132
147
  const configJson = config !== void 0 ? JSON.stringify(config) : void 0;
133
148
  await proxy.send("init", { dbName, configJson });
134
149
  const nudgeCallbacks = /* @__PURE__ */ new Set();
@@ -216,7 +231,7 @@ async function createBrowserDB(dbName, config) {
216
231
  },
217
232
  subscribe: (filter, callback) => {
218
233
  let active = true;
219
- let lastJson = "[]";
234
+ let lastJson = "";
220
235
  let timer = null;
221
236
  const poll = async () => {
222
237
  if (!active) return;
@@ -256,8 +271,12 @@ async function createBrowserDB(dbName, config) {
256
271
  compact: () => proxy.send("compact"),
257
272
  close: async () => {
258
273
  channel?.close();
259
- await proxy.send("close");
260
- worker.terminate();
274
+ try {
275
+ await proxy.send("close");
276
+ } finally {
277
+ worker.terminate();
278
+ proxy.abort(new Error("taladb worker closed"));
279
+ }
261
280
  }
262
281
  };
263
282
  }
@@ -268,14 +287,14 @@ async function createNodeDB(dbName, config) {
268
287
  function wrapCollection(name, opts) {
269
288
  const col = db.collection(name);
270
289
  const wrapped = {
271
- insert: async (doc) => col.insert(doc),
272
- insertMany: async (docs) => col.insertMany(docs),
273
- find: async (filter) => col.find(filter ?? null),
290
+ insert: async (doc) => col.insertAsync ? col.insertAsync(doc) : col.insert(doc),
291
+ insertMany: async (docs) => col.insertManyAsync ? col.insertManyAsync(docs) : col.insertMany(docs),
292
+ find: async (filter) => col.findAsync ? col.findAsync(filter ?? null) : col.find(filter ?? null),
274
293
  findOne: async (filter) => col.findOne(filter) ?? null,
275
- updateOne: async (filter, update) => col.updateOne(filter, update),
276
- updateMany: async (filter, update) => col.updateMany(filter, update),
277
- deleteOne: async (filter) => col.deleteOne(filter),
278
- deleteMany: async (filter) => col.deleteMany(filter),
294
+ updateOne: async (filter, update) => col.updateOneAsync ? col.updateOneAsync(filter, update) : col.updateOne(filter, update),
295
+ updateMany: async (filter, update) => col.updateManyAsync ? col.updateManyAsync(filter, update) : col.updateMany(filter, update),
296
+ deleteOne: async (filter) => col.deleteOneAsync ? col.deleteOneAsync(filter) : col.deleteOne(filter),
297
+ deleteMany: async (filter) => col.deleteManyAsync ? col.deleteManyAsync(filter) : col.deleteMany(filter),
279
298
  count: async (filter) => col.count(filter ?? null),
280
299
  createIndex: async (field) => col.createIndex(field),
281
300
  dropIndex: async (field) => col.dropIndex(field),
@@ -299,8 +318,8 @@ async function createNodeDB(dbName, config) {
299
318
  return {
300
319
  collection: (name, opts) => wrapCollection(name, opts),
301
320
  compact: async () => db.compact(),
302
- close: async () => {
303
- }
321
+ // Releases the native file handle/lock (no-op on older .node binaries).
322
+ close: async () => db.close?.()
304
323
  };
305
324
  }
306
325
  async function createNativeDB(_dbName) {
@@ -336,7 +355,9 @@ async function createNativeDB(_dbName) {
336
355
  },
337
356
  dropVectorIndex: async (field) => native.dropVectorIndex(name, field),
338
357
  upgradeVectorIndex: async (field) => native.upgradeVectorIndex(name, field),
339
- listIndexes: async () => ({}),
358
+ // The JSI HostObject does not expose index introspection yet; return a
359
+ // correctly-shaped empty result rather than `{}` cast to the interface.
360
+ listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
340
361
  findNearest: async (field, vector, topK, filter) => {
341
362
  const raw = native.findNearest(name, field, vector, topK, filter ?? null);
342
363
  return raw;
package/dist/index.js CHANGED
@@ -42,6 +42,14 @@ var ENDPOINT_FIELDS = [
42
42
  "update_endpoint",
43
43
  "delete_endpoint"
44
44
  ];
45
+ var LOCALHOST_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
46
+ function isLocalhostUrl(url) {
47
+ try {
48
+ return LOCALHOST_HOSTS.has(new URL(url).hostname);
49
+ } catch {
50
+ return false;
51
+ }
52
+ }
45
53
  function validateConfig(config) {
46
54
  const sync = config.sync;
47
55
  if (!sync) return;
@@ -52,6 +60,11 @@ function validateConfig(config) {
52
60
  `TalaDB config: invalid endpoint URL "${url}" \u2014 must start with http:// or https://`
53
61
  );
54
62
  }
63
+ if (url?.startsWith("http://") && !isLocalhostUrl(url)) {
64
+ console.warn(
65
+ `[TalaDB] sync endpoint "${url}" uses plaintext HTTP \u2014 use HTTPS in production to prevent changeset interception`
66
+ );
67
+ }
55
68
  }
56
69
  }
57
70
  async function loadConfig(configPath) {
@@ -166,6 +179,7 @@ var WorkerProxy = class {
166
179
  constructor(port) {
167
180
  this.pending = /* @__PURE__ */ new Map();
168
181
  this.nextId = 1;
182
+ this.dead = null;
169
183
  this.port = port;
170
184
  this.port.onmessage = (e) => {
171
185
  const { id, result, error } = e.data;
@@ -179,12 +193,23 @@ var WorkerProxy = class {
179
193
  this.port.start?.();
180
194
  }
181
195
  send(op, args = {}) {
196
+ if (this.dead) return Promise.reject(this.dead);
182
197
  return new Promise((resolve, reject) => {
183
198
  const id = this.nextId++;
184
199
  this.pending.set(id, { resolve, reject });
185
200
  this.port.postMessage({ id, op, ...args });
186
201
  });
187
202
  }
203
+ /**
204
+ * Reject every in-flight request and refuse new ones. Called when the
205
+ * worker errors or is terminated — without this, pending promises would
206
+ * hang forever (awaiting callers deadlock).
207
+ */
208
+ abort(reason) {
209
+ this.dead = reason;
210
+ for (const [, p] of this.pending) p.reject(reason);
211
+ this.pending.clear();
212
+ }
188
213
  };
189
214
  function makePoller(findFn, callback) {
190
215
  let active = true;
@@ -211,6 +236,9 @@ async function createBrowserDB(dbName, config) {
211
236
  const workerUrl = new URL("@taladb/web/worker/taladb.worker.js", import_meta.url);
212
237
  const worker = new Worker(workerUrl, { type: "module", name: "taladb" });
213
238
  const proxy = new WorkerProxy(worker);
239
+ worker.onerror = (e) => {
240
+ proxy.abort(new Error(`taladb worker error: ${e.message ?? "unknown"}`));
241
+ };
214
242
  const configJson = config !== void 0 ? JSON.stringify(config) : void 0;
215
243
  await proxy.send("init", { dbName, configJson });
216
244
  const nudgeCallbacks = /* @__PURE__ */ new Set();
@@ -298,7 +326,7 @@ async function createBrowserDB(dbName, config) {
298
326
  },
299
327
  subscribe: (filter, callback) => {
300
328
  let active = true;
301
- let lastJson = "[]";
329
+ let lastJson = "";
302
330
  let timer = null;
303
331
  const poll = async () => {
304
332
  if (!active) return;
@@ -338,8 +366,12 @@ async function createBrowserDB(dbName, config) {
338
366
  compact: () => proxy.send("compact"),
339
367
  close: async () => {
340
368
  channel?.close();
341
- await proxy.send("close");
342
- worker.terminate();
369
+ try {
370
+ await proxy.send("close");
371
+ } finally {
372
+ worker.terminate();
373
+ proxy.abort(new Error("taladb worker closed"));
374
+ }
343
375
  }
344
376
  };
345
377
  }
@@ -350,14 +382,14 @@ async function createNodeDB(dbName, config) {
350
382
  function wrapCollection(name, opts) {
351
383
  const col = db.collection(name);
352
384
  const wrapped = {
353
- insert: async (doc) => col.insert(doc),
354
- insertMany: async (docs) => col.insertMany(docs),
355
- find: async (filter) => col.find(filter ?? null),
385
+ insert: async (doc) => col.insertAsync ? col.insertAsync(doc) : col.insert(doc),
386
+ insertMany: async (docs) => col.insertManyAsync ? col.insertManyAsync(docs) : col.insertMany(docs),
387
+ find: async (filter) => col.findAsync ? col.findAsync(filter ?? null) : col.find(filter ?? null),
356
388
  findOne: async (filter) => col.findOne(filter) ?? null,
357
- updateOne: async (filter, update) => col.updateOne(filter, update),
358
- updateMany: async (filter, update) => col.updateMany(filter, update),
359
- deleteOne: async (filter) => col.deleteOne(filter),
360
- deleteMany: async (filter) => col.deleteMany(filter),
389
+ updateOne: async (filter, update) => col.updateOneAsync ? col.updateOneAsync(filter, update) : col.updateOne(filter, update),
390
+ updateMany: async (filter, update) => col.updateManyAsync ? col.updateManyAsync(filter, update) : col.updateMany(filter, update),
391
+ deleteOne: async (filter) => col.deleteOneAsync ? col.deleteOneAsync(filter) : col.deleteOne(filter),
392
+ deleteMany: async (filter) => col.deleteManyAsync ? col.deleteManyAsync(filter) : col.deleteMany(filter),
361
393
  count: async (filter) => col.count(filter ?? null),
362
394
  createIndex: async (field) => col.createIndex(field),
363
395
  dropIndex: async (field) => col.dropIndex(field),
@@ -381,8 +413,8 @@ async function createNodeDB(dbName, config) {
381
413
  return {
382
414
  collection: (name, opts) => wrapCollection(name, opts),
383
415
  compact: async () => db.compact(),
384
- close: async () => {
385
- }
416
+ // Releases the native file handle/lock (no-op on older .node binaries).
417
+ close: async () => db.close?.()
386
418
  };
387
419
  }
388
420
  async function createNativeDB(_dbName) {
@@ -418,7 +450,9 @@ async function createNativeDB(_dbName) {
418
450
  },
419
451
  dropVectorIndex: async (field) => native.dropVectorIndex(name, field),
420
452
  upgradeVectorIndex: async (field) => native.upgradeVectorIndex(name, field),
421
- listIndexes: async () => ({}),
453
+ // The JSI HostObject does not expose index introspection yet; return a
454
+ // correctly-shaped empty result rather than `{}` cast to the interface.
455
+ listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
422
456
  findNearest: async (field, vector, topK, filter) => {
423
457
  const raw = native.findNearest(name, field, vector, topK, filter ?? null);
424
458
  return raw;
package/dist/index.mjs CHANGED
@@ -5,6 +5,14 @@ var ENDPOINT_FIELDS = [
5
5
  "update_endpoint",
6
6
  "delete_endpoint"
7
7
  ];
8
+ var LOCALHOST_HOSTS = /* @__PURE__ */ new Set(["localhost", "127.0.0.1", "[::1]", "::1"]);
9
+ function isLocalhostUrl(url) {
10
+ try {
11
+ return LOCALHOST_HOSTS.has(new URL(url).hostname);
12
+ } catch {
13
+ return false;
14
+ }
15
+ }
8
16
  function validateConfig(config) {
9
17
  const sync = config.sync;
10
18
  if (!sync) return;
@@ -15,6 +23,11 @@ function validateConfig(config) {
15
23
  `TalaDB config: invalid endpoint URL "${url}" \u2014 must start with http:// or https://`
16
24
  );
17
25
  }
26
+ if (url?.startsWith("http://") && !isLocalhostUrl(url)) {
27
+ console.warn(
28
+ `[TalaDB] sync endpoint "${url}" uses plaintext HTTP \u2014 use HTTPS in production to prevent changeset interception`
29
+ );
30
+ }
18
31
  }
19
32
  }
20
33
  async function loadConfig(configPath) {
@@ -128,6 +141,7 @@ var WorkerProxy = class {
128
141
  constructor(port) {
129
142
  this.pending = /* @__PURE__ */ new Map();
130
143
  this.nextId = 1;
144
+ this.dead = null;
131
145
  this.port = port;
132
146
  this.port.onmessage = (e) => {
133
147
  const { id, result, error } = e.data;
@@ -141,12 +155,23 @@ var WorkerProxy = class {
141
155
  this.port.start?.();
142
156
  }
143
157
  send(op, args = {}) {
158
+ if (this.dead) return Promise.reject(this.dead);
144
159
  return new Promise((resolve, reject) => {
145
160
  const id = this.nextId++;
146
161
  this.pending.set(id, { resolve, reject });
147
162
  this.port.postMessage({ id, op, ...args });
148
163
  });
149
164
  }
165
+ /**
166
+ * Reject every in-flight request and refuse new ones. Called when the
167
+ * worker errors or is terminated — without this, pending promises would
168
+ * hang forever (awaiting callers deadlock).
169
+ */
170
+ abort(reason) {
171
+ this.dead = reason;
172
+ for (const [, p] of this.pending) p.reject(reason);
173
+ this.pending.clear();
174
+ }
150
175
  };
151
176
  function makePoller(findFn, callback) {
152
177
  let active = true;
@@ -173,6 +198,9 @@ async function createBrowserDB(dbName, config) {
173
198
  const workerUrl = new URL("@taladb/web/worker/taladb.worker.js", import.meta.url);
174
199
  const worker = new Worker(workerUrl, { type: "module", name: "taladb" });
175
200
  const proxy = new WorkerProxy(worker);
201
+ worker.onerror = (e) => {
202
+ proxy.abort(new Error(`taladb worker error: ${e.message ?? "unknown"}`));
203
+ };
176
204
  const configJson = config !== void 0 ? JSON.stringify(config) : void 0;
177
205
  await proxy.send("init", { dbName, configJson });
178
206
  const nudgeCallbacks = /* @__PURE__ */ new Set();
@@ -260,7 +288,7 @@ async function createBrowserDB(dbName, config) {
260
288
  },
261
289
  subscribe: (filter, callback) => {
262
290
  let active = true;
263
- let lastJson = "[]";
291
+ let lastJson = "";
264
292
  let timer = null;
265
293
  const poll = async () => {
266
294
  if (!active) return;
@@ -300,8 +328,12 @@ async function createBrowserDB(dbName, config) {
300
328
  compact: () => proxy.send("compact"),
301
329
  close: async () => {
302
330
  channel?.close();
303
- await proxy.send("close");
304
- worker.terminate();
331
+ try {
332
+ await proxy.send("close");
333
+ } finally {
334
+ worker.terminate();
335
+ proxy.abort(new Error("taladb worker closed"));
336
+ }
305
337
  }
306
338
  };
307
339
  }
@@ -312,14 +344,14 @@ async function createNodeDB(dbName, config) {
312
344
  function wrapCollection(name, opts) {
313
345
  const col = db.collection(name);
314
346
  const wrapped = {
315
- insert: async (doc) => col.insert(doc),
316
- insertMany: async (docs) => col.insertMany(docs),
317
- find: async (filter) => col.find(filter ?? null),
347
+ insert: async (doc) => col.insertAsync ? col.insertAsync(doc) : col.insert(doc),
348
+ insertMany: async (docs) => col.insertManyAsync ? col.insertManyAsync(docs) : col.insertMany(docs),
349
+ find: async (filter) => col.findAsync ? col.findAsync(filter ?? null) : col.find(filter ?? null),
318
350
  findOne: async (filter) => col.findOne(filter) ?? null,
319
- updateOne: async (filter, update) => col.updateOne(filter, update),
320
- updateMany: async (filter, update) => col.updateMany(filter, update),
321
- deleteOne: async (filter) => col.deleteOne(filter),
322
- deleteMany: async (filter) => col.deleteMany(filter),
351
+ updateOne: async (filter, update) => col.updateOneAsync ? col.updateOneAsync(filter, update) : col.updateOne(filter, update),
352
+ updateMany: async (filter, update) => col.updateManyAsync ? col.updateManyAsync(filter, update) : col.updateMany(filter, update),
353
+ deleteOne: async (filter) => col.deleteOneAsync ? col.deleteOneAsync(filter) : col.deleteOne(filter),
354
+ deleteMany: async (filter) => col.deleteManyAsync ? col.deleteManyAsync(filter) : col.deleteMany(filter),
323
355
  count: async (filter) => col.count(filter ?? null),
324
356
  createIndex: async (field) => col.createIndex(field),
325
357
  dropIndex: async (field) => col.dropIndex(field),
@@ -343,8 +375,8 @@ async function createNodeDB(dbName, config) {
343
375
  return {
344
376
  collection: (name, opts) => wrapCollection(name, opts),
345
377
  compact: async () => db.compact(),
346
- close: async () => {
347
- }
378
+ // Releases the native file handle/lock (no-op on older .node binaries).
379
+ close: async () => db.close?.()
348
380
  };
349
381
  }
350
382
  async function createNativeDB(_dbName) {
@@ -380,7 +412,9 @@ async function createNativeDB(_dbName) {
380
412
  },
381
413
  dropVectorIndex: async (field) => native.dropVectorIndex(name, field),
382
414
  upgradeVectorIndex: async (field) => native.upgradeVectorIndex(name, field),
383
- listIndexes: async () => ({}),
415
+ // The JSI HostObject does not expose index introspection yet; return a
416
+ // correctly-shaped empty result rather than `{}` cast to the interface.
417
+ listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
384
418
  findNearest: async (field, vector, topK, filter) => {
385
419
  const raw = native.findNearest(name, field, vector, topK, filter ?? null);
386
420
  return raw;
@@ -84,6 +84,7 @@ var WorkerProxy = class {
84
84
  constructor(port) {
85
85
  this.pending = /* @__PURE__ */ new Map();
86
86
  this.nextId = 1;
87
+ this.dead = null;
87
88
  this.port = port;
88
89
  this.port.onmessage = (e) => {
89
90
  const { id, result, error } = e.data;
@@ -97,12 +98,23 @@ var WorkerProxy = class {
97
98
  this.port.start?.();
98
99
  }
99
100
  send(op, args = {}) {
101
+ if (this.dead) return Promise.reject(this.dead);
100
102
  return new Promise((resolve, reject) => {
101
103
  const id = this.nextId++;
102
104
  this.pending.set(id, { resolve, reject });
103
105
  this.port.postMessage({ id, op, ...args });
104
106
  });
105
107
  }
108
+ /**
109
+ * Reject every in-flight request and refuse new ones. Called when the
110
+ * worker errors or is terminated — without this, pending promises would
111
+ * hang forever (awaiting callers deadlock).
112
+ */
113
+ abort(reason) {
114
+ this.dead = reason;
115
+ for (const [, p] of this.pending) p.reject(reason);
116
+ this.pending.clear();
117
+ }
106
118
  };
107
119
  function makePoller(findFn, callback) {
108
120
  let active = true;
@@ -129,6 +141,9 @@ async function createBrowserDB(dbName, config) {
129
141
  const workerUrl = new URL("@taladb/web/worker/taladb.worker.js", "react-native://unreachable");
130
142
  const worker = new Worker(workerUrl, { type: "module", name: "taladb" });
131
143
  const proxy = new WorkerProxy(worker);
144
+ worker.onerror = (e) => {
145
+ proxy.abort(new Error(`taladb worker error: ${e.message ?? "unknown"}`));
146
+ };
132
147
  const configJson = config !== void 0 ? JSON.stringify(config) : void 0;
133
148
  await proxy.send("init", { dbName, configJson });
134
149
  const nudgeCallbacks = /* @__PURE__ */ new Set();
@@ -216,7 +231,7 @@ async function createBrowserDB(dbName, config) {
216
231
  },
217
232
  subscribe: (filter, callback) => {
218
233
  let active = true;
219
- let lastJson = "[]";
234
+ let lastJson = "";
220
235
  let timer = null;
221
236
  const poll = async () => {
222
237
  if (!active) return;
@@ -256,8 +271,12 @@ async function createBrowserDB(dbName, config) {
256
271
  compact: () => proxy.send("compact"),
257
272
  close: async () => {
258
273
  channel?.close();
259
- await proxy.send("close");
260
- worker.terminate();
274
+ try {
275
+ await proxy.send("close");
276
+ } finally {
277
+ worker.terminate();
278
+ proxy.abort(new Error("taladb worker closed"));
279
+ }
261
280
  }
262
281
  };
263
282
  }
@@ -268,14 +287,14 @@ async function createNodeDB(dbName, config) {
268
287
  function wrapCollection(name, opts) {
269
288
  const col = db.collection(name);
270
289
  const wrapped = {
271
- insert: async (doc) => col.insert(doc),
272
- insertMany: async (docs) => col.insertMany(docs),
273
- find: async (filter) => col.find(filter ?? null),
290
+ insert: async (doc) => col.insertAsync ? col.insertAsync(doc) : col.insert(doc),
291
+ insertMany: async (docs) => col.insertManyAsync ? col.insertManyAsync(docs) : col.insertMany(docs),
292
+ find: async (filter) => col.findAsync ? col.findAsync(filter ?? null) : col.find(filter ?? null),
274
293
  findOne: async (filter) => col.findOne(filter) ?? null,
275
- updateOne: async (filter, update) => col.updateOne(filter, update),
276
- updateMany: async (filter, update) => col.updateMany(filter, update),
277
- deleteOne: async (filter) => col.deleteOne(filter),
278
- deleteMany: async (filter) => col.deleteMany(filter),
294
+ updateOne: async (filter, update) => col.updateOneAsync ? col.updateOneAsync(filter, update) : col.updateOne(filter, update),
295
+ updateMany: async (filter, update) => col.updateManyAsync ? col.updateManyAsync(filter, update) : col.updateMany(filter, update),
296
+ deleteOne: async (filter) => col.deleteOneAsync ? col.deleteOneAsync(filter) : col.deleteOne(filter),
297
+ deleteMany: async (filter) => col.deleteManyAsync ? col.deleteManyAsync(filter) : col.deleteMany(filter),
279
298
  count: async (filter) => col.count(filter ?? null),
280
299
  createIndex: async (field) => col.createIndex(field),
281
300
  dropIndex: async (field) => col.dropIndex(field),
@@ -299,8 +318,8 @@ async function createNodeDB(dbName, config) {
299
318
  return {
300
319
  collection: (name, opts) => wrapCollection(name, opts),
301
320
  compact: async () => db.compact(),
302
- close: async () => {
303
- }
321
+ // Releases the native file handle/lock (no-op on older .node binaries).
322
+ close: async () => db.close?.()
304
323
  };
305
324
  }
306
325
  async function createNativeDB(_dbName) {
@@ -336,7 +355,9 @@ async function createNativeDB(_dbName) {
336
355
  },
337
356
  dropVectorIndex: async (field) => native.dropVectorIndex(name, field),
338
357
  upgradeVectorIndex: async (field) => native.upgradeVectorIndex(name, field),
339
- listIndexes: async () => ({}),
358
+ // The JSI HostObject does not expose index introspection yet; return a
359
+ // correctly-shaped empty result rather than `{}` cast to the interface.
360
+ listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
340
361
  findNearest: async (field, vector, topK, filter) => {
341
362
  const raw = native.findNearest(name, field, vector, topK, filter ?? null);
342
363
  return raw;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "taladb",
3
- "version": "0.7.10",
3
+ "version": "0.8.2",
4
4
  "description": "Local-first document and vector database for React, React Native, and Node.js",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",