{"version":3,"file":"text.mjs","sources":["../../../src/llm/text.ts"],"sourcesContent":["export interface TextStreamOptions {\n  minChunkSize?: number;\n  maxChunkSize?: number;\n  delay?: number;\n  firstWordChunk?: boolean;\n}\n\nexport type ProgressCallback = (chunk: string) => void;\nexport type PostChunkCallback = (chunk: string) => void;\n\nexport class TextStream {\n  private text: string;\n  private currentIndex: number;\n  private minChunkSize: number;\n  private maxChunkSize: number;\n  private delay: number;\n  private firstWordChunk: boolean;\n\n  constructor(text: string, options: TextStreamOptions = {}) {\n    this.text = text;\n    this.currentIndex = 0;\n    this.minChunkSize = options.minChunkSize ?? 4;\n    this.maxChunkSize = options.maxChunkSize ?? 8;\n    this.delay = options.delay ?? 20;\n    this.firstWordChunk = options.firstWordChunk ?? true;\n  }\n\n  private randomInt(min: number, max: number): number {\n    return Math.floor(Math.random() * (max - min)) + min;\n  }\n\n  private static readonly BOUNDARIES = new Set([\n    ' ',\n    '.',\n    ',',\n    '!',\n    '?',\n    ';',\n    ':',\n  ]);\n\n  private findFirstWordBoundary(text: string, minSize: number): number {\n    if (minSize >= text.length) return text.length;\n\n    // Ensure we meet the minimum size first\n    let pos = minSize;\n\n    // Look forward until we find a boundary\n    while (pos < text.length) {\n      if (TextStream.BOUNDARIES.has(text[pos])) {\n        return pos + 1; // Include the boundary character\n      }\n      pos++;\n    }\n\n    return text.length; // If no boundary found, return entire remaining text\n  }\n\n  async *generateText(\n    signal?: AbortSignal,\n    progressCallback?: ProgressCallback\n  ): AsyncGenerator<string, void, unknown> {\n    const { delay, minChunkSize, maxChunkSize } = this;\n\n    while (this.currentIndex < this.text.length) {\n      if (signal?.aborted === true) {\n        break;\n      }\n      await new Promise((resolve) => setTimeout(resolve, delay));\n\n      const remainingText = this.text.slice(this.currentIndex);\n      let chunkSize: number;\n\n      if (this.firstWordChunk) {\n        chunkSize = this.findFirstWordBoundary(remainingText, minChunkSize);\n      } else {\n        const remainingChars = remainingText.length;\n        chunkSize = Math.min(\n          this.randomInt(minChunkSize, maxChunkSize + 1),\n          remainingChars\n        );\n      }\n\n      const chunk = this.text.slice(\n        this.currentIndex,\n        this.currentIndex + chunkSize\n      );\n      progressCallback?.(chunk);\n\n      yield chunk;\n      this.currentIndex += chunkSize;\n    }\n  }\n}\n"],"names":[],"mappings":"MAUa,UAAU,CAAA;AACb,IAAA,IAAI;AACJ,IAAA,YAAY;AACZ,IAAA,YAAY;AACZ,IAAA,YAAY;AACZ,IAAA,KAAK;AACL,IAAA,cAAc;IAEtB,WAAA,CAAY,IAAY,EAAE,OAAA,GAA6B,EAAE,EAAA;AACvD,QAAA,IAAI,CAAC,IAAI,GAAG,IAAI;AAChB,QAAA,IAAI,CAAC,YAAY,GAAG,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC;QAC7C,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC;QAC7C,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE;QAChC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,IAAI;IACtD;IAEQ,SAAS,CAAC,GAAW,EAAE,GAAW,EAAA;AACxC,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG;IACtD;AAEQ,IAAA,OAAgB,UAAU,GAAG,IAAI,GAAG,CAAC;QAC3C,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;QACH,GAAG;AACJ,KAAA,CAAC;IAEM,qBAAqB,CAAC,IAAY,EAAE,OAAe,EAAA;AACzD,QAAA,IAAI,OAAO,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,MAAM;;QAG9C,IAAI,GAAG,GAAG,OAAO;;AAGjB,QAAA,OAAO,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE;AACxB,YAAA,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE;AACxC,gBAAA,OAAO,GAAG,GAAG,CAAC,CAAC;YACjB;AACA,YAAA,GAAG,EAAE;QACP;AAEA,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB;AAEA,IAAA,OAAO,YAAY,CACjB,MAAoB,EACpB,gBAAmC,EAAA;QAEnC,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,IAAI;QAElD,OAAO,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;AAC3C,YAAA,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE;gBAC5B;YACF;AACA,YAAA,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AAE1D,YAAA,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC;AACxD,YAAA,IAAI,SAAiB;AAErB,YAAA,IAAI,IAAI,CAAC,cAAc,EAAE;gBACvB,SAAS,GAAG,IAAI,CAAC,qBAAqB,CAAC,aAAa,EAAE,YAAY,CAAC;YACrE;iBAAO;AACL,gBAAA,MAAM,cAAc,GAAG,aAAa,CAAC,MAAM;AAC3C,gBAAA,SAAS,GAAG,IAAI,CAAC,GAAG,CAClB,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,GAAG,CAAC,CAAC,EAC9C,cAAc,CACf;YACH;AAEA,YAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAC3B,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,YAAY,GAAG,SAAS,CAC9B;AACD,YAAA,gBAAgB,GAAG,KAAK,CAAC;AAEzB,YAAA,MAAM,KAAK;AACX,YAAA,IAAI,CAAC,YAAY,IAAI,SAAS;QAChC;IACF;;;;;"}