@dr2rai/raid-canvas 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 +201 -0
- package/NOTICE +2 -0
- package/dist/RaiBridge.d.ts +54 -0
- package/dist/RaiBridge.d.ts.map +1 -0
- package/dist/RaiBridge.js +408 -0
- package/dist/RaiBridge.js.map +1 -0
- package/dist/X6Shapes.d.ts +134 -0
- package/dist/X6Shapes.d.ts.map +1 -0
- package/dist/X6Shapes.js +536 -0
- package/dist/X6Shapes.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +162 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +32 -0
- package/dist/types.js.map +1 -0
- package/package.json +42 -0
- package/src/RaiBridge.ts +485 -0
- package/src/X6Shapes.ts +575 -0
- package/src/index.ts +39 -0
- package/src/styles/aoaim-theme.css +205 -0
- package/src/types.ts +208 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* aoaim-theme.css
|
|
3
|
+
* Semantic CSS design tokens and component styling for the RaidCanvas AOAIM visual modeler.
|
|
4
|
+
* Adheres to the Cascais Heraldry palette and the aim-* ontological contract.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
:root {
|
|
8
|
+
/* Cascais Heraldry Design Tokens */
|
|
9
|
+
--aim-net-gold: #F59E0B;
|
|
10
|
+
--aim-heraldic-green: #10B981;
|
|
11
|
+
--aim-warm-graphite: #1F2937;
|
|
12
|
+
--aim-graphite-muted: #4B5563;
|
|
13
|
+
--aim-silver-line: #E5E7EB;
|
|
14
|
+
--aim-silver-line-dark: #D1D5DB;
|
|
15
|
+
--aim-chalk-white: #FFFFFF;
|
|
16
|
+
--aim-canvas-cream: #F8FAFC;
|
|
17
|
+
--aim-accent-blue: #3B82F6;
|
|
18
|
+
--aim-danger-crimson: #EF4444;
|
|
19
|
+
|
|
20
|
+
/* Typography */
|
|
21
|
+
--aim-font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
22
|
+
--aim-font-mono: 'JetBrains Mono', 'Menlo', 'Courier New', monospace;
|
|
23
|
+
|
|
24
|
+
/* Node Dimensions & Radii */
|
|
25
|
+
--aim-radius-act: 12px;
|
|
26
|
+
--aim-radius-card: 6px;
|
|
27
|
+
--aim-radius-round: 9999px;
|
|
28
|
+
|
|
29
|
+
/* Shadows */
|
|
30
|
+
--aim-shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
|
|
31
|
+
--aim-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
|
|
32
|
+
--aim-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
|
33
|
+
--aim-shadow-glow-gold: 0 0 0 3px rgba(245, 158, 11, 0.35);
|
|
34
|
+
--aim-shadow-glow-green: 0 0 0 3px rgba(16, 185, 129, 0.35);
|
|
35
|
+
--aim-shadow-glow-blue: 0 0 0 3px rgba(59, 130, 246, 0.35);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/* Canvas Container */
|
|
39
|
+
.aim-canvas {
|
|
40
|
+
background-color: var(--aim-canvas-cream);
|
|
41
|
+
font-family: var(--aim-font-family);
|
|
42
|
+
user-select: none;
|
|
43
|
+
-webkit-user-select: none;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* Base Ontological Node */
|
|
47
|
+
.aim-node {
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
transition: transform 0.1s ease, filter 0.15s ease;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.aim-node:hover {
|
|
53
|
+
filter: drop-shadow(0 4px 6px rgba(0, 0, 0, 0.08));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.aim-node.aim-selected {
|
|
57
|
+
outline: none;
|
|
58
|
+
filter: drop-shadow(0 0 8px rgba(59, 130, 246, 0.4));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/* 1. UseCase Nodes ('uc') */
|
|
62
|
+
.aim-node[aim-uc],
|
|
63
|
+
.aim-node[aim-kind="uc"],
|
|
64
|
+
.aim-uc {
|
|
65
|
+
fill: var(--aim-chalk-white);
|
|
66
|
+
stroke: var(--aim-net-gold);
|
|
67
|
+
stroke-width: 2px;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.aim-node[aim-uc]:hover,
|
|
71
|
+
.aim-node[aim-kind="uc"]:hover {
|
|
72
|
+
filter: drop-shadow(0 0 6px rgba(245, 158, 11, 0.4));
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/* 2. Activity Nodes ('act') */
|
|
76
|
+
.aim-node[aim-act],
|
|
77
|
+
.aim-node[aim-kind="act"],
|
|
78
|
+
.aim-act {
|
|
79
|
+
fill: var(--aim-canvas-cream);
|
|
80
|
+
stroke: var(--aim-heraldic-green);
|
|
81
|
+
stroke-width: 2px;
|
|
82
|
+
rx: var(--aim-radius-act);
|
|
83
|
+
ry: var(--aim-radius-act);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.aim-node[aim-act]:hover,
|
|
87
|
+
.aim-node[aim-kind="act"]:hover {
|
|
88
|
+
filter: drop-shadow(0 0 6px rgba(16, 185, 129, 0.4));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* 3. Class Specification Nodes ('cls') */
|
|
92
|
+
.aim-node[aim-cls],
|
|
93
|
+
.aim-node[aim-kind="cls"],
|
|
94
|
+
.aim-cls {
|
|
95
|
+
fill: var(--aim-chalk-white);
|
|
96
|
+
stroke: var(--aim-warm-graphite);
|
|
97
|
+
stroke-width: 1.5px;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.aim-node[aim-cls] .aim-cls-header {
|
|
101
|
+
fill: var(--aim-canvas-cream);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.aim-node[aim-cls] .aim-cls-divider {
|
|
105
|
+
stroke: var(--aim-silver-line);
|
|
106
|
+
stroke-width: 1px;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* 4. Object Instance Nodes ('obj') */
|
|
110
|
+
.aim-node[aim-obj],
|
|
111
|
+
.aim-node[aim-kind="obj"],
|
|
112
|
+
.aim-obj {
|
|
113
|
+
fill: var(--aim-chalk-white);
|
|
114
|
+
stroke: var(--aim-silver-line-dark);
|
|
115
|
+
stroke-width: 1.5px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/* 5. Person / Actor Nodes ('per') */
|
|
119
|
+
.aim-node[aim-per],
|
|
120
|
+
.aim-node[aim-kind="per"],
|
|
121
|
+
.aim-per {
|
|
122
|
+
fill: var(--aim-canvas-cream);
|
|
123
|
+
stroke: var(--aim-warm-graphite);
|
|
124
|
+
stroke-width: 1.5px;
|
|
125
|
+
rx: var(--aim-radius-card);
|
|
126
|
+
ry: var(--aim-radius-card);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.aim-node[aim-per][aim-role="initiating"] {
|
|
130
|
+
stroke: var(--aim-net-gold);
|
|
131
|
+
stroke-width: 2px;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* Relationship Edges */
|
|
135
|
+
.aim-edge {
|
|
136
|
+
fill: none;
|
|
137
|
+
stroke: var(--aim-warm-graphite);
|
|
138
|
+
stroke-width: 1.5px;
|
|
139
|
+
stroke-linecap: round;
|
|
140
|
+
stroke-linejoin: round;
|
|
141
|
+
transition: stroke 0.15s ease, stroke-width 0.15s ease;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.aim-edge:hover {
|
|
145
|
+
stroke: var(--aim-accent-blue);
|
|
146
|
+
stroke-width: 2.5px;
|
|
147
|
+
cursor: pointer;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.aim-edge[aim-edge-kind="dependency"] {
|
|
151
|
+
stroke-dasharray: 5, 5;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.aim-edge[aim-edge-kind="realization"] {
|
|
155
|
+
stroke-dasharray: 6, 4;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* Orthogonal Port Docking Magnets */
|
|
159
|
+
.aim-port-body {
|
|
160
|
+
fill: var(--aim-chalk-white);
|
|
161
|
+
stroke: var(--aim-warm-graphite);
|
|
162
|
+
stroke-width: 1.5px;
|
|
163
|
+
transition: transform 0.1s ease, fill 0.1s ease;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.aim-port-body:hover {
|
|
167
|
+
fill: var(--aim-net-gold);
|
|
168
|
+
stroke: var(--aim-warm-graphite);
|
|
169
|
+
transform: scale(1.4);
|
|
170
|
+
cursor: crosshair;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/* User-Editable Edge Bend Point Vertices */
|
|
174
|
+
.x6-edge-tool-vertex {
|
|
175
|
+
fill: var(--aim-chalk-white);
|
|
176
|
+
stroke: var(--aim-accent-blue);
|
|
177
|
+
stroke-width: 2px;
|
|
178
|
+
cursor: move;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
.x6-edge-tool-vertex:hover {
|
|
182
|
+
fill: var(--aim-accent-blue);
|
|
183
|
+
transform: scale(1.3);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/* Dark Mode Overrides */
|
|
187
|
+
@media (prefers-color-scheme: dark) {
|
|
188
|
+
:root {
|
|
189
|
+
--aim-canvas-cream: #0F172A;
|
|
190
|
+
--aim-chalk-white: #1E293B;
|
|
191
|
+
--aim-warm-graphite: #94A3B8;
|
|
192
|
+
--aim-silver-line: #334155;
|
|
193
|
+
--aim-silver-line-dark: #475569;
|
|
194
|
+
--aim-text-primary: #F8FAFC;
|
|
195
|
+
--aim-text-secondary: #94A3B8;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.aim-canvas {
|
|
199
|
+
background-color: var(--aim-canvas-cream);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.aim-edge {
|
|
203
|
+
stroke: var(--aim-warm-graphite);
|
|
204
|
+
}
|
|
205
|
+
}
|
package/src/types.ts
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file types.ts
|
|
3
|
+
* @description Core ontological types, metamodel contracts, and SVG attributes
|
|
4
|
+
* for the RaidCanvas AOAIM visual modeler.
|
|
5
|
+
*
|
|
6
|
+
* Honors Alan Kay's vision of living, reactive object systems and Rainer Burkhardt's
|
|
7
|
+
* C++ GrafObj graphical object hierarchies.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Canonical AOAIM (Activity-Object-AI Model) entity archetypes.
|
|
12
|
+
*
|
|
13
|
+
* - 'uc' : UseCase (elliptical boundary, Cascais Net Gold accent)
|
|
14
|
+
* - 'act' : Activity (rounded rectangle process step, Heraldic Green accent)
|
|
15
|
+
* - 'cls' : Class (compartmentalized class specification card)
|
|
16
|
+
* - 'obj' : Object / Instance (runtime instance card with underlined title)
|
|
17
|
+
* - 'per' : Person / Actor (Initiating or Defined role stick-figure/card)
|
|
18
|
+
*/
|
|
19
|
+
export type AimOntologyKind = 'uc' | 'act' | 'cls' | 'obj' | 'per';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Ontological relationship classifications in AOAIM.
|
|
23
|
+
*/
|
|
24
|
+
export type AimEdgeKind =
|
|
25
|
+
| 'association'
|
|
26
|
+
| 'dependency'
|
|
27
|
+
| 'generalization'
|
|
28
|
+
| 'realization'
|
|
29
|
+
| 'aggregation'
|
|
30
|
+
| 'composition';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* 2D Cartesian coordinate pair for geometry and Manhattan orthogonal routing.
|
|
34
|
+
*/
|
|
35
|
+
export interface Point {
|
|
36
|
+
readonly x: number;
|
|
37
|
+
readonly y: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Single bend point (vertex) along an orthogonal Manhattan edge path.
|
|
42
|
+
*/
|
|
43
|
+
export interface SvgBendPoint {
|
|
44
|
+
readonly x: number;
|
|
45
|
+
readonly y: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 2D Bounding box for nodes and frames.
|
|
50
|
+
*/
|
|
51
|
+
export interface Bounds {
|
|
52
|
+
readonly x: number;
|
|
53
|
+
readonly y: number;
|
|
54
|
+
readonly width: number;
|
|
55
|
+
readonly height: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Canonical port identifiers for 4-way orthogonal docking.
|
|
60
|
+
*/
|
|
61
|
+
export type OrthogonalPortId = 'port-top' | 'port-right' | 'port-bottom' | 'port-left';
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Metadata carried by an ontological node inside AntV X6.
|
|
65
|
+
*/
|
|
66
|
+
export interface RaidNodeData {
|
|
67
|
+
/** Unique entity identifier in the metamodel (e.g., 'SignContract_UC'). */
|
|
68
|
+
readonly id: string;
|
|
69
|
+
|
|
70
|
+
/** Ontological kind of the node. */
|
|
71
|
+
readonly kind: AimOntologyKind;
|
|
72
|
+
|
|
73
|
+
/** Display label presented on the canvas. */
|
|
74
|
+
readonly displayName: string;
|
|
75
|
+
|
|
76
|
+
/** Optional ontological stereotype (e.g., '«initiates»', '«executes»'). */
|
|
77
|
+
readonly stereotype?: string;
|
|
78
|
+
|
|
79
|
+
/** Subtitle, frame, or namespace tag. */
|
|
80
|
+
readonly namespace?: string;
|
|
81
|
+
|
|
82
|
+
/** For 'cls' / 'obj': list of attribute or field declarations. */
|
|
83
|
+
readonly attributes?: readonly string[];
|
|
84
|
+
|
|
85
|
+
/** For 'cls': list of method or operation declarations. */
|
|
86
|
+
readonly methods?: readonly string[];
|
|
87
|
+
|
|
88
|
+
/** Spatial bounds of the node. */
|
|
89
|
+
readonly bounds: Bounds;
|
|
90
|
+
|
|
91
|
+
/** Custom extension properties passed from or serialized to .raid manifests. */
|
|
92
|
+
readonly properties?: Readonly<Record<string, unknown>>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Metadata carried by an ontological edge inside AntV X6.
|
|
97
|
+
*/
|
|
98
|
+
export interface RaidEdgeData {
|
|
99
|
+
/** Unique edge identifier. */
|
|
100
|
+
readonly id: string;
|
|
101
|
+
|
|
102
|
+
/** Ontological relationship type. */
|
|
103
|
+
readonly kind: AimEdgeKind;
|
|
104
|
+
|
|
105
|
+
/** Identifier of the source node. */
|
|
106
|
+
readonly sourceId: string;
|
|
107
|
+
|
|
108
|
+
/** Identifier of the target node. */
|
|
109
|
+
readonly targetId: string;
|
|
110
|
+
|
|
111
|
+
/** Optional docking port on source node. */
|
|
112
|
+
readonly sourcePort?: OrthogonalPortId | string;
|
|
113
|
+
|
|
114
|
+
/** Optional docking port on target node. */
|
|
115
|
+
readonly targetPort?: OrthogonalPortId | string;
|
|
116
|
+
|
|
117
|
+
/** Optional edge label text. */
|
|
118
|
+
readonly label?: string;
|
|
119
|
+
|
|
120
|
+
/** Optional edge stereotype annotation (e.g., '«DependsOn»'). */
|
|
121
|
+
readonly stereotype?: string;
|
|
122
|
+
|
|
123
|
+
/** Multiplicity / Cardinality at the source end (e.g., '1', '0..*'). */
|
|
124
|
+
readonly sourceCardinality?: string;
|
|
125
|
+
|
|
126
|
+
/** Multiplicity / Cardinality at the target end (e.g., '0..1', '*'). */
|
|
127
|
+
readonly targetCardinality?: string;
|
|
128
|
+
|
|
129
|
+
/** User-editable or router-computed Manhattan bend points. */
|
|
130
|
+
readonly bendPoints: readonly SvgBendPoint[];
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Full in-memory metamodel representation corresponding to a `.raid` manifest.
|
|
135
|
+
*/
|
|
136
|
+
export interface RaidMetamodel {
|
|
137
|
+
/** Diagram identifier (e.g., 'SignContract_UCD'). */
|
|
138
|
+
readonly diagramId: string;
|
|
139
|
+
|
|
140
|
+
/** Optional human-readable title. */
|
|
141
|
+
readonly title?: string;
|
|
142
|
+
|
|
143
|
+
/** Archetype classification (e.g., 'OneUseCaseDiagram', 'ClassDiagram', 'ActivityDiagram'). */
|
|
144
|
+
readonly archetype: string;
|
|
145
|
+
|
|
146
|
+
/** Entity nodes projected in the diagram. */
|
|
147
|
+
readonly nodes: readonly RaidNodeData[];
|
|
148
|
+
|
|
149
|
+
/** Relationships connecting projected nodes. */
|
|
150
|
+
readonly edges: readonly RaidEdgeData[];
|
|
151
|
+
|
|
152
|
+
/** Additional diagram-level metadata. */
|
|
153
|
+
readonly metadata?: Readonly<Record<string, unknown>>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Contractual SVG attribute names adhering to the 'aim-*' standard.
|
|
158
|
+
*/
|
|
159
|
+
export const AimSvgContract = {
|
|
160
|
+
// Node marking & attributes
|
|
161
|
+
ATTR_NODE: 'aim-node',
|
|
162
|
+
ATTR_ID: 'aim-id',
|
|
163
|
+
ATTR_KIND: 'aim-kind',
|
|
164
|
+
ATTR_DISPLAY_NAME: 'aim-display-name',
|
|
165
|
+
ATTR_STEREOTYPE: 'aim-stereotype',
|
|
166
|
+
ATTR_NAMESPACE: 'aim-namespace',
|
|
167
|
+
|
|
168
|
+
// Edge marking & attributes
|
|
169
|
+
ATTR_EDGE: 'aim-edge',
|
|
170
|
+
ATTR_EDGE_KIND: 'aim-edge-kind',
|
|
171
|
+
ATTR_SOURCE: 'aim-source',
|
|
172
|
+
ATTR_TARGET: 'aim-target',
|
|
173
|
+
ATTR_SOURCE_PORT: 'aim-source-port',
|
|
174
|
+
ATTR_TARGET_PORT: 'aim-target-port',
|
|
175
|
+
ATTR_BENDS: 'aim-bends',
|
|
176
|
+
|
|
177
|
+
// Selectors for DOM queries
|
|
178
|
+
SELECTOR_NODE: '[aim-node], [data-node], g[aim-kind]',
|
|
179
|
+
SELECTOR_EDGE: '[aim-edge], path[aim-edge-kind]',
|
|
180
|
+
} as const;
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Options for hydrating an AntV X6 graph from an SVG document.
|
|
184
|
+
*/
|
|
185
|
+
export interface HydrationOptions {
|
|
186
|
+
/** If true, clears any existing graph elements before populating. Default: true. */
|
|
187
|
+
readonly clearGraph?: boolean;
|
|
188
|
+
|
|
189
|
+
/** If true, automatically executes Manhattan routing if bend points are missing. Default: true. */
|
|
190
|
+
readonly autoRouteEdges?: boolean;
|
|
191
|
+
|
|
192
|
+
/** Default fallback dimensions when width/height are unspecified in SVG. */
|
|
193
|
+
readonly defaultNodeSize?: { readonly width: number; readonly height: number };
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Options for serializing an AntV X6 graph to an SVG document.
|
|
198
|
+
*/
|
|
199
|
+
export interface SerializationOptions {
|
|
200
|
+
/** Base SVG template to inject updated coordinates and bend points into. */
|
|
201
|
+
readonly baseSvg?: string;
|
|
202
|
+
|
|
203
|
+
/** Pretty-print XML output with indentation. Default: true. */
|
|
204
|
+
readonly format?: boolean;
|
|
205
|
+
|
|
206
|
+
/** Inject Cascais design token CSS variables into `<defs><style>`. Default: true. */
|
|
207
|
+
readonly embedStyles?: boolean;
|
|
208
|
+
}
|