@stream-mdx/worker 0.1.0 → 0.1.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/CHANGELOG.md +9 -0
- package/dist/hosted/markdown-worker.js +259 -26
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @stream-mdx/worker
|
|
2
2
|
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Refine streaming scheduling and list layout, add worker append batching/debug state support, and refresh docs/README examples.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
- @stream-mdx/core@0.1.1
|
|
10
|
+
- @stream-mdx/plugins@0.1.1
|
|
11
|
+
|
|
3
12
|
## 0.1.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
|
@@ -81968,6 +81968,12 @@ var documentPluginState = {};
|
|
|
81968
81968
|
var txCounter = 0;
|
|
81969
81969
|
var workerGrammarEngine = "js";
|
|
81970
81970
|
var workerCredits = 1;
|
|
81971
|
+
var lastDiffSummary = null;
|
|
81972
|
+
var lastStructuralDiffSummary = null;
|
|
81973
|
+
var maxEmittedBlockCount = 0;
|
|
81974
|
+
var maxDeferredQueueSize = 0;
|
|
81975
|
+
var maxStructuralBlockCount = 0;
|
|
81976
|
+
var lastHighCountNoStructural = null;
|
|
81971
81977
|
var MAX_DEFERRED_PATCHES = 400;
|
|
81972
81978
|
var deferredPatchQueue = [];
|
|
81973
81979
|
var MAX_DEFERRED_FLUSH_PATCHES = 120;
|
|
@@ -81984,6 +81990,50 @@ var MAX_WORKER_MDX_CACHE_ENTRIES = 128;
|
|
|
81984
81990
|
var loggedMdxSkipCount = 0;
|
|
81985
81991
|
var MAX_MDX_SKIP_LOGS = 20;
|
|
81986
81992
|
var MIXED_CONTENT_AUTOCLOSE_NEWLINES = 2;
|
|
81993
|
+
var DEFAULT_APPEND_CHUNK_SIZE = 1400;
|
|
81994
|
+
var DEFAULT_APPEND_BATCH_MS = 12;
|
|
81995
|
+
var MIN_APPEND_CHUNK_SIZE = 256;
|
|
81996
|
+
var MAX_APPEND_CHUNK_SIZE = 12e3;
|
|
81997
|
+
var MIN_APPEND_BATCH_MS = 4;
|
|
81998
|
+
var MAX_APPEND_BATCH_MS = 50;
|
|
81999
|
+
var APPEND_NEWLINE_GRACE = 200;
|
|
82000
|
+
function clampInt(value, min, max) {
|
|
82001
|
+
if (!Number.isFinite(value)) return min;
|
|
82002
|
+
return Math.min(max, Math.max(min, Math.floor(value)));
|
|
82003
|
+
}
|
|
82004
|
+
function readNumericEnv(key2) {
|
|
82005
|
+
try {
|
|
82006
|
+
if (typeof process !== "undefined" && process.env && process.env[key2]) {
|
|
82007
|
+
const parsed = Number(process.env[key2]);
|
|
82008
|
+
if (Number.isFinite(parsed)) {
|
|
82009
|
+
return parsed;
|
|
82010
|
+
}
|
|
82011
|
+
}
|
|
82012
|
+
} catch {
|
|
82013
|
+
}
|
|
82014
|
+
return null;
|
|
82015
|
+
}
|
|
82016
|
+
var APPEND_CHUNK_SIZE = clampInt(
|
|
82017
|
+
readNumericEnv("NEXT_PUBLIC_STREAMING_APPEND_CHUNK") ?? DEFAULT_APPEND_CHUNK_SIZE,
|
|
82018
|
+
MIN_APPEND_CHUNK_SIZE,
|
|
82019
|
+
MAX_APPEND_CHUNK_SIZE
|
|
82020
|
+
);
|
|
82021
|
+
var APPEND_BATCH_MS = clampInt(
|
|
82022
|
+
readNumericEnv("NEXT_PUBLIC_STREAMING_APPEND_BATCH_MS") ?? DEFAULT_APPEND_BATCH_MS,
|
|
82023
|
+
MIN_APPEND_BATCH_MS,
|
|
82024
|
+
MAX_APPEND_BATCH_MS
|
|
82025
|
+
);
|
|
82026
|
+
function sliceAppendChunk(text12, maxChars) {
|
|
82027
|
+
if (text12.length <= maxChars) {
|
|
82028
|
+
return { chunk: text12, rest: "" };
|
|
82029
|
+
}
|
|
82030
|
+
const newlineIndex = text12.lastIndexOf("\n", maxChars);
|
|
82031
|
+
const cut = newlineIndex > 0 && maxChars - newlineIndex <= APPEND_NEWLINE_GRACE ? newlineIndex + 1 : maxChars;
|
|
82032
|
+
return { chunk: text12.slice(0, cut), rest: text12.slice(cut) };
|
|
82033
|
+
}
|
|
82034
|
+
function waitForNextTick() {
|
|
82035
|
+
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
82036
|
+
}
|
|
81987
82037
|
function isDebugEnabled(flag) {
|
|
81988
82038
|
try {
|
|
81989
82039
|
if (typeof process !== "undefined" && process.env) {
|
|
@@ -82191,7 +82241,23 @@ function partitionPatchesForCredits(patches, maxImmediate) {
|
|
|
82191
82241
|
const immediate = [];
|
|
82192
82242
|
const deferred = [];
|
|
82193
82243
|
let heavyBudget = computeHeavyPatchBudget(workerCredits);
|
|
82244
|
+
let nonStructuralImmediate = 0;
|
|
82245
|
+
const isStructuralPatch = (patch5) => {
|
|
82246
|
+
switch (patch5.op) {
|
|
82247
|
+
case "insertChild":
|
|
82248
|
+
case "deleteChild":
|
|
82249
|
+
case "replaceChild":
|
|
82250
|
+
case "reorder":
|
|
82251
|
+
return true;
|
|
82252
|
+
default:
|
|
82253
|
+
return false;
|
|
82254
|
+
}
|
|
82255
|
+
};
|
|
82194
82256
|
for (const patch5 of combined) {
|
|
82257
|
+
if (isStructuralPatch(patch5)) {
|
|
82258
|
+
immediate.push(patch5);
|
|
82259
|
+
continue;
|
|
82260
|
+
}
|
|
82195
82261
|
const heavy = isHeavyPatch(patch5);
|
|
82196
82262
|
if (heavy) {
|
|
82197
82263
|
if (heavyBudget <= 0) {
|
|
@@ -82203,14 +82269,14 @@ function partitionPatchesForCredits(patches, maxImmediate) {
|
|
|
82203
82269
|
heavyBudget -= 1;
|
|
82204
82270
|
}
|
|
82205
82271
|
}
|
|
82272
|
+
if (typeof maxImmediate === "number" && nonStructuralImmediate >= maxImmediate) {
|
|
82273
|
+
deferred.push(patch5);
|
|
82274
|
+
continue;
|
|
82275
|
+
}
|
|
82206
82276
|
immediate.push(patch5);
|
|
82277
|
+
nonStructuralImmediate += 1;
|
|
82207
82278
|
}
|
|
82208
|
-
|
|
82209
|
-
const overflow = immediate.splice(maxImmediate);
|
|
82210
|
-
deferredPatchQueue = overflow.concat(deferred);
|
|
82211
|
-
} else {
|
|
82212
|
-
deferredPatchQueue = deferred;
|
|
82213
|
-
}
|
|
82279
|
+
deferredPatchQueue = deferred;
|
|
82214
82280
|
return immediate;
|
|
82215
82281
|
}
|
|
82216
82282
|
function flushDeferredPatches() {
|
|
@@ -82354,25 +82420,35 @@ async function initialize(initialContent = "", prewarmLangs = [], docPlugins, md
|
|
|
82354
82420
|
}
|
|
82355
82421
|
}
|
|
82356
82422
|
async function handleAppend(text12) {
|
|
82357
|
-
|
|
82358
|
-
|
|
82359
|
-
|
|
82360
|
-
|
|
82361
|
-
|
|
82362
|
-
|
|
82363
|
-
|
|
82364
|
-
setActiveMetricsCollector(
|
|
82365
|
-
|
|
82366
|
-
|
|
82367
|
-
|
|
82368
|
-
|
|
82369
|
-
|
|
82370
|
-
|
|
82371
|
-
|
|
82372
|
-
|
|
82373
|
-
|
|
82374
|
-
|
|
82375
|
-
|
|
82423
|
+
let remaining = text12;
|
|
82424
|
+
let batchStartedAt = now();
|
|
82425
|
+
while (remaining.length > 0) {
|
|
82426
|
+
const { chunk, rest } = sliceAppendChunk(remaining, APPEND_CHUNK_SIZE);
|
|
82427
|
+
remaining = rest;
|
|
82428
|
+
performanceTimer.mark("append-operation");
|
|
82429
|
+
const metricsCollector = new WorkerMetricsCollector(workerGrammarEngine);
|
|
82430
|
+
setActiveMetricsCollector(metricsCollector);
|
|
82431
|
+
await appendAndReparse(chunk, metricsCollector);
|
|
82432
|
+
const hadPatchMetrics = metricsCollector.patchCount > 0;
|
|
82433
|
+
const totalTime = performanceTimer.measure("append-operation");
|
|
82434
|
+
if (getActiveMetricsCollector() === metricsCollector) {
|
|
82435
|
+
setActiveMetricsCollector(null);
|
|
82436
|
+
}
|
|
82437
|
+
if (!hadPatchMetrics && totalTime !== null && Number.isFinite(totalTime)) {
|
|
82438
|
+
postMessage({
|
|
82439
|
+
type: "METRICS",
|
|
82440
|
+
metrics: {
|
|
82441
|
+
parseMs: roundMetric(totalTime),
|
|
82442
|
+
parseTime: roundMetric(totalTime),
|
|
82443
|
+
blocksProduced: blocks.length,
|
|
82444
|
+
grammarEngine: workerGrammarEngine
|
|
82445
|
+
}
|
|
82446
|
+
});
|
|
82447
|
+
}
|
|
82448
|
+
if (remaining.length > 0 && now() - batchStartedAt >= APPEND_BATCH_MS) {
|
|
82449
|
+
await waitForNextTick();
|
|
82450
|
+
batchStartedAt = now();
|
|
82451
|
+
}
|
|
82376
82452
|
}
|
|
82377
82453
|
}
|
|
82378
82454
|
async function parseAll(content4, options = {}) {
|
|
@@ -82395,9 +82471,24 @@ async function appendAndReparse(appendedText, metrics) {
|
|
|
82395
82471
|
metrics?.markParseStart();
|
|
82396
82472
|
const newContent = currentContent + appendedText;
|
|
82397
82473
|
const changeRanges = computeChangedRanges(currentContent, newContent);
|
|
82398
|
-
|
|
82474
|
+
let newTree = lastTree ? parser.parse(newContent, lastTree.fragments) : parser.parse(newContent);
|
|
82399
82475
|
let changedBlocks = await extractBlocks(newTree, newContent);
|
|
82400
82476
|
changedBlocks = runDocumentPlugins(changedBlocks, newContent);
|
|
82477
|
+
const lastRange = changedBlocks.length > 0 ? changedBlocks[changedBlocks.length - 1]?.payload?.range : void 0;
|
|
82478
|
+
const lastTo = typeof lastRange?.to === "number" ? lastRange.to : 0;
|
|
82479
|
+
if (lastTo < newContent.length - 1) {
|
|
82480
|
+
const tail = newContent.slice(lastTo).trim();
|
|
82481
|
+
if (tail.length > 0) {
|
|
82482
|
+
const fullTree = parser.parse(newContent);
|
|
82483
|
+
let fullBlocks = await extractBlocks(fullTree, newContent);
|
|
82484
|
+
fullBlocks = runDocumentPlugins(fullBlocks, newContent);
|
|
82485
|
+
const fullLast = fullBlocks.length > 0 ? fullBlocks[fullBlocks.length - 1]?.payload?.range?.to ?? 0 : 0;
|
|
82486
|
+
if (fullLast >= newContent.length - 1 || fullBlocks.length >= changedBlocks.length) {
|
|
82487
|
+
newTree = fullTree;
|
|
82488
|
+
changedBlocks = fullBlocks;
|
|
82489
|
+
}
|
|
82490
|
+
}
|
|
82491
|
+
}
|
|
82401
82492
|
const prevBlocks = blocks;
|
|
82402
82493
|
blocks = changedBlocks;
|
|
82403
82494
|
lastTree = newTree;
|
|
@@ -83218,6 +83309,50 @@ async function emitBlockDiffPatches(previousBlocks, nextBlocks, changedRanges, m
|
|
|
83218
83309
|
});
|
|
83219
83310
|
}
|
|
83220
83311
|
const immediatePatches = partitionPatchesForCredits(combined, paragraphLimit === null ? void 0 : paragraphLimit);
|
|
83312
|
+
if (deferredPatchQueue.length > maxDeferredQueueSize) {
|
|
83313
|
+
maxDeferredQueueSize = deferredPatchQueue.length;
|
|
83314
|
+
}
|
|
83315
|
+
let structuralCount = 0;
|
|
83316
|
+
for (const patch5 of patches) {
|
|
83317
|
+
if (patch5.op === "insertChild" || patch5.op === "deleteChild" || patch5.op === "replaceChild" || patch5.op === "reorder") {
|
|
83318
|
+
structuralCount += 1;
|
|
83319
|
+
}
|
|
83320
|
+
}
|
|
83321
|
+
lastDiffSummary = {
|
|
83322
|
+
prevCount: previousBlocks.length,
|
|
83323
|
+
nextCount: nextBlocks.length,
|
|
83324
|
+
prefix,
|
|
83325
|
+
removeCount,
|
|
83326
|
+
addCount,
|
|
83327
|
+
structuralPatches: structuralCount,
|
|
83328
|
+
contentPatches: contentPatches.length,
|
|
83329
|
+
immediatePatches: immediatePatches.length,
|
|
83330
|
+
deferredQueue: deferredPatchQueue.length
|
|
83331
|
+
};
|
|
83332
|
+
if (addCount > 0 || removeCount > 0 || structuralCount > 0 || deferredPatchQueue.length > 0) {
|
|
83333
|
+
lastStructuralDiffSummary = { ...lastDiffSummary };
|
|
83334
|
+
}
|
|
83335
|
+
if (immediatePatches.length > 0) {
|
|
83336
|
+
maxEmittedBlockCount = Math.max(maxEmittedBlockCount, nextBlocks.length);
|
|
83337
|
+
}
|
|
83338
|
+
if (structuralCount > 0) {
|
|
83339
|
+
maxStructuralBlockCount = Math.max(maxStructuralBlockCount, nextBlocks.length);
|
|
83340
|
+
}
|
|
83341
|
+
if (nextBlocks.length >= 60 && removeCount === 0 && addCount === 0) {
|
|
83342
|
+
const sliceStart = Math.max(0, Math.min(55, nextBlocks.length - 1));
|
|
83343
|
+
const sliceEnd = Math.min(nextBlocks.length, sliceStart + 8);
|
|
83344
|
+
const toPreview = (block) => ({
|
|
83345
|
+
id: block.id,
|
|
83346
|
+
type: block.type,
|
|
83347
|
+
raw: typeof block.payload.raw === "string" ? block.payload.raw.slice(0, 80) : ""
|
|
83348
|
+
});
|
|
83349
|
+
lastHighCountNoStructural = {
|
|
83350
|
+
nextCount: nextBlocks.length,
|
|
83351
|
+
sliceStart,
|
|
83352
|
+
prevSlice: previousBlocks.slice(sliceStart, sliceEnd).map(toPreview),
|
|
83353
|
+
nextSlice: nextBlocks.slice(sliceStart, sliceEnd).map(toPreview)
|
|
83354
|
+
};
|
|
83355
|
+
}
|
|
83221
83356
|
if (immediatePatches.length === 0) {
|
|
83222
83357
|
if (metrics) {
|
|
83223
83358
|
metrics.finalizePatch(txCounter, 0, deferredPatchQueue.length, 0);
|
|
@@ -83786,6 +83921,104 @@ async function processWorkerMessage(msg) {
|
|
|
83786
83921
|
case "FINALIZE":
|
|
83787
83922
|
await finalizeAllBlocks();
|
|
83788
83923
|
return;
|
|
83924
|
+
case "DEBUG_STATE": {
|
|
83925
|
+
const blockTypeCounts = {};
|
|
83926
|
+
for (const block of blocks) {
|
|
83927
|
+
const key2 = block.type ?? "unknown";
|
|
83928
|
+
blockTypeCounts[key2] = (blockTypeCounts[key2] || 0) + 1;
|
|
83929
|
+
}
|
|
83930
|
+
let lastBlockType;
|
|
83931
|
+
let lastBlockRange;
|
|
83932
|
+
let lastBlockRawTail;
|
|
83933
|
+
const headingTexts = [];
|
|
83934
|
+
const tailBlocks = [];
|
|
83935
|
+
const headBlocks = [];
|
|
83936
|
+
const duplicateBlockIds = [];
|
|
83937
|
+
const seenBlockIds = /* @__PURE__ */ new Set();
|
|
83938
|
+
const headingIndices = {};
|
|
83939
|
+
for (const block of blocks) {
|
|
83940
|
+
if (seenBlockIds.has(block.id)) {
|
|
83941
|
+
if (duplicateBlockIds.length < 8) {
|
|
83942
|
+
duplicateBlockIds.push(block.id);
|
|
83943
|
+
}
|
|
83944
|
+
} else {
|
|
83945
|
+
seenBlockIds.add(block.id);
|
|
83946
|
+
}
|
|
83947
|
+
}
|
|
83948
|
+
if (blocks.length > 0) {
|
|
83949
|
+
const lastBlock = blocks[blocks.length - 1];
|
|
83950
|
+
lastBlockType = lastBlock.type;
|
|
83951
|
+
const range2 = lastBlock.payload.range;
|
|
83952
|
+
if (range2 && typeof range2.from === "number" && typeof range2.to === "number") {
|
|
83953
|
+
lastBlockRange = { from: range2.from, to: range2.to };
|
|
83954
|
+
}
|
|
83955
|
+
const raw2 = typeof lastBlock.payload.raw === "string" ? lastBlock.payload.raw : "";
|
|
83956
|
+
lastBlockRawTail = raw2 ? raw2.slice(Math.max(0, raw2.length - 240)) : void 0;
|
|
83957
|
+
for (const block of blocks) {
|
|
83958
|
+
if (block.type === "heading" && typeof block.payload.raw === "string") {
|
|
83959
|
+
headingTexts.push(block.payload.raw);
|
|
83960
|
+
}
|
|
83961
|
+
}
|
|
83962
|
+
const targets = ["HTML and MDX Testing", "Inline Code", "Code Blocks", "Media", "Tables", "Footnotes"];
|
|
83963
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
83964
|
+
const block = blocks[i];
|
|
83965
|
+
if (block.type === "heading" && typeof block.payload.raw === "string") {
|
|
83966
|
+
if (targets.includes(block.payload.raw)) {
|
|
83967
|
+
headingIndices[block.payload.raw] = i;
|
|
83968
|
+
}
|
|
83969
|
+
}
|
|
83970
|
+
}
|
|
83971
|
+
const tailStart = Math.max(0, blocks.length - 8);
|
|
83972
|
+
for (let i = tailStart; i < blocks.length; i++) {
|
|
83973
|
+
const block = blocks[i];
|
|
83974
|
+
const raw3 = typeof block.payload.raw === "string" ? block.payload.raw : "";
|
|
83975
|
+
tailBlocks.push({
|
|
83976
|
+
id: block.id,
|
|
83977
|
+
type: block.type,
|
|
83978
|
+
raw: raw3.slice(0, 120)
|
|
83979
|
+
});
|
|
83980
|
+
}
|
|
83981
|
+
const headEnd = Math.min(8, blocks.length);
|
|
83982
|
+
for (let i = 0; i < headEnd; i++) {
|
|
83983
|
+
const block = blocks[i];
|
|
83984
|
+
const raw3 = typeof block.payload.raw === "string" ? block.payload.raw : "";
|
|
83985
|
+
headBlocks.push({
|
|
83986
|
+
id: block.id,
|
|
83987
|
+
type: block.type,
|
|
83988
|
+
raw: raw3.slice(0, 120)
|
|
83989
|
+
});
|
|
83990
|
+
}
|
|
83991
|
+
}
|
|
83992
|
+
const contentTail = currentContent.slice(Math.max(0, currentContent.length - 500));
|
|
83993
|
+
postMessage({
|
|
83994
|
+
type: "DEBUG_STATE",
|
|
83995
|
+
state: {
|
|
83996
|
+
contentLength: currentContent.length,
|
|
83997
|
+
contentTail,
|
|
83998
|
+
blockCount: blocks.length,
|
|
83999
|
+
blockTypeCounts,
|
|
84000
|
+
lastBlockType,
|
|
84001
|
+
lastBlockRange,
|
|
84002
|
+
lastBlockRawTail,
|
|
84003
|
+
headingTexts,
|
|
84004
|
+
headBlocks,
|
|
84005
|
+
tailBlocks,
|
|
84006
|
+
headingIndices,
|
|
84007
|
+
lastDiffSummary,
|
|
84008
|
+
lastStructuralDiffSummary,
|
|
84009
|
+
maxEmittedBlockCount,
|
|
84010
|
+
maxDeferredQueueSize,
|
|
84011
|
+
maxStructuralBlockCount,
|
|
84012
|
+
lastHighCountNoStructural,
|
|
84013
|
+
duplicateBlockIds,
|
|
84014
|
+
duplicateBlockCount: duplicateBlockIds.length,
|
|
84015
|
+
hasInlineCodeHeading: currentContent.includes("# Inline Code"),
|
|
84016
|
+
hasCodeBlocksHeading: currentContent.includes("# Code Blocks"),
|
|
84017
|
+
hasMediaHeading: currentContent.includes("# Media")
|
|
84018
|
+
}
|
|
84019
|
+
});
|
|
84020
|
+
return;
|
|
84021
|
+
}
|
|
83789
84022
|
case "MDX_COMPILED":
|
|
83790
84023
|
handleMdxStatus(msg.blockId, {
|
|
83791
84024
|
compiledRef: { id: msg.compiledId },
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stream-mdx/worker",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Worker client utilities and shared worker helpers for the Streaming Markdown V2 pipeline",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"@lezer/common": "^1.2.3",
|
|
64
64
|
"@lezer/lr": "^1.4.2",
|
|
65
65
|
"@lezer/markdown": "^1.3.0",
|
|
66
|
-
"@stream-mdx/core": "0.1.
|
|
67
|
-
"@stream-mdx/plugins": "0.1.
|
|
66
|
+
"@stream-mdx/core": "0.1.1",
|
|
67
|
+
"@stream-mdx/plugins": "0.1.1",
|
|
68
68
|
"@mdx-js/mdx": "^3.1.0",
|
|
69
69
|
"@shikijs/engine-javascript": "^1.29.2",
|
|
70
70
|
"@shikijs/engine-oniguruma": "^1.29.2",
|