@coldtea/pr-lens-renderer 0.1.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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/bounds.d.ts +23 -0
- package/dist/bounds.d.ts.map +1 -0
- package/dist/bounds.js +39 -0
- package/dist/bounds.js.map +1 -0
- package/dist/corrections.d.ts +12 -0
- package/dist/corrections.d.ts.map +1 -0
- package/dist/corrections.js +122 -0
- package/dist/corrections.js.map +1 -0
- package/dist/design.d.ts +112 -0
- package/dist/design.d.ts.map +1 -0
- package/dist/design.js +112 -0
- package/dist/design.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +9 -0
- package/dist/errors.js.map +1 -0
- package/dist/geometry.d.ts +20 -0
- package/dist/geometry.d.ts.map +1 -0
- package/dist/geometry.js +15 -0
- package/dist/geometry.js.map +1 -0
- package/dist/glob.d.ts +7 -0
- package/dist/glob.d.ts.map +1 -0
- package/dist/glob.js +17 -0
- package/dist/glob.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/architecture.d.ts +78 -0
- package/dist/layout/architecture.d.ts.map +1 -0
- package/dist/layout/architecture.js +207 -0
- package/dist/layout/architecture.js.map +1 -0
- package/dist/layout/congestion.d.ts +18 -0
- package/dist/layout/congestion.d.ts.map +1 -0
- package/dist/layout/congestion.js +50 -0
- package/dist/layout/congestion.js.map +1 -0
- package/dist/layout/dataflow.d.ts +85 -0
- package/dist/layout/dataflow.d.ts.map +1 -0
- package/dist/layout/dataflow.js +184 -0
- package/dist/layout/dataflow.js.map +1 -0
- package/dist/layout/edges.d.ts +48 -0
- package/dist/layout/edges.d.ts.map +1 -0
- package/dist/layout/edges.js +843 -0
- package/dist/layout/edges.js.map +1 -0
- package/dist/layout/labels.d.ts +9 -0
- package/dist/layout/labels.d.ts.map +1 -0
- package/dist/layout/labels.js +149 -0
- package/dist/layout/labels.js.map +1 -0
- package/dist/layout/rank.d.ts +16 -0
- package/dist/layout/rank.d.ts.map +1 -0
- package/dist/layout/rank.js +80 -0
- package/dist/layout/rank.js.map +1 -0
- package/dist/layout/seating.d.ts +29 -0
- package/dist/layout/seating.d.ts.map +1 -0
- package/dist/layout/seating.js +131 -0
- package/dist/layout/seating.js.map +1 -0
- package/dist/manifest.d.ts +39 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +99 -0
- package/dist/manifest.js.map +1 -0
- package/dist/render.d.ts +49 -0
- package/dist/render.d.ts.map +1 -0
- package/dist/render.js +125 -0
- package/dist/render.js.map +1 -0
- package/dist/scope.d.ts +21 -0
- package/dist/scope.d.ts.map +1 -0
- package/dist/scope.js +57 -0
- package/dist/scope.js.map +1 -0
- package/dist/svg/architecture.d.ts +15 -0
- package/dist/svg/architecture.d.ts.map +1 -0
- package/dist/svg/architecture.js +197 -0
- package/dist/svg/architecture.js.map +1 -0
- package/dist/svg/dataflow.d.ts +9 -0
- package/dist/svg/dataflow.d.ts.map +1 -0
- package/dist/svg/dataflow.js +284 -0
- package/dist/svg/dataflow.js.map +1 -0
- package/dist/svg/document.d.ts +37 -0
- package/dist/svg/document.d.ts.map +1 -0
- package/dist/svg/document.js +148 -0
- package/dist/svg/document.js.map +1 -0
- package/dist/svg/icons.d.ts +3 -0
- package/dist/svg/icons.d.ts.map +1 -0
- package/dist/svg/icons.js +106 -0
- package/dist/svg/icons.js.map +1 -0
- package/dist/svg/primitives.d.ts +13 -0
- package/dist/svg/primitives.d.ts.map +1 -0
- package/dist/svg/primitives.js +34 -0
- package/dist/svg/primitives.js.map +1 -0
- package/dist/svg/pulse.d.ts +24 -0
- package/dist/svg/pulse.d.ts.map +1 -0
- package/dist/svg/pulse.js +33 -0
- package/dist/svg/pulse.js.map +1 -0
- package/dist/text.d.ts +18 -0
- package/dist/text.d.ts.map +1 -0
- package/dist/text.js +70 -0
- package/dist/text.js.map +1 -0
- package/dist/theme.d.ts +44 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +72 -0
- package/dist/theme.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +9 -0
- package/dist/version.js.map +1 -0
- package/package.json +56 -0
- package/src/bounds.ts +50 -0
- package/src/corrections.ts +166 -0
- package/src/design.ts +124 -0
- package/src/errors.ts +21 -0
- package/src/geometry.ts +22 -0
- package/src/glob.ts +20 -0
- package/src/index.ts +30 -0
- package/src/layout/architecture.ts +324 -0
- package/src/layout/congestion.ts +76 -0
- package/src/layout/dataflow.ts +307 -0
- package/src/layout/edges.ts +1061 -0
- package/src/layout/labels.ts +192 -0
- package/src/layout/rank.ts +95 -0
- package/src/layout/seating.ts +189 -0
- package/src/manifest.ts +118 -0
- package/src/render.ts +190 -0
- package/src/scope.ts +67 -0
- package/src/svg/architecture.ts +293 -0
- package/src/svg/dataflow.ts +408 -0
- package/src/svg/document.ts +198 -0
- package/src/svg/icons.ts +121 -0
- package/src/svg/primitives.ts +50 -0
- package/src/svg/pulse.ts +48 -0
- package/src/text.ts +92 -0
- package/src/theme.ts +107 -0
- package/src/version.ts +9 -0
package/dist/manifest.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { SCHEMA_VERSION } from "@coldtea/pr-lens-schema";
|
|
3
|
+
import { RENDERER_NAME, RENDERER_VERSION } from "./version.js";
|
|
4
|
+
/**
|
|
5
|
+
* How many hex characters of the digest an address carries. Long enough that
|
|
6
|
+
* two different renders will not collide inside one repository's history,
|
|
7
|
+
* short enough to read in a URL.
|
|
8
|
+
*/
|
|
9
|
+
export const CONTENT_HASH_LENGTH = 32;
|
|
10
|
+
/**
|
|
11
|
+
* The one place render bytes become an address.
|
|
12
|
+
*
|
|
13
|
+
* GitHub proxies comment images and caches them hard, so a changed diagram
|
|
14
|
+
* has to arrive as a different URL rather than as new bytes at the old one.
|
|
15
|
+
* Every surface that builds such a URL — the action writing files, the hosted
|
|
16
|
+
* app uploading them — must hash through here, or the two will disagree about
|
|
17
|
+
* what the same render is called.
|
|
18
|
+
*/
|
|
19
|
+
export const contentHash = (bytes) => createHash("sha256").update(bytes, "utf8").digest("hex").slice(0, CONTENT_HASH_LENGTH);
|
|
20
|
+
/** JSON with object keys in sorted order, so equal documents hash equal. */
|
|
21
|
+
export const canonicalJson = (value) => {
|
|
22
|
+
if (value === null || typeof value !== "object")
|
|
23
|
+
return JSON.stringify(value) ?? "null";
|
|
24
|
+
if (Array.isArray(value))
|
|
25
|
+
return `[${value.map(canonicalJson).join(",")}]`;
|
|
26
|
+
const entries = Object.entries(value)
|
|
27
|
+
.filter(([, nested]) => nested !== undefined)
|
|
28
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0));
|
|
29
|
+
return `{${entries.map(([key, nested]) => `${JSON.stringify(key)}:${canonicalJson(nested)}`).join(",")}}`;
|
|
30
|
+
};
|
|
31
|
+
export const graphContentHash = (doc) => contentHash(canonicalJson(doc));
|
|
32
|
+
/**
|
|
33
|
+
* How the characters a view id may contain but a file name may not are spelled.
|
|
34
|
+
*
|
|
35
|
+
* View ids are authored by an extraction model, and the contract lets one
|
|
36
|
+
* contain `/`, `:` and `.` — so `a/../../elsewhere` is a perfectly valid id.
|
|
37
|
+
* Surfaces join an asset's path to an output directory, and that id would walk
|
|
38
|
+
* straight out of it. The mapping is one-to-one rather than a scrub, so two
|
|
39
|
+
* different views can never be handed the same address: `_` names itself
|
|
40
|
+
* first, which is what keeps the other three from colliding with text that
|
|
41
|
+
* was already there.
|
|
42
|
+
*/
|
|
43
|
+
const FILE_NAME_ESCAPES = [
|
|
44
|
+
["_", "_u"],
|
|
45
|
+
["/", "_s"],
|
|
46
|
+
[":", "_c"],
|
|
47
|
+
[".", "_d"],
|
|
48
|
+
];
|
|
49
|
+
const escapeForFileName = (id) => FILE_NAME_ESCAPES.reduce((text, [character, escape]) => text.split(character).join(escape), id);
|
|
50
|
+
/** The contract's ceiling on an `Id`, which an asset id has to stay under. */
|
|
51
|
+
const ASSET_ID_MAX = 128;
|
|
52
|
+
const THEME_SUFFIX_MAX = "-light".length;
|
|
53
|
+
const STEM_MAX = ASSET_ID_MAX - THEME_SUFFIX_MAX;
|
|
54
|
+
const DIGEST_LENGTH = 12;
|
|
55
|
+
/**
|
|
56
|
+
* `_h` cannot occur in an escaped id — every `_` there opens one of the four
|
|
57
|
+
* escapes above — so it can mark the digest without ever being mistaken for
|
|
58
|
+
* text that was already in the id.
|
|
59
|
+
*/
|
|
60
|
+
const DIGEST_MARKER = "_h";
|
|
61
|
+
const PREFIX_MAX = STEM_MAX - DIGEST_MARKER.length - DIGEST_LENGTH;
|
|
62
|
+
/**
|
|
63
|
+
* A view id spelled so that it is both a legal file name and a legal `Id`.
|
|
64
|
+
*
|
|
65
|
+
* Escaping can double the length of an id that is already near the contract's
|
|
66
|
+
* limit, so a stem that would overflow keeps a readable prefix and ends in a
|
|
67
|
+
* digest of the whole original. The digest is what preserves the one property
|
|
68
|
+
* that matters: two different views can never be handed the same address.
|
|
69
|
+
*/
|
|
70
|
+
const fileNameSafe = (id) => {
|
|
71
|
+
const escaped = escapeForFileName(id);
|
|
72
|
+
if (escaped.length <= STEM_MAX)
|
|
73
|
+
return escaped;
|
|
74
|
+
const prefix = escaped.slice(0, PREFIX_MAX).replace(/_$/, "");
|
|
75
|
+
return `${prefix}${DIGEST_MARKER}${contentHash(id).slice(0, DIGEST_LENGTH)}`;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* The identity of one rendered SVG within a render: the drill-down section it
|
|
79
|
+
* belongs to and the half of the theme pair it is. A render with no sections
|
|
80
|
+
* falls back to the lens, which is unique across the same render.
|
|
81
|
+
*
|
|
82
|
+
* This doubles as the stem of the file name, so it is spelled in the alphabet
|
|
83
|
+
* a file name can carry.
|
|
84
|
+
*/
|
|
85
|
+
export const renderAssetId = ({ lens, theme, view }) => `${fileNameSafe(view ?? lens)}-${theme}`;
|
|
86
|
+
/** The file name an asset is written or published under. */
|
|
87
|
+
export const renderAssetFileName = (address, hash) => `${renderAssetId(address)}-${hash}.svg`;
|
|
88
|
+
export const buildManifest = (doc, assets) => ({
|
|
89
|
+
schemaVersion: SCHEMA_VERSION,
|
|
90
|
+
kind: "render-manifest",
|
|
91
|
+
graph: {
|
|
92
|
+
id: doc.id,
|
|
93
|
+
headSha: doc.provenance.head.sha,
|
|
94
|
+
contentHash: graphContentHash(doc),
|
|
95
|
+
},
|
|
96
|
+
renderer: { name: RENDERER_NAME, version: RENDERER_VERSION },
|
|
97
|
+
assets: [...assets],
|
|
98
|
+
});
|
|
99
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Config, GraphDoc, Lens, RenderAsset, RenderManifest } from "@coldtea/pr-lens-schema";
|
|
2
|
+
import { type Theme } from "./theme.js";
|
|
3
|
+
export type RenderOptions = {
|
|
4
|
+
lens: Lens;
|
|
5
|
+
theme: Theme;
|
|
6
|
+
/** Id of the drill-down section to draw. Omitted renders the whole document. */
|
|
7
|
+
view?: string;
|
|
8
|
+
/** The repository's corrections, applied as an overlay before layout. */
|
|
9
|
+
config?: Config;
|
|
10
|
+
};
|
|
11
|
+
export type RenderedSvg = {
|
|
12
|
+
svg: string;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
lens: Lens;
|
|
16
|
+
theme: Theme;
|
|
17
|
+
view: string | undefined;
|
|
18
|
+
animated: boolean;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A schema-valid document in, one self-contained SVG out.
|
|
22
|
+
*
|
|
23
|
+
* Nothing here reads a clock, a file or a random number: the same document
|
|
24
|
+
* and options produce the same bytes, on any machine, in any order. That is
|
|
25
|
+
* what lets a render be addressed by its own hash, and what keeps a diagram
|
|
26
|
+
* from rearranging itself between two pushes that barely changed anything.
|
|
27
|
+
*/
|
|
28
|
+
export declare const render: (doc: GraphDoc, options: RenderOptions) => RenderedSvg;
|
|
29
|
+
export type RenderAllOptions = {
|
|
30
|
+
config?: Config;
|
|
31
|
+
/** Which halves of the theme pair to produce. Both, by default. */
|
|
32
|
+
themes?: readonly Theme[];
|
|
33
|
+
};
|
|
34
|
+
export type RenderedAsset = RenderedSvg & {
|
|
35
|
+
asset: RenderAsset;
|
|
36
|
+
};
|
|
37
|
+
export type RenderAllResult = {
|
|
38
|
+
assets: RenderedAsset[];
|
|
39
|
+
manifest: RenderManifest;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Every drill-down section a comment will show, in both themes.
|
|
43
|
+
*
|
|
44
|
+
* A document with no sections still renders: it gets one diagram per lens it
|
|
45
|
+
* declares, which is what a comment falls back to when extraction found
|
|
46
|
+
* nothing worth splitting into a tree.
|
|
47
|
+
*/
|
|
48
|
+
export declare const renderAll: (doc: GraphDoc, options?: RenderAllOptions) => RenderAllResult;
|
|
49
|
+
//# sourceMappingURL=render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAmB,MAAM,yBAAyB,CAAC;AAMpH,OAAO,EAAsB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAK5D,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;IACb,gFAAgF;IAChF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAoCF;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,QAAS,QAAQ,WAAW,aAAa,KAAG,WA0B9D,CAAC;AASF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,MAAM,CAAC,EAAE,SAAS,KAAK,EAAE,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG;IAAE,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAEjE,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,QAAS,QAAQ,YAAW,gBAAgB,KAAQ,eA8DzE,CAAC"}
|
package/dist/render.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { assertNever, MAX_RENDER_ASSETS } from "@coldtea/pr-lens-schema";
|
|
2
|
+
import { applyCorrections } from "./corrections.js";
|
|
3
|
+
import { PrLensRenderError } from "./errors.js";
|
|
4
|
+
import { buildManifest, contentHash, renderAssetFileName, renderAssetId } from "./manifest.js";
|
|
5
|
+
import { findView, flattenViews, resolveScope } from "./scope.js";
|
|
6
|
+
import { paletteFor, THEMES } from "./theme.js";
|
|
7
|
+
import { paintArchitecture } from "./svg/architecture.js";
|
|
8
|
+
import { paintDataFlow } from "./svg/dataflow.js";
|
|
9
|
+
import { svgDocument } from "./svg/document.js";
|
|
10
|
+
const WHOLE_DOCUMENT = { kind: "all" };
|
|
11
|
+
const prepare = (doc, config) => config === undefined ? doc : applyCorrections(doc, config.map);
|
|
12
|
+
const paint = (lens, graph, doc, theme) => {
|
|
13
|
+
const palette = paletteFor(theme);
|
|
14
|
+
switch (lens) {
|
|
15
|
+
case "architecture": {
|
|
16
|
+
if (graph.nodes.length === 0)
|
|
17
|
+
throw new PrLensRenderError("NOTHING_TO_RENDER", "no nodes are in scope for this view");
|
|
18
|
+
const painting = paintArchitecture(graph, doc.layout, palette);
|
|
19
|
+
return { ...painting, animated: graph.edges.some((edge) => edge.animated) };
|
|
20
|
+
}
|
|
21
|
+
case "data-flow": {
|
|
22
|
+
if (graph.flows.length === 0)
|
|
23
|
+
throw new PrLensRenderError("NO_FLOW_IN_SCOPE", "the data-flow lens needs a flow to draw");
|
|
24
|
+
const painting = paintDataFlow(graph.flows, doc.nodes, palette);
|
|
25
|
+
return {
|
|
26
|
+
...painting,
|
|
27
|
+
animated: graph.flows.some((flow) => flow.messages.some((message) => message.animated)),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
default:
|
|
31
|
+
return assertNever(lens, "Unhandled lens");
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* A schema-valid document in, one self-contained SVG out.
|
|
36
|
+
*
|
|
37
|
+
* Nothing here reads a clock, a file or a random number: the same document
|
|
38
|
+
* and options produce the same bytes, on any machine, in any order. That is
|
|
39
|
+
* what lets a render be addressed by its own hash, and what keeps a diagram
|
|
40
|
+
* from rearranging itself between two pushes that barely changed anything.
|
|
41
|
+
*/
|
|
42
|
+
export const render = (doc, options) => {
|
|
43
|
+
const prepared = prepare(doc, options.config);
|
|
44
|
+
if (!prepared.lenses.includes(options.lens))
|
|
45
|
+
throw new PrLensRenderError("LENS_NOT_DECLARED", `this document does not declare the '${options.lens}' lens`);
|
|
46
|
+
const view = options.view === undefined ? undefined : requireView(prepared.views, options.view);
|
|
47
|
+
const scope = view?.scope ?? WHOLE_DOCUMENT;
|
|
48
|
+
const graph = resolveScope(prepared, scope);
|
|
49
|
+
const { width, height, body, animated } = paint(options.lens, graph, prepared, options.theme);
|
|
50
|
+
const svg = svgDocument({
|
|
51
|
+
width,
|
|
52
|
+
height,
|
|
53
|
+
palette: paletteFor(options.theme),
|
|
54
|
+
title: view?.title ?? prepared.title,
|
|
55
|
+
description: view?.summary ?? prepared.summary,
|
|
56
|
+
body,
|
|
57
|
+
});
|
|
58
|
+
return { svg, width, height, lens: options.lens, theme: options.theme, view: view?.id, animated };
|
|
59
|
+
};
|
|
60
|
+
const requireView = (views, id) => {
|
|
61
|
+
const view = findView(views, id);
|
|
62
|
+
if (view === undefined)
|
|
63
|
+
throw new PrLensRenderError("UNKNOWN_VIEW", `this document has no view '${id}'`);
|
|
64
|
+
return view;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Every drill-down section a comment will show, in both themes.
|
|
68
|
+
*
|
|
69
|
+
* A document with no sections still renders: it gets one diagram per lens it
|
|
70
|
+
* declares, which is what a comment falls back to when extraction found
|
|
71
|
+
* nothing worth splitting into a tree.
|
|
72
|
+
*/
|
|
73
|
+
export const renderAll = (doc, options = {}) => {
|
|
74
|
+
const prepared = prepare(doc, options.config);
|
|
75
|
+
const themes = options.themes ?? THEMES;
|
|
76
|
+
const targets = prepared.views.length > 0
|
|
77
|
+
? flattenViews(prepared.views)
|
|
78
|
+
.filter((view) => prepared.lenses.includes(view.lens))
|
|
79
|
+
.map((view) => ({ lens: view.lens, view }))
|
|
80
|
+
: prepared.lenses
|
|
81
|
+
.filter((lens) => lens !== "data-flow" || prepared.flows.length > 0)
|
|
82
|
+
.map((lens) => ({ lens, view: undefined }));
|
|
83
|
+
/**
|
|
84
|
+
* The contract caps a view tree at the number of views a two-theme render
|
|
85
|
+
* fits inside a manifest, so a parsed document cannot reach this. A
|
|
86
|
+
* hand-built one can: the cap lives in a refinement, and a refinement does
|
|
87
|
+
* not survive into the inferred type. This is a postcondition on what is
|
|
88
|
+
* about to be produced rather than a re-reading of what came in — the count
|
|
89
|
+
* depends on how many themes the caller asked for, which no document knows.
|
|
90
|
+
*/
|
|
91
|
+
if (targets.length * themes.length > MAX_RENDER_ASSETS)
|
|
92
|
+
throw new PrLensRenderError("TOO_MANY_ASSETS", `this document asks for ${targets.length * themes.length} pictures across ${targets.length} views ` +
|
|
93
|
+
`and ${themes.length} themes, and a render manifest carries at most ${MAX_RENDER_ASSETS}`);
|
|
94
|
+
const assets = [];
|
|
95
|
+
for (const target of targets)
|
|
96
|
+
for (const theme of themes) {
|
|
97
|
+
const rendered = render(prepared, {
|
|
98
|
+
lens: target.lens,
|
|
99
|
+
theme,
|
|
100
|
+
view: target.view?.id,
|
|
101
|
+
});
|
|
102
|
+
const address = { lens: target.lens, theme, view: target.view?.id };
|
|
103
|
+
const hash = contentHash(rendered.svg);
|
|
104
|
+
assets.push({
|
|
105
|
+
...rendered,
|
|
106
|
+
asset: {
|
|
107
|
+
id: renderAssetId(address),
|
|
108
|
+
lens: target.lens,
|
|
109
|
+
theme,
|
|
110
|
+
view: target.view?.id,
|
|
111
|
+
mediaType: "image/svg+xml",
|
|
112
|
+
contentHash: hash,
|
|
113
|
+
bytes: Buffer.byteLength(rendered.svg, "utf8"),
|
|
114
|
+
width: rendered.width,
|
|
115
|
+
height: rendered.height,
|
|
116
|
+
animated: rendered.animated,
|
|
117
|
+
path: renderAssetFileName(address, hash),
|
|
118
|
+
},
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (assets.length === 0)
|
|
122
|
+
throw new PrLensRenderError("NOTHING_TO_RENDER", "this document declares no renderable view");
|
|
123
|
+
return { assets, manifest: buildManifest(prepared, assets.map(({ asset }) => asset)) };
|
|
124
|
+
};
|
|
125
|
+
//# sourceMappingURL=render.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"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"}
|
package/dist/scope.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Flow, GraphDoc, GraphEdge, GraphNode, Lane, View, ViewScope } from "@coldtea/pr-lens-schema";
|
|
2
|
+
/** The slice of a document one SVG draws. */
|
|
3
|
+
export type ScopedGraph = {
|
|
4
|
+
lanes: Lane[];
|
|
5
|
+
nodes: GraphNode[];
|
|
6
|
+
edges: GraphEdge[];
|
|
7
|
+
flows: Flow[];
|
|
8
|
+
};
|
|
9
|
+
export declare const findView: (views: readonly View[], id: string) => View | undefined;
|
|
10
|
+
export declare const flattenViews: (views: readonly View[]) => View[];
|
|
11
|
+
/**
|
|
12
|
+
* Turns a view's scope into the elements to draw.
|
|
13
|
+
*
|
|
14
|
+
* A selection pulls in what its members need to make sense: the lanes its
|
|
15
|
+
* nodes sit in, and both ends of every edge it names, since half an arrow is
|
|
16
|
+
* worse than none. Edges are the one place the author keeps full control —
|
|
17
|
+
* name any and exactly those are drawn, name none and the connections between
|
|
18
|
+
* the selected nodes come along.
|
|
19
|
+
*/
|
|
20
|
+
export declare const resolveScope: (doc: GraphDoc, scope: ViewScope) => ScopedGraph;
|
|
21
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAG3G,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,QAAQ,UAAW,SAAS,IAAI,EAAE,MAAM,MAAM,KAAG,IAAI,GAAG,SAOpE,CAAC;AAEF,eAAO,MAAM,YAAY,UAAW,SAAS,IAAI,EAAE,KAAG,IAAI,EACO,CAAC;AAElE;;;;;;;;GAQG;AACH,eAAO,MAAM,YAAY,QAAS,QAAQ,SAAS,SAAS,KAAG,WAkC9D,CAAC"}
|
package/dist/scope.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { assertNever } from "@coldtea/pr-lens-schema";
|
|
2
|
+
export const findView = (views, id) => {
|
|
3
|
+
for (const view of views) {
|
|
4
|
+
if (view.id === id)
|
|
5
|
+
return view;
|
|
6
|
+
const nested = findView(view.children, id);
|
|
7
|
+
if (nested)
|
|
8
|
+
return nested;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
};
|
|
12
|
+
export const flattenViews = (views) => views.flatMap((view) => [view, ...flattenViews(view.children)]);
|
|
13
|
+
/**
|
|
14
|
+
* Turns a view's scope into the elements to draw.
|
|
15
|
+
*
|
|
16
|
+
* A selection pulls in what its members need to make sense: the lanes its
|
|
17
|
+
* nodes sit in, and both ends of every edge it names, since half an arrow is
|
|
18
|
+
* worse than none. Edges are the one place the author keeps full control —
|
|
19
|
+
* name any and exactly those are drawn, name none and the connections between
|
|
20
|
+
* the selected nodes come along.
|
|
21
|
+
*/
|
|
22
|
+
export const resolveScope = (doc, scope) => {
|
|
23
|
+
switch (scope.kind) {
|
|
24
|
+
case "all":
|
|
25
|
+
return { lanes: [...doc.lanes], nodes: [...doc.nodes], edges: [...doc.edges], flows: [...doc.flows] };
|
|
26
|
+
case "selection": {
|
|
27
|
+
const selectedLanes = new Set(scope.lanes);
|
|
28
|
+
const selectedEdges = new Set(scope.edges);
|
|
29
|
+
const selectedFlows = new Set(scope.flows);
|
|
30
|
+
const flows = doc.flows.filter((flow) => selectedFlows.has(flow.id));
|
|
31
|
+
const nodeIds = new Set(scope.nodes);
|
|
32
|
+
for (const node of doc.nodes)
|
|
33
|
+
if (selectedLanes.has(node.lane))
|
|
34
|
+
nodeIds.add(node.id);
|
|
35
|
+
for (const edge of doc.edges) {
|
|
36
|
+
if (!selectedEdges.has(edge.id))
|
|
37
|
+
continue;
|
|
38
|
+
nodeIds.add(edge.from);
|
|
39
|
+
nodeIds.add(edge.to);
|
|
40
|
+
}
|
|
41
|
+
for (const flow of flows)
|
|
42
|
+
for (const participant of flow.participants)
|
|
43
|
+
nodeIds.add(participant.node);
|
|
44
|
+
const nodes = doc.nodes.filter((node) => nodeIds.has(node.id));
|
|
45
|
+
const edges = scope.edges.length > 0
|
|
46
|
+
? doc.edges.filter((edge) => selectedEdges.has(edge.id))
|
|
47
|
+
: doc.edges.filter((edge) => nodeIds.has(edge.from) && nodeIds.has(edge.to));
|
|
48
|
+
const laneIds = new Set(scope.lanes);
|
|
49
|
+
for (const node of nodes)
|
|
50
|
+
laneIds.add(node.lane);
|
|
51
|
+
return { lanes: doc.lanes.filter((lane) => laneIds.has(lane.id)), nodes, edges, flows };
|
|
52
|
+
}
|
|
53
|
+
default:
|
|
54
|
+
return assertNever(scope, "Unhandled view scope");
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LayoutHints } from "@coldtea/pr-lens-schema";
|
|
2
|
+
import { type Box } from "../geometry.js";
|
|
3
|
+
import { type PlacedNode } from "../layout/architecture.js";
|
|
4
|
+
import type { ScopedGraph } from "../scope.js";
|
|
5
|
+
import type { Palette } from "../theme.js";
|
|
6
|
+
import { type Tone } from "./document.js";
|
|
7
|
+
export declare const paintCard: (placed: PlacedNode) => string;
|
|
8
|
+
export declare const paintLabelPill: (text: string, box: Box, tone: Tone) => string;
|
|
9
|
+
export type ArchitecturePainting = {
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
body: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const paintArchitecture: (graph: ScopedGraph, hints: LayoutHints | undefined, palette: Palette) => ArchitecturePainting;
|
|
15
|
+
//# sourceMappingURL=architecture.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architecture.d.ts","sourceRoot":"","sources":["../../src/svg/architecture.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAwB,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAoBjF,OAAO,EAAS,KAAK,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAA2C,KAAK,IAAI,EAAE,MAAM,eAAe,CAAC;AAwDnF,eAAO,MAAM,SAAS,WAAY,UAAU,KAAG,MA8D9C,CAAC;AAqDF,eAAO,MAAM,cAAc,SAAU,MAAM,OAAO,GAAG,QAAQ,IAAI,KAAG,MAqBjE,CAAC;AAEJ,MAAM,MAAM,oBAAoB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnF,eAAO,MAAM,iBAAiB,UACrB,WAAW,SACX,WAAW,GAAG,SAAS,WACrB,OAAO,KACf,oBAyDF,CAAC"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { assertNever } from "@coldtea/pr-lens-schema";
|
|
2
|
+
import { BADGE_GAP, BADGE_HEIGHT, BADGE_RADIUS, BADGE_RISE, CARD_PADDING_X, CARD_RADIUS, HERO_PULSE_COUNT, ICON_CHIP_GAP, ICON_CHIP_RADIUS, ICON_CHIP_SIZE, LANE_HEADER_BASELINE, LANE_PADDING_X, LANE_RADIUS, SUBTITLE_SIZE, } from "../design.js";
|
|
3
|
+
import { canvasFor, union } from "../bounds.js";
|
|
4
|
+
import { DIAGRAM_MARGIN } from "../design.js";
|
|
5
|
+
import { coord } from "../geometry.js";
|
|
6
|
+
import { badgeRow, badgeWidth, cardBadges, deltaBadgeText, laneHeaderText, } from "../layout/architecture.js";
|
|
7
|
+
import { relieveCongestion } from "../layout/congestion.js";
|
|
8
|
+
import { curveBounds } from "../layout/edges.js";
|
|
9
|
+
import { placeLabelPills } from "../layout/labels.js";
|
|
10
|
+
import { truncate } from "../text.js";
|
|
11
|
+
import { markerFor, shifted, toneColour, toneFor } from "./document.js";
|
|
12
|
+
import { glyphGroup } from "./icons.js";
|
|
13
|
+
import { lines, tag, textNode, wrap } from "./primitives.js";
|
|
14
|
+
import { travellingPulses } from "./pulse.js";
|
|
15
|
+
const badgeTone = (node, text) => text === deltaBadgeText(node.delta) ? toneFor(node.delta) : "neutral";
|
|
16
|
+
/** The badge row, laid left to right across the strip the layout reserved. */
|
|
17
|
+
const paintBadges = (placed) => {
|
|
18
|
+
const row = badgeRow(placed);
|
|
19
|
+
if (row === undefined)
|
|
20
|
+
return "";
|
|
21
|
+
let x = row.box.x;
|
|
22
|
+
return lines(row.badges.map((text) => {
|
|
23
|
+
const width = badgeWidth(text);
|
|
24
|
+
const painted = wrap("g", { class: `bdg bdg-${badgeTone(placed.node, text)}` }, tag("rect", {
|
|
25
|
+
x: coord(x),
|
|
26
|
+
y: coord(row.box.y),
|
|
27
|
+
width: coord(width),
|
|
28
|
+
height: BADGE_HEIGHT,
|
|
29
|
+
rx: BADGE_RADIUS,
|
|
30
|
+
}) +
|
|
31
|
+
textNode({
|
|
32
|
+
x: coord(x + width / 2),
|
|
33
|
+
y: coord(row.box.y + BADGE_HEIGHT / 2 + 3),
|
|
34
|
+
"text-anchor": "middle",
|
|
35
|
+
}, text));
|
|
36
|
+
x += width + BADGE_GAP;
|
|
37
|
+
return painted;
|
|
38
|
+
}));
|
|
39
|
+
};
|
|
40
|
+
const cardOutlineClass = (node) => {
|
|
41
|
+
switch (node.delta) {
|
|
42
|
+
case "added":
|
|
43
|
+
return "card card-added";
|
|
44
|
+
case "modified":
|
|
45
|
+
return "card card-modified";
|
|
46
|
+
case "removed":
|
|
47
|
+
case "unchanged":
|
|
48
|
+
return "card";
|
|
49
|
+
default:
|
|
50
|
+
return assertNever(node.delta, "Unhandled delta");
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
export const paintCard = (placed) => {
|
|
54
|
+
const { node, box, showIcon, titleSize } = placed;
|
|
55
|
+
const textX = box.x + CARD_PADDING_X + (showIcon ? ICON_CHIP_SIZE + ICON_CHIP_GAP : 0);
|
|
56
|
+
const textWidth = box.x + box.width - CARD_PADDING_X - textX;
|
|
57
|
+
const hasSubtitle = node.subtitle !== undefined;
|
|
58
|
+
const titleBaseline = box.y + (hasSubtitle ? 27 : 31);
|
|
59
|
+
const chip = showIcon
|
|
60
|
+
? tag("rect", {
|
|
61
|
+
class: "chip",
|
|
62
|
+
x: coord(box.x + CARD_PADDING_X),
|
|
63
|
+
y: coord(box.y + (box.height - ICON_CHIP_SIZE) / 2),
|
|
64
|
+
width: ICON_CHIP_SIZE,
|
|
65
|
+
height: ICON_CHIP_SIZE,
|
|
66
|
+
rx: ICON_CHIP_RADIUS,
|
|
67
|
+
}) +
|
|
68
|
+
glyphGroup(node.kind, box.x + CARD_PADDING_X + ICON_CHIP_SIZE / 2, box.y + box.height / 2)
|
|
69
|
+
: "";
|
|
70
|
+
const title = textNode({
|
|
71
|
+
class: node.delta === "removed" ? "ntitle strike" : "ntitle",
|
|
72
|
+
x: coord(textX),
|
|
73
|
+
y: coord(titleBaseline),
|
|
74
|
+
"font-size": titleSize,
|
|
75
|
+
}, truncate(node.label, "sans-bold", titleSize, textWidth));
|
|
76
|
+
const subtitle = node.subtitle === undefined
|
|
77
|
+
? ""
|
|
78
|
+
: textNode({ class: "nsub", x: coord(textX), y: coord(box.y + 45) }, truncate(node.subtitle, "mono", SUBTITLE_SIZE, textWidth));
|
|
79
|
+
const groupClass = node.delta === "removed" ? "cardsh ghost" : node.delta === "unchanged" ? "cardsh context" : "cardsh";
|
|
80
|
+
return wrap("g", { class: groupClass }, lines([
|
|
81
|
+
tag("rect", {
|
|
82
|
+
class: cardOutlineClass(node),
|
|
83
|
+
x: coord(box.x),
|
|
84
|
+
y: coord(box.y),
|
|
85
|
+
width: coord(box.width),
|
|
86
|
+
height: coord(box.height),
|
|
87
|
+
rx: CARD_RADIUS,
|
|
88
|
+
}),
|
|
89
|
+
chip,
|
|
90
|
+
title,
|
|
91
|
+
subtitle,
|
|
92
|
+
paintBadges(placed),
|
|
93
|
+
]));
|
|
94
|
+
};
|
|
95
|
+
const pulses = (edge, path, palette) => edge.animated
|
|
96
|
+
? travellingPulses({
|
|
97
|
+
path,
|
|
98
|
+
colour: toneColour(palette, toneFor(edge.delta)),
|
|
99
|
+
count: edge.emphasis === "hero" ? HERO_PULSE_COUNT : 1,
|
|
100
|
+
lag: 0,
|
|
101
|
+
})
|
|
102
|
+
: "";
|
|
103
|
+
/**
|
|
104
|
+
* Paints one edge and the pill settled onto it. Every edge carries at most
|
|
105
|
+
* one label, and the layout already chose its place — on the route's longest
|
|
106
|
+
* straight run, nudged clear of every other pill — so a reader traces a line
|
|
107
|
+
* to its own words.
|
|
108
|
+
*
|
|
109
|
+
* The line and the label come back separately because they belong to
|
|
110
|
+
* different layers: a line passes behind a card, and a pill — which is opaque
|
|
111
|
+
* precisely so that it can be read wherever it lands — passes in front of one.
|
|
112
|
+
*/
|
|
113
|
+
const paintEdge = (routed, palette, label) => {
|
|
114
|
+
const { edge, path } = routed;
|
|
115
|
+
const tone = toneFor(edge.delta);
|
|
116
|
+
const hero = edge.emphasis === "hero";
|
|
117
|
+
const classes = ["edge", `edge-${tone}`];
|
|
118
|
+
if (hero)
|
|
119
|
+
classes.push("hero");
|
|
120
|
+
if (edge.emphasis === "muted")
|
|
121
|
+
classes.push("faded");
|
|
122
|
+
if (edge.delta === "unchanged")
|
|
123
|
+
classes.push("context");
|
|
124
|
+
const glow = hero
|
|
125
|
+
? tag("path", { class: "glow", stroke: toneColour(palette, tone), d: path })
|
|
126
|
+
: "";
|
|
127
|
+
return {
|
|
128
|
+
markup: lines([
|
|
129
|
+
glow,
|
|
130
|
+
tag("path", { class: classes.join(" "), d: path, "marker-end": markerFor(tone) }),
|
|
131
|
+
pulses(edge, path, palette),
|
|
132
|
+
]),
|
|
133
|
+
pill: label === undefined || edge.label === undefined
|
|
134
|
+
? ""
|
|
135
|
+
: paintLabelPill(edge.label, label, tone),
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
export const paintLabelPill = (text, box, tone) => wrap("g", {}, tag("rect", {
|
|
139
|
+
class: "lpill",
|
|
140
|
+
x: coord(box.x),
|
|
141
|
+
y: coord(box.y),
|
|
142
|
+
width: coord(box.width),
|
|
143
|
+
height: coord(box.height),
|
|
144
|
+
rx: box.height / 2,
|
|
145
|
+
}) +
|
|
146
|
+
textNode({
|
|
147
|
+
class: tone === "neutral" ? "ltext" : `ltext ltext-${tone}`,
|
|
148
|
+
x: coord(box.x + box.width / 2),
|
|
149
|
+
y: coord(box.y + box.height / 2 + 3.5),
|
|
150
|
+
"text-anchor": "middle",
|
|
151
|
+
}, text));
|
|
152
|
+
export const paintArchitecture = (graph, hints, palette) => {
|
|
153
|
+
const { layout, routed } = relieveCongestion(graph, hints);
|
|
154
|
+
const pills = placeLabelPills(routed);
|
|
155
|
+
const drawn = layout.nodes.flatMap((node) => {
|
|
156
|
+
const row = badgeRow(node);
|
|
157
|
+
return row === undefined ? [node.box] : [node.box, row.box];
|
|
158
|
+
});
|
|
159
|
+
const edgeMarkup = [];
|
|
160
|
+
const pillMarkup = [];
|
|
161
|
+
for (const edge of routed) {
|
|
162
|
+
const label = pills.get(edge.edge.id);
|
|
163
|
+
const { markup, pill } = paintEdge(edge, palette, label);
|
|
164
|
+
edgeMarkup.push(markup);
|
|
165
|
+
pillMarkup.push(pill);
|
|
166
|
+
if (label !== undefined)
|
|
167
|
+
drawn.push(label);
|
|
168
|
+
}
|
|
169
|
+
const lanes = layout.lanes.map(({ lane, box }) => lines([
|
|
170
|
+
tag("rect", {
|
|
171
|
+
class: "lanebox",
|
|
172
|
+
x: coord(box.x),
|
|
173
|
+
y: coord(box.y),
|
|
174
|
+
width: coord(box.width),
|
|
175
|
+
height: coord(box.height),
|
|
176
|
+
rx: LANE_RADIUS,
|
|
177
|
+
}),
|
|
178
|
+
textNode({ class: "lanelabel", x: coord(box.x + LANE_PADDING_X), y: LANE_HEADER_BASELINE }, laneHeaderText(lane)),
|
|
179
|
+
]));
|
|
180
|
+
const canvas = canvasFor(layout, union([
|
|
181
|
+
...layout.lanes.map(({ box }) => box),
|
|
182
|
+
...drawn,
|
|
183
|
+
...routed.map(({ curve }) => curveBounds(curve)),
|
|
184
|
+
]), DIAGRAM_MARGIN);
|
|
185
|
+
const painted = lines([
|
|
186
|
+
wrap("g", {}, lines(lanes)),
|
|
187
|
+
wrap("g", {}, lines(edgeMarkup)),
|
|
188
|
+
wrap("g", {}, lines(layout.nodes.map(paintCard))),
|
|
189
|
+
wrap("g", {}, lines(pillMarkup)),
|
|
190
|
+
]);
|
|
191
|
+
return {
|
|
192
|
+
width: canvas.width,
|
|
193
|
+
height: canvas.height,
|
|
194
|
+
body: shifted(canvas, painted),
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
//# sourceMappingURL=architecture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"architecture.js","sourceRoot":"","sources":["../../src/svg/architecture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Flow, GraphNode } from "@coldtea/pr-lens-schema";
|
|
2
|
+
import type { Palette } from "../theme.js";
|
|
3
|
+
export type DataFlowPainting = {
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
body: string;
|
|
7
|
+
};
|
|
8
|
+
export declare const paintDataFlow: (flows: readonly Flow[], nodes: readonly GraphNode[], palette: Palette) => DataFlowPainting;
|
|
9
|
+
//# sourceMappingURL=dataflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dataflow.d.ts","sourceRoot":"","sources":["../../src/svg/dataflow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAe,SAAS,EAAe,MAAM,yBAAyB,CAAC;AAgCzF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA4V3C,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/E,eAAO,MAAM,aAAa,UACjB,SAAS,IAAI,EAAE,SACf,SAAS,SAAS,EAAE,WAClB,OAAO,KACf,gBAqBF,CAAC"}
|