flux-md 0.20.1 → 0.20.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/client.d.ts CHANGED
@@ -158,6 +158,10 @@ export declare class FluxClient {
158
158
  * order, after the store updates) — for side effects like lazily
159
159
  * highlighting a finished code block or analytics. A committed block never
160
160
  * re-fires; the streaming tail does not (subscribe for live tail updates).
161
+ * NOTE: this is a PARSER-commit hook — the block carries the parser's raw
162
+ * id. During a setContent divergence swap the rendered view may show that
163
+ * block under a different id (an adopted old id, or a namespaced one), so
164
+ * correlate with rendered blocks via subscribe()+getSnapshot(), not this id.
161
165
  * @param options.coalesce opt-in (default `false`): collapse multiple
162
166
  * intra-frame patch notifications into ONE `requestAnimationFrame`-scheduled
163
167
  * flush to subscribers, so a React `useSyncExternalStore` consumer renders at
@@ -289,8 +293,11 @@ export declare class FluxClient {
289
293
  * - identical committed block (html + kind + open + speculative) → the OLD
290
294
  * block object, so its id and reference survive the swap and the block
291
295
  * never re-renders (blocksEqual / the DOM keyed reconcile hold);
292
- * - changed committed block → the new block, its id offset into this
293
- * generation's namespace (adopted old ids and raw new ids could collide);
296
+ * - changed committed block → the new block CARRYING THE OLD BLOCK'S id, so
297
+ * the same keyed component re-renders in place and its state (pagination,
298
+ * expansion…) survives the swap; only a NET-NEW position (past the old
299
+ * document's end) takes a namespace-offset id, where a raw parser id
300
+ * could genuinely collide with a retained old id;
294
301
  * - still-open block over old content → the old block (never a shrinking
295
302
  * partial where complete content was already on screen); past the old
296
303
  * document's end the live tail streams in as-is;
package/dist/client.js CHANGED
@@ -262,6 +262,10 @@ class FluxClient {
262
262
  * order, after the store updates) — for side effects like lazily
263
263
  * highlighting a finished code block or analytics. A committed block never
264
264
  * re-fires; the streaming tail does not (subscribe for live tail updates).
265
+ * NOTE: this is a PARSER-commit hook — the block carries the parser's raw
266
+ * id. During a setContent divergence swap the rendered view may show that
267
+ * block under a different id (an adopted old id, or a namespaced one), so
268
+ * correlate with rendered blocks via subscribe()+getSnapshot(), not this id.
265
269
  * @param options.coalesce opt-in (default `false`): collapse multiple
266
270
  * intra-frame patch notifications into ONE `requestAnimationFrame`-scheduled
267
271
  * flush to subscribers, so a React `useSyncExternalStore` consumer renders at
@@ -416,6 +420,9 @@ class FluxClient {
416
420
  setContent(content, opts) {
417
421
  if (content !== this.lastContent) {
418
422
  if (!this.contentDone && content.startsWith(this.lastContent)) {
423
+ if (this.lastContent === "" && content.length > 0 && this.getSnapshot().length > 0) {
424
+ this.softReset(this.getSnapshot());
425
+ }
419
426
  this.append(content.slice(this.lastContent.length));
420
427
  } else {
421
428
  const displayed = this.getSnapshot();
@@ -544,8 +551,11 @@ class FluxClient {
544
551
  * - identical committed block (html + kind + open + speculative) → the OLD
545
552
  * block object, so its id and reference survive the swap and the block
546
553
  * never re-renders (blocksEqual / the DOM keyed reconcile hold);
547
- * - changed committed block → the new block, its id offset into this
548
- * generation's namespace (adopted old ids and raw new ids could collide);
554
+ * - changed committed block → the new block CARRYING THE OLD BLOCK'S id, so
555
+ * the same keyed component re-renders in place and its state (pagination,
556
+ * expansion…) survives the swap; only a NET-NEW position (past the old
557
+ * document's end) takes a namespace-offset id, where a raw parser id
558
+ * could genuinely collide with a retained old id;
549
559
  * - still-open block over old content → the old block (never a shrinking
550
560
  * partial where complete content was already on screen); past the old
551
561
  * document's end the live tail streams in as-is;
@@ -583,6 +593,8 @@ class FluxClient {
583
593
  view[i] = ob;
584
594
  continue;
585
595
  }
596
+ view[i] = { ...nb, id: ob.id };
597
+ continue;
586
598
  }
587
599
  view[i] = { ...nb, id: this.idNamespace + nb.id };
588
600
  }
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flux-md",
3
- "version": "0.20.1",
3
+ "version": "0.20.3",
4
4
  "description": "Zero-dep streaming markdown for the browser. Rust→WASM core, Web Worker per stream, incremental parse with speculative closure.",
5
5
  "type": "module",
6
6
  "sideEffects": ["./dist/worker.js", "./dist/styles.css"],