@ai-react-markdown/engine 2.9.1 → 2.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.dev.js CHANGED
@@ -4354,24 +4354,32 @@ var SMOOTH_STREAM_PACING_PRESETS = Object.freeze({
4354
4354
  correctionTauMs: 280,
4355
4355
  emaTauMs: 2600,
4356
4356
  minCharsPerSecond: 4,
4357
- drainMs: 320
4357
+ drainMs: 320,
4358
+ maxLagMs: 3500
4358
4359
  }),
4359
4360
  balanced: Object.freeze({
4360
4361
  bufferFactor: 1,
4361
4362
  correctionTauMs: 180,
4362
4363
  emaTauMs: 1800,
4363
4364
  minCharsPerSecond: 6,
4364
- drainMs: 240
4365
+ drainMs: 240,
4366
+ maxLagMs: 2500
4365
4367
  }),
4366
4368
  responsive: Object.freeze({
4367
4369
  bufferFactor: 0.45,
4368
4370
  correctionTauMs: 110,
4369
4371
  emaTauMs: 1100,
4370
4372
  minCharsPerSecond: 10,
4371
- drainMs: 150
4373
+ drainMs: 150,
4374
+ maxLagMs: 800
4372
4375
  })
4373
4376
  });
4374
- var MAX_TARGET_BUFFER_MS = 1200;
4377
+ var GAP_WINDOW = 16;
4378
+ var INTERVAL_QUANTILE = 0.9;
4379
+ var HORIZON_PAD_MS = 50;
4380
+ var DEADLINE_FLOOR_MS = 33;
4381
+ var DRAIN_CATCHUP_FACTOR = 2;
4382
+ var DRAIN_MAX_FACTOR = 3;
4375
4383
  var defaultNow = typeof performance !== "undefined" && typeof performance.now === "function" ? () => performance.now() : () => Date.now();
