@stream-mdx/react 0.4.0 → 1.0.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.
Files changed (106) hide show
  1. package/CHANGELOG.md +385 -4
  2. package/README.md +141 -16
  3. package/dist/blocks-renderer-DAOBFBfi.d.ts +29 -0
  4. package/dist/blocks-renderer-DQEL1kJW.d.cts +29 -0
  5. package/dist/components/bottom-stick-scroll-area.cjs +268 -0
  6. package/dist/components/bottom-stick-scroll-area.d.cts +36 -0
  7. package/dist/components/bottom-stick-scroll-area.d.ts +36 -0
  8. package/dist/components/bottom-stick-scroll-area.mjs +249 -0
  9. package/dist/components/diff-renderer.cjs +86 -0
  10. package/dist/components/diff-renderer.d.cts +11 -0
  11. package/dist/components/diff-renderer.d.ts +11 -0
  12. package/dist/components/diff-renderer.mjs +66 -0
  13. package/dist/components/index.cjs +2879 -1295
  14. package/dist/components/index.d.cts +9 -2
  15. package/dist/components/index.d.ts +9 -2
  16. package/dist/components/index.mjs +2842 -1277
  17. package/dist/components/katex-math.cjs +220 -0
  18. package/dist/components/katex-math.d.cts +10 -0
  19. package/dist/components/katex-math.d.ts +10 -0
  20. package/dist/components/katex-math.mjs +188 -0
  21. package/dist/contexts/math-tracker.cjs +240 -521
  22. package/dist/contexts/math-tracker.mjs +235 -513
  23. package/dist/index-Cmne1yUK.d.cts +723 -0
  24. package/dist/index-D7dyyu3q.d.ts +723 -0
  25. package/dist/index.cjs +13180 -5640
  26. package/dist/index.d.cts +72 -40
  27. package/dist/index.d.ts +72 -40
  28. package/dist/index.mjs +12587 -5038
  29. package/dist/math/display-wrapper.cjs +7 -15
  30. package/dist/math/display-wrapper.d.cts +2 -2
  31. package/dist/math/display-wrapper.d.ts +2 -2
  32. package/dist/math/display-wrapper.mjs +2 -6
  33. package/dist/node-views-Bpc6Gkgl.d.cts +13 -0
  34. package/dist/node-views-DpnYdaAS.d.ts +13 -0
  35. package/dist/renderer/hooks.cjs +35 -20
  36. package/dist/renderer/hooks.d.cts +22 -1
  37. package/dist/renderer/hooks.d.ts +22 -1
  38. package/dist/renderer/hooks.mjs +27 -12
  39. package/dist/renderer/patch-batching.cjs +7 -8
  40. package/dist/renderer/patch-batching.d.cts +1 -1
  41. package/dist/renderer/patch-batching.d.ts +1 -1
  42. package/dist/renderer/patch-batching.mjs +2 -1
  43. package/dist/renderer/patch-coalescing.cjs +5 -8
  44. package/dist/renderer/patch-commit-scheduler.cjs +160 -326
  45. package/dist/renderer/patch-commit-scheduler.d.cts +28 -4
  46. package/dist/renderer/patch-commit-scheduler.d.ts +28 -4
  47. package/dist/renderer/patch-commit-scheduler.mjs +157 -318
  48. package/dist/renderer/store.cjs +3847 -1099
  49. package/dist/renderer/store.d.cts +111 -3
  50. package/dist/renderer/store.d.ts +111 -3
  51. package/dist/renderer/store.mjs +3847 -1085
  52. package/dist/renderer/virtualized-code.cjs +415 -71
  53. package/dist/renderer/virtualized-code.d.cts +24 -23
  54. package/dist/renderer/virtualized-code.d.ts +24 -23
  55. package/dist/renderer/virtualized-code.mjs +409 -62
  56. package/dist/renderer.cjs +10939 -3974
  57. package/dist/renderer.d.cts +100 -29
  58. package/dist/renderer.d.ts +100 -29
  59. package/dist/renderer.mjs +10711 -3697
  60. package/dist/server-regions-CPLHGli0.d.cts +32 -0
  61. package/dist/server-regions-mUhyoKi7.d.ts +32 -0
  62. package/dist/server.cjs +10286 -3365
  63. package/dist/server.d.cts +17 -247
  64. package/dist/server.d.ts +17 -247
  65. package/dist/server.mjs +10565 -3619
  66. package/dist/{streaming-markdown-DOc2uLiP.d.ts → streaming-markdown-yELbJxyH.d.ts} +51 -55
  67. package/dist/{streaming-markdown-D-JcByd9.d.cts → streaming-markdown-zVwFuaJG.d.cts} +51 -55
  68. package/dist/streaming-markdown.cjs +11828 -4879
  69. package/dist/streaming-markdown.d.cts +9 -2
  70. package/dist/streaming-markdown.d.ts +9 -2
  71. package/dist/streaming-markdown.mjs +11820 -4821
  72. package/dist/trusted-mdx/index.cjs +833 -0
  73. package/dist/trusted-mdx/index.d.cts +11 -0
  74. package/dist/trusted-mdx/index.d.ts +11 -0
  75. package/dist/trusted-mdx/index.mjs +807 -0
  76. package/dist/trusted-mdx/native-children-slot.cjs +45 -0
  77. package/dist/trusted-mdx/native-children-slot.d.cts +11 -0
  78. package/dist/trusted-mdx/native-children-slot.d.ts +11 -0
  79. package/dist/trusted-mdx/native-children-slot.mjs +24 -0
  80. package/dist/trusted-mdx/server.cjs +752 -0
  81. package/dist/trusted-mdx/server.d.cts +24 -0
  82. package/dist/trusted-mdx/server.d.ts +24 -0
  83. package/dist/trusted-mdx/server.mjs +724 -0
  84. package/dist/trusted-mdx-contract-ElKpkDI5.d.cts +113 -0
  85. package/dist/trusted-mdx-contract-ElKpkDI5.d.ts +113 -0
  86. package/dist/utils/inline-html.cjs +246 -147
  87. package/dist/utils/inline-html.d.cts +39 -6
  88. package/dist/utils/inline-html.d.ts +39 -6
  89. package/dist/utils/inline-html.mjs +237 -134
  90. package/package.json +52 -18
  91. package/shadcn/README.md +28 -0
  92. package/shadcn/bottom-stick-scroll-area.tsx +358 -0
  93. package/dist/index-D2MYusAM.d.cts +0 -248
  94. package/dist/index-D2MYusAM.d.ts +0 -248
  95. package/dist/mdx-client.cjs +0 -408
  96. package/dist/mdx-client.d.cts +0 -113
  97. package/dist/mdx-client.d.ts +0 -113
  98. package/dist/mdx-client.mjs +0 -369
  99. package/dist/mdx-coordinator.cjs +0 -563
  100. package/dist/mdx-coordinator.d.cts +0 -21
  101. package/dist/mdx-coordinator.d.ts +0 -21
  102. package/dist/mdx-coordinator.mjs +0 -529
  103. package/dist/renderer/node-views.cjs +0 -1642
  104. package/dist/renderer/node-views.d.cts +0 -12
  105. package/dist/renderer/node-views.d.ts +0 -12
  106. package/dist/renderer/node-views.mjs +0 -1616
