@geml/geml 1.7.7 → 1.7.8

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 (2) hide show
  1. package/dist/render.js +35 -27
  2. package/package.json +1 -1
package/dist/render.js CHANGED
@@ -562,17 +562,27 @@ export class RenderCtx {
562
562
  return `<figure${idAttr}><p class="table-note">external data <code>${esc(src)}</code> — loaded at render time</p>${cap0}</figure>`;
563
563
  }
564
564
  }
565
+ // Overflow FOLDS; it is never dropped. `--to html` is a CONVERSION, and
566
+ // a conversion that loses data is not one — the old behaviour kept the
567
+ // first 500 lines and said "the complete data is in the document
568
+ // source", which is no help at all to someone holding only the HTML.
569
+ // The bound belongs to what is OPEN, not to what is present: the rest
570
+ // sits in a collapsed <details>, so the page is exactly as short as
571
+ // before and the block is complete. There is no ceiling above which
572
+ // lines vanish again, because a <pre> is a single text node — the cost
573
+ // of keeping them is bytes on disk, which is what not losing data
574
+ // costs.
565
575
  const tail = fmt === "jsonl" && lines.length > limit;
566
576
  const shown = tail ? lines.slice(-limit) : lines.slice(0, limit);
567
- const omitted = lines.length - shown.length;
568
- const note = omitted > 0
569
- ? `<p class="table-note">${tail
570
- ? `showing the last ${shown.length} of ${lines.length} lines — earlier lines are in the document source`
571
- : `showing the first ${shown.length} of ${lines.length} lines — the complete data is in the document source`}</p>`
572
- : "";
577
+ const rest = tail ? lines.slice(0, lines.length - shown.length) : lines.slice(shown.length);
573
578
  const cap = caption ? `<figcaption>${esc(caption)}</figcaption>` : "";
574
- const pre = `<pre class="data-src" data-format="${escAttr(fmt)}">${esc(shown.join("\n"))}</pre>`;
575
- return `<figure${idAttr}>${tail ? note + pre : pre + note}${cap}</figure>`;
579
+ const pre = (ls) => `<pre class="data-src" data-format="${escAttr(fmt)}">${esc(ls.join("\n"))}</pre>`;
580
+ if (rest.length === 0)
581
+ return `<figure${idAttr}>${pre(shown)}${cap}</figure>`;
582
+ // jsonl reads as an append-log, so its open end is the NEWEST lines and
583
+ // the fold holds the earlier ones, above; json reads from the top.
584
+ const more = `<details class="data-more"><summary>${rest.length} ${tail ? "earlier" : "more"} line${rest.length === 1 ? "" : "s"} of ${lines.length}</summary>${pre(rest)}</details>`;
585
+ return `<figure${idAttr}>${tail ? more + pre(shown) : pre(shown) + more}${cap}</figure>`;
576
586
  }
577
587
  case "table":
578
588
  return b.table ? this.table(b.table, b.id, caption) : `<p class="render-error">table failed to parse</p>`;
@@ -636,17 +646,20 @@ export class RenderCtx {
636
646
  table(t, id, caption) {
637
647
  const idAttr = id ? ` id="${escAttr(id)}"` : "";
638
648
  const alignStyle = (a) => (a ? ` style="text-align:${a}"` : "");
639
- // Parsing + laying out tens of thousands of <table> rows freezes the
640
- // page for seconds, so the HTML view renders a bounded preview (the
641
- // model keeps every row: charts, computed summaries and the code-graph
642
- // never read the HTML). Codemap edge tables additionally fold shut
643
- // they are machine data; elsewhere the table is content and stays open.
644
- // The codemap index's #modules table IS the page's content — the module
645
- // inventory people scan and filter so it renders in full. Edge tables
646
- // (#calls / #called-by) stay previewed+folded: machine data at scale.
647
- const maxRows = this.isCodemapDoc && id === "modules" ? Infinity : (this.opts.tableRows ?? 500);
649
+ // Laying out tens of thousands of <table> rows OPEN freezes the page for
650
+ // seconds, so a long table renders folded shut the codemap's edge tables
651
+ // (#calls / #called-by) are the ones that get there. Its #modules table is
652
+ // the page's content, the inventory people came to scan and filter, so that
653
+ // one stays open at any size.
654
+ //
655
+ // EVERY row is rendered. `tableRows` bounds what is OPEN, never what is
656
+ // present: past it the whole table goes inside a collapsed <details>, which
657
+ // costs the reader one click and costs the document nothing. It used to
658
+ // slice the rows away and say the complete table was in the source, which
659
+ // made `--to html` a lossy conversion of a table the model holds in full.
660
+ const foldAbove = this.isCodemapDoc && id === "modules" ? Infinity : (this.opts.tableRows ?? 500);
648
661
  const allRows = t.rows;
649
- const rows = allRows.length > maxRows ? allRows.slice(0, maxRows) : allRows;
662
+ const rows = allRows;
650
663
  const thead = t.header
651
664
  ? `<thead><tr>${t.columns.map((col, c) => `<th${alignStyle(t.align[c])}>${esc(col)}</th>`).join("")}</tr></thead>`
652
665
  : "";
@@ -666,15 +679,10 @@ export class RenderCtx {
666
679
  : "";
667
680
  const cap = caption ? `<figcaption>${esc(caption)}</figcaption>` : "";
668
681
  const tools = `<div class="table-tools"><input class="table-filter" type="search" placeholder="Filter rows…" aria-label="Filter table rows"></div>`;
669
- if (allRows.length > maxRows) {
670
- const note = `<p class="table-note">showing the first ${maxRows} of ${allRows.length} rows — the complete table is in the document source</p>`;
671
- if (this.isCodemapDoc) {
672
- const summary = `${esc(id ? "#" + id : "table")} · ${allRows.length} rows (preview: first ${maxRows})`;
673
- return `<figure class="table-figure"${idAttr}><details><summary>${summary}</summary>${tools}` +
674
- `<div class="table-scroll"><table class="geml-table">${thead}<tbody>\n${bodyRows}\n</tbody>${tfoot}</table></div>${note}</details>${cap}</figure>`;
675
- }
676
- return `<figure class="table-figure"${idAttr}>${tools}` +
677
- `<div class="table-scroll"><table class="geml-table">${thead}<tbody>\n${bodyRows}\n</tbody>${tfoot}</table></div>${note}${cap}</figure>`;
682
+ if (allRows.length > foldAbove) {
683
+ const summary = `${esc(id ? "#" + id : "table")} · ${allRows.length} rows`;
684
+ return `<figure class="table-figure"${idAttr}><details><summary>${summary}</summary>${tools}` +
685
+ `<div class="table-scroll"><table class="geml-table">${thead}<tbody>\n${bodyRows}\n</tbody>${tfoot}</table></div></details>${cap}</figure>`;
678
686
  }
679
687
  return `<figure class="table-figure"${idAttr}>${tools}` +
680
688
  `<div class="table-scroll"><table class="geml-table">${thead}<tbody>\n${bodyRows}\n</tbody>${tfoot}</table></div>${cap}</figure>`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geml/geml",
3
- "version": "1.7.7",
3
+ "version": "1.7.8",
4
4
  "mcpName": "io.github.geml-spec/geml",
5
5
  "publishConfig": {
6
6
  "access": "public"