@sgummalla-works/sketchon 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 +34 -0
- package/README.md +197 -0
- package/assets/emoji/1f4a1.svg +1 -0
- package/assets/emoji/1f4c8.svg +1 -0
- package/assets/emoji/1f4ca.svg +1 -0
- package/assets/emoji/1f4cb.svg +1 -0
- package/assets/emoji/1f4da.svg +1 -0
- package/assets/emoji/1f4dd.svg +1 -0
- package/assets/emoji/1f4e5.svg +1 -0
- package/assets/emoji/1f501.svg +1 -0
- package/assets/emoji/1f50d.svg +1 -0
- package/assets/emoji/1f517.svg +1 -0
- package/assets/emoji/1f525.svg +1 -0
- package/assets/emoji/1f5c4.svg +1 -0
- package/assets/emoji/1f9e0.svg +1 -0
- package/assets/emoji/1f9ee.svg +1 -0
- package/assets/emoji/23f8.svg +1 -0
- package/assets/emoji/2699.svg +1 -0
- package/assets/emoji/26a1.svg +1 -0
- package/assets/emoji/2705.svg +1 -0
- package/assets/emoji/2753.svg +1 -0
- package/assets/inter-400.ttf +0 -0
- package/assets/inter-600.ttf +0 -0
- package/assets/inter-700.ttf +0 -0
- package/dist/adapters/baseline.d.ts +3 -0
- package/dist/adapters/baseline.d.ts.map +1 -0
- package/dist/adapters/baseline.js +196 -0
- package/dist/adapters/baseline.js.map +1 -0
- package/dist/adapters/elk.d.ts +3 -0
- package/dist/adapters/elk.d.ts.map +1 -0
- package/dist/adapters/elk.js +230 -0
- package/dist/adapters/elk.js.map +1 -0
- package/dist/adapters/emoji.d.ts +10 -0
- package/dist/adapters/emoji.d.ts.map +1 -0
- package/dist/adapters/emoji.js +80 -0
- package/dist/adapters/emoji.js.map +1 -0
- package/dist/adapters/fonts.d.ts +13 -0
- package/dist/adapters/fonts.d.ts.map +1 -0
- package/dist/adapters/fonts.js +27 -0
- package/dist/adapters/fonts.js.map +1 -0
- package/dist/adapters/satori-helpers.d.ts +48 -0
- package/dist/adapters/satori-helpers.d.ts.map +1 -0
- package/dist/adapters/satori-helpers.js +43 -0
- package/dist/adapters/satori-helpers.js.map +1 -0
- package/dist/adapters/satori.d.ts +3 -0
- package/dist/adapters/satori.d.ts.map +1 -0
- package/dist/adapters/satori.js +269 -0
- package/dist/adapters/satori.js.map +1 -0
- package/dist/adapters/sequence.d.ts +3 -0
- package/dist/adapters/sequence.d.ts.map +1 -0
- package/dist/adapters/sequence.js +136 -0
- package/dist/adapters/sequence.js.map +1 -0
- package/dist/adapters/svg.d.ts +43 -0
- package/dist/adapters/svg.d.ts.map +1 -0
- package/dist/adapters/svg.js +92 -0
- package/dist/adapters/svg.js.map +1 -0
- package/dist/application/registry.d.ts +43 -0
- package/dist/application/registry.d.ts.map +1 -0
- package/dist/application/registry.js +45 -0
- package/dist/application/registry.js.map +1 -0
- package/dist/application/router.d.ts +56 -0
- package/dist/application/router.d.ts.map +1 -0
- package/dist/application/router.js +59 -0
- package/dist/application/router.js.map +1 -0
- package/dist/constants.d.ts +25 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +35 -0
- package/dist/constants.js.map +1 -0
- package/dist/domain/spec.d.ts +163 -0
- package/dist/domain/spec.d.ts.map +1 -0
- package/dist/domain/spec.js +17 -0
- package/dist/domain/spec.js.map +1 -0
- package/dist/domain/theme.d.ts +68 -0
- package/dist/domain/theme.d.ts.map +1 -0
- package/dist/domain/theme.js +60 -0
- package/dist/domain/theme.js.map +1 -0
- package/dist/domain/validate.d.ts +19 -0
- package/dist/domain/validate.d.ts.map +1 -0
- package/dist/domain/validate.js +69 -0
- package/dist/domain/validate.js.map +1 -0
- package/dist/index.d.ts +62 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +83 -0
- package/dist/index.js.map +1 -0
- package/dist/ports/Technique.d.ts +69 -0
- package/dist/ports/Technique.d.ts.map +1 -0
- package/dist/ports/Technique.js +2 -0
- package/dist/ports/Technique.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export class TechniqueRegistry {
|
|
2
|
+
map = new Map();
|
|
3
|
+
/**
|
|
4
|
+
* Register a layout engine.
|
|
5
|
+
* Returns `this` for fluent chaining at the composition root.
|
|
6
|
+
*
|
|
7
|
+
* @param key stable engine identifier
|
|
8
|
+
* @param technique the Technique implementation
|
|
9
|
+
* @throws if the key is already registered (prevents silent overwrites)
|
|
10
|
+
*/
|
|
11
|
+
register(key, technique) {
|
|
12
|
+
if (this.map.has(key)) {
|
|
13
|
+
throw new Error(`Technique "${key}" is already registered. Each engine key must be unique.`);
|
|
14
|
+
}
|
|
15
|
+
this.map.set(key, technique);
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Look up a technique by engine key.
|
|
20
|
+
*
|
|
21
|
+
* @param key the engine identifier
|
|
22
|
+
* @throws if no technique is registered for that key
|
|
23
|
+
*/
|
|
24
|
+
get(key) {
|
|
25
|
+
const t = this.map.get(key);
|
|
26
|
+
if (!t) {
|
|
27
|
+
throw new Error(`No technique registered for key "${key}". ` +
|
|
28
|
+
`Registered: ${[...this.map.keys()].join(', ')}`);
|
|
29
|
+
}
|
|
30
|
+
return t;
|
|
31
|
+
}
|
|
32
|
+
/** Whether a key is registered. */
|
|
33
|
+
has(key) {
|
|
34
|
+
return this.map.has(key);
|
|
35
|
+
}
|
|
36
|
+
/** All registered techniques in insertion order. */
|
|
37
|
+
techniques() {
|
|
38
|
+
return [...this.map.values()];
|
|
39
|
+
}
|
|
40
|
+
/** All registered engine keys in insertion order. */
|
|
41
|
+
keys() {
|
|
42
|
+
return [...this.map.keys()];
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/application/registry.ts"],"names":[],"mappings":"AAkBA,MAAM,OAAO,iBAAiB;IACX,GAAG,GAAG,IAAI,GAAG,EAAqB,CAAC;IAEpD;;;;;;;OAOG;IACH,QAAQ,CAAC,GAAW,EAAE,SAAoB;QACxC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,cAAc,GAAG,0DAA0D,CAC5E,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,GAAG,CAAC,GAAW;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,IAAI,KAAK,CACb,oCAAoC,GAAG,KAAK;gBAC1C,eAAe,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnD,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,mCAAmC;IACnC,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAED,oDAAoD;IACpD,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,qDAAqD;IACrD,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;CACF"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Router — application-layer routing logic.
|
|
3
|
+
*
|
|
4
|
+
* HEXAGONAL ARCHITECTURE INVARIANT:
|
|
5
|
+
* This file MUST NEVER import from '../adapters/' or any concrete adapter.
|
|
6
|
+
* It depends on TechniqueRegistry (application layer) and the domain types.
|
|
7
|
+
* The routing table (KIND_ENGINE) is application policy, not adapter knowledge.
|
|
8
|
+
*
|
|
9
|
+
* The router takes a TechniqueRegistry via constructor injection.
|
|
10
|
+
* The registry is populated by the composition root (index.ts), which is the
|
|
11
|
+
* only place that is allowed to import concrete adapters.
|
|
12
|
+
*/
|
|
13
|
+
import type { DiagramSpec } from '../domain/spec.js';
|
|
14
|
+
import type { Technique, RenderResult } from '../ports/Technique.js';
|
|
15
|
+
import type { TechniqueRegistry } from './registry.js';
|
|
16
|
+
/**
|
|
17
|
+
* Valid engine keys — extend this union when registering a new engine.
|
|
18
|
+
* Lives here because routing policy (which kind maps to which engine)
|
|
19
|
+
* is an application concern, not a domain or adapter concern.
|
|
20
|
+
*/
|
|
21
|
+
export type EngineKey = 'baseline' | 'elk' | 'satori' | 'sequence';
|
|
22
|
+
/**
|
|
23
|
+
* The Router orchestrates rendering by resolving the right engine from the
|
|
24
|
+
* registry based on the spec's kind (or an explicit override).
|
|
25
|
+
*
|
|
26
|
+
* Constructed with a TechniqueRegistry injected from the composition root.
|
|
27
|
+
* Has no knowledge of which concrete adapters exist.
|
|
28
|
+
*/
|
|
29
|
+
export declare class Router {
|
|
30
|
+
private readonly registry;
|
|
31
|
+
constructor(registry: TechniqueRegistry);
|
|
32
|
+
/**
|
|
33
|
+
* Select the engine key for a spec.
|
|
34
|
+
* An explicit `spec.renderer` override takes priority over the kind default.
|
|
35
|
+
*
|
|
36
|
+
* @param spec the diagram spec
|
|
37
|
+
* @returns the resolved engine key
|
|
38
|
+
*/
|
|
39
|
+
selectEngineKey(spec: DiagramSpec): EngineKey;
|
|
40
|
+
/**
|
|
41
|
+
* Resolve the Technique that will render a spec.
|
|
42
|
+
*
|
|
43
|
+
* @param spec the diagram spec
|
|
44
|
+
* @returns the chosen Technique implementation
|
|
45
|
+
*/
|
|
46
|
+
selectEngine(spec: DiagramSpec): Technique;
|
|
47
|
+
/**
|
|
48
|
+
* Render a spec with the routed engine.
|
|
49
|
+
* This is the primary use case entry point — what consumers call.
|
|
50
|
+
*
|
|
51
|
+
* @param spec the validated, coordinate-free diagram spec
|
|
52
|
+
* @returns the rendered SVG + metadata
|
|
53
|
+
*/
|
|
54
|
+
renderDiagram(spec: DiagramSpec): RenderResult | Promise<RenderResult>;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/application/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEvD;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAC;AAgBnE;;;;;;GAMG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,iBAAiB;IAExD;;;;;;OAMG;IACH,eAAe,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS;IAO7C;;;;;OAKG;IACH,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,SAAS;IAI1C;;;;;;OAMG;IACH,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CAGvE"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The authoritative kind → engine mapping.
|
|
3
|
+
* One entry per DiagramKind — adding a new kind means adding one line here.
|
|
4
|
+
*/
|
|
5
|
+
const KIND_ENGINE = {
|
|
6
|
+
concept: 'satori',
|
|
7
|
+
mindmap: 'satori',
|
|
8
|
+
sequence: 'sequence',
|
|
9
|
+
flow: 'elk',
|
|
10
|
+
architecture: 'elk',
|
|
11
|
+
state: 'elk',
|
|
12
|
+
er: 'elk',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The Router orchestrates rendering by resolving the right engine from the
|
|
16
|
+
* registry based on the spec's kind (or an explicit override).
|
|
17
|
+
*
|
|
18
|
+
* Constructed with a TechniqueRegistry injected from the composition root.
|
|
19
|
+
* Has no knowledge of which concrete adapters exist.
|
|
20
|
+
*/
|
|
21
|
+
export class Router {
|
|
22
|
+
registry;
|
|
23
|
+
constructor(registry) {
|
|
24
|
+
this.registry = registry;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Select the engine key for a spec.
|
|
28
|
+
* An explicit `spec.renderer` override takes priority over the kind default.
|
|
29
|
+
*
|
|
30
|
+
* @param spec the diagram spec
|
|
31
|
+
* @returns the resolved engine key
|
|
32
|
+
*/
|
|
33
|
+
selectEngineKey(spec) {
|
|
34
|
+
if (spec.renderer && this.registry.has(spec.renderer)) {
|
|
35
|
+
return spec.renderer;
|
|
36
|
+
}
|
|
37
|
+
return KIND_ENGINE[spec.kind] ?? 'elk';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the Technique that will render a spec.
|
|
41
|
+
*
|
|
42
|
+
* @param spec the diagram spec
|
|
43
|
+
* @returns the chosen Technique implementation
|
|
44
|
+
*/
|
|
45
|
+
selectEngine(spec) {
|
|
46
|
+
return this.registry.get(this.selectEngineKey(spec));
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Render a spec with the routed engine.
|
|
50
|
+
* This is the primary use case entry point — what consumers call.
|
|
51
|
+
*
|
|
52
|
+
* @param spec the validated, coordinate-free diagram spec
|
|
53
|
+
* @returns the rendered SVG + metadata
|
|
54
|
+
*/
|
|
55
|
+
renderDiagram(spec) {
|
|
56
|
+
return this.selectEngine(spec).render(spec);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/application/router.ts"],"names":[],"mappings":"AAuBA;;;GAGG;AACH,MAAM,WAAW,GAAmC;IAClD,OAAO,EAAO,QAAQ;IACtB,OAAO,EAAO,QAAQ;IACtB,QAAQ,EAAM,UAAU;IACxB,IAAI,EAAU,KAAK;IACnB,YAAY,EAAE,KAAK;IACnB,KAAK,EAAS,KAAK;IACnB,EAAE,EAAY,KAAK;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,OAAO,MAAM;IACY;IAA7B,YAA6B,QAA2B;QAA3B,aAAQ,GAAR,QAAQ,CAAmB;IAAG,CAAC;IAE5D;;;;;;OAMG;IACH,eAAe,CAAC,IAAiB;QAC/B,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC,QAAqB,CAAC;QACpC,CAAC;QACD,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;IACzC,CAAC;IAED;;;;;OAKG;IACH,YAAY,CAAC,IAAiB;QAC5B,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;IACvD,CAAC;IAED;;;;;;OAMG;IACH,aAAa,CAAC,IAAiB;QAC7B,OAAO,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9C,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunable constants for the diagram lab. Kept out of logic files so a
|
|
3
|
+
* technique or metric never inlines a magic number — change layout/eval
|
|
4
|
+
* behaviour here, in one place.
|
|
5
|
+
*/
|
|
6
|
+
export declare const AVG_CHAR_WIDTH_EM = 0.58;
|
|
7
|
+
export declare const DEFAULT_FONT_SIZE = 14;
|
|
8
|
+
export declare const NODE_LABEL_FONT_SIZE = 14;
|
|
9
|
+
export declare const NODE_SUBLABEL_FONT_SIZE = 11;
|
|
10
|
+
export declare const EDGE_LABEL_FONT_SIZE = 12;
|
|
11
|
+
export declare const NODE_PADDING_X = 16;
|
|
12
|
+
export declare const NODE_PADDING_Y = 12;
|
|
13
|
+
export declare const NODE_MIN_WIDTH = 72;
|
|
14
|
+
export declare const NODE_MIN_HEIGHT = 40;
|
|
15
|
+
export declare const NODE_MAX_WIDTH = 240;
|
|
16
|
+
export declare const LAYER_GAP = 90;
|
|
17
|
+
export declare const NODE_GAP = 36;
|
|
18
|
+
export declare const CANVAS_PADDING = 40;
|
|
19
|
+
export declare const SCORE_START = 100;
|
|
20
|
+
export declare const PENALTY_PER_OVERLAP_PAIR = 12;
|
|
21
|
+
export declare const PENALTY_PER_OFFCANVAS_BOX = 10;
|
|
22
|
+
export declare const PENALTY_PER_TEXT_OVERFLOW = 8;
|
|
23
|
+
export declare const PENALTY_PER_EDGE_CROSSING = 3;
|
|
24
|
+
export declare const TEXT_OVERFLOW_TOLERANCE_PX = 2;
|
|
25
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,eAAO,MAAM,iBAAiB,OAAO,CAAC;AACtC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,uBAAuB,KAAK,CAAC;AAC1C,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAGvC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,cAAc,KAAK,CAAC;AACjC,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,eAAO,MAAM,cAAc,MAAM,CAAC;AAGlC,eAAO,MAAM,SAAS,KAAK,CAAC;AAC5B,eAAO,MAAM,QAAQ,KAAK,CAAC;AAC3B,eAAO,MAAM,cAAc,KAAK,CAAC;AAKjC,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,yBAAyB,KAAK,CAAC;AAC5C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,yBAAyB,IAAI,CAAC;AAC3C,eAAO,MAAM,0BAA0B,IAAI,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tunable constants for the diagram lab. Kept out of logic files so a
|
|
3
|
+
* technique or metric never inlines a magic number — change layout/eval
|
|
4
|
+
* behaviour here, in one place.
|
|
5
|
+
*/
|
|
6
|
+
// ── Text measurement ────────────────────────────────────────────────────────
|
|
7
|
+
// We have no real font metrics in the baseline (no browser, no Satori yet),
|
|
8
|
+
// so width is estimated as `chars * AVG_CHAR_WIDTH_EM * fontSize`. ~0.58em is a
|
|
9
|
+
// reasonable mean advance width for a humanist sans at typical sizes. Real
|
|
10
|
+
// engines (Satori/resvg) will replace this estimate with true glyph metrics.
|
|
11
|
+
export const AVG_CHAR_WIDTH_EM = 0.58;
|
|
12
|
+
export const DEFAULT_FONT_SIZE = 14;
|
|
13
|
+
export const NODE_LABEL_FONT_SIZE = 14;
|
|
14
|
+
export const NODE_SUBLABEL_FONT_SIZE = 11;
|
|
15
|
+
export const EDGE_LABEL_FONT_SIZE = 12;
|
|
16
|
+
// ── Node sizing ─────────────────────────────────────────────────────────────
|
|
17
|
+
export const NODE_PADDING_X = 16;
|
|
18
|
+
export const NODE_PADDING_Y = 12;
|
|
19
|
+
export const NODE_MIN_WIDTH = 72;
|
|
20
|
+
export const NODE_MIN_HEIGHT = 40;
|
|
21
|
+
export const NODE_MAX_WIDTH = 240;
|
|
22
|
+
// ── Layout spacing (baseline layered layout) ────────────────────────────────
|
|
23
|
+
export const LAYER_GAP = 90; // gap between layers (rank direction)
|
|
24
|
+
export const NODE_GAP = 36; // gap between siblings within a layer
|
|
25
|
+
export const CANVAS_PADDING = 40; // margin around the whole drawing
|
|
26
|
+
// ── Eval thresholds + scoring weights ───────────────────────────────────────
|
|
27
|
+
// Composite score starts at 100; each problem subtracts its weight (clamped
|
|
28
|
+
// at 0). Weights encode "how bad is this for a reader."
|
|
29
|
+
export const SCORE_START = 100;
|
|
30
|
+
export const PENALTY_PER_OVERLAP_PAIR = 12; // boxes physically overlapping
|
|
31
|
+
export const PENALTY_PER_OFFCANVAS_BOX = 10; // box outside the viewBox
|
|
32
|
+
export const PENALTY_PER_TEXT_OVERFLOW = 8; // label wider than its box
|
|
33
|
+
export const PENALTY_PER_EDGE_CROSSING = 3; // two edges crossing
|
|
34
|
+
export const TEXT_OVERFLOW_TOLERANCE_PX = 2; // ignore sub-pixel rounding
|
|
35
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,+EAA+E;AAC/E,4EAA4E;AAC5E,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC;AACtC,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AACvC,MAAM,CAAC,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAC1C,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC;AACjC,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC;AAElC,+EAA+E;AAC/E,MAAM,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC,sCAAsC;AACnE,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,sCAAsC;AAClE,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,CAAC,CAAC,kCAAkC;AAEpE,+EAA+E;AAC/E,4EAA4E;AAC5E,wDAAwD;AACxD,MAAM,CAAC,MAAM,WAAW,GAAG,GAAG,CAAC;AAC/B,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC,CAAC,+BAA+B;AAC3E,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,CAAC,CAAC,0BAA0B;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,CAAC,2BAA2B;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,CAAC,qBAAqB;AACjE,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,CAAC,4BAA4B"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The DiagramSpec — a SEMANTIC, coordinate-free description of a diagram.
|
|
3
|
+
*
|
|
4
|
+
* This is the central contract of the lab and the thing that eventually ports
|
|
5
|
+
* into pragna2. The whole premise of #36 is: the model (or a hand-authored
|
|
6
|
+
* fixture) emits ONLY structure — what relates to what, how it's grouped, what
|
|
7
|
+
* to emphasise — and a deterministic layout engine computes every pixel. So
|
|
8
|
+
* there are deliberately NO x/y/width coordinates anywhere in this file. If a
|
|
9
|
+
* coordinate ever appears in a spec, the design has leaked the broken part
|
|
10
|
+
* (model-does-trig) back in.
|
|
11
|
+
*
|
|
12
|
+
* One schema spans ALL diagram kinds (flow, sequence, architecture, ER, state,
|
|
13
|
+
* and free-form concept/illustrative). A technique reads the same spec and
|
|
14
|
+
* lays it out however suits its engine.
|
|
15
|
+
*/
|
|
16
|
+
/** What family of diagram this is. Drives default layout strategy + shapes. */
|
|
17
|
+
export type DiagramKind = 'flow' | 'sequence' | 'architecture' | 'er' | 'state' | 'mindmap' | 'concept';
|
|
18
|
+
/** Preferred primary flow direction. Engines may honour or override. */
|
|
19
|
+
export type Direction = 'TB' | 'BT' | 'LR' | 'RL';
|
|
20
|
+
/** Visual shape of a node. Semantic, not pixel-level. */
|
|
21
|
+
export type NodeShape = 'box' | 'rounded' | 'pill' | 'circle' | 'diamond' | 'cylinder' | 'actor' | 'note' | 'icon' | 'card' | 'checkpoint';
|
|
22
|
+
/**
|
|
23
|
+
* Visual weight. Lets the author say "this is the important one" without
|
|
24
|
+
* choosing colours — the renderer maps emphasis → theme tokens.
|
|
25
|
+
*/
|
|
26
|
+
export type Emphasis = 'normal' | 'primary' | 'muted' | 'danger' | 'success' | 'accent';
|
|
27
|
+
/** Line treatment for an edge. */
|
|
28
|
+
export type EdgeStyle = 'solid' | 'dashed' | 'dotted';
|
|
29
|
+
/** Arrowhead treatment. */
|
|
30
|
+
export type ArrowKind = 'none' | 'open' | 'filled';
|
|
31
|
+
/**
|
|
32
|
+
* Semantic edge category. The renderer can style each consistently
|
|
33
|
+
* (e.g. dataflow vs dependency vs sequence-message) without per-edge styling
|
|
34
|
+
* from the author.
|
|
35
|
+
*/
|
|
36
|
+
export type EdgeSemantic = 'default' | 'dependency' | 'dataflow' | 'message' | 'return' | 'association';
|
|
37
|
+
export interface DiagramNode {
|
|
38
|
+
/** Stable id, referenced by edges, groups, annotations. */
|
|
39
|
+
id: string;
|
|
40
|
+
/** Primary visible text. */
|
|
41
|
+
label: string;
|
|
42
|
+
/**
|
|
43
|
+
* Optional second line (role, type, short qualifier). For `card` shapes this
|
|
44
|
+
* is the tinted sub-line; render as `·`-joined when given as `sublabelParts`.
|
|
45
|
+
*/
|
|
46
|
+
sublabel?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Structured sub-line tokens for rich cards, rendered `·`-separated
|
|
49
|
+
* (e.g. ["Vector DB", "semantic search", "doc chunking"]). Preferred over
|
|
50
|
+
* `sublabel` for `card` shapes; the renderer joins them.
|
|
51
|
+
*/
|
|
52
|
+
sublabelParts?: string[];
|
|
53
|
+
shape?: NodeShape;
|
|
54
|
+
emphasis?: Emphasis;
|
|
55
|
+
/**
|
|
56
|
+
* Optional leading glyph. May be a literal emoji (e.g. "🔍") for concept/card
|
|
57
|
+
* diagrams, or a semantic icon name the renderer maps. Never a URL.
|
|
58
|
+
*/
|
|
59
|
+
icon?: string;
|
|
60
|
+
/** Id of the group this node belongs to, if any. */
|
|
61
|
+
group?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Id of the colour `category` this node belongs to (legend-style colouring).
|
|
64
|
+
* Independent of `emphasis`: category drives the colour family + legend,
|
|
65
|
+
* emphasis is a per-node weight. When both are set, category wins for fill.
|
|
66
|
+
*/
|
|
67
|
+
category?: string;
|
|
68
|
+
}
|
|
69
|
+
export interface DiagramEdge {
|
|
70
|
+
/** Source node id. */
|
|
71
|
+
from: string;
|
|
72
|
+
/** Target node id. */
|
|
73
|
+
to: string;
|
|
74
|
+
/** Optional edge text (condition, message, cardinality). */
|
|
75
|
+
label?: string;
|
|
76
|
+
style?: EdgeStyle;
|
|
77
|
+
arrow?: ArrowKind;
|
|
78
|
+
semantic?: EdgeSemantic;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* A visual grouping / container (a subsystem boundary, a swimlane, a cluster).
|
|
82
|
+
* Members are node ids. Groups may nest via `parent`.
|
|
83
|
+
*/
|
|
84
|
+
export interface DiagramGroup {
|
|
85
|
+
id: string;
|
|
86
|
+
label?: string;
|
|
87
|
+
members: string[];
|
|
88
|
+
emphasis?: Emphasis;
|
|
89
|
+
/** Optional parent group id for nested containers. */
|
|
90
|
+
parent?: string;
|
|
91
|
+
}
|
|
92
|
+
/** Where an annotation sits relative to its target. */
|
|
93
|
+
export type AnnotationPlacement = 'top' | 'bottom' | 'left' | 'right' | 'callout';
|
|
94
|
+
/**
|
|
95
|
+
* Free-floating explanatory text, optionally tied to a node/group. Central to
|
|
96
|
+
* the illustrative/concept kind ("build intuition" labels pointing at parts).
|
|
97
|
+
*/
|
|
98
|
+
export interface DiagramAnnotation {
|
|
99
|
+
text: string;
|
|
100
|
+
/** Node or group id this annotation points at, if any. */
|
|
101
|
+
target?: string;
|
|
102
|
+
placement?: AnnotationPlacement;
|
|
103
|
+
}
|
|
104
|
+
/** Optional hints; renderer supplies defaults for anything omitted. */
|
|
105
|
+
export interface ThemeHints {
|
|
106
|
+
/** 'light' | 'dark' — renderer picks token set. */
|
|
107
|
+
mode?: 'light' | 'dark';
|
|
108
|
+
/** Rough density preference. */
|
|
109
|
+
density?: 'compact' | 'comfortable';
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A named category for legend-style colour coding (e.g. "retrieval",
|
|
113
|
+
* "execution"). Added after the 2026-05-31 reference image, which colours nodes
|
|
114
|
+
* by CATEGORY (retrieval=blue, reasoning=purple, …) and renders a legend — a
|
|
115
|
+
* different axis from per-node semantic `emphasis`. A node points at a category
|
|
116
|
+
* via `DiagramNode.category`; the renderer maps category → colour and draws the
|
|
117
|
+
* legend from the categories actually used.
|
|
118
|
+
*/
|
|
119
|
+
export interface DiagramCategory {
|
|
120
|
+
/** Stable id referenced by `DiagramNode.category`. */
|
|
121
|
+
id: string;
|
|
122
|
+
/** Legend label, e.g. "Retrieval / grounding". */
|
|
123
|
+
label: string;
|
|
124
|
+
/** Colour intent; renderer maps to a concrete token. */
|
|
125
|
+
emphasis?: Emphasis;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Column headers for the annotated two-column "concept" layout (the reference
|
|
129
|
+
* image's "Tool layer" / "Why it's mandatory"). Only meaningful when nodes
|
|
130
|
+
* carry right-placed annotations rendered as a paired second column.
|
|
131
|
+
*/
|
|
132
|
+
export interface ColumnHeaders {
|
|
133
|
+
/** Heading over the node column. */
|
|
134
|
+
primary: string;
|
|
135
|
+
/** Heading over the annotation column. */
|
|
136
|
+
annotation: string;
|
|
137
|
+
}
|
|
138
|
+
export interface DiagramSpec {
|
|
139
|
+
/** Stable id for the spec (used in filenames / preview). */
|
|
140
|
+
id: string;
|
|
141
|
+
/** Optional diagram title rendered as a heading. */
|
|
142
|
+
title?: string;
|
|
143
|
+
kind: DiagramKind;
|
|
144
|
+
/** Preferred direction for directed kinds. Default per-kind in the renderer. */
|
|
145
|
+
direction?: Direction;
|
|
146
|
+
nodes: DiagramNode[];
|
|
147
|
+
edges: DiagramEdge[];
|
|
148
|
+
groups?: DiagramGroup[];
|
|
149
|
+
annotations?: DiagramAnnotation[];
|
|
150
|
+
/** Legend-style colour categories referenced by `DiagramNode.category`. */
|
|
151
|
+
categories?: DiagramCategory[];
|
|
152
|
+
/** Column headers for the annotated two-column concept layout. */
|
|
153
|
+
columns?: ColumnHeaders;
|
|
154
|
+
/**
|
|
155
|
+
* Optional engine override. Normally omitted — the renderer auto-routes by
|
|
156
|
+
* `kind` (panel/concept → Satori, graph kinds → elkjs). Set only for the rare
|
|
157
|
+
* case where the kind's default engine is the wrong fit. The model should not
|
|
158
|
+
* set this routinely; declaring the right `kind` is the intended path.
|
|
159
|
+
*/
|
|
160
|
+
renderer?: 'satori' | 'elk' | 'sequence';
|
|
161
|
+
theme?: ThemeHints;
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/domain/spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The DiagramSpec — a SEMANTIC, coordinate-free description of a diagram.
|
|
3
|
+
*
|
|
4
|
+
* This is the central contract of the lab and the thing that eventually ports
|
|
5
|
+
* into pragna2. The whole premise of #36 is: the model (or a hand-authored
|
|
6
|
+
* fixture) emits ONLY structure — what relates to what, how it's grouped, what
|
|
7
|
+
* to emphasise — and a deterministic layout engine computes every pixel. So
|
|
8
|
+
* there are deliberately NO x/y/width coordinates anywhere in this file. If a
|
|
9
|
+
* coordinate ever appears in a spec, the design has leaked the broken part
|
|
10
|
+
* (model-does-trig) back in.
|
|
11
|
+
*
|
|
12
|
+
* One schema spans ALL diagram kinds (flow, sequence, architecture, ER, state,
|
|
13
|
+
* and free-form concept/illustrative). A technique reads the same spec and
|
|
14
|
+
* lays it out however suits its engine.
|
|
15
|
+
*/
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/domain/spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour tokens for the diagram renderer.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for every colour value used across all rendering
|
|
5
|
+
* adapters. No hex string should appear in any adapter file — use these named
|
|
6
|
+
* constants instead so the visual language is tunable from one place.
|
|
7
|
+
*
|
|
8
|
+
* Tokens are grouped by concern. All values are hex strings or rgba() strings
|
|
9
|
+
* that SVG and Satori both accept.
|
|
10
|
+
*/
|
|
11
|
+
export declare const COLOR_TEXT_PRIMARY = "#0f172a";
|
|
12
|
+
export declare const COLOR_TEXT_BODY = "#475569";
|
|
13
|
+
export declare const COLOR_TEXT_MUTED = "#64748b";
|
|
14
|
+
export declare const COLOR_TEXT_WHITE = "#ffffff";
|
|
15
|
+
export declare const COLOR_BORDER_LIGHT = "#e2e8f0";
|
|
16
|
+
export declare const COLOR_BORDER_DEFAULT = "#cbd5e1";
|
|
17
|
+
export declare const COLOR_EDGE_DEFAULT = "#64748b";
|
|
18
|
+
export declare const COLOR_EDGE_DASHED = "#94a3b8";
|
|
19
|
+
export declare const PALETTE_NORMAL: {
|
|
20
|
+
fill: string;
|
|
21
|
+
stroke: string;
|
|
22
|
+
text: string;
|
|
23
|
+
};
|
|
24
|
+
export declare const PALETTE_PRIMARY: {
|
|
25
|
+
fill: string;
|
|
26
|
+
stroke: string;
|
|
27
|
+
text: string;
|
|
28
|
+
};
|
|
29
|
+
export declare const PALETTE_ACCENT: {
|
|
30
|
+
fill: string;
|
|
31
|
+
stroke: string;
|
|
32
|
+
text: string;
|
|
33
|
+
};
|
|
34
|
+
export declare const PALETTE_MUTED: {
|
|
35
|
+
fill: string;
|
|
36
|
+
stroke: string;
|
|
37
|
+
text: string;
|
|
38
|
+
};
|
|
39
|
+
export declare const PALETTE_DANGER: {
|
|
40
|
+
fill: string;
|
|
41
|
+
stroke: string;
|
|
42
|
+
text: string;
|
|
43
|
+
};
|
|
44
|
+
export declare const PALETTE_SUCCESS: {
|
|
45
|
+
fill: string;
|
|
46
|
+
stroke: string;
|
|
47
|
+
text: string;
|
|
48
|
+
};
|
|
49
|
+
export declare const DARK_PRIMARY = "#1e3a5f";
|
|
50
|
+
export declare const DARK_ACCENT = "#3730a3";
|
|
51
|
+
export declare const DARK_SUCCESS = "#14532d";
|
|
52
|
+
export declare const DARK_DANGER = "#7f1d1d";
|
|
53
|
+
export declare const DARK_NORMAL = "#334155";
|
|
54
|
+
export declare const DARK_MUTED = "#475569";
|
|
55
|
+
export declare const ACTOR_CYCLE_FILLS: readonly ["#1e3a5f", "#14532d", "#3730a3", "#7c2d12", "#134e4a", "#4c1d95"];
|
|
56
|
+
export declare const CARD_PALETTE_PRIMARY = "#1e4e79";
|
|
57
|
+
export declare const CARD_PALETTE_ACCENT = "#4b3f9e";
|
|
58
|
+
export declare const CARD_PALETTE_DANGER = "#8a3a2c";
|
|
59
|
+
export declare const CARD_PALETTE_SUCCESS = "#3f6e26";
|
|
60
|
+
export declare const CARD_PALETTE_NORMAL = "#3b4250";
|
|
61
|
+
export declare const CARD_PALETTE_MUTED = "#64748b";
|
|
62
|
+
export declare const CHECKPOINT_FILL = "#6b5212";
|
|
63
|
+
export declare const CHECKPOINT_BORDER = "#b8923a";
|
|
64
|
+
export declare const CHECKPOINT_TEXT = "#ffd98a";
|
|
65
|
+
export declare const CONNECTOR_COLOR = "#cbd5e1";
|
|
66
|
+
export declare const ARROW_FILL = "#475569";
|
|
67
|
+
export declare const ARROW_STROKE = "#475569";
|
|
68
|
+
//# sourceMappingURL=theme.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.d.ts","sourceRoot":"","sources":["../../src/domain/theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,eAAO,MAAM,kBAAkB,YAAe,CAAC;AAC/C,eAAO,MAAM,eAAe,YAAkB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,YAAiB,CAAC;AAC/C,eAAO,MAAM,gBAAgB,YAAiB,CAAC;AAE/C,eAAO,MAAM,kBAAkB,YAAe,CAAC;AAC/C,eAAO,MAAM,oBAAoB,YAAa,CAAC;AAC/C,eAAO,MAAM,kBAAkB,YAAe,CAAC;AAC/C,eAAO,MAAM,iBAAiB,YAAgB,CAAC;AAI/C,eAAO,MAAM,cAAc;;;;CAAoE,CAAC;AAChG,eAAO,MAAM,eAAe;;;;CAA0D,CAAC;AACvF,eAAO,MAAM,cAAc;;;;CAA2D,CAAC;AACvF,eAAO,MAAM,aAAa;;;;CAA4D,CAAC;AACvF,eAAO,MAAM,cAAc;;;;CAA2D,CAAC;AACvF,eAAO,MAAM,eAAe;;;;CAA0D,CAAC;AAGvF,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,WAAW,YAAa,CAAC;AACtC,eAAO,MAAM,YAAY,YAAY,CAAC;AACtC,eAAO,MAAM,WAAW,YAAa,CAAC;AACtC,eAAO,MAAM,WAAW,YAAa,CAAC;AACtC,eAAO,MAAM,UAAU,YAAc,CAAC;AAGtC,eAAO,MAAM,iBAAiB,6EAOpB,CAAC;AAGX,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,oBAAoB,YAAY,CAAC;AAC9C,eAAO,MAAM,mBAAmB,YAAa,CAAC;AAC9C,eAAO,MAAM,kBAAkB,YAAc,CAAC;AAG9C,eAAO,MAAM,eAAe,YAAc,CAAC;AAC3C,eAAO,MAAM,iBAAiB,YAAY,CAAC;AAC3C,eAAO,MAAM,eAAe,YAAc,CAAC;AAG3C,eAAO,MAAM,eAAe,YAAY,CAAC;AAGzC,eAAO,MAAM,UAAU,YAAc,CAAC;AACtC,eAAO,MAAM,YAAY,YAAY,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour tokens for the diagram renderer.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for every colour value used across all rendering
|
|
5
|
+
* adapters. No hex string should appear in any adapter file — use these named
|
|
6
|
+
* constants instead so the visual language is tunable from one place.
|
|
7
|
+
*
|
|
8
|
+
* Tokens are grouped by concern. All values are hex strings or rgba() strings
|
|
9
|
+
* that SVG and Satori both accept.
|
|
10
|
+
*/
|
|
11
|
+
// ── Structural / neutral ──────────────────────────────────────────────────────
|
|
12
|
+
export const COLOR_TEXT_PRIMARY = '#0f172a'; // heading text
|
|
13
|
+
export const COLOR_TEXT_BODY = '#475569'; // body / label text
|
|
14
|
+
export const COLOR_TEXT_MUTED = '#64748b'; // secondary / muted labels
|
|
15
|
+
export const COLOR_TEXT_WHITE = '#ffffff'; // white text on dark fills
|
|
16
|
+
export const COLOR_BORDER_LIGHT = '#e2e8f0'; // dividers, subtle borders
|
|
17
|
+
export const COLOR_BORDER_DEFAULT = '#cbd5e1'; // lifelines, group outlines
|
|
18
|
+
export const COLOR_EDGE_DEFAULT = '#64748b'; // solid edge stroke
|
|
19
|
+
export const COLOR_EDGE_DASHED = '#94a3b8'; // dashed / return edge stroke
|
|
20
|
+
// ── Light semantic palette (outlined boxes — baseline + elk nodes) ────────────
|
|
21
|
+
// Fill + stroke + text per emphasis value.
|
|
22
|
+
export const PALETTE_NORMAL = { fill: '#f1f5f9', stroke: '#94a3b8', text: COLOR_TEXT_PRIMARY };
|
|
23
|
+
export const PALETTE_PRIMARY = { fill: '#dbeafe', stroke: '#3b82f6', text: '#0c2a5b' };
|
|
24
|
+
export const PALETTE_ACCENT = { fill: '#ede9fe', stroke: '#8b5cf6', text: '#3b1d80' };
|
|
25
|
+
export const PALETTE_MUTED = { fill: '#f8fafc', stroke: '#cbd5e1', text: '#475569' };
|
|
26
|
+
export const PALETTE_DANGER = { fill: '#fee2e2', stroke: '#ef4444', text: '#7f1d1d' };
|
|
27
|
+
export const PALETTE_SUCCESS = { fill: '#dcfce7', stroke: '#22c55e', text: '#14532d' };
|
|
28
|
+
// ── Dark semantic palette (sequence actor boxes — saturated fills + white text) ─
|
|
29
|
+
export const DARK_PRIMARY = '#1e3a5f'; // deep navy
|
|
30
|
+
export const DARK_ACCENT = '#3730a3'; // deep indigo / purple
|
|
31
|
+
export const DARK_SUCCESS = '#14532d'; // dark forest green
|
|
32
|
+
export const DARK_DANGER = '#7f1d1d'; // dark crimson
|
|
33
|
+
export const DARK_NORMAL = '#334155'; // dark slate
|
|
34
|
+
export const DARK_MUTED = '#475569'; // medium slate
|
|
35
|
+
// Cycling fills for actors with no explicit emphasis (distinct per slot).
|
|
36
|
+
export const ACTOR_CYCLE_FILLS = [
|
|
37
|
+
DARK_PRIMARY, // navy (slot 0)
|
|
38
|
+
DARK_SUCCESS, // green (slot 1)
|
|
39
|
+
DARK_ACCENT, // indigo (slot 2)
|
|
40
|
+
'#7c2d12', // rust (slot 3)
|
|
41
|
+
'#134e4a', // teal (slot 4)
|
|
42
|
+
'#4c1d95', // violet (slot 5)
|
|
43
|
+
];
|
|
44
|
+
// ── Satori card palette (rich panel cards — always white text) ────────────────
|
|
45
|
+
export const CARD_PALETTE_PRIMARY = '#1e4e79';
|
|
46
|
+
export const CARD_PALETTE_ACCENT = '#4b3f9e';
|
|
47
|
+
export const CARD_PALETTE_DANGER = '#8a3a2c';
|
|
48
|
+
export const CARD_PALETTE_SUCCESS = '#3f6e26';
|
|
49
|
+
export const CARD_PALETTE_NORMAL = '#3b4250';
|
|
50
|
+
export const CARD_PALETTE_MUTED = '#64748b';
|
|
51
|
+
// ── Satori checkpoint pills ───────────────────────────────────────────────────
|
|
52
|
+
export const CHECKPOINT_FILL = '#6b5212';
|
|
53
|
+
export const CHECKPOINT_BORDER = '#b8923a';
|
|
54
|
+
export const CHECKPOINT_TEXT = '#ffd98a';
|
|
55
|
+
// ── Satori connector arrows (vertical between cards) ─────────────────────────
|
|
56
|
+
export const CONNECTOR_COLOR = '#cbd5e1';
|
|
57
|
+
// ── Arrow markers (graph edges) ───────────────────────────────────────────────
|
|
58
|
+
export const ARROW_FILL = '#475569'; // filled arrowhead
|
|
59
|
+
export const ARROW_STROKE = '#475569'; // open arrowhead stroke
|
|
60
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../../src/domain/theme.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime validation for a DiagramSpec. The schema is the contract a model
|
|
3
|
+
* (later) must emit; the lab fails loud on a malformed spec so a technique
|
|
4
|
+
* never silently renders garbage. Pure, dependency-free.
|
|
5
|
+
*/
|
|
6
|
+
import type { DiagramSpec } from './spec.js';
|
|
7
|
+
export interface ValidationIssue {
|
|
8
|
+
path: string;
|
|
9
|
+
message: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validate structural integrity of a spec: unique node ids, edges/groups/
|
|
13
|
+
* annotations referencing real nodes, non-empty labels.
|
|
14
|
+
*
|
|
15
|
+
* @param spec the diagram spec to check
|
|
16
|
+
* @returns a list of issues; empty means valid
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateSpec(spec: DiagramSpec): ValidationIssue[];
|
|
19
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/domain/validate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,WAAW,GAAG,eAAe,EAAE,CA+DjE"}
|