@mastra/libsql 1.0.0-beta.1 → 1.0.0-beta.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.
- package/CHANGELOG.md +9 -0
- package/README.md +3 -0
- package/dist/index.cjs +190 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +190 -17
- package/dist/index.js.map +1 -1
- package/dist/vector/index.d.ts +4 -2
- package/dist/vector/index.d.ts.map +1 -1
- package/dist/vector/sql-builder.d.ts.map +1 -1
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @mastra/libsql
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Add new deleteVectors, updateVector by filter ([#10408](https://github.com/mastra-ai/mastra/pull/10408))
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`21a15de`](https://github.com/mastra-ai/mastra/commit/21a15de369fe82aac26bb642ed7be73505475e8b), [`feb7ee4`](https://github.com/mastra-ai/mastra/commit/feb7ee4d09a75edb46c6669a3beaceec78811747), [`b0e2ea5`](https://github.com/mastra-ai/mastra/commit/b0e2ea5b52c40fae438b9e2f7baee6f0f89c5442), [`c456e01`](https://github.com/mastra-ai/mastra/commit/c456e0149e3c176afcefdbd9bb1d2c5917723725), [`ab035c2`](https://github.com/mastra-ai/mastra/commit/ab035c2ef6d8cc7bb25f06f1a38508bd9e6f126b), [`1a46a56`](https://github.com/mastra-ai/mastra/commit/1a46a566f45a3fcbadc1cf36bf86d351f264bfa3), [`3cf540b`](https://github.com/mastra-ai/mastra/commit/3cf540b9fbfea8f4fc8d3a2319a4e6c0b0cbfd52), [`1c6ce51`](https://github.com/mastra-ai/mastra/commit/1c6ce51f875915ab57fd36873623013699a2a65d), [`898a972`](https://github.com/mastra-ai/mastra/commit/898a9727d286c2510d6b702dfd367e6aaf5c6b0f), [`a97003a`](https://github.com/mastra-ai/mastra/commit/a97003aa1cf2f4022a41912324a1e77263b326b8), [`ccc141e`](https://github.com/mastra-ai/mastra/commit/ccc141ed27da0abc3a3fc28e9e5128152e8e37f4), [`fe3b897`](https://github.com/mastra-ai/mastra/commit/fe3b897c2ccbcd2b10e81b099438c7337feddf89), [`00123ba`](https://github.com/mastra-ai/mastra/commit/00123ba96dc9e5cd0b110420ebdba56d8f237b25), [`29c4309`](https://github.com/mastra-ai/mastra/commit/29c4309f818b24304c041bcb4a8f19b5f13f6b62), [`16785ce`](https://github.com/mastra-ai/mastra/commit/16785ced928f6f22638f4488cf8a125d99211799), [`de8239b`](https://github.com/mastra-ai/mastra/commit/de8239bdcb1d8c0cfa06da21f1569912a66bbc8a), [`b5e6cd7`](https://github.com/mastra-ai/mastra/commit/b5e6cd77fc8c8e64e0494c1d06cee3d84e795d1e), [`3759cb0`](https://github.com/mastra-ai/mastra/commit/3759cb064935b5f74c65ac2f52a1145f7352899d), [`651e772`](https://github.com/mastra-ai/mastra/commit/651e772eb1475fb13e126d3fcc01751297a88214), [`b61b93f`](https://github.com/mastra-ai/mastra/commit/b61b93f9e058b11dd2eec169853175d31dbdd567), [`bae33d9`](https://github.com/mastra-ai/mastra/commit/bae33d91a63fbb64d1e80519e1fc1acaed1e9013), [`c0b731f`](https://github.com/mastra-ai/mastra/commit/c0b731fb27d712dc8582e846df5c0332a6a0c5ba), [`43ca8f2`](https://github.com/mastra-ai/mastra/commit/43ca8f2c7334851cc7b4d3d2f037d8784bfbdd5f), [`2ca67cc`](https://github.com/mastra-ai/mastra/commit/2ca67cc3bb1f6a617353fdcab197d9efebe60d6f), [`9e67002`](https://github.com/mastra-ai/mastra/commit/9e67002b52c9be19936c420a489dbee9c5fd6a78), [`35edc49`](https://github.com/mastra-ai/mastra/commit/35edc49ac0556db609189641d6341e76771b81fc)]:
|
|
10
|
+
- @mastra/core@1.0.0-beta.5
|
|
11
|
+
|
|
3
12
|
## 1.0.0-beta.1
|
|
4
13
|
|
|
5
14
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -131,6 +131,9 @@ Example filter:
|
|
|
131
131
|
- `createIndex({indexName, dimension, metric?, indexConfig?, defineIndex?})`: Create a new table with vector support
|
|
132
132
|
- `upsert({indexName, vectors, metadata?, ids?})`: Add or update vectors
|
|
133
133
|
- `query({indexName, queryVector, topK?, filter?, includeVector?, minScore?})`: Search for similar vectors
|
|
134
|
+
- `updateVector({ indexName, id?, filter?, update })`: Update a single vector by ID or metadata filter
|
|
135
|
+
- `deleteVector({ indexName, id })`: Delete a single vector by ID
|
|
136
|
+
- `deleteVectors({ indexName, ids?, filter? })`: Delete multiple vectors by IDs or metadata filter
|
|
134
137
|
- `defineIndex({indexName, metric?, indexConfig?})`: Define an index
|
|
135
138
|
- `listIndexes()`: List all vector-enabled tables
|
|
136
139
|
- `describeIndex(indexName)`: Get table statistics
|
package/dist/index.cjs
CHANGED
|
@@ -92,12 +92,20 @@ var createBasicOperator = (symbol) => {
|
|
|
92
92
|
};
|
|
93
93
|
};
|
|
94
94
|
var createNumericOperator = (symbol) => {
|
|
95
|
-
return (key) => {
|
|
95
|
+
return (key, value) => {
|
|
96
96
|
const jsonPath = getJsonPath(key);
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
97
|
+
const isNumeric = typeof value === "number" || typeof value === "string" && !isNaN(Number(value)) && value.trim() !== "";
|
|
98
|
+
if (isNumeric) {
|
|
99
|
+
return {
|
|
100
|
+
sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
|
|
101
|
+
needsValue: true
|
|
102
|
+
};
|
|
103
|
+
} else {
|
|
104
|
+
return {
|
|
105
|
+
sql: `CAST(json_extract(metadata, ${jsonPath}) AS TEXT) ${symbol} ?`,
|
|
106
|
+
needsValue: true
|
|
107
|
+
};
|
|
108
|
+
}
|
|
101
109
|
};
|
|
102
110
|
};
|
|
103
111
|
var validateJsonArray = (key) => {
|
|
@@ -826,8 +834,27 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
826
834
|
updateVector(args) {
|
|
827
835
|
return this.executeWriteOperationWithRetry(() => this.doUpdateVector(args));
|
|
828
836
|
}
|
|
829
|
-
async doUpdateVector(
|
|
837
|
+
async doUpdateVector(params) {
|
|
838
|
+
const { indexName, update } = params;
|
|
830
839
|
const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
|
|
840
|
+
if ("id" in params && params.id && "filter" in params && params.filter) {
|
|
841
|
+
throw new error.MastraError({
|
|
842
|
+
id: "LIBSQL_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE_PARAMS",
|
|
843
|
+
domain: error.ErrorDomain.STORAGE,
|
|
844
|
+
category: error.ErrorCategory.USER,
|
|
845
|
+
details: { indexName },
|
|
846
|
+
text: "id and filter are mutually exclusive - provide only one"
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
if (!update.vector && !update.metadata) {
|
|
850
|
+
throw new error.MastraError({
|
|
851
|
+
id: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
852
|
+
domain: error.ErrorDomain.STORAGE,
|
|
853
|
+
category: error.ErrorCategory.USER,
|
|
854
|
+
details: { indexName },
|
|
855
|
+
text: "No updates provided"
|
|
856
|
+
});
|
|
857
|
+
}
|
|
831
858
|
const updates = [];
|
|
832
859
|
const args = [];
|
|
833
860
|
if (update.vector) {
|
|
@@ -839,32 +866,81 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
839
866
|
args.push(JSON.stringify(update.metadata));
|
|
840
867
|
}
|
|
841
868
|
if (updates.length === 0) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
let whereClause;
|
|
872
|
+
let whereValues;
|
|
873
|
+
if ("id" in params && params.id) {
|
|
874
|
+
whereClause = "vector_id = ?";
|
|
875
|
+
whereValues = [params.id];
|
|
876
|
+
} else if ("filter" in params && params.filter) {
|
|
877
|
+
const filter = params.filter;
|
|
878
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
879
|
+
throw new error.MastraError({
|
|
880
|
+
id: "LIBSQL_VECTOR_UPDATE_EMPTY_FILTER",
|
|
881
|
+
domain: error.ErrorDomain.STORAGE,
|
|
882
|
+
category: error.ErrorCategory.USER,
|
|
883
|
+
details: { indexName },
|
|
884
|
+
text: "Cannot update with empty filter"
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
const translatedFilter = this.transformFilter(filter);
|
|
888
|
+
const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
889
|
+
if (!filterSql || filterSql.trim() === "") {
|
|
890
|
+
throw new error.MastraError({
|
|
891
|
+
id: "LIBSQL_VECTOR_UPDATE_INVALID_FILTER",
|
|
892
|
+
domain: error.ErrorDomain.STORAGE,
|
|
893
|
+
category: error.ErrorCategory.USER,
|
|
894
|
+
details: { indexName },
|
|
895
|
+
text: "Filter produced empty WHERE clause"
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
|
|
899
|
+
const matchAllPatterns = ["true", "1 = 1", "1=1"];
|
|
900
|
+
if (matchAllPatterns.includes(normalizedCondition)) {
|
|
901
|
+
throw new error.MastraError({
|
|
902
|
+
id: "LIBSQL_VECTOR_UPDATE_MATCH_ALL_FILTER",
|
|
903
|
+
domain: error.ErrorDomain.STORAGE,
|
|
904
|
+
category: error.ErrorCategory.USER,
|
|
905
|
+
details: { indexName, filterSql: normalizedCondition },
|
|
906
|
+
text: "Filter matches all vectors. Provide a specific filter to update targeted vectors."
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
whereClause = filterSql.replace(/^WHERE\s+/i, "");
|
|
910
|
+
whereValues = filterValues;
|
|
911
|
+
} else {
|
|
842
912
|
throw new error.MastraError({
|
|
843
|
-
id: "
|
|
913
|
+
id: "LIBSQL_VECTOR_UPDATE_MISSING_PARAMS",
|
|
844
914
|
domain: error.ErrorDomain.STORAGE,
|
|
845
915
|
category: error.ErrorCategory.USER,
|
|
846
|
-
details: { indexName
|
|
847
|
-
text: "
|
|
916
|
+
details: { indexName },
|
|
917
|
+
text: "Either id or filter must be provided"
|
|
848
918
|
});
|
|
849
919
|
}
|
|
850
|
-
args.push(id);
|
|
851
920
|
const query = `
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
921
|
+
UPDATE ${parsedIndexName}
|
|
922
|
+
SET ${updates.join(", ")}
|
|
923
|
+
WHERE ${whereClause};
|
|
924
|
+
`;
|
|
856
925
|
try {
|
|
857
926
|
await this.turso.execute({
|
|
858
927
|
sql: query,
|
|
859
|
-
args
|
|
928
|
+
args: [...args, ...whereValues]
|
|
860
929
|
});
|
|
861
930
|
} catch (error$1) {
|
|
931
|
+
const errorDetails = { indexName };
|
|
932
|
+
if ("id" in params && params.id) {
|
|
933
|
+
errorDetails.id = params.id;
|
|
934
|
+
}
|
|
935
|
+
if ("filter" in params && params.filter) {
|
|
936
|
+
errorDetails.filter = JSON.stringify(params.filter);
|
|
937
|
+
}
|
|
862
938
|
throw new error.MastraError(
|
|
863
939
|
{
|
|
864
940
|
id: "LIBSQL_VECTOR_UPDATE_VECTOR_FAILED",
|
|
865
941
|
domain: error.ErrorDomain.STORAGE,
|
|
866
942
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
867
|
-
details:
|
|
943
|
+
details: errorDetails
|
|
868
944
|
},
|
|
869
945
|
error$1
|
|
870
946
|
);
|
|
@@ -886,7 +962,10 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
886
962
|
id: "LIBSQL_VECTOR_DELETE_VECTOR_FAILED",
|
|
887
963
|
domain: error.ErrorDomain.STORAGE,
|
|
888
964
|
category: error.ErrorCategory.THIRD_PARTY,
|
|
889
|
-
details: {
|
|
965
|
+
details: {
|
|
966
|
+
indexName: args.indexName,
|
|
967
|
+
...args.id && { id: args.id }
|
|
968
|
+
}
|
|
890
969
|
},
|
|
891
970
|
error$1
|
|
892
971
|
);
|
|
@@ -899,6 +978,100 @@ var LibSQLVector = class extends vector.MastraVector {
|
|
|
899
978
|
args: [id]
|
|
900
979
|
});
|
|
901
980
|
}
|
|
981
|
+
deleteVectors(args) {
|
|
982
|
+
return this.executeWriteOperationWithRetry(() => this.doDeleteVectors(args));
|
|
983
|
+
}
|
|
984
|
+
async doDeleteVectors({ indexName, filter, ids }) {
|
|
985
|
+
const parsedIndexName = utils.parseSqlIdentifier(indexName, "index name");
|
|
986
|
+
if (!filter && !ids) {
|
|
987
|
+
throw new error.MastraError({
|
|
988
|
+
id: "LIBSQL_VECTOR_DELETE_MISSING_PARAMS",
|
|
989
|
+
domain: error.ErrorDomain.STORAGE,
|
|
990
|
+
category: error.ErrorCategory.USER,
|
|
991
|
+
details: { indexName },
|
|
992
|
+
text: "Either filter or ids must be provided"
|
|
993
|
+
});
|
|
994
|
+
}
|
|
995
|
+
if (filter && ids) {
|
|
996
|
+
throw new error.MastraError({
|
|
997
|
+
id: "LIBSQL_VECTOR_DELETE_CONFLICTING_PARAMS",
|
|
998
|
+
domain: error.ErrorDomain.STORAGE,
|
|
999
|
+
category: error.ErrorCategory.USER,
|
|
1000
|
+
details: { indexName },
|
|
1001
|
+
text: "Cannot provide both filter and ids - they are mutually exclusive"
|
|
1002
|
+
});
|
|
1003
|
+
}
|
|
1004
|
+
let query;
|
|
1005
|
+
let values;
|
|
1006
|
+
if (ids) {
|
|
1007
|
+
if (ids.length === 0) {
|
|
1008
|
+
throw new error.MastraError({
|
|
1009
|
+
id: "LIBSQL_VECTOR_DELETE_EMPTY_IDS",
|
|
1010
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1011
|
+
category: error.ErrorCategory.USER,
|
|
1012
|
+
details: { indexName },
|
|
1013
|
+
text: "Cannot delete with empty ids array"
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
1017
|
+
query = `DELETE FROM ${parsedIndexName} WHERE vector_id IN (${placeholders})`;
|
|
1018
|
+
values = ids;
|
|
1019
|
+
} else {
|
|
1020
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
1021
|
+
throw new error.MastraError({
|
|
1022
|
+
id: "LIBSQL_VECTOR_DELETE_EMPTY_FILTER",
|
|
1023
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1024
|
+
category: error.ErrorCategory.USER,
|
|
1025
|
+
details: { indexName },
|
|
1026
|
+
text: "Cannot delete with empty filter. Use deleteIndex to delete all vectors."
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
const translatedFilter = this.transformFilter(filter);
|
|
1030
|
+
const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
1031
|
+
if (!filterSql || filterSql.trim() === "") {
|
|
1032
|
+
throw new error.MastraError({
|
|
1033
|
+
id: "LIBSQL_VECTOR_DELETE_INVALID_FILTER",
|
|
1034
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1035
|
+
category: error.ErrorCategory.USER,
|
|
1036
|
+
details: { indexName },
|
|
1037
|
+
text: "Filter produced empty WHERE clause"
|
|
1038
|
+
});
|
|
1039
|
+
}
|
|
1040
|
+
const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
|
|
1041
|
+
const matchAllPatterns = ["true", "1 = 1", "1=1"];
|
|
1042
|
+
if (matchAllPatterns.includes(normalizedCondition)) {
|
|
1043
|
+
throw new error.MastraError({
|
|
1044
|
+
id: "LIBSQL_VECTOR_DELETE_MATCH_ALL_FILTER",
|
|
1045
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1046
|
+
category: error.ErrorCategory.USER,
|
|
1047
|
+
details: { indexName, filterSql: normalizedCondition },
|
|
1048
|
+
text: "Filter matches all vectors. Use deleteIndex to delete all vectors from an index."
|
|
1049
|
+
});
|
|
1050
|
+
}
|
|
1051
|
+
query = `DELETE FROM ${parsedIndexName} ${filterSql}`;
|
|
1052
|
+
values = filterValues;
|
|
1053
|
+
}
|
|
1054
|
+
try {
|
|
1055
|
+
await this.turso.execute({
|
|
1056
|
+
sql: query,
|
|
1057
|
+
args: values
|
|
1058
|
+
});
|
|
1059
|
+
} catch (error$1) {
|
|
1060
|
+
throw new error.MastraError(
|
|
1061
|
+
{
|
|
1062
|
+
id: "LIBSQL_VECTOR_DELETE_VECTORS_FAILED",
|
|
1063
|
+
domain: error.ErrorDomain.STORAGE,
|
|
1064
|
+
category: error.ErrorCategory.THIRD_PARTY,
|
|
1065
|
+
details: {
|
|
1066
|
+
indexName,
|
|
1067
|
+
...filter && { filter: JSON.stringify(filter) },
|
|
1068
|
+
...ids && { idsCount: ids.length }
|
|
1069
|
+
}
|
|
1070
|
+
},
|
|
1071
|
+
error$1
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
902
1075
|
truncateIndex(args) {
|
|
903
1076
|
try {
|
|
904
1077
|
return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));
|