@mastra/libsql 1.10.1-alpha.1 → 1.10.1-alpha.3

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
@@ -1171,29 +1171,33 @@ var LibSQLVector = class extends MastraVector {
1171
1171
  }
1172
1172
  };
1173
1173
  var safeStringify = (value) => {
1174
- const seen = /* @__PURE__ */ new WeakSet();
1174
+ const ancestors = /* @__PURE__ */ new Set();
1175
1175
  const sanitize = (val) => {
1176
1176
  if (val === null || val === void 0) return val;
1177
1177
  if (typeof val === "function") return void 0;
1178
1178
  if (typeof val === "symbol") return void 0;
1179
1179
  if (typeof val === "bigint") return val.toString();
1180
1180
  if (typeof val !== "object") return val;
1181
- if (seen.has(val)) return void 0;
1182
- seen.add(val);
1181
+ if (ancestors.has(val)) return void 0;
1183
1182
  if (typeof val.toJSON === "function") {
1184
1183
  return sanitize(val.toJSON());
1185
1184
  }
1186
- if (Array.isArray(val)) {
1187
- return val.map((item) => sanitize(item));
1188
- }
1189
- const result = {};
1190
- for (const key of Object.keys(val)) {
1191
- const sanitized = sanitize(val[key]);
1192
- if (sanitized !== void 0) {
1193
- result[key] = sanitized;
1185
+ ancestors.add(val);
1186
+ try {
1187
+ if (Array.isArray(val)) {
1188
+ return val.map((item) => sanitize(item));
1194
1189
  }
1190
+ const result = {};
1191
+ for (const key of Object.keys(val)) {
1192
+ const sanitized = sanitize(val[key]);
1193
+ if (sanitized !== void 0) {
1194
+ result[key] = sanitized;
1195
+ }
1196
+ }
1197
+ return result;
1198
+ } finally {
1199
+ ancestors.delete(val);
1195
1200
  }
1196
- return result;
1197
1201
  };
1198
1202
  return JSON.stringify(sanitize(value)) ?? "null";
1199
1203
  };
@@ -1928,15 +1932,21 @@ var LibSQLDB = class extends MastraBase {
1928
1932
  async migrateSpansTable() {
1929
1933
  const schema = TABLE_SCHEMAS[TABLE_SPANS];
1930
1934
  try {
1935
+ const existingColumnsRaw = await this.getTableColumns(TABLE_SPANS);
1936
+ const existingColumns = new Set([...existingColumnsRaw].map((column) => column.toLowerCase()));
1937
+ let addedColumns = false;
1931
1938
  for (const [columnName, columnDef] of Object.entries(schema)) {
1932
- const columnExists = await this.hasColumn(TABLE_SPANS, columnName);
1933
- if (!columnExists) {
1939
+ if (!existingColumns.has(columnName.toLowerCase())) {
1934
1940
  const sqlType = this.getSqlType(columnDef.type);
1935
1941
  const alterSql = `ALTER TABLE "${TABLE_SPANS}" ADD COLUMN "${columnName}" ${sqlType}`;
1936
1942
  await this.client.execute(alterSql);
1943
+ addedColumns = true;
1937
1944
  this.logger.debug(`LibSQLDB: Added column '${columnName}' to ${TABLE_SPANS}`);
1938
1945
  }
1939
1946
  }
1947
+ if (addedColumns) {
1948
+ this.tableColumnsCache.delete(TABLE_SPANS);
1949
+ }
1940
1950
  const indexExists = await this.spansUniqueIndexExists();
1941
1951
  if (!indexExists) {
1942
1952
  const duplicateInfo = await this.checkForDuplicateSpans();
@@ -3345,11 +3355,18 @@ var ChannelsLibSQL = class extends ChannelsStorage {
3345
3355
  tableName: TABLE_CHANNEL_CONFIG,
3346
3356
  schema: TABLE_SCHEMAS[TABLE_CHANNEL_CONFIG]
3347
3357
  });
3348
- await this.#client.execute(
3349
- `CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_installations_webhook ON "${TABLE_CHANNEL_INSTALLATIONS}" ("webhookId")`
3350
- );
3351
- await this.#client.execute(
3352
- `CREATE INDEX IF NOT EXISTS idx_channel_installations_platform_agent ON "${TABLE_CHANNEL_INSTALLATIONS}" ("platform", "agentId")`
3358
+ await this.#client.batch(
3359
+ [
3360
+ {
3361
+ sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_channel_installations_webhook ON "${TABLE_CHANNEL_INSTALLATIONS}" ("webhookId")`,
3362
+ args: []
3363
+ },
3364
+ {
3365
+ sql: `CREATE INDEX IF NOT EXISTS idx_channel_installations_platform_agent ON "${TABLE_CHANNEL_INSTALLATIONS}" ("platform", "agentId")`,
3366
+ args: []
3367
+ }
3368
+ ],
3369
+ "write"
3353
3370
  );
3354
3371
  }
3355
3372
  async dangerouslyClearAll() {
@@ -3493,26 +3510,31 @@ var DatasetsLibSQL = class extends DatasetsStorage {
3493
3510
  await this.#addColumnIfNotExists(TABLE_DATASET_ITEMS, "requestContext", "TEXT");
3494
3511
  await this.#addColumnIfNotExists(TABLE_DATASET_ITEMS, "source", "TEXT");
3495
3512
  await this.#addColumnIfNotExists(TABLE_DATASET_ITEMS, "expectedTrajectory", "TEXT");
3496
- await this.#client.execute({
3497
- sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto ON "${TABLE_DATASET_ITEMS}" ("datasetId", "validTo")`,
3498
- args: []
3499
- });
3500
- await this.#client.execute({
3501
- sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_version ON "${TABLE_DATASET_ITEMS}" ("datasetId", "datasetVersion")`,
3502
- args: []
3503
- });
3504
- await this.#client.execute({
3505
- sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto_deleted ON "${TABLE_DATASET_ITEMS}" ("datasetId", "validTo", "isDeleted")`,
3506
- args: []
3507
- });
3508
- await this.#client.execute({
3509
- sql: `CREATE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version ON "${TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
3510
- args: []
3511
- });
3512
- await this.#client.execute({
3513
- sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version_unique ON "${TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
3514
- args: []
3515
- });
3513
+ await this.#client.batch(
3514
+ [
3515
+ {
3516
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto ON "${TABLE_DATASET_ITEMS}" ("datasetId", "validTo")`,
3517
+ args: []
3518
+ },
3519
+ {
3520
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_version ON "${TABLE_DATASET_ITEMS}" ("datasetId", "datasetVersion")`,
3521
+ args: []
3522
+ },
3523
+ {
3524
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_items_dataset_validto_deleted ON "${TABLE_DATASET_ITEMS}" ("datasetId", "validTo", "isDeleted")`,
3525
+ args: []
3526
+ },
3527
+ {
3528
+ sql: `CREATE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version ON "${TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
3529
+ args: []
3530
+ },
3531
+ {
3532
+ sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_dataset_versions_dataset_version_unique ON "${TABLE_DATASET_VERSIONS}" ("datasetId", "version")`,
3533
+ args: []
3534
+ }
3535
+ ],
3536
+ "write"
3537
+ );
3516
3538
  }
