mnfst 0.5.218 → 0.5.220

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.
@@ -516,9 +516,11 @@ async function initializeMarkdownPlugin() {
516
516
  markdownSource = normalizeContent(newContent);
517
517
  }
518
518
 
519
- // Skip if no content
519
+ // Skip if no content. Baked content stays visible: a reactive
520
+ // expression can evaluate empty at boot (data still loading),
521
+ // and hiding then would blank prerendered output.
520
522
  if (!markdownSource || markdownSource.trim() === '') {
521
- element.style.opacity = '0';
523
+ if (!hasContent) element.style.opacity = '0';
522
524
  return;
523
525
  }
524
526
 
@@ -607,11 +609,13 @@ async function initializeMarkdownPlugin() {
607
609
  return;
608
610
  }
609
611
 
610
- // Prerendered MPA pages with baked content are already correct — skip
611
- // the effect (MPA navigation is full page loads).
612
- if (hasBakedContent) {
613
- return;
614
- }
612
+ // Prerendered MPA pages with baked content are already correct on
613
+ // FIRST paint, but the effect still has to register: a reactive
614
+ // expression (x-markdown="note") must keep re-rendering when its
615
+ // value changes. File-backed markdown never reaches here — the
616
+ // prerender strips x-markdown from those (data-mnfst-md-src), so
617
+ // registering the effect cannot re-fetch baked articles.
618
+ // updateContent already no-ops when the render equals the baked HTML.
615
619
 
616
620
  // Classify the source: real expressions evaluate; bare markdown/paths
617
621
  // are quoted so Alpine doesn't choke on them.
@@ -641,15 +645,21 @@ async function initializeMarkdownPlugin() {
641
645
 
642
646
  // Track last processed content to prevent unnecessary re-renders
643
647
  let lastProcessedContent = null;
648
+ // Baked output is protected from empty-value hides only until the
649
+ // first live render replaces it; after that, clearing the value
650
+ // hides the element like it always did.
651
+ let bakedOnly = hasBakedContent;
644
652
 
645
653
  effect(() => {
646
654
  getMarkdownContent(async (pathOrContent) => {
647
655
  const mdDone = mdTrack();
648
656
  try {
649
- // Reset visibility if content is empty/undefined
657
+ // Reset visibility if content is empty/undefined. Baked
658
+ // content stays visible: a reactive expression can evaluate
659
+ // empty at boot (data still loading), and hiding then would
660
+ // blank prerendered output.
650
661
  if (!pathOrContent || pathOrContent === undefined || pathOrContent === '') {
651
- el.style.opacity = '0';
652
- hasContent = false;
662
+ if (!bakedOnly) { el.style.opacity = '0'; hasContent = false; }
653
663
  return;
654
664
  }
655
665
 
@@ -722,8 +732,7 @@ async function initializeMarkdownPlugin() {
722
732
  // Ensure we have a string (e.g. $route('path')?.content can be a proxy while loading)
723
733
  const contentStr = typeof markdownContent === 'string' ? markdownContent : '';
724
734
  if (!contentStr || contentStr.trim() === '') {
725
- el.style.opacity = '0';
726
- hasContent = false;
735
+ if (!bakedOnly) { el.style.opacity = '0'; hasContent = false; }
727
736
  return;
728
737
  }
729
738
 
@@ -766,6 +775,7 @@ async function initializeMarkdownPlugin() {
766
775
 
767
776
  // Show content with fade-in
768
777
  hasContent = true;
778
+ bakedOnly = false;
769
779
  el.style.opacity = '1';
770
780
 
771
781
  // Extract headings for anchor links