@stream-mdx/react 0.1.0 → 0.2.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.
- package/CHANGELOG.md +9 -0
- package/README.md +4 -0
- package/dist/components/index.cjs +497 -163
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.mjs +496 -163
- package/dist/{index-Bt1opGCs.d.cts → index-D0akq48G.d.cts} +24 -2
- package/dist/{index-Bt1opGCs.d.ts → index-D0akq48G.d.ts} +24 -2
- package/dist/index.cjs +3797 -2048
- package/dist/index.d.cts +43 -5
- package/dist/index.d.ts +43 -5
- package/dist/index.mjs +3741 -1990
- package/dist/mdx-client.cjs +60 -18
- package/dist/mdx-client.d.cts +11 -0
- package/dist/mdx-client.d.ts +11 -0
- package/dist/mdx-client.mjs +60 -18
- package/dist/mdx-coordinator.cjs +60 -18
- package/dist/mdx-coordinator.mjs +60 -18
- package/dist/renderer/node-views.cjs +481 -130
- package/dist/renderer/node-views.d.cts +1 -1
- package/dist/renderer/node-views.d.ts +1 -1
- package/dist/renderer/node-views.mjs +424 -65
- package/dist/renderer/patch-commit-scheduler.cjs +68 -7
- package/dist/renderer/patch-commit-scheduler.d.cts +6 -5
- package/dist/renderer/patch-commit-scheduler.d.ts +6 -5
- package/dist/renderer/patch-commit-scheduler.mjs +68 -7
- package/dist/renderer/store.cjs +481 -56
- package/dist/renderer/store.d.cts +2 -1
- package/dist/renderer/store.d.ts +2 -1
- package/dist/renderer/store.mjs +479 -47
- package/dist/renderer/virtualized-code.cjs +8 -2
- package/dist/renderer/virtualized-code.d.cts +4 -0
- package/dist/renderer/virtualized-code.d.ts +4 -0
- package/dist/renderer/virtualized-code.mjs +8 -2
- package/dist/renderer.cjs +3188 -2172
- package/dist/renderer.d.cts +4 -2
- package/dist/renderer.d.ts +4 -2
- package/dist/renderer.mjs +3009 -1985
- package/dist/streaming-markdown-Ch6PwjAa.d.cts +154 -0
- package/dist/streaming-markdown-tca-Mf8D.d.ts +154 -0
- package/dist/streaming-markdown.cjs +3929 -2202
- package/dist/streaming-markdown.d.cts +6 -95
- package/dist/streaming-markdown.d.ts +6 -95
- package/dist/streaming-markdown.mjs +3943 -2208
- package/dist/utils/inline-html.d.cts +1 -1
- package/dist/utils/inline-html.d.ts +1 -1
- package/package.json +3 -3
package/dist/renderer/store.cjs
CHANGED
|
@@ -21,13 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/renderer/store.ts
|
|
22
22
|
var store_exports = {};
|
|
23
23
|
__export(store_exports, {
|
|
24
|
-
createRendererStore: () => createRendererStore
|
|
24
|
+
createRendererStore: () => createRendererStore,
|
|
25
|
+
isListPatchDebugEnabled: () => isListPatchDebugEnabled
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(store_exports);
|
|
27
28
|
var import_core2 = require("@stream-mdx/core");
|
|
28
|
-
var import_core3 = require("@stream-mdx/core");
|
|
29
|
-
var import_core4 = require("@stream-mdx/core");
|
|
30
|
-
var import_core5 = require("@stream-mdx/core");
|
|
31
29
|
|
|
32
30
|
// src/renderer/list-utils.ts
|
|
33
31
|
function updateNodeDepth(node, depth) {
|
|
@@ -52,6 +50,22 @@ function normalizeAllListDepths(map, touched, rootId = "__root__") {
|
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
}
|
|
53
|
+
function normalizeListDepthsForIds(map, touched, listIds, rootId = "__root__") {
|
|
54
|
+
if (listIds.size === 0) {
|
|
55
|
+
normalizeAllListDepths(map, touched, rootId);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const visited = /* @__PURE__ */ new Set();
|
|
59
|
+
for (const listId of listIds) {
|
|
60
|
+
const base = map.get(listId);
|
|
61
|
+
if (!base) continue;
|
|
62
|
+
const listNode = base.type === "list" ? base : findNearestListAncestor(map, base);
|
|
63
|
+
if (!listNode || visited.has(listNode.id)) continue;
|
|
64
|
+
visited.add(listNode.id);
|
|
65
|
+
const depth = computeListDepth(map, listNode, rootId);
|
|
66
|
+
normalizeListDepthRecursive(map, listNode, depth, touched);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
55
69
|
function normalizeListDepthRecursive(map, listNode, depth, touched) {
|
|
56
70
|
if (!listNode) return;
|
|
57
71
|
if (updateNodeDepth(listNode, depth)) {
|
|
@@ -76,6 +90,28 @@ function normalizeListDepthRecursive(map, listNode, depth, touched) {
|
|
|
76
90
|
}
|
|
77
91
|
}
|
|
78
92
|
}
|
|
93
|
+
function findNearestListAncestor(map, node) {
|
|
94
|
+
let current = node;
|
|
95
|
+
while (current) {
|
|
96
|
+
if (current.type === "list") return current;
|
|
97
|
+
if (!current.parentId) return void 0;
|
|
98
|
+
current = map.get(current.parentId);
|
|
99
|
+
}
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
function computeListDepth(map, listNode, rootId) {
|
|
103
|
+
let depth = 0;
|
|
104
|
+
let current = listNode;
|
|
105
|
+
while (current && current.parentId && current.parentId !== rootId) {
|
|
106
|
+
const parent = map.get(current.parentId);
|
|
107
|
+
if (!parent) break;
|
|
108
|
+
if (parent.type === "list") {
|
|
109
|
+
depth += 1;
|
|
110
|
+
}
|
|
111
|
+
current = parent;
|
|
112
|
+
}
|
|
113
|
+
return depth;
|
|
114
|
+
}
|
|
79
115
|
|
|
80
116
|
// src/renderer/patch-coalescing.ts
|
|
81
117
|
var import_core = require("@stream-mdx/core");
|
|
@@ -90,12 +126,35 @@ function snapshotToBlock(node) {
|
|
|
90
126
|
}
|
|
91
127
|
var nodeSnapshotCache = /* @__PURE__ */ new Map();
|
|
92
128
|
var childrenSnapshotCache = /* @__PURE__ */ new Map();
|
|
129
|
+
var NODE_SNAPSHOT_CACHE_LIMIT = 5e4;
|
|
130
|
+
var CHILDREN_SNAPSHOT_CACHE_LIMIT = 5e4;
|
|
131
|
+
var NODE_SNAPSHOT_CACHE_BUFFER = Math.max(200, Math.floor(NODE_SNAPSHOT_CACHE_LIMIT * 0.1));
|
|
132
|
+
var CHILDREN_SNAPSHOT_CACHE_BUFFER = Math.max(200, Math.floor(CHILDREN_SNAPSHOT_CACHE_LIMIT * 0.1));
|
|
133
|
+
function pruneCache(cache, max, buffer) {
|
|
134
|
+
if (cache.size <= max + buffer) return;
|
|
135
|
+
let remaining = cache.size - max;
|
|
136
|
+
for (const key of cache.keys()) {
|
|
137
|
+
cache.delete(key);
|
|
138
|
+
remaining -= 1;
|
|
139
|
+
if (remaining <= 0) break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
93
142
|
var EMPTY_CHILDREN = Object.freeze([]);
|
|
94
143
|
var EMPTY_NODE_SNAPSHOT = Object.freeze({ version: -1, node: void 0 });
|
|
95
144
|
var EMPTY_CHILDREN_SNAPSHOT = Object.freeze({
|
|
96
145
|
version: -1,
|
|
97
146
|
children: EMPTY_CHILDREN
|
|
98
147
|
});
|
|
148
|
+
function isListPatchDebugEnabled() {
|
|
149
|
+
if (typeof globalThis !== "undefined") {
|
|
150
|
+
const flag = globalThis.__STREAMING_LIST_DEBUG__;
|
|
151
|
+
if (flag === true) return true;
|
|
152
|
+
}
|
|
153
|
+
if (typeof process !== "undefined" && process.env.NEXT_PUBLIC_STREAMING_LIST_DEBUG === "true") {
|
|
154
|
+
return true;
|
|
155
|
+
}
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
99
158
|
var CODE_BLOCK_DEBUG_ENABLED = (() => {
|
|
100
159
|
try {
|
|
101
160
|
if (typeof process !== "undefined" && process.env && process.env.NEXT_PUBLIC_STREAMING_DEBUG_CODELINES === "1") {
|
|
@@ -111,6 +170,128 @@ var CODE_BLOCK_DEBUG_ENABLED = (() => {
|
|
|
111
170
|
}
|
|
112
171
|
return false;
|
|
113
172
|
})() || false;
|
|
173
|
+
var CODE_BLOCK_VALIDATION_ENABLED = typeof process !== "undefined" && process.env ? process.env.NODE_ENV !== "production" : true;
|
|
174
|
+
var PATCH_PERF_HISTORY_LIMIT = 120;
|
|
175
|
+
var getPerfNow = (() => {
|
|
176
|
+
if (typeof performance !== "undefined" && typeof performance.now === "function") {
|
|
177
|
+
return () => performance.now();
|
|
178
|
+
}
|
|
179
|
+
return () => Date.now();
|
|
180
|
+
})();
|
|
181
|
+
function isPatchPerfDebugEnabled() {
|
|
182
|
+
try {
|
|
183
|
+
if (typeof process !== "undefined" && process.env) {
|
|
184
|
+
const value = process.env.NEXT_PUBLIC_STREAMING_DEBUG_PATCH_PERF;
|
|
185
|
+
if (value === "1" || value === "true") {
|
|
186
|
+
return true;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} catch {
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const debug = globalThis.__STREAMING_DEBUG__;
|
|
193
|
+
if (debug?.patchPerf) {
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
} catch {
|
|
197
|
+
}
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
function recordPatchPerf(summary) {
|
|
201
|
+
try {
|
|
202
|
+
if (typeof globalThis === "undefined") return;
|
|
203
|
+
const root = globalThis;
|
|
204
|
+
const history = root.__STREAM_MDX_PATCH_STATS__ ?? [];
|
|
205
|
+
history.push(summary);
|
|
206
|
+
if (history.length > PATCH_PERF_HISTORY_LIMIT) {
|
|
207
|
+
history.splice(0, history.length - PATCH_PERF_HISTORY_LIMIT);
|
|
208
|
+
}
|
|
209
|
+
root.__STREAM_MDX_PATCH_STATS__ = history;
|
|
210
|
+
root.__STREAM_MDX_PATCH_STATS_LAST__ = summary;
|
|
211
|
+
const totals = root.__STREAM_MDX_PATCH_STATS_TOTALS__ ?? {
|
|
212
|
+
calls: 0,
|
|
213
|
+
totalMs: 0,
|
|
214
|
+
applyMs: 0,
|
|
215
|
+
coalesceMs: 0,
|
|
216
|
+
listNormalizeMs: 0,
|
|
217
|
+
patches: 0,
|
|
218
|
+
coalescedPatches: 0,
|
|
219
|
+
ops: {},
|
|
220
|
+
setPropsByType: {},
|
|
221
|
+
setPropsBySize: {}
|
|
222
|
+
};
|
|
223
|
+
totals.calls += 1;
|
|
224
|
+
totals.totalMs += summary.totalMs;
|
|
225
|
+
totals.applyMs += summary.applyMs;
|
|
226
|
+
totals.coalesceMs += summary.coalesceMs;
|
|
227
|
+
totals.listNormalizeMs += summary.listNormalizeMs;
|
|
228
|
+
totals.patches += summary.patches;
|
|
229
|
+
totals.coalescedPatches += summary.coalescedPatches;
|
|
230
|
+
for (const [op, stats] of Object.entries(summary.ops)) {
|
|
231
|
+
const entry = totals.ops[op] ?? { count: 0, durationMs: 0 };
|
|
232
|
+
entry.count += stats.count;
|
|
233
|
+
entry.durationMs += stats.durationMs;
|
|
234
|
+
totals.ops[op] = entry;
|
|
235
|
+
}
|
|
236
|
+
if (summary.setPropsByType) {
|
|
237
|
+
for (const [key, stats] of Object.entries(summary.setPropsByType)) {
|
|
238
|
+
const entry = totals.setPropsByType[key] ?? { count: 0, durationMs: 0 };
|
|
239
|
+
entry.count += stats.count;
|
|
240
|
+
entry.durationMs += stats.durationMs;
|
|
241
|
+
totals.setPropsByType[key] = entry;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (summary.setPropsBySize) {
|
|
245
|
+
for (const [key, stats] of Object.entries(summary.setPropsBySize)) {
|
|
246
|
+
const entry = totals.setPropsBySize[key] ?? { count: 0, durationMs: 0 };
|
|
247
|
+
entry.count += stats.count;
|
|
248
|
+
entry.durationMs += stats.durationMs;
|
|
249
|
+
totals.setPropsBySize[key] = entry;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
root.__STREAM_MDX_PATCH_STATS_TOTALS__ = totals;
|
|
253
|
+
} catch {
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function estimateBlockPayloadSize(block) {
|
|
257
|
+
if (!block || !block.payload) return 0;
|
|
258
|
+
let size = 0;
|
|
259
|
+
const payload = block.payload;
|
|
260
|
+
if (typeof payload.raw === "string") size += payload.raw.length;
|
|
261
|
+
if (typeof payload.highlightedHtml === "string") size += payload.highlightedHtml.length;
|
|
262
|
+
if (typeof payload.sanitizedHtml === "string") size += payload.sanitizedHtml.length;
|
|
263
|
+
if (typeof payload.compiledMdxModule?.code === "string") size += payload.compiledMdxModule.code.length;
|
|
264
|
+
if (Array.isArray(payload.inline)) size += payload.inline.length * 8;
|
|
265
|
+
return size;
|
|
266
|
+
}
|
|
267
|
+
function estimatePropsSize(props, block) {
|
|
268
|
+
let size = 0;
|
|
269
|
+
if (props) {
|
|
270
|
+
for (const [key, value] of Object.entries(props)) {
|
|
271
|
+
if (key === "block") continue;
|
|
272
|
+
if (typeof value === "string") {
|
|
273
|
+
size += value.length;
|
|
274
|
+
} else if (typeof value === "number") {
|
|
275
|
+
size += 8;
|
|
276
|
+
} else if (typeof value === "boolean") {
|
|
277
|
+
size += 4;
|
|
278
|
+
} else if (Array.isArray(value)) {
|
|
279
|
+
size += value.length * 4;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (block) {
|
|
284
|
+
size += estimateBlockPayloadSize(block);
|
|
285
|
+
}
|
|
286
|
+
return size;
|
|
287
|
+
}
|
|
288
|
+
function bucketBySize(size) {
|
|
289
|
+
if (size < 1024) return "<1k";
|
|
290
|
+
if (size < 10 * 1024) return "1-10k";
|
|
291
|
+
if (size < 50 * 1024) return "10-50k";
|
|
292
|
+
if (size < 200 * 1024) return "50-200k";
|
|
293
|
+
return ">=200k";
|
|
294
|
+
}
|
|
114
295
|
function debugCodeBlock(event, payload) {
|
|
115
296
|
if (!CODE_BLOCK_DEBUG_ENABLED) return;
|
|
116
297
|
try {
|
|
@@ -120,7 +301,7 @@ function debugCodeBlock(event, payload) {
|
|
|
120
301
|
}
|
|
121
302
|
function createRootRecord() {
|
|
122
303
|
return {
|
|
123
|
-
id:
|
|
304
|
+
id: import_core2.PATCH_ROOT_ID,
|
|
124
305
|
type: "__root__",
|
|
125
306
|
parentId: null,
|
|
126
307
|
children: [],
|
|
@@ -187,7 +368,7 @@ function escapeHtml(value) {
|
|
|
187
368
|
}
|
|
188
369
|
function stripOuterLineSpan(html) {
|
|
189
370
|
if (!html) return null;
|
|
190
|
-
const openTagMatch = html.match(/<span[^>]
|
|
371
|
+
const openTagMatch = html.match(/<span[^>]*>/i);
|
|
191
372
|
if (!openTagMatch) {
|
|
192
373
|
return null;
|
|
193
374
|
}
|
|
@@ -206,7 +387,7 @@ function stripOuterLineSpan(html) {
|
|
|
206
387
|
function sanitizeLineInnerHtml(innerHtml, fallbackText) {
|
|
207
388
|
if (innerHtml && innerHtml.trim().length > 0) {
|
|
208
389
|
const wrapped = `<span class="line">${innerHtml}</span>`;
|
|
209
|
-
const sanitized = (0,
|
|
390
|
+
const sanitized = (0, import_core2.sanitizeCodeHTML)(wrapped);
|
|
210
391
|
const inner = stripOuterLineSpan(typeof sanitized === "string" ? sanitized : String(sanitized));
|
|
211
392
|
if (inner !== null) {
|
|
212
393
|
return inner;
|
|
@@ -304,8 +485,12 @@ function normalizeCodeBlockChildren(nodes, parent, touched) {
|
|
|
304
485
|
touched.add(node.id);
|
|
305
486
|
mutated = true;
|
|
306
487
|
}
|
|
307
|
-
const
|
|
308
|
-
if (
|
|
488
|
+
const incoming = { index: idx, text: node.props?.text, html: node.props?.html };
|
|
489
|
+
if (Object.prototype.hasOwnProperty.call(node.props ?? {}, "tokens")) {
|
|
490
|
+
incoming.tokens = node.props.tokens;
|
|
491
|
+
}
|
|
492
|
+
const normalizedProps = normalizeCodeLineProps(incoming, node.props);
|
|
493
|
+
if (normalizedProps !== node.props) {
|
|
309
494
|
node.props = normalizedProps;
|
|
310
495
|
node.version++;
|
|
311
496
|
touched.add(node.id);
|
|
@@ -351,43 +536,68 @@ function normalizeCodeBlockChildren(nodes, parent, touched) {
|
|
|
351
536
|
children: parent.children.slice()
|
|
352
537
|
});
|
|
353
538
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
issues: validation.issues
|
|
359
|
-
});
|
|
360
|
-
if (!rebuildCodeBlockFromSnapshot(nodes, parent, touched, validation.issues)) {
|
|
361
|
-
console.warn("[renderer-store] unable to fully normalize code block", {
|
|
539
|
+
if (CODE_BLOCK_VALIDATION_ENABLED) {
|
|
540
|
+
const validation = validateCodeBlockChildren(nodes, parent);
|
|
541
|
+
if (!validation.ok) {
|
|
542
|
+
debugCodeBlock("code-block-validation-failed", {
|
|
362
543
|
parentId: parent.id,
|
|
363
544
|
issues: validation.issues
|
|
364
545
|
});
|
|
546
|
+
if (!rebuildCodeBlockFromSnapshot(nodes, parent, touched, validation.issues)) {
|
|
547
|
+
console.warn("[renderer-store] unable to fully normalize code block", {
|
|
548
|
+
parentId: parent.id,
|
|
549
|
+
issues: validation.issues
|
|
550
|
+
});
|
|
551
|
+
}
|
|
365
552
|
}
|
|
366
553
|
}
|
|
367
554
|
}
|
|
368
555
|
function normalizeCodeLineProps(incoming, previous) {
|
|
369
|
-
const
|
|
556
|
+
const previousIndex = typeof previous?.index === "number" ? previous?.index : 0;
|
|
557
|
+
const index = typeof incoming.index === "number" ? incoming.index : previousIndex;
|
|
370
558
|
const previousText = typeof previous?.text === "string" ? previous?.text : "";
|
|
371
559
|
const previousHtml = typeof previous?.html === "string" ? previous?.html : null;
|
|
560
|
+
const previousTokens = Object.prototype.hasOwnProperty.call(previous ?? {}, "tokens") ? previous?.tokens : void 0;
|
|
372
561
|
const hasIncomingText = typeof incoming.text === "string";
|
|
562
|
+
const hasIncomingHtml = typeof incoming.html === "string";
|
|
563
|
+
const hasIncomingTokens = Object.prototype.hasOwnProperty.call(incoming, "tokens");
|
|
564
|
+
const incomingTokens = hasIncomingTokens ? incoming.tokens : void 0;
|
|
373
565
|
const rawText = hasIncomingText ? incoming.text : previousText;
|
|
566
|
+
if (previous && !hasIncomingHtml && !hasIncomingTokens && index === previousIndex && (!hasIncomingText || rawText === previousText)) {
|
|
567
|
+
return previous;
|
|
568
|
+
}
|
|
569
|
+
if (previous && hasIncomingHtml && !hasIncomingTokens && incoming.html === previousHtml && index === previousIndex && (!hasIncomingText || rawText === previousText)) {
|
|
570
|
+
return previous;
|
|
571
|
+
}
|
|
374
572
|
let highlight = null;
|
|
375
|
-
if (
|
|
573
|
+
if (hasIncomingHtml) {
|
|
376
574
|
highlight = incoming.html;
|
|
377
575
|
} else if (!hasIncomingText || rawText === previousText) {
|
|
378
576
|
highlight = previousHtml;
|
|
379
577
|
}
|
|
380
|
-
|
|
578
|
+
let tokens = void 0;
|
|
579
|
+
if (hasIncomingTokens) {
|
|
580
|
+
tokens = incomingTokens ?? null;
|
|
581
|
+
} else if (!hasIncomingText || rawText === previousText) {
|
|
582
|
+
tokens = previousTokens;
|
|
583
|
+
} else {
|
|
584
|
+
tokens = null;
|
|
585
|
+
}
|
|
586
|
+
return createCodeLineProps(index, rawText, highlight, tokens);
|
|
381
587
|
}
|
|
382
|
-
function createCodeLineProps(index, text, highlight) {
|
|
588
|
+
function createCodeLineProps(index, text, highlight, tokens) {
|
|
383
589
|
const safeText = typeof text === "string" ? text : "";
|
|
384
590
|
const sanitized = sanitizeLineInnerHtml(highlight, safeText);
|
|
385
591
|
const html = sanitized && sanitized.length >= safeText.length ? sanitized : escapeHtml(safeText);
|
|
386
|
-
|
|
592
|
+
const props = {
|
|
387
593
|
index,
|
|
388
594
|
text: safeText,
|
|
389
595
|
html
|
|
390
596
|
};
|
|
597
|
+
if (tokens !== void 0) {
|
|
598
|
+
props.tokens = tokens;
|
|
599
|
+
}
|
|
600
|
+
return props;
|
|
391
601
|
}
|
|
392
602
|
function clampIndex(index, length) {
|
|
393
603
|
if (!Number.isFinite(index)) return 0;
|
|
@@ -429,8 +639,13 @@ function mergeInlineSegmentProps(previous, incoming) {
|
|
|
429
639
|
function applyCodeBlockMetadata(record) {
|
|
430
640
|
const block = record.block;
|
|
431
641
|
const highlightedHtml = block?.payload.highlightedHtml ?? "";
|
|
432
|
-
const { preAttrs, codeAttrs } = (0, import_core3.extractCodeWrapperAttributes)(highlightedHtml);
|
|
433
642
|
const lang = typeof block?.payload.meta?.lang === "string" ? block?.payload.meta?.lang : record.props?.lang;
|
|
643
|
+
let { preAttrs, codeAttrs } = (0, import_core2.extractCodeWrapperAttributes)(highlightedHtml);
|
|
644
|
+
if (!preAttrs || !codeAttrs) {
|
|
645
|
+
const defaults = (0, import_core2.getDefaultCodeWrapperAttributes)(typeof lang === "string" ? lang : void 0);
|
|
646
|
+
preAttrs = preAttrs ?? defaults.preAttrs;
|
|
647
|
+
codeAttrs = codeAttrs ?? defaults.codeAttrs;
|
|
648
|
+
}
|
|
434
649
|
record.props = {
|
|
435
650
|
...record.props ?? {},
|
|
436
651
|
lang,
|
|
@@ -443,7 +658,8 @@ function normalizeNodeProps(snapshot) {
|
|
|
443
658
|
const index = typeof snapshot.props?.index === "number" ? snapshot.props?.index : 0;
|
|
444
659
|
const text = typeof snapshot.props?.text === "string" ? snapshot.props?.text : "";
|
|
445
660
|
const html = typeof snapshot.props?.html === "string" ? snapshot.props?.html : null;
|
|
446
|
-
|
|
661
|
+
const tokens = Object.prototype.hasOwnProperty.call(snapshot.props ?? {}, "tokens") ? snapshot.props?.tokens : void 0;
|
|
662
|
+
return createCodeLineProps(index, text, html, tokens);
|
|
447
663
|
}
|
|
448
664
|
if (isInlineSegmentType(snapshot.type)) {
|
|
449
665
|
const incoming = snapshot.props ? { ...snapshot.props } : {};
|
|
@@ -596,8 +812,8 @@ function resolveParent(map, path) {
|
|
|
596
812
|
if (path.nodeId) {
|
|
597
813
|
return map.get(path.nodeId);
|
|
598
814
|
}
|
|
599
|
-
if (path.blockId ===
|
|
600
|
-
return map.get(
|
|
815
|
+
if (path.blockId === import_core2.PATCH_ROOT_ID) {
|
|
816
|
+
return map.get(import_core2.PATCH_ROOT_ID);
|
|
601
817
|
}
|
|
602
818
|
return map.get(path.blockId);
|
|
603
819
|
}
|
|
@@ -695,7 +911,7 @@ function createRendererStore(initialBlocks = []) {
|
|
|
695
911
|
const snapshot = (0, import_core2.createBlockSnapshot)(block);
|
|
696
912
|
insertSnapshotAt(nodes, root, root.children.length, snapshot);
|
|
697
913
|
}
|
|
698
|
-
normalizeAllListDepths(nodes, /* @__PURE__ */ new Set(),
|
|
914
|
+
normalizeAllListDepths(nodes, /* @__PURE__ */ new Set(), import_core2.PATCH_ROOT_ID);
|
|
699
915
|
version++;
|
|
700
916
|
blocksDirty = true;
|
|
701
917
|
scheduleNotify();
|
|
@@ -711,6 +927,13 @@ function createRendererStore(initialBlocks = []) {
|
|
|
711
927
|
lastCoalescingMetrics = options?.metrics ?? null;
|
|
712
928
|
return touched;
|
|
713
929
|
}
|
|
930
|
+
const perfEnabled = isPatchPerfDebugEnabled();
|
|
931
|
+
const perfStart = perfEnabled ? getPerfNow() : 0;
|
|
932
|
+
const opStats = perfEnabled ? {} : {};
|
|
933
|
+
const setPropsByType = perfEnabled ? {} : {};
|
|
934
|
+
const setPropsBySize = perfEnabled ? {} : {};
|
|
935
|
+
let applyMs = 0;
|
|
936
|
+
let listNormalizeMs = 0;
|
|
714
937
|
let coalescedPatches = patches;
|
|
715
938
|
let metrics = options?.metrics ?? null;
|
|
716
939
|
if (!options?.coalesced) {
|
|
@@ -719,38 +942,117 @@ function createRendererStore(initialBlocks = []) {
|
|
|
719
942
|
metrics = result.metrics;
|
|
720
943
|
}
|
|
721
944
|
lastCoalescingMetrics = metrics;
|
|
722
|
-
const root = nodes.get(
|
|
945
|
+
const root = nodes.get(import_core2.PATCH_ROOT_ID);
|
|
723
946
|
if (!root) {
|
|
724
|
-
nodes.set(
|
|
947
|
+
nodes.set(import_core2.PATCH_ROOT_ID, createRootRecord());
|
|
725
948
|
}
|
|
726
949
|
let mutatedBlocks = false;
|
|
727
950
|
let listDepthDirty = false;
|
|
951
|
+
const listDepthDirtyNodes = /* @__PURE__ */ new Set();
|
|
952
|
+
const debugListPatches = isListPatchDebugEnabled();
|
|
953
|
+
const isListRelated = (type) => type === "list" || type === "list-item";
|
|
954
|
+
const logListPatch = (label, details) => {
|
|
955
|
+
if (!debugListPatches) return;
|
|
956
|
+
try {
|
|
957
|
+
console.debug(`[list-patch] ${label}`, details);
|
|
958
|
+
} catch {
|
|
959
|
+
}
|
|
960
|
+
};
|
|
961
|
+
const findNearestListNode = (nodeId) => {
|
|
962
|
+
if (!nodeId) return void 0;
|
|
963
|
+
let current = nodes.get(nodeId);
|
|
964
|
+
while (current) {
|
|
965
|
+
if (current.type === "list") return current;
|
|
966
|
+
if (!current.parentId) return void 0;
|
|
967
|
+
current = nodes.get(current.parentId);
|
|
968
|
+
}
|
|
969
|
+
return void 0;
|
|
970
|
+
};
|
|
971
|
+
const markListDepthDirty = (nodeId) => {
|
|
972
|
+
const listNode = findNearestListNode(nodeId);
|
|
973
|
+
if (listNode) {
|
|
974
|
+
listDepthDirtyNodes.add(listNode.id);
|
|
975
|
+
} else {
|
|
976
|
+
listDepthDirty = true;
|
|
977
|
+
}
|
|
978
|
+
};
|
|
728
979
|
const applyPropsUpdate = (at, props) => {
|
|
980
|
+
const perfStartLocal = perfEnabled ? getPerfNow() : 0;
|
|
729
981
|
const targetId = at.nodeId ?? at.blockId;
|
|
730
982
|
if (!targetId) return;
|
|
731
983
|
const target = nodes.get(targetId);
|
|
732
984
|
if (!target) return;
|
|
733
|
-
const
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
985
|
+
const parentType = target.parentId ? nodes.get(target.parentId)?.type : void 0;
|
|
986
|
+
if (debugListPatches && (isListRelated(target.type) || isListRelated(parentType))) {
|
|
987
|
+
logListPatch("setProps", {
|
|
988
|
+
id: target.id,
|
|
989
|
+
type: target.type,
|
|
990
|
+
parentType,
|
|
991
|
+
keys: props ? Object.keys(props) : []
|
|
992
|
+
});
|
|
737
993
|
}
|
|
738
994
|
let propsChanged = false;
|
|
739
995
|
if (target.type === "code-line") {
|
|
740
|
-
const
|
|
741
|
-
|
|
996
|
+
const incoming = {
|
|
997
|
+
index: props?.index,
|
|
998
|
+
text: props?.text,
|
|
999
|
+
html: props?.html
|
|
1000
|
+
};
|
|
1001
|
+
if (Object.prototype.hasOwnProperty.call(props ?? {}, "tokens")) {
|
|
1002
|
+
incoming.tokens = props.tokens;
|
|
1003
|
+
}
|
|
1004
|
+
const normalized = normalizeCodeLineProps(incoming, target.props);
|
|
1005
|
+
if (normalized !== target.props) {
|
|
742
1006
|
target.props = normalized;
|
|
743
1007
|
propsChanged = true;
|
|
744
1008
|
}
|
|
1009
|
+
if (propsChanged) {
|
|
1010
|
+
target.version++;
|
|
1011
|
+
touched.add(target.id);
|
|
1012
|
+
const parent = target.parentId ? nodes.get(target.parentId) : void 0;
|
|
1013
|
+
if (parent) {
|
|
1014
|
+
parent.version++;
|
|
1015
|
+
touched.add(parent.id);
|
|
1016
|
+
if (parent.type === "code") {
|
|
1017
|
+
normalizeCodeBlockChildren(nodes, parent, touched);
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
}
|
|
1021
|
+
if (perfEnabled) {
|
|
1022
|
+
const duration = getPerfNow() - perfStartLocal;
|
|
1023
|
+
const typeKey = target.type || "unknown";
|
|
1024
|
+
const sizeKey = bucketBySize(estimatePropsSize(props, void 0));
|
|
1025
|
+
const typeEntry = setPropsByType[typeKey] ?? { count: 0, durationMs: 0 };
|
|
1026
|
+
typeEntry.count += 1;
|
|
1027
|
+
typeEntry.durationMs += duration;
|
|
1028
|
+
setPropsByType[typeKey] = typeEntry;
|
|
1029
|
+
const sizeEntry = setPropsBySize[sizeKey] ?? { count: 0, durationMs: 0 };
|
|
1030
|
+
sizeEntry.count += 1;
|
|
1031
|
+
sizeEntry.durationMs += duration;
|
|
1032
|
+
setPropsBySize[sizeKey] = sizeEntry;
|
|
1033
|
+
}
|
|
1034
|
+
return;
|
|
745
1035
|
} else if (isInlineSegmentType(target.type)) {
|
|
1036
|
+
const nextProps = props ? { ...props } : {};
|
|
1037
|
+
if ("block" in nextProps) {
|
|
1038
|
+
delete nextProps.block;
|
|
1039
|
+
}
|
|
746
1040
|
const mergedSegments = mergeInlineSegmentProps(target.props, nextProps);
|
|
747
1041
|
if (!shallowEqualRecords(target.props, mergedSegments)) {
|
|
748
1042
|
target.props = mergedSegments;
|
|
749
1043
|
propsChanged = true;
|
|
750
1044
|
}
|
|
751
1045
|
} else {
|
|
1046
|
+
const nextProps = props ? { ...props } : {};
|
|
1047
|
+
if ("block" in nextProps) {
|
|
1048
|
+
delete nextProps.block;
|
|
1049
|
+
}
|
|
752
1050
|
const base = target.props ? { ...target.props } : {};
|
|
753
1051
|
let localChanged = false;
|
|
1052
|
+
if (Object.prototype.hasOwnProperty.call(base, "block")) {
|
|
1053
|
+
delete base.block;
|
|
1054
|
+
localChanged = true;
|
|
1055
|
+
}
|
|
754
1056
|
for (const [key, value] of Object.entries(nextProps)) {
|
|
755
1057
|
if (value === void 0) {
|
|
756
1058
|
if (Object.prototype.hasOwnProperty.call(base, key)) {
|
|
@@ -768,6 +1070,7 @@ function createRendererStore(initialBlocks = []) {
|
|
|
768
1070
|
}
|
|
769
1071
|
}
|
|
770
1072
|
let blockChanged = false;
|
|
1073
|
+
const incomingBlock = props?.block;
|
|
771
1074
|
if (incomingBlock && typeof incomingBlock === "object") {
|
|
772
1075
|
target.block = (0, import_core2.cloneBlock)(incomingBlock);
|
|
773
1076
|
if (target.type === "code") {
|
|
@@ -797,13 +1100,26 @@ function createRendererStore(initialBlocks = []) {
|
|
|
797
1100
|
} else if (parentForNormalization) {
|
|
798
1101
|
normalizeCodeBlockChildren(nodes, parentForNormalization, touched);
|
|
799
1102
|
}
|
|
800
|
-
const
|
|
801
|
-
if (target.type
|
|
802
|
-
|
|
1103
|
+
const parentType2 = target.parentId ? nodes.get(target.parentId)?.type : void 0;
|
|
1104
|
+
if (isListRelated(target.type) || isListRelated(parentType2)) {
|
|
1105
|
+
markListDepthDirty(target.id);
|
|
803
1106
|
}
|
|
804
1107
|
}
|
|
1108
|
+
if (perfEnabled) {
|
|
1109
|
+
const duration = getPerfNow() - perfStartLocal;
|
|
1110
|
+
const typeKey = target.type || "unknown";
|
|
1111
|
+
const sizeKey = bucketBySize(estimatePropsSize(props, incomingBlock && typeof incomingBlock === "object" ? incomingBlock : void 0));
|
|
1112
|
+
const typeEntry = setPropsByType[typeKey] ?? { count: 0, durationMs: 0 };
|
|
1113
|
+
typeEntry.count += 1;
|
|
1114
|
+
typeEntry.durationMs += duration;
|
|
1115
|
+
setPropsByType[typeKey] = typeEntry;
|
|
1116
|
+
const sizeEntry = setPropsBySize[sizeKey] ?? { count: 0, durationMs: 0 };
|
|
1117
|
+
sizeEntry.count += 1;
|
|
1118
|
+
sizeEntry.durationMs += duration;
|
|
1119
|
+
setPropsBySize[sizeKey] = sizeEntry;
|
|
1120
|
+
}
|
|
805
1121
|
};
|
|
806
|
-
|
|
1122
|
+
const applyPatch = (patch) => {
|
|
807
1123
|
switch (patch.op) {
|
|
808
1124
|
case "insertChild": {
|
|
809
1125
|
const parent = resolveParent(nodes, patch.at);
|
|
@@ -813,8 +1129,20 @@ function createRendererStore(initialBlocks = []) {
|
|
|
813
1129
|
touched.add(id);
|
|
814
1130
|
}
|
|
815
1131
|
mutatedBlocks = true;
|
|
816
|
-
if (inserted.record.type
|
|
817
|
-
|
|
1132
|
+
if (isListRelated(inserted.record.type) || isListRelated(parent?.type)) {
|
|
1133
|
+
markListDepthDirty(inserted.record.id);
|
|
1134
|
+
if (parent) {
|
|
1135
|
+
markListDepthDirty(parent.id);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
if (debugListPatches && (isListRelated(inserted.record.type) || isListRelated(parent?.type))) {
|
|
1139
|
+
logListPatch("insertChild", {
|
|
1140
|
+
id: inserted.record.id,
|
|
1141
|
+
type: inserted.record.type,
|
|
1142
|
+
parentId: parent?.id,
|
|
1143
|
+
parentType: parent?.type,
|
|
1144
|
+
index: patch.index
|
|
1145
|
+
});
|
|
818
1146
|
}
|
|
819
1147
|
}
|
|
820
1148
|
break;
|
|
@@ -831,8 +1159,17 @@ function createRendererStore(initialBlocks = []) {
|
|
|
831
1159
|
touched.add(parent.id);
|
|
832
1160
|
ensureUniqueChildren(parent, touched);
|
|
833
1161
|
mutatedBlocks = true;
|
|
834
|
-
if (parent.type
|
|
835
|
-
|
|
1162
|
+
if (isListRelated(parent.type) || isListRelated(removedNode?.type)) {
|
|
1163
|
+
markListDepthDirty(parent.id);
|
|
1164
|
+
}
|
|
1165
|
+
if (debugListPatches && (isListRelated(parent.type) || isListRelated(removedNode?.type))) {
|
|
1166
|
+
logListPatch("deleteChild", {
|
|
1167
|
+
id: childId,
|
|
1168
|
+
type: removedNode?.type,
|
|
1169
|
+
parentId: parent.id,
|
|
1170
|
+
parentType: parent.type,
|
|
1171
|
+
index: patch.index
|
|
1172
|
+
});
|
|
836
1173
|
}
|
|
837
1174
|
}
|
|
838
1175
|
break;
|
|
@@ -843,8 +1180,15 @@ function createRendererStore(initialBlocks = []) {
|
|
|
843
1180
|
replaceSnapshotAt(nodes, parent, patch.index, patch.node, touched);
|
|
844
1181
|
touched.add(parent.id);
|
|
845
1182
|
mutatedBlocks = true;
|
|
846
|
-
if (parent.type
|
|
847
|
-
|
|
1183
|
+
if (isListRelated(parent.type)) {
|
|
1184
|
+
markListDepthDirty(parent.id);
|
|
1185
|
+
}
|
|
1186
|
+
if (debugListPatches && isListRelated(parent.type)) {
|
|
1187
|
+
logListPatch("replaceChild", {
|
|
1188
|
+
parentId: parent.id,
|
|
1189
|
+
parentType: parent.type,
|
|
1190
|
+
index: patch.index
|
|
1191
|
+
});
|
|
848
1192
|
}
|
|
849
1193
|
break;
|
|
850
1194
|
}
|
|
@@ -870,6 +1214,15 @@ function createRendererStore(initialBlocks = []) {
|
|
|
870
1214
|
touched.add(target.id);
|
|
871
1215
|
mutatedBlocks = true;
|
|
872
1216
|
}
|
|
1217
|
+
if (isListRelated(target.type)) {
|
|
1218
|
+
markListDepthDirty(target.id);
|
|
1219
|
+
}
|
|
1220
|
+
if (debugListPatches && isListRelated(target.type)) {
|
|
1221
|
+
logListPatch("finalize", {
|
|
1222
|
+
id: target.id,
|
|
1223
|
+
type: target.type
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
873
1226
|
break;
|
|
874
1227
|
}
|
|
875
1228
|
case "reorder": {
|
|
@@ -887,8 +1240,17 @@ function createRendererStore(initialBlocks = []) {
|
|
|
887
1240
|
parent.children.splice(to, 0, ...moved);
|
|
888
1241
|
parent.version++;
|
|
889
1242
|
touched.add(parent.id);
|
|
890
|
-
if (parent.type
|
|
891
|
-
|
|
1243
|
+
if (isListRelated(parent.type)) {
|
|
1244
|
+
markListDepthDirty(parent.id);
|
|
1245
|
+
}
|
|
1246
|
+
if (debugListPatches && isListRelated(parent.type)) {
|
|
1247
|
+
logListPatch("reorder", {
|
|
1248
|
+
parentId: parent.id,
|
|
1249
|
+
parentType: parent.type,
|
|
1250
|
+
from: patch.from,
|
|
1251
|
+
to: patch.to,
|
|
1252
|
+
count: patch.count
|
|
1253
|
+
});
|
|
892
1254
|
}
|
|
893
1255
|
break;
|
|
894
1256
|
}
|
|
@@ -909,7 +1271,14 @@ function createRendererStore(initialBlocks = []) {
|
|
|
909
1271
|
const lineId = `${parent.id}::line:${absoluteIndex}`;
|
|
910
1272
|
insertedIds.push(lineId);
|
|
911
1273
|
insertedSet.add(lineId);
|
|
912
|
-
const
|
|
1274
|
+
const hasTokens = Object.prototype.hasOwnProperty.call(patch, "tokens");
|
|
1275
|
+
const nextTokens = hasTokens ? patch.tokens?.[offset] ?? null : void 0;
|
|
1276
|
+
const nextLineProps = createCodeLineProps(
|
|
1277
|
+
absoluteIndex,
|
|
1278
|
+
patch.lines[offset] ?? "",
|
|
1279
|
+
patch.highlight?.[offset] ?? null,
|
|
1280
|
+
nextTokens
|
|
1281
|
+
);
|
|
913
1282
|
const existing = nodes.get(lineId);
|
|
914
1283
|
if (existing && existing.type === "code-line") {
|
|
915
1284
|
const existingIndex = parent.children.indexOf(lineId);
|
|
@@ -962,8 +1331,12 @@ function createRendererStore(initialBlocks = []) {
|
|
|
962
1331
|
const childId = parent.children[idx];
|
|
963
1332
|
const child = nodes.get(childId);
|
|
964
1333
|
if (child && child.type === "code-line") {
|
|
965
|
-
const
|
|
966
|
-
if (
|
|
1334
|
+
const incoming = { index: idx, text: child.props?.text, html: child.props?.html };
|
|
1335
|
+
if (Object.prototype.hasOwnProperty.call(child.props ?? {}, "tokens")) {
|
|
1336
|
+
incoming.tokens = child.props.tokens;
|
|
1337
|
+
}
|
|
1338
|
+
const normalized = normalizeCodeLineProps(incoming, child.props);
|
|
1339
|
+
if (normalized !== child.props) {
|
|
967
1340
|
child.props = normalized;
|
|
968
1341
|
child.version++;
|
|
969
1342
|
touched.add(child.id);
|
|
@@ -984,7 +1357,7 @@ function createRendererStore(initialBlocks = []) {
|
|
|
984
1357
|
case "setHTML": {
|
|
985
1358
|
const target = nodes.get(patch.at.nodeId ?? patch.at.blockId);
|
|
986
1359
|
if (!target) break;
|
|
987
|
-
const sanitized = patch.sanitized ? patch.html : (0,
|
|
1360
|
+
const sanitized = patch.sanitized ? patch.html : (0, import_core2.sanitizeHTML)(patch.html);
|
|
988
1361
|
target.props = {
|
|
989
1362
|
...target.props ?? {},
|
|
990
1363
|
html: sanitized,
|
|
@@ -1006,24 +1379,73 @@ function createRendererStore(initialBlocks = []) {
|
|
|
1006
1379
|
default:
|
|
1007
1380
|
break;
|
|
1008
1381
|
}
|
|
1382
|
+
};
|
|
1383
|
+
if (perfEnabled) {
|
|
1384
|
+
const loopStart = getPerfNow();
|
|
1385
|
+
for (const patch of coalescedPatches) {
|
|
1386
|
+
const opStart = getPerfNow();
|
|
1387
|
+
applyPatch(patch);
|
|
1388
|
+
const opDuration = getPerfNow() - opStart;
|
|
1389
|
+
const entry = opStats[patch.op] ?? { count: 0, durationMs: 0 };
|
|
1390
|
+
entry.count += 1;
|
|
1391
|
+
entry.durationMs += opDuration;
|
|
1392
|
+
opStats[patch.op] = entry;
|
|
1393
|
+
}
|
|
1394
|
+
applyMs = getPerfNow() - loopStart;
|
|
1395
|
+
} else {
|
|
1396
|
+
for (const patch of coalescedPatches) {
|
|
1397
|
+
applyPatch(patch);
|
|
1398
|
+
}
|
|
1009
1399
|
}
|
|
1010
1400
|
if (mutatedBlocks) {
|
|
1011
1401
|
blocksDirty = true;
|
|
1012
1402
|
}
|
|
1013
1403
|
if (listDepthDirty) {
|
|
1014
|
-
|
|
1404
|
+
if (perfEnabled) {
|
|
1405
|
+
const start = getPerfNow();
|
|
1406
|
+
normalizeAllListDepths(nodes, touched, import_core2.PATCH_ROOT_ID);
|
|
1407
|
+
listNormalizeMs = getPerfNow() - start;
|
|
1408
|
+
} else {
|
|
1409
|
+
normalizeAllListDepths(nodes, touched, import_core2.PATCH_ROOT_ID);
|
|
1410
|
+
}
|
|
1411
|
+
} else if (listDepthDirtyNodes.size > 0) {
|
|
1412
|
+
if (perfEnabled) {
|
|
1413
|
+
const start = getPerfNow();
|
|
1414
|
+
normalizeListDepthsForIds(nodes, touched, listDepthDirtyNodes, import_core2.PATCH_ROOT_ID);
|
|
1415
|
+
listNormalizeMs = getPerfNow() - start;
|
|
1416
|
+
} else {
|
|
1417
|
+
normalizeListDepthsForIds(nodes, touched, listDepthDirtyNodes, import_core2.PATCH_ROOT_ID);
|
|
1418
|
+
}
|
|
1015
1419
|
}
|
|
1016
1420
|
if (touched.size > 0 || mutatedBlocks) {
|
|
1017
1421
|
version++;
|
|
1018
1422
|
scheduleNotify();
|
|
1019
1423
|
}
|
|
1424
|
+
if (perfEnabled) {
|
|
1425
|
+
const totalMs = getPerfNow() - perfStart;
|
|
1426
|
+
const coalesceMs = typeof metrics?.durationMs === "number" ? metrics.durationMs : 0;
|
|
1427
|
+
recordPatchPerf({
|
|
1428
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1429
|
+
totalMs,
|
|
1430
|
+
applyMs,
|
|
1431
|
+
coalesceMs,
|
|
1432
|
+
listNormalizeMs,
|
|
1433
|
+
patches: patches.length,
|
|
1434
|
+
coalescedPatches: coalescedPatches.length,
|
|
1435
|
+
touchedCount: touched.size,
|
|
1436
|
+
mutatedBlocks,
|
|
1437
|
+
ops: opStats,
|
|
1438
|
+
setPropsByType,
|
|
1439
|
+
setPropsBySize
|
|
1440
|
+
});
|
|
1441
|
+
}
|
|
1020
1442
|
return touched;
|
|
1021
1443
|
},
|
|
1022
1444
|
getBlocks() {
|
|
1023
1445
|
if (!blocksDirty) {
|
|
1024
1446
|
return blocksCache;
|
|
1025
1447
|
}
|
|
1026
|
-
const root = nodes.get(
|
|
1448
|
+
const root = nodes.get(import_core2.PATCH_ROOT_ID);
|
|
1027
1449
|
if (!root) {
|
|
1028
1450
|
blocksCache = [];
|
|
1029
1451
|
} else {
|
|
@@ -1049,6 +1471,7 @@ function createRendererStore(initialBlocks = []) {
|
|
|
1049
1471
|
}
|
|
1050
1472
|
const snapshot = { version: record.version, node: record };
|
|
1051
1473
|
nodeSnapshotCache.set(id, snapshot);
|
|
1474
|
+
pruneCache(nodeSnapshotCache, NODE_SNAPSHOT_CACHE_LIMIT, NODE_SNAPSHOT_CACHE_BUFFER);
|
|
1052
1475
|
return snapshot;
|
|
1053
1476
|
},
|
|
1054
1477
|
getChildren(id) {
|
|
@@ -1062,11 +1485,12 @@ function createRendererStore(initialBlocks = []) {
|
|
|
1062
1485
|
return EMPTY_CHILDREN_SNAPSHOT;
|
|
1063
1486
|
}
|
|
1064
1487
|
const cached = childrenSnapshotCache.get(id);
|
|
1065
|
-
if (cached && cached.version === record.version
|
|
1488
|
+
if (cached && cached.version === record.version) {
|
|
1066
1489
|
return cached;
|
|
1067
1490
|
}
|
|
1068
|
-
const snapshot = { version: record.version, children: record.children };
|
|
1491
|
+
const snapshot = { version: record.version, children: record.children.slice() };
|
|
1069
1492
|
childrenSnapshotCache.set(id, snapshot);
|
|
1493
|
+
pruneCache(childrenSnapshotCache, CHILDREN_SNAPSHOT_CACHE_LIMIT, CHILDREN_SNAPSHOT_CACHE_BUFFER);
|
|
1070
1494
|
return snapshot;
|
|
1071
1495
|
},
|
|
1072
1496
|
getLastCoalescingMetrics() {
|
|
@@ -1083,5 +1507,6 @@ function createRendererStore(initialBlocks = []) {
|
|
|
1083
1507
|
}
|
|
1084
1508
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1085
1509
|
0 && (module.exports = {
|
|
1086
|
-
createRendererStore
|
|
1510
|
+
createRendererStore,
|
|
1511
|
+
isListPatchDebugEnabled
|
|
1087
1512
|
});
|