@mastra/libsql 1.12.0-alpha.0 → 1.12.1-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/dist/index.cjs CHANGED
@@ -6350,6 +6350,7 @@ var MemoryLibSQL = class extends storage.MemoryStorage {
6350
6350
  }
6351
6351
  }
6352
6352
  async dangerouslyClearAll() {
6353
+ await this.init();
6353
6354
  await this.#db.deleteData({ tableName: storage.TABLE_MESSAGES });
6354
6355
  await this.#db.deleteData({ tableName: storage.TABLE_THREADS });
6355
6356
  await this.#db.deleteData({ tableName: storage.TABLE_RESOURCES });
@@ -8355,6 +8356,294 @@ ${unreflectedContent}` : bufferedReflection;
8355
8356
  }
8356
8357
  }
8357
8358
  };
8359
+ var statusTimestamp = (status, now) => {
8360
+ if (status === "delivered") return { deliveredAt: now };
8361
+ if (status === "seen") return { seenAt: now };
8362
+ if (status === "dismissed") return { dismissedAt: now };
8363
+ if (status === "archived") return { archivedAt: now };
8364
+ if (status === "discarded") return { discardedAt: now };
8365
+ return {};
8366
+ };
8367
+ function parseJson2(value) {
8368
+ if (value == null) return void 0;
8369
+ if (typeof value === "string") {
8370
+ try {
8371
+ return JSON.parse(value);
8372
+ } catch {
8373
+ return value;
8374
+ }
8375
+ }
8376
+ return value;
8377
+ }
8378
+ function parseDate(value) {
8379
+ return value == null ? void 0 : new Date(String(value));
8380
+ }
8381
+ var cloneValue = (value) => value === void 0 ? void 0 : structuredClone(value);
8382
+ function rowToNotification(row) {
8383
+ return {
8384
+ id: String(row.id),
8385
+ threadId: String(row.threadId),
8386
+ source: String(row.source),
8387
+ kind: String(row.kind),
8388
+ priority: String(row.priority),
8389
+ status: String(row.status),
8390
+ summary: String(row.summary),
8391
+ payload: parseJson2(row.payload),
8392
+ resourceId: row.resourceId == null ? void 0 : String(row.resourceId),
8393
+ agentId: row.agentId == null ? void 0 : String(row.agentId),
8394
+ sourceId: row.sourceId == null ? void 0 : String(row.sourceId),
8395
+ dedupeKey: row.dedupeKey == null ? void 0 : String(row.dedupeKey),
8396
+ coalesceKey: row.coalesceKey == null ? void 0 : String(row.coalesceKey),
8397
+ coalescedCount: Number(row.coalescedCount ?? 1),
8398
+ attributes: parseJson2(row.attributes),
8399
+ createdAt: new Date(String(row.createdAt)),
8400
+ updatedAt: new Date(String(row.updatedAt)),
8401
+ deliveredAt: parseDate(row.deliveredAt),
8402
+ seenAt: parseDate(row.seenAt),
8403
+ dismissedAt: parseDate(row.dismissedAt),
8404
+ archivedAt: parseDate(row.archivedAt),
8405
+ discardedAt: parseDate(row.discardedAt),
8406
+ deliverAt: parseDate(row.deliverAt),
8407
+ summaryAt: parseDate(row.summaryAt),
8408
+ deliveryReason: row.deliveryReason == null ? void 0 : String(row.deliveryReason),
8409
+ deliveryAttempts: Number(row.deliveryAttempts ?? 0),
8410
+ lastDeliveryAttemptAt: parseDate(row.lastDeliveryAttemptAt),
8411
+ lastDeliveryError: row.lastDeliveryError == null ? void 0 : String(row.lastDeliveryError),
8412
+ deliveredSignalId: row.deliveredSignalId == null ? void 0 : String(row.deliveredSignalId),
8413
+ summarySignalId: row.summarySignalId == null ? void 0 : String(row.summarySignalId),
8414
+ metadata: parseJson2(row.metadata)
8415
+ };
8416
+ }
8417
+ function addArrayFilter(conditions, args, column, value) {
8418
+ if (!value) return;
8419
+ const values = Array.isArray(value) ? value : [value];
8420
+ conditions.push(`"${column}" IN (${values.map(() => "?").join(", ")})`);
8421
+ args.push(...values);
8422
+ }
8423
+ var NotificationsLibSQL = class extends storage.NotificationsStorage {
8424
+ #db;
8425
+ #client;
8426
+ constructor(config) {
8427
+ super();
8428
+ const client = resolveClient(config);
8429
+ this.#client = client;
8430
+ this.#db = new LibSQLDB({ client, maxRetries: config.maxRetries, initialBackoffMs: config.initialBackoffMs });
8431
+ }
8432
+ async init() {
8433
+ await this.#db.createTable({
8434
+ tableName: storage.TABLE_NOTIFICATIONS,
8435
+ schema: storage.TABLE_SCHEMAS[storage.TABLE_NOTIFICATIONS]
8436
+ });
8437
+ await this.#client.batch(
8438
+ [
8439
+ {
8440
+ sql: `CREATE INDEX IF NOT EXISTS idx_notifications_thread_status_updated ON "${storage.TABLE_NOTIFICATIONS}" ("threadId", "status", "updatedAt")`,
8441
+ args: []
8442
+ },
8443
+ {
8444
+ sql: `CREATE INDEX IF NOT EXISTS idx_notifications_coalescing ON "${storage.TABLE_NOTIFICATIONS}" ("threadId", "source", "kind", "status", "agentId", "resourceId", "dedupeKey", "coalesceKey")`,
8445
+ args: []
8446
+ },
8447
+ {
8448
+ sql: `CREATE INDEX IF NOT EXISTS idx_notifications_due ON "${storage.TABLE_NOTIFICATIONS}" ("status", "deliverAt", "summaryAt")`,
8449
+ args: []
8450
+ }
8451
+ ],
8452
+ "write"
8453
+ );
8454
+ }
8455
+ async dangerouslyClearAll() {
8456
+ await this.#db.deleteData({ tableName: storage.TABLE_NOTIFICATIONS });
8457
+ }
8458
+ async createNotification(input) {
8459
+ const existing = await this.findCoalescable(input);
8460
+ if (existing) {
8461
+ const now2 = /* @__PURE__ */ new Date();
8462
+ const attributes = input.attributes ? { ...cloneValue(existing.attributes), ...cloneValue(input.attributes) } : cloneValue(existing.attributes);
8463
+ const metadata = input.metadata ? { ...cloneValue(existing.metadata), ...cloneValue(input.metadata) } : cloneValue(existing.metadata);
8464
+ await this.#db.update({
8465
+ tableName: storage.TABLE_NOTIFICATIONS,
8466
+ keys: { threadId: existing.threadId, id: existing.id },
8467
+ data: {
8468
+ summary: input.summary,
8469
+ payload: cloneValue(input.payload ?? existing.payload) ?? null,
8470
+ priority: input.priority ?? existing.priority,
8471
+ attributes: attributes ?? null,
8472
+ updatedAt: now2,
8473
+ deliverAt: input.deliverAt ?? existing.deliverAt ?? null,
8474
+ summaryAt: input.summaryAt ?? existing.summaryAt ?? null,
8475
+ deliveryReason: input.deliveryReason ?? existing.deliveryReason ?? null,
8476
+ coalescedCount: (existing.coalescedCount ?? 1) + 1,
8477
+ metadata: metadata ?? null
8478
+ }
8479
+ });
8480
+ const updated = await this.getNotification({ threadId: existing.threadId, id: existing.id });
8481
+ if (!updated) throw new Error(`Notification ${existing.id} was not found for thread ${existing.threadId}`);
8482
+ return updated;
8483
+ }
8484
+ const now = input.createdAt ?? /* @__PURE__ */ new Date();
8485
+ const record = {
8486
+ id: input.id ?? crypto$1.randomUUID(),
8487
+ threadId: input.threadId,
8488
+ source: input.source,
8489
+ kind: input.kind,
8490
+ priority: input.priority ?? "medium",
8491
+ status: "pending",
8492
+ summary: input.summary,
8493
+ payload: cloneValue(input.payload),
8494
+ resourceId: input.resourceId,
8495
+ agentId: input.agentId,
8496
+ sourceId: input.sourceId,
8497
+ dedupeKey: input.dedupeKey,
8498
+ coalesceKey: input.coalesceKey,
8499
+ coalescedCount: 1,
8500
+ attributes: cloneValue(input.attributes),
8501
+ createdAt: now,
8502
+ updatedAt: now,
8503
+ deliverAt: input.deliverAt,
8504
+ summaryAt: input.summaryAt,
8505
+ deliveryReason: input.deliveryReason,
8506
+ deliveryAttempts: 0,
8507
+ metadata: cloneValue(input.metadata)
8508
+ };
8509
+ await this.#db.insert({
8510
+ tableName: storage.TABLE_NOTIFICATIONS,
8511
+ record: {
8512
+ ...record,
8513
+ payload: record.payload ?? null,
8514
+ attributes: record.attributes ?? null,
8515
+ metadata: record.metadata ?? null,
8516
+ resourceId: record.resourceId ?? null,
8517
+ agentId: record.agentId ?? null,
8518
+ sourceId: record.sourceId ?? null,
8519
+ dedupeKey: record.dedupeKey ?? null,
8520
+ coalesceKey: record.coalesceKey ?? null,
8521
+ deliverAt: record.deliverAt ?? null,
8522
+ summaryAt: record.summaryAt ?? null,
8523
+ deliveryReason: record.deliveryReason ?? null,
8524
+ deliveryAttempts: record.deliveryAttempts ?? 0
8525
+ }
8526
+ });
8527
+ return record;
8528
+ }
8529
+ async listNotifications(input) {
8530
+ const conditions = ['"threadId" = ?'];
8531
+ const args = [input.threadId];
8532
+ addArrayFilter(conditions, args, "status", input.status);
8533
+ addArrayFilter(conditions, args, "priority", input.priority);
8534
+ if (input.source) {
8535
+ conditions.push('"source" = ?');
8536
+ args.push(input.source);
8537
+ }
8538
+ if (input.resourceId) {
8539
+ conditions.push('"resourceId" = ?');
8540
+ args.push(input.resourceId);
8541
+ }
8542
+ if (input.agentId) {
8543
+ conditions.push('"agentId" = ?');
8544
+ args.push(input.agentId);
8545
+ }
8546
+ if (input.search) {
8547
+ conditions.push('(LOWER("summary") LIKE ? OR LOWER("kind") LIKE ?)');
8548
+ const search = `%${input.search.toLowerCase()}%`;
8549
+ args.push(search, search);
8550
+ }
8551
+ const limit = input.limit ? " LIMIT ?" : "";
8552
+ if (input.limit) args.push(input.limit);
8553
+ const result = await this.#client.execute({
8554
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_NOTIFICATIONS)} FROM "${storage.TABLE_NOTIFICATIONS}" WHERE ${conditions.join(" AND ")} ORDER BY "updatedAt" DESC${limit}`,
8555
+ args
8556
+ });
8557
+ return (result.rows ?? []).map((row) => rowToNotification(row));
8558
+ }
8559
+ async listDueNotifications(input) {
8560
+ const now = input.now.toISOString();
8561
+ const conditions = [
8562
+ '"status" = ?',
8563
+ '(("deliverAt" IS NOT NULL AND "deliverAt" <= ?) OR ("summaryAt" IS NOT NULL AND "summaryAt" <= ?))'
8564
+ ];
8565
+ const args = ["pending", now, now];
8566
+ if (input.agentId) {
8567
+ conditions.push('"agentId" = ?');
8568
+ args.push(input.agentId);
8569
+ }
8570
+ if (input.resourceId) {
8571
+ conditions.push('"resourceId" = ?');
8572
+ args.push(input.resourceId);
8573
+ }
8574
+ const limit = input.limit ? " LIMIT ?" : "";
8575
+ if (input.limit) args.push(input.limit);
8576
+ const result = await this.#client.execute({
8577
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_NOTIFICATIONS)} FROM "${storage.TABLE_NOTIFICATIONS}" WHERE ${conditions.join(" AND ")} ORDER BY CASE WHEN "deliverAt" IS NULL THEN "summaryAt" WHEN "summaryAt" IS NULL THEN "deliverAt" WHEN "deliverAt" <= "summaryAt" THEN "deliverAt" ELSE "summaryAt" END ASC, "updatedAt" ASC${limit}`,
8578
+ args
8579
+ });
8580
+ return (result.rows ?? []).map((row) => rowToNotification(row));
8581
+ }
8582
+ async getNotification(input) {
8583
+ const result = await this.#client.execute({
8584
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_NOTIFICATIONS)} FROM "${storage.TABLE_NOTIFICATIONS}" WHERE "threadId" = ? AND "id" = ? LIMIT 1`,
8585
+ args: [input.threadId, input.id]
8586
+ });
8587
+ const row = result.rows?.[0];
8588
+ return row ? rowToNotification(row) : null;
8589
+ }
8590
+ async updateNotification(input) {
8591
+ const existing = await this.getNotification({ threadId: input.threadId, id: input.id });
8592
+ if (!existing) {
8593
+ throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
8594
+ }
8595
+ const now = /* @__PURE__ */ new Date();
8596
+ await this.#db.update({
8597
+ tableName: storage.TABLE_NOTIFICATIONS,
8598
+ keys: { threadId: input.threadId, id: input.id },
8599
+ data: {
8600
+ ...input.status ? { status: input.status, ...statusTimestamp(input.status, now) } : {},
8601
+ ...input.summary !== void 0 ? { summary: input.summary } : {},
8602
+ ...input.payload !== void 0 ? { payload: cloneValue(input.payload) } : {},
8603
+ ...input.attributes !== void 0 ? { attributes: cloneValue(input.attributes) } : {},
8604
+ ...input.metadata !== void 0 ? { metadata: cloneValue(input.metadata) } : {},
8605
+ ...input.deliverAt !== void 0 ? { deliverAt: input.deliverAt } : {},
8606
+ ...input.summaryAt !== void 0 ? { summaryAt: input.summaryAt } : {},
8607
+ ...input.deliveryReason !== void 0 ? { deliveryReason: input.deliveryReason } : {},
8608
+ ...input.deliveryAttempts !== void 0 ? { deliveryAttempts: input.deliveryAttempts } : {},
8609
+ ...input.lastDeliveryAttemptAt !== void 0 ? { lastDeliveryAttemptAt: input.lastDeliveryAttemptAt } : {},
8610
+ ...input.lastDeliveryError !== void 0 ? { lastDeliveryError: input.lastDeliveryError } : {},
8611
+ ...input.deliveredSignalId !== void 0 ? { deliveredSignalId: input.deliveredSignalId } : {},
8612
+ ...input.summarySignalId !== void 0 ? { summarySignalId: input.summarySignalId } : {},
8613
+ updatedAt: now
8614
+ }
8615
+ });
8616
+ const updated = await this.getNotification({ threadId: input.threadId, id: input.id });
8617
+ if (!updated) throw new Error(`Notification ${input.id} was not found for thread ${input.threadId}`);
8618
+ return updated;
8619
+ }
8620
+ async findCoalescable(input) {
8621
+ if (!input.dedupeKey && !input.coalesceKey) return void 0;
8622
+ const agentId = input.agentId ?? null;
8623
+ const resourceId = input.resourceId ?? null;
8624
+ const dedupeKey = input.dedupeKey ?? null;
8625
+ const coalesceKey = input.coalesceKey ?? null;
8626
+ const result = await this.#client.execute({
8627
+ sql: `SELECT ${buildSelectColumns(storage.TABLE_NOTIFICATIONS)} FROM "${storage.TABLE_NOTIFICATIONS}" WHERE "threadId" = ? AND "source" = ? AND "kind" = ? AND "status" = ? AND (("agentId" = ?) OR ("agentId" IS NULL AND ? IS NULL)) AND (("resourceId" = ?) OR ("resourceId" IS NULL AND ? IS NULL)) AND ((? IS NOT NULL AND "dedupeKey" = ?) OR (? IS NOT NULL AND "coalesceKey" = ?)) ORDER BY "updatedAt" DESC LIMIT 1`,
8628
+ args: [
8629
+ input.threadId,
8630
+ input.source,
8631
+ input.kind,
8632
+ "pending",
8633
+ agentId,
8634
+ agentId,
8635
+ resourceId,
8636
+ resourceId,
8637
+ dedupeKey,
8638
+ dedupeKey,
8639
+ coalesceKey,
8640
+ coalesceKey
8641
+ ]
8642
+ });
8643
+ const row = result.rows?.[0];
8644
+ return row ? rowToNotification(row) : void 0;
8645
+ }
8646
+ };
8358
8647
  var ObservabilityLibSQL = class extends storage.ObservabilityStorage {
8359
8648
  #db;
8360
8649
  constructor(config) {
@@ -9327,7 +9616,7 @@ var PromptBlocksLibSQL = class extends storage.PromptBlocksStorage {
9327
9616
  };
9328
9617
  }
9329
9618
  };
