@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/dist/index.js
CHANGED
|
@@ -90,12 +90,20 @@ var createBasicOperator = (symbol) => {
|
|
|
90
90
|
};
|
|
91
91
|
};
|
|
92
92
|
var createNumericOperator = (symbol) => {
|
|
93
|
-
return (key) => {
|
|
93
|
+
return (key, value) => {
|
|
94
94
|
const jsonPath = getJsonPath(key);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
const isNumeric = typeof value === "number" || typeof value === "string" && !isNaN(Number(value)) && value.trim() !== "";
|
|
96
|
+
if (isNumeric) {
|
|
97
|
+
return {
|
|
98
|
+
sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
|
|
99
|
+
needsValue: true
|
|
100
|
+
};
|
|
101
|
+
} else {
|
|
102
|
+
return {
|
|
103
|
+
sql: `CAST(json_extract(metadata, ${jsonPath}) AS TEXT) ${symbol} ?`,
|
|
104
|
+
needsValue: true
|
|
105
|
+
};
|
|
106
|
+
}
|
|
99
107
|
};
|
|
100
108
|
};
|
|
101
109
|
var validateJsonArray = (key) => {
|
|
@@ -824,8 +832,27 @@ var LibSQLVector = class extends MastraVector {
|
|
|
824
832
|
updateVector(args) {
|
|
825
833
|
return this.executeWriteOperationWithRetry(() => this.doUpdateVector(args));
|
|
826
834
|
}
|
|
827
|
-
async doUpdateVector(
|
|
835
|
+
async doUpdateVector(params) {
|
|
836
|
+
const { indexName, update } = params;
|
|
828
837
|
const parsedIndexName = parseSqlIdentifier(indexName, "index name");
|
|
838
|
+
if ("id" in params && params.id && "filter" in params && params.filter) {
|
|
839
|
+
throw new MastraError({
|
|
840
|
+
id: "LIBSQL_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE_PARAMS",
|
|
841
|
+
domain: ErrorDomain.STORAGE,
|
|
842
|
+
category: ErrorCategory.USER,
|
|
843
|
+
details: { indexName },
|
|
844
|
+
text: "id and filter are mutually exclusive - provide only one"
|
|
845
|
+
});
|
|
846
|
+
}
|
|
847
|
+
if (!update.vector && !update.metadata) {
|
|
848
|
+
throw new MastraError({
|
|
849
|
+
id: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
850
|
+
domain: ErrorDomain.STORAGE,
|
|
851
|
+
category: ErrorCategory.USER,
|
|
852
|
+
details: { indexName },
|
|
853
|
+
text: "No updates provided"
|
|
854
|
+
});
|
|
855
|
+
}
|
|
829
856
|
const updates = [];
|
|
830
857
|
const args = [];
|
|
831
858
|
if (update.vector) {
|
|
@@ -837,32 +864,81 @@ var LibSQLVector = class extends MastraVector {
|
|
|
837
864
|
args.push(JSON.stringify(update.metadata));
|
|
838
865
|
}
|
|
839
866
|
if (updates.length === 0) {
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
let whereClause;
|
|
870
|
+
let whereValues;
|
|
871
|
+
if ("id" in params && params.id) {
|
|
872
|
+
whereClause = "vector_id = ?";
|
|
873
|
+
whereValues = [params.id];
|
|
874
|
+
} else if ("filter" in params && params.filter) {
|
|
875
|
+
const filter = params.filter;
|
|
876
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
877
|
+
throw new MastraError({
|
|
878
|
+
id: "LIBSQL_VECTOR_UPDATE_EMPTY_FILTER",
|
|
879
|
+
domain: ErrorDomain.STORAGE,
|
|
880
|
+
category: ErrorCategory.USER,
|
|
881
|
+
details: { indexName },
|
|
882
|
+
text: "Cannot update with empty filter"
|
|
883
|
+
});
|
|
884
|
+
}
|
|
885
|
+
const translatedFilter = this.transformFilter(filter);
|
|
886
|
+
const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
887
|
+
if (!filterSql || filterSql.trim() === "") {
|
|
888
|
+
throw new MastraError({
|
|
889
|
+
id: "LIBSQL_VECTOR_UPDATE_INVALID_FILTER",
|
|
890
|
+
domain: ErrorDomain.STORAGE,
|
|
891
|
+
category: ErrorCategory.USER,
|
|
892
|
+
details: { indexName },
|
|
893
|
+
text: "Filter produced empty WHERE clause"
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
|
|
897
|
+
const matchAllPatterns = ["true", "1 = 1", "1=1"];
|
|
898
|
+
if (matchAllPatterns.includes(normalizedCondition)) {
|
|
899
|
+
throw new MastraError({
|
|
900
|
+
id: "LIBSQL_VECTOR_UPDATE_MATCH_ALL_FILTER",
|
|
901
|
+
domain: ErrorDomain.STORAGE,
|
|
902
|
+
category: ErrorCategory.USER,
|
|
903
|
+
details: { indexName, filterSql: normalizedCondition },
|
|
904
|
+
text: "Filter matches all vectors. Provide a specific filter to update targeted vectors."
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
whereClause = filterSql.replace(/^WHERE\s+/i, "");
|
|
908
|
+
whereValues = filterValues;
|
|
909
|
+
} else {
|
|
840
910
|
throw new MastraError({
|
|
841
|
-
id: "
|
|
911
|
+
id: "LIBSQL_VECTOR_UPDATE_MISSING_PARAMS",
|
|
842
912
|
domain: ErrorDomain.STORAGE,
|
|
843
913
|
category: ErrorCategory.USER,
|
|
844
|
-
details: { indexName
|
|
845
|
-
text: "
|
|
914
|
+
details: { indexName },
|
|
915
|
+
text: "Either id or filter must be provided"
|
|
846
916
|
});
|
|
847
917
|
}
|
|
848
|
-
args.push(id);
|
|
849
918
|
const query = `
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
919
|
+
UPDATE ${parsedIndexName}
|
|
920
|
+
SET ${updates.join(", ")}
|
|
921
|
+
WHERE ${whereClause};
|
|
922
|
+
`;
|
|
854
923
|
try {
|
|
855
924
|
await this.turso.execute({
|
|
856
925
|
sql: query,
|
|
857
|
-
args
|
|
926
|
+
args: [...args, ...whereValues]
|
|
858
927
|
});
|
|
859
928
|
} catch (error) {
|
|
929
|
+
const errorDetails = { indexName };
|
|
930
|
+
if ("id" in params && params.id) {
|
|
931
|
+
errorDetails.id = params.id;
|
|
932
|
+
}
|
|
933
|
+
if ("filter" in params && params.filter) {
|
|
934
|
+
errorDetails.filter = JSON.stringify(params.filter);
|
|
935
|
+
}
|
|
860
936
|
throw new MastraError(
|
|
861
937
|
{
|
|
862
938
|
id: "LIBSQL_VECTOR_UPDATE_VECTOR_FAILED",
|
|
863
939
|
domain: ErrorDomain.STORAGE,
|
|
864
940
|
category: ErrorCategory.THIRD_PARTY,
|
|
865
|
-
details:
|
|
941
|
+
details: errorDetails
|
|
866
942
|
},
|
|
867
943
|
error
|
|
868
944
|
);
|
|
@@ -884,7 +960,10 @@ var LibSQLVector = class extends MastraVector {
|
|
|
884
960
|
id: "LIBSQL_VECTOR_DELETE_VECTOR_FAILED",
|
|
885
961
|
domain: ErrorDomain.STORAGE,
|
|
886
962
|
category: ErrorCategory.THIRD_PARTY,
|
|
887
|
-
details: {
|
|
963
|
+
details: {
|
|
964
|
+
indexName: args.indexName,
|
|
965
|
+
...args.id && { id: args.id }
|
|
966
|
+
}
|
|
888
967
|
},
|
|
889
968
|
error
|
|
890
969
|
);
|
|
@@ -897,6 +976,100 @@ var LibSQLVector = class extends MastraVector {
|
|
|
897
976
|
args: [id]
|
|
898
977
|
});
|
|
899
978
|
}
|
|
979
|
+
deleteVectors(args) {
|
|
980
|
+
return this.executeWriteOperationWithRetry(() => this.doDeleteVectors(args));
|
|
981
|
+
}
|
|
982
|
+
async doDeleteVectors({ indexName, filter, ids }) {
|
|
983
|
+
const parsedIndexName = parseSqlIdentifier(indexName, "index name");
|
|
984
|
+
if (!filter && !ids) {
|
|
985
|
+
throw new MastraError({
|
|
986
|
+
id: "LIBSQL_VECTOR_DELETE_MISSING_PARAMS",
|
|
987
|
+
domain: ErrorDomain.STORAGE,
|
|
988
|
+
category: ErrorCategory.USER,
|
|
989
|
+
details: { indexName },
|
|
990
|
+
text: "Either filter or ids must be provided"
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
if (filter && ids) {
|
|
994
|
+
throw new MastraError({
|
|
995
|
+
id: "LIBSQL_VECTOR_DELETE_CONFLICTING_PARAMS",
|
|
996
|
+
domain: ErrorDomain.STORAGE,
|
|
997
|
+
category: ErrorCategory.USER,
|
|
998
|
+
details: { indexName },
|
|
999
|
+
text: "Cannot provide both filter and ids - they are mutually exclusive"
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
let query;
|
|
1003
|
+
let values;
|
|
1004
|
+
if (ids) {
|
|
1005
|
+
if (ids.length === 0) {
|
|
1006
|
+
throw new MastraError({
|
|
1007
|
+
id: "LIBSQL_VECTOR_DELETE_EMPTY_IDS",
|
|
1008
|
+
domain: ErrorDomain.STORAGE,
|
|
1009
|
+
category: ErrorCategory.USER,
|
|
1010
|
+
details: { indexName },
|
|
1011
|
+
text: "Cannot delete with empty ids array"
|
|
1012
|
+
});
|
|
1013
|
+
}
|
|
1014
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
1015
|
+
query = `DELETE FROM ${parsedIndexName} WHERE vector_id IN (${placeholders})`;
|
|
1016
|
+
values = ids;
|
|
1017
|
+
} else {
|
|
1018
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
1019
|
+
throw new MastraError({
|
|
1020
|
+
id: "LIBSQL_VECTOR_DELETE_EMPTY_FILTER",
|
|
1021
|
+
domain: ErrorDomain.STORAGE,
|
|
1022
|
+
category: ErrorCategory.USER,
|
|
1023
|
+
details: { indexName },
|
|
1024
|
+
text: "Cannot delete with empty filter. Use deleteIndex to delete all vectors."
|
|
1025
|
+
});
|
|
1026
|
+
}
|
|
1027
|
+
const translatedFilter = this.transformFilter(filter);
|
|
1028
|
+
const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
1029
|
+
if (!filterSql || filterSql.trim() === "") {
|
|
1030
|
+
throw new MastraError({
|
|
1031
|
+
id: "LIBSQL_VECTOR_DELETE_INVALID_FILTER",
|
|
1032
|
+
domain: ErrorDomain.STORAGE,
|
|
1033
|
+
category: ErrorCategory.USER,
|
|
1034
|
+
details: { indexName },
|
|
1035
|
+
text: "Filter produced empty WHERE clause"
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
1038
|
+
const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
|
|
1039
|
+
const matchAllPatterns = ["true", "1 = 1", "1=1"];
|
|
1040
|
+
if (matchAllPatterns.includes(normalizedCondition)) {
|
|
1041
|
+
throw new MastraError({
|
|
1042
|
+
id: "LIBSQL_VECTOR_DELETE_MATCH_ALL_FILTER",
|
|
1043
|
+
domain: ErrorDomain.STORAGE,
|
|
1044
|
+
category: ErrorCategory.USER,
|
|
1045
|
+
details: { indexName, filterSql: normalizedCondition },
|
|
1046
|
+
text: "Filter matches all vectors. Use deleteIndex to delete all vectors from an index."
|
|
1047
|
+
});
|
|
1048
|
+
}
|
|
1049
|
+
query = `DELETE FROM ${parsedIndexName} ${filterSql}`;
|
|
1050
|
+
values = filterValues;
|
|
1051
|
+
}
|
|
1052
|
+
try {
|
|
1053
|
+
await this.turso.execute({
|
|
1054
|
+
sql: query,
|
|
1055
|
+
args: values
|
|
1056
|
+
});
|
|
1057
|
+
} catch (error) {
|
|
1058
|
+
throw new MastraError(
|
|
1059
|
+
{
|
|
1060
|
+
id: "LIBSQL_VECTOR_DELETE_VECTORS_FAILED",
|
|
1061
|
+
domain: ErrorDomain.STORAGE,
|
|
1062
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1063
|
+
details: {
|
|
1064
|
+
indexName,
|
|
1065
|
+
...filter && { filter: JSON.stringify(filter) },
|
|
1066
|
+
...ids && { idsCount: ids.length }
|
|
1067
|
+
}
|
|
1068
|
+
},
|
|
1069
|
+
error
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
900
1073
|
truncateIndex(args) {
|
|
901
1074
|
try {
|
|
902
1075
|
return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));
|