@mastra/loggers 1.3.7 → 1.3.8-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-loggers
3
3
  description: Documentation for @mastra/loggers. Use when working with @mastra/loggers APIs, configuration, or implementation.
4
4
  metadata:
5
5
  package: "@mastra/loggers"
6
- version: "1.3.7"
6
+ version: "1.3.8-alpha.0"
7
7
  ---
8
8
 
9
9
  ## When to use
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.3.7",
2
+ "version": "1.3.8-alpha.0",
3
3
  "package": "@mastra/loggers",
4
4
  "exports": {},
5
5
  "modules": {}
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_pagination = require("../pagination-D4VAcPxN.cjs");
2
3
  let _mastra_core_logger = require("@mastra/core/logger");
3
4
  let fs = require("fs");
4
5
  let readline = require("readline");
@@ -47,6 +48,7 @@ var FileTransport = class extends _mastra_core_logger.LoggerTransport {
47
48
  callback(error);
48
49
  }
49
50
  async listLogs(params) {
51
+ require_pagination.normalizePagination(params?.page, params?.perPage);
50
52
  try {
51
53
  return await this.#queryLogs(params || {});
52
54
  } catch (error) {
@@ -59,6 +61,7 @@ var FileTransport = class extends _mastra_core_logger.LoggerTransport {
59
61
  }
60
62
  }
61
63
  async listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) {
64
+ require_pagination.normalizePagination(page, perPage);
62
65
  try {
63
66
  return await this.#queryLogs({
64
67
  runId,
@@ -86,10 +89,7 @@ var FileTransport = class extends _mastra_core_logger.LoggerTransport {
86
89
  * retaining only the requested page (or all matches when pagination is off).
87
90
  */
88
91
  async #queryLogs({ runId, fromDate, toDate, logLevel, filters, returnPaginationResults = true, page: pageInput, perPage: perPageInput }) {
89
- const page = pageInput === 0 ? 1 : pageInput ?? 1;
90
- const perPage = (perPageInput ?? 100) || 100;
91
- const start = (page - 1) * perPage;
92
- const end = start + perPage;
92
+ const { page, perPage, start, end } = require_pagination.normalizePagination(pageInput, perPageInput);
93
93
  const filterEntries = Object.entries(filters ?? {});
94
94
  const logs = [];
95
95
  let total = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["LoggerTransport","#queryLogs","MastraError","ErrorDomain","ErrorCategory"],"sources":["../../src/file/index.ts"],"sourcesContent":["import type { WriteStream } from 'node:fs';\nimport { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class FileTransport extends LoggerTransport {\n path: string;\n fileStream: WriteStream;\n constructor({ path }: { path: string }) {\n super({ objectMode: true });\n this.path = path;\n\n if (!existsSync(this.path)) {\n throw new Error('File path does not exist');\n }\n\n if (!statSync(this.path).isFile()) {\n throw new Error(`File path must point to a file: ${this.path}`);\n }\n\n this.fileStream = createWriteStream(this.path, { flags: 'a' });\n // Without a listener, the file stream's 'error' event would crash the process.\n // Write failures already reach the transport through the write callback, so only\n // forward errors that have not destroyed the transport yet (e.g. open failures).\n this.fileStream.on('error', error => {\n if (!this.destroyed) this.destroy(error);\n });\n }\n\n _transform(chunk: any, _encoding: string, callback: (error: Error | null, chunk?: any) => void) {\n try {\n this.fileStream.write(chunk, error => {\n if (error) callback(error);\n else callback(null, chunk);\n });\n } catch (error) {\n callback(error as Error);\n }\n }\n\n _flush(callback: Function) {\n // End the file stream when transform stream ends\n this.fileStream.end(() => {\n callback();\n });\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n // Clean up resources\n _destroy(error: Error, callback: Function) {\n if (this.fileStream) {\n this.fileStream.destroy(error);\n }\n callback(error);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n return await this.#queryLogs(params || {});\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path },\n },\n error,\n );\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n return await this.#queryLogs({ runId, fromDate, toDate, logLevel, filters, page, perPage });\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_BY_RUN_ID_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path, runId },\n },\n error,\n );\n }\n }\n\n /**\n * Streams the log file line by line, counting every matching record but\n * retaining only the requested page (or all matches when pagination is off).\n */\n async #queryLogs({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults = true,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId?: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }) {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = (perPageInput ?? 100) || 100;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const filterEntries = Object.entries(filters ?? {});\n\n const logs: BaseLogMessage[] = [];\n let total = 0;\n\n const lines = createInterface({ input: createReadStream(this.path, 'utf8'), crlfDelay: Infinity });\n for await (const line of lines) {\n if (!line.trim()) continue;\n\n let log: any;\n try {\n log = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (log === null || typeof log !== 'object') continue;\n if (runId !== undefined && log.runId !== runId) continue;\n if (!filterEntries.every(([key, value]) => log[key] === value)) continue;\n if (logLevel && log.level !== logLevel) continue;\n if (fromDate && !(new Date(log.time).getTime() >= fromDate.getTime())) continue;\n if (toDate && !(new Date(log.time).getTime() <= toDate.getTime())) continue;\n\n if (!returnPaginationResults || (total >= start && total < end)) {\n logs.push(log);\n }\n total++;\n }\n\n if (!returnPaginationResults) {\n return { logs, total, page, perPage: total, hasMore: false };\n }\n\n return { logs, total, page, perPage, hasMore: end < total };\n }\n}\n"],"mappings":";;;;;;AAOA,IAAa,gBAAb,cAAmCA,oBAAAA,gBAAgB;CACjD;CACA;CACA,YAAY,EAAE,QAA0B;EACtC,MAAM,EAAE,YAAY,KAAK,CAAC;EAC1B,KAAK,OAAO;EAEZ,IAAI,EAAA,GAAA,GAAA,WAAA,CAAY,KAAK,IAAI,GACvB,MAAM,IAAI,MAAM,0BAA0B;EAG5C,IAAI,EAAA,GAAA,GAAA,SAAA,CAAU,KAAK,IAAI,CAAC,CAAC,OAAO,GAC9B,MAAM,IAAI,MAAM,mCAAmC,KAAK,MAAM;EAGhE,KAAK,cAAA,GAAA,GAAA,kBAAA,CAA+B,KAAK,MAAM,EAAE,OAAO,IAAI,CAAC;EAI7D,KAAK,WAAW,GAAG,UAAS,UAAS;GACnC,IAAI,CAAC,KAAK,WAAW,KAAK,QAAQ,KAAK;EACzC,CAAC;CACH;CAEA,WAAW,OAAY,WAAmB,UAAsD;EAC9F,IAAI;GACF,KAAK,WAAW,MAAM,QAAO,UAAS;IACpC,IAAI,OAAO,SAAS,KAAK;SACpB,SAAS,MAAM,KAAK;GAC3B,CAAC;EACH,SAAS,OAAO;GACd,SAAS,KAAc;EACzB;CACF;CAEA,OAAO,UAAoB;EAEzB,KAAK,WAAW,UAAU;GACxB,SAAS;EACX,CAAC;CACH;CAEA,OAAO,OAAY,UAAmB,UAAoD;EACxF,IAAI,OAAO,aAAa,YAAY;GAClC,KAAK,WAAW,OAAO,YAAY,QAAQ,QAAQ;GACnD,OAAO;EACT;EAEA,KAAK,WAAW,OAAO,YAAY,SAAS,UAAwB;GAClE,IAAI,OAAO,QAAQ,MAAM,6BAA6B,KAAK;EAC7D,CAAC;EACD,OAAO;CACT;CAGA,SAAS,OAAc,UAAoB;EACzC,IAAI,KAAK,YACP,KAAK,WAAW,QAAQ,KAAK;EAE/B,SAAS,KAAK;CAChB;CAEA,MAAM,SAAS,QAcZ;EACD,IAAI;GACF,OAAO,MAAM,KAAKC,WAAW,UAAU,CAAC,CAAC;EAC3C,SAAS,OAAO;GACd,MAAM,IAAIC,mBAAAA,YACR;IACE,IAAI;IACJ,QAAQC,mBAAAA,YAAY;IACpB,UAAUC,mBAAAA,cAAc;IACxB,SAAS,EAAE,MAAM,KAAK,KAAK;GAC7B,GACA,KACF;EACF;CACF;CAEA,MAAM,gBAAgB,EACpB,OACA,UACA,QACA,UACA,SACA,MACA,WAeC;EACD,IAAI;GACF,OAAO,MAAM,KAAKH,WAAW;IAAE;IAAO;IAAU;IAAQ;IAAU;IAAS;IAAM;GAAQ,CAAC;EAC5F,SAAS,OAAO;GACd,MAAM,IAAIC,mBAAAA,YACR;IACE,IAAI;IACJ,QAAQC,mBAAAA,YAAY;IACpB,UAAUC,mBAAAA,cAAc;IACxB,SAAS;KAAE,MAAM,KAAK;KAAM;IAAM;GACpC,GACA,KACF;EACF;CACF;;;;;CAMA,MAAMH,WAAW,EACf,OACA,UACA,QACA,UACA,SACA,0BAA0B,MAC1B,MAAM,WACN,SAAS,gBAUR;EACD,MAAM,OAAO,cAAc,IAAI,IAAK,aAAa;EACjD,MAAM,WAAW,gBAAgB,QAAQ;EACzC,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,MAAM,QAAQ;EACpB,MAAM,gBAAgB,OAAO,QAAQ,WAAW,CAAC,CAAC;EAElD,MAAM,OAAyB,CAAC;EAChC,IAAI,QAAQ;EAEZ,MAAM,SAAA,GAAA,SAAA,gBAAA,CAAwB;GAAE,QAAA,GAAA,GAAA,iBAAA,CAAwB,KAAK,MAAM,MAAM;GAAG,WAAW;EAAS,CAAC;EACjG,WAAW,MAAM,QAAQ,OAAO;GAC9B,IAAI,CAAC,KAAK,KAAK,GAAG;GAElB,IAAI;GACJ,IAAI;IACF,MAAM,KAAK,MAAM,IAAI;GACvB,QAAQ;IACN;GACF;GAEA,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;GAC7C,IAAI,UAAU,KAAA,KAAa,IAAI,UAAU,OAAO;GAChD,IAAI,CAAC,cAAc,OAAO,CAAC,KAAK,WAAW,IAAI,SAAS,KAAK,GAAG;GAChE,IAAI,YAAY,IAAI,UAAU,UAAU;GACxC,IAAI,YAAY,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,QAAQ,IAAI;GACvE,IAAI,UAAU,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,QAAQ,IAAI;GAEnE,IAAI,CAAC,2BAA4B,SAAS,SAAS,QAAQ,KACzD,KAAK,KAAK,GAAG;GAEf;EACF;EAEA,IAAI,CAAC,yBACH,OAAO;GAAE;GAAM;GAAO;GAAM,SAAS;GAAO,SAAS;EAAM;EAG7D,OAAO;GAAE;GAAM;GAAO;GAAM;GAAS,SAAS,MAAM;EAAM;CAC5D;AACF"}
1
+ {"version":3,"file":"index.cjs","names":["LoggerTransport","#queryLogs","MastraError","ErrorDomain","ErrorCategory","normalizePagination"],"sources":["../../src/file/index.ts"],"sourcesContent":["import type { WriteStream } from 'node:fs';\nimport { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\nimport { normalizePagination } from '../pagination';\n\nexport class FileTransport extends LoggerTransport {\n path: string;\n fileStream: WriteStream;\n constructor({ path }: { path: string }) {\n super({ objectMode: true });\n this.path = path;\n\n if (!existsSync(this.path)) {\n throw new Error('File path does not exist');\n }\n\n if (!statSync(this.path).isFile()) {\n throw new Error(`File path must point to a file: ${this.path}`);\n }\n\n this.fileStream = createWriteStream(this.path, { flags: 'a' });\n // Without a listener, the file stream's 'error' event would crash the process.\n // Write failures already reach the transport through the write callback, so only\n // forward errors that have not destroyed the transport yet (e.g. open failures).\n this.fileStream.on('error', error => {\n if (!this.destroyed) this.destroy(error);\n });\n }\n\n _transform(chunk: any, _encoding: string, callback: (error: Error | null, chunk?: any) => void) {\n try {\n this.fileStream.write(chunk, error => {\n if (error) callback(error);\n else callback(null, chunk);\n });\n } catch (error) {\n callback(error as Error);\n }\n }\n\n _flush(callback: Function) {\n // End the file stream when transform stream ends\n this.fileStream.end(() => {\n callback();\n });\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n // Clean up resources\n _destroy(error: Error, callback: Function) {\n if (this.fileStream) {\n this.fileStream.destroy(error);\n }\n callback(error);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n normalizePagination(params?.page, params?.perPage);\n try {\n return await this.#queryLogs(params || {});\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path },\n },\n error,\n );\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n normalizePagination(page, perPage);\n try {\n return await this.#queryLogs({ runId, fromDate, toDate, logLevel, filters, page, perPage });\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_BY_RUN_ID_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path, runId },\n },\n error,\n );\n }\n }\n\n /**\n * Streams the log file line by line, counting every matching record but\n * retaining only the requested page (or all matches when pagination is off).\n */\n async #queryLogs({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults = true,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId?: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }) {\n const { page, perPage, start, end } = normalizePagination(pageInput, perPageInput);\n const filterEntries = Object.entries(filters ?? {});\n\n const logs: BaseLogMessage[] = [];\n let total = 0;\n\n const lines = createInterface({ input: createReadStream(this.path, 'utf8'), crlfDelay: Infinity });\n for await (const line of lines) {\n if (!line.trim()) continue;\n\n let log: any;\n try {\n log = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (log === null || typeof log !== 'object') continue;\n if (runId !== undefined && log.runId !== runId) continue;\n if (!filterEntries.every(([key, value]) => log[key] === value)) continue;\n if (logLevel && log.level !== logLevel) continue;\n if (fromDate && !(new Date(log.time).getTime() >= fromDate.getTime())) continue;\n if (toDate && !(new Date(log.time).getTime() <= toDate.getTime())) continue;\n\n if (!returnPaginationResults || (total >= start && total < end)) {\n logs.push(log);\n }\n total++;\n }\n\n if (!returnPaginationResults) {\n return { logs, total, page, perPage: total, hasMore: false };\n }\n\n return { logs, total, page, perPage, hasMore: end < total };\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpE,qBAAa,aAAc,SAAQ,eAAe;;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,WAAW,CAAC;IACxB,YAAY,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAmBrC;IAED,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,QAS7F;IAED,MAAM,CAAC,QAAQ,EAAE,QAAQ,QAKxB;IAED,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAUxF;IAGD,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,QAKxC;IAEK,QAAQ,CAAC,MAAM,CAAC,EAAE;QACtB,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAClC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAcD;IAEK,eAAe,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,OAAO,GACR,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAcD;CAgEF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/file/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAI3C,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpE,qBAAa,aAAc,SAAQ,eAAe;;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,WAAW,CAAC;IACxB,YAAY,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,EAmBrC;IAED,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,IAAI,QAS7F;IAED,MAAM,CAAC,QAAQ,EAAE,QAAQ,QAKxB;IAED,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAUxF;IAGD,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,QAKxC;IAEK,QAAQ,CAAC,MAAM,CAAC,EAAE;QACtB,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAClC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAeD;IAEK,eAAe,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,EACJ,OAAO,GACR,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAeD;CA6DF"}
@@ -1,3 +1,4 @@
1
+ import { t as normalizePagination } from "../pagination-BfSC4BZ-.js";
1
2
  import { LoggerTransport } from "@mastra/core/logger";
2
3
  import { createReadStream, createWriteStream, existsSync, statSync } from "fs";
3
4
  import { createInterface } from "readline";
@@ -46,6 +47,7 @@ var FileTransport = class extends LoggerTransport {
46
47
  callback(error);
47
48
  }
48
49
  async listLogs(params) {
50
+ normalizePagination(params?.page, params?.perPage);
49
51
  try {
50
52
  return await this.#queryLogs(params || {});
51
53
  } catch (error) {
@@ -58,6 +60,7 @@ var FileTransport = class extends LoggerTransport {
58
60
  }
59
61
  }
60
62
  async listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page, perPage }) {
63
+ normalizePagination(page, perPage);
61
64
  try {
62
65
  return await this.#queryLogs({
63
66
  runId,
@@ -85,10 +88,7 @@ var FileTransport = class extends LoggerTransport {
85
88
  * retaining only the requested page (or all matches when pagination is off).
86
89
  */
87
90
  async #queryLogs({ runId, fromDate, toDate, logLevel, filters, returnPaginationResults = true, page: pageInput, perPage: perPageInput }) {
88
- const page = pageInput === 0 ? 1 : pageInput ?? 1;
89
- const perPage = (perPageInput ?? 100) || 100;
90
- const start = (page - 1) * perPage;
91
- const end = start + perPage;
91
+ const { page, perPage, start, end } = normalizePagination(pageInput, perPageInput);
92
92
  const filterEntries = Object.entries(filters ?? {});
93
93
  const logs = [];
94
94
  let total = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["#queryLogs"],"sources":["../../src/file/index.ts"],"sourcesContent":["import type { WriteStream } from 'node:fs';\nimport { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class FileTransport extends LoggerTransport {\n path: string;\n fileStream: WriteStream;\n constructor({ path }: { path: string }) {\n super({ objectMode: true });\n this.path = path;\n\n if (!existsSync(this.path)) {\n throw new Error('File path does not exist');\n }\n\n if (!statSync(this.path).isFile()) {\n throw new Error(`File path must point to a file: ${this.path}`);\n }\n\n this.fileStream = createWriteStream(this.path, { flags: 'a' });\n // Without a listener, the file stream's 'error' event would crash the process.\n // Write failures already reach the transport through the write callback, so only\n // forward errors that have not destroyed the transport yet (e.g. open failures).\n this.fileStream.on('error', error => {\n if (!this.destroyed) this.destroy(error);\n });\n }\n\n _transform(chunk: any, _encoding: string, callback: (error: Error | null, chunk?: any) => void) {\n try {\n this.fileStream.write(chunk, error => {\n if (error) callback(error);\n else callback(null, chunk);\n });\n } catch (error) {\n callback(error as Error);\n }\n }\n\n _flush(callback: Function) {\n // End the file stream when transform stream ends\n this.fileStream.end(() => {\n callback();\n });\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n // Clean up resources\n _destroy(error: Error, callback: Function) {\n if (this.fileStream) {\n this.fileStream.destroy(error);\n }\n callback(error);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n return await this.#queryLogs(params || {});\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path },\n },\n error,\n );\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n return await this.#queryLogs({ runId, fromDate, toDate, logLevel, filters, page, perPage });\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_BY_RUN_ID_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path, runId },\n },\n error,\n );\n }\n }\n\n /**\n * Streams the log file line by line, counting every matching record but\n * retaining only the requested page (or all matches when pagination is off).\n */\n async #queryLogs({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults = true,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId?: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }) {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = (perPageInput ?? 100) || 100;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const filterEntries = Object.entries(filters ?? {});\n\n const logs: BaseLogMessage[] = [];\n let total = 0;\n\n const lines = createInterface({ input: createReadStream(this.path, 'utf8'), crlfDelay: Infinity });\n for await (const line of lines) {\n if (!line.trim()) continue;\n\n let log: any;\n try {\n log = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (log === null || typeof log !== 'object') continue;\n if (runId !== undefined && log.runId !== runId) continue;\n if (!filterEntries.every(([key, value]) => log[key] === value)) continue;\n if (logLevel && log.level !== logLevel) continue;\n if (fromDate && !(new Date(log.time).getTime() >= fromDate.getTime())) continue;\n if (toDate && !(new Date(log.time).getTime() <= toDate.getTime())) continue;\n\n if (!returnPaginationResults || (total >= start && total < end)) {\n logs.push(log);\n }\n total++;\n }\n\n if (!returnPaginationResults) {\n return { logs, total, page, perPage: total, hasMore: false };\n }\n\n return { logs, total, page, perPage, hasMore: end < total };\n }\n}\n"],"mappings":";;;;;AAOA,IAAa,gBAAb,cAAmC,gBAAgB;CACjD;CACA;CACA,YAAY,EAAE,QAA0B;EACtC,MAAM,EAAE,YAAY,KAAK,CAAC;EAC1B,KAAK,OAAO;EAEZ,IAAI,CAAC,WAAW,KAAK,IAAI,GACvB,MAAM,IAAI,MAAM,0BAA0B;EAG5C,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC,OAAO,GAC9B,MAAM,IAAI,MAAM,mCAAmC,KAAK,MAAM;EAGhE,KAAK,aAAa,kBAAkB,KAAK,MAAM,EAAE,OAAO,IAAI,CAAC;EAI7D,KAAK,WAAW,GAAG,UAAS,UAAS;GACnC,IAAI,CAAC,KAAK,WAAW,KAAK,QAAQ,KAAK;EACzC,CAAC;CACH;CAEA,WAAW,OAAY,WAAmB,UAAsD;EAC9F,IAAI;GACF,KAAK,WAAW,MAAM,QAAO,UAAS;IACpC,IAAI,OAAO,SAAS,KAAK;SACpB,SAAS,MAAM,KAAK;GAC3B,CAAC;EACH,SAAS,OAAO;GACd,SAAS,KAAc;EACzB;CACF;CAEA,OAAO,UAAoB;EAEzB,KAAK,WAAW,UAAU;GACxB,SAAS;EACX,CAAC;CACH;CAEA,OAAO,OAAY,UAAmB,UAAoD;EACxF,IAAI,OAAO,aAAa,YAAY;GAClC,KAAK,WAAW,OAAO,YAAY,QAAQ,QAAQ;GACnD,OAAO;EACT;EAEA,KAAK,WAAW,OAAO,YAAY,SAAS,UAAwB;GAClE,IAAI,OAAO,QAAQ,MAAM,6BAA6B,KAAK;EAC7D,CAAC;EACD,OAAO;CACT;CAGA,SAAS,OAAc,UAAoB;EACzC,IAAI,KAAK,YACP,KAAK,WAAW,QAAQ,KAAK;EAE/B,SAAS,KAAK;CAChB;CAEA,MAAM,SAAS,QAcZ;EACD,IAAI;GACF,OAAO,MAAM,KAAKA,WAAW,UAAU,CAAC,CAAC;EAC3C,SAAS,OAAO;GACd,MAAM,IAAI,YACR;IACE,IAAI;IACJ,QAAQ,YAAY;IACpB,UAAU,cAAc;IACxB,SAAS,EAAE,MAAM,KAAK,KAAK;GAC7B,GACA,KACF;EACF;CACF;CAEA,MAAM,gBAAgB,EACpB,OACA,UACA,QACA,UACA,SACA,MACA,WAeC;EACD,IAAI;GACF,OAAO,MAAM,KAAKA,WAAW;IAAE;IAAO;IAAU;IAAQ;IAAU;IAAS;IAAM;GAAQ,CAAC;EAC5F,SAAS,OAAO;GACd,MAAM,IAAI,YACR;IACE,IAAI;IACJ,QAAQ,YAAY;IACpB,UAAU,cAAc;IACxB,SAAS;KAAE,MAAM,KAAK;KAAM;IAAM;GACpC,GACA,KACF;EACF;CACF;;;;;CAMA,MAAMA,WAAW,EACf,OACA,UACA,QACA,UACA,SACA,0BAA0B,MAC1B,MAAM,WACN,SAAS,gBAUR;EACD,MAAM,OAAO,cAAc,IAAI,IAAK,aAAa;EACjD,MAAM,WAAW,gBAAgB,QAAQ;EACzC,MAAM,SAAS,OAAO,KAAK;EAC3B,MAAM,MAAM,QAAQ;EACpB,MAAM,gBAAgB,OAAO,QAAQ,WAAW,CAAC,CAAC;EAElD,MAAM,OAAyB,CAAC;EAChC,IAAI,QAAQ;EAEZ,MAAM,QAAQ,gBAAgB;GAAE,OAAO,iBAAiB,KAAK,MAAM,MAAM;GAAG,WAAW;EAAS,CAAC;EACjG,WAAW,MAAM,QAAQ,OAAO;GAC9B,IAAI,CAAC,KAAK,KAAK,GAAG;GAElB,IAAI;GACJ,IAAI;IACF,MAAM,KAAK,MAAM,IAAI;GACvB,QAAQ;IACN;GACF;GAEA,IAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;GAC7C,IAAI,UAAU,KAAA,KAAa,IAAI,UAAU,OAAO;GAChD,IAAI,CAAC,cAAc,OAAO,CAAC,KAAK,WAAW,IAAI,SAAS,KAAK,GAAG;GAChE,IAAI,YAAY,IAAI,UAAU,UAAU;GACxC,IAAI,YAAY,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS,QAAQ,IAAI;GACvE,IAAI,UAAU,EAAE,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ,KAAK,OAAO,QAAQ,IAAI;GAEnE,IAAI,CAAC,2BAA4B,SAAS,SAAS,QAAQ,KACzD,KAAK,KAAK,GAAG;GAEf;EACF;EAEA,IAAI,CAAC,yBACH,OAAO;GAAE;GAAM;GAAO;GAAM,SAAS;GAAO,SAAS;EAAM;EAG7D,OAAO;GAAE;GAAM;GAAO;GAAM;GAAS,SAAS,MAAM;EAAM;CAC5D;AACF"}
1
+ {"version":3,"file":"index.js","names":["#queryLogs"],"sources":["../../src/file/index.ts"],"sourcesContent":["import type { WriteStream } from 'node:fs';\nimport { createReadStream, createWriteStream, existsSync, statSync } from 'node:fs';\nimport { createInterface } from 'node:readline';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\nimport { normalizePagination } from '../pagination';\n\nexport class FileTransport extends LoggerTransport {\n path: string;\n fileStream: WriteStream;\n constructor({ path }: { path: string }) {\n super({ objectMode: true });\n this.path = path;\n\n if (!existsSync(this.path)) {\n throw new Error('File path does not exist');\n }\n\n if (!statSync(this.path).isFile()) {\n throw new Error(`File path must point to a file: ${this.path}`);\n }\n\n this.fileStream = createWriteStream(this.path, { flags: 'a' });\n // Without a listener, the file stream's 'error' event would crash the process.\n // Write failures already reach the transport through the write callback, so only\n // forward errors that have not destroyed the transport yet (e.g. open failures).\n this.fileStream.on('error', error => {\n if (!this.destroyed) this.destroy(error);\n });\n }\n\n _transform(chunk: any, _encoding: string, callback: (error: Error | null, chunk?: any) => void) {\n try {\n this.fileStream.write(chunk, error => {\n if (error) callback(error);\n else callback(null, chunk);\n });\n } catch (error) {\n callback(error as Error);\n }\n }\n\n _flush(callback: Function) {\n // End the file stream when transform stream ends\n this.fileStream.end(() => {\n callback();\n });\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n // Clean up resources\n _destroy(error: Error, callback: Function) {\n if (this.fileStream) {\n this.fileStream.destroy(error);\n }\n callback(error);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n normalizePagination(params?.page, params?.perPage);\n try {\n return await this.#queryLogs(params || {});\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path },\n },\n error,\n );\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n normalizePagination(page, perPage);\n try {\n return await this.#queryLogs({ runId, fromDate, toDate, logLevel, filters, page, perPage });\n } catch (error) {\n throw new MastraError(\n {\n id: 'FILE_TRANSPORT_LIST_LOGS_BY_RUN_ID_FAILED',\n domain: ErrorDomain.MASTRA_OBSERVABILITY,\n category: ErrorCategory.SYSTEM,\n details: { path: this.path, runId },\n },\n error,\n );\n }\n }\n\n /**\n * Streams the log file line by line, counting every matching record but\n * retaining only the requested page (or all matches when pagination is off).\n */\n async #queryLogs({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults = true,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId?: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }) {\n const { page, perPage, start, end } = normalizePagination(pageInput, perPageInput);\n const filterEntries = Object.entries(filters ?? {});\n\n const logs: BaseLogMessage[] = [];\n let total = 0;\n\n const lines = createInterface({ input: createReadStream(this.path, 'utf8'), crlfDelay: Infinity });\n for await (const line of lines) {\n if (!line.trim()) continue;\n\n let log: any;\n try {\n log = JSON.parse(line);\n } catch {\n continue;\n }\n\n if (log === null || typeof log !== 'object') continue;\n if (runId !== undefined && log.runId !== runId) continue;\n if (!filterEntries.every(([key, value]) => log[key] === value)) continue;\n if (logLevel && log.level !== logLevel) continue;\n if (fromDate && !(new Date(log.time).getTime() >= fromDate.getTime())) continue;\n if (toDate && !(new Date(log.time).getTime() <= toDate.getTime())) continue;\n\n if (!returnPaginationResults || (total >= start && total < end)) {\n logs.push(log);\n }\n total++;\n }\n\n if (!returnPaginationResults) {\n return { logs, total, page, perPage: total, hasMore: false };\n }\n\n return { logs, total, page, perPage, hasMore: end < total };\n }\n}\n"],"mappings":"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"}
@@ -60,11 +60,14 @@ var HttpTransport = class extends _mastra_core_logger.LoggerTransport {
60
60
  this.lastFlush = Date.now();
61
61
  this.flushIntervalId = setInterval(() => this.requestFlush(), this.flushInterval);
62
62
  }
63
- async makeHttpRequest(data, retryCount = 0) {
63
+ async makeHttpRequest(data) {
64
+ const body = JSON.stringify({ logs: data });
65
+ return this.sendWithRetry(body);
66
+ }
67
+ async sendWithRetry(body, retryCount = 0) {
64
68
  const controller = new AbortController();
65
69
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
66
70
  try {
67
- const body = JSON.stringify({ logs: data });
68
71
  const response = await fetch(this.url, {
69
72
  method: this.method,
70
73
  headers: this.headers,
@@ -81,7 +84,7 @@ var HttpTransport = class extends _mastra_core_logger.LoggerTransport {
81
84
  const retryAfter = error instanceof HttpResponseError ? error.retryAfterMs ?? 0 : 0;
82
85
  const delay = Math.max(backoff, Math.min(retryAfter, this.timeout));
83
86
  await new Promise((resolve) => setTimeout(resolve, delay));
84
- return this.makeHttpRequest(data, retryCount + 1);
87
+ return this.sendWithRetry(body, retryCount + 1);
85
88
  }
86
89
  throw error;
87
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["LoggerTransport"],"sources":["../../src/http/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\ninterface RetryOptions {\n maxRetries?: number;\n retryDelay?: number;\n exponentialBackoff?: boolean;\n}\n\ninterface HttpTransportOptions {\n url: string;\n method?: 'POST' | 'PUT' | 'PATCH';\n headers?: Record<string, string>;\n batchSize?: number;\n flushInterval?: number;\n timeout?: number;\n retryOptions?: RetryOptions;\n maxBufferSize?: number;\n}\n\nclass HttpResponseError extends Error {\n constructor(\n readonly status: number,\n statusText: string,\n readonly retryAfterMs: number | undefined,\n ) {\n super(`HTTP ${status}: ${statusText}`);\n }\n}\n\n// Other 4xx responses mean the request itself is wrong and will fail the same way on every retry.\nfunction isRetryableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\n// Retry-After is either delta-seconds or an HTTP date (RFC 9110). Invalid values are ignored.\nfunction parseRetryAfter(headers: Headers | undefined): number | undefined {\n const value = headers?.get('retry-after')?.trim();\n if (!value) return undefined;\n if (/^\\d+$/.test(value)) return Number(value) * 1000;\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nexport class HttpTransport extends LoggerTransport {\n private url: string;\n private method: string;\n private headers: Record<string, string>;\n private batchSize: number;\n private flushInterval: number;\n private timeout: number;\n private retryOptions: Required<RetryOptions>;\n private logBuffer: BaseLogMessage[];\n private maxBufferSize: number;\n private droppedLogCount = 0;\n private flushPromise: Promise<void> | null = null;\n private flushRequested = false;\n private lastFlush: number;\n private flushIntervalId: NodeJS.Timeout;\n\n constructor(options: HttpTransportOptions) {\n super({ objectMode: true });\n\n if (!options.url) {\n throw new Error('HTTP URL is required');\n }\n\n this.url = options.url;\n this.method = options.method || 'POST';\n this.headers = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n this.batchSize = options.batchSize ?? 100;\n this.flushInterval = options.flushInterval || 10000;\n this.timeout = options.timeout || 30000;\n this.retryOptions = {\n maxRetries: options.retryOptions?.maxRetries ?? 3,\n retryDelay: options.retryOptions?.retryDelay ?? 1000,\n exponentialBackoff: options.retryOptions?.exponentialBackoff ?? true,\n };\n\n if (!Number.isInteger(this.batchSize) || this.batchSize < 1) {\n throw new Error('HttpTransport batchSize must be a positive integer');\n }\n\n const maxBufferSize = options.maxBufferSize ?? 10_000;\n if (!Number.isInteger(maxBufferSize) || maxBufferSize < 1) {\n throw new Error('HttpTransport maxBufferSize must be a positive integer');\n }\n this.maxBufferSize = Math.max(maxBufferSize, this.batchSize);\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => this.requestFlush(), this.flushInterval);\n }\n\n private async makeHttpRequest(data: any, retryCount = 0): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const body = JSON.stringify({ logs: data });\n\n const response = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new HttpResponseError(response.status, response.statusText, parseRetryAfter(response.headers));\n }\n\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n\n const isPermanent = error instanceof HttpResponseError && !isRetryableStatus(error.status);\n if (!isPermanent && retryCount < this.retryOptions.maxRetries) {\n const backoff = this.retryOptions.exponentialBackoff\n ? this.retryOptions.retryDelay * Math.pow(2, retryCount)\n : this.retryOptions.retryDelay;\n // Honor the server's Retry-After, capped at the request timeout so a large value can't stall shutdown.\n const retryAfter = error instanceof HttpResponseError ? (error.retryAfterMs ?? 0) : 0;\n const delay = Math.max(backoff, Math.min(retryAfter, this.timeout));\n\n await new Promise(resolve => setTimeout(resolve, delay));\n return this.makeHttpRequest(data, retryCount + 1);\n }\n\n throw error;\n }\n }\n\n private enforceBufferLimit(): void {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow <= 0) {\n return;\n }\n\n this.logBuffer.splice(0, overflow);\n if (this.droppedLogCount === 0) {\n console.warn(\n `HttpTransport: buffer exceeded maxBufferSize (${this.maxBufferSize}); dropping oldest logs. Use getDroppedLogCount() to track drops.`,\n );\n }\n this.droppedLogCount += overflow;\n }\n\n // Internal fire-and-forget flush. While a request is in flight this only records the request, so writes\n // during a slow or retrying request don't each attach another handler to the pending promise.\n private requestFlush(): void {\n if (this.flushPromise) {\n this.flushRequested = true;\n return;\n }\n this._flush().catch(err => {\n console.error('Error flushing logs to HTTP endpoint:', err);\n });\n }\n\n _flush(): Promise<void> {\n // Only one request in flight at a time, so an outage doesn't fan out into overlapping retry chains.\n if (this.flushPromise) {\n this.flushRequested = true;\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushRequested = false;\n const flush = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n this.flushPromise = flush;\n // Flushes requested while this request was in flight only got this promise back, so send their logs now,\n // and keep draining full batches. On a transient failure, wait for the next interval instead of retrying\n // straight away. A permanently rejected batch was dropped, so the logs behind it can go out now.\n const continueDraining = () => {\n if (this.logBuffer.length >= this.batchSize || (this.flushRequested && this.logBuffer.length > 0)) {\n this.requestFlush();\n }\n };\n flush.then(continueDraining, error => {\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n continueDraining();\n }\n });\n return flush;\n }\n\n private async flushBatch(): Promise<void> {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n await this.makeHttpRequest(logs);\n this.lastFlush = now;\n } catch (error) {\n // The endpoint rejected this batch outright, so resending it can't succeed and would block the logs behind it.\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n this.droppedLogCount += logs.length;\n console.warn(\n `HttpTransport: endpoint rejected a batch with HTTP ${error.status}; dropping ${logs.length} logs. Use getDroppedLogCount() to track drops.`,\n );\n throw error;\n }\n\n // On a transient error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function): void {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n this.enforceBufferLimit();\n\n // Flush if buffer reaches batch size\n if (this.logBuffer.length >= this.batchSize) {\n this.requestFlush();\n }\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function): void {\n clearInterval(this.flushIntervalId);\n\n // Final drain. Wait out any in-flight request (ignoring its failure, since its logs are back in the buffer),\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n if (this.logBuffer.length > 0 || this.flushPromise) {\n const drain = async () => {\n await this.flushPromise?.catch(() => {});\n while (this.flushPromise || this.logBuffer.length > 0) {\n await (this.flushPromise ?? this._flush());\n }\n };\n\n drain()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogs: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: params?.page === 0 ? 1 : (params?.page ?? 1),\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n\n async listLogsByRunId({\n runId: _runId,\n fromDate: _fromDate,\n toDate: _toDate,\n logLevel: _logLevel,\n filters: _filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogsByRunId: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: page === 0 ? 1 : (page ?? 1),\n perPage: perPage ?? 100,\n hasMore: false,\n };\n }\n\n // Utility methods\n public getBufferedLogs(): BaseLogMessage[] {\n return [...this.logBuffer];\n }\n\n public clearBuffer(): void {\n this.logBuffer = [];\n }\n\n public getDroppedLogCount(): number {\n return this.droppedLogCount;\n }\n\n public getLastFlushTime(): number {\n return this.lastFlush;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["LoggerTransport"],"sources":["../../src/http/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\ninterface RetryOptions {\n maxRetries?: number;\n retryDelay?: number;\n exponentialBackoff?: boolean;\n}\n\ninterface HttpTransportOptions {\n url: string;\n method?: 'POST' | 'PUT' | 'PATCH';\n headers?: Record<string, string>;\n batchSize?: number;\n flushInterval?: number;\n timeout?: number;\n retryOptions?: RetryOptions;\n maxBufferSize?: number;\n}\n\nclass HttpResponseError extends Error {\n constructor(\n readonly status: number,\n statusText: string,\n readonly retryAfterMs: number | undefined,\n ) {\n super(`HTTP ${status}: ${statusText}`);\n }\n}\n\n// Other 4xx responses mean the request itself is wrong and will fail the same way on every retry.\nfunction isRetryableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\n// Retry-After is either delta-seconds or an HTTP date (RFC 9110). Invalid values are ignored.\nfunction parseRetryAfter(headers: Headers | undefined): number | undefined {\n const value = headers?.get('retry-after')?.trim();\n if (!value) return undefined;\n if (/^\\d+$/.test(value)) return Number(value) * 1000;\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nexport class HttpTransport extends LoggerTransport {\n private url: string;\n private method: string;\n private headers: Record<string, string>;\n private batchSize: number;\n private flushInterval: number;\n private timeout: number;\n private retryOptions: Required<RetryOptions>;\n private logBuffer: BaseLogMessage[];\n private maxBufferSize: number;\n private droppedLogCount = 0;\n private flushPromise: Promise<void> | null = null;\n private flushRequested = false;\n private lastFlush: number;\n private flushIntervalId: NodeJS.Timeout;\n\n constructor(options: HttpTransportOptions) {\n super({ objectMode: true });\n\n if (!options.url) {\n throw new Error('HTTP URL is required');\n }\n\n this.url = options.url;\n this.method = options.method || 'POST';\n this.headers = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n this.batchSize = options.batchSize ?? 100;\n this.flushInterval = options.flushInterval || 10000;\n this.timeout = options.timeout || 30000;\n this.retryOptions = {\n maxRetries: options.retryOptions?.maxRetries ?? 3,\n retryDelay: options.retryOptions?.retryDelay ?? 1000,\n exponentialBackoff: options.retryOptions?.exponentialBackoff ?? true,\n };\n\n if (!Number.isInteger(this.batchSize) || this.batchSize < 1) {\n throw new Error('HttpTransport batchSize must be a positive integer');\n }\n\n const maxBufferSize = options.maxBufferSize ?? 10_000;\n if (!Number.isInteger(maxBufferSize) || maxBufferSize < 1) {\n throw new Error('HttpTransport maxBufferSize must be a positive integer');\n }\n this.maxBufferSize = Math.max(maxBufferSize, this.batchSize);\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => this.requestFlush(), this.flushInterval);\n }\n\n private async makeHttpRequest(data: any): Promise<Response> {\n // Serialize once, outside the retry loop: serialization failures are not retryable,\n // and every retry must send the exact same payload.\n const body = JSON.stringify({ logs: data });\n return this.sendWithRetry(body);\n }\n\n private async sendWithRetry(body: string, retryCount = 0): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new HttpResponseError(response.status, response.statusText, parseRetryAfter(response.headers));\n }\n\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n\n const isPermanent = error instanceof HttpResponseError && !isRetryableStatus(error.status);\n if (!isPermanent && retryCount < this.retryOptions.maxRetries) {\n const backoff = this.retryOptions.exponentialBackoff\n ? this.retryOptions.retryDelay * Math.pow(2, retryCount)\n : this.retryOptions.retryDelay;\n // Honor the server's Retry-After, capped at the request timeout so a large value can't stall shutdown.\n const retryAfter = error instanceof HttpResponseError ? (error.retryAfterMs ?? 0) : 0;\n const delay = Math.max(backoff, Math.min(retryAfter, this.timeout));\n\n await new Promise(resolve => setTimeout(resolve, delay));\n return this.sendWithRetry(body, retryCount + 1);\n }\n\n throw error;\n }\n }\n\n private enforceBufferLimit(): void {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow <= 0) {\n return;\n }\n\n this.logBuffer.splice(0, overflow);\n if (this.droppedLogCount === 0) {\n console.warn(\n `HttpTransport: buffer exceeded maxBufferSize (${this.maxBufferSize}); dropping oldest logs. Use getDroppedLogCount() to track drops.`,\n );\n }\n this.droppedLogCount += overflow;\n }\n\n // Internal fire-and-forget flush. While a request is in flight this only records the request, so writes\n // during a slow or retrying request don't each attach another handler to the pending promise.\n private requestFlush(): void {\n if (this.flushPromise) {\n this.flushRequested = true;\n return;\n }\n this._flush().catch(err => {\n console.error('Error flushing logs to HTTP endpoint:', err);\n });\n }\n\n _flush(): Promise<void> {\n // Only one request in flight at a time, so an outage doesn't fan out into overlapping retry chains.\n if (this.flushPromise) {\n this.flushRequested = true;\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushRequested = false;\n const flush = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n this.flushPromise = flush;\n // Flushes requested while this request was in flight only got this promise back, so send their logs now,\n // and keep draining full batches. On a transient failure, wait for the next interval instead of retrying\n // straight away. A permanently rejected batch was dropped, so the logs behind it can go out now.\n const continueDraining = () => {\n if (this.logBuffer.length >= this.batchSize || (this.flushRequested && this.logBuffer.length > 0)) {\n this.requestFlush();\n }\n };\n flush.then(continueDraining, error => {\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n continueDraining();\n }\n });\n return flush;\n }\n\n private async flushBatch(): Promise<void> {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n await this.makeHttpRequest(logs);\n this.lastFlush = now;\n } catch (error) {\n // The endpoint rejected this batch outright, so resending it can't succeed and would block the logs behind it.\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n this.droppedLogCount += logs.length;\n console.warn(\n `HttpTransport: endpoint rejected a batch with HTTP ${error.status}; dropping ${logs.length} logs. Use getDroppedLogCount() to track drops.`,\n );\n throw error;\n }\n\n // On a transient error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function): void {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n this.enforceBufferLimit();\n\n // Flush if buffer reaches batch size\n if (this.logBuffer.length >= this.batchSize) {\n this.requestFlush();\n }\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function): void {\n clearInterval(this.flushIntervalId);\n\n // Final drain. Wait out any in-flight request (ignoring its failure, since its logs are back in the buffer),\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n if (this.logBuffer.length > 0 || this.flushPromise) {\n const drain = async () => {\n await this.flushPromise?.catch(() => {});\n while (this.flushPromise || this.logBuffer.length > 0) {\n await (this.flushPromise ?? this._flush());\n }\n };\n\n drain()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogs: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: params?.page === 0 ? 1 : (params?.page ?? 1),\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n\n async listLogsByRunId({\n runId: _runId,\n fromDate: _fromDate,\n toDate: _toDate,\n logLevel: _logLevel,\n filters: _filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogsByRunId: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: page === 0 ? 1 : (page ?? 1),\n perPage: perPage ?? 100,\n hasMore: false,\n };\n }\n\n // Utility methods\n public getBufferedLogs(): BaseLogMessage[] {\n return [...this.logBuffer];\n }\n\n public clearBuffer(): void {\n this.logBuffer = [];\n }\n\n public getDroppedLogCount(): number {\n return this.droppedLogCount;\n }\n\n public getLastFlushTime(): number {\n return this.lastFlush;\n }\n}\n"],"mappings":"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"}
@@ -32,6 +32,7 @@ export declare class HttpTransport extends LoggerTransport {
32
32
  private flushIntervalId;
33
33
  constructor(options: HttpTransportOptions);
34
34
  private makeHttpRequest;
35
+ private sendWithRetry;
35
36
  private enforceBufferLimit;
36
37
  private requestFlush;
37
38
  _flush(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"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"}
@@ -59,11 +59,14 @@ var HttpTransport = class extends LoggerTransport {
59
59
  this.lastFlush = Date.now();
60
60
  this.flushIntervalId = setInterval(() => this.requestFlush(), this.flushInterval);
61
61
  }
62
- async makeHttpRequest(data, retryCount = 0) {
62
+ async makeHttpRequest(data) {
63
+ const body = JSON.stringify({ logs: data });
64
+ return this.sendWithRetry(body);
65
+ }
66
+ async sendWithRetry(body, retryCount = 0) {
63
67
  const controller = new AbortController();
64
68
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
65
69
  try {
66
- const body = JSON.stringify({ logs: data });
67
70
  const response = await fetch(this.url, {
68
71
  method: this.method,
69
72
  headers: this.headers,
@@ -80,7 +83,7 @@ var HttpTransport = class extends LoggerTransport {
80
83
  const retryAfter = error instanceof HttpResponseError ? error.retryAfterMs ?? 0 : 0;
81
84
  const delay = Math.max(backoff, Math.min(retryAfter, this.timeout));
82
85
  await new Promise((resolve) => setTimeout(resolve, delay));
83
- return this.makeHttpRequest(data, retryCount + 1);
86
+ return this.sendWithRetry(body, retryCount + 1);
84
87
  }
85
88
  throw error;
86
89
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/http/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\ninterface RetryOptions {\n maxRetries?: number;\n retryDelay?: number;\n exponentialBackoff?: boolean;\n}\n\ninterface HttpTransportOptions {\n url: string;\n method?: 'POST' | 'PUT' | 'PATCH';\n headers?: Record<string, string>;\n batchSize?: number;\n flushInterval?: number;\n timeout?: number;\n retryOptions?: RetryOptions;\n maxBufferSize?: number;\n}\n\nclass HttpResponseError extends Error {\n constructor(\n readonly status: number,\n statusText: string,\n readonly retryAfterMs: number | undefined,\n ) {\n super(`HTTP ${status}: ${statusText}`);\n }\n}\n\n// Other 4xx responses mean the request itself is wrong and will fail the same way on every retry.\nfunction isRetryableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\n// Retry-After is either delta-seconds or an HTTP date (RFC 9110). Invalid values are ignored.\nfunction parseRetryAfter(headers: Headers | undefined): number | undefined {\n const value = headers?.get('retry-after')?.trim();\n if (!value) return undefined;\n if (/^\\d+$/.test(value)) return Number(value) * 1000;\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nexport class HttpTransport extends LoggerTransport {\n private url: string;\n private method: string;\n private headers: Record<string, string>;\n private batchSize: number;\n private flushInterval: number;\n private timeout: number;\n private retryOptions: Required<RetryOptions>;\n private logBuffer: BaseLogMessage[];\n private maxBufferSize: number;\n private droppedLogCount = 0;\n private flushPromise: Promise<void> | null = null;\n private flushRequested = false;\n private lastFlush: number;\n private flushIntervalId: NodeJS.Timeout;\n\n constructor(options: HttpTransportOptions) {\n super({ objectMode: true });\n\n if (!options.url) {\n throw new Error('HTTP URL is required');\n }\n\n this.url = options.url;\n this.method = options.method || 'POST';\n this.headers = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n this.batchSize = options.batchSize ?? 100;\n this.flushInterval = options.flushInterval || 10000;\n this.timeout = options.timeout || 30000;\n this.retryOptions = {\n maxRetries: options.retryOptions?.maxRetries ?? 3,\n retryDelay: options.retryOptions?.retryDelay ?? 1000,\n exponentialBackoff: options.retryOptions?.exponentialBackoff ?? true,\n };\n\n if (!Number.isInteger(this.batchSize) || this.batchSize < 1) {\n throw new Error('HttpTransport batchSize must be a positive integer');\n }\n\n const maxBufferSize = options.maxBufferSize ?? 10_000;\n if (!Number.isInteger(maxBufferSize) || maxBufferSize < 1) {\n throw new Error('HttpTransport maxBufferSize must be a positive integer');\n }\n this.maxBufferSize = Math.max(maxBufferSize, this.batchSize);\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => this.requestFlush(), this.flushInterval);\n }\n\n private async makeHttpRequest(data: any, retryCount = 0): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const body = JSON.stringify({ logs: data });\n\n const response = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new HttpResponseError(response.status, response.statusText, parseRetryAfter(response.headers));\n }\n\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n\n const isPermanent = error instanceof HttpResponseError && !isRetryableStatus(error.status);\n if (!isPermanent && retryCount < this.retryOptions.maxRetries) {\n const backoff = this.retryOptions.exponentialBackoff\n ? this.retryOptions.retryDelay * Math.pow(2, retryCount)\n : this.retryOptions.retryDelay;\n // Honor the server's Retry-After, capped at the request timeout so a large value can't stall shutdown.\n const retryAfter = error instanceof HttpResponseError ? (error.retryAfterMs ?? 0) : 0;\n const delay = Math.max(backoff, Math.min(retryAfter, this.timeout));\n\n await new Promise(resolve => setTimeout(resolve, delay));\n return this.makeHttpRequest(data, retryCount + 1);\n }\n\n throw error;\n }\n }\n\n private enforceBufferLimit(): void {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow <= 0) {\n return;\n }\n\n this.logBuffer.splice(0, overflow);\n if (this.droppedLogCount === 0) {\n console.warn(\n `HttpTransport: buffer exceeded maxBufferSize (${this.maxBufferSize}); dropping oldest logs. Use getDroppedLogCount() to track drops.`,\n );\n }\n this.droppedLogCount += overflow;\n }\n\n // Internal fire-and-forget flush. While a request is in flight this only records the request, so writes\n // during a slow or retrying request don't each attach another handler to the pending promise.\n private requestFlush(): void {\n if (this.flushPromise) {\n this.flushRequested = true;\n return;\n }\n this._flush().catch(err => {\n console.error('Error flushing logs to HTTP endpoint:', err);\n });\n }\n\n _flush(): Promise<void> {\n // Only one request in flight at a time, so an outage doesn't fan out into overlapping retry chains.\n if (this.flushPromise) {\n this.flushRequested = true;\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushRequested = false;\n const flush = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n this.flushPromise = flush;\n // Flushes requested while this request was in flight only got this promise back, so send their logs now,\n // and keep draining full batches. On a transient failure, wait for the next interval instead of retrying\n // straight away. A permanently rejected batch was dropped, so the logs behind it can go out now.\n const continueDraining = () => {\n if (this.logBuffer.length >= this.batchSize || (this.flushRequested && this.logBuffer.length > 0)) {\n this.requestFlush();\n }\n };\n flush.then(continueDraining, error => {\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n continueDraining();\n }\n });\n return flush;\n }\n\n private async flushBatch(): Promise<void> {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n await this.makeHttpRequest(logs);\n this.lastFlush = now;\n } catch (error) {\n // The endpoint rejected this batch outright, so resending it can't succeed and would block the logs behind it.\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n this.droppedLogCount += logs.length;\n console.warn(\n `HttpTransport: endpoint rejected a batch with HTTP ${error.status}; dropping ${logs.length} logs. Use getDroppedLogCount() to track drops.`,\n );\n throw error;\n }\n\n // On a transient error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function): void {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n this.enforceBufferLimit();\n\n // Flush if buffer reaches batch size\n if (this.logBuffer.length >= this.batchSize) {\n this.requestFlush();\n }\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function): void {\n clearInterval(this.flushIntervalId);\n\n // Final drain. Wait out any in-flight request (ignoring its failure, since its logs are back in the buffer),\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n if (this.logBuffer.length > 0 || this.flushPromise) {\n const drain = async () => {\n await this.flushPromise?.catch(() => {});\n while (this.flushPromise || this.logBuffer.length > 0) {\n await (this.flushPromise ?? this._flush());\n }\n };\n\n drain()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogs: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: params?.page === 0 ? 1 : (params?.page ?? 1),\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n\n async listLogsByRunId({\n runId: _runId,\n fromDate: _fromDate,\n toDate: _toDate,\n logLevel: _logLevel,\n filters: _filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogsByRunId: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: page === 0 ? 1 : (page ?? 1),\n perPage: perPage ?? 100,\n hasMore: false,\n };\n }\n\n // Utility methods\n public getBufferedLogs(): BaseLogMessage[] {\n return [...this.logBuffer];\n }\n\n public clearBuffer(): void {\n this.logBuffer = [];\n }\n\n public getDroppedLogCount(): number {\n return this.droppedLogCount;\n }\n\n public getLastFlushTime(): number {\n return this.lastFlush;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/http/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\ninterface RetryOptions {\n maxRetries?: number;\n retryDelay?: number;\n exponentialBackoff?: boolean;\n}\n\ninterface HttpTransportOptions {\n url: string;\n method?: 'POST' | 'PUT' | 'PATCH';\n headers?: Record<string, string>;\n batchSize?: number;\n flushInterval?: number;\n timeout?: number;\n retryOptions?: RetryOptions;\n maxBufferSize?: number;\n}\n\nclass HttpResponseError extends Error {\n constructor(\n readonly status: number,\n statusText: string,\n readonly retryAfterMs: number | undefined,\n ) {\n super(`HTTP ${status}: ${statusText}`);\n }\n}\n\n// Other 4xx responses mean the request itself is wrong and will fail the same way on every retry.\nfunction isRetryableStatus(status: number): boolean {\n return status === 408 || status === 425 || status === 429 || status >= 500;\n}\n\n// Retry-After is either delta-seconds or an HTTP date (RFC 9110). Invalid values are ignored.\nfunction parseRetryAfter(headers: Headers | undefined): number | undefined {\n const value = headers?.get('retry-after')?.trim();\n if (!value) return undefined;\n if (/^\\d+$/.test(value)) return Number(value) * 1000;\n const date = Date.parse(value);\n return Number.isNaN(date) ? undefined : Math.max(0, date - Date.now());\n}\n\nexport class HttpTransport extends LoggerTransport {\n private url: string;\n private method: string;\n private headers: Record<string, string>;\n private batchSize: number;\n private flushInterval: number;\n private timeout: number;\n private retryOptions: Required<RetryOptions>;\n private logBuffer: BaseLogMessage[];\n private maxBufferSize: number;\n private droppedLogCount = 0;\n private flushPromise: Promise<void> | null = null;\n private flushRequested = false;\n private lastFlush: number;\n private flushIntervalId: NodeJS.Timeout;\n\n constructor(options: HttpTransportOptions) {\n super({ objectMode: true });\n\n if (!options.url) {\n throw new Error('HTTP URL is required');\n }\n\n this.url = options.url;\n this.method = options.method || 'POST';\n this.headers = {\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n this.batchSize = options.batchSize ?? 100;\n this.flushInterval = options.flushInterval || 10000;\n this.timeout = options.timeout || 30000;\n this.retryOptions = {\n maxRetries: options.retryOptions?.maxRetries ?? 3,\n retryDelay: options.retryOptions?.retryDelay ?? 1000,\n exponentialBackoff: options.retryOptions?.exponentialBackoff ?? true,\n };\n\n if (!Number.isInteger(this.batchSize) || this.batchSize < 1) {\n throw new Error('HttpTransport batchSize must be a positive integer');\n }\n\n const maxBufferSize = options.maxBufferSize ?? 10_000;\n if (!Number.isInteger(maxBufferSize) || maxBufferSize < 1) {\n throw new Error('HttpTransport maxBufferSize must be a positive integer');\n }\n this.maxBufferSize = Math.max(maxBufferSize, this.batchSize);\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => this.requestFlush(), this.flushInterval);\n }\n\n private async makeHttpRequest(data: any): Promise<Response> {\n // Serialize once, outside the retry loop: serialization failures are not retryable,\n // and every retry must send the exact same payload.\n const body = JSON.stringify({ logs: data });\n return this.sendWithRetry(body);\n }\n\n private async sendWithRetry(body: string, retryCount = 0): Promise<Response> {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body,\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new HttpResponseError(response.status, response.statusText, parseRetryAfter(response.headers));\n }\n\n return response;\n } catch (error) {\n clearTimeout(timeoutId);\n\n const isPermanent = error instanceof HttpResponseError && !isRetryableStatus(error.status);\n if (!isPermanent && retryCount < this.retryOptions.maxRetries) {\n const backoff = this.retryOptions.exponentialBackoff\n ? this.retryOptions.retryDelay * Math.pow(2, retryCount)\n : this.retryOptions.retryDelay;\n // Honor the server's Retry-After, capped at the request timeout so a large value can't stall shutdown.\n const retryAfter = error instanceof HttpResponseError ? (error.retryAfterMs ?? 0) : 0;\n const delay = Math.max(backoff, Math.min(retryAfter, this.timeout));\n\n await new Promise(resolve => setTimeout(resolve, delay));\n return this.sendWithRetry(body, retryCount + 1);\n }\n\n throw error;\n }\n }\n\n private enforceBufferLimit(): void {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow <= 0) {\n return;\n }\n\n this.logBuffer.splice(0, overflow);\n if (this.droppedLogCount === 0) {\n console.warn(\n `HttpTransport: buffer exceeded maxBufferSize (${this.maxBufferSize}); dropping oldest logs. Use getDroppedLogCount() to track drops.`,\n );\n }\n this.droppedLogCount += overflow;\n }\n\n // Internal fire-and-forget flush. While a request is in flight this only records the request, so writes\n // during a slow or retrying request don't each attach another handler to the pending promise.\n private requestFlush(): void {\n if (this.flushPromise) {\n this.flushRequested = true;\n return;\n }\n this._flush().catch(err => {\n console.error('Error flushing logs to HTTP endpoint:', err);\n });\n }\n\n _flush(): Promise<void> {\n // Only one request in flight at a time, so an outage doesn't fan out into overlapping retry chains.\n if (this.flushPromise) {\n this.flushRequested = true;\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushRequested = false;\n const flush = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n this.flushPromise = flush;\n // Flushes requested while this request was in flight only got this promise back, so send their logs now,\n // and keep draining full batches. On a transient failure, wait for the next interval instead of retrying\n // straight away. A permanently rejected batch was dropped, so the logs behind it can go out now.\n const continueDraining = () => {\n if (this.logBuffer.length >= this.batchSize || (this.flushRequested && this.logBuffer.length > 0)) {\n this.requestFlush();\n }\n };\n flush.then(continueDraining, error => {\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n continueDraining();\n }\n });\n return flush;\n }\n\n private async flushBatch(): Promise<void> {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n await this.makeHttpRequest(logs);\n this.lastFlush = now;\n } catch (error) {\n // The endpoint rejected this batch outright, so resending it can't succeed and would block the logs behind it.\n if (error instanceof HttpResponseError && !isRetryableStatus(error.status)) {\n this.droppedLogCount += logs.length;\n console.warn(\n `HttpTransport: endpoint rejected a batch with HTTP ${error.status}; dropping ${logs.length} logs. Use getDroppedLogCount() to track drops.`,\n );\n throw error;\n }\n\n // On a transient error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function): void {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n this.enforceBufferLimit();\n\n // Flush if buffer reaches batch size\n if (this.logBuffer.length >= this.batchSize) {\n this.requestFlush();\n }\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function): void {\n clearInterval(this.flushIntervalId);\n\n // Final drain. Wait out any in-flight request (ignoring its failure, since its logs are back in the buffer),\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n if (this.logBuffer.length > 0 || this.flushPromise) {\n const drain = async () => {\n await this.flushPromise?.catch(() => {});\n while (this.flushPromise || this.logBuffer.length > 0) {\n await (this.flushPromise ?? this._flush());\n }\n };\n\n drain()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogs: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: params?.page === 0 ? 1 : (params?.page ?? 1),\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n\n async listLogsByRunId({\n runId: _runId,\n fromDate: _fromDate,\n toDate: _toDate,\n logLevel: _logLevel,\n filters: _filters,\n page,\n perPage,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n // HttpTransport is write-only by default\n // Subclasses can override this method to implement log retrieval\n console.warn(\n 'HttpTransport.listLogsByRunId: This transport is write-only. Override this method to implement log retrieval.',\n );\n\n return {\n logs: [],\n total: 0,\n page: page === 0 ? 1 : (page ?? 1),\n perPage: perPage ?? 100,\n hasMore: false,\n };\n }\n\n // Utility methods\n public getBufferedLogs(): BaseLogMessage[] {\n return [...this.logBuffer];\n }\n\n public clearBuffer(): void {\n this.logBuffer = [];\n }\n\n public getDroppedLogCount(): number {\n return this.droppedLogCount;\n }\n\n public getLastFlushTime(): number {\n return this.lastFlush;\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ //#region src/pagination.ts
2
+ /**
3
+ * Normalizes and validates log query pagination. `page: 0` aliases page 1 and
4
+ * `perPage: 0` aliases the default of 100. Throws RangeError for anything that
5
+ * is not a positive safe integer, or whose range would exceed safe integers.
6
+ */
7
+ function normalizePagination(pageInput, perPageInput) {
8
+ const page = pageInput === void 0 || pageInput === 0 ? 1 : pageInput;
9
+ const perPage = perPageInput === void 0 || perPageInput === 0 ? 100 : perPageInput;
10
+ if (!Number.isSafeInteger(page) || page < 1) throw new RangeError(`Invalid page: ${pageInput}. Expected a positive integer.`);
11
+ if (!Number.isSafeInteger(perPage) || perPage < 1) throw new RangeError(`Invalid perPage: ${perPageInput}. Expected a positive integer.`);
12
+ const start = (page - 1) * perPage;
13
+ const end = start + perPage;
14
+ if (!Number.isSafeInteger(end)) throw new RangeError(`Pagination range too large: page ${page}, perPage ${perPage}.`);
15
+ return {
16
+ page,
17
+ perPage,
18
+ start,
19
+ end
20
+ };
21
+ }
22
+ //#endregion
23
+ export { normalizePagination as t };
24
+
25
+ //# sourceMappingURL=pagination-BfSC4BZ-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination-BfSC4BZ-.js","names":[],"sources":["../src/pagination.ts"],"sourcesContent":["/**\n * Normalizes and validates log query pagination. `page: 0` aliases page 1 and\n * `perPage: 0` aliases the default of 100. Throws RangeError for anything that\n * is not a positive safe integer, or whose range would exceed safe integers.\n */\nexport function normalizePagination(pageInput?: number, perPageInput?: number) {\n const page = pageInput === undefined || pageInput === 0 ? 1 : pageInput;\n const perPage = perPageInput === undefined || perPageInput === 0 ? 100 : perPageInput;\n\n if (!Number.isSafeInteger(page) || page < 1) {\n throw new RangeError(`Invalid page: ${pageInput}. Expected a positive integer.`);\n }\n if (!Number.isSafeInteger(perPage) || perPage < 1) {\n throw new RangeError(`Invalid perPage: ${perPageInput}. Expected a positive integer.`);\n }\n\n const start = (page - 1) * perPage;\n const end = start + perPage;\n if (!Number.isSafeInteger(end)) {\n throw new RangeError(`Pagination range too large: page ${page}, perPage ${perPage}.`);\n }\n\n return { page, perPage, start, end };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,oBAAoB,WAAoB,cAAuB;CAC7E,MAAM,OAAO,cAAc,KAAA,KAAa,cAAc,IAAI,IAAI;CAC9D,MAAM,UAAU,iBAAiB,KAAA,KAAa,iBAAiB,IAAI,MAAM;CAEzE,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GACxC,MAAM,IAAI,WAAW,iBAAiB,UAAU,+BAA+B;CAEjF,IAAI,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,GAC9C,MAAM,IAAI,WAAW,oBAAoB,aAAa,+BAA+B;CAGvF,MAAM,SAAS,OAAO,KAAK;CAC3B,MAAM,MAAM,QAAQ;CACpB,IAAI,CAAC,OAAO,cAAc,GAAG,GAC3B,MAAM,IAAI,WAAW,oCAAoC,KAAK,YAAY,QAAQ,EAAE;CAGtF,OAAO;EAAE;EAAM;EAAS;EAAO;CAAI;AACrC"}
@@ -0,0 +1,30 @@
1
+ //#region src/pagination.ts
2
+ /**
3
+ * Normalizes and validates log query pagination. `page: 0` aliases page 1 and
4
+ * `perPage: 0` aliases the default of 100. Throws RangeError for anything that
5
+ * is not a positive safe integer, or whose range would exceed safe integers.
6
+ */
7
+ function normalizePagination(pageInput, perPageInput) {
8
+ const page = pageInput === void 0 || pageInput === 0 ? 1 : pageInput;
9
+ const perPage = perPageInput === void 0 || perPageInput === 0 ? 100 : perPageInput;
10
+ if (!Number.isSafeInteger(page) || page < 1) throw new RangeError(`Invalid page: ${pageInput}. Expected a positive integer.`);
11
+ if (!Number.isSafeInteger(perPage) || perPage < 1) throw new RangeError(`Invalid perPage: ${perPageInput}. Expected a positive integer.`);
12
+ const start = (page - 1) * perPage;
13
+ const end = start + perPage;
14
+ if (!Number.isSafeInteger(end)) throw new RangeError(`Pagination range too large: page ${page}, perPage ${perPage}.`);
15
+ return {
16
+ page,
17
+ perPage,
18
+ start,
19
+ end
20
+ };
21
+ }
22
+ //#endregion
23
+ Object.defineProperty(exports, "normalizePagination", {
24
+ enumerable: true,
25
+ get: function() {
26
+ return normalizePagination;
27
+ }
28
+ });
29
+
30
+ //# sourceMappingURL=pagination-D4VAcPxN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination-D4VAcPxN.cjs","names":[],"sources":["../src/pagination.ts"],"sourcesContent":["/**\n * Normalizes and validates log query pagination. `page: 0` aliases page 1 and\n * `perPage: 0` aliases the default of 100. Throws RangeError for anything that\n * is not a positive safe integer, or whose range would exceed safe integers.\n */\nexport function normalizePagination(pageInput?: number, perPageInput?: number) {\n const page = pageInput === undefined || pageInput === 0 ? 1 : pageInput;\n const perPage = perPageInput === undefined || perPageInput === 0 ? 100 : perPageInput;\n\n if (!Number.isSafeInteger(page) || page < 1) {\n throw new RangeError(`Invalid page: ${pageInput}. Expected a positive integer.`);\n }\n if (!Number.isSafeInteger(perPage) || perPage < 1) {\n throw new RangeError(`Invalid perPage: ${perPageInput}. Expected a positive integer.`);\n }\n\n const start = (page - 1) * perPage;\n const end = start + perPage;\n if (!Number.isSafeInteger(end)) {\n throw new RangeError(`Pagination range too large: page ${page}, perPage ${perPage}.`);\n }\n\n return { page, perPage, start, end };\n}\n"],"mappings":";;;;;;AAKA,SAAgB,oBAAoB,WAAoB,cAAuB;CAC7E,MAAM,OAAO,cAAc,KAAA,KAAa,cAAc,IAAI,IAAI;CAC9D,MAAM,UAAU,iBAAiB,KAAA,KAAa,iBAAiB,IAAI,MAAM;CAEzE,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,GACxC,MAAM,IAAI,WAAW,iBAAiB,UAAU,+BAA+B;CAEjF,IAAI,CAAC,OAAO,cAAc,OAAO,KAAK,UAAU,GAC9C,MAAM,IAAI,WAAW,oBAAoB,aAAa,+BAA+B;CAGvF,MAAM,SAAS,OAAO,KAAK;CAC3B,MAAM,MAAM,QAAQ;CACpB,IAAI,CAAC,OAAO,cAAc,GAAG,GAC3B,MAAM,IAAI,WAAW,oCAAoC,KAAK,YAAY,QAAQ,EAAE;CAGtF,OAAO;EAAE;EAAM;EAAS;EAAO;CAAI;AACrC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Normalizes and validates log query pagination. `page: 0` aliases page 1 and
3
+ * `perPage: 0` aliases the default of 100. Throws RangeError for anything that
4
+ * is not a positive safe integer, or whose range would exceed safe integers.
5
+ */
6
+ export declare function normalizePagination(pageInput?: number, perPageInput?: number): {
7
+ page: number;
8
+ perPage: number;
9
+ start: number;
10
+ end: number;
11
+ };
12
+ //# sourceMappingURL=pagination.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM;;;;;EAkB5E"}
@@ -1,4 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_pagination = require("../pagination-D4VAcPxN.cjs");
2
3
  let _mastra_core_logger = require("@mastra/core/logger");
3
4
  //#region src/upstash/index.ts
4
5
  var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
@@ -146,15 +147,12 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
146
147
  return !filters || Object.entries(filters).every(([key, value]) => log[key] === value);
147
148
  }
148
149
  async listLogs(params) {
150
+ const { page, perPage, start, end } = require_pagination.normalizePagination(params?.page, params?.perPage);
149
151
  try {
150
- const { fromDate, toDate, logLevel, filters, returnPaginationResults: returnPaginationResultsInput, page: pageInput, perPage: perPageInput } = params || {};
151
- const page = pageInput === 0 ? 1 : pageInput ?? 1;
152
- const perPage = perPageInput || 100;
152
+ const { fromDate, toDate, logLevel, filters, returnPaginationResults: returnPaginationResultsInput } = params || {};
153
153
  const returnPaginationResults = returnPaginationResultsInput ?? true;
154
154
  const hasFilters = Boolean(fromDate || toDate || logLevel || filters && Object.keys(filters).length > 0);
155
155
  if (returnPaginationResults && !hasFilters) {
156
- const start = (page - 1) * perPage;
157
- const end = start + perPage;
158
156
  const response = await this.executeUpstashCommands([["LLEN", this.listName], [
159
157
  "LRANGE",
160
158
  this.listName,
@@ -190,8 +188,6 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
190
188
  hasMore: false
191
189
  };
192
190
  const total = filteredLogs.length;
193
- const start = (page - 1) * perPage;
194
- const end = start + perPage;
195
191
  return {
196
192
  logs: filteredLogs.slice(start, end),
197
193
  total,
@@ -204,16 +200,15 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
204
200
  return {
205
201
  logs: [],
206
202
  total: 0,
207
- page: params?.page === 0 ? 1 : params?.page ?? 1,
208
- perPage: params?.perPage ?? 100,
203
+ page,
204
+ perPage,
209
205
  hasMore: false
210
206
  };
211
207
  }
212
208
  }
213
209
  async listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page: pageInput, perPage: perPageInput }) {
210
+ const { page, perPage, start, end } = require_pagination.normalizePagination(pageInput, perPageInput);
214
211
  try {
215
- const page = pageInput === 0 ? 1 : pageInput ?? 1;
216
- const perPage = perPageInput || 100;
217
212
  const logs = (await this.listLogs({
218
213
  fromDate,
219
214
  toDate,
@@ -222,8 +217,6 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
222
217
  returnPaginationResults: false
223
218
  })).logs.filter((log) => this.matchesLog(log, { runId }));
224
219
  const total = logs.length;
225
- const start = (page - 1) * perPage;
226
- const end = start + perPage;
227
220
  return {
228
221
  logs: logs.slice(start, end),
229
222
  total,
@@ -236,8 +229,8 @@ var UpstashTransport = class extends _mastra_core_logger.LoggerTransport {
236
229
  return {
237
230
  logs: [],
238
231
  total: 0,
239
- page: pageInput === 0 ? 1 : pageInput ?? 1,
240
- perPage: perPageInput ?? 100,
232
+ page,
233
+ perPage,
241
234
  hasMore: false
242
235
  };
243
236
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["LoggerTransport"],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n maxBufferSize: number;\n /** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */\n droppedRecords = 0;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n private flushPromise: Promise<void> | null = null;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n /** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */\n maxBufferSize?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n // A non-positive maxListLength disables LTRIM, so it cannot serve as the buffer limit.\n this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 10000);\n if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) {\n throw new Error('maxBufferSize must be a positive integer');\n }\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */\n _flush(): Promise<void> {\n if (this.flushPromise) {\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushPromise = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n return this.flushPromise;\n }\n\n /** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */\n private async flushBatch() {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n /** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */\n private enforceBufferLimit() {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow > 0) {\n this.logBuffer.splice(0, overflow);\n this.droppedRecords += overflow;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush once a batch is ready, or earlier if the buffer limit is smaller than a batch\n if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n this.enforceBufferLimit();\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0 || this.flushPromise) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n // Wait out any in-flight request, ignoring its failure since its records are back in the buffer,\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n private async drainBuffer(): Promise<void> {\n await this.flushPromise?.catch(() => {});\n while (this.logBuffer.length > 0 || this.flushPromise) {\n await (this.flushPromise ?? this._flush());\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n page: pageInput,\n perPage: perPageInput,\n } = params || {};\n\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: params?.page === 0 ? 1 : (params?.page ?? 1),\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: pageInput === 0 ? 1 : (pageInput ?? 1),\n perPage: perPageInput ?? 100,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["LoggerTransport","normalizePagination"],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\nimport { normalizePagination } from '../pagination';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n maxBufferSize: number;\n /** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */\n droppedRecords = 0;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n private flushPromise: Promise<void> | null = null;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n /** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */\n maxBufferSize?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n // A non-positive maxListLength disables LTRIM, so it cannot serve as the buffer limit.\n this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 10000);\n if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) {\n throw new Error('maxBufferSize must be a positive integer');\n }\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */\n _flush(): Promise<void> {\n if (this.flushPromise) {\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushPromise = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n return this.flushPromise;\n }\n\n /** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */\n private async flushBatch() {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n /** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */\n private enforceBufferLimit() {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow > 0) {\n this.logBuffer.splice(0, overflow);\n this.droppedRecords += overflow;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush once a batch is ready, or earlier if the buffer limit is smaller than a batch\n if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n this.enforceBufferLimit();\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0 || this.flushPromise) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n // Wait out any in-flight request, ignoring its failure since its records are back in the buffer,\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n private async drainBuffer(): Promise<void> {\n await this.flushPromise?.catch(() => {});\n while (this.logBuffer.length > 0 || this.flushPromise) {\n await (this.flushPromise ?? this._flush());\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n const { page, perPage, start, end } = normalizePagination(params?.page, params?.perPage);\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n } = params || {};\n\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page,\n perPage,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n const { page, perPage, start, end } = normalizePagination(pageInput, perPageInput);\n try {\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page,\n perPage,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":";;;;AAIA,IAAa,mBAAb,cAAsCA,oBAAAA,gBAAgB;CACpD;CACA;CACA;CACA;CACA;;CAEA,iBAAiB;CACjB;CACA;CACA;CACA;CACA;CACA,eAA6C;CAE7C,YAAY,MAST;EACD,MAAM,EAAE,YAAY,KAAK,CAAC;EAE1B,IAAI,CAAC,KAAK,cAAc,CAAC,KAAK,cAC5B,MAAM,IAAI,MAAM,oCAAoC;EAGtD,KAAK,aAAa,KAAK;EACvB,KAAK,eAAe,KAAK;EACzB,KAAK,WAAW,KAAK,YAAY;EACjC,KAAK,gBAAgB,KAAK,iBAAiB;EAE3C,KAAK,gBAAgB,KAAK,kBAAkB,KAAK,gBAAgB,IAAI,KAAK,gBAAgB;EAC1F,IAAI,CAAC,OAAO,UAAU,KAAK,aAAa,KAAK,KAAK,gBAAgB,GAChE,MAAM,IAAI,MAAM,0CAA0C;EAE5D,KAAK,YAAY,KAAK,aAAa;EACnC,KAAK,gBAAgB,KAAK,iBAAiB;EAE3C,KAAK,YAAY,CAAC;EAClB,KAAK,YAAY,KAAK,IAAI;EAG1B,KAAK,kBAAkB,kBAAkB;GACvC,KAAK,OAAO,CAAC,CAAC,OAAM,QAAO;IACzB,QAAQ,MAAM,mCAAmC,GAAG;GACtD,CAAC;EACH,GAAG,KAAK,aAAa;CACvB;CAEA,MAAc,uBAAuB,UAAiC;EACpE,MAAM,WAAW,MAAM,MAAM,GAAG,KAAK,WAAW,YAAY;GAC1D,QAAQ;GACR,SAAS;IACP,eAAe,UAAU,KAAK;IAC9B,gBAAgB;GAClB;GACA,MAAM,KAAK,UAAU,QAAQ;EAC/B,CAAC;EAED,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,sCAAsC,SAAS,YAAY;EAG7E,OAAO,SAAS,KAAK;CACvB;;CAGA,SAAwB;EACtB,IAAI,KAAK,cACP,OAAO,KAAK;EAEd,IAAI,KAAK,UAAU,WAAW,GAC5B,OAAO,QAAQ,QAAQ;EAGzB,KAAK,eAAe,KAAK,WAAW,CAAC,CAAC,cAAc;GAClD,KAAK,eAAe;EACtB,CAAC;EACD,OAAO,KAAK;CACd;;CAGA,MAAc,aAAa;EACzB,MAAM,MAAM,KAAK,IAAI;EACrB,MAAM,OAAO,KAAK,UAAU,OAAO,GAAG,KAAK,SAAS;EAEpD,IAAI;GACF,MAAM,WAAoB,CAAC;IAAC;IAAS,KAAK;IAAU,GAAG,KAAK,KAAI,QAAO,KAAK,UAAU,GAAG,CAAC;GAAC,CAAC;GAG5F,IAAI,KAAK,gBAAgB,GACvB,SAAS,KAAK;IAAC;IAAS,KAAK;IAAU;IAAG,KAAK,gBAAgB;GAAC,CAAC;GAGnE,MAAM,KAAK,uBAAuB,QAAQ;GAC1C,KAAK,YAAY;EACnB,SAAS,OAAO;GAEd,KAAK,UAAU,QAAQ,GAAG,IAAI;GAC9B,KAAK,mBAAmB;GACxB,MAAM;EACR;CACF;;CAGA,qBAA6B;EAC3B,MAAM,WAAW,KAAK,UAAU,SAAS,KAAK;EAC9C,IAAI,WAAW,GAAG;GAChB,KAAK,UAAU,OAAO,GAAG,QAAQ;GACjC,KAAK,kBAAkB;EACzB;CACF;CAEA,OAAO,OAAY,UAAmB,UAAoD;EACxF,IAAI,OAAO,aAAa,YAAY;GAClC,KAAK,WAAW,OAAO,YAAY,QAAQ,QAAQ;GACnD,OAAO;EACT;EAEA,KAAK,WAAW,OAAO,YAAY,SAAS,UAAwB;GAClE,IAAI,OAAO,QAAQ,MAAM,6BAA6B,KAAK;EAC7D,CAAC;EACD,OAAO;CACT;CAEA,WAAW,OAAe,MAAc,IAAc;EACpD,IAAI;GAEF,MAAM,SAAS,OAAO,UAAU,WAAW,KAAK,MAAM,KAAK,IAAI;GAG/D,MAAM,MAAM,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,OAAO;IAAE,GAAG;IAAQ,MAAM,KAAK,IAAI;GAAE,IAAI;GAGlG,KAAK,UAAU,KAAK,GAAG;GAGvB,IAAI,KAAK,UAAU,UAAU,KAAK,IAAI,KAAK,WAAW,KAAK,aAAa,GACtE,KAAK,OAAO,CAAC,CAAC,OAAM,QAAO;IACzB,QAAQ,MAAM,mCAAmC,GAAG;GACtD,CAAC;GAGH,KAAK,mBAAmB;GAGxB,GAAG,MAAM,KAAK;EAChB,SAAS,OAAO;GACd,GAAG,KAAK;EACV;CACF;CAEA,SAAS,KAAY,IAAc;EACjC,cAAc,KAAK,eAAe;EAGlC,IAAI,KAAK,UAAU,SAAS,KAAK,KAAK,cACpC,KAAK,YAAY,CAAC,CACf,WAAW,GAAG,GAAG,CAAC,CAAC,CACnB,OAAM,aAAY;GACjB,QAAQ,MAAM,yBAAyB,QAAQ;GAC/C,GAAG,OAAO,QAAQ;EACpB,CAAC;OAEH,GAAG,GAAG;CAEV;CAIA,MAAc,cAA6B;EACzC,MAAM,KAAK,cAAc,YAAY,CAAC,CAAC;EACvC,OAAO,KAAK,UAAU,SAAS,KAAK,KAAK,cACvC,OAAO,KAAK,gBAAgB,KAAK,OAAO;CAE5C;CAEA,UAAkB,MAAiC;EACjD,IAAI,CAAC,MAAM,QAAQ,IAAI,GAAG,OAAO,CAAC;EAElC,OAAO,KAAK,SAAS,QAAgB;GACnC,IAAI;IACF,MAAM,YAAY,KAAK,MAAM,GAAG;IAChC,OAAO,cAAc,QAAQ,OAAO,cAAc,WAAW,CAAC,SAAS,IAAI,CAAC;GAC9E,QAAQ;IACN,OAAO,CAAC;GACV;EACF,CAAC;CACH;CAEA,WACE,KACA,EACE,UACA,QACA,UACA,SACA,SAQO;EACT,IAAI,UAAU,KAAA,KAAa,IAAI,UAAU,OAAO,OAAO;EACvD,IAAI,YAAY,IAAI,UAAU,UAAU,OAAO;EAC/C,MAAM,UAAU,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,QAAQ;EAC3C,IAAI,YAAY,EAAE,WAAW,SAAS,QAAQ,IAAI,OAAO;EACzD,IAAI,UAAU,EAAE,WAAW,OAAO,QAAQ,IAAI,OAAO;EAErD,OAAO,CAAC,WAAW,OAAO,QAAQ,OAAO,CAAC,CAAC,OAAO,CAAC,KAAK,WAAW,IAAI,SAAiC,KAAK;CAC/G;CAEA,MAAM,SAAS,QAcZ;EACD,MAAM,EAAE,MAAM,SAAS,OAAO,QAAQC,mBAAAA,oBAAoB,QAAQ,MAAM,QAAQ,OAAO;EACvF,IAAI;GACF,MAAM,EACJ,UACA,QACA,UACA,SACA,yBAAyB,iCACvB,UAAU,CAAC;GAEf,MAAM,0BAA0B,gCAAgC;GAChE,MAAM,aAAa,QAAQ,YAAY,UAAU,YAAa,WAAW,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,CAAE;GAEzG,IAAI,2BAA2B,CAAC,YAAY;IAC1C,MAAM,WAAW,MAAM,KAAK,uBAAuB,CACjD,CAAC,QAAQ,KAAK,QAAQ,GACtB;KAAC;KAAU,KAAK;KAAU;KAAO,MAAM;IAAC,CAC1C,CAAC;IACD,MAAM,QAAQ,OAAO,WAAW,EAAE,EAAE,MAAM,KAAK;IAG/C,OAAO;KACL,MAHW,KAAK,UAAU,WAAW,EAAE,EAAE,MAGtC;KACH;KACA;KACA;KACA,SAAS,MAAM;IACjB;GACF;GAEA,MAAM,WAAW,MAAM,KAAK,uBAAuB,CAAC;IAAC;IAAU,KAAK;IAAU;IAAG;GAAE,CAAC,CAAC;GACrF,MAAM,eAAe,KAAK,UAAU,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC,QAAO,QAChE,KAAK,WAAW,KAAK;IAAE;IAAU;IAAQ;IAAU;GAAQ,CAAC,CAC9D;GAEA,IAAI,CAAC,yBACH,OAAO;IACL,MAAM;IACN,OAAO,aAAa;IACpB;IACA,SAAS,aAAa;IACtB,SAAS;GACX;GAGF,MAAM,QAAQ,aAAa;GAE3B,OAAO;IACL,MAAM,aAAa,MAAM,OAAO,GAAG;IACnC;IACA;IACA;IACA,SAAS,MAAM;GACjB;EACF,SAAS,OAAO;GACd,QAAQ,MAAM,oCAAoC,KAAK;GACvD,OAAO;IACL,MAAM,CAAC;IACP,OAAO;IACP;IACA;IACA,SAAS;GACX;EACF;CACF;CAEA,MAAM,gBAAgB,EACpB,OACA,UACA,QACA,UACA,SACA,MAAM,WACN,SAAS,gBAeR;EACD,MAAM,EAAE,MAAM,SAAS,OAAO,QAAQA,mBAAAA,oBAAoB,WAAW,YAAY;EACjF,IAAI;GAEF,MAAM,QAAO,MADS,KAAK,SAAS;IAAE;IAAU;IAAQ;IAAU;IAAS,yBAAyB;GAAM,CAAC,EAAA,CACtF,KAAK,QAAO,QAAO,KAAK,WAAW,KAAK,EAAE,MAAM,CAAC,CAAC;GACvE,MAAM,QAAQ,KAAK;GAEnB,OAAO;IACL,MAAM,KAAK,MAAM,OAAO,GAAG;IAC3B;IACA;IACA;IACA,SAAS,MAAM;GACjB;EACF,SAAS,OAAO;GACd,QAAQ,MAAM,6CAA6C,KAAK;GAChE,OAAO;IACL,MAAM,CAAC;IACP,OAAO;IACP;IACA;IACA,SAAS;GACX;EACF;CACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstash/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpE,qBAAa,gBAAiB,SAAQ,eAAe;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,wFAAwF;IACxF,cAAc,SAAK;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,GAAG,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC;IAChC,OAAO,CAAC,YAAY,CAA8B;IAElD,YAAY,IAAI,EAAE;QAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,uLAAuL;QACvL,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,YAAY,EAAE,MAAM,CAAC;KACtB,EA4BA;YAEa,sBAAsB;IAiBpC,4GAA4G;IAC5G,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAYtB;IAED,0GAA0G;YAC5F,UAAU;IAsBxB,iFAAiF;IACjF,OAAO,CAAC,kBAAkB;IAQ1B,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GAAG,OAAO,CAUxF;IAED,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,QAAQ,QAyBnD;IAED,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,QAchC;YAIa,WAAW;IAOzB,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,UAAU;IAyBZ,QAAQ,CAAC,MAAM,CAAC,EAAE;QACtB,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,uBAAuB,CAAC,EAAE,OAAO,CAAC;QAClC,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAiED;IAEK,eAAe,CAAC,EACpB,KAAK,EACL,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,OAAO,EACP,IAAI,EAAE,SAAS,EACf,OAAO,EAAE,YAAY,GACtB,EAAE;QACD,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,CAAC,EAAE,IAAI,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC;QACd,QAAQ,CAAC,EAAE,QAAQ,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QACV,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC,CAwBD;CACF"}
@@ -1,3 +1,4 @@
1
+ import { t as normalizePagination } from "../pagination-BfSC4BZ-.js";
1
2
  import { LoggerTransport } from "@mastra/core/logger";
2
3
  //#region src/upstash/index.ts
3
4
  var UpstashTransport = class extends LoggerTransport {
@@ -145,15 +146,12 @@ var UpstashTransport = class extends LoggerTransport {
145
146
  return !filters || Object.entries(filters).every(([key, value]) => log[key] === value);
146
147
  }
147
148
  async listLogs(params) {
149
+ const { page, perPage, start, end } = normalizePagination(params?.page, params?.perPage);
148
150
  try {
149
- const { fromDate, toDate, logLevel, filters, returnPaginationResults: returnPaginationResultsInput, page: pageInput, perPage: perPageInput } = params || {};
150
- const page = pageInput === 0 ? 1 : pageInput ?? 1;
151
- const perPage = perPageInput || 100;
151
+ const { fromDate, toDate, logLevel, filters, returnPaginationResults: returnPaginationResultsInput } = params || {};
152
152
  const returnPaginationResults = returnPaginationResultsInput ?? true;
153
153
  const hasFilters = Boolean(fromDate || toDate || logLevel || filters && Object.keys(filters).length > 0);
154
154
  if (returnPaginationResults && !hasFilters) {
155
- const start = (page - 1) * perPage;
156
- const end = start + perPage;
157
155
  const response = await this.executeUpstashCommands([["LLEN", this.listName], [
158
156
  "LRANGE",
159
157
  this.listName,
@@ -189,8 +187,6 @@ var UpstashTransport = class extends LoggerTransport {
189
187
  hasMore: false
190
188
  };
191
189
  const total = filteredLogs.length;
192
- const start = (page - 1) * perPage;
193
- const end = start + perPage;
194
190
  return {
195
191
  logs: filteredLogs.slice(start, end),
196
192
  total,
@@ -203,16 +199,15 @@ var UpstashTransport = class extends LoggerTransport {
203
199
  return {
204
200
  logs: [],
205
201
  total: 0,
206
- page: params?.page === 0 ? 1 : params?.page ?? 1,
207
- perPage: params?.perPage ?? 100,
202
+ page,
203
+ perPage,
208
204
  hasMore: false
209
205
  };
210
206
  }
211
207
  }
212
208
  async listLogsByRunId({ runId, fromDate, toDate, logLevel, filters, page: pageInput, perPage: perPageInput }) {
209
+ const { page, perPage, start, end } = normalizePagination(pageInput, perPageInput);
213
210
  try {
214
- const page = pageInput === 0 ? 1 : pageInput ?? 1;
215
- const perPage = perPageInput || 100;
216
211
  const logs = (await this.listLogs({
217
212
  fromDate,
218
213
  toDate,
@@ -221,8 +216,6 @@ var UpstashTransport = class extends LoggerTransport {
221
216
  returnPaginationResults: false
222
217
  })).logs.filter((log) => this.matchesLog(log, { runId }));
223
218
  const total = logs.length;
224
- const start = (page - 1) * perPage;
225
- const end = start + perPage;
226
219
  return {
227
220
  logs: logs.slice(start, end),
228
221
  total,
@@ -235,8 +228,8 @@ var UpstashTransport = class extends LoggerTransport {
235
228
  return {
236
229
  logs: [],
237
230
  total: 0,
238
- page: pageInput === 0 ? 1 : pageInput ?? 1,
239
- perPage: perPageInput ?? 100,
231
+ page,
232
+ perPage,
240
233
  hasMore: false
241
234
  };
242
235
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n maxBufferSize: number;\n /** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */\n droppedRecords = 0;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n private flushPromise: Promise<void> | null = null;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n /** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */\n maxBufferSize?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n // A non-positive maxListLength disables LTRIM, so it cannot serve as the buffer limit.\n this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 10000);\n if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) {\n throw new Error('maxBufferSize must be a positive integer');\n }\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */\n _flush(): Promise<void> {\n if (this.flushPromise) {\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushPromise = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n return this.flushPromise;\n }\n\n /** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */\n private async flushBatch() {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n /** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */\n private enforceBufferLimit() {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow > 0) {\n this.logBuffer.splice(0, overflow);\n this.droppedRecords += overflow;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush once a batch is ready, or earlier if the buffer limit is smaller than a batch\n if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n this.enforceBufferLimit();\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0 || this.flushPromise) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n // Wait out any in-flight request, ignoring its failure since its records are back in the buffer,\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n private async drainBuffer(): Promise<void> {\n await this.flushPromise?.catch(() => {});\n while (this.logBuffer.length > 0 || this.flushPromise) {\n await (this.flushPromise ?? this._flush());\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n page: pageInput,\n perPage: perPageInput,\n } = params || {};\n\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const start = (page - 1) * perPage;\n const end = start + perPage;\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: params?.page === 0 ? 1 : (params?.page ?? 1),\n perPage: params?.perPage ?? 100,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n try {\n const page = pageInput === 0 ? 1 : (pageInput ?? 1);\n const perPage = perPageInput || 100;\n\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n const start = (page - 1) * perPage;\n const end = start + perPage;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page: pageInput === 0 ? 1 : (pageInput ?? 1),\n perPage: perPageInput ?? 100,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/upstash/index.ts"],"sourcesContent":["import { LoggerTransport } from '@mastra/core/logger';\nimport type { BaseLogMessage, LogLevel } from '@mastra/core/logger';\nimport { normalizePagination } from '../pagination';\n\nexport class UpstashTransport extends LoggerTransport {\n upstashUrl: string;\n upstashToken: string;\n listName: string;\n maxListLength: number;\n maxBufferSize: number;\n /** Number of buffered records discarded because the buffer exceeded `maxBufferSize`. */\n droppedRecords = 0;\n batchSize: number;\n flushInterval: number;\n logBuffer: any[];\n lastFlush: number;\n flushIntervalId: NodeJS.Timeout;\n private flushPromise: Promise<void> | null = null;\n\n constructor(opts: {\n listName?: string;\n maxListLength?: number;\n /** Maximum number of records held in memory while Upstash is unreachable. Must be a positive integer. Defaults to `maxListLength`, or 10000 when `maxListLength` disables trimming. */\n maxBufferSize?: number;\n batchSize?: number;\n upstashUrl: string;\n flushInterval?: number;\n upstashToken: string;\n }) {\n super({ objectMode: true });\n\n if (!opts.upstashUrl || !opts.upstashToken) {\n throw new Error('Upstash URL and token are required');\n }\n\n this.upstashUrl = opts.upstashUrl;\n this.upstashToken = opts.upstashToken;\n this.listName = opts.listName || 'application-logs';\n this.maxListLength = opts.maxListLength || 10000;\n // A non-positive maxListLength disables LTRIM, so it cannot serve as the buffer limit.\n this.maxBufferSize = opts.maxBufferSize ?? (this.maxListLength > 0 ? this.maxListLength : 10000);\n if (!Number.isInteger(this.maxBufferSize) || this.maxBufferSize < 1) {\n throw new Error('maxBufferSize must be a positive integer');\n }\n this.batchSize = opts.batchSize || 100;\n this.flushInterval = opts.flushInterval || 10000;\n\n this.logBuffer = [];\n this.lastFlush = Date.now();\n\n // Start flush interval\n this.flushIntervalId = setInterval(() => {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }, this.flushInterval);\n }\n\n private async executeUpstashCommands(commands: any[][]): Promise<any> {\n const response = await fetch(`${this.upstashUrl}/pipeline`, {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${this.upstashToken}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(commands),\n });\n\n if (!response.ok) {\n throw new Error(`Failed to execute Upstash command: ${response.statusText}`);\n }\n\n return response.json();\n }\n\n /** Sends the next batch to Upstash. Callers share the in-flight flush instead of starting a new request. */\n _flush(): Promise<void> {\n if (this.flushPromise) {\n return this.flushPromise;\n }\n if (this.logBuffer.length === 0) {\n return Promise.resolve();\n }\n\n this.flushPromise = this.flushBatch().finally(() => {\n this.flushPromise = null;\n });\n return this.flushPromise;\n }\n\n /** Pushes one batch to Upstash, returning the records to the front of the buffer if the request fails. */\n private async flushBatch() {\n const now = Date.now();\n const logs = this.logBuffer.splice(0, this.batchSize);\n\n try {\n const commands: any[][] = [['LPUSH', this.listName, ...logs.map(log => JSON.stringify(log))]];\n\n // Trim the list if it exceeds maxListLength (must be a separate pipeline command)\n if (this.maxListLength > 0) {\n commands.push(['LTRIM', this.listName, 0, this.maxListLength - 1]);\n }\n\n await this.executeUpstashCommands(commands);\n this.lastFlush = now;\n } catch (error) {\n // On error, put logs back in the buffer\n this.logBuffer.unshift(...logs);\n this.enforceBufferLimit();\n throw error;\n }\n }\n\n /** Drops the oldest buffered records once the buffer exceeds `maxBufferSize`. */\n private enforceBufferLimit() {\n const overflow = this.logBuffer.length - this.maxBufferSize;\n if (overflow > 0) {\n this.logBuffer.splice(0, overflow);\n this.droppedRecords += overflow;\n }\n }\n\n _write(chunk: any, encoding?: string, callback?: (error?: Error | null) => void): boolean {\n if (typeof callback === 'function') {\n this._transform(chunk, encoding || 'utf8', callback);\n return true;\n }\n\n this._transform(chunk, encoding || 'utf8', (error: Error | null) => {\n if (error) console.error('Transform error in write:', error);\n });\n return true;\n }\n\n _transform(chunk: string, _enc: string, cb: Function) {\n try {\n // Parse the log line if it's a string\n const parsed = typeof chunk === 'string' ? JSON.parse(chunk) : chunk;\n\n // Add timestamp if not present, on a copy so caller-owned (possibly frozen) records stay untouched\n const log = parsed.time === undefined || parsed.time === null ? { ...parsed, time: Date.now() } : parsed;\n\n // Add to buffer\n this.logBuffer.push(log);\n\n // Flush once a batch is ready, or earlier if the buffer limit is smaller than a batch\n if (this.logBuffer.length >= Math.min(this.batchSize, this.maxBufferSize)) {\n this._flush().catch(err => {\n console.error('Error flushing logs to Upstash:', err);\n });\n }\n\n this.enforceBufferLimit();\n\n // Pass through the log\n cb(null, chunk);\n } catch (error) {\n cb(error);\n }\n }\n\n _destroy(err: Error, cb: Function) {\n clearInterval(this.flushIntervalId);\n\n // Final flush\n if (this.logBuffer.length > 0 || this.flushPromise) {\n this.drainBuffer()\n .then(() => cb(err))\n .catch(flushErr => {\n console.error('Error in final flush:', flushErr);\n cb(err || flushErr);\n });\n } else {\n cb(err);\n }\n }\n\n // Wait out any in-flight request, ignoring its failure since its records are back in the buffer,\n // then keep sending until the buffer is empty. A failed request ends the drain instead of retrying forever.\n private async drainBuffer(): Promise<void> {\n await this.flushPromise?.catch(() => {});\n while (this.logBuffer.length > 0 || this.flushPromise) {\n await (this.flushPromise ?? this._flush());\n }\n }\n\n private parseLogs(logs: unknown): BaseLogMessage[] {\n if (!Array.isArray(logs)) return [];\n\n return logs.flatMap((log: string) => {\n try {\n const parsedLog = JSON.parse(log);\n return parsedLog !== null && typeof parsedLog === 'object' ? [parsedLog] : [];\n } catch {\n return [];\n }\n });\n }\n\n private matchesLog(\n log: BaseLogMessage,\n {\n fromDate,\n toDate,\n logLevel,\n filters,\n runId,\n }: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n runId?: string;\n },\n ): boolean {\n if (runId !== undefined && log.runId !== runId) return false;\n if (logLevel && log.level !== logLevel) return false;\n const logTime = new Date(log.time).getTime();\n if (fromDate && !(logTime >= fromDate.getTime())) return false;\n if (toDate && !(logTime <= toDate.getTime())) return false;\n\n return !filters || Object.entries(filters).every(([key, value]) => log[key as keyof BaseLogMessage] === value);\n }\n\n async listLogs(params?: {\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n returnPaginationResults?: boolean; // default true\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n const { page, perPage, start, end } = normalizePagination(params?.page, params?.perPage);\n try {\n const {\n fromDate,\n toDate,\n logLevel,\n filters,\n returnPaginationResults: returnPaginationResultsInput,\n } = params || {};\n\n const returnPaginationResults = returnPaginationResultsInput ?? true;\n const hasFilters = Boolean(fromDate || toDate || logLevel || (filters && Object.keys(filters).length > 0));\n\n if (returnPaginationResults && !hasFilters) {\n const response = await this.executeUpstashCommands([\n ['LLEN', this.listName],\n ['LRANGE', this.listName, start, end - 1],\n ]);\n const total = Number(response?.[0]?.result) || 0;\n const logs = this.parseLogs(response?.[1]?.result);\n\n return {\n logs,\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n }\n\n const response = await this.executeUpstashCommands([['LRANGE', this.listName, 0, -1]]);\n const filteredLogs = this.parseLogs(response?.[0]?.result).filter(log =>\n this.matchesLog(log, { fromDate, toDate, logLevel, filters }),\n );\n\n if (!returnPaginationResults) {\n return {\n logs: filteredLogs,\n total: filteredLogs.length,\n page,\n perPage: filteredLogs.length,\n hasMore: false,\n };\n }\n\n const total = filteredLogs.length;\n\n return {\n logs: filteredLogs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page,\n perPage,\n hasMore: false,\n };\n }\n }\n\n async listLogsByRunId({\n runId,\n fromDate,\n toDate,\n logLevel,\n filters,\n page: pageInput,\n perPage: perPageInput,\n }: {\n runId: string;\n fromDate?: Date;\n toDate?: Date;\n logLevel?: LogLevel;\n filters?: Record<string, any>;\n page?: number;\n perPage?: number;\n }): Promise<{\n logs: BaseLogMessage[];\n total: number;\n page: number;\n perPage: number;\n hasMore: boolean;\n }> {\n const { page, perPage, start, end } = normalizePagination(pageInput, perPageInput);\n try {\n const allLogs = await this.listLogs({ fromDate, toDate, logLevel, filters, returnPaginationResults: false });\n const logs = allLogs.logs.filter(log => this.matchesLog(log, { runId }));\n const total = logs.length;\n\n return {\n logs: logs.slice(start, end),\n total,\n page,\n perPage,\n hasMore: end < total,\n };\n } catch (error) {\n console.error('Error getting logs by runId from Upstash:', error);\n return {\n logs: [],\n total: 0,\n page,\n perPage,\n hasMore: false,\n };\n }\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/loggers",
3
- "version": "1.3.7",
3
+ "version": "1.3.8-alpha.0",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "files": [
@@ -76,9 +76,9 @@
76
76
  "tsx": "^4.23.1",
77
77
  "typescript": "^7.0.2",
78
78
  "vitest": "4.1.11",
79
- "@internal/types-builder": "0.0.118",
80
79
  "@internal/lint": "0.0.143",
81
- "@mastra/core": "1.77.0"
80
+ "@internal/types-builder": "0.0.118",
81
+ "@mastra/core": "1.78.0-alpha.9"
82
82
  },
83
83
  "peerDependencies": {
84
84
  "@mastra/core": ">=1.0.0-0 <2.0.0-0"