3517
3539
  async #addColumnIfNotExists(table, column, sqlType) {
3518
3540
  const exists = await this.#db.hasColumn(table, column);
@@ -4413,18 +4435,23 @@ var ExperimentsLibSQL = class extends ExperimentsStorage {
4413
4435
  schema: EXPERIMENT_RESULTS_SCHEMA,
4414
4436
  ifNotExists: ["status", "tags"]
4415
4437
  });
4416
- await this.#client.execute({
4417
- sql: `CREATE INDEX IF NOT EXISTS idx_experiments_datasetid ON "${TABLE_EXPERIMENTS}" ("datasetId")`,
4418
- args: []
4419
- });
4420
- await this.#client.execute({
4421
- sql: `CREATE INDEX IF NOT EXISTS idx_experiment_results_experimentid ON "${TABLE_EXPERIMENT_RESULTS}" ("experimentId")`,
4422
- args: []
4423
- });
4424
- await this.#client.execute({
4425
- sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_experiment_results_exp_item ON "${TABLE_EXPERIMENT_RESULTS}" ("experimentId", "itemId")`,
4426
- args: []
4427
- });
4438
+ await this.#client.batch(
4439
+ [
4440
+ {
4441
+ sql: `CREATE INDEX IF NOT EXISTS idx_experiments_datasetid ON "${TABLE_EXPERIMENTS}" ("datasetId")`,
4442
+ args: []
4443
+ },
4444
+ {
4445
+ sql: `CREATE INDEX IF NOT EXISTS idx_experiment_results_experimentid ON "${TABLE_EXPERIMENT_RESULTS}" ("experimentId")`,
4446
+ args: []
4447
+ },
4448
+ {
4449
+ sql: `CREATE UNIQUE INDEX IF NOT EXISTS idx_experiment_results_exp_item ON "${TABLE_EXPERIMENT_RESULTS}" ("experimentId", "itemId")`,
4450
+ args: []
4451
+ }
4452
+ ],
4453
+ "write"
4454
+ );
4428
4455
  }
4429
4456
  async dangerouslyClearAll() {
4430
4457
  await this.#db.deleteData({ tableName: TABLE_EXPERIMENT_RESULTS });
@@ -5964,6 +5991,19 @@ var MemoryLibSQL = class extends MemoryStorage {
5964
5991
  schema: TABLE_SCHEMAS[TABLE_MESSAGES],
5965
5992
  ifNotExists: ["resourceId"]
5966
5993
  });
5994
+ await this.#client.batch(
5995
+ [
5996
+ {
5997
+ sql: `CREATE INDEX IF NOT EXISTS idx_messages_thread_created_at ON ${TABLE_MESSAGES} (thread_id, "createdAt")`,
5998
+ args: []
5999
+ },
6000
+ {
6001
+ sql: `CREATE INDEX IF NOT EXISTS idx_messages_thread_resource_created_at ON ${TABLE_MESSAGES} (thread_id, "resourceId", "createdAt")`,
6002
+ args: []
6003
+ }
6004
+ ],
6005
+ "write"
6006
+ );
5967
6007
  if (omSchema) {
5968
6008
  await this.#client.execute({
5969
6009
  sql: `CREATE INDEX IF NOT EXISTS idx_om_lookup_key ON "${OM_TABLE}" ("lookupKey")`,
@@ -6634,11 +6674,18 @@ var MemoryLibSQL = class extends MemoryStorage {
6634
6674
  });
6635
6675
  return updatedResource;
6636
6676
  }
6637
- async getThreadById({ threadId }) {
6677
+ async getThreadById({
6678
+ threadId,
6679
+ resourceId
6680
+ }) {
6638
6681
  try {
6682
+ const keys = { id: threadId };
6683
+ if (resourceId !== void 0) {
6684
+ keys.resourceId = resourceId;
6685
+ }
6639
6686
  const result = await this.#db.select({
6640
6687
  tableName: TABLE_THREADS,
6641
- keys: { id: threadId }
6688
+ keys
6642
6689
  });
6643
6690
  if (!result) {
6644
6691
  return null;
@@ -11390,10 +11437,15 @@ var WorkspacesLibSQL = class extends WorkspacesStorage {
11390
11437
  };
11391
11438
 
11392
11439
  // src/storage/index.ts
11440
+ var DEFAULT_LOCAL_CACHE_SIZE = -16e3;
11441
+ var DEFAULT_LOCAL_MMAP_SIZE = 134217728;
11393
11442
  var LibSQLStore = class extends MastraCompositeStore {
11394
11443
  client;
11395
11444
  maxRetries;
11396
11445
  initialBackoffMs;
11446
+ pragmasReady;
11447
+ isLocalDb;
11448
+ localPragmas;
11397
11449
  stores;
11398
11450
  constructor(config) {
11399
11451
  if (!config.id || typeof config.id !== "string" || config.id.trim() === "") {
@@ -11402,20 +11454,24 @@ var LibSQLStore = class extends MastraCompositeStore {
11402
11454
  super({ id: config.id, name: `LibSQLStore`, disableInit: config.disableInit });
11403
11455
  this.maxRetries = config.maxRetries ?? 5;
11404
11456
  this.initialBackoffMs = config.initialBackoffMs ?? 100;
11457
+ this.localPragmas = {
11458
+ cacheSize: config.localPragmas?.cacheSize ?? DEFAULT_LOCAL_CACHE_SIZE,
11459
+ mmapSize: config.localPragmas?.mmapSize ?? DEFAULT_LOCAL_MMAP_SIZE
11460
+ };
11405
11461
  if ("url" in config) {
11406
- if (config.url.endsWith(":memory:")) {
11462
+ if (config.url.includes(":memory:")) {
11407
11463
  this.shouldCacheInit = false;
11408
11464
  }
11409
11465
  this.client = createClient({
11410
11466
  url: config.url,
11411
11467
  ...config.authToken ? { authToken: config.authToken } : {}
11412
11468
  });
11413
- if (config.url.startsWith("file:") || config.url.includes(":memory:")) {
11414
- this.client.execute("PRAGMA journal_mode=WAL;").then(() => this.logger.debug("LibSQLStore: PRAGMA journal_mode=WAL set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA journal_mode=WAL.", err));
11415
- this.client.execute("PRAGMA busy_timeout = 5000;").then(() => this.logger.debug("LibSQLStore: PRAGMA busy_timeout=5000 set.")).catch((err) => this.logger.warn("LibSQLStore: Failed to set PRAGMA busy_timeout.", err));
11416
- }
11469
+ this.isLocalDb = config.url.startsWith("file:") || config.url.includes(":memory:");
11470
+ this.pragmasReady = this.isLocalDb ? this.applyLocalPragmas() : Promise.resolve();
11417
11471
  } else {
11418
11472
  this.client = config.client;
11473
+ this.isLocalDb = false;
11474
+ this.pragmasReady = Promise.resolve();
11419
11475
  }
11420
11476
  const domainConfig = {
11421
11477
  client: this.client,
@@ -11459,6 +11515,63 @@ var LibSQLStore = class extends MastraCompositeStore {
11459
11515
  schedules
11460
11516
  };
11461
11517
  }
11518
+ async applyLocalPragmas() {
11519
+ const pragmas = [
11520
+ ["journal_mode=WAL", "PRAGMA journal_mode=WAL;"],
11521
+ ["busy_timeout=5000", "PRAGMA busy_timeout=5000;"],
11522
+ ["synchronous=NORMAL", "PRAGMA synchronous=NORMAL;"],
11523
+ ["temp_store=MEMORY", "PRAGMA temp_store=MEMORY;"],
11524
+ [`cache_size=${this.localPragmas.cacheSize}`, `PRAGMA cache_size=${this.localPragmas.cacheSize};`],
11525
+ [`mmap_size=${this.localPragmas.mmapSize}`, `PRAGMA mmap_size=${this.localPragmas.mmapSize};`]
11526
+ ];
11527
+ for (const [label, sql] of pragmas) {
11528
+ try {
11529
+ await this.client.execute(sql);
11530
+ this.logger.debug(`LibSQLStore: PRAGMA ${label} set.`);
11531
+ } catch (err) {
11532
+ this.logger.warn(`LibSQLStore: Failed to set PRAGMA ${label}.`, err);
11533
+ }
11534
+ }
11535
+ }
11536
+ getStoresToInit() {
11537
+ return Object.values(this.stores).filter(Boolean);
11538
+ }
11539
+ async initDomainsSequentially() {
11540
+ for (const store of this.getStoresToInit()) {
11541
+ await store.init();
11542
+ }
11543
+ return true;
11544
+ }
11545
+ async initDomainsInParallel() {
11546
+ await Promise.all(this.getStoresToInit().map((store) => store.init()));
11547
+ return true;
11548
+ }
11549
+ async init() {
11550
+ await this.pragmasReady;
11551
+ if (!this.isLocalDb) {
11552
+ if (this.shouldCacheInit) {
11553
+ if (this.hasInitialized) {
11554
+ await this.hasInitialized;
11555
+ return;
11556
+ }
11557
+ this.hasInitialized = this.initDomainsInParallel();
11558
+ await this.hasInitialized;
11559
+ return;
11560
+ }
11561
+ await this.initDomainsInParallel();
11562
+ return;
11563
+ }
11564
+ if (this.shouldCacheInit) {
11565
+ if (this.hasInitialized) {
11566
+ await this.hasInitialized;
11567
+ return;
11568
+ }
11569
+ this.hasInitialized = this.initDomainsSequentially();
11570
+ await this.hasInitialized;
11571
+ return;
11572
+ }
11573
+ await this.initDomainsSequentially();
11574
+ }
11462
11575
  };
11463
11576
 
11464
11577
  // src/vector/prompt.ts