@inflexa-ai/harness 0.20.0 → 0.21.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/dist/agents/conversation-agent.d.ts +26 -14
- package/dist/agents/conversation-agent.js +12 -23
- package/dist/agents/report-session-agent.d.ts +31 -5
- package/dist/agents/report-session-agent.js +31 -6
- package/dist/app/chat-turn.js +3 -1
- package/dist/app/message-assembly.d.ts +15 -1
- package/dist/app/message-assembly.js +22 -8
- package/dist/app/report-session-runtime.d.ts +21 -4
- package/dist/app/report-session-runtime.js +53 -6
- package/dist/app/spawn-report-session.d.ts +174 -17
- package/dist/app/spawn-report-session.js +233 -21
- package/dist/contracts/chat-events.d.ts +7 -2
- package/dist/contracts/message.d.ts +10 -0
- package/dist/contracts/report-blocks.d.ts +743 -19
- package/dist/contracts/report-blocks.js +186 -11
- package/dist/contracts/report-reference.d.ts +88 -0
- package/dist/contracts/report-reference.js +48 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +20 -0
- package/dist/lib/chrome.d.ts +26 -6
- package/dist/lib/chrome.js +99 -32
- package/dist/lib/eyes.d.ts +57 -0
- package/dist/lib/eyes.js +45 -0
- package/dist/lib/page-capture.d.ts +14 -0
- package/dist/lib/page-capture.js +56 -2
- package/dist/loop/run-agent.js +58 -23
- package/dist/loop/tool-detail.d.ts +19 -2
- package/dist/loop/tool-detail.js +35 -2
- package/dist/memory/content-to-cortex.d.ts +3 -2
- package/dist/memory/content-to-cortex.js +21 -12
- package/dist/memory/conversation-display-replay.js +14 -7
- package/dist/memory/thread-history.d.ts +60 -3
- package/dist/memory/thread-history.js +55 -16
- package/dist/memory/thread-store.d.ts +11 -1
- package/dist/memory/thread-store.js +12 -2
- package/dist/prompts/conversation.d.ts +1 -1
- package/dist/prompts/conversation.js +23 -6
- package/dist/prompts/report-session.d.ts +1 -1
- package/dist/prompts/report-session.js +183 -9
- package/dist/report-model/authoring-grammar.d.ts +463 -0
- package/dist/report-model/authoring-grammar.js +77 -0
- package/dist/report-model/block-walk.d.ts +57 -14
- package/dist/report-model/block-walk.js +116 -11
- package/dist/report-model/draft-finish.d.ts +22 -4
- package/dist/report-model/draft-finish.js +39 -7
- package/dist/report-model/draft-operations.d.ts +3 -0
- package/dist/report-model/draft-operations.js +19 -5
- package/dist/report-model/draft-read.d.ts +8 -5
- package/dist/report-model/draft-read.js +21 -5
- package/dist/report-model/fixture-resolver.js +15 -4
- package/dist/report-model/pin-snapshot.d.ts +24 -6
- package/dist/report-model/pin-snapshot.js +204 -6
- package/dist/report-model/production-resolver.js +15 -4
- package/dist/report-model/reference-resolver.d.ts +50 -1
- package/dist/report-model/reference-resolver.js +94 -1
- package/dist/report-model/reference-stamp.d.ts +45 -0
- package/dist/report-model/reference-stamp.js +173 -0
- package/dist/report-model/structural-validation.d.ts +4 -1
- package/dist/report-model/structural-validation.js +48 -3
- package/dist/report-model/validate.d.ts +1 -1
- package/dist/report-model/validate.js +1 -1
- package/dist/report-render/asset-lookup.d.ts +19 -0
- package/dist/report-render/asset-lookup.js +37 -0
- package/dist/report-render/assets.d.ts +45 -1
- package/dist/report-render/assets.js +65 -6
- package/dist/report-render/chart-presets.d.ts +102 -0
- package/dist/report-render/chart-presets.js +205 -0
- package/dist/report-render/chart.d.ts +112 -10
- package/dist/report-render/chart.js +1164 -41
- package/dist/report-render/design.d.ts +99 -0
- package/dist/report-render/design.js +289 -107
- package/dist/report-render/number-format.d.ts +117 -0
- package/dist/report-render/number-format.js +479 -0
- package/dist/report-render/page.d.ts +121 -5
- package/dist/report-render/page.js +689 -7
- package/dist/report-render/references.d.ts +70 -16
- package/dist/report-render/references.js +54 -22
- package/dist/report-render/render.d.ts +23 -5
- package/dist/report-render/render.js +81 -22
- package/dist/report-render/table-data.d.ts +92 -0
- package/dist/report-render/table-data.js +129 -0
- package/dist/report-render/types.d.ts +15 -0
- package/dist/report-render/value-bridge.js +6 -2
- package/dist/report-render/views/chart-view.d.ts +12 -5
- package/dist/report-render/views/chart-view.js +14 -8
- package/dist/report-render/views/page-view.d.ts +36 -15
- package/dist/report-render/views/page-view.js +45 -23
- package/dist/report-render/views/prose.d.ts +12 -2
- package/dist/report-render/views/prose.js +29 -7
- package/dist/report-render/views/references-view.d.ts +22 -8
- package/dist/report-render/views/references-view.js +101 -13
- package/dist/report-render/views/values.d.ts +128 -13
- package/dist/report-render/views/values.js +199 -18
- package/dist/runtime/assemble.d.ts +39 -5
- package/dist/runtime/assemble.js +47 -6
- package/dist/sandbox/client.d.ts +10 -1
- package/dist/sandbox/create-sandbox.d.ts +9 -4
- package/dist/sandbox/create-sandbox.js +22 -16
- package/dist/sandbox/docker-client.js +10 -7
- package/dist/sandbox/mount-plan.d.ts +45 -7
- package/dist/sandbox/mount-plan.js +43 -5
- package/dist/sandbox/types.d.ts +6 -0
- package/dist/state/init.js +38 -9
- package/dist/state/report-session-state.d.ts +42 -1
- package/dist/state/report-session-state.js +70 -2
- package/dist/state/report-versions.d.ts +22 -17
- package/dist/state/report-versions.js +48 -35
- package/dist/state/snapshot-parse.js +16 -1
- package/dist/tools/define-tool.d.ts +32 -0
- package/dist/tools/define-tool.js +4 -0
- package/dist/tools/detail-resolver.d.ts +7 -2
- package/dist/tools/detail-resolver.js +7 -2
- package/dist/tools/iterate-report.d.ts +1 -1
- package/dist/tools/report/preview-snapshot.js +1 -0
- package/dist/tools/report-authoring/authoring-tools.d.ts +15 -6
- package/dist/tools/report-authoring/authoring-tools.js +99 -18
- package/dist/tools/report-session/derive-table.d.ts +162 -0
- package/dist/tools/report-session/derive-table.js +459 -0
- package/dist/tools/report-session/examine-page.d.ts +48 -18
- package/dist/tools/report-session/examine-page.js +204 -24
- package/dist/tools/report-session/index.d.ts +2 -0
- package/dist/tools/report-session/index.js +2 -0
- package/dist/tools/report-session/list-artifacts.d.ts +97 -0
- package/dist/tools/report-session/list-artifacts.js +197 -0
- package/dist/tools/report-session/preview-report.d.ts +6 -0
- package/dist/tools/report-session/preview-report.js +180 -28
- package/dist/tools/report-session/record-version.d.ts +22 -10
- package/dist/tools/report-session/record-version.js +99 -14
- package/dist/tools/start-report-session.d.ts +115 -0
- package/dist/tools/start-report-session.js +179 -0
- package/dist/workspace/paths.d.ts +50 -0
- package/dist/workspace/paths.js +63 -0
- package/package.json +2 -1
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
* serves. Thus a `figure` here carries a ready `src` string, and the renderer holds no policy about the
|
|
8
8
|
* image bytes.
|
|
9
9
|
*/
|
|
10
|
+
import type { DataAsset } from "./table-data.js";
|
|
10
11
|
/**
|
|
11
12
|
* The value that one block resolves to, as a closed union. A `scalar` gives one number or one string. A
|
|
12
13
|
* `table` gives the rows and the optional column order. A `figure` gives a ready source string. A
|
|
13
14
|
* `citation` echoes one external id.
|
|
15
|
+
*
|
|
16
|
+
* A `table` carries `total` when a row bound cut the rows of the artifact. The renderer states the shown
|
|
17
|
+
* count against it. A table with no bound carries none, and the row count answers for it.
|
|
14
18
|
*/
|
|
15
19
|
export type RenderValue = {
|
|
16
20
|
type: "scalar";
|
|
@@ -19,6 +23,7 @@ export type RenderValue = {
|
|
|
19
23
|
type: "table";
|
|
20
24
|
rows: Array<Record<string, string | number>>;
|
|
21
25
|
columns?: string[];
|
|
26
|
+
total?: number;
|
|
22
27
|
} | {
|
|
23
28
|
type: "figure";
|
|
24
29
|
src: string;
|
|
@@ -37,3 +42,13 @@ export interface RenderProblem {
|
|
|
37
42
|
}
|
|
38
43
|
/** The value map that the renderer takes, keyed by block id. */
|
|
39
44
|
export type RenderValues = Record<string, RenderValue>;
|
|
45
|
+
/**
|
|
46
|
+
* One rendered page: the HTML string, and each data asset that the page references.
|
|
47
|
+
*
|
|
48
|
+
* The renderer writes no file. Thus it gives the asset bytes back to the caller, and the caller stages
|
|
49
|
+
* them beside the page. A document with no table gives an empty list, and its page references none.
|
|
50
|
+
*/
|
|
51
|
+
export interface RenderedPage {
|
|
52
|
+
html: string;
|
|
53
|
+
dataAssets: DataAsset[];
|
|
54
|
+
}
|
|
@@ -69,12 +69,16 @@ export function bridgeValues(resolutions, figureSrc) {
|
|
|
69
69
|
/**
|
|
70
70
|
* Map a resolved table onto a render table. The explicit column order carries through when it is present,
|
|
71
71
|
* and it stays absent otherwise, thus the renderer keeps its first-row order as the default.
|
|
72
|
+
*
|
|
73
|
+
* The pre-bound total carries through the same way. The resolution is the one step that reads the whole
|
|
74
|
+
* artifact, thus the renderer takes that count and never counts again.
|
|
72
75
|
*/
|
|
73
76
|
function tableValue(value) {
|
|
77
|
+
const total = value.total === undefined ? {} : { total: value.total };
|
|
74
78
|
if (value.columns !== undefined) {
|
|
75
|
-
return { type: "table", rows: value.rows, columns: value.columns };
|
|
79
|
+
return { type: "table", rows: value.rows, columns: value.columns, ...total };
|
|
76
80
|
}
|
|
77
|
-
return { type: "table", rows: value.rows };
|
|
81
|
+
return { type: "table", rows: value.rows, ...total };
|
|
78
82
|
}
|
|
79
83
|
/** Make one mismatch that names the block, its kind, the resolved type that it needs, and the type that arrived. */
|
|
80
84
|
function mismatch(blockId, blockKind, expected, actual) {
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The chart
|
|
2
|
+
* The chart card markup.
|
|
3
3
|
*
|
|
4
4
|
* The bootstrap in `page.ts` reads the option from the next element sibling of the container. Thus the
|
|
5
5
|
* `<script type="application/json">` element MUST follow the container div with no element between them.
|
|
6
6
|
*
|
|
7
|
-
* The
|
|
8
|
-
*
|
|
7
|
+
* The card is the square corner-accent form of the table and the figure, with the mono title line over it. A
|
|
8
|
+
* report is a document, thus the card wears no application-window costume. The chart body carries a fixed
|
|
9
9
|
* height, because the chart runtime measures the container and a container with no height shows no chart.
|
|
10
10
|
*/
|
|
11
11
|
import type { ChartBlock } from "../../contracts/report-blocks.js";
|
|
12
12
|
import type { EchartOption } from "../chart.js";
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
import type { ReferenceLedger } from "../references.js";
|
|
14
|
+
/**
|
|
15
|
+
* Render the card markup for a chart.
|
|
16
|
+
*
|
|
17
|
+
* The whole-table binding joins the reference ladder, thus the title line carries the marker and the
|
|
18
|
+
* appendix names the artifact that the chart plots. A chart with no title still shows its marker on the
|
|
19
|
+
* same line.
|
|
20
|
+
*/
|
|
21
|
+
export declare function renderChart(block: ChartBlock, ledger: ReferenceLedger, option: EchartOption): string;
|
|
@@ -1,26 +1,32 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* The chart
|
|
3
|
+
* The chart card markup.
|
|
4
4
|
*
|
|
5
5
|
* The bootstrap in `page.ts` reads the option from the next element sibling of the container. Thus the
|
|
6
6
|
* `<script type="application/json">` element MUST follow the container div with no element between them.
|
|
7
7
|
*
|
|
8
|
-
* The
|
|
9
|
-
*
|
|
8
|
+
* The card is the square corner-accent form of the table and the figure, with the mono title line over it. A
|
|
9
|
+
* report is a document, thus the card wears no application-window costume. The chart body carries a fixed
|
|
10
10
|
* height, because the chart runtime measures the container and a container with no height shows no chart.
|
|
11
11
|
*/
|
|
12
12
|
import { raw } from "hono/html";
|
|
13
|
+
import { Marker } from "./references-view.js";
|
|
13
14
|
import { scriptJson } from "../script-json.js";
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Render the card markup for a chart.
|
|
17
|
+
*
|
|
18
|
+
* The whole-table binding joins the reference ladder, thus the title line carries the marker and the
|
|
19
|
+
* appendix names the artifact that the chart plots. A chart with no title still shows its marker on the
|
|
20
|
+
* same line.
|
|
21
|
+
*/
|
|
22
|
+
export function renderChart(block, ledger, option) {
|
|
23
|
+
const n = ledger.mark(block.binding);
|
|
18
24
|
const containerId = chartContainerId(block.id);
|
|
19
25
|
// The JSON goes to the page through `raw()`, thus `scriptJson` is the sole guard of this sink. It
|
|
20
26
|
// replaces every `<` with `\u003c`, thus a `</script` sequence in a string cell cannot close the
|
|
21
27
|
// element early. The JSON parser reads `\u003c` as `<`, thus the option value stays exact.
|
|
22
28
|
const json = scriptJson(option);
|
|
23
|
-
return String(_jsxs("div", { class: "report-chart", children: [_jsxs("div", { class: "
|
|
29
|
+
return String(_jsxs("div", { class: "report-chart", children: [_jsxs("div", { class: "report-chart-title", children: [block.title, _jsx(Marker, { n: n })] }), _jsxs("div", { class: "report-chart-card corner-accents", children: [_jsx("div", { id: containerId, "data-echarts-id": block.id, class: "chart-container" }), _jsx("script", { type: "application/json", children: raw(json) })] }), block.caption !== undefined ? _jsx("p", { class: "report-caption", children: block.caption }) : null] }));
|
|
24
30
|
}
|
|
25
31
|
/** The container id derives from the block id, thus the id stays stable across renders. */
|
|
26
32
|
function chartContainerId(blockId) {
|
|
@@ -1,17 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The page assembly: the hero, the bands, the
|
|
2
|
+
* The page assembly: the hero, the bands, the appendix band, and the footer.
|
|
3
3
|
*
|
|
4
|
-
* The skeleton inlines the style rules in the head, and it puts the
|
|
5
|
-
* The order
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
4
|
+
* The skeleton inlines the style rules in the head, and it puts the page scripts at the end of the body.
|
|
5
|
+
* The script order is a contract. The theme registration runs before the chart bootstrap, thus each chart
|
|
6
|
+
* finds its theme. The fade-in observer also runs before the chart bootstrap, thus the bootstrap finds the
|
|
7
|
+
* reveal gate and it signals readiness after the first reveal pass. The grid boot runs before the chart
|
|
8
|
+
* bootstrap too, thus every grid stands before the page signals that it is ready. The scrollspy reads the
|
|
9
|
+
* sections alone, thus its position is free. The navigation, the main content, and the reference frame
|
|
10
|
+
* arrive as already-escaped markup strings, thus `raw()` inserts them byte for byte.
|
|
10
11
|
*
|
|
11
12
|
* One band holds one top-level section. The band index drives the alternation of the background and of the
|
|
12
13
|
* texture, thus a caller that adds a band passes the next index.
|
|
14
|
+
*
|
|
15
|
+
* The container gives the full-bleed gutter of a region, and the content column inside it gives the one
|
|
16
|
+
* measure of the page. The hero, each band, and the footer use the same pair. Thus every block kind reads at
|
|
17
|
+
* one width, and the title over them sits on the same left edge.
|
|
13
18
|
*/
|
|
14
|
-
import type {
|
|
19
|
+
import type { DataAsset } from "../table-data.js";
|
|
20
|
+
import type { CitationRecords } from "../../report-model/reference-resolver.js";
|
|
21
|
+
import type { DerivationChains, ReferenceLedger } from "../references.js";
|
|
15
22
|
/**
|
|
16
23
|
* Wrap already-escaped markup in one full-bleed band. An even index gives the white background and the dot
|
|
17
24
|
* texture, and an odd index gives the slate background and the grid texture. The noise texture lies over
|
|
@@ -19,13 +26,27 @@ import type { ReferenceLedger } from "../references.js";
|
|
|
19
26
|
*/
|
|
20
27
|
export declare function renderBand(index: number, inner: string): string;
|
|
21
28
|
/**
|
|
22
|
-
* Wrap the
|
|
23
|
-
*
|
|
29
|
+
* Wrap the one appendix in a band of its own, under the one title.
|
|
30
|
+
*
|
|
31
|
+
* The two reference kinds answer different questions, but one marker notation sends the reader to both.
|
|
32
|
+
* Thus one list serves them, and the kind tag of an entry states which question it answers.
|
|
33
|
+
*
|
|
34
|
+
* An empty ledger renders no band. The index continues the band alternation of the sections, thus the
|
|
35
|
+
* appendix takes the next surface. The records carry the bibliography of each cited key, and a ledger with
|
|
36
|
+
* no citation reads none of them. The chains carry the derivation of each derived path, and an entry of
|
|
37
|
+
* such a path states it.
|
|
24
38
|
*/
|
|
25
|
-
export declare function renderReferenceSection(ledger: ReferenceLedger, index: number): string;
|
|
39
|
+
export declare function renderReferenceSection(ledger: ReferenceLedger, index: number, records?: CitationRecords, chains?: DerivationChains): string;
|
|
26
40
|
/**
|
|
27
|
-
* Assemble the page from the title, the navigation, the main content,
|
|
28
|
-
* passes through the runtime as text, and the runtime escapes it. The reference frame is
|
|
29
|
-
* an empty frame adds no markup.
|
|
41
|
+
* Assemble the page from the title, the navigation, the main content, the reference frame, and the data
|
|
42
|
+
* assets. The title passes through the runtime as text, and the runtime escapes it. The reference frame is
|
|
43
|
+
* optional, thus an empty frame adds no markup.
|
|
44
|
+
*
|
|
45
|
+
* Each data asset rides a classic `script` tag at the end of the body, and the decoder runs after the last
|
|
46
|
+
* of them. Thus every payload is registered before any reader looks. A page with no asset carries no tag
|
|
47
|
+
* and no decoder.
|
|
48
|
+
*
|
|
49
|
+
* `grids` states that the content holds a grid mount. The grid runtime weighs about two megabytes, thus a
|
|
50
|
+
* page whose only payload feeds a chart references neither the runtime nor the grid boot.
|
|
30
51
|
*/
|
|
31
|
-
export declare function assemblePage(title: string, nav: string, content: string, references: string): string;
|
|
52
|
+
export declare function assemblePage(title: string, nav: string, content: string, references: string, dataAssets: readonly DataAsset[], grids: boolean): string;
|
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* The page assembly: the hero, the bands, the
|
|
3
|
+
* The page assembly: the hero, the bands, the appendix band, and the footer.
|
|
4
4
|
*
|
|
5
|
-
* The skeleton inlines the style rules in the head, and it puts the
|
|
6
|
-
* The order
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* The skeleton inlines the style rules in the head, and it puts the page scripts at the end of the body.
|
|
6
|
+
* The script order is a contract. The theme registration runs before the chart bootstrap, thus each chart
|
|
7
|
+
* finds its theme. The fade-in observer also runs before the chart bootstrap, thus the bootstrap finds the
|
|
8
|
+
* reveal gate and it signals readiness after the first reveal pass. The grid boot runs before the chart
|
|
9
|
+
* bootstrap too, thus every grid stands before the page signals that it is ready. The scrollspy reads the
|
|
10
|
+
* sections alone, thus its position is free. The navigation, the main content, and the reference frame
|
|
11
|
+
* arrive as already-escaped markup strings, thus `raw()` inserts them byte for byte.
|
|
11
12
|
*
|
|
12
13
|
* One band holds one top-level section. The band index drives the alternation of the background and of the
|
|
13
14
|
* texture, thus a caller that adds a band passes the next index.
|
|
15
|
+
*
|
|
16
|
+
* The container gives the full-bleed gutter of a region, and the content column inside it gives the one
|
|
17
|
+
* measure of the page. The hero, each band, and the footer use the same pair. Thus every block kind reads at
|
|
18
|
+
* one width, and the title over them sits on the same left edge.
|
|
14
19
|
*/
|
|
15
20
|
import { raw } from "hono/html";
|
|
16
|
-
import { ASSET_HEAD, CHART_BOOTSTRAP, FADE_IN_OBSERVER } from "../page.js";
|
|
21
|
+
import { ASSET_HEAD, CHART_BOOTSTRAP, FADE_IN_OBSERVER, GRID_ASSET_HEAD, GRID_BOOTSTRAP, SECTION_SPY, TABLE_DATA_DECODER } from "../page.js";
|
|
22
|
+
import { stagedSource } from "../assets.js";
|
|
17
23
|
import { DESIGN_CSS, ECHARTS_THEME, ECHARTS_THEME_NAME } from "../design.js";
|
|
18
|
-
import {
|
|
24
|
+
import { renderReferences } from "./references-view.js";
|
|
19
25
|
import { scriptJson } from "../script-json.js";
|
|
20
26
|
/** The constant eyebrow of the hero. The render reads no clock, thus the hero carries no date. */
|
|
21
27
|
const HERO_EYEBROW = "INFLEXA · ANALYSIS REPORT";
|
|
22
28
|
/** The constant note of the footer. */
|
|
23
|
-
const FOOTER_NOTE = "Powered by Inflexa
|
|
29
|
+
const FOOTER_NOTE = "Powered by Inflexa";
|
|
30
|
+
/** The title of the one appendix. It holds each artifact and each paper that the report names. */
|
|
31
|
+
const REFERENCES_TITLE = "References";
|
|
24
32
|
/**
|
|
25
33
|
* The theme object as script-safe JSON. `scriptJson` replaces every `<` with `\u003c`, thus a later edit
|
|
26
34
|
* that adds a `<` to the theme stays safe inside the script sink. The JSON parser reads `\u003c` as `<`, thus
|
|
@@ -44,26 +52,40 @@ const THEME_REGISTRATION = `(function () {
|
|
|
44
52
|
*/
|
|
45
53
|
export function renderBand(index, inner) {
|
|
46
54
|
const surface = index % 2 === 0 ? "report-band-white texture-dots" : "report-band-slate texture-grid";
|
|
47
|
-
return String(_jsx("section", { class: `report-band ${surface} texture-noise`, children: _jsx("div", { class: "report-container fade-in", children: raw(inner) }) }));
|
|
55
|
+
return String(_jsx("section", { class: `report-band ${surface} texture-noise`, children: _jsx("div", { class: "report-container fade-in", children: _jsx("div", { class: "report-content", children: raw(inner) }) }) }));
|
|
48
56
|
}
|
|
49
57
|
/**
|
|
50
|
-
* Wrap the
|
|
51
|
-
*
|
|
58
|
+
* Wrap the one appendix in a band of its own, under the one title.
|
|
59
|
+
*
|
|
60
|
+
* The two reference kinds answer different questions, but one marker notation sends the reader to both.
|
|
61
|
+
* Thus one list serves them, and the kind tag of an entry states which question it answers.
|
|
62
|
+
*
|
|
63
|
+
* An empty ledger renders no band. The index continues the band alternation of the sections, thus the
|
|
64
|
+
* appendix takes the next surface. The records carry the bibliography of each cited key, and a ledger with
|
|
65
|
+
* no citation reads none of them. The chains carry the derivation of each derived path, and an entry of
|
|
66
|
+
* such a path states it.
|
|
52
67
|
*/
|
|
53
|
-
export function renderReferenceSection(ledger, index) {
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
68
|
+
export function renderReferenceSection(ledger, index, records, chains) {
|
|
69
|
+
const references = renderReferences(ledger, records, chains);
|
|
70
|
+
if (references === "") {
|
|
56
71
|
return "";
|
|
57
72
|
}
|
|
58
|
-
const heading = String(_jsx("h2", { class: "report-heading report-heading-
|
|
59
|
-
return renderBand(index, heading +
|
|
73
|
+
const heading = String(_jsx("h2", { class: "report-heading report-heading-3 report-ref-title", children: REFERENCES_TITLE }));
|
|
74
|
+
return renderBand(index, heading + references);
|
|
60
75
|
}
|
|
61
76
|
/**
|
|
62
|
-
* Assemble the page from the title, the navigation, the main content,
|
|
63
|
-
* passes through the runtime as text, and the runtime escapes it. The reference frame is
|
|
64
|
-
* an empty frame adds no markup.
|
|
77
|
+
* Assemble the page from the title, the navigation, the main content, the reference frame, and the data
|
|
78
|
+
* assets. The title passes through the runtime as text, and the runtime escapes it. The reference frame is
|
|
79
|
+
* optional, thus an empty frame adds no markup.
|
|
80
|
+
*
|
|
81
|
+
* Each data asset rides a classic `script` tag at the end of the body, and the decoder runs after the last
|
|
82
|
+
* of them. Thus every payload is registered before any reader looks. A page with no asset carries no tag
|
|
83
|
+
* and no decoder.
|
|
84
|
+
*
|
|
85
|
+
* `grids` states that the content holds a grid mount. The grid runtime weighs about two megabytes, thus a
|
|
86
|
+
* page whose only payload feeds a chart references neither the runtime nor the grid boot.
|
|
65
87
|
*/
|
|
66
|
-
export function assemblePage(title, nav, content, references) {
|
|
88
|
+
export function assemblePage(title, nav, content, references, dataAssets, grids) {
|
|
67
89
|
return ("<!doctype html>" +
|
|
68
|
-
String(_jsxs("html", { lang: "en", children: [_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: title }), raw(ASSET_HEAD), _jsx("style", { children: raw(DESIGN_CSS) })] }), _jsxs("body", { children: [raw(nav), _jsx("header", { class: "report-hero texture-noise", children:
|
|
90
|
+
String(_jsxs("html", { lang: "en", children: [_jsxs("head", { children: [_jsx("meta", { charset: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1" }), _jsx("title", { children: title }), raw(ASSET_HEAD), grids ? raw(GRID_ASSET_HEAD) : null, _jsx("style", { children: raw(DESIGN_CSS) })] }), _jsxs("body", { children: [raw(nav), _jsx("header", { class: "report-hero texture-noise", children: _jsx("div", { class: "report-container", children: _jsxs("div", { class: "report-content", children: [_jsx("p", { class: "report-eyebrow", children: HERO_EYEBROW }), _jsx("h1", { class: "report-display", children: title })] }) }) }), _jsxs("main", { children: [raw(content), references.length > 0 ? raw(references) : null] }), _jsx("footer", { class: "report-footer", children: _jsx("div", { class: "report-container", children: _jsxs("div", { class: "report-content report-footer-row", children: [_jsx("span", { class: "report-footer-title", children: title }), _jsx("span", { class: "report-footer-note", children: FOOTER_NOTE })] }) }) }), dataAssets.map((asset) => (_jsx("script", { src: stagedSource(asset.name) }))), dataAssets.length > 0 ? _jsx("script", { children: raw(TABLE_DATA_DECODER) }) : null, _jsx("script", { children: raw(THEME_REGISTRATION) }), _jsx("script", { children: raw(FADE_IN_OBSERVER) }), grids ? _jsx("script", { children: raw(GRID_BOOTSTRAP) }) : null, _jsx("script", { children: raw(CHART_BOOTSTRAP) }), _jsx("script", { children: raw(SECTION_SPY) })] })] })));
|
|
69
91
|
}
|
|
@@ -4,15 +4,25 @@
|
|
|
4
4
|
* The runtime escapes every interpolated string, thus hostile prose reaches the page as text. A text
|
|
5
5
|
* block and a claim block split the prose on a blank line, and each part becomes one paragraph. A claim
|
|
6
6
|
* adds one marker for each binding, and the markers number through the shared ledger.
|
|
7
|
+
*
|
|
8
|
+
* A text block also carries a typed list, and the list renders as list markup after the paragraphs. Each
|
|
9
|
+
* item takes the same escape as a paragraph, thus no item reaches the page as markup.
|
|
7
10
|
*/
|
|
8
11
|
import type { ClaimBlock, SectionBlock, TextBlock } from "../../contracts/report-blocks.js";
|
|
9
12
|
import type { ReferenceLedger } from "../references.js";
|
|
10
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Render a text block as escaped paragraphs, and then its list.
|
|
15
|
+
*
|
|
16
|
+
* The lead sentences introduce the enumeration, thus the list comes after them. An empty prose gives no
|
|
17
|
+
* paragraph, and a block with a list alone renders the list alone. A block with no list renders the
|
|
18
|
+
* paragraphs alone, exactly as it did before the field existed.
|
|
19
|
+
*/
|
|
11
20
|
export declare function renderText(block: TextBlock): string;
|
|
12
21
|
/**
|
|
13
22
|
* Render a claim block as escaped paragraphs plus evidence markers. The markers attach to the last
|
|
14
23
|
* paragraph, thus they sit at the end of the claim text. The ledger marks each binding, thus a shared
|
|
15
|
-
* reference keeps one number across the page.
|
|
24
|
+
* reference keeps one number across the page. An artifact binding and a citation binding read the same
|
|
25
|
+
* bracket, because one ladder counts them both.
|
|
16
26
|
*/
|
|
17
27
|
export declare function renderClaim(block: ClaimBlock, ledger: ReferenceLedger): string;
|
|
18
28
|
/**
|
|
@@ -5,11 +5,18 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "hono/jsx/jsx-
|
|
|
5
5
|
* The runtime escapes every interpolated string, thus hostile prose reaches the page as text. A text
|
|
6
6
|
* block and a claim block split the prose on a blank line, and each part becomes one paragraph. A claim
|
|
7
7
|
* adds one marker for each binding, and the markers number through the shared ledger.
|
|
8
|
+
*
|
|
9
|
+
* A text block also carries a typed list, and the list renders as list markup after the paragraphs. Each
|
|
10
|
+
* item takes the same escape as a paragraph, thus no item reaches the page as markup.
|
|
8
11
|
*/
|
|
9
12
|
import { raw } from "hono/html";
|
|
10
13
|
import { Marker } from "./references-view.js";
|
|
11
|
-
/** The paragraph class of a text block and a claim block. The
|
|
14
|
+
/** The paragraph class of a text block and a claim block. The paragraph fills the content column. */
|
|
12
15
|
const PARAGRAPH_CLASS = "report-prose";
|
|
16
|
+
/** The class of a rendered list. The list fills the content column, the same as a paragraph. */
|
|
17
|
+
const LIST_CLASS = "report-list";
|
|
18
|
+
/** The site that the navigation brand links to. It is the one reference of the page that leaves the page. */
|
|
19
|
+
const BRAND_HREF = "https://inflexa.ai/";
|
|
13
20
|
/**
|
|
14
21
|
* Split prose into paragraphs on a blank line. A run of blank lines makes one split. An empty part drops
|
|
15
22
|
* out, thus a leading or a trailing blank line adds no empty paragraph.
|
|
@@ -25,19 +32,34 @@ function splitParagraphs(prose) {
|
|
|
25
32
|
}
|
|
26
33
|
return paragraphs;
|
|
27
34
|
}
|
|
28
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* One typed list as list markup. The flag selects the element: an ordered list numbers its items, and an
|
|
37
|
+
* unordered one bullets them. Each item is one inline line, thus no item holds a list of its own.
|
|
38
|
+
*/
|
|
39
|
+
function TextListView({ list }) {
|
|
40
|
+
const items = list.items.map((item) => _jsx("li", { class: "report-list-item", children: item }));
|
|
41
|
+
return list.ordered ? _jsx("ol", { class: LIST_CLASS, children: items }) : _jsx("ul", { class: LIST_CLASS, children: items });
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Render a text block as escaped paragraphs, and then its list.
|
|
45
|
+
*
|
|
46
|
+
* The lead sentences introduce the enumeration, thus the list comes after them. An empty prose gives no
|
|
47
|
+
* paragraph, and a block with a list alone renders the list alone. A block with no list renders the
|
|
48
|
+
* paragraphs alone, exactly as it did before the field existed.
|
|
49
|
+
*/
|
|
29
50
|
export function renderText(block) {
|
|
30
51
|
const paragraphs = splitParagraphs(block.content.prose);
|
|
31
|
-
|
|
52
|
+
const list = block.content.list;
|
|
53
|
+
return String(_jsxs(_Fragment, { children: [paragraphs.map((paragraph) => (_jsx("p", { class: PARAGRAPH_CLASS, children: paragraph }))), list !== undefined ? _jsx(TextListView, { list: list }) : null] }));
|
|
32
54
|
}
|
|
33
55
|
/**
|
|
34
56
|
* Render a claim block as escaped paragraphs plus evidence markers. The markers attach to the last
|
|
35
57
|
* paragraph, thus they sit at the end of the claim text. The ledger marks each binding, thus a shared
|
|
36
|
-
* reference keeps one number across the page.
|
|
58
|
+
* reference keeps one number across the page. An artifact binding and a citation binding read the same
|
|
59
|
+
* bracket, because one ladder counts them both.
|
|
37
60
|
*/
|
|
38
61
|
export function renderClaim(block, ledger) {
|
|
39
|
-
const
|
|
40
|
-
const markers = markerNumbers.map((n) => _jsx(Marker, { n: n }));
|
|
62
|
+
const markers = block.bindings.map((reference) => _jsx(Marker, { n: ledger.mark(reference) }));
|
|
41
63
|
const paragraphs = splitParagraphs(block.content.prose);
|
|
42
64
|
if (paragraphs.length === 0) {
|
|
43
65
|
return String(_jsx("p", { class: PARAGRAPH_CLASS, children: markers }));
|
|
@@ -65,5 +87,5 @@ export function renderSection(section, depth, childrenHtml) {
|
|
|
65
87
|
* The `report-sidebar` id is the hook of the layout shift on a large viewport.
|
|
66
88
|
*/
|
|
67
89
|
export function renderNav(topSections) {
|
|
68
|
-
return String(_jsxs("aside", { id: "report-sidebar", class: "report-nav", "aria-label": "Report navigation", children: [_jsx("div", { class: "report-nav-brand", children: _jsx("
|
|
90
|
+
return String(_jsxs("aside", { id: "report-sidebar", class: "report-nav", "aria-label": "Report navigation", children: [_jsx("div", { class: "report-nav-brand", children: _jsx("a", { class: "report-nav-brand-name", href: BRAND_HREF, children: "inflexa" }) }), _jsx("nav", { class: "report-nav-list", "aria-label": "Report sections", children: topSections.map((section, index) => (_jsxs("a", { href: `#${section.id}`, class: "report-nav-link", children: [_jsx("span", { class: "report-nav-index", children: index + 1 }), _jsx("span", { class: "report-nav-label", children: section.title })] }))) })] }));
|
|
69
91
|
}
|
|
@@ -1,20 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The reference markup: the evidence marker and the
|
|
2
|
+
* The reference markup: the one evidence marker, and the one appendix list under it.
|
|
3
3
|
*
|
|
4
4
|
* The runtime escapes each child and each attribute value, thus a hostile path, a hostile id, or a
|
|
5
|
-
* hostile operation reaches the page as text. The list keeps the first-appearance order of the
|
|
5
|
+
* hostile operation reaches the page as text. The list keeps the first-appearance order of the ladder,
|
|
6
6
|
* thus the ordinal of each item matches its marker.
|
|
7
|
+
*
|
|
8
|
+
* One list holds both reference kinds, flat and in number order. Each entry leads with a kind tag, thus an
|
|
9
|
+
* artifact entry and a literature entry stay apart on sight without a heading between them. A page with an
|
|
10
|
+
* empty ledger renders no list at all.
|
|
7
11
|
*/
|
|
8
|
-
import type
|
|
12
|
+
import { type CitationRecords } from "../../report-model/reference-resolver.js";
|
|
13
|
+
import { type DerivationChains, type ReferenceLedger } from "../references.js";
|
|
9
14
|
/**
|
|
10
|
-
* One evidence marker as a
|
|
11
|
-
*
|
|
15
|
+
* One evidence marker as a bracket number that links to its appendix entry.
|
|
16
|
+
*
|
|
17
|
+
* A bracket reads as a reference inside prose, and it stays a span beside the words. One notation serves
|
|
18
|
+
* every kind, thus one list answers every marker.
|
|
12
19
|
*/
|
|
13
20
|
export declare function Marker({ n }: {
|
|
14
21
|
n: number;
|
|
15
22
|
}): import("hono/jsx/jsx-dev-runtime").JSX.Element;
|
|
16
23
|
/**
|
|
17
|
-
* The
|
|
18
|
-
*
|
|
24
|
+
* The one appendix list: one entry for each distinct reference of the page, in the order of the ladder.
|
|
25
|
+
*
|
|
26
|
+
* The list is an appendix: a reader consults one entry from a marker, thus the design keeps it quieter than
|
|
27
|
+
* the body. The ordered list numbers its own items, thus the shown number of an entry matches the marker
|
|
28
|
+
* that sent the reader to it. An empty ledger gives an empty string, thus the page shows no empty list.
|
|
29
|
+
*
|
|
30
|
+
* The records carry the bibliography of each cited key, and a ledger with no citation reads none of them.
|
|
31
|
+
* The chains are the derivations of the session, keyed by the output path. An entry whose path the chains
|
|
32
|
+
* hold carries the chain line, and each other entry carries none.
|
|
19
33
|
*/
|
|
20
|
-
export declare function
|
|
34
|
+
export declare function renderReferences(ledger: ReferenceLedger, records?: CitationRecords, chains?: DerivationChains): string;
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "hono/jsx/jsx-runtime";
|
|
2
|
+
import { citationRecordOf } from "../../report-model/reference-resolver.js";
|
|
3
|
+
import { citationKeyOf } from "../references.js";
|
|
2
4
|
/**
|
|
3
|
-
* One evidence marker as a
|
|
4
|
-
*
|
|
5
|
+
* One evidence marker as a bracket number that links to its appendix entry.
|
|
6
|
+
*
|
|
7
|
+
* A bracket reads as a reference inside prose, and it stays a span beside the words. One notation serves
|
|
8
|
+
* every kind, thus one list answers every marker.
|
|
5
9
|
*/
|
|
6
10
|
export function Marker({ n }) {
|
|
7
|
-
return (_jsx("
|
|
11
|
+
return (_jsx("span", { class: "report-marker", children: _jsx("a", { href: `#ref-${n}`, children: `[${n}]` }) }));
|
|
8
12
|
}
|
|
9
13
|
/** The kind label of one reference entry. */
|
|
10
14
|
function RefKind({ children }) {
|
|
@@ -18,6 +22,56 @@ function PathCode({ children }) {
|
|
|
18
22
|
function Detail({ children }) {
|
|
19
23
|
return _jsx("span", { class: "report-ref-detail", children: children });
|
|
20
24
|
}
|
|
25
|
+
/** The head of a content hash in a monospace span. */
|
|
26
|
+
function HashCode({ children }) {
|
|
27
|
+
return _jsx("code", { class: "report-ref-hash", children: children });
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The count of hash characters that a chain line shows.
|
|
31
|
+
*
|
|
32
|
+
* A content hash is 64 hex characters, and a line that carries three whole ones reads as noise. The head
|
|
33
|
+
* identifies the bytes, and it matches the count that a staged file name carries. Thus a reader compares the
|
|
34
|
+
* two by sight.
|
|
35
|
+
*/
|
|
36
|
+
const CHAIN_HASH_CHARS = 12;
|
|
37
|
+
/** The head of one content hash: the hex after the algorithm name, cut to the shown length. */
|
|
38
|
+
function hashHead(hash) {
|
|
39
|
+
return hash.slice(hash.lastIndexOf(":") + 1).slice(0, CHAIN_HASH_CHARS);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The head of the script hash, as a link to the staged script where the caller staged one.
|
|
43
|
+
*
|
|
44
|
+
* The hash head stays the text of the link. Thus the reader reads the same head as before, and the click
|
|
45
|
+
* opens the script itself. A chain with no staged script shows the head alone.
|
|
46
|
+
*/
|
|
47
|
+
function ScriptLink({ chain }) {
|
|
48
|
+
const head = _jsx(HashCode, { children: hashHead(chain.scriptHash) });
|
|
49
|
+
return chain.scriptSource === undefined ? (head) : (_jsx("a", { class: "report-ref-link", href: chain.scriptSource, children: head }));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The chain of one derived path: each source with the head of its hash, then the head of the script hash,
|
|
53
|
+
* then the derived file.
|
|
54
|
+
*
|
|
55
|
+
* The line rides under the entry of the path, thus the entry itself keeps the form of a pinned artifact and
|
|
56
|
+
* the chain adds one quiet line under it. A reader mounts the same sources, runs the same script, and gets
|
|
57
|
+
* the same bytes.
|
|
58
|
+
*
|
|
59
|
+
* The script and the derived file are relative links, thus the whole chain walks with no network and no
|
|
60
|
+
* host. Each hash head stays beside its link, because the head is what a reader compares against the name of
|
|
61
|
+
* a staged file.
|
|
62
|
+
*/
|
|
63
|
+
function ChainLine({ chain }) {
|
|
64
|
+
return (_jsxs("div", { class: "report-ref-chain", children: [_jsx(RefKind, { children: "Derived from" }), " ", chain.sources.map((source, index) => (_jsxs(_Fragment, { children: [index > 0 ? " and " : "", _jsx(PathCode, { children: source.path }), " ", _jsx(HashCode, { children: hashHead(source.hash) })] }))), " ", _jsx(Detail, { children: "by script" }), " ", _jsx(ScriptLink, { chain: chain }), chain.outputSource !== undefined ? (_jsxs(_Fragment, { children: [" ", _jsx(Detail, { children: "into" }), " ", _jsx("a", { class: "report-ref-link", href: chain.outputSource, children: _jsx(PathCode, { children: chain.outputSource }) })] })) : null] }));
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The one path that an artifact reference names, or `undefined` for a kind that names no single file.
|
|
68
|
+
*
|
|
69
|
+
* A derivation reference computes over two inputs, thus it names no output file of its own and no chain
|
|
70
|
+
* belongs to it.
|
|
71
|
+
*/
|
|
72
|
+
function pathOf(reference) {
|
|
73
|
+
return reference.kind === "derivation" ? undefined : reference.path;
|
|
74
|
+
}
|
|
21
75
|
/**
|
|
22
76
|
* Describe a locator as plain text: the column and the one row selector. The refine of the schema admits
|
|
23
77
|
* exactly one of `row` or `rowFilter`, thus the two branches cover a valid locator.
|
|
@@ -33,11 +87,11 @@ function describeLocator(locator) {
|
|
|
33
87
|
return `column ${locator.column}`;
|
|
34
88
|
}
|
|
35
89
|
/**
|
|
36
|
-
* The inner markup of one
|
|
37
|
-
* reference pins one cell. A
|
|
38
|
-
*
|
|
90
|
+
* The inner markup of one artifact entry. An artifact entry names its path, and it adds the locator when
|
|
91
|
+
* the reference pins one cell. A derivation entry names its operation and its two inputs, each by path and
|
|
92
|
+
* locator.
|
|
39
93
|
*/
|
|
40
|
-
function
|
|
94
|
+
function ReferenceBody({ reference }) {
|
|
41
95
|
switch (reference.kind) {
|
|
42
96
|
case "artifact-value":
|
|
43
97
|
return (_jsxs(_Fragment, { children: [_jsx(RefKind, { children: "Artifact value" }), " ", _jsx(PathCode, { children: reference.path }), " ", _jsx(Detail, { children: describeLocator(reference.locator) })] }));
|
|
@@ -45,20 +99,54 @@ function ReferenceEntry({ reference }) {
|
|
|
45
99
|
return (_jsxs(_Fragment, { children: [_jsx(RefKind, { children: "Artifact table" }), " ", _jsx(PathCode, { children: reference.path })] }));
|
|
46
100
|
case "artifact-file":
|
|
47
101
|
return (_jsxs(_Fragment, { children: [_jsx(RefKind, { children: "Artifact file" }), " ", _jsx(PathCode, { children: reference.path })] }));
|
|
48
|
-
case "citation":
|
|
49
|
-
return (_jsxs(_Fragment, { children: [_jsx(RefKind, { children: "Citation" }), " ", _jsx(Detail, { children: `${reference.idKind}:${reference.id}` })] }));
|
|
50
102
|
case "derivation":
|
|
51
103
|
return (_jsxs(_Fragment, { children: [_jsx(RefKind, { children: `Derivation (${reference.op})` }), " ", reference.inputs.map((input, index) => (_jsxs(_Fragment, { children: [index > 0 ? " and " : "", _jsx(PathCode, { children: input.path }), " ", _jsx(Detail, { children: describeLocator(input.locator) })] })))] }));
|
|
52
104
|
}
|
|
53
105
|
}
|
|
54
106
|
/**
|
|
55
|
-
*
|
|
56
|
-
*
|
|
107
|
+
* One artifact entry: the body of its kind, and the chain of its path where the records hold one.
|
|
108
|
+
*
|
|
109
|
+
* A path that no record names renders the body alone, thus a page over pinned artifacts alone reads exactly
|
|
110
|
+
* as it did before the chains existed.
|
|
111
|
+
*/
|
|
112
|
+
function ArtifactEntry({ reference, chains }) {
|
|
113
|
+
const path = pathOf(reference);
|
|
114
|
+
const chain = path === undefined ? undefined : chains?.get(path);
|
|
115
|
+
return (_jsxs(_Fragment, { children: [_jsx(ReferenceBody, { reference: reference }), chain !== undefined ? _jsx(ChainLine, { chain: chain }) : null] }));
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The inner markup of one literature entry: the kind tag, the short citation of the pinned record, the key,
|
|
119
|
+
* and the description of the record on a line of its own. A key that the record map does not hold shows the
|
|
120
|
+
* key alone, because absence is a normal condition.
|
|
121
|
+
*
|
|
122
|
+
* The description sits in the appendix and never on the card. The card sits in the body of the report,
|
|
123
|
+
* where a paragraph about the paper competes with the prose around it.
|
|
124
|
+
*/
|
|
125
|
+
function CitationEntry({ reference, records }) {
|
|
126
|
+
const key = citationKeyOf(reference);
|
|
127
|
+
const record = citationRecordOf(records, key);
|
|
128
|
+
const description = record?.description;
|
|
129
|
+
return (_jsxs(_Fragment, { children: [_jsx(RefKind, { children: "Citation" }), " ", record !== undefined ? (_jsxs(_Fragment, { children: [_jsx("span", { class: "report-cite-source", children: record.citation }), " "] })) : null, _jsx(Detail, { children: key }), description !== undefined ? _jsx("div", { class: "report-cite-description", children: description }) : null] }));
|
|
130
|
+
}
|
|
131
|
+
/** One appendix entry. The kind of the reference selects the shape, and the two shapes share the ladder. */
|
|
132
|
+
function ReferenceEntry({ reference, records, chains }) {
|
|
133
|
+
return reference.kind === "citation" ? _jsx(CitationEntry, { reference: reference, records: records }) : _jsx(ArtifactEntry, { reference: reference, chains: chains });
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The one appendix list: one entry for each distinct reference of the page, in the order of the ladder.
|
|
137
|
+
*
|
|
138
|
+
* The list is an appendix: a reader consults one entry from a marker, thus the design keeps it quieter than
|
|
139
|
+
* the body. The ordered list numbers its own items, thus the shown number of an entry matches the marker
|
|
140
|
+
* that sent the reader to it. An empty ledger gives an empty string, thus the page shows no empty list.
|
|
141
|
+
*
|
|
142
|
+
* The records carry the bibliography of each cited key, and a ledger with no citation reads none of them.
|
|
143
|
+
* The chains are the derivations of the session, keyed by the output path. An entry whose path the chains
|
|
144
|
+
* hold carries the chain line, and each other entry carries none.
|
|
57
145
|
*/
|
|
58
|
-
export function
|
|
146
|
+
export function renderReferences(ledger, records, chains) {
|
|
59
147
|
const entries = ledger.entries();
|
|
60
148
|
if (entries.length === 0) {
|
|
61
149
|
return "";
|
|
62
150
|
}
|
|
63
|
-
return String(_jsx("ol", { class: "report-references", children: entries.map((reference, index) => (_jsx("li", { id: `ref-${index + 1}`, class: "report-ref-item", children: _jsx(ReferenceEntry, { reference: reference }) }))) }));
|
|
151
|
+
return String(_jsx("ol", { class: "report-references", children: entries.map((reference, index) => (_jsx("li", { id: `ref-${index + 1}`, class: "report-ref-item", children: _jsx(ReferenceEntry, { reference: reference, records: records, chains: chains }) }))) }));
|
|
64
152
|
}
|