yarramate 1.24.0 → 1.25.1
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/adapters/visual/layout-sidecar.d.ts +28 -0
- package/dist/adapters/visual/layout-sidecar.js +61 -0
- package/dist/adapters/visual/protocol-contract.d.ts +19 -0
- package/dist/adapters/visual/session-server.js +28 -35
- package/dist/adapters/visual/wire.d.ts +9 -1
- package/dist/notation/archimate.d.ts +6 -1
- package/dist/notation/archimate.js +9 -4
- package/dist/schema-validation.d.ts +1 -0
- package/dist/schema-validation.js +1 -0
- package/dist/schema-validators.generated.d.ts +6 -0
- package/dist/schema-validators.generated.js +592 -1
- package/dist/visual-app/assets/elk-worker.min-D8OVqK8T.js +22 -0
- package/dist/visual-app/assets/elk.bundled-CLux5E_P.js +24 -0
- package/dist/visual-app/assets/index-DGkU2CSB.js +369 -0
- package/dist/visual-app/index.html +1 -1
- package/dist/visual-app-lib/editor.js +31036 -29678
- package/dist/visual-app-lib/types/adapters/visual/layout-sidecar.d.ts +28 -0
- package/dist/visual-app-lib/types/adapters/visual/protocol-contract.d.ts +19 -0
- package/dist/visual-app-lib/types/adapters/visual/wire.d.ts +9 -1
- package/dist/visual-app-lib/types/notation/archimate.d.ts +6 -1
- package/dist/visual-app-lib/types/schema-validation.d.ts +1 -0
- package/dist/visual-app-lib/types/schema-validators.generated.d.ts +6 -0
- package/dist/visual-app-lib/types/visual-app/edge-routes.d.ts +17 -1
- package/dist/visual-app-lib/types/visual-app/elk-layout.d.ts +42 -5
- package/dist/visual-app-lib/types/visual-app/graph-canvas.d.ts +35 -5
- package/dist/visual-app-lib/types/visual-app/kind-icons.d.ts +1 -1
- package/dist/visual-app-lib/types/visual-app/layout-controls.d.ts +12 -6
- package/dist/visual-app-lib/types/visual-app/mount.d.ts +12 -0
- package/dist/visual-app-lib/types/visual-app/save-view.d.ts +15 -6
- package/dist/visual-app-lib/types/visual-app/style-presets.d.ts +39 -0
- package/dist/visual-app-lib/types/visual-app/workspace-state.d.ts +9 -0
- package/docs/CONSUMING-YARRAMATE.md +16 -0
- package/package.json +1 -1
- package/schema/yarramate-visual-event.schema.json +10 -0
- package/schema/yarramate-visual-layout.schema.json +31 -0
- package/dist/visual-app/assets/index-wKXrkA2V.js +0 -392
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { VisualLayoutPositions, VisualLayoutRoutes } from './protocol-contract.js';
|
|
2
|
+
/** Where every host writes a projection's sidecar, and reads it back from. */
|
|
3
|
+
export declare const LAYOUT_SIDECAR_DIR = ".yarramate/visual-layout";
|
|
4
|
+
export declare const layoutSidecarPath: (projectionId: string) => string;
|
|
5
|
+
/** A path a store or directory holds that could be a sidecar. */
|
|
6
|
+
export declare const isLayoutSidecarPath: (path: string) => boolean;
|
|
7
|
+
export interface LayoutSidecars {
|
|
8
|
+
readonly layouts: Record<string, VisualLayoutPositions>;
|
|
9
|
+
readonly folds: Record<string, {
|
|
10
|
+
folded: string[];
|
|
11
|
+
unfolded: string[];
|
|
12
|
+
}>;
|
|
13
|
+
readonly routes: Record<string, VisualLayoutRoutes>;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* What the sidecars say, keyed by the projection id each one names.
|
|
17
|
+
*
|
|
18
|
+
* Presentation state must never fail a session (ADR 0023): a source that does
|
|
19
|
+
* not parse or does not validate is skipped, not reported. A sidecar written
|
|
20
|
+
* before #473 has neither fold list and says nothing about folding rather
|
|
21
|
+
* than "fold nothing" - the view's own default decides - so only a sidecar
|
|
22
|
+
* that STATES a fold yields a `folds` entry. A sidecar written before the
|
|
23
|
+
* routes says nothing about them, and the layout recomputes.
|
|
24
|
+
*/
|
|
25
|
+
export declare const readLayoutSidecars: (sources: Iterable<{
|
|
26
|
+
readonly path: string;
|
|
27
|
+
readonly source: string;
|
|
28
|
+
}>) => LayoutSidecars;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout sidecar, read back the one way (#503).
|
|
3
|
+
*
|
|
4
|
+
* A drag saves `.yarramate/visual-layout/<projectionId>.yaml` (ADR 0085), and
|
|
5
|
+
* since 1.25.0 the routes and the fold state ride in it beside the positions
|
|
6
|
+
* (ADR 0147, #473). Two hosts write that file and two hosts have to read it:
|
|
7
|
+
* the session server from disk, the local host a product mounts from its
|
|
8
|
+
* store. Until this module the server had a reader and the local host had
|
|
9
|
+
* none, so on a mounted host a saved drag was written faithfully and never
|
|
10
|
+
* applied again - found by ApertureX on 1.25.0 (#503). One reader here, and
|
|
11
|
+
* the two cannot drift apart a second time.
|
|
12
|
+
*
|
|
13
|
+
* Pure: it takes sources and returns what the model carries. Whoever can read
|
|
14
|
+
* a directory or a store hands the bytes over.
|
|
15
|
+
*/
|
|
16
|
+
import { parse } from 'yaml';
|
|
17
|
+
import { validateVisualLayout } from '../../schema-validation.js';
|
|
18
|
+
/** Where every host writes a projection's sidecar, and reads it back from. */
|
|
19
|
+
export const LAYOUT_SIDECAR_DIR = '.yarramate/visual-layout';
|
|
20
|
+
export const layoutSidecarPath = (projectionId) => `${LAYOUT_SIDECAR_DIR}/${projectionId}.yaml`;
|
|
21
|
+
/** A path a store or directory holds that could be a sidecar. */
|
|
22
|
+
export const isLayoutSidecarPath = (path) => path.startsWith(`${LAYOUT_SIDECAR_DIR}/`) &&
|
|
23
|
+
!path.slice(LAYOUT_SIDECAR_DIR.length + 1).includes('/') &&
|
|
24
|
+
(path.endsWith('.yaml') || path.endsWith('.yml'));
|
|
25
|
+
/**
|
|
26
|
+
* What the sidecars say, keyed by the projection id each one names.
|
|
27
|
+
*
|
|
28
|
+
* Presentation state must never fail a session (ADR 0023): a source that does
|
|
29
|
+
* not parse or does not validate is skipped, not reported. A sidecar written
|
|
30
|
+
* before #473 has neither fold list and says nothing about folding rather
|
|
31
|
+
* than "fold nothing" - the view's own default decides - so only a sidecar
|
|
32
|
+
* that STATES a fold yields a `folds` entry. A sidecar written before the
|
|
33
|
+
* routes says nothing about them, and the layout recomputes.
|
|
34
|
+
*/
|
|
35
|
+
export const readLayoutSidecars = (sources) => {
|
|
36
|
+
const layouts = {};
|
|
37
|
+
const folds = {};
|
|
38
|
+
const routes = {};
|
|
39
|
+
for (const { source } of sources) {
|
|
40
|
+
let parsed;
|
|
41
|
+
try {
|
|
42
|
+
parsed = parse(source);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (!validateVisualLayout(parsed))
|
|
48
|
+
continue;
|
|
49
|
+
const sidecar = parsed;
|
|
50
|
+
layouts[sidecar.projectionId] = sidecar.positions;
|
|
51
|
+
if (sidecar.routes !== undefined)
|
|
52
|
+
routes[sidecar.projectionId] = sidecar.routes;
|
|
53
|
+
if (sidecar.folded !== undefined || sidecar.unfolded !== undefined) {
|
|
54
|
+
folds[sidecar.projectionId] = {
|
|
55
|
+
folded: [...(sidecar.folded ?? [])],
|
|
56
|
+
unfolded: [...(sidecar.unfolded ?? [])],
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return { layouts, folds, routes };
|
|
61
|
+
};
|
|
@@ -267,6 +267,23 @@ export interface VisualLayoutPositions {
|
|
|
267
267
|
readonly y: number;
|
|
268
268
|
};
|
|
269
269
|
}
|
|
270
|
+
/**
|
|
271
|
+
* The routes the canvas was drawing when a layout was saved (ADR 0147), keyed
|
|
272
|
+
* by relationship id: absolute canvas coordinates from the source end, both
|
|
273
|
+
* endpoints included, and where along the route the label sits. Saved WITH
|
|
274
|
+
* the positions, because a route is only right for the positions it was
|
|
275
|
+
* computed for: a reader who moved one subject keeps every other edge's
|
|
276
|
+
* route, and only the moved subject's edges fall back to a straight line.
|
|
277
|
+
*/
|
|
278
|
+
export interface VisualLayoutRoutes {
|
|
279
|
+
readonly [relationshipId: string]: {
|
|
280
|
+
readonly points: readonly {
|
|
281
|
+
readonly x: number;
|
|
282
|
+
readonly y: number;
|
|
283
|
+
}[];
|
|
284
|
+
readonly labelAt: number | null;
|
|
285
|
+
};
|
|
286
|
+
}
|
|
270
287
|
/**
|
|
271
288
|
* A change to a projection document, staged rather than written (ADR 0103).
|
|
272
289
|
*
|
|
@@ -332,6 +349,8 @@ export interface VisualLayoutSavePayload {
|
|
|
332
349
|
*/
|
|
333
350
|
readonly folded?: readonly string[];
|
|
334
351
|
readonly unfolded?: readonly string[];
|
|
352
|
+
/** The routes in force at save time (ADR 0147); absent when nothing was routed. */
|
|
353
|
+
readonly routes?: VisualLayoutRoutes;
|
|
335
354
|
}
|
|
336
355
|
/**
|
|
337
356
|
* Terminal event payload. Every reason is the runtime's to choose: only it
|
|
@@ -6,7 +6,6 @@ import { basename, extname, join, relative, resolve, sep } from "node:path";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import Ajv2020Module from "ajv/dist/2020.js";
|
|
8
8
|
import { WebSocketServer } from "ws";
|
|
9
|
-
import { parse } from "yaml";
|
|
10
9
|
import { VISUAL_LIMITS, VISUAL_PROTOCOL_VERSION, digestOf, parseVisualBrowserInput, parseVisualResponse, parseVisualSessionStarted, parseVisualStatus, toWireFileUri, visualBrowserInputType, } from "./protocol.js";
|
|
11
10
|
import { appendTerminalEvent, appendVisualEvent, appendVisualResponse, createVisualSession, isActionableVisualEvent, recoverVisualSession, removeVisualSession, writeVisualSessionDescriptor, } from "./session-store.js";
|
|
12
11
|
import { loadProjection, } from "../../projection.js";
|
|
@@ -17,17 +16,13 @@ import { planOperations, posixDirectoryOf, writeConflictDiagnostics, } from "../
|
|
|
17
16
|
import { createFileSystemStore } from "../../source-store.js";
|
|
18
17
|
import { emitYaml } from "../../yaml-emission.js";
|
|
19
18
|
import { loadWorkspaceManifest, } from "../../workspace.js";
|
|
20
|
-
import
|
|
21
|
-
import visualProjectionSchema from "../../../schema/yarramate-projection.schema.json" with { type: "json" };
|
|
19
|
+
import { LAYOUT_SIDECAR_DIR, isLayoutSidecarPath, layoutSidecarPath, readLayoutSidecars, } from "./layout-sidecar.js";
|
|
22
20
|
// The layout sidecar is adapter-owned presentation state (ADR 0023) that
|
|
23
21
|
// protocol.ts's validators never touch — the browser's own `layout.save`
|
|
24
22
|
// payload is already schema-validated by `parseVisualBrowserInput` before it
|
|
25
23
|
// reaches this module — so this file compiles its own single-purpose
|
|
26
24
|
// validator for the sidecar files it reads directly off disk.
|
|
27
25
|
const Ajv2020 = Ajv2020Module.default;
|
|
28
|
-
const layoutAjv = new Ajv2020({ allErrors: true });
|
|
29
|
-
layoutAjv.addSchema(visualProjectionSchema);
|
|
30
|
-
const validateVisualLayout = layoutAjv.compile(visualLayoutSchema);
|
|
31
26
|
/**
|
|
32
27
|
* Returned on every response. The policy admits no external origin at all, so
|
|
33
28
|
* neither a compromised model nor a hostile chat message can reach the network,
|
|
@@ -454,44 +449,30 @@ export const startVisualServer = async (options) => {
|
|
|
454
449
|
// Drag positions are adapter-owned presentation state (ADR 0023): never
|
|
455
450
|
// validated by Core. An invalid or unreadable sidecar is skipped exactly
|
|
456
451
|
// like a broken saved view above — presentation state must never fail a
|
|
457
|
-
// session.
|
|
458
|
-
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
const folds = {};
|
|
452
|
+
// session. The reading itself is shared with the local host (#503): this
|
|
453
|
+
// host can read a directory, so it hands the bytes over.
|
|
454
|
+
const layoutDir = resolve(options.cwd, LAYOUT_SIDECAR_DIR);
|
|
455
|
+
const { layouts, folds, routes } = readLayoutSidecars((() => {
|
|
462
456
|
let entries;
|
|
463
457
|
try {
|
|
464
458
|
entries = readdirSync(layoutDir);
|
|
465
459
|
}
|
|
466
460
|
catch {
|
|
467
|
-
return
|
|
461
|
+
return [];
|
|
468
462
|
}
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
463
|
+
return entries.flatMap((entry) => {
|
|
464
|
+
const path = `${LAYOUT_SIDECAR_DIR}/${entry}`;
|
|
465
|
+
if (!isLayoutSidecarPath(path))
|
|
466
|
+
return [];
|
|
472
467
|
try {
|
|
473
|
-
|
|
474
|
-
const parsed = parse(source);
|
|
475
|
-
if (!validateVisualLayout(parsed))
|
|
476
|
-
continue;
|
|
477
|
-
const sidecar = parsed;
|
|
478
|
-
layouts[sidecar.projectionId] = sidecar.positions;
|
|
479
|
-
// A sidecar written before #473 has neither list, and says nothing
|
|
480
|
-
// about folding rather than saying "fold nothing" - the view's own
|
|
481
|
-
// default decides for it. Only a sidecar that STATES a fold overrides.
|
|
482
|
-
if (sidecar.folded !== undefined || sidecar.unfolded !== undefined) {
|
|
483
|
-
folds[sidecar.projectionId] = {
|
|
484
|
-
folded: [...(sidecar.folded ?? [])],
|
|
485
|
-
unfolded: [...(sidecar.unfolded ?? [])],
|
|
486
|
-
};
|
|
487
|
-
}
|
|
468
|
+
return [{ path, source: readFileSync(join(layoutDir, entry), "utf8") }];
|
|
488
469
|
}
|
|
489
470
|
catch {
|
|
490
471
|
// Skipped sidecar: presentation state must never fail a session.
|
|
472
|
+
return [];
|
|
491
473
|
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
})();
|
|
474
|
+
});
|
|
475
|
+
})());
|
|
495
476
|
// `request.initialModel.graph` is the caller's compile (`buildVisualModelGraph`,
|
|
496
477
|
// before invoking `yarramate-visual start`) and is only the fallback below:
|
|
497
478
|
// `recompileWorkspace` immediately below is the one path that actually fills
|
|
@@ -505,6 +486,7 @@ export const startVisualServer = async (options) => {
|
|
|
505
486
|
vocabulary: { conceptKinds: [], relationshipKinds: [] },
|
|
506
487
|
layouts,
|
|
507
488
|
...(Object.keys(folds).length === 0 ? {} : { folds }),
|
|
489
|
+
...(Object.keys(routes).length === 0 ? {} : { routes }),
|
|
508
490
|
sourceDigests: request.initialModel.sourceDigests,
|
|
509
491
|
// The request's model has no projections in it - `visual-model/v1` carries
|
|
510
492
|
// a graph, not a workspace - so the fallback states nothing rather than
|
|
@@ -643,6 +625,11 @@ export const startVisualServer = async (options) => {
|
|
|
643
625
|
initialView: rendered.initialView,
|
|
644
626
|
documents: resolvedWorkspace.documents,
|
|
645
627
|
layouts: rendered.layouts,
|
|
628
|
+
// The fold state and the routes the sidecars said, or a save set,
|
|
629
|
+
// carried across the recompile like the positions are (#503): a
|
|
630
|
+
// commit is not a reason to forget how the reviewer arranged things.
|
|
631
|
+
...(rendered.folds === undefined ? {} : { folds: rendered.folds }),
|
|
632
|
+
...(rendered.routes === undefined ? {} : { routes: rendered.routes }),
|
|
646
633
|
// Minted from the bytes this compile just read, so what the browser
|
|
647
634
|
// renders and what it can later claim it rendered are the same read.
|
|
648
635
|
sourceDigests: Object.fromEntries(sources.map(({ path, source }) => [path, digestOf(source)])),
|
|
@@ -1424,7 +1411,7 @@ export const startVisualServer = async (options) => {
|
|
|
1424
1411
|
// never `git commit`ed. It never asks the agent anything, so it is
|
|
1425
1412
|
// answered here directly rather than through the pending queue a
|
|
1426
1413
|
// poll would drain.
|
|
1427
|
-
const { projectionId, positions, folded, unfolded } = event.payload;
|
|
1414
|
+
const { projectionId, positions, folded, unfolded, routes: savedRoutes } = event.payload;
|
|
1428
1415
|
if (!views.some((view) => view.id === projectionId)) {
|
|
1429
1416
|
sendFrame(socket, {
|
|
1430
1417
|
kind: "layout-save-result",
|
|
@@ -1435,7 +1422,7 @@ export const startVisualServer = async (options) => {
|
|
|
1435
1422
|
});
|
|
1436
1423
|
return;
|
|
1437
1424
|
}
|
|
1438
|
-
const path =
|
|
1425
|
+
const path = layoutSidecarPath(projectionId);
|
|
1439
1426
|
mkdirSync(layoutDir, { recursive: true });
|
|
1440
1427
|
writeFileSync(resolve(options.cwd, path), emitYaml({
|
|
1441
1428
|
format: "yarramate/visual-layout/v1",
|
|
@@ -1446,10 +1433,16 @@ export const startVisualServer = async (options) => {
|
|
|
1446
1433
|
// sidecar written by one host is read by the other.
|
|
1447
1434
|
...(folded === undefined ? {} : { folded }),
|
|
1448
1435
|
...(unfolded === undefined ? {} : { unfolded }),
|
|
1436
|
+
// The routes in force, beside the positions they were computed
|
|
1437
|
+
// for (ADR 0147); a save with nothing routed writes none.
|
|
1438
|
+
...(savedRoutes === undefined ? {} : { routes: savedRoutes }),
|
|
1449
1439
|
}), "utf8");
|
|
1450
1440
|
rendered = {
|
|
1451
1441
|
...rendered,
|
|
1452
1442
|
layouts: { ...rendered.layouts, [projectionId]: positions },
|
|
1443
|
+
...(savedRoutes === undefined
|
|
1444
|
+
? {}
|
|
1445
|
+
: { routes: { ...rendered.routes, [projectionId]: savedRoutes } }),
|
|
1453
1446
|
...(folded === undefined && unfolded === undefined
|
|
1454
1447
|
? {}
|
|
1455
1448
|
: {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CanvasGraph } from '../../graph-projection.js';
|
|
2
2
|
import type { PatternMembership, PatternVacancy } from '../../compiler.js';
|
|
3
|
-
import type { VISUAL_PROTOCOL_VERSION, VisualApplyResultPayload, VisualAuthority, VisualBrowserInput, VisualCapabilities, VisualChoicePresentPayload, VisualDiagnostic, VisualFilterResultPayload, VisualFreezeReason, VisualKindOption, VisualPatternOption, VisualLayoutPositions, VisualLayoutSaveResultPayload, VisualResponse, VisualTerminationReason, VisualViewSummary } from './protocol-contract.js';
|
|
3
|
+
import type { VISUAL_PROTOCOL_VERSION, VisualApplyResultPayload, VisualAuthority, VisualBrowserInput, VisualCapabilities, VisualChoicePresentPayload, VisualDiagnostic, VisualFilterResultPayload, VisualFreezeReason, VisualKindOption, VisualPatternOption, VisualLayoutPositions, VisualLayoutRoutes, VisualLayoutSaveResultPayload, VisualResponse, VisualTerminationReason, VisualViewSummary } from './protocol-contract.js';
|
|
4
4
|
/**
|
|
5
5
|
* Transport shapes the session server and the browser application both speak.
|
|
6
6
|
*
|
|
@@ -77,6 +77,14 @@ export interface VisualRenderedModel {
|
|
|
77
77
|
readonly unfolded: readonly string[];
|
|
78
78
|
};
|
|
79
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* The routes each saved layout was drawing (ADR 0147), keyed by projection
|
|
82
|
+
* id. A sibling of `layouts` for the reason `folds` is: a layout entry is
|
|
83
|
+
* positions, and widening it would reach every reader of it.
|
|
84
|
+
*/
|
|
85
|
+
readonly routes?: {
|
|
86
|
+
readonly [projectionId: string]: VisualLayoutRoutes;
|
|
87
|
+
};
|
|
80
88
|
/**
|
|
81
89
|
* Which subject fills which slot of which instance (ADR 0131), and which
|
|
82
90
|
* slots nothing fills (#447), forwarded so the browser can draw containment
|
|
@@ -55,7 +55,12 @@ export interface ConceptNotation extends ShapeMeta {
|
|
|
55
55
|
}
|
|
56
56
|
export declare const CONCEPT_NOTATION: readonly ConceptNotation[];
|
|
57
57
|
export declare function conceptNotationOf(kindLabel: string): ConceptNotation | null;
|
|
58
|
-
|
|
58
|
+
/**
|
|
59
|
+
* The glyph as a data URI, drawn in `ink` - the notation's own by default, or
|
|
60
|
+
* the light stroke a dark ground needs (ADR 0148). The stroke is the only
|
|
61
|
+
* thing that varies; the strokes themselves are the notation's.
|
|
62
|
+
*/
|
|
63
|
+
export declare function kindGlyphDataUriOf(kindLabel: string, ink?: string): string | null;
|
|
59
64
|
export interface ArrowNotation {
|
|
60
65
|
readonly shape: 'none' | 'diamond' | 'triangle' | 'circle' | 'vee';
|
|
61
66
|
readonly fill?: 'filled' | 'hollow';
|
|
@@ -38,10 +38,10 @@ export const ASPECT_SHAPES = {
|
|
|
38
38
|
const KIND_SHAPE_OVERRIDES = {
|
|
39
39
|
grouping: { borderStyle: 'dashed' },
|
|
40
40
|
};
|
|
41
|
-
function svg(body) {
|
|
41
|
+
function svg(body, ink = INK) {
|
|
42
42
|
return (`<svg xmlns="http://www.w3.org/2000/svg" width="${ICON_SIZE}" height="${ICON_SIZE}" ` +
|
|
43
43
|
`viewBox="0 0 ${ICON_SIZE} ${ICON_SIZE}">` +
|
|
44
|
-
`<g fill="none" stroke="${
|
|
44
|
+
`<g fill="none" stroke="${ink}" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">${body}</g>` +
|
|
45
45
|
`</svg>`);
|
|
46
46
|
}
|
|
47
47
|
function toDataUri(svgMarkup) {
|
|
@@ -205,9 +205,14 @@ const CONCEPT_NOTATION_BY_ID = Object.fromEntries(CONCEPT_NOTATION.map((row) =>
|
|
|
205
205
|
export function conceptNotationOf(kindLabel) {
|
|
206
206
|
return CONCEPT_NOTATION_BY_ID[kindLabel] ?? null;
|
|
207
207
|
}
|
|
208
|
-
|
|
208
|
+
/**
|
|
209
|
+
* The glyph as a data URI, drawn in `ink` - the notation's own by default, or
|
|
210
|
+
* the light stroke a dark ground needs (ADR 0148). The stroke is the only
|
|
211
|
+
* thing that varies; the strokes themselves are the notation's.
|
|
212
|
+
*/
|
|
213
|
+
export function kindGlyphDataUriOf(kindLabel, ink = INK) {
|
|
209
214
|
const glyph = CONCEPT_NOTATION_BY_ID[kindLabel]?.glyph;
|
|
210
|
-
return glyph == null ? null : toDataUri(svg(glyph));
|
|
215
|
+
return glyph == null ? null : toDataUri(svg(glyph, ink));
|
|
211
216
|
}
|
|
212
217
|
// The 11 rows from `graph-canvas.tsx`'s ArchiMate edge selectors (Task 11).
|
|
213
218
|
const RELATIONSHIP_STYLE = {
|
|
@@ -39,4 +39,5 @@ export declare const validateEvidence: ValidateFunction;
|
|
|
39
39
|
export declare const validateCoreContract: ValidateFunction;
|
|
40
40
|
export declare const validateAdapterMapping: ValidateFunction;
|
|
41
41
|
export declare const validateCatalogue: ValidateFunction;
|
|
42
|
+
export declare const validateVisualLayout: ValidateFunction;
|
|
42
43
|
export declare const validateOperations: ValidateFunction;
|
|
@@ -40,4 +40,5 @@ export const validateEvidence = generated.validateEvidence;
|
|
|
40
40
|
export const validateCoreContract = generated.validateCoreContract;
|
|
41
41
|
export const validateAdapterMapping = generated.validateAdapterMapping;
|
|
42
42
|
export const validateCatalogue = generated.validateCatalogue;
|
|
43
|
+
export const validateVisualLayout = generated.validateVisualLayout;
|
|
43
44
|
export const validateOperations = generatedOperations.validateOperations;
|
|
@@ -52,4 +52,10 @@ declare function validate74(data: any, { instancePath, parentData, parentDataPro
|
|
|
52
52
|
instancePath?: string | undefined;
|
|
53
53
|
rootData?: any;
|
|
54
54
|
}): boolean;
|
|
55
|
+
export declare const validateVisualLayout: typeof validate82;
|
|
56
|
+
declare function validate82(data: any, { instancePath, parentData, parentDataProperty, rootData, dynamicAnchors }?: {
|
|
57
|
+
dynamicAnchors?: {} | undefined;
|
|
58
|
+
instancePath?: string | undefined;
|
|
59
|
+
rootData?: any;
|
|
60
|
+
}): boolean;
|
|
55
61
|
export {};
|