@mastra/dynamodb 1.4.2 → 1.4.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.
@@ -3,7 +3,7 @@ name: mastra-dynamodb
3
3
  description: Documentation for @mastra/dynamodb. Use when working with @mastra/dynamodb APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/dynamodb"
6
- version: "1.4.2"
6
+ version: "1.4.3-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.4.2",
2
+ "version": "1.4.3-alpha.0",
3
3
  "package": "@mastra/dynamodb",
4
4
  "exports": {},
5
5
  "modules": {}
package/dist/index.cjs CHANGED
@@ -1687,9 +1687,52 @@ async function goWithRunFence(service, check, write) {
1687
1687
  await backoff(attempt);
1688
1688
  }
1689
1689
  }
1690
+ /**
1691
+ * Deletes up to `limit` items of a run claim entity whose epoch-ms `attribute`
1692
+ * is older than `cutoff`. These entities have no index on the anchor, so this
1693
+ * scans for them. Each delete repeats the cutoff as its condition, so an item
1694
+ * claimed or raised again since the scan is kept.
1695
+ */
1696
+ async function pruneRunClaims(service, entityName, attribute, cutoff, limit) {
1697
+ const entity = service.entities[entityName];
1698
+ const olderThanCutoff = (attr, op) => op.lt(attr[attribute], cutoff);
1699
+ let deleted = 0;
1700
+ let cursor = null;
1701
+ do {
1702
+ const page = await entity.scan.where(olderThanCutoff).go({
1703
+ cursor,
1704
+ limit: limit - deleted
1705
+ });
1706
+ for (const item of page.data) {
1707
+ try {
1708
+ await retryOnTransactionConflict(() => entity.delete({
1709
+ entity: entityName,
1710
+ run_id: item.run_id
1711
+ }).where(olderThanCutoff).go());
1712
+ deleted++;
1713
+ } catch (error) {
1714
+ if (!isConditionalCheckFailed(error)) throw error;
1715
+ }
1716
+ if (deleted >= limit) return deleted;
1717
+ }
1718
+ cursor = page.cursor;
1719
+ } while (cursor);
1720
+ return deleted;
1721
+ }
1690
1722
  //#endregion
1691
1723
  //#region src/storage/domains/memory/index.ts
1692
- var MemoryStorageDynamoDB = class extends _mastra_core_storage.MemoryStorage {
1724
+ var MemoryStorageDynamoDB = class MemoryStorageDynamoDB extends _mastra_core_storage.MemoryStorage {
1725
+ /**
1726
+ * Tables `prune()` can clean up. Run fences anchor on `retiredAt` (epoch ms), which stays unset until the
1727
+ * execution holding the fence settles, so a running execution's fence is
1728
+ * never pruned.
1729
+ */
1730
+ static retentionTables = { runFences: {
1731
+ table: _mastra_core_storage.TABLE_MEMORY_RUN_FENCES,
1732
+ column: "retiredAt",
1733
+ indexed: false,
1734
+ anchorType: "epoch-ms"
1735
+ } };
1693
1736
  supportsPartialThreadUpdate = true;
1694
1737
  service;
1695
1738
  ttlConfig;
@@ -1702,6 +1745,19 @@ var MemoryStorageDynamoDB = class extends _mastra_core_storage.MemoryStorage {
1702
1745
  supportsRunFencing() {
1703
1746
  return true;
1704
1747
  }
1748
+ async prune(policies, options) {
1749
+ return (0, _mastra_core_storage.executeRetentionPrune)({
1750
+ domain: "memory",
1751
+ targets: (0, _mastra_core_storage.resolveRetentionTargets)({
1752
+ policies,
1753
+ descriptor: MemoryStorageDynamoDB.retentionTables,
1754
+ order: ["runFences"]
1755
+ }),
1756
+ options,
1757
+ cutoffFor: (target, now) => (0, _mastra_core_storage.retentionCutoffMs)(target.policy, now),
1758
+ deleteBatch: (_target, cutoff, limit) => pruneRunClaims(this.service, "memory_run_fence", "retiredAt", Number(cutoff), limit)
1759
+ });
1760
+ }
1705
1761
  async dangerouslyClearAll() {
1706
1762
  await deleteTableData(this.service, _mastra_core_storage.TABLE_THREADS);
1707
1763
  await deleteTableData(this.service, _mastra_core_storage.TABLE_MESSAGES);
@@ -2833,7 +2889,18 @@ function toRunOwnershipRecord(item) {
2833
2889
  }
2834
2890
  const MAX_RETRIES = 5;
2835
2891
  const BASE_DELAY_MS = 50;
2836
- var WorkflowStorageDynamoDB = class extends _mastra_core_storage.WorkflowsStorage {
2892
+ var WorkflowStorageDynamoDB = class WorkflowStorageDynamoDB extends _mastra_core_storage.WorkflowsStorage {
2893
+ /**
2894
+ * Tables `prune()` can clean up. Run ownership records anchor on `updatedAt` (epoch ms), which every
2895
+ * claim, renewal and release refreshes, so a live execution's record is never
2896
+ * older than its renew interval.
2897
+ */
2898
+ static retentionTables = { runOwnership: {
2899
+ table: _mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS,
2900
+ column: "updatedAt",
2901
+ indexed: false,
2902
+ anchorType: "epoch-ms"
2903
+ } };
2837
2904
  service;
2838
2905
  ttlConfig;
2839
2906
  constructor(config) {
@@ -2848,6 +2915,19 @@ var WorkflowStorageDynamoDB = class extends _mastra_core_storage.WorkflowsStorag
2848
2915
  supportsRunFencing() {
2849
2916
  return true;
2850
2917
  }
2918
+ async prune(policies, options) {
2919
+ return (0, _mastra_core_storage.executeRetentionPrune)({
2920
+ domain: "workflows",
2921
+ targets: (0, _mastra_core_storage.resolveRetentionTargets)({
2922
+ policies,
2923
+ descriptor: WorkflowStorageDynamoDB.retentionTables,
2924
+ order: ["runOwnership"]
2925
+ }),
2926
+ options,
2927
+ cutoffFor: (target, now) => (0, _mastra_core_storage.retentionCutoffMs)(target.policy, now),
2928
+ deleteBatch: (_target, cutoff, limit) => pruneRunClaims(this.service, "workflow_run_owner", "updatedAt", Number(cutoff), limit)
2929
+ });
2930
+ }
2851
2931
  async dangerouslyClearAll() {
2852
2932
  await deleteTableData(this.service, _mastra_core_storage.TABLE_WORKFLOW_SNAPSHOT);
2853
2933
  await deleteTableData(this.service, _mastra_core_storage.TABLE_WORKFLOW_RUN_OWNERS);