@mastra/libsql 1.23.0 → 1.23.1-alpha.1

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
@@ -1,6 +1,6 @@
1
1
  import { createClient } from "@libsql/client";
2
2
  import { ErrorCategory, ErrorDomain, MastraError } from "@mastra/core/error";
3
- import { AGENTS_SCHEMA, AGENT_VERSIONS_SCHEMA, AgentsStorage, BackgroundTasksStorage, BlobStore, ChannelsStorage, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, DatasetsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, ExperimentsStorage, FAVORITES_SCHEMA, FactoryStorage, FavoritesStorage, HarnessStorage, KNOWLEDGE_ACTIVITY_SCHEMA, KNOWLEDGE_CURSORS_SCHEMA, KNOWLEDGE_MENTIONS_SCHEMA, KNOWLEDGE_NODES_SCHEMA, KNOWLEDGE_RECORDS_SCHEMA, KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA, KnowledgeConflictError, KnowledgeNotFoundError, KnowledgeStorage, MCPClientsStorage, MCPServersStorage, MCP_CLIENTS_SCHEMA, MCP_CLIENT_VERSIONS_SCHEMA, MCP_SERVERS_SCHEMA, MCP_SERVER_VERSIONS_SCHEMA, MastraCompositeStore, MemoryStorage, NotificationsStorage, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, ObservabilityStorage, PROMPT_BLOCKS_SCHEMA, PROMPT_BLOCK_VERSIONS_SCHEMA, PromptBlocksStorage, SCORERS_SCHEMA, SCORER_DEFINITIONS_SCHEMA, SCORER_DEFINITION_VERSIONS_SCHEMA, SKILLS_SCHEMA, SKILL_BLOBS_SCHEMA, SKILL_VERSIONS_SCHEMA, SPAN_SCHEMA, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_HARNESS_SESSIONS, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_CURSORS, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_THREAD_STATE, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, THREAD_STATE_SCHEMA, TOOL_PROVIDER_CONNECTIONS_SCHEMA, ThreadStateStorage, ToolProviderConnectionsStorage, TraceStatus, UniqueViolationError, WORKSPACES_SCHEMA, WORKSPACE_VERSIONS_SCHEMA, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, assertKnowledgeCeilingRaised, assertKnowledgeScopeWithinCeiling, calculatePagination, canonicalizeKnowledgeScope, createKnowledgeUlid, createStorageErrorId, createVectorErrorId, ensureDate, getSqlType, hasErrorCode, isKnowledgeScopeVisible, knowledgeScopeKey, knowledgeSemanticDocumentId, knowledgeSemanticIdempotencyKey, listTracesArgsSchema, matchesExpectedWorkflowStatus, mergeWorkflowStepResult, normalizePerPage, normalizeScheduleTarget, parseDuration, parseKnowledgeNodeCursor, parseKnowledgeWikilinks, safelyParseJSON, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
3
+ import { AGENTS_SCHEMA, AGENT_VERSIONS_SCHEMA, AgentsStorage, BackgroundTasksStorage, BlobStore, ChannelsStorage, DATASETS_SCHEMA, DATASET_ITEMS_SCHEMA, DATASET_VERSIONS_SCHEMA, DatasetsStorage, EXPERIMENTS_SCHEMA, EXPERIMENT_RESULTS_SCHEMA, ExperimentsStorage, FAVORITES_SCHEMA, FactoryStorage, FavoritesStorage, HarnessStorage, KNOWLEDGE_ACTIVITY_SCHEMA, KNOWLEDGE_CURSORS_SCHEMA, KNOWLEDGE_MENTIONS_SCHEMA, KNOWLEDGE_NODES_SCHEMA, KNOWLEDGE_RECORDS_SCHEMA, KNOWLEDGE_SEMANTIC_OUTBOX_SCHEMA, KnowledgeConflictError, KnowledgeNotFoundError, KnowledgeStorage, MCPClientsStorage, MCPServersStorage, MCP_CLIENTS_SCHEMA, MCP_CLIENT_VERSIONS_SCHEMA, MCP_SERVERS_SCHEMA, MCP_SERVER_VERSIONS_SCHEMA, MastraCompositeStore, MemoryStorage, NotificationsStorage, OBSERVATIONAL_MEMORY_TABLE_SCHEMA, ObservabilityStorage, PROMPT_BLOCKS_SCHEMA, PROMPT_BLOCK_VERSIONS_SCHEMA, PromptBlocksStorage, SCORERS_SCHEMA, SCORER_DEFINITIONS_SCHEMA, SCORER_DEFINITION_VERSIONS_SCHEMA, SKILLS_SCHEMA, SKILL_BLOBS_SCHEMA, SKILL_VERSIONS_SCHEMA, SPAN_SCHEMA, SchedulesStorage, ScorerDefinitionsStorage, ScoresStorage, SkillsStorage, TABLE_AGENTS, TABLE_AGENT_VERSIONS, TABLE_BACKGROUND_TASKS, TABLE_CHANNEL_CONFIG, TABLE_CHANNEL_INSTALLATIONS, TABLE_DATASETS, TABLE_DATASET_ITEMS, TABLE_DATASET_VERSIONS, TABLE_EXPERIMENTS, TABLE_EXPERIMENT_RESULTS, TABLE_FAVORITES, TABLE_HARNESS_SESSIONS, TABLE_KNOWLEDGE_ACTIVITY, TABLE_KNOWLEDGE_CURSORS, TABLE_KNOWLEDGE_MENTIONS, TABLE_KNOWLEDGE_NODES, TABLE_KNOWLEDGE_RECORDS, TABLE_KNOWLEDGE_SEMANTIC_OUTBOX, TABLE_MCP_CLIENTS, TABLE_MCP_CLIENT_VERSIONS, TABLE_MCP_SERVERS, TABLE_MCP_SERVER_VERSIONS, TABLE_MESSAGES, TABLE_NOTIFICATIONS, TABLE_PROMPT_BLOCKS, TABLE_PROMPT_BLOCK_VERSIONS, TABLE_RESOURCES, TABLE_SCHEDULES, TABLE_SCHEDULE_TRIGGERS, TABLE_SCHEMAS, TABLE_SCORERS, TABLE_SCORER_DEFINITIONS, TABLE_SCORER_DEFINITION_VERSIONS, TABLE_SKILLS, TABLE_SKILL_BLOBS, TABLE_SKILL_VERSIONS, TABLE_SPANS, TABLE_THREADS, TABLE_THREAD_STATE, TABLE_TOOL_PROVIDER_CONNECTIONS, TABLE_WORKFLOW_DEFINITIONS, TABLE_WORKFLOW_SNAPSHOT, TABLE_WORKSPACES, TABLE_WORKSPACE_VERSIONS, THREAD_STATE_SCHEMA, TOOL_PROVIDER_CONNECTIONS_SCHEMA, ThreadStateStorage, ToolProviderConnectionsStorage, TraceStatus, UniqueViolationError, WORKSPACES_SCHEMA, WORKSPACE_VERSIONS_SCHEMA, WorkflowDefinitionsStorage, WorkflowsStorage, WorkspacesStorage, assertKnowledgeCeilingRaised, assertKnowledgeScopeWithinCeiling, calculatePagination, canonicalizeKnowledgeScope, createKnowledgeUlid, createStorageErrorId, createVectorErrorId, ensureDate, executeRetentionPrune, getSqlType, hasErrorCode, isKnowledgeScopeVisible, knowledgeScopeKey, knowledgeSemanticDocumentId, knowledgeSemanticIdempotencyKey, listTracesArgsSchema, matchesExpectedWorkflowStatus, mergeWorkflowStepResult, normalizePerPage, normalizeScheduleTarget, parseKnowledgeNodeCursor, parseKnowledgeWikilinks, resolveRetentionTargets, retentionCutoffMs, runRetentionBatches, safelyParseJSON, toTraceSpans, transformScoreRow, validateStorageMetadataFilter } from "@mastra/core/storage";
4
4
  import { parseFieldKey, parseSqlIdentifier } from "@mastra/core/utils";
5
5
  import { MastraVector, validateTopK, validateUpsertInput } from "@mastra/core/vector";
6
6
  import { BaseFilterTranslator } from "@mastra/core/vector/filter";
@@ -2872,13 +2872,6 @@ var AgentsLibSQL = class extends AgentsStorage {
2872
2872
  };
2873
2873
  //#endregion
2874
2874
  //#region src/storage/retention.ts
2875
- const DEFAULT_BATCH_SIZE = 1e3;
2876
- /**
2877
- * Lazily create the single-column anchor index a prune target relies on.
2878
- * Called from the prune path (not init) so only deployments that actually
2879
- * configure retention pay the index's write/disk overhead. Best-effort: a
2880
- * failure is logged and pruning proceeds (correct, just slower).
2881
- */
2882
2875
  async function ensureAnchorIndex(db, target, logger) {
2883
2876
  if (!target.indexed) return;
2884
2877
  try {
@@ -2891,134 +2884,32 @@ async function ensureAnchorIndex(db, target, logger) {
2891
2884
  logger?.warn?.(`Failed to ensure retention index on ${target.table}(${target.column}):`, error);
2892
2885
  }
2893
2886
  }
2894
- async function sleep(ms, signal) {
2895
- if (ms <= 0 || signal?.aborted) return;
2896
- await new Promise((resolve) => {
2897
- const timer = setTimeout(() => {
2898
- signal?.removeEventListener("abort", onAbort);
2899
- resolve();
2900
- }, ms);
2901
- const onAbort = () => {
2902
- clearTimeout(timer);
2903
- resolve();
2904
- };
2905
- signal?.addEventListener("abort", onAbort, { once: true });
2906
- });
2907
- }
2908
- /**
2909
- * Runs the bounded, batched, cancellable delete loop for a set of tables in the
2910
- * given order (callers pass children before parents for cascade-safe pruning),
2911
- * and returns one {@link PruneResult} per table.
2912
- *
2913
- * The loop:
2914
- * - deletes in chunks of `batchSize` (default 1000), each its own statement;
2915
- * - stops a table's loop when a batch deletes fewer rows than requested (drained),
2916
- * or when `maxBatches`/`maxRows` is hit, or the `signal` aborts — the latter
2917
- * three leave `done: false` so the caller can resume;
2918
- * - pauses `pauseMs` between batches when set, to avoid starving live traffic.
2919
- *
2920
- * `prune()` only deletes rows; it never reclaims disk. Freed pages are reused
2921
- * by future writes so the file stops growing. Handing disk back to the OS is
2922
- * left to the underlying database and the operator to manage.
2923
- */
2924
- /** Convert a policy's `maxAge` into a cutoff bound matching the anchor's storage type. */
2925
2887
  function cutoffFor(policy, anchorType, now = Date.now()) {
2926
- const cutoffMs = now - parseDuration(policy.maxAge);
2888
+ const cutoffMs = retentionCutoffMs(policy, now);
2927
2889
  return anchorType === "epoch-ms" ? cutoffMs : new Date(cutoffMs).toISOString();
2928
2890
  }
2929
- /**
2930
- * Run the bounded/cancellable batched-delete loop for a single logical target,
2931
- * delegating the actual delete of up to `limit` rows to `deleteBatch`. Returns
2932
- * `{ deleted, done }`; `done: false` means the loop stopped on a bound or the
2933
- * abort signal and eligible rows may remain.
2934
- */
2935
- async function runBatchedDelete({ deleteBatch, batchSize, options }) {
2936
- if (!Number.isSafeInteger(batchSize) || batchSize <= 0) throw new Error(`retention batchSize must be a positive integer; received ${batchSize}`);
2937
- let deleted = 0;
2938
- let batches = 0;
2939
- while (true) {
2940
- if (options?.signal?.aborted) return {
2941
- deleted,
2942
- done: false
2943
- };
2944
- if (options?.maxBatches !== void 0 && batches >= options.maxBatches) return {
2945
- deleted,
2946
- done: false
2947
- };
2948
- let limit = batchSize;
2949
- if (options?.maxRows !== void 0) {
2950
- const remaining = options.maxRows - deleted;
2951
- if (remaining <= 0) return {
2952
- deleted,
2953
- done: false
2954
- };
2955
- limit = Math.min(limit, remaining);
2956
- }
2957
- const affected = await deleteBatch(limit);
2958
- deleted += affected;
2959
- batches += 1;
2960
- if (affected < limit) return {
2961
- deleted,
2962
- done: true
2963
- };
2964
- if (options?.pauseMs) await sleep(options.pauseMs, options.signal);
2965
- }
2966
- }
2967
- async function runPrune({ db, domain, targets, options, logger }) {
2968
- const results = [];
2969
- const now = Date.now();
2970
- for (const target of targets) {
2971
- if (options?.signal?.aborted) {
2972
- results.push({
2973
- domain,
2974
- table: target.table,
2975
- deleted: 0,
2976
- done: false
2977
- });
2978
- continue;
2979
- }
2980
- await ensureAnchorIndex(db, target, logger);
2981
- const cutoff = cutoffFor(target.policy, target.anchorType, now);
2982
- const { deleted, done } = await runBatchedDelete({
2983
- deleteBatch: (limit) => db.pruneBatch({
2984
- tableName: target.table,
2985
- column: target.column,
2986
- cutoff,
2987
- limit
2988
- }),
2989
- batchSize: target.policy.batchSize ?? DEFAULT_BATCH_SIZE,
2990
- options
2991
- });
2992
- results.push({
2993
- domain,
2994
- table: target.table,
2995
- deleted,
2996
- done
2997
- });
2998
- }
2999
- return results;
2891
+ const runBatchedDelete = runRetentionBatches;
2892
+ function runPrune({ db, domain, targets, options, logger }) {
2893
+ return executeRetentionPrune({
2894
+ domain,
2895
+ targets,
2896
+ options,
2897
+ beforeTarget: (target) => ensureAnchorIndex(db, target, logger),
2898
+ cutoffFor: (target, now) => cutoffFor(target.policy, target.anchorType ?? "timestamp", now),
2899
+ deleteBatch: (target, cutoff, limit) => db.pruneBatch({
2900
+ tableName: target.table,
2901
+ column: target.column,
2902
+ cutoff,
2903
+ limit
2904
+ })
2905
+ });
3000
2906
  }
3001
- /**
3002
- * Resolve a domain's `{ tableKey: policy }` map plus its descriptor into an
3003
- * ordered list of {@link PruneTarget}s. `order` lists table keys children-first
3004
- * so cascade-dependent rows are removed before their parents. Table keys not in
3005
- * `policies` are skipped (unset = keep forever).
3006
- */
3007
2907
  function resolveTargets({ policies, descriptor, order }) {
3008
- const targets = [];
3009
- for (const key of order) {
3010
- const policy = policies[key];
3011
- const entry = descriptor[key];
3012
- if (!policy || !entry) continue;
3013
- targets.push({
3014
- table: entry.table,
3015
- column: entry.column,
3016
- anchorType: entry.anchorType ?? "timestamp",
3017
- indexed: entry.indexed ?? true,
3018
- policy
3019
- });
3020
- }
3021
- return targets;
2908
+ return resolveRetentionTargets({
2909
+ policies,
2910
+ descriptor,
2911
+ order
2912
+ });
3022
2913
  }
3023
2914
  //#endregion
3024
2915
  //#region src/storage/domains/background-tasks/index.ts
@@ -14407,10 +14298,15 @@ var LibSQLFactoryStorageOps = class {
14407
14298
  const filter = this.#buildWhere(schema, where);
14408
14299
  const sql = `UPDATE "${schema.name}" SET ${columns.map((c) => `"${c}" = ?`).join(", ")} WHERE ${filter.sql}`;
14409
14300
  const args = [...columns.map((column) => this.#serialize(this.#column(schema, column), set[column])), ...filter.args];
14410
- return (await this.#client.execute({
14411
- sql,
14412
- args
14413
- })).rowsAffected;
14301
+ try {
14302
+ return (await this.#client.execute({
14303
+ sql,
14304
+ args
14305
+ })).rowsAffected;
14306
+ } catch (error) {
14307
+ if (isUniqueViolation(error)) throw new UniqueViolationError(collection, { cause: error });
14308
+ throw error;
14309
+ }
14414
14310
  }
14415
14311
  async updateMany(collection, where, set) {
14416
14312
  return this.#withWriteLock(() => this.#updateMany(collection, where, set));