@mastra/libsql 0.16.2-alpha.0 → 0.16.3-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/index.cjs +195 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +195 -18
- package/dist/index.js.map +1 -1
- package/dist/storage/domains/memory/index.d.ts.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 +5 -5
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) => {
|
|
@@ -823,8 +831,27 @@ var LibSQLVector = class extends MastraVector {
|
|
|
823
831
|
updateVector(args) {
|
|
824
832
|
return this.executeWriteOperationWithRetry(() => this.doUpdateVector(args));
|
|
825
833
|
}
|
|
826
|
-
async doUpdateVector(
|
|
834
|
+
async doUpdateVector(params) {
|
|
835
|
+
const { indexName, update } = params;
|
|
827
836
|
const parsedIndexName = parseSqlIdentifier(indexName, "index name");
|
|
837
|
+
if ("id" in params && params.id && "filter" in params && params.filter) {
|
|
838
|
+
throw new MastraError({
|
|
839
|
+
id: "LIBSQL_VECTOR_UPDATE_MUTUALLY_EXCLUSIVE_PARAMS",
|
|
840
|
+
domain: ErrorDomain.STORAGE,
|
|
841
|
+
category: ErrorCategory.USER,
|
|
842
|
+
details: { indexName },
|
|
843
|
+
text: "id and filter are mutually exclusive - provide only one"
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
if (!update.vector && !update.metadata) {
|
|
847
|
+
throw new MastraError({
|
|
848
|
+
id: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
|
|
849
|
+
domain: ErrorDomain.STORAGE,
|
|
850
|
+
category: ErrorCategory.USER,
|
|
851
|
+
details: { indexName },
|
|
852
|
+
text: "No updates provided"
|
|
853
|
+
});
|
|
854
|
+
}
|
|
828
855
|
const updates = [];
|
|
829
856
|
const args = [];
|
|
830
857
|
if (update.vector) {
|
|
@@ -836,32 +863,81 @@ var LibSQLVector = class extends MastraVector {
|
|
|
836
863
|
args.push(JSON.stringify(update.metadata));
|
|
837
864
|
}
|
|
838
865
|
if (updates.length === 0) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
let whereClause;
|
|
869
|
+
let whereValues;
|
|
870
|
+
if ("id" in params && params.id) {
|
|
871
|
+
whereClause = "vector_id = ?";
|
|
872
|
+
whereValues = [params.id];
|
|
873
|
+
} else if ("filter" in params && params.filter) {
|
|
874
|
+
const filter = params.filter;
|
|
875
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
876
|
+
throw new MastraError({
|
|
877
|
+
id: "LIBSQL_VECTOR_UPDATE_EMPTY_FILTER",
|
|
878
|
+
domain: ErrorDomain.STORAGE,
|
|
879
|
+
category: ErrorCategory.USER,
|
|
880
|
+
details: { indexName },
|
|
881
|
+
text: "Cannot update with empty filter"
|
|
882
|
+
});
|
|
883
|
+
}
|
|
884
|
+
const translatedFilter = this.transformFilter(filter);
|
|
885
|
+
const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
886
|
+
if (!filterSql || filterSql.trim() === "") {
|
|
887
|
+
throw new MastraError({
|
|
888
|
+
id: "LIBSQL_VECTOR_UPDATE_INVALID_FILTER",
|
|
889
|
+
domain: ErrorDomain.STORAGE,
|
|
890
|
+
category: ErrorCategory.USER,
|
|
891
|
+
details: { indexName },
|
|
892
|
+
text: "Filter produced empty WHERE clause"
|
|
893
|
+
});
|
|
894
|
+
}
|
|
895
|
+
const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
|
|
896
|
+
const matchAllPatterns = ["true", "1 = 1", "1=1"];
|
|
897
|
+
if (matchAllPatterns.includes(normalizedCondition)) {
|
|
898
|
+
throw new MastraError({
|
|
899
|
+
id: "LIBSQL_VECTOR_UPDATE_MATCH_ALL_FILTER",
|
|
900
|
+
domain: ErrorDomain.STORAGE,
|
|
901
|
+
category: ErrorCategory.USER,
|
|
902
|
+
details: { indexName, filterSql: normalizedCondition },
|
|
903
|
+
text: "Filter matches all vectors. Provide a specific filter to update targeted vectors."
|
|
904
|
+
});
|
|
905
|
+
}
|
|
906
|
+
whereClause = filterSql.replace(/^WHERE\s+/i, "");
|
|
907
|
+
whereValues = filterValues;
|
|
908
|
+
} else {
|
|
839
909
|
throw new MastraError({
|
|
840
|
-
id: "
|
|
910
|
+
id: "LIBSQL_VECTOR_UPDATE_MISSING_PARAMS",
|
|
841
911
|
domain: ErrorDomain.STORAGE,
|
|
842
912
|
category: ErrorCategory.USER,
|
|
843
|
-
details: { indexName
|
|
844
|
-
text: "
|
|
913
|
+
details: { indexName },
|
|
914
|
+
text: "Either id or filter must be provided"
|
|
845
915
|
});
|
|
846
916
|
}
|
|
847
|
-
args.push(id);
|
|
848
917
|
const query = `
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
918
|
+
UPDATE ${parsedIndexName}
|
|
919
|
+
SET ${updates.join(", ")}
|
|
920
|
+
WHERE ${whereClause};
|
|
921
|
+
`;
|
|
853
922
|
try {
|
|
854
923
|
await this.turso.execute({
|
|
855
924
|
sql: query,
|
|
856
|
-
args
|
|
925
|
+
args: [...args, ...whereValues]
|
|
857
926
|
});
|
|
858
927
|
} catch (error) {
|
|
928
|
+
const errorDetails = { indexName };
|
|
929
|
+
if ("id" in params && params.id) {
|
|
930
|
+
errorDetails.id = params.id;
|
|
931
|
+
}
|
|
932
|
+
if ("filter" in params && params.filter) {
|
|
933
|
+
errorDetails.filter = JSON.stringify(params.filter);
|
|
934
|
+
}
|
|
859
935
|
throw new MastraError(
|
|
860
936
|
{
|
|
861
937
|
id: "LIBSQL_VECTOR_UPDATE_VECTOR_FAILED",
|
|
862
938
|
domain: ErrorDomain.STORAGE,
|
|
863
939
|
category: ErrorCategory.THIRD_PARTY,
|
|
864
|
-
details:
|
|
940
|
+
details: errorDetails
|
|
865
941
|
},
|
|
866
942
|
error
|
|
867
943
|
);
|
|
@@ -883,7 +959,10 @@ var LibSQLVector = class extends MastraVector {
|
|
|
883
959
|
id: "LIBSQL_VECTOR_DELETE_VECTOR_FAILED",
|
|
884
960
|
domain: ErrorDomain.STORAGE,
|
|
885
961
|
category: ErrorCategory.THIRD_PARTY,
|
|
886
|
-
details: {
|
|
962
|
+
details: {
|
|
963
|
+
indexName: args.indexName,
|
|
964
|
+
...args.id && { id: args.id }
|
|
965
|
+
}
|
|
887
966
|
},
|
|
888
967
|
error
|
|
889
968
|
);
|
|
@@ -896,6 +975,100 @@ var LibSQLVector = class extends MastraVector {
|
|
|
896
975
|
args: [id]
|
|
897
976
|
});
|
|
898
977
|
}
|
|
978
|
+
deleteVectors(args) {
|
|
979
|
+
return this.executeWriteOperationWithRetry(() => this.doDeleteVectors(args));
|
|
980
|
+
}
|
|
981
|
+
async doDeleteVectors({ indexName, filter, ids }) {
|
|
982
|
+
const parsedIndexName = parseSqlIdentifier(indexName, "index name");
|
|
983
|
+
if (!filter && !ids) {
|
|
984
|
+
throw new MastraError({
|
|
985
|
+
id: "LIBSQL_VECTOR_DELETE_MISSING_PARAMS",
|
|
986
|
+
domain: ErrorDomain.STORAGE,
|
|
987
|
+
category: ErrorCategory.USER,
|
|
988
|
+
details: { indexName },
|
|
989
|
+
text: "Either filter or ids must be provided"
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
if (filter && ids) {
|
|
993
|
+
throw new MastraError({
|
|
994
|
+
id: "LIBSQL_VECTOR_DELETE_CONFLICTING_PARAMS",
|
|
995
|
+
domain: ErrorDomain.STORAGE,
|
|
996
|
+
category: ErrorCategory.USER,
|
|
997
|
+
details: { indexName },
|
|
998
|
+
text: "Cannot provide both filter and ids - they are mutually exclusive"
|
|
999
|
+
});
|
|
1000
|
+
}
|
|
1001
|
+
let query;
|
|
1002
|
+
let values;
|
|
1003
|
+
if (ids) {
|
|
1004
|
+
if (ids.length === 0) {
|
|
1005
|
+
throw new MastraError({
|
|
1006
|
+
id: "LIBSQL_VECTOR_DELETE_EMPTY_IDS",
|
|
1007
|
+
domain: ErrorDomain.STORAGE,
|
|
1008
|
+
category: ErrorCategory.USER,
|
|
1009
|
+
details: { indexName },
|
|
1010
|
+
text: "Cannot delete with empty ids array"
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
1013
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
1014
|
+
query = `DELETE FROM ${parsedIndexName} WHERE vector_id IN (${placeholders})`;
|
|
1015
|
+
values = ids;
|
|
1016
|
+
} else {
|
|
1017
|
+
if (!filter || Object.keys(filter).length === 0) {
|
|
1018
|
+
throw new MastraError({
|
|
1019
|
+
id: "LIBSQL_VECTOR_DELETE_EMPTY_FILTER",
|
|
1020
|
+
domain: ErrorDomain.STORAGE,
|
|
1021
|
+
category: ErrorCategory.USER,
|
|
1022
|
+
details: { indexName },
|
|
1023
|
+
text: "Cannot delete with empty filter. Use deleteIndex to delete all vectors."
|
|
1024
|
+
});
|
|
1025
|
+
}
|
|
1026
|
+
const translatedFilter = this.transformFilter(filter);
|
|
1027
|
+
const { sql: filterSql, values: filterValues } = buildFilterQuery(translatedFilter);
|
|
1028
|
+
if (!filterSql || filterSql.trim() === "") {
|
|
1029
|
+
throw new MastraError({
|
|
1030
|
+
id: "LIBSQL_VECTOR_DELETE_INVALID_FILTER",
|
|
1031
|
+
domain: ErrorDomain.STORAGE,
|
|
1032
|
+
category: ErrorCategory.USER,
|
|
1033
|
+
details: { indexName },
|
|
1034
|
+
text: "Filter produced empty WHERE clause"
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
1037
|
+
const normalizedCondition = filterSql.replace(/^\s*WHERE\s+/i, "").trim().toLowerCase();
|
|
1038
|
+
const matchAllPatterns = ["true", "1 = 1", "1=1"];
|
|
1039
|
+
if (matchAllPatterns.includes(normalizedCondition)) {
|
|
1040
|
+
throw new MastraError({
|
|
1041
|
+
id: "LIBSQL_VECTOR_DELETE_MATCH_ALL_FILTER",
|
|
1042
|
+
domain: ErrorDomain.STORAGE,
|
|
1043
|
+
category: ErrorCategory.USER,
|
|
1044
|
+
details: { indexName, filterSql: normalizedCondition },
|
|
1045
|
+
text: "Filter matches all vectors. Use deleteIndex to delete all vectors from an index."
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
query = `DELETE FROM ${parsedIndexName} ${filterSql}`;
|
|
1049
|
+
values = filterValues;
|
|
1050
|
+
}
|
|
1051
|
+
try {
|
|
1052
|
+
await this.turso.execute({
|
|
1053
|
+
sql: query,
|
|
1054
|
+
args: values
|
|
1055
|
+
});
|
|
1056
|
+
} catch (error) {
|
|
1057
|
+
throw new MastraError(
|
|
1058
|
+
{
|
|
1059
|
+
id: "LIBSQL_VECTOR_DELETE_VECTORS_FAILED",
|
|
1060
|
+
domain: ErrorDomain.STORAGE,
|
|
1061
|
+
category: ErrorCategory.THIRD_PARTY,
|
|
1062
|
+
details: {
|
|
1063
|
+
indexName,
|
|
1064
|
+
...filter && { filter: JSON.stringify(filter) },
|
|
1065
|
+
...ids && { idsCount: ids.length }
|
|
1066
|
+
}
|
|
1067
|
+
},
|
|
1068
|
+
error
|
|
1069
|
+
);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
899
1072
|
truncateIndex(args) {
|
|
900
1073
|
try {
|
|
901
1074
|
return this.executeWriteOperationWithRetry(() => this._doTruncateIndex(args));
|
|
@@ -1254,7 +1427,11 @@ var MemoryLibSQL = class extends MemoryStorage {
|
|
|
1254
1427
|
args: [...queryParams, ...excludeIds, perPage, currentOffset]
|
|
1255
1428
|
});
|
|
1256
1429
|
messages.push(...(dataResult.rows || []).map((row) => this.parseRow(row)));
|
|
1257
|
-
const
|
|
1430
|
+
const list = new MessageList().add(messages, "memory");
|
|
1431
|
+
let messagesToReturn = format === "v1" ? list.get.all.v1() : list.get.all.v2();
|
|
1432
|
+
messagesToReturn = messagesToReturn.sort(
|
|
1433
|
+
(a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime()
|
|
1434
|
+
);
|
|
1258
1435
|
return {
|
|
1259
1436
|
messages: messagesToReturn,
|
|
1260
1437
|
total,
|