@mastra/libsql 1.0.0-beta.0 → 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/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
- return {
96
- sql: `CAST(json_extract(metadata, ${jsonPath}) AS NUMERIC) ${symbol} ?`,
97
- needsValue: true
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({ indexName, id, update }) {
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: "LIBSQL_VECTOR_UPDATE_VECTOR_INVALID_ARGS",
911
+ id: "LIBSQL_VECTOR_UPDATE_MISSING_PARAMS",
842
912
  domain: ErrorDomain.STORAGE,
843
913
  category: ErrorCategory.USER,
844
- details: { indexName, id },
845
- text: "No updates provided"
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
- UPDATE ${parsedIndexName}
851
- SET ${updates.join(", ")}
852
- WHERE vector_id = ?;
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: { indexName, id }
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: { indexName: args.indexName, id: args.id }
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));
@@ -2853,11 +3026,12 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
2853
3026
  activePaths: [],
2854
3027
  timestamp: Date.now(),
2855
3028
  suspendedPaths: {},
3029
+ activeStepsPath: {},
2856
3030
  resumeLabels: {},
2857
3031
  serializedStepGraph: [],
3032
+ status: "pending",
2858
3033
  value: {},
2859
3034
  waitingPaths: {},
2860
- status: "pending",
2861
3035
  runId,
2862
3036
  requestContext: {}
2863
3037
  };
@@ -2990,7 +3164,8 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
2990
3164
  toDate,
2991
3165
  page,
2992
3166
  perPage,
2993
- resourceId
3167
+ resourceId,
3168
+ status
2994
3169
  } = {}) {
2995
3170
  try {
2996
3171
  const conditions = [];
@@ -2999,6 +3174,10 @@ var WorkflowsLibSQL = class extends WorkflowsStorage {
2999
3174
  conditions.push("workflow_name = ?");
3000
3175
  args.push(workflowName);
3001
3176
  }
3177
+ if (status) {
3178
+ conditions.push("json_extract(snapshot, '$.status') = ?");
3179
+ args.push(status);
3180
+ }
3002
3181
  if (fromDate) {
3003
3182
  conditions.push("createdAt >= ?");
3004
3183
  args.push(fromDate.toISOString());
@@ -3229,15 +3408,8 @@ var LibSQLStore = class extends MastraStorage {
3229
3408
  }) {
3230
3409
  return this.stores.workflows.loadWorkflowSnapshot({ workflowName, runId });
3231
3410
  }
3232
- async listWorkflowRuns({
3233
- workflowName,
3234
- fromDate,
3235
- toDate,
3236
- perPage,
3237
- page,
3238
- resourceId
3239
- } = {}) {
3240
- return this.stores.workflows.listWorkflowRuns({ workflowName, fromDate, toDate, perPage, page, resourceId });
3411
+ async listWorkflowRuns(args = {}) {
3412
+ return this.stores.workflows.listWorkflowRuns(args);
3241
3413
  }
3242
3414
  async getWorkflowRunById({
3243
3415
  runId,