@@ -1,5 +1,8 @@
1
1
  "use client";
2
2
 
3
+ // src/renderer/patch-commit-scheduler.ts
4
+ import { getPatchKind } from "@stream-mdx/core/perf/patch-batching";
5
+
3
6
  // src/renderer/patch-coalescing.ts
4
7
  import {
5
8
  DEFAULT_COALESCE_CONFIG,
@@ -10,227 +13,166 @@ import {
10
13
  } from "@stream-mdx/core";
11
14
 
12
15
  // src/renderer/patch-commit-scheduler.ts
13
- var DEFAULT_TIMEOUT_MS = 16;
14
- var COALESCING_DURATION_SAMPLE_LIMIT = 60;
15
- var COALESCING_DURATION_ACTIVATE_MS = 6;
16
- var COALESCING_DURATION_DEACTIVATE_MS = 4;
17
- var RETAIN_TOUCHED_IN_HISTORY = typeof process !== "undefined" && process.env ? process.env.NODE_ENV !== "production" : true;
18
- var EMPTY_TOUCHED_SET = /* @__PURE__ */ new Set();
16
+ var DEFAULT_TIMEOUT_MS = 16, COALESCING_DURATION_SAMPLE_LIMIT = 60, COALESCING_DURATION_ACTIVATE_MS = 6, COALESCING_DURATION_DEACTIVATE_MS = 4, RETAIN_TOUCHED_IN_HISTORY = typeof process < "u" && process.env ? process.env.NODE_ENV !== "production" : !0, EMPTY_TOUCHED_SET = /* @__PURE__ */ new Set();
17
+ function semanticEnvelopeKeyForPatch(patch) {
18
+ if (getPatchKind(patch) !== "semantic") return;
19
+ let meta = patch.op === "setHTML" ? patch.patchMeta : patch.meta, streamSeq = meta?.streamSeq, parseEpoch = meta?.parseEpoch, tx = meta?.tx;
20
+ if (!(typeof streamSeq != "number" || !Number.isFinite(streamSeq) || streamSeq < 0 || typeof parseEpoch != "number" || !Number.isFinite(parseEpoch) || parseEpoch < 0 || typeof tx != "number" || !Number.isFinite(tx) || tx < 0))
21
+ return `${streamSeq}/${parseEpoch}/${tx}`;
22
+ }
23
+ function shouldSkipCoalescing(patches) {
24
+ if (patches.length <= 1) return !0;
25
+ let firstEnvelopeKey, hasEnvelopeKey = !1, hasMultipleEnvelopes = !1, hasUnsequencedSemantic = !1, hasEnrichment = !1, observePatch = (patch) => {
26
+ if (getPatchKind(patch) === "enrichment") {
27
+ hasEnrichment = !0;
28
+ return;
29
+ }
30
+ let key = semanticEnvelopeKeyForPatch(patch);
31
+ if (key === void 0) {
32
+ hasUnsequencedSemantic = !0;
33
+ return;
34
+ }
35
+ hasEnvelopeKey && firstEnvelopeKey !== key && (hasMultipleEnvelopes = !0), hasEnvelopeKey || (firstEnvelopeKey = key, hasEnvelopeKey = !0);
36
+ };
37
+ for (let patch of patches)
38
+ if (patch.op === "setPropsBatch")
39
+ for (let entry of patch.entries ?? [])
40
+ !entry || !entry.at || observePatch({
41
+ op: "setProps",
42
+ at: entry.at,
43
+ props: entry.props,
44
+ meta: { ...patch.meta ?? {}, ...entry.meta ?? {} }
45
+ });
46
+ else
47
+ observePatch(patch);
48
+ return hasEnvelopeKey && (hasMultipleEnvelopes || hasUnsequencedSemantic || hasEnrichment);
49
+ }
19
50
  function getDefaultNow() {
20
- if (typeof performance !== "undefined" && typeof performance.now === "function") {
21
- return () => performance.now();
22
- }
23
- return () => Date.now();
51
+ return typeof performance < "u" && typeof performance.now == "function" ? () => performance.now() : () => Date.now();
24
52
  }
25
53
  function getDefaultRaf() {
26
- if (typeof globalThis !== "undefined") {
27
- const candidate = globalThis.requestAnimationFrame;
28
- if (typeof candidate === "function") {
54
+ if (typeof globalThis < "u") {
55
+ let candidate = globalThis.requestAnimationFrame;
56
+ if (typeof candidate == "function")
29
57
  return candidate.bind(globalThis);
30
- }
31
58
  }
32
59
  return null;
33
60
  }
34
61
  function getDefaultCancelRaf() {
35
- if (typeof globalThis !== "undefined") {
36
- const candidate = globalThis.cancelAnimationFrame;
37
- if (typeof candidate === "function") {
62
+ if (typeof globalThis < "u") {
63
+ let candidate = globalThis.cancelAnimationFrame;
64
+ if (typeof candidate == "function")
38
65
  return candidate.bind(globalThis);
39
- }
40
66
  }
41
67
  return null;
42
68
  }
43
69
  var PatchCommitScheduler = class {
44
70
  constructor(params) {
45
- this.highQueue = [];
46
- this.lowQueue = [];
47
- this.scheduled = false;
48
- this.flushing = false;
71
+ this.semanticQueue = [];
72
+ this.enrichmentHighQueue = [];
73
+ this.enrichmentLowQueue = [];
74
+ this.scheduled = !1;
75
+ this.flushing = !1;
49
76
  this.scheduledHandle = null;
50
- this.scheduledViaRaf = false;
77
+ this.scheduledViaRaf = !1;
51
78
  this.sequence = 0;
52
79
  this.idleResolvers = [];
53
- this.paused = false;
80
+ this.paused = !1;
54
81
  this.history = [];
55
82
  this.scheduleToken = 0;
56
83
  this.coalescingDurationSamples = [];
57
- this.adaptiveBudgetActive = false;
58
- this.store = params.store;
59
- this.onFlush = params.onFlush;
60
- this.frameBudgetMs = Math.max(1, params.options?.frameBudgetMs ?? 10);
61
- this.maxBatchesPerFlush = params.options?.maxBatchesPerFlush ?? 12;
62
- this.now = params.options?.now ?? getDefaultNow();
63
- this.raf = params.options?.raf ?? getDefaultRaf();
64
- this.cancelRaf = params.options?.cancelRaf ?? getDefaultCancelRaf();
65
- this.timeoutMs = Math.max(1, params.options?.timeoutMs ?? DEFAULT_TIMEOUT_MS);
66
- this.lowPriorityFrameBudgetMs = Math.max(
84
+ this.adaptiveBudgetActive = !1;
85
+ this.flushCount = 0;
86
+ this.store = params.store, this.onFlush = params.onFlush, this.isGenerationCurrent = params.isGenerationCurrent, this.frameBudgetMs = Math.max(1, params.options?.frameBudgetMs ?? 4), this.maxBatchesPerFlush = params.options?.maxBatchesPerFlush ?? 12, this.now = params.options?.now ?? getDefaultNow(), this.raf = params.options?.raf ?? getDefaultRaf(), this.cancelRaf = params.options?.cancelRaf ?? getDefaultCancelRaf(), this.timeoutMs = Math.max(1, params.options?.timeoutMs ?? DEFAULT_TIMEOUT_MS), this.lowPriorityFrameBudgetMs = Math.max(
67
87
  1,
68
88
  params.options?.lowPriorityFrameBudgetMs ?? Math.max(2, Math.floor(this.frameBudgetMs * 0.6))
69
- );
70
- this.maxLowPriorityBatchesPerFlush = params.options?.maxLowPriorityBatchesPerFlush ?? 2;
71
- this.urgentQueueThreshold = Math.max(1, params.options?.urgentQueueThreshold ?? 4);
72
- this.historyLimit = Math.max(1, params.options?.historyLimit ?? 200);
73
- const requestedBatch = params.options?.batch;
74
- if (requestedBatch === "microtask") {
75
- this.batchStrategy = "microtask";
76
- } else if (requestedBatch === "timeout") {
77
- this.batchStrategy = "timeout";
78
- } else if (requestedBatch === "rAF") {
79
- this.batchStrategy = this.raf ? "rAF" : "timeout";
80
- } else {
81
- this.batchStrategy = "microtask";
82
- }
83
- if (this.batchStrategy === "microtask" && typeof queueMicrotask !== "function") {
84
- this.batchStrategy = this.raf ? "rAF" : "timeout";
85
- }
89
+ ), this.maxLowPriorityBatchesPerFlush = params.options?.maxLowPriorityBatchesPerFlush ?? 2, this.urgentQueueThreshold = Math.max(1, params.options?.urgentQueueThreshold ?? 4), this.historyLimit = Math.max(1, params.options?.historyLimit ?? 200), this.startupMicrotaskFlushes = Math.max(0, Math.floor(params.options?.startupMicrotaskFlushes ?? 0)), this.adaptiveBudgeting = params.options?.adaptiveBudgeting ?? !0;
90
+ let requestedBatch = params.options?.batch;
91
+ requestedBatch === "microtask" ? this.batchStrategy = "microtask" : requestedBatch === "timeout" ? this.batchStrategy = "timeout" : requestedBatch === "rAF" ? this.batchStrategy = this.raf ? "rAF" : "timeout" : this.batchStrategy = this.raf ? "rAF" : "timeout", this.batchStrategy === "microtask" && typeof queueMicrotask != "function" && (this.batchStrategy = this.raf ? "rAF" : "timeout");
86
92
  }
87
93
  enqueue(input) {
88
- if (!input || !input.patches || input.patches.length === 0) {
94
+ if (!input || !input.patches || input.patches.length === 0)
89
95
  return;
90
- }
91
- if (!this.paused && !this.flushing && this.getPendingCount() >= this.urgentQueueThreshold) {
92
- this.runFlush(this.frameBudgetMs, false);
93
- }
94
- const batch = {
96
+ this.batchStrategy !== "rAF" && !this.paused && !this.flushing && this.getPendingCount() >= this.urgentQueueThreshold && this.runFlush(this.frameBudgetMs, !1);
97
+ let explicitKind = input.meta?.kind, hasExplicitKind = explicitKind === "semantic" || explicitKind === "enrichment", hasSemanticPatch = !1, hasNonInputSourcePatch = !1;
98
+ for (let patch of input.patches)
99
+ patch.op !== "appendInputSource" && (hasNonInputSourcePatch = !0), !hasExplicitKind && !hasSemanticPatch && getPatchKind(patch) === "semantic" && (hasSemanticPatch = !0);
100
+ let batch = {
95
101
  seq: ++this.sequence,
96
102
  patches: input.patches,
97
103
  meta: input.meta ?? {},
98
104
  receivedAt: input.meta?.receivedAt ?? this.now(),
105
+ kind: explicitKind === "semantic" || explicitKind === "enrichment" ? explicitKind : hasSemanticPatch ? "semantic" : "enrichment",
106
+ hasNonInputSourcePatch,
99
107
  priority: input.meta?.priority === "low" ? "low" : "high"
100
108
  };
101
- if (batch.priority === "low") {
102
- this.lowQueue.push(batch);
103
- } else {
104
- this.highQueue.push(batch);
105
- }
106
- if (!this.paused) {
107
- this.schedule();
108
- }
109
+ batch.kind === "semantic" ? (batch.priority = "high", this.semanticQueue.push(batch)) : batch.priority === "low" ? this.enrichmentLowQueue.push(batch) : this.enrichmentHighQueue.push(batch), this.paused || this.schedule();
109
110
  }
110
111
  flushAll() {
111
- if (this.highQueue.length === 0 && this.lowQueue.length === 0 && !this.flushing) {
112
+ if (this.semanticQueue.length === 0 && this.enrichmentHighQueue.length === 0 && this.enrichmentLowQueue.length === 0 && !this.flushing)
112
113
  return null;
113
- }
114
114
  this.cancelScheduled();
115
- const result = this.runFlush(Number.POSITIVE_INFINITY, true);
116
- this.maybeResolveIdle();
117
- return result;
115
+ let result = this.runFlush(Number.POSITIVE_INFINITY, !0);
116
+ return this.maybeResolveIdle(), result;
118
117
  }
119
118
  clear() {
120
- this.cancelScheduled();
121
- this.highQueue = [];
122
- this.lowQueue = [];
123
- this.flushing = false;
124
- this.coalescingDurationSamples = [];
125
- this.adaptiveBudgetActive = false;
126
- this.adaptiveHighBatchCap = void 0;
127
- this.adaptiveLowBatchCap = void 0;
128
- this.maybeResolveIdle();
119
+ this.cancelScheduled(), this.semanticQueue = [], this.enrichmentHighQueue = [], this.enrichmentLowQueue = [], this.flushing = !1, this.flushCount = 0, this.coalescingDurationSamples = [], this.adaptiveBudgetActive = !1, this.adaptiveHighBatchCap = void 0, this.adaptiveLowBatchCap = void 0, this.maybeResolveIdle();
129
120
  }
130
121
  getPendingCount() {
131
- return this.highQueue.length + this.lowQueue.length;
122
+ return this.semanticQueue.length + this.enrichmentHighQueue.length + this.enrichmentLowQueue.length;
132
123
  }
133
124
  isIdle() {
134
- return !this.flushing && !this.scheduled && this.highQueue.length === 0 && this.lowQueue.length === 0;
125
+ return !this.flushing && !this.scheduled && this.semanticQueue.length === 0 && this.enrichmentHighQueue.length === 0 && this.enrichmentLowQueue.length === 0;
135
126
  }
136
127
  awaitIdle() {
137
- if (this.isIdle()) {
138
- return Promise.resolve();
139
- }
140
- return new Promise((resolve) => {
128
+ return this.isIdle() ? Promise.resolve() : new Promise((resolve) => {
141
129
  this.idleResolvers.push(resolve);
142
130
  });
143
131
  }
144
132
  schedule() {
145
- if (this.paused) {
146
- return;
147
- }
148
- if (this.scheduled || this.flushing) {
133
+ if (this.paused || this.scheduled || this.flushing)
149
134
  return;
150
- }
151
- const token = ++this.scheduleToken;
152
- this.scheduled = true;
153
- const execute = () => {
135
+ let token = ++this.scheduleToken;
136
+ this.scheduled = !0;
137
+ let execute = () => {
154
138
  if (token !== this.scheduleToken) {
155
- this.scheduled = false;
156
- this.scheduledHandle = null;
157
- this.scheduledViaRaf = false;
158
- this.maybeResolveIdle();
139
+ this.scheduled = !1, this.scheduledHandle = null, this.scheduledViaRaf = !1, this.maybeResolveIdle();
159
140
  return;
160
141
  }
161
142
  if (this.paused) {
162
- this.scheduled = false;
163
- this.scheduledHandle = null;
164
- this.scheduledViaRaf = false;
165
- this.maybeResolveIdle();
143
+ this.scheduled = !1, this.scheduledHandle = null, this.scheduledViaRaf = !1, this.maybeResolveIdle();
166
144
  return;
167
145
  }
168
- this.scheduled = false;
169
- this.scheduledHandle = null;
170
- this.scheduledViaRaf = false;
171
- this.runFlush(this.frameBudgetMs, false);
172
- this.maybeResolveIdle();
173
- };
174
- if (this.batchStrategy === "microtask" && typeof queueMicrotask === "function") {
175
- this.scheduledViaRaf = false;
176
- this.scheduledHandle = token;
177
- queueMicrotask(execute);
178
- } else if (this.batchStrategy === "rAF" && this.raf) {
179
- this.scheduledViaRaf = true;
180
- this.scheduledHandle = this.raf(() => execute());
181
- } else {
182
- this.scheduledViaRaf = false;
183
- this.scheduledHandle = setTimeout(() => execute(), this.timeoutMs);
184
- }
146
+ this.scheduled = !1, this.scheduledHandle = null, this.scheduledViaRaf = !1, this.runFlush(this.frameBudgetMs, !1), this.maybeResolveIdle();
147
+ }, useStartupMicrotask = this.batchStrategy !== "microtask" && this.startupMicrotaskFlushes > 0 && this.flushCount < this.startupMicrotaskFlushes && typeof queueMicrotask == "function";
148
+ (this.batchStrategy === "microtask" || useStartupMicrotask) && typeof queueMicrotask == "function" ? (this.scheduledViaRaf = !1, this.scheduledHandle = token, queueMicrotask(execute)) : this.batchStrategy === "rAF" && this.raf ? (this.scheduledViaRaf = !0, this.scheduledHandle = this.raf(() => execute())) : (this.scheduledViaRaf = !1, this.scheduledHandle = setTimeout(() => execute(), this.timeoutMs));
185
149
  }
186
150
  cancelScheduled() {
187
- if (!this.scheduled) return;
188
- this.scheduleToken++;
189
- if (this.scheduledHandle !== null) {
190
- if (this.scheduledViaRaf && this.cancelRaf) {
191
- this.cancelRaf(this.scheduledHandle);
192
- } else {
193
- clearTimeout(this.scheduledHandle);
194
- }
195
- }
196
- this.scheduled = false;
197
- this.scheduledHandle = null;
198
- this.scheduledViaRaf = false;
151
+ this.scheduled && (this.scheduleToken++, this.scheduledHandle !== null && (this.scheduledViaRaf && this.cancelRaf ? this.cancelRaf(this.scheduledHandle) : clearTimeout(this.scheduledHandle)), this.scheduled = !1, this.scheduledHandle = null, this.scheduledViaRaf = !1);
199
152
  }
200
153
  runFlush(budgetMs, manual) {
201
- if (this.paused && !manual) {
202
- return null;
203
- }
204
- if (this.highQueue.length === 0 && this.lowQueue.length === 0) {
154
+ if (this.paused && !manual || this.semanticQueue.length === 0 && this.enrichmentHighQueue.length === 0 && this.enrichmentLowQueue.length === 0)
205
155
  return null;
206
- }
207
- this.flushing = true;
208
- const startedAt = this.now();
209
- const initialQueueSize = this.highQueue.length + this.lowQueue.length;
210
- const batches = [];
211
- let totalInputPatches = 0;
212
- let totalAppliedPatches = 0;
213
- let elapsed = 0;
214
- const processQueue = (queue, maxBatches, budgetLimit) => {
215
- const effectiveBudget = manual ? Number.POSITIVE_INFINITY : Math.max(0, budgetLimit ?? budgetMs);
216
- const startingBatchCount = batches.length;
217
- let consumed = 0;
218
- while (consumed < queue.length) {
219
- const next = queue[consumed];
156
+ this.flushing = !0;
157
+ let startedAt = this.now(), elapsed = 0, initialSemanticQueueSize = this.semanticQueue.length, initialEnrichmentQueueSize = this.enrichmentHighQueue.length + this.enrichmentLowQueue.length, initialQueueSize = initialSemanticQueueSize + initialEnrichmentQueueSize, batches = [], totalInputPatches = 0, totalAppliedPatches = 0, hasNonInputSourcePatch = !1, processQueue = (queue, maxBatches, budgetLimit) => {
158
+ let effectiveBudget = manual ? Number.POSITIVE_INFINITY : Math.max(0, budgetLimit ?? budgetMs), startingBatchCount = batches.length, consumed = 0;
159
+ for (; consumed < queue.length; ) {
160
+ let next = queue[consumed];
220
161
  if (!next) break;
221
- consumed += 1;
222
- const applyStart = this.now();
223
- const queueDelayMs = Math.max(0, applyStart - next.receivedAt);
224
- const { patches: coalesced, metrics: coalescingMetrics } = coalescePatchesWithMetrics(next.patches, DEFAULT_COALESCE_CONFIG);
225
- const touched = this.store.applyPatches(coalesced, {
226
- coalesced: true,
162
+ if (consumed += 1, next.meta.generation !== void 0 && this.isGenerationCurrent && !this.isGenerationCurrent(next.meta.generation)) continue;
163
+ hasNonInputSourcePatch || (hasNonInputSourcePatch = next.hasNonInputSourcePatch);
164
+ let applyStart = this.now(), queueDelayMs = Math.max(0, applyStart - next.receivedAt), coalesced, coalescingMetrics;
165
+ if (shouldSkipCoalescing(next.patches))
166
+ coalesced = next.patches;
167
+ else {
168
+ let result = coalescePatchesWithMetrics(next.patches, DEFAULT_COALESCE_CONFIG);
169
+ coalesced = result.patches, coalescingMetrics = result.metrics;
170
+ }
171
+ let touched = this.store.applyPatches(coalesced, {
172
+ coalesced: !0,
227
173
  metrics: coalescingMetrics
228
- });
229
- const durationMs = this.now() - applyStart;
230
- this.recordCoalescingDuration(coalescingMetrics?.durationMs);
231
- totalInputPatches += next.patches.length;
232
- totalAppliedPatches += coalesced.length;
233
- batches.push({
174
+ }), durationMs = this.now() - applyStart;
175
+ if (this.recordCoalescingDuration(coalescingMetrics?.durationMs), totalInputPatches += next.patches.length, totalAppliedPatches += coalesced.length, batches.push({
234
176
  tx: next.meta.tx,
235
177
  metrics: next.meta.metrics,
236
178
  patchCount: next.patches.length,
@@ -241,43 +183,30 @@ var PatchCommitScheduler = class {
241
183
  receivedAt: next.receivedAt,
242
184
  appliedAt: applyStart,
243
185
  priority: next.priority,
186
+ kind: next.kind,
244
187
  coalescing: coalescingMetrics
245
- });
246
- if (maxBatches && batches.length - startingBatchCount >= maxBatches) {
188
+ }), maxBatches && batches.length - startingBatchCount >= maxBatches || !manual && (elapsed = this.now() - startedAt, elapsed >= effectiveBudget))
247
189
  break;
248
- }
249
- if (!manual) {
250
- elapsed = this.now() - startedAt;
251
- if (elapsed >= effectiveBudget) {
252
- break;
253
- }
254
- }
255
- }
256
- if (consumed > 0) {
257
- queue.splice(0, consumed);
258
190
  }
191
+ consumed > 0 && queue.splice(0, consumed);
259
192
  };
260
- const initialHighQueueSize = this.highQueue.length;
261
- const configuredHighLimit = manual || !this.maxBatchesPerFlush ? void 0 : initialHighQueueSize > this.maxBatchesPerFlush ? void 0 : this.maxBatchesPerFlush;
262
- const highBatchLimit = this.adaptiveHighBatchCap ?? configuredHighLimit;
263
- processQueue(this.highQueue, highBatchLimit, budgetMs);
264
- if (manual) {
265
- processQueue(this.lowQueue, void 0, Number.POSITIVE_INFINITY);
266
- } else if (this.lowQueue.length > 0) {
267
- elapsed = this.now() - startedAt;
268
- const budgetForLow = Math.max(0, this.lowPriorityFrameBudgetMs - elapsed);
269
- if (budgetForLow > 0) {
270
- const initialLowQueueSize = this.lowQueue.length;
271
- const configuredLowLimit = manual || !this.maxLowPriorityBatchesPerFlush ? void 0 : initialLowQueueSize > this.maxLowPriorityBatchesPerFlush ? void 0 : this.maxLowPriorityBatchesPerFlush;
272
- const lowBatchLimit = this.adaptiveLowBatchCap ?? configuredLowLimit;
273
- processQueue(this.lowQueue, lowBatchLimit, budgetForLow);
193
+ if (processQueue(this.semanticQueue, void 0, budgetMs), this.semanticQueue.length === 0) {
194
+ let initialHighQueueSize = this.enrichmentHighQueue.length, configuredHighLimit = manual || !this.maxBatchesPerFlush || initialHighQueueSize > this.maxBatchesPerFlush ? void 0 : this.maxBatchesPerFlush, highBatchLimit = this.adaptiveBudgeting ? this.adaptiveHighBatchCap ?? configuredHighLimit : configuredHighLimit;
195
+ if (processQueue(this.enrichmentHighQueue, highBatchLimit, budgetMs), manual)
196
+ processQueue(this.enrichmentLowQueue, void 0, Number.POSITIVE_INFINITY);
197
+ else if (this.enrichmentLowQueue.length > 0) {
198
+ elapsed = this.now() - startedAt;
199
+ let budgetForLow = Math.max(0, this.lowPriorityFrameBudgetMs - elapsed), processedHigherPriorityWork = batches.length > 0;
200
+ if (budgetForLow > 0 || !processedHigherPriorityWork) {
201
+ let initialLowQueueSize = this.enrichmentLowQueue.length, configuredLowLimit = this.maxLowPriorityBatchesPerFlush ? initialLowQueueSize > this.maxLowPriorityBatchesPerFlush ? void 0 : this.maxLowPriorityBatchesPerFlush : void 0, lowBatchLimit = this.adaptiveBudgeting ? this.adaptiveLowBatchCap ?? configuredLowLimit : configuredLowLimit;
202
+ processQueue(this.enrichmentLowQueue, lowBatchLimit, budgetForLow);
203
+ }
274
204
  }
275
205
  }
276
- this.flushing = false;
277
- const completedAt = this.now();
278
- const totalDurationMs = completedAt - startedAt;
279
- const remaining = this.highQueue.length + this.lowQueue.length;
206
+ this.flushing = !1;
207
+ let completedAt = this.now(), totalDurationMs = completedAt - startedAt, remainingSemantic = this.semanticQueue.length, remainingEnrichment = this.enrichmentHighQueue.length + this.enrichmentLowQueue.length, remaining = remainingSemantic + remainingEnrichment;
280
208
  if (batches.length > 0) {
209
+ this.flushCount += 1;
281
210
  try {
282
211
  this.onFlush({
283
212
  batches,
@@ -285,54 +214,48 @@ var PatchCommitScheduler = class {
285
214
  totalAppliedPatches,
286
215
  totalDurationMs,
287
216
  remainingQueueSize: remaining,
217
+ remainingSemanticQueueSize: remainingSemantic,
218
+ remainingEnrichmentQueueSize: remainingEnrichment,
288
219
  queueDepthBefore: initialQueueSize,
220
+ semanticQueueDepthBefore: initialSemanticQueueSize,
221
+ enrichmentQueueDepthBefore: initialEnrichmentQueueSize,
289
222
  flushStartedAt: startedAt,
290
223
  flushCompletedAt: completedAt
291
- });
224
+ }, hasNonInputSourcePatch);
292
225
  } catch (error) {
293
226
  console.error("[patch-scheduler] onFlush callback failed", error);
294
227
  }
295
228
  }
296
- if (remaining > 0 && !this.paused) {
297
- this.schedule();
298
- }
299
- const coalescingStats = this.computeCoalescingDurationStats();
300
- this.updateAdaptiveBudget(coalescingStats.p95);
301
- const adaptiveState = this.snapshotAdaptiveBudget(coalescingStats.p95 ?? null);
302
- const flushResult = batches.length > 0 ? {
229
+ remaining > 0 && !this.paused && this.schedule();
230
+ let coalescingStats = this.adaptiveBudgeting ? this.computeCoalescingDurationStats() : { sampleCount: this.coalescingDurationSamples.length, p95: null };
231
+ this.adaptiveBudgeting && this.updateAdaptiveBudget(coalescingStats.p95);
232
+ let adaptiveState = this.adaptiveBudgeting ? this.snapshotAdaptiveBudget(coalescingStats.p95 ?? null) : void 0, flushResult = batches.length > 0 ? {
303
233
  batches,
304
234
  totalPatches: totalInputPatches,
305
235
  totalAppliedPatches,
306
236
  totalDurationMs,
307
237
  remainingQueueSize: remaining,
238
+ remainingSemanticQueueSize: remainingSemantic,
239
+ remainingEnrichmentQueueSize: remainingEnrichment,
308
240
  queueDepthBefore: initialQueueSize,
241
+ semanticQueueDepthBefore: initialSemanticQueueSize,
242
+ enrichmentQueueDepthBefore: initialEnrichmentQueueSize,
309
243
  flushStartedAt: startedAt,
310
244
  flushCompletedAt: completedAt,
311
245
  coalescingDurationP95: coalescingStats.p95 ?? void 0,
312
246
  coalescingDurationSampleCount: coalescingStats.sampleCount,
313
- adaptiveBudgetActive: adaptiveState.active,
247
+ adaptiveBudgetActive: adaptiveState?.active,
314
248
  adaptiveBudgetState: adaptiveState
315
249
  } : null;
316
- if (flushResult) {
317
- this.recordHistory(flushResult);
318
- }
319
- return flushResult;
250
+ return flushResult && this.recordHistory(flushResult), flushResult;
320
251
  }
321
252
  recordCoalescingDuration(value) {
322
- if (typeof value !== "number" || !Number.isFinite(value)) {
323
- return;
324
- }
325
- this.coalescingDurationSamples.push(value);
326
- if (this.coalescingDurationSamples.length > COALESCING_DURATION_SAMPLE_LIMIT) {
327
- this.coalescingDurationSamples.splice(0, this.coalescingDurationSamples.length - COALESCING_DURATION_SAMPLE_LIMIT);
328
- }
253
+ typeof value != "number" || !Number.isFinite(value) || (this.coalescingDurationSamples.push(value), this.coalescingDurationSamples.length > COALESCING_DURATION_SAMPLE_LIMIT && this.coalescingDurationSamples.splice(0, this.coalescingDurationSamples.length - COALESCING_DURATION_SAMPLE_LIMIT));
329
254
  }
330
255
  computeCoalescingDurationStats() {
331
- if (this.coalescingDurationSamples.length === 0) {
256
+ if (this.coalescingDurationSamples.length === 0)
332
257
  return { sampleCount: 0, p95: null };
333
- }
334
- const sorted = [...this.coalescingDurationSamples].sort((a, b) => a - b);
335
- const index = Math.min(sorted.length - 1, Math.max(0, Math.floor(0.95 * (sorted.length - 1))));
258
+ let sorted = [...this.coalescingDurationSamples].sort((a, b) => a - b), index = Math.min(sorted.length - 1, Math.max(0, Math.floor(0.95 * (sorted.length - 1))));
336
259
  return { sampleCount: this.coalescingDurationSamples.length, p95: sorted[index] ?? null };
337
260
  }
338
261
  snapshotAdaptiveBudget(latestP95) {
@@ -342,50 +265,32 @@ var PatchCommitScheduler = class {
342
265
  lowBatchCap: this.adaptiveLowBatchCap,
343
266
  activateThresholdMs: COALESCING_DURATION_ACTIVATE_MS,
344
267
  deactivateThresholdMs: COALESCING_DURATION_DEACTIVATE_MS,
345
- lastObservedP95: typeof latestP95 === "number" ? latestP95 : null
268
+ lastObservedP95: typeof latestP95 == "number" ? latestP95 : null
346
269
  };
347
270
  }
348
271
  updateAdaptiveBudget(p95) {
349
- if (p95 !== null && p95 > COALESCING_DURATION_ACTIVATE_MS) {
350
- if (!this.adaptiveBudgetActive) {
351
- this.adaptiveBudgetActive = true;
352
- this.adaptiveHighBatchCap = this.computeAdaptiveCap(this.maxBatchesPerFlush, 2);
353
- this.adaptiveLowBatchCap = this.computeAdaptiveCap(this.maxLowPriorityBatchesPerFlush, 1);
354
- }
355
- } else if (this.adaptiveBudgetActive && (p95 === null || p95 < COALESCING_DURATION_DEACTIVATE_MS)) {
356
- this.adaptiveBudgetActive = false;
357
- this.adaptiveHighBatchCap = void 0;
358
- this.adaptiveLowBatchCap = void 0;
359
- }
272
+ this.adaptiveBudgeting && (p95 !== null && p95 > COALESCING_DURATION_ACTIVATE_MS ? this.adaptiveBudgetActive || (this.adaptiveBudgetActive = !0, this.adaptiveHighBatchCap = this.computeAdaptiveCap(this.maxBatchesPerFlush, 2), this.adaptiveLowBatchCap = this.computeAdaptiveCap(this.maxLowPriorityBatchesPerFlush, 1)) : this.adaptiveBudgetActive && (p95 === null || p95 < COALESCING_DURATION_DEACTIVATE_MS) && (this.adaptiveBudgetActive = !1, this.adaptiveHighBatchCap = void 0, this.adaptiveLowBatchCap = void 0));
360
273
  }
361
274
  computeAdaptiveCap(configured, fallback = 1) {
362
- if (configured === void 0 || configured <= 0) {
363
- return Math.max(1, fallback);
364
- }
365
- return Math.max(1, Math.floor(configured / 2));
275
+ return configured === void 0 || configured <= 0 ? Math.max(1, fallback) : Math.max(1, Math.floor(configured / 2));
366
276
  }
367
277
  maybeResolveIdle() {
368
- if (!this.isIdle()) {
278
+ if (!this.isIdle() || this.idleResolvers.length === 0)
369
279
  return;
370
- }
371
- if (this.idleResolvers.length === 0) {
372
- return;
373
- }
374
- const pending = this.idleResolvers.slice();
280
+ let pending = this.idleResolvers.slice();
375
281
  this.idleResolvers = [];
376
- for (const resolve of pending) {
282
+ for (let resolve of pending)
377
283
  try {
378
284
  resolve();
379
285
  } catch (error) {
380
286
  console.error("[patch-scheduler] idle resolver failed", error);
381
287
  }
382
- }
383
288
  }
384
289
  recordHistory(result) {
385
- if (RETAIN_TOUCHED_IN_HISTORY) {
290
+ if (RETAIN_TOUCHED_IN_HISTORY)
386
291
  this.history.push(result);
387
- } else {
388
- const trimmed = {
292
+ else {
293
+ let trimmed = {
389
294
  ...result,
390
295
  batches: result.batches.map((batch) => ({
391
296
  ...batch,
@@ -394,100 +299,34 @@ var PatchCommitScheduler = class {
394
299
  };
395
300
  this.history.push(trimmed);
396
301
  }
397
- if (this.history.length > this.historyLimit) {
398
- this.history.splice(0, this.history.length - this.historyLimit);
399
- }
302
+ this.history.length > this.historyLimit && this.history.splice(0, this.history.length - this.historyLimit);
400
303
  }
401
304
  pause() {
402
- if (this.paused) {
403
- return;
404
- }
405
- this.paused = true;
406
- this.cancelScheduled();
305
+ this.paused || (this.paused = !0, this.cancelScheduled());
407
306
  }
408
307
  resume() {
409
- if (!this.paused) {
410
- return;
411
- }
412
- this.paused = false;
413
- if (this.getPendingCount() > 0) {
414
- this.schedule();
415
- }
308
+ this.paused && (this.paused = !1, this.getPendingCount() > 0 && this.schedule());
416
309
  }
417
310
  isPaused() {
418
311
  return this.paused;
419
312
  }
420
313
  restart() {
421
- this.cancelScheduled();
422
- this.highQueue = [];
423
- this.lowQueue = [];
424
- this.flushing = false;
425
- this.sequence = 0;
426
- this.history = [];
427
- this.scheduleToken++;
428
- this.paused = false;
429
- this.coalescingDurationSamples = [];
430
- this.adaptiveBudgetActive = false;
431
- this.adaptiveHighBatchCap = void 0;
432
- this.adaptiveLowBatchCap = void 0;
433
- this.maybeResolveIdle();
314
+ this.cancelScheduled(), this.semanticQueue = [], this.enrichmentHighQueue = [], this.enrichmentLowQueue = [], this.flushing = !1, this.sequence = 0, this.history = [], this.flushCount = 0, this.scheduleToken++, this.paused = !1, this.coalescingDurationSamples = [], this.adaptiveBudgetActive = !1, this.adaptiveHighBatchCap = void 0, this.adaptiveLowBatchCap = void 0, this.maybeResolveIdle();
434
315
  }
435
316
  getHistory(limit) {
436
- if (limit === void 0 || limit >= this.history.length) {
437
- return [...this.history];
438
- }
439
- return this.history.slice(this.history.length - limit);
317
+ return limit === void 0 || limit >= this.history.length ? [...this.history] : this.history.slice(this.history.length - limit);
440
318
  }
441
319
  setHistoryLimit(limit) {
442
- this.historyLimit = Math.max(1, limit);
443
- if (this.history.length > this.historyLimit) {
444
- this.history.splice(0, this.history.length - this.historyLimit);
445
- }
320
+ this.historyLimit = Math.max(1, limit), this.history.length > this.historyLimit && this.history.splice(0, this.history.length - this.historyLimit);
446
321
  }
447
322
  updateOptions(options) {
448
323
  if (!options) return;
449
- let shouldReschedule = false;
450
- if (typeof options.frameBudgetMs !== "undefined") {
451
- this.frameBudgetMs = Math.max(1, options.frameBudgetMs);
452
- shouldReschedule = true;
453
- }
454
- if (typeof options.maxBatchesPerFlush !== "undefined") {
455
- this.maxBatchesPerFlush = options.maxBatchesPerFlush;
456
- shouldReschedule = true;
457
- }
458
- if (typeof options.lowPriorityFrameBudgetMs !== "undefined") {
459
- this.lowPriorityFrameBudgetMs = Math.max(1, options.lowPriorityFrameBudgetMs);
460
- shouldReschedule = true;
461
- }
462
- if (typeof options.maxLowPriorityBatchesPerFlush !== "undefined") {
463
- this.maxLowPriorityBatchesPerFlush = options.maxLowPriorityBatchesPerFlush;
464
- shouldReschedule = true;
465
- }
466
- if (typeof options.urgentQueueThreshold !== "undefined") {
467
- this.urgentQueueThreshold = Math.max(1, options.urgentQueueThreshold);
468
- shouldReschedule = true;
469
- }
470
- if (typeof options.historyLimit !== "undefined") {
471
- this.setHistoryLimit(options.historyLimit);
472
- }
473
- if (typeof options.batch !== "undefined") {
474
- const requestedBatch = options.batch;
475
- if (requestedBatch === "microtask") {
476
- this.batchStrategy = "microtask";
477
- } else if (requestedBatch === "timeout") {
478
- this.batchStrategy = "timeout";
479
- } else if (requestedBatch === "rAF") {
480
- this.batchStrategy = this.raf ? "rAF" : "timeout";
481
- }
482
- if (this.batchStrategy === "microtask" && typeof queueMicrotask !== "function") {
483
- this.batchStrategy = this.raf ? "rAF" : "timeout";
484
- }
485
- shouldReschedule = true;
486
- }
487
- if (shouldReschedule && !this.paused && !this.flushing && this.getPendingCount() > 0) {
488
- this.cancelScheduled();
489
- this.schedule();
324
+ let shouldReschedule = !1;
325
+ if (typeof options.frameBudgetMs < "u" && (this.frameBudgetMs = Math.max(1, options.frameBudgetMs), shouldReschedule = !0), typeof options.maxBatchesPerFlush < "u" && (this.maxBatchesPerFlush = options.maxBatchesPerFlush, shouldReschedule = !0), typeof options.lowPriorityFrameBudgetMs < "u" && (this.lowPriorityFrameBudgetMs = Math.max(1, options.lowPriorityFrameBudgetMs), shouldReschedule = !0), typeof options.maxLowPriorityBatchesPerFlush < "u" && (this.maxLowPriorityBatchesPerFlush = options.maxLowPriorityBatchesPerFlush, shouldReschedule = !0), typeof options.urgentQueueThreshold < "u" && (this.urgentQueueThreshold = Math.max(1, options.urgentQueueThreshold), shouldReschedule = !0), typeof options.historyLimit < "u" && this.setHistoryLimit(options.historyLimit), typeof options.startupMicrotaskFlushes < "u" && (this.startupMicrotaskFlushes = Math.max(0, Math.floor(options.startupMicrotaskFlushes))), typeof options.adaptiveBudgeting < "u" && (this.adaptiveBudgeting = options.adaptiveBudgeting), typeof options.batch < "u") {
326
+ let requestedBatch = options.batch;
327
+ requestedBatch === "microtask" ? this.batchStrategy = "microtask" : requestedBatch === "timeout" ? this.batchStrategy = "timeout" : requestedBatch === "rAF" && (this.batchStrategy = this.raf ? "rAF" : "timeout"), this.batchStrategy === "microtask" && typeof queueMicrotask != "function" && (this.batchStrategy = this.raf ? "rAF" : "timeout"), shouldReschedule = !0;
490
328
  }
329
+ shouldReschedule && !this.paused && !this.flushing && this.getPendingCount() > 0 && (this.cancelScheduled(), this.schedule());
491
330
  }
492
331
  clearHistory() {
493
332
  this.history = [];