9330
- function parseJson2(val) {
9619
+ function parseJson3(val) {
9331
9620
  if (val == null) return void 0;
9332
9621
  if (typeof val === "string") {
9333
9622
  try {
@@ -9343,7 +9632,7 @@ function toNumber(val) {
9343
9632
  return Number(val);
9344
9633
  }
9345
9634
  function rowToSchedule(row) {
9346
- const target = parseJson2(row.target);
9635
+ const target = parseJson3(row.target);
9347
9636
  if (!target) {
9348
9637
  throw new Error(`Schedule row ${row.id} has invalid target`);
9349
9638
  }
@@ -9359,7 +9648,7 @@ function rowToSchedule(row) {
9359
9648
  if (row.timezone != null) schedule.timezone = String(row.timezone);
9360
9649
  if (row.last_fire_at != null) schedule.lastFireAt = toNumber(row.last_fire_at);
9361
9650
  if (row.last_run_id != null) schedule.lastRunId = String(row.last_run_id);
9362
- const metadata = parseJson2(row.metadata);
9651
+ const metadata = parseJson3(row.metadata);
9363
9652
  if (metadata !== void 0) schedule.metadata = metadata;
9364
9653
  if (row.owner_type != null) schedule.ownerType = String(row.owner_type);
9365
9654
  if (row.owner_id != null) schedule.ownerId = String(row.owner_id);
@@ -9377,7 +9666,7 @@ function rowToTrigger(row) {
9377
9666
  };
9378
9667
  if (row.error != null) trigger.error = String(row.error);
9379
9668
  if (row.parent_trigger_id != null) trigger.parentTriggerId = String(row.parent_trigger_id);
9380
- const metadata = parseJson2(row.metadata);
9669
+ const metadata = parseJson3(row.metadata);
9381
9670
  if (metadata !== void 0) trigger.metadata = metadata;
9382
9671
  return trigger;
9383
9672
  }
@@ -12119,6 +12408,7 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
12119
12408
  const backgroundTasks = new BackgroundTasksLibSQL(domainConfig);
12120
12409
  const schedules = new SchedulesLibSQL(domainConfig);
12121
12410
  const toolProviderConnections = new ToolProviderConnectionsLibSQL(domainConfig);
12411
+ const notifications = new NotificationsLibSQL(domainConfig);
12122
12412
  this.stores = {
12123
12413
  scores,
12124
12414
  workflows,
@@ -12138,7 +12428,8 @@ var LibSQLStore = class extends storage.MastraCompositeStore {
12138
12428
  blobs,
12139
12429
  backgroundTasks,
12140
12430
  schedules,
12141
- toolProviderConnections
12431
+ toolProviderConnections,
12432
+ notifications
12142
12433
  };
12143
12434
  }
12144
12435
  async applyLocalPragmas() {
@@ -12341,6 +12632,7 @@ exports.LibSQLVector = LibSQLVector;
12341
12632
  exports.MCPClientsLibSQL = MCPClientsLibSQL;
12342
12633
  exports.MCPServersLibSQL = MCPServersLibSQL;
12343
12634
  exports.MemoryLibSQL = MemoryLibSQL;
12635
+ exports.NotificationsLibSQL = NotificationsLibSQL;
12344
12636
  exports.ObservabilityLibSQL = ObservabilityLibSQL;
12345
12637
  exports.PromptBlocksLibSQL = PromptBlocksLibSQL;
12346
12638
  exports.SchedulesLibSQL = SchedulesLibSQL;