taladb 0.11.2 → 0.11.3
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.browser.mjs +78 -47
- package/dist/index.d.mts +13 -26
- package/dist/index.d.ts +13 -26
- package/dist/index.js +78 -47
- package/dist/index.mjs +78 -47
- package/dist/index.react-native.mjs +78 -47
- package/package.json +3 -3
package/dist/index.browser.mjs
CHANGED
|
@@ -838,7 +838,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
838
838
|
function nudgedPoller(collection, fetchJson, callback, onError) {
|
|
839
839
|
let active = true;
|
|
840
840
|
let lastJson = "";
|
|
841
|
-
let lastGeneration =
|
|
841
|
+
let lastGeneration = null;
|
|
842
842
|
let generationSupported = true;
|
|
843
843
|
let timer = null;
|
|
844
844
|
let running = false;
|
|
@@ -903,6 +903,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
903
903
|
await proxy.send("flush");
|
|
904
904
|
},
|
|
905
905
|
isPrimary: () => proxy.send("isPrimary"),
|
|
906
|
+
storageInfo: () => proxy.send("capabilities"),
|
|
906
907
|
close: async () => {
|
|
907
908
|
channel?.close();
|
|
908
909
|
try {
|
|
@@ -915,14 +916,16 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
915
916
|
listCollectionNames: async () => JSON.parse(await proxy.send("listCollections"))
|
|
916
917
|
};
|
|
917
918
|
if (migrations?.length) {
|
|
918
|
-
await
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
919
|
+
await navigator.locks.request(`taladb:migrations:${dbName}`, async () => {
|
|
920
|
+
await runMigrations(
|
|
921
|
+
handle,
|
|
922
|
+
async () => proxy.send("userVersion"),
|
|
923
|
+
async (v) => {
|
|
924
|
+
await proxy.send("setUserVersion", { version: v });
|
|
925
|
+
},
|
|
926
|
+
migrations
|
|
927
|
+
);
|
|
928
|
+
});
|
|
926
929
|
}
|
|
927
930
|
return handle;
|
|
928
931
|
}
|
|
@@ -1010,78 +1013,106 @@ async function createNativeDB(_dbName, webhook, migrations) {
|
|
|
1010
1013
|
);
|
|
1011
1014
|
}
|
|
1012
1015
|
const native = maybeNative;
|
|
1016
|
+
let nativeQueue = Promise.resolve();
|
|
1017
|
+
let queued = 0;
|
|
1018
|
+
let closed = false;
|
|
1019
|
+
const call = (op, ...args) => {
|
|
1020
|
+
if (queued >= 128) return Promise.reject(new Error("TalaDB native request queue is full"));
|
|
1021
|
+
queued++;
|
|
1022
|
+
const result = nativeQueue.then(async () => {
|
|
1023
|
+
if (closed) throw new Error("TalaDB database is closed");
|
|
1024
|
+
if (op === "close") {
|
|
1025
|
+
closed = true;
|
|
1026
|
+
native.close();
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
if (op === "findNearest" && native.findNearestAsync) {
|
|
1030
|
+
return native.findNearestAsync(...args);
|
|
1031
|
+
}
|
|
1032
|
+
if (native.callAsync) return native.callAsync(op, args);
|
|
1033
|
+
if (op === "find" && native.findAsync) {
|
|
1034
|
+
return native.findAsync(...args);
|
|
1035
|
+
}
|
|
1036
|
+
const method = native[op];
|
|
1037
|
+
if (!method) throw new Error(`${op} requires a newer @taladb/react-native binary; rebuild the native module`);
|
|
1038
|
+
return method(...args);
|
|
1039
|
+
});
|
|
1040
|
+
nativeQueue = result.catch(() => {
|
|
1041
|
+
}).finally(() => {
|
|
1042
|
+
queued--;
|
|
1043
|
+
});
|
|
1044
|
+
return result;
|
|
1045
|
+
};
|
|
1013
1046
|
function wrapCollection(name, opts) {
|
|
1014
1047
|
const wrapped = {
|
|
1015
|
-
insert: async (doc) =>
|
|
1016
|
-
insertMany: async (docs) =>
|
|
1017
|
-
find: async (filter) =>
|
|
1018
|
-
findOne: async (filter) =>
|
|
1019
|
-
updateOne: async (filter, update) =>
|
|
1020
|
-
updateMany: async (filter, update) =>
|
|
1021
|
-
deleteOne: async (filter) =>
|
|
1022
|
-
deleteMany: async (filter) =>
|
|
1023
|
-
count: async (filter) =>
|
|
1024
|
-
aggregate: async (pipeline) =>
|
|
1025
|
-
createIndex: async (field) =>
|
|
1026
|
-
dropIndex: async (field) =>
|
|
1027
|
-
createCompoundIndex: async (fields) =>
|
|
1028
|
-
dropCompoundIndex: async (fields) =>
|
|
1029
|
-
createFtsIndex: async (field) =>
|
|
1030
|
-
dropFtsIndex: async (field) =>
|
|
1048
|
+
insert: async (doc) => await call("insert", name, doc),
|
|
1049
|
+
insertMany: async (docs) => await call("insertMany", name, docs),
|
|
1050
|
+
find: async (filter) => await call("find", name, filter ?? {}),
|
|
1051
|
+
findOne: async (filter) => await call("findOne", name, filter ?? {}),
|
|
1052
|
+
updateOne: async (filter, update) => await call("updateOne", name, filter, update),
|
|
1053
|
+
updateMany: async (filter, update) => await call("updateMany", name, filter, update),
|
|
1054
|
+
deleteOne: async (filter) => await call("deleteOne", name, filter),
|
|
1055
|
+
deleteMany: async (filter) => await call("deleteMany", name, filter),
|
|
1056
|
+
count: async (filter) => await call("count", name, filter ?? {}),
|
|
1057
|
+
aggregate: async (pipeline) => await call("aggregate", name, pipeline),
|
|
1058
|
+
createIndex: async (field) => await call("createIndex", name, field),
|
|
1059
|
+
dropIndex: async (field) => await call("dropIndex", name, field),
|
|
1060
|
+
createCompoundIndex: async (fields) => await call("createCompoundIndex", name, fields),
|
|
1061
|
+
dropCompoundIndex: async (fields) => await call("dropCompoundIndex", name, fields),
|
|
1062
|
+
createFtsIndex: async (field) => await call("createFtsIndex", name, field),
|
|
1063
|
+
dropFtsIndex: async (field) => await call("dropFtsIndex", name, field),
|
|
1031
1064
|
createVectorIndex: async (field, options) => {
|
|
1032
1065
|
const opts2 = {};
|
|
1033
1066
|
if (options.metric) opts2.metric = options.metric;
|
|
1034
|
-
if (options.
|
|
1035
|
-
opts2.hnsw = { m: options.hnswM,
|
|
1067
|
+
if (options.indexType === "hnsw") {
|
|
1068
|
+
opts2.hnsw = { m: options.hnswM ?? 32, ef_construction: options.hnswEfConstruction ?? 200 };
|
|
1036
1069
|
}
|
|
1037
|
-
return
|
|
1070
|
+
return await call("createVectorIndex", name, field, options.dimensions, opts2);
|
|
1038
1071
|
},
|
|
1039
|
-
dropVectorIndex: async (field) =>
|
|
1040
|
-
upgradeVectorIndex: async (field) =>
|
|
1041
|
-
|
|
1042
|
-
// correctly-shaped empty result rather than `{}` cast to the interface.
|
|
1043
|
-
listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
|
|
1072
|
+
dropVectorIndex: async (field) => await call("dropVectorIndex", name, field),
|
|
1073
|
+
upgradeVectorIndex: async (field) => await call("upgradeVectorIndex", name, field),
|
|
1074
|
+
listIndexes: async () => call("listIndexes", name),
|
|
1044
1075
|
findNearest: async (field, vector, topK, filter) => {
|
|
1045
|
-
const raw =
|
|
1076
|
+
const raw = await call("findNearest", name, field, vector, topK, filter ?? null);
|
|
1046
1077
|
return raw;
|
|
1047
1078
|
},
|
|
1048
1079
|
searchText: async (field, query, topK, filter, options) => {
|
|
1049
|
-
if (!native.searchText) {
|
|
1080
|
+
if (!native.callAsync && !native.searchText) {
|
|
1050
1081
|
throw new Error("searchText requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1051
1082
|
}
|
|
1052
|
-
return
|
|
1083
|
+
return await call("searchText", name, field, query, topK, filter ?? null, options ?? null);
|
|
1053
1084
|
},
|
|
1054
1085
|
hybridSearch: async (text, vector, topK, filter, options) => {
|
|
1055
|
-
if (!native.hybridSearch) {
|
|
1086
|
+
if (!native.callAsync && !native.hybridSearch) {
|
|
1056
1087
|
throw new Error("hybridSearch requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1057
1088
|
}
|
|
1058
|
-
return
|
|
1089
|
+
return await call("hybridSearch", name, text.textField, text.text, vector.vectorField, vector.vector, topK, filter ?? null, options ?? null);
|
|
1059
1090
|
},
|
|
1060
|
-
subscribe: (filter, callback, onError) => makePoller(async () =>
|
|
1061
|
-
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () =>
|
|
1091
|
+
subscribe: (filter, callback, onError) => makePoller(async () => await call("find", name, filter ?? {}), callback, onError),
|
|
1092
|
+
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () => await call("aggregate", name, pipeline), callback, onError)
|
|
1062
1093
|
};
|
|
1063
1094
|
return decorateCollection(wrapped, name, opts, webhook);
|
|
1064
1095
|
}
|
|
1065
1096
|
const handle = {
|
|
1066
1097
|
collection: (name, opts) => wrapCollection(name, opts),
|
|
1067
|
-
compact: async () =>
|
|
1068
|
-
close: async () =>
|
|
1069
|
-
flush: native.flush ? async () => {
|
|
1070
|
-
|
|
1098
|
+
compact: async () => await call("compact"),
|
|
1099
|
+
close: async () => await call("close"),
|
|
1100
|
+
flush: native.callAsync || native.flush ? async () => {
|
|
1101
|
+
await call("flush");
|
|
1071
1102
|
} : void 0,
|
|
1072
1103
|
// One process owns the file — there is no other tab to defer to.
|
|
1073
1104
|
isPrimary: async () => true
|
|
1074
1105
|
};
|
|
1075
1106
|
if (migrations?.length) {
|
|
1076
|
-
if (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function") {
|
|
1107
|
+
if (!native.callAsync && (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function")) {
|
|
1077
1108
|
throw new Error(
|
|
1078
1109
|
"openDB({ migrations }) is not available on this @taladb/react-native binary yet (the JSI HostObject does not expose userVersion/setUserVersion). Update the native module."
|
|
1079
1110
|
);
|
|
1080
1111
|
}
|
|
1081
1112
|
await runMigrations(
|
|
1082
1113
|
handle,
|
|
1083
|
-
async () =>
|
|
1084
|
-
async (v) =>
|
|
1114
|
+
async () => call("userVersion"),
|
|
1115
|
+
async (v) => call("setUserVersion", v),
|
|
1085
1116
|
migrations
|
|
1086
1117
|
);
|
|
1087
1118
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -108,7 +108,7 @@ interface VectorIndexOptions {
|
|
|
108
108
|
* Requires the `vector-hnsw` feature to be compiled in.
|
|
109
109
|
*/
|
|
110
110
|
indexType?: 'flat' | 'hnsw';
|
|
111
|
-
/** HNSW connectivity parameter M
|
|
111
|
+
/** HNSW connectivity parameter M. This implementation supports only 32 (the default). */
|
|
112
112
|
hnswM?: number;
|
|
113
113
|
/** HNSW build-time quality parameter ef_construction (default 200). */
|
|
114
114
|
hnswEfConstruction?: number;
|
|
@@ -681,33 +681,20 @@ interface TalaDB {
|
|
|
681
681
|
*/
|
|
682
682
|
flush?(): Promise<void>;
|
|
683
683
|
/**
|
|
684
|
-
* Whether this tab
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
* **Browser only.** The first tab to open a database becomes the primary and
|
|
688
|
-
* owns the storage; later tabs run an in-memory copy and forward their writes
|
|
689
|
-
* to it over BroadcastChannel. Both the OPFS owner and — where OPFS is
|
|
690
|
-
* unavailable — the tab that publishes the IndexedDB snapshot report `true`.
|
|
691
|
-
*
|
|
692
|
-
* Use it for work that must not run in more than one tab at a time, or that
|
|
693
|
-
* depends on reading its own writes back immediately: a background queue
|
|
694
|
-
* drainer, a scheduled cleanup pass, an outbound sync loop. A secondary tab
|
|
695
|
-
* sees other tabs' writes up to ~500 ms late, and its own writes only once
|
|
696
|
-
* the primary has applied them.
|
|
697
|
-
*
|
|
698
|
-
* Primary status changes during a session — closing the owning tab promotes
|
|
699
|
-
* another — so re-check it rather than caching the answer.
|
|
700
|
-
*
|
|
701
|
-
* Always `true` on Node.js and React Native, where a single process owns the
|
|
702
|
-
* database. May be absent on older `@taladb/web` builds — treat absence as
|
|
703
|
-
* `true`.
|
|
704
|
-
*
|
|
705
|
-
* @example
|
|
706
|
-
* if (await db.isPrimary?.() ?? true) {
|
|
707
|
-
* await drainOutbox();
|
|
708
|
-
* }
|
|
684
|
+
* Whether this browser tab owns the database storage. All tabs execute reads
|
|
685
|
+
* and writes through that owner and await its result. Ownership can change
|
|
686
|
+
* after the owning tab closes. Node.js and React Native return true.
|
|
709
687
|
*/
|
|
710
688
|
isPrimary?(): Promise<boolean>;
|
|
689
|
+
/** Actual browser storage/durability capabilities, including fallback errors. */
|
|
690
|
+
storageInfo?(): Promise<{
|
|
691
|
+
storage: 'opfs' | 'indexeddb';
|
|
692
|
+
durableWrites: boolean;
|
|
693
|
+
maxSnapshotBytes: number | null;
|
|
694
|
+
storageError: string | null;
|
|
695
|
+
hnsw: boolean;
|
|
696
|
+
owner: boolean;
|
|
697
|
+
}>;
|
|
711
698
|
/**
|
|
712
699
|
* Change-webhook delivery counters, when the webhook is enabled. All zero
|
|
713
700
|
* (and `pending: 0`) when it is not.
|
package/dist/index.d.ts
CHANGED
|
@@ -108,7 +108,7 @@ interface VectorIndexOptions {
|
|
|
108
108
|
* Requires the `vector-hnsw` feature to be compiled in.
|
|
109
109
|
*/
|
|
110
110
|
indexType?: 'flat' | 'hnsw';
|
|
111
|
-
/** HNSW connectivity parameter M
|
|
111
|
+
/** HNSW connectivity parameter M. This implementation supports only 32 (the default). */
|
|
112
112
|
hnswM?: number;
|
|
113
113
|
/** HNSW build-time quality parameter ef_construction (default 200). */
|
|
114
114
|
hnswEfConstruction?: number;
|
|
@@ -681,33 +681,20 @@ interface TalaDB {
|
|
|
681
681
|
*/
|
|
682
682
|
flush?(): Promise<void>;
|
|
683
683
|
/**
|
|
684
|
-
* Whether this tab
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
* **Browser only.** The first tab to open a database becomes the primary and
|
|
688
|
-
* owns the storage; later tabs run an in-memory copy and forward their writes
|
|
689
|
-
* to it over BroadcastChannel. Both the OPFS owner and — where OPFS is
|
|
690
|
-
* unavailable — the tab that publishes the IndexedDB snapshot report `true`.
|
|
691
|
-
*
|
|
692
|
-
* Use it for work that must not run in more than one tab at a time, or that
|
|
693
|
-
* depends on reading its own writes back immediately: a background queue
|
|
694
|
-
* drainer, a scheduled cleanup pass, an outbound sync loop. A secondary tab
|
|
695
|
-
* sees other tabs' writes up to ~500 ms late, and its own writes only once
|
|
696
|
-
* the primary has applied them.
|
|
697
|
-
*
|
|
698
|
-
* Primary status changes during a session — closing the owning tab promotes
|
|
699
|
-
* another — so re-check it rather than caching the answer.
|
|
700
|
-
*
|
|
701
|
-
* Always `true` on Node.js and React Native, where a single process owns the
|
|
702
|
-
* database. May be absent on older `@taladb/web` builds — treat absence as
|
|
703
|
-
* `true`.
|
|
704
|
-
*
|
|
705
|
-
* @example
|
|
706
|
-
* if (await db.isPrimary?.() ?? true) {
|
|
707
|
-
* await drainOutbox();
|
|
708
|
-
* }
|
|
684
|
+
* Whether this browser tab owns the database storage. All tabs execute reads
|
|
685
|
+
* and writes through that owner and await its result. Ownership can change
|
|
686
|
+
* after the owning tab closes. Node.js and React Native return true.
|
|
709
687
|
*/
|
|
710
688
|
isPrimary?(): Promise<boolean>;
|
|
689
|
+
/** Actual browser storage/durability capabilities, including fallback errors. */
|
|
690
|
+
storageInfo?(): Promise<{
|
|
691
|
+
storage: 'opfs' | 'indexeddb';
|
|
692
|
+
durableWrites: boolean;
|
|
693
|
+
maxSnapshotBytes: number | null;
|
|
694
|
+
storageError: string | null;
|
|
695
|
+
hnsw: boolean;
|
|
696
|
+
owner: boolean;
|
|
697
|
+
}>;
|
|
711
698
|
/**
|
|
712
699
|
* Change-webhook delivery counters, when the webhook is enabled. All zero
|
|
713
700
|
* (and `pending: 0`) when it is not.
|
package/dist/index.js
CHANGED
|
@@ -912,7 +912,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
912
912
|
function nudgedPoller(collection, fetchJson, callback, onError) {
|
|
913
913
|
let active = true;
|
|
914
914
|
let lastJson = "";
|
|
915
|
-
let lastGeneration =
|
|
915
|
+
let lastGeneration = null;
|
|
916
916
|
let generationSupported = true;
|
|
917
917
|
let timer = null;
|
|
918
918
|
let running = false;
|
|
@@ -977,6 +977,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
977
977
|
await proxy.send("flush");
|
|
978
978
|
},
|
|
979
979
|
isPrimary: () => proxy.send("isPrimary"),
|
|
980
|
+
storageInfo: () => proxy.send("capabilities"),
|
|
980
981
|
close: async () => {
|
|
981
982
|
channel?.close();
|
|
982
983
|
try {
|
|
@@ -989,14 +990,16 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
989
990
|
listCollectionNames: async () => JSON.parse(await proxy.send("listCollections"))
|
|
990
991
|
};
|
|
991
992
|
if (migrations?.length) {
|
|
992
|
-
await
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
993
|
+
await navigator.locks.request(`taladb:migrations:${dbName}`, async () => {
|
|
994
|
+
await runMigrations(
|
|
995
|
+
handle,
|
|
996
|
+
async () => proxy.send("userVersion"),
|
|
997
|
+
async (v) => {
|
|
998
|
+
await proxy.send("setUserVersion", { version: v });
|
|
999
|
+
},
|
|
1000
|
+
migrations
|
|
1001
|
+
);
|
|
1002
|
+
});
|
|
1000
1003
|
}
|
|
1001
1004
|
return handle;
|
|
1002
1005
|
}
|
|
@@ -1084,78 +1087,106 @@ async function createNativeDB(_dbName, webhook, migrations) {
|
|
|
1084
1087
|
);
|
|
1085
1088
|
}
|
|
1086
1089
|
const native = maybeNative;
|
|
1090
|
+
let nativeQueue = Promise.resolve();
|
|
1091
|
+
let queued = 0;
|
|
1092
|
+
let closed = false;
|
|
1093
|
+
const call = (op, ...args) => {
|
|
1094
|
+
if (queued >= 128) return Promise.reject(new Error("TalaDB native request queue is full"));
|
|
1095
|
+
queued++;
|
|
1096
|
+
const result = nativeQueue.then(async () => {
|
|
1097
|
+
if (closed) throw new Error("TalaDB database is closed");
|
|
1098
|
+
if (op === "close") {
|
|
1099
|
+
closed = true;
|
|
1100
|
+
native.close();
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
if (op === "findNearest" && native.findNearestAsync) {
|
|
1104
|
+
return native.findNearestAsync(...args);
|
|
1105
|
+
}
|
|
1106
|
+
if (native.callAsync) return native.callAsync(op, args);
|
|
1107
|
+
if (op === "find" && native.findAsync) {
|
|
1108
|
+
return native.findAsync(...args);
|
|
1109
|
+
}
|
|
1110
|
+
const method = native[op];
|
|
1111
|
+
if (!method) throw new Error(`${op} requires a newer @taladb/react-native binary; rebuild the native module`);
|
|
1112
|
+
return method(...args);
|
|
1113
|
+
});
|
|
1114
|
+
nativeQueue = result.catch(() => {
|
|
1115
|
+
}).finally(() => {
|
|
1116
|
+
queued--;
|
|
1117
|
+
});
|
|
1118
|
+
return result;
|
|
1119
|
+
};
|
|
1087
1120
|
function wrapCollection(name, opts) {
|
|
1088
1121
|
const wrapped = {
|
|
1089
|
-
insert: async (doc) =>
|
|
1090
|
-
insertMany: async (docs) =>
|
|
1091
|
-
find: async (filter) =>
|
|
1092
|
-
findOne: async (filter) =>
|
|
1093
|
-
updateOne: async (filter, update) =>
|
|
1094
|
-
updateMany: async (filter, update) =>
|
|
1095
|
-
deleteOne: async (filter) =>
|
|
1096
|
-
deleteMany: async (filter) =>
|
|
1097
|
-
count: async (filter) =>
|
|
1098
|
-
aggregate: async (pipeline) =>
|
|
1099
|
-
createIndex: async (field) =>
|
|
1100
|
-
dropIndex: async (field) =>
|
|
1101
|
-
createCompoundIndex: async (fields) =>
|
|
1102
|
-
dropCompoundIndex: async (fields) =>
|
|
1103
|
-
createFtsIndex: async (field) =>
|
|
1104
|
-
dropFtsIndex: async (field) =>
|
|
1122
|
+
insert: async (doc) => await call("insert", name, doc),
|
|
1123
|
+
insertMany: async (docs) => await call("insertMany", name, docs),
|
|
1124
|
+
find: async (filter) => await call("find", name, filter ?? {}),
|
|
1125
|
+
findOne: async (filter) => await call("findOne", name, filter ?? {}),
|
|
1126
|
+
updateOne: async (filter, update) => await call("updateOne", name, filter, update),
|
|
1127
|
+
updateMany: async (filter, update) => await call("updateMany", name, filter, update),
|
|
1128
|
+
deleteOne: async (filter) => await call("deleteOne", name, filter),
|
|
1129
|
+
deleteMany: async (filter) => await call("deleteMany", name, filter),
|
|
1130
|
+
count: async (filter) => await call("count", name, filter ?? {}),
|
|
1131
|
+
aggregate: async (pipeline) => await call("aggregate", name, pipeline),
|
|
1132
|
+
createIndex: async (field) => await call("createIndex", name, field),
|
|
1133
|
+
dropIndex: async (field) => await call("dropIndex", name, field),
|
|
1134
|
+
createCompoundIndex: async (fields) => await call("createCompoundIndex", name, fields),
|
|
1135
|
+
dropCompoundIndex: async (fields) => await call("dropCompoundIndex", name, fields),
|
|
1136
|
+
createFtsIndex: async (field) => await call("createFtsIndex", name, field),
|
|
1137
|
+
dropFtsIndex: async (field) => await call("dropFtsIndex", name, field),
|
|
1105
1138
|
createVectorIndex: async (field, options) => {
|
|
1106
1139
|
const opts2 = {};
|
|
1107
1140
|
if (options.metric) opts2.metric = options.metric;
|
|
1108
|
-
if (options.
|
|
1109
|
-
opts2.hnsw = { m: options.hnswM,
|
|
1141
|
+
if (options.indexType === "hnsw") {
|
|
1142
|
+
opts2.hnsw = { m: options.hnswM ?? 32, ef_construction: options.hnswEfConstruction ?? 200 };
|
|
1110
1143
|
}
|
|
1111
|
-
return
|
|
1144
|
+
return await call("createVectorIndex", name, field, options.dimensions, opts2);
|
|
1112
1145
|
},
|
|
1113
|
-
dropVectorIndex: async (field) =>
|
|
1114
|
-
upgradeVectorIndex: async (field) =>
|
|
1115
|
-
|
|
1116
|
-
// correctly-shaped empty result rather than `{}` cast to the interface.
|
|
1117
|
-
listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
|
|
1146
|
+
dropVectorIndex: async (field) => await call("dropVectorIndex", name, field),
|
|
1147
|
+
upgradeVectorIndex: async (field) => await call("upgradeVectorIndex", name, field),
|
|
1148
|
+
listIndexes: async () => call("listIndexes", name),
|
|
1118
1149
|
findNearest: async (field, vector, topK, filter) => {
|
|
1119
|
-
const raw =
|
|
1150
|
+
const raw = await call("findNearest", name, field, vector, topK, filter ?? null);
|
|
1120
1151
|
return raw;
|
|
1121
1152
|
},
|
|
1122
1153
|
searchText: async (field, query, topK, filter, options) => {
|
|
1123
|
-
if (!native.searchText) {
|
|
1154
|
+
if (!native.callAsync && !native.searchText) {
|
|
1124
1155
|
throw new Error("searchText requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1125
1156
|
}
|
|
1126
|
-
return
|
|
1157
|
+
return await call("searchText", name, field, query, topK, filter ?? null, options ?? null);
|
|
1127
1158
|
},
|
|
1128
1159
|
hybridSearch: async (text, vector, topK, filter, options) => {
|
|
1129
|
-
if (!native.hybridSearch) {
|
|
1160
|
+
if (!native.callAsync && !native.hybridSearch) {
|
|
1130
1161
|
throw new Error("hybridSearch requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1131
1162
|
}
|
|
1132
|
-
return
|
|
1163
|
+
return await call("hybridSearch", name, text.textField, text.text, vector.vectorField, vector.vector, topK, filter ?? null, options ?? null);
|
|
1133
1164
|
},
|
|
1134
|
-
subscribe: (filter, callback, onError) => makePoller(async () =>
|
|
1135
|
-
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () =>
|
|
1165
|
+
subscribe: (filter, callback, onError) => makePoller(async () => await call("find", name, filter ?? {}), callback, onError),
|
|
1166
|
+
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () => await call("aggregate", name, pipeline), callback, onError)
|
|
1136
1167
|
};
|
|
1137
1168
|
return decorateCollection(wrapped, name, opts, webhook);
|
|
1138
1169
|
}
|
|
1139
1170
|
const handle = {
|
|
1140
1171
|
collection: (name, opts) => wrapCollection(name, opts),
|
|
1141
|
-
compact: async () =>
|
|
1142
|
-
close: async () =>
|
|
1143
|
-
flush: native.flush ? async () => {
|
|
1144
|
-
|
|
1172
|
+
compact: async () => await call("compact"),
|
|
1173
|
+
close: async () => await call("close"),
|
|
1174
|
+
flush: native.callAsync || native.flush ? async () => {
|
|
1175
|
+
await call("flush");
|
|
1145
1176
|
} : void 0,
|
|
1146
1177
|
// One process owns the file — there is no other tab to defer to.
|
|
1147
1178
|
isPrimary: async () => true
|
|
1148
1179
|
};
|
|
1149
1180
|
if (migrations?.length) {
|
|
1150
|
-
if (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function") {
|
|
1181
|
+
if (!native.callAsync && (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function")) {
|
|
1151
1182
|
throw new Error(
|
|
1152
1183
|
"openDB({ migrations }) is not available on this @taladb/react-native binary yet (the JSI HostObject does not expose userVersion/setUserVersion). Update the native module."
|
|
1153
1184
|
);
|
|
1154
1185
|
}
|
|
1155
1186
|
await runMigrations(
|
|
1156
1187
|
handle,
|
|
1157
|
-
async () =>
|
|
1158
|
-
async (v) =>
|
|
1188
|
+
async () => call("userVersion"),
|
|
1189
|
+
async (v) => call("setUserVersion", v),
|
|
1159
1190
|
migrations
|
|
1160
1191
|
);
|
|
1161
1192
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -867,7 +867,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
867
867
|
function nudgedPoller(collection, fetchJson, callback, onError) {
|
|
868
868
|
let active = true;
|
|
869
869
|
let lastJson = "";
|
|
870
|
-
let lastGeneration =
|
|
870
|
+
let lastGeneration = null;
|
|
871
871
|
let generationSupported = true;
|
|
872
872
|
let timer = null;
|
|
873
873
|
let running = false;
|
|
@@ -932,6 +932,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
932
932
|
await proxy.send("flush");
|
|
933
933
|
},
|
|
934
934
|
isPrimary: () => proxy.send("isPrimary"),
|
|
935
|
+
storageInfo: () => proxy.send("capabilities"),
|
|
935
936
|
close: async () => {
|
|
936
937
|
channel?.close();
|
|
937
938
|
try {
|
|
@@ -944,14 +945,16 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
944
945
|
listCollectionNames: async () => JSON.parse(await proxy.send("listCollections"))
|
|
945
946
|
};
|
|
946
947
|
if (migrations?.length) {
|
|
947
|
-
await
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
948
|
+
await navigator.locks.request(`taladb:migrations:${dbName}`, async () => {
|
|
949
|
+
await runMigrations(
|
|
950
|
+
handle,
|
|
951
|
+
async () => proxy.send("userVersion"),
|
|
952
|
+
async (v) => {
|
|
953
|
+
await proxy.send("setUserVersion", { version: v });
|
|
954
|
+
},
|
|
955
|
+
migrations
|
|
956
|
+
);
|
|
957
|
+
});
|
|
955
958
|
}
|
|
956
959
|
return handle;
|
|
957
960
|
}
|
|
@@ -1039,78 +1042,106 @@ async function createNativeDB(_dbName, webhook, migrations) {
|
|
|
1039
1042
|
);
|
|
1040
1043
|
}
|
|
1041
1044
|
const native = maybeNative;
|
|
1045
|
+
let nativeQueue = Promise.resolve();
|
|
1046
|
+
let queued = 0;
|
|
1047
|
+
let closed = false;
|
|
1048
|
+
const call = (op, ...args) => {
|
|
1049
|
+
if (queued >= 128) return Promise.reject(new Error("TalaDB native request queue is full"));
|
|
1050
|
+
queued++;
|
|
1051
|
+
const result = nativeQueue.then(async () => {
|
|
1052
|
+
if (closed) throw new Error("TalaDB database is closed");
|
|
1053
|
+
if (op === "close") {
|
|
1054
|
+
closed = true;
|
|
1055
|
+
native.close();
|
|
1056
|
+
return;
|
|
1057
|
+
}
|
|
1058
|
+
if (op === "findNearest" && native.findNearestAsync) {
|
|
1059
|
+
return native.findNearestAsync(...args);
|
|
1060
|
+
}
|
|
1061
|
+
if (native.callAsync) return native.callAsync(op, args);
|
|
1062
|
+
if (op === "find" && native.findAsync) {
|
|
1063
|
+
return native.findAsync(...args);
|
|
1064
|
+
}
|
|
1065
|
+
const method = native[op];
|
|
1066
|
+
if (!method) throw new Error(`${op} requires a newer @taladb/react-native binary; rebuild the native module`);
|
|
1067
|
+
return method(...args);
|
|
1068
|
+
});
|
|
1069
|
+
nativeQueue = result.catch(() => {
|
|
1070
|
+
}).finally(() => {
|
|
1071
|
+
queued--;
|
|
1072
|
+
});
|
|
1073
|
+
return result;
|
|
1074
|
+
};
|
|
1042
1075
|
function wrapCollection(name, opts) {
|
|
1043
1076
|
const wrapped = {
|
|
1044
|
-
insert: async (doc) =>
|
|
1045
|
-
insertMany: async (docs) =>
|
|
1046
|
-
find: async (filter) =>
|
|
1047
|
-
findOne: async (filter) =>
|
|
1048
|
-
updateOne: async (filter, update) =>
|
|
1049
|
-
updateMany: async (filter, update) =>
|
|
1050
|
-
deleteOne: async (filter) =>
|
|
1051
|
-
deleteMany: async (filter) =>
|
|
1052
|
-
count: async (filter) =>
|
|
1053
|
-
aggregate: async (pipeline) =>
|
|
1054
|
-
createIndex: async (field) =>
|
|
1055
|
-
dropIndex: async (field) =>
|
|
1056
|
-
createCompoundIndex: async (fields) =>
|
|
1057
|
-
dropCompoundIndex: async (fields) =>
|
|
1058
|
-
createFtsIndex: async (field) =>
|
|
1059
|
-
dropFtsIndex: async (field) =>
|
|
1077
|
+
insert: async (doc) => await call("insert", name, doc),
|
|
1078
|
+
insertMany: async (docs) => await call("insertMany", name, docs),
|
|
1079
|
+
find: async (filter) => await call("find", name, filter ?? {}),
|
|
1080
|
+
findOne: async (filter) => await call("findOne", name, filter ?? {}),
|
|
1081
|
+
updateOne: async (filter, update) => await call("updateOne", name, filter, update),
|
|
1082
|
+
updateMany: async (filter, update) => await call("updateMany", name, filter, update),
|
|
1083
|
+
deleteOne: async (filter) => await call("deleteOne", name, filter),
|
|
1084
|
+
deleteMany: async (filter) => await call("deleteMany", name, filter),
|
|
1085
|
+
count: async (filter) => await call("count", name, filter ?? {}),
|
|
1086
|
+
aggregate: async (pipeline) => await call("aggregate", name, pipeline),
|
|
1087
|
+
createIndex: async (field) => await call("createIndex", name, field),
|
|
1088
|
+
dropIndex: async (field) => await call("dropIndex", name, field),
|
|
1089
|
+
createCompoundIndex: async (fields) => await call("createCompoundIndex", name, fields),
|
|
1090
|
+
dropCompoundIndex: async (fields) => await call("dropCompoundIndex", name, fields),
|
|
1091
|
+
createFtsIndex: async (field) => await call("createFtsIndex", name, field),
|
|
1092
|
+
dropFtsIndex: async (field) => await call("dropFtsIndex", name, field),
|
|
1060
1093
|
createVectorIndex: async (field, options) => {
|
|
1061
1094
|
const opts2 = {};
|
|
1062
1095
|
if (options.metric) opts2.metric = options.metric;
|
|
1063
|
-
if (options.
|
|
1064
|
-
opts2.hnsw = { m: options.hnswM,
|
|
1096
|
+
if (options.indexType === "hnsw") {
|
|
1097
|
+
opts2.hnsw = { m: options.hnswM ?? 32, ef_construction: options.hnswEfConstruction ?? 200 };
|
|
1065
1098
|
}
|
|
1066
|
-
return
|
|
1099
|
+
return await call("createVectorIndex", name, field, options.dimensions, opts2);
|
|
1067
1100
|
},
|
|
1068
|
-
dropVectorIndex: async (field) =>
|
|
1069
|
-
upgradeVectorIndex: async (field) =>
|
|
1070
|
-
|
|
1071
|
-
// correctly-shaped empty result rather than `{}` cast to the interface.
|
|
1072
|
-
listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
|
|
1101
|
+
dropVectorIndex: async (field) => await call("dropVectorIndex", name, field),
|
|
1102
|
+
upgradeVectorIndex: async (field) => await call("upgradeVectorIndex", name, field),
|
|
1103
|
+
listIndexes: async () => call("listIndexes", name),
|
|
1073
1104
|
findNearest: async (field, vector, topK, filter) => {
|
|
1074
|
-
const raw =
|
|
1105
|
+
const raw = await call("findNearest", name, field, vector, topK, filter ?? null);
|
|
1075
1106
|
return raw;
|
|
1076
1107
|
},
|
|
1077
1108
|
searchText: async (field, query, topK, filter, options) => {
|
|
1078
|
-
if (!native.searchText) {
|
|
1109
|
+
if (!native.callAsync && !native.searchText) {
|
|
1079
1110
|
throw new Error("searchText requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1080
1111
|
}
|
|
1081
|
-
return
|
|
1112
|
+
return await call("searchText", name, field, query, topK, filter ?? null, options ?? null);
|
|
1082
1113
|
},
|
|
1083
1114
|
hybridSearch: async (text, vector, topK, filter, options) => {
|
|
1084
|
-
if (!native.hybridSearch) {
|
|
1115
|
+
if (!native.callAsync && !native.hybridSearch) {
|
|
1085
1116
|
throw new Error("hybridSearch requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1086
1117
|
}
|
|
1087
|
-
return
|
|
1118
|
+
return await call("hybridSearch", name, text.textField, text.text, vector.vectorField, vector.vector, topK, filter ?? null, options ?? null);
|
|
1088
1119
|
},
|
|
1089
|
-
subscribe: (filter, callback, onError) => makePoller(async () =>
|
|
1090
|
-
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () =>
|
|
1120
|
+
subscribe: (filter, callback, onError) => makePoller(async () => await call("find", name, filter ?? {}), callback, onError),
|
|
1121
|
+
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () => await call("aggregate", name, pipeline), callback, onError)
|
|
1091
1122
|
};
|
|
1092
1123
|
return decorateCollection(wrapped, name, opts, webhook);
|
|
1093
1124
|
}
|
|
1094
1125
|
const handle = {
|
|
1095
1126
|
collection: (name, opts) => wrapCollection(name, opts),
|
|
1096
|
-
compact: async () =>
|
|
1097
|
-
close: async () =>
|
|
1098
|
-
flush: native.flush ? async () => {
|
|
1099
|
-
|
|
1127
|
+
compact: async () => await call("compact"),
|
|
1128
|
+
close: async () => await call("close"),
|
|
1129
|
+
flush: native.callAsync || native.flush ? async () => {
|
|
1130
|
+
await call("flush");
|
|
1100
1131
|
} : void 0,
|
|
1101
1132
|
// One process owns the file — there is no other tab to defer to.
|
|
1102
1133
|
isPrimary: async () => true
|
|
1103
1134
|
};
|
|
1104
1135
|
if (migrations?.length) {
|
|
1105
|
-
if (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function") {
|
|
1136
|
+
if (!native.callAsync && (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function")) {
|
|
1106
1137
|
throw new Error(
|
|
1107
1138
|
"openDB({ migrations }) is not available on this @taladb/react-native binary yet (the JSI HostObject does not expose userVersion/setUserVersion). Update the native module."
|
|
1108
1139
|
);
|
|
1109
1140
|
}
|
|
1110
1141
|
await runMigrations(
|
|
1111
1142
|
handle,
|
|
1112
|
-
async () =>
|
|
1113
|
-
async (v) =>
|
|
1143
|
+
async () => call("userVersion"),
|
|
1144
|
+
async (v) => call("setUserVersion", v),
|
|
1114
1145
|
migrations
|
|
1115
1146
|
);
|
|
1116
1147
|
}
|
|
@@ -838,7 +838,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
838
838
|
function nudgedPoller(collection, fetchJson, callback, onError) {
|
|
839
839
|
let active = true;
|
|
840
840
|
let lastJson = "";
|
|
841
|
-
let lastGeneration =
|
|
841
|
+
let lastGeneration = null;
|
|
842
842
|
let generationSupported = true;
|
|
843
843
|
let timer = null;
|
|
844
844
|
let running = false;
|
|
@@ -903,6 +903,7 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
903
903
|
await proxy.send("flush");
|
|
904
904
|
},
|
|
905
905
|
isPrimary: () => proxy.send("isPrimary"),
|
|
906
|
+
storageInfo: () => proxy.send("capabilities"),
|
|
906
907
|
close: async () => {
|
|
907
908
|
channel?.close();
|
|
908
909
|
try {
|
|
@@ -915,14 +916,16 @@ async function createBrowserDB(dbName, webhook, config, passphrase, migrations)
|
|
|
915
916
|
listCollectionNames: async () => JSON.parse(await proxy.send("listCollections"))
|
|
916
917
|
};
|
|
917
918
|
if (migrations?.length) {
|
|
918
|
-
await
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
919
|
+
await navigator.locks.request(`taladb:migrations:${dbName}`, async () => {
|
|
920
|
+
await runMigrations(
|
|
921
|
+
handle,
|
|
922
|
+
async () => proxy.send("userVersion"),
|
|
923
|
+
async (v) => {
|
|
924
|
+
await proxy.send("setUserVersion", { version: v });
|
|
925
|
+
},
|
|
926
|
+
migrations
|
|
927
|
+
);
|
|
928
|
+
});
|
|
926
929
|
}
|
|
927
930
|
return handle;
|
|
928
931
|
}
|
|
@@ -1010,78 +1013,106 @@ async function createNativeDB(_dbName, webhook, migrations) {
|
|
|
1010
1013
|
);
|
|
1011
1014
|
}
|
|
1012
1015
|
const native = maybeNative;
|
|
1016
|
+
let nativeQueue = Promise.resolve();
|
|
1017
|
+
let queued = 0;
|
|
1018
|
+
let closed = false;
|
|
1019
|
+
const call = (op, ...args) => {
|
|
1020
|
+
if (queued >= 128) return Promise.reject(new Error("TalaDB native request queue is full"));
|
|
1021
|
+
queued++;
|
|
1022
|
+
const result = nativeQueue.then(async () => {
|
|
1023
|
+
if (closed) throw new Error("TalaDB database is closed");
|
|
1024
|
+
if (op === "close") {
|
|
1025
|
+
closed = true;
|
|
1026
|
+
native.close();
|
|
1027
|
+
return;
|
|
1028
|
+
}
|
|
1029
|
+
if (op === "findNearest" && native.findNearestAsync) {
|
|
1030
|
+
return native.findNearestAsync(...args);
|
|
1031
|
+
}
|
|
1032
|
+
if (native.callAsync) return native.callAsync(op, args);
|
|
1033
|
+
if (op === "find" && native.findAsync) {
|
|
1034
|
+
return native.findAsync(...args);
|
|
1035
|
+
}
|
|
1036
|
+
const method = native[op];
|
|
1037
|
+
if (!method) throw new Error(`${op} requires a newer @taladb/react-native binary; rebuild the native module`);
|
|
1038
|
+
return method(...args);
|
|
1039
|
+
});
|
|
1040
|
+
nativeQueue = result.catch(() => {
|
|
1041
|
+
}).finally(() => {
|
|
1042
|
+
queued--;
|
|
1043
|
+
});
|
|
1044
|
+
return result;
|
|
1045
|
+
};
|
|
1013
1046
|
function wrapCollection(name, opts) {
|
|
1014
1047
|
const wrapped = {
|
|
1015
|
-
insert: async (doc) =>
|
|
1016
|
-
insertMany: async (docs) =>
|
|
1017
|
-
find: async (filter) =>
|
|
1018
|
-
findOne: async (filter) =>
|
|
1019
|
-
updateOne: async (filter, update) =>
|
|
1020
|
-
updateMany: async (filter, update) =>
|
|
1021
|
-
deleteOne: async (filter) =>
|
|
1022
|
-
deleteMany: async (filter) =>
|
|
1023
|
-
count: async (filter) =>
|
|
1024
|
-
aggregate: async (pipeline) =>
|
|
1025
|
-
createIndex: async (field) =>
|
|
1026
|
-
dropIndex: async (field) =>
|
|
1027
|
-
createCompoundIndex: async (fields) =>
|
|
1028
|
-
dropCompoundIndex: async (fields) =>
|
|
1029
|
-
createFtsIndex: async (field) =>
|
|
1030
|
-
dropFtsIndex: async (field) =>
|
|
1048
|
+
insert: async (doc) => await call("insert", name, doc),
|
|
1049
|
+
insertMany: async (docs) => await call("insertMany", name, docs),
|
|
1050
|
+
find: async (filter) => await call("find", name, filter ?? {}),
|
|
1051
|
+
findOne: async (filter) => await call("findOne", name, filter ?? {}),
|
|
1052
|
+
updateOne: async (filter, update) => await call("updateOne", name, filter, update),
|
|
1053
|
+
updateMany: async (filter, update) => await call("updateMany", name, filter, update),
|
|
1054
|
+
deleteOne: async (filter) => await call("deleteOne", name, filter),
|
|
1055
|
+
deleteMany: async (filter) => await call("deleteMany", name, filter),
|
|
1056
|
+
count: async (filter) => await call("count", name, filter ?? {}),
|
|
1057
|
+
aggregate: async (pipeline) => await call("aggregate", name, pipeline),
|
|
1058
|
+
createIndex: async (field) => await call("createIndex", name, field),
|
|
1059
|
+
dropIndex: async (field) => await call("dropIndex", name, field),
|
|
1060
|
+
createCompoundIndex: async (fields) => await call("createCompoundIndex", name, fields),
|
|
1061
|
+
dropCompoundIndex: async (fields) => await call("dropCompoundIndex", name, fields),
|
|
1062
|
+
createFtsIndex: async (field) => await call("createFtsIndex", name, field),
|
|
1063
|
+
dropFtsIndex: async (field) => await call("dropFtsIndex", name, field),
|
|
1031
1064
|
createVectorIndex: async (field, options) => {
|
|
1032
1065
|
const opts2 = {};
|
|
1033
1066
|
if (options.metric) opts2.metric = options.metric;
|
|
1034
|
-
if (options.
|
|
1035
|
-
opts2.hnsw = { m: options.hnswM,
|
|
1067
|
+
if (options.indexType === "hnsw") {
|
|
1068
|
+
opts2.hnsw = { m: options.hnswM ?? 32, ef_construction: options.hnswEfConstruction ?? 200 };
|
|
1036
1069
|
}
|
|
1037
|
-
return
|
|
1070
|
+
return await call("createVectorIndex", name, field, options.dimensions, opts2);
|
|
1038
1071
|
},
|
|
1039
|
-
dropVectorIndex: async (field) =>
|
|
1040
|
-
upgradeVectorIndex: async (field) =>
|
|
1041
|
-
|
|
1042
|
-
// correctly-shaped empty result rather than `{}` cast to the interface.
|
|
1043
|
-
listIndexes: async () => ({ btree: [], fts: [], vector: [] }),
|
|
1072
|
+
dropVectorIndex: async (field) => await call("dropVectorIndex", name, field),
|
|
1073
|
+
upgradeVectorIndex: async (field) => await call("upgradeVectorIndex", name, field),
|
|
1074
|
+
listIndexes: async () => call("listIndexes", name),
|
|
1044
1075
|
findNearest: async (field, vector, topK, filter) => {
|
|
1045
|
-
const raw =
|
|
1076
|
+
const raw = await call("findNearest", name, field, vector, topK, filter ?? null);
|
|
1046
1077
|
return raw;
|
|
1047
1078
|
},
|
|
1048
1079
|
searchText: async (field, query, topK, filter, options) => {
|
|
1049
|
-
if (!native.searchText) {
|
|
1080
|
+
if (!native.callAsync && !native.searchText) {
|
|
1050
1081
|
throw new Error("searchText requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1051
1082
|
}
|
|
1052
|
-
return
|
|
1083
|
+
return await call("searchText", name, field, query, topK, filter ?? null, options ?? null);
|
|
1053
1084
|
},
|
|
1054
1085
|
hybridSearch: async (text, vector, topK, filter, options) => {
|
|
1055
|
-
if (!native.hybridSearch) {
|
|
1086
|
+
if (!native.callAsync && !native.hybridSearch) {
|
|
1056
1087
|
throw new Error("hybridSearch requires @taladb/react-native \u2265 0.10 \u2014 rebuild the native module");
|
|
1057
1088
|
}
|
|
1058
|
-
return
|
|
1089
|
+
return await call("hybridSearch", name, text.textField, text.text, vector.vectorField, vector.vector, topK, filter ?? null, options ?? null);
|
|
1059
1090
|
},
|
|
1060
|
-
subscribe: (filter, callback, onError) => makePoller(async () =>
|
|
1061
|
-
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () =>
|
|
1091
|
+
subscribe: (filter, callback, onError) => makePoller(async () => await call("find", name, filter ?? {}), callback, onError),
|
|
1092
|
+
subscribeAggregate: (pipeline, callback, onError) => makePoller(async () => await call("aggregate", name, pipeline), callback, onError)
|
|
1062
1093
|
};
|
|
1063
1094
|
return decorateCollection(wrapped, name, opts, webhook);
|
|
1064
1095
|
}
|
|
1065
1096
|
const handle = {
|
|
1066
1097
|
collection: (name, opts) => wrapCollection(name, opts),
|
|
1067
|
-
compact: async () =>
|
|
1068
|
-
close: async () =>
|
|
1069
|
-
flush: native.flush ? async () => {
|
|
1070
|
-
|
|
1098
|
+
compact: async () => await call("compact"),
|
|
1099
|
+
close: async () => await call("close"),
|
|
1100
|
+
flush: native.callAsync || native.flush ? async () => {
|
|
1101
|
+
await call("flush");
|
|
1071
1102
|
} : void 0,
|
|
1072
1103
|
// One process owns the file — there is no other tab to defer to.
|
|
1073
1104
|
isPrimary: async () => true
|
|
1074
1105
|
};
|
|
1075
1106
|
if (migrations?.length) {
|
|
1076
|
-
if (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function") {
|
|
1107
|
+
if (!native.callAsync && (typeof native.userVersion !== "function" || typeof native.setUserVersion !== "function")) {
|
|
1077
1108
|
throw new Error(
|
|
1078
1109
|
"openDB({ migrations }) is not available on this @taladb/react-native binary yet (the JSI HostObject does not expose userVersion/setUserVersion). Update the native module."
|
|
1079
1110
|
);
|
|
1080
1111
|
}
|
|
1081
1112
|
await runMigrations(
|
|
1082
1113
|
handle,
|
|
1083
|
-
async () =>
|
|
1084
|
-
async (v) =>
|
|
1114
|
+
async () => call("userVersion"),
|
|
1115
|
+
async (v) => call("setUserVersion", v),
|
|
1085
1116
|
migrations
|
|
1086
1117
|
);
|
|
1087
1118
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "taladb",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "The embedded vector database for on-device AI — documents, similarity search, and offline sync for browser, React Native, and Node.js",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -62,8 +62,8 @@
|
|
|
62
62
|
"vitest": "^3.2.0"
|
|
63
63
|
},
|
|
64
64
|
"peerDependencies": {
|
|
65
|
-
"@taladb/web": "0.11.
|
|
66
|
-
"@taladb/node": "0.11.
|
|
65
|
+
"@taladb/web": "0.11.3",
|
|
66
|
+
"@taladb/node": "0.11.3"
|
|
67
67
|
},
|
|
68
68
|
"peerDependenciesMeta": {
|
|
69
69
|
"@taladb/web": {
|