4376
4384
  var defaultSchedule = (cb) => {
4377
4385
  if (typeof requestAnimationFrame === "function") {
@@ -4422,18 +4430,18 @@ var createSmoothStreamController = (options = {}) => {
4422
4430
  let lastTickAt = 0;
4423
4431
  let cancelFrame;
4424
4432
  let disposed = false;
4425
- let rateEma;
4426
- let intervalEma;
4433
+ let gapWindow = [];
4427
4434
  let lastArrivalAt;
4428
4435
  const listeners = /* @__PURE__ */ new Set();
4429
4436
  const resolveParams = () => {
4430
- const preset = SMOOTH_STREAM_PACING_PRESETS[options.pacing] ?? SMOOTH_STREAM_PACING_PRESETS.balanced;
4437
+ const preset = Object.hasOwn(SMOOTH_STREAM_PACING_PRESETS, options.pacing) ? SMOOTH_STREAM_PACING_PRESETS[options.pacing] : SMOOTH_STREAM_PACING_PRESETS.balanced;
4431
4438
  return {
4432
4439
  bufferFactor: finiteOr(options.bufferFactor, preset.bufferFactor),
4433
4440
  correctionTauMs: finiteOr(options.correctionTauMs, preset.correctionTauMs),
4434
4441
  emaTauMs: finiteOr(options.emaTauMs, preset.emaTauMs),
4435
4442
  minCharsPerSecond: finiteOr(options.minCharsPerSecond, preset.minCharsPerSecond),
4436
- drainMs: finiteOr(options.drainMs, preset.drainMs)
4443
+ drainMs: finiteOr(options.drainMs, preset.drainMs),
4444
+ maxLagMs: finiteOr(options.maxLagMs, preset.maxLagMs ?? 2500)
4437
4445
  };
4438
4446
  };
4439
4447
  const recordArrival = (t, added) => {
@@ -4444,12 +4452,8 @@ var createSmoothStreamController = (options = {}) => {
4444
4452
  }
4445
4453
  const gap = Math.max(1, t - lastArrivalAt);
4446
4454
  lastArrivalAt = t;
4447
- const tau = Math.max(1, resolveParams().emaTauMs);
4448
- if (gap > tau) return;
4449
- const alpha = 1 - Math.exp(-gap / tau);
4450
- const instantRate = added * 1e3 / gap;
4451
- rateEma = (rateEma ?? 0) + alpha * (instantRate - (rateEma ?? 0));
4452
- intervalEma = (intervalEma ?? 0) + alpha * (gap - (intervalEma ?? 0));
4455
+ gapWindow.push({ gap, added });
4456
+ if (gapWindow.length > GAP_WINDOW) gapWindow.shift();
4453
4457
  };
4454
4458
  const notify = () => {
4455
4459
  visibleCache = source.slice(0, visibleEnd);
@@ -4475,15 +4479,12 @@ var createSmoothStreamController = (options = {}) => {
4475
4479
  let rate;
4476
4480
  if (finished && drainDeadlineAt !== void 0) {
4477
4481
  rate = Math.max(params.minCharsPerSecond, pending.length * 1e3 / Math.max(1, drainDeadlineAt - t));
4478
- } else if (rateEma !== void 0 && intervalEma !== void 0) {
4479
- const targetBuffer = Math.max(
4480
- 1,
4481
- Math.min(params.bufferFactor * rateEma * (intervalEma / 1e3), rateEma * MAX_TARGET_BUFFER_MS / 1e3)
4482
- );
4483
- rate = Math.max(
4484
- params.minCharsPerSecond,
4485
- rateEma + (pending.length - targetBuffer) * 1e3 / Math.max(1, params.correctionTauMs)
4486
- );
4482
+ } else if (gapWindow.length > 0 && lastArrivalAt !== void 0) {
4483
+ const gaps = gapWindow.map((s) => s.gap).sort((a, b) => a - b);
4484
+ const intervalQ = gaps[Math.min(gaps.length - 1, Math.floor(gaps.length * INTERVAL_QUANTILE))];
4485
+ const horizon = Math.max(16, Math.min(params.bufferFactor * intervalQ + HORIZON_PAD_MS, params.maxLagMs));
4486
+ const deadline = Math.max(lastArrivalAt + horizon, t + DEADLINE_FLOOR_MS);
4487
+ rate = Math.max(params.minCharsPerSecond, pending.length * 1e3 / Math.max(1, deadline - t));
4487
4488
  } else {
4488
4489
  rate = Math.max(params.minCharsPerSecond, pending.length * 1e3 / Math.max(1, params.correctionTauMs));
4489
4490
  }
@@ -4529,8 +4530,7 @@ var createSmoothStreamController = (options = {}) => {
4529
4530
  initialized = true;
4530
4531
  finished = false;
4531
4532
  drainDeadlineAt = void 0;
4532
- rateEma = void 0;
4533
- intervalEma = void 0;
4533
+ gapWindow = [];
4534
4534
  lastArrivalAt = void 0;
4535
4535
  source = next;
4536
4536
  visibleEnd = next.length;
@@ -4567,10 +4567,26 @@ var createSmoothStreamController = (options = {}) => {
4567
4567
  if (finished) return;
4568
4568
  finished = true;
4569
4569
  lastArrivalAt = void 0;
4570
- drainDeadlineAt = now() + resolveParams().drainMs;
4571
4570
  if (tentativeEnd > (pending.length > 0 ? pending[pending.length - 1] : visibleEnd)) {
4572
4571
  pending.push(tentativeEnd);
4573
4572
  }
4573
+ const params = resolveParams();
4574
+ let drainWin = params.drainMs;
4575
+ let chars = 0;
4576
+ let ms = 0;
4577
+ for (let i = 0; i < gapWindow.length - 1; i += 1) {
4578
+ chars += gapWindow[i].added;
4579
+ ms += gapWindow[i].gap;
4580
+ }
4581
+ const backlog = source.length - visibleEnd;
4582
+ if (chars > 0 && ms > 0 && backlog > 0) {
4583
+ const throughput = chars * 1e3 / ms;
4584
+ drainWin = Math.min(
4585
+ Math.max(backlog * 1e3 / (DRAIN_CATCHUP_FACTOR * throughput), params.drainMs),
4586
+ DRAIN_MAX_FACTOR * params.drainMs
4587
+ );
4588
+ }
4589
+ drainDeadlineAt = now() + drainWin;
4574
4590
  seam = source.length;
4575
4591
  ensureScheduled();
4576
4592
  },
@@ -4902,8 +4918,20 @@ function escapeLatexPipesInUnclosed(text) {
4902
4918
  const tail = text.substring(unclosedStart + delimLen);
4903
4919
  return before + delim + replaceUnescapedPipes(tail);
4904
4920
  }
4921
+ function opensMathFlow(text, pos) {
4922
+ let i = pos;
4923
+ let spaces = 0;
4924
+ while (i > 0 && text[i - 1] !== "\n") {
4925
+ i -= 1;
4926
+ if (text[i] !== " ") return false;
4927
+ spaces += 1;
4928
+ if (spaces > 3) return false;
4929
+ }
4930
+ return true;
4931
+ }
4905
4932
  function truncateUnclosedLatexBlock(text, unclosedStart = findUnclosedDelimiterStart(text, "double-only")) {
4906
4933
  if (unclosedStart === -1) return text;
4934
+ if (!opensMathFlow(text, unclosedStart)) return text;
4907
4935
  return text.substring(0, unclosedStart).trimEnd();
4908
4936
  }
4909
4937
  function escapeTextUnderscores(text) {
@@ -5004,7 +5032,7 @@ function processSlice(slice, probe = true) {
5004
5032
  unclosedDouble = findUnclosedDelimiterStart(text, "double-only");
5005
5033
  if (unclosedDouble !== -1) {
5006
5034
  quiescent = false;
5007
- if (index === 0 && text.slice(0, unclosedDouble).trim() === "") {
5035
+ if (index === 0 && opensMathFlow(text, unclosedDouble) && text.slice(0, unclosedDouble).trim() === "") {
5008
5036
  truncatedAtSeamStart = true;
5009
5037
  }
5010
5038
  }