@peter.prib/renderengine 0.2.5 → 0.2.7

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.
Files changed (67) hide show
  1. package/README.md +219 -213
  2. package/REFERENCE.md +272 -6
  3. package/dist/renderengine-workspace.umd.js +11980 -7421
  4. package/dist/renderengine.umd.js +8991 -5784
  5. package/examples/archimate.html +68 -66
  6. package/examples/data-model.html +534 -0
  7. package/package.json +70 -68
  8. package/src/bian.js +182 -0
  9. package/src/charting/CheckboxTreeSelector.js +373 -304
  10. package/src/charting/DiagramEditor.js +53 -32
  11. package/src/charting/DiagramTypeRegistry.js +13 -3
  12. package/src/charting/ModelCheckDialog.js +63 -0
  13. package/src/charting/ModelChecker.js +26 -0
  14. package/src/charting/ViewTabStrip.js +94 -81
  15. package/src/charting/archimate/ArchimateCanvasEditor.js +825 -815
  16. package/src/charting/archimate/ArchimateElementTemplate.js +208 -195
  17. package/src/charting/datamodel/BianLandscapeReader.js +185 -0
  18. package/src/charting/datamodel/BianSemanticApiReader.js +183 -0
  19. package/src/charting/datamodel/DataModel.js +645 -0
  20. package/src/charting/datamodel/DataModelChecker.js +92 -0
  21. package/src/charting/datamodel/DataModelCompared.js +127 -0
  22. package/src/charting/datamodel/DataModelContext.js +108 -0
  23. package/src/charting/datamodel/DataModelFileFormat.js +33 -0
  24. package/src/charting/datamodel/DataModelPerspective.js +129 -0
  25. package/src/charting/datamodel/DataType.js +108 -0
  26. package/src/charting/datamodel/EnumerationType.js +51 -0
  27. package/src/charting/datamodel/LevelMapping.js +38 -0
  28. package/src/charting/datamodel/LevelSchema.js +41 -0
  29. package/src/charting/datamodel/ServiceDomain.js +177 -0
  30. package/src/charting/datamodel/ServiceLandscape.js +104 -0
  31. package/src/charting/datamodel/StructuredType.js +63 -0
  32. package/src/charting/datamodel/index.js +15 -0
  33. package/src/charting/diagramModel/MergeModelCommand.js +43 -37
  34. package/src/charting/diagramModel/OpenViewList.js +75 -0
  35. package/src/charting/diagramModel/ViewSetChecker.js +22 -34
  36. package/src/charting/diagrams/DataModelDiagram.js +160 -86
  37. package/src/charting/diagrams/DataModelRelationshipStrategy.js +94 -38
  38. package/src/charting/diagrams/EdgeGeometry.js +578 -553
  39. package/src/charting/diagrams/GraphDiagram.js +11 -1
  40. package/src/charting/diagrams/NodeGeometry.js +169 -158
  41. package/src/charting/diagrams/nesting.js +31 -0
  42. package/src/charting/glyphs/PersonGlyph.js +24 -23
  43. package/src/charting/modelTree/ModelTree.js +202 -164
  44. package/src/charting/modelTree/ModelTreePanel.js +36 -3
  45. package/src/charting/modelTree/TreeViewMode.js +131 -110
  46. package/src/charting/modelTree/modes/FlatTreeMode.js +32 -46
  47. package/src/charting/modelTree/modes/LayerGroupedTreeMode.js +47 -62
  48. package/src/charting/modelTree/modes/TypeGroupedTreeMode.js +46 -60
  49. package/src/datamodel.js +132 -122
  50. package/src/diagramCatalog.js +35 -30
  51. package/src/index.js +2666 -2659
  52. package/src/workspace/EditorShell.js +166 -67
  53. package/src/workspace/PanelLayout.js +56 -0
  54. package/src/workspace/index.js +1 -0
  55. package/src/workspace/layout/TabsNode.js +205 -191
  56. package/src/workspace/parts/ArchimateCanvasPart.js +10 -9
  57. package/src/workspace/parts/ChartPart.js +6 -1
  58. package/src/workspace/parts/DataModelPart.js +544 -0
  59. package/src/workspace/parts/DiagramEditorPart.js +2 -8
  60. package/src/workspace/parts/EditorPart.js +461 -407
  61. package/src/workspace/parts/ModelFile.js +216 -187
  62. package/src/workspace/parts/ModelsPart.js +483 -192
  63. package/src/workspace/storage/BackupFolder.js +145 -0
  64. package/src/workspace/storage/KeyValueStore.js +92 -0
  65. package/src/workspace/storage/ModelLibrary.js +65 -0
  66. package/src/workspace/workArea.js +417 -413
  67. package/src/yaml/YamlReader.js +372 -0
package/package.json CHANGED
@@ -1,68 +1,70 @@
1
- {
2
- "name": "@peter.prib/renderengine",
3
- "version": "0.2.5",
4
- "description": "ArchiMate modeller, diagram editor and chart library for the browser, with no runtime dependencies.",
5
- "type": "module",
6
- "main": "src/index.js",
7
- "module": "src/index.js",
8
- "browser": "dist/renderengine.umd.js",
9
- "exports": {
10
- ".": "./src/index.js",
11
- "./workspace": "./src/workspace/index.js",
12
- "./src/*": "./src/*",
13
- "./dist/*": "./dist/*",
14
- "./package.json": "./package.json"
15
- },
16
- "files": [
17
- "src/",
18
- "dist/*.umd.js",
19
- "examples/archimate.html",
20
- "examples/diagram-editor.html",
21
- "README.md",
22
- "REFERENCE.md",
23
- "LICENSE"
24
- ],
25
- "scripts": {
26
- "start": "node scripts/open.mjs examples/archimate.html",
27
- "archimate": "node scripts/open.mjs examples/archimate.html",
28
- "diagram": "node scripts/open.mjs examples/diagram-editor.html",
29
- "test": "node --test --test-timeout=10000 ./test/*.js ./test/charting/*.js ./test/charting/charts/*.js ./test/charting/diagrams/*.js ./test/charting/shapes/*.js",
30
- "build": "rollup -c",
31
- "prepublishOnly": "npm test && npm run build",
32
- "screenshots": "node scripts/screenshots/screenshots.mjs"
33
- },
34
- "keywords": [
35
- "archimate",
36
- "archi",
37
- "diagram",
38
- "diagram-editor",
39
- "modelling",
40
- "charts",
41
- "svg",
42
- "canvas",
43
- "render",
44
- "engine",
45
- "graphics"
46
- ],
47
- "author": "Peter Prib <peter.prib@gmail.com>",
48
- "license": "MIT",
49
- "repository": {
50
- "type": "git",
51
- "url": "git+https://gitlab.com/peter.prib/renderengine.git"
52
- },
53
- "homepage": "https://gitlab.com/peter.prib/renderengine#readme",
54
- "bugs": {
55
- "url": "https://gitlab.com/peter.prib/renderengine/-/issues"
56
- },
57
- "engines": {
58
- "node": ">=18"
59
- },
60
- "publishConfig": {
61
- "access": "public"
62
- },
63
- "devDependencies": {
64
- "@rollup/plugin-commonjs": "^25.0.8",
65
- "@rollup/plugin-node-resolve": "^15.3.1",
66
- "rollup": "^3.30.0"
67
- }
68
- }
1
+ {
2
+ "name": "@peter.prib/renderengine",
3
+ "version": "0.2.7",
4
+ "description": "ArchiMate modeller, diagram editor and chart library for the browser, with no runtime dependencies.",
5
+ "type": "module",
6
+ "main": "src/index.js",
7
+ "module": "src/index.js",
8
+ "browser": "dist/renderengine.umd.js",
9
+ "exports": {
10
+ ".": "./src/index.js",
11
+ "./workspace": "./src/workspace/index.js",
12
+ "./src/*": "./src/*",
13
+ "./dist/*": "./dist/*",
14
+ "./package.json": "./package.json"
15
+ },
16
+ "files": [
17
+ "src/",
18
+ "dist/*.umd.js",
19
+ "examples/archimate.html",
20
+ "examples/diagram-editor.html",
21
+ "examples/data-model.html",
22
+ "README.md",
23
+ "REFERENCE.md",
24
+ "LICENSE"
25
+ ],
26
+ "scripts": {
27
+ "start": "node scripts/open.mjs examples/archimate.html",
28
+ "archimate": "node scripts/open.mjs examples/archimate.html",
29
+ "diagram": "node scripts/open.mjs examples/diagram-editor.html",
30
+ "datamodel": "node scripts/open.mjs examples/data-model.html",
31
+ "test": "node --test --test-timeout=10000 ./test/*.js ./test/charting/*.js ./test/charting/charts/*.js ./test/charting/diagrams/*.js ./test/charting/shapes/*.js",
32
+ "build": "rollup -c",
33
+ "prepublishOnly": "npm test && npm run build",
34
+ "screenshots": "node scripts/screenshots/screenshots.mjs"
35
+ },
36
+ "keywords": [
37
+ "archimate",
38
+ "archi",
39
+ "diagram",
40
+ "diagram-editor",
41
+ "modelling",
42
+ "charts",
43
+ "svg",
44
+ "canvas",
45
+ "render",
46
+ "engine",
47
+ "graphics"
48
+ ],
49
+ "author": "Peter Prib <peter.prib@gmail.com>",
50
+ "license": "MIT",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://gitlab.com/peter.prib/renderengine.git"
54
+ },
55
+ "homepage": "https://gitlab.com/peter.prib/renderengine#readme",
56
+ "bugs": {
57
+ "url": "https://gitlab.com/peter.prib/renderengine/-/issues"
58
+ },
59
+ "engines": {
60
+ "node": ">=18"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public"
64
+ },
65
+ "devDependencies": {
66
+ "@rollup/plugin-commonjs": "^25.0.8",
67
+ "@rollup/plugin-node-resolve": "^15.3.1",
68
+ "rollup": "^3.30.0"
69
+ }
70
+ }
package/src/bian.js ADDED
@@ -0,0 +1,182 @@
1
+ /**
2
+ * BIAN vocabulary — the Banking Industry Architecture Network's service
3
+ * domain terms, as one registry (as src/archimate.js and src/datamodel.js are)
4
+ * that pickers, dialogs and service domains read rather than restate.
5
+ *
6
+ * Sources: the BIAN Semantic API Practitioner Guide V8.1 (December 2024) for the
7
+ * functional patterns' descriptions and the action terms in their four groups;
8
+ * BIAN's v14 model as its service landscape portal publishes it
9
+ * (bian.org/servicelandscape-14-0-0) for each pattern's generic artifact, its
10
+ * behaviour qualifier type (the type the artifact aggregates) and the creating
11
+ * action term it aggregates; BIAN's release 14.0.0 semantic APIs
12
+ * (github.com/bian-official/public, Apache-2.0) for the names control records
13
+ * have and, where a pattern aggregates two creating terms (Monitor: evaluate
14
+ * and initiate), the one its APIs use. Every value is BIAN's; `inferred` is
15
+ * kept for a value that is not. See BIAN_ALIGNMENT.md.
16
+ */
17
+
18
+ /** One way a service domain behaves: what it does to its asset, and the record it keeps of it. */
19
+ export class BianFunctionalPattern {
20
+ /**
21
+ * @param {string} name - 'Fulfill'
22
+ * @param {Object} spec
23
+ * @param {string} spec.artifact - The generic artifact a control record is ('Facility')
24
+ * @param {string} spec.description
25
+ * @param {string} spec.creates - The action term that makes a new control record ('initiate')
26
+ * @param {string} spec.qualifierType - How the control record is broken down ('Fulfillment')
27
+ * @param {string[]} [spec.inferred] - Which of creates/qualifierType are inferred, not confirmed
28
+ * @param {string[]} [spec.formerArtifacts] - Names the artifact had before ('Arrangement' for Fulfill's)
29
+ */
30
+ constructor(name, { artifact, description, creates, qualifierType, inferred = [], formerArtifacts = [] }) {
31
+ this.name = name;
32
+ this.artifact = artifact;
33
+ this.formerArtifacts = Object.freeze([...formerArtifacts]);
34
+ this.description = description;
35
+ this.creates = creates;
36
+ this.qualifierType = qualifierType;
37
+ this.inferred = Object.freeze([...inferred]);
38
+ }
39
+
40
+ /** The control record's name for an asset: 'Current Account' gives 'Current Account Facility'. */
41
+ controlRecordName(asset) {
42
+ return [asset, this.artifact].filter(Boolean).join(' ');
43
+ }
44
+ }
45
+
46
+ /** An action term: what a service operation does, and to what. */
47
+ export class BianActionTerm {
48
+ /**
49
+ * @param {string} name - 'initiate'
50
+ * @param {'service-domain'|'create'|'instance'|'read'} group
51
+ * @param {string} description
52
+ */
53
+ constructor(name, group, description) {
54
+ this.name = name;
55
+ this.group = group;
56
+ this.description = description;
57
+ }
58
+ }
59
+
60
+ const fp = (name, artifact, description, creates, qualifierType, inferred = [], formerArtifacts = []) =>
61
+ [name, new BianFunctionalPattern(name, { artifact, description, creates, qualifierType, inferred, formerArtifacts })];
62
+
63
+ /**
64
+ * The nineteen functional patterns, each with its artifact, creating action term
65
+ * and behaviour qualifier type as BIAN's v14 model has them.
66
+ */
67
+ const FUNCTIONAL_PATTERNS = new Map([
68
+ fp('Direct', 'Strategy', 'Define the policies, goals and objectives and strategies for an organizational entity or unit.', 'create', 'Goal'),
69
+ fp('Manage', 'Management Plan', 'Oversee the working of a business unit, assign work, manage against a plan and troubleshoot issues.', 'create', 'Duty'),
70
+ fp('Administer', 'Administrative Plan', 'Handle and assign the day to day activities, capture time worked, costs and income for an operational unit.', 'create', 'Routine'),
71
+ fp('Design', 'Specification', 'Create and maintain a design for a procedure, product/service model or other such entity.', 'create', 'Aspect'),
72
+ fp('Develop', 'Development', 'Build or enhance something, typically an IT production system: development, assessment and deployment.', 'create', 'Deliverable'),
73
+ fp('Process', 'Procedure', 'Complete work tasks following a procedure in support of general office activities and product and service delivery.', 'initiate', 'Workstep'),
74
+ fp('Operate', 'Operating Session', 'Operate equipment and/or a largely automated facility.', 'initiate', 'Function'),
75
+ fp('Maintain', 'Maintenance Arrangement', 'Provide a maintenance service and repair devices/equipment as necessary.', 'initiate', 'Item'),
76
+ fp('Fulfill', 'Facility', 'Fulfill scheduled and ad-hoc obligations under a service arrangement, most typically for a financial product or facility.', 'initiate', 'Fulfillment', [], ['Arrangement']),
77
+ fp('Transact', 'Transaction', 'Execute a well bounded financial transaction/task, typically largely automated, structured fulfillment processing.', 'initiate', 'Task'),
78
+ fp('Agree Terms', 'Agreement', 'Maintain the terms and conditions that apply to a commercial relationship.', 'evaluate', 'Term'),
79
+ fp('Assess', 'Assessment', 'Test or assess an entity, possibly against some formal qualification or certification requirement.', 'evaluate', 'Test'),
80
+ fp('Analyze', 'Analysis', 'Analyze the performance or behavior of some on-going activity or entity.', 'evaluate', 'Algorithm'),
81
+ fp('Monitor', 'State', 'Monitor and define the state/rating of some entity.', 'initiate', 'Indicator'),
82
+ fp('Track', 'Log', 'Maintain a log of transactions or activity, typically a financial account/journal or a log of activity.', 'initiate', 'Event', [], ['Log Record']),
83
+ fp('Catalog', 'Directory Entry', 'Capture and maintain reference information about some type of entity.', 'register', 'Property'),
84
+ fp('Enroll', 'Membership', 'Maintain a membership for some group or related collection of parties.', 'register', 'Clause'),
85
+ fp('Allocate', 'Allocation', 'Maintain an inventory or holding of some resource and make assignments/allocations as requested.', 'provide', 'Criteria'),
86
+ fp('Advise', 'Advice', 'Provide specialist advice and/or support as an ongoing service or for a specific task/event.', 'initiate', 'Topic'),
87
+ ]);
88
+
89
+ /** Names a pattern has had ('Analyse', the guide's; BIAN's model has 'Analyze'). */
90
+ const PATTERN_ALIASES = new Map([['Analyse', 'Analyze']]);
91
+
92
+ const at = (name, group, description) => [name, new BianActionTerm(name, group, description)];
93
+
94
+ /** The seventeen action terms in their four groups (Practitioner Guide V8.1, Figure 14 and after). */
95
+ const ACTION_TERMS = new Map([
96
+ at('activate', 'service-domain', 'Start the service domain operating as a service center.'),
97
+ at('configure', 'service-domain', 'Change how the service domain operates.'),
98
+ at('feedback', 'service-domain', 'Give feedback on how the service domain operates.'),
99
+ at('create', 'create', 'Make a new control record (a plan, a design, a solution).'),
100
+ at('initiate', 'create', 'Create and start a new control record, or a behaviour qualifier of one.'),
101
+ at('register', 'create', 'Add a new entry: catalogue or enroll.'),
102
+ at('evaluate', 'create', 'Start a test, check or analysis.'),
103
+ at('provide', 'create', 'Provide a new instance (an allocation, a log record).'),
104
+ at('update', 'instance', 'Change the values of an active control record.'),
105
+ at('control', 'instance', 'Change the state of an active control record (suspend, resume, terminate).'),
106
+ at('exchange', 'instance', 'Accept, reject, verify or otherwise exchange about an active control record.'),
107
+ at('capture', 'instance', 'Take in information about an active control record from outside.'),
108
+ at('execute', 'instance', 'Run an automated task on an active control record or one of its behaviour qualifiers.'),
109
+ at('request', 'instance', 'Ask for a task on an active control record that needs a decision or manual work.'),
110
+ at('grant', 'instance', 'Give an authorization or permission against an active control record.'),
111
+ at('retrieve', 'read', 'Get details of one or more control records, without changing them.'),
112
+ at('notify', 'read', 'Subscribe to changes of control records, without changing them.'),
113
+ ]);
114
+
115
+ /** The behaviour qualifier types, as BIAN v14.0 rationalised them (release notes, section 7.2). */
116
+ const QUALIFIER_TYPES = Object.freeze([
117
+ 'Fulfillment', 'Term', 'Duty', 'Aspect', 'Clause', 'Algorithm', 'Task', 'Property', 'Routine', 'Criteria',
118
+ 'Deliverable', 'Indicator', 'Topic', 'Workstep', 'Event', 'Goal', 'Function', 'Test', 'Item',
119
+ ]);
120
+
121
+ /** The action terms that act on an existing control record or behaviour qualifier, or read one. */
122
+ const ON_INSTANCE = Object.freeze(['instance', 'read']);
123
+
124
+ export const BianNotation = {
125
+ /** Every functional pattern, in the guide's order. */
126
+ functionalPatterns() { return [...FUNCTIONAL_PATTERNS.values()]; },
127
+ /** A functional pattern by name, or null. */
128
+ functionalPattern(name) { return FUNCTIONAL_PATTERNS.get(name) ?? FUNCTIONAL_PATTERNS.get(PATTERN_ALIASES.get(name)) ?? null; },
129
+ /** A pattern by its name as written anywhere: any case, extra spaces, a former name ('analyse'); null for none. */
130
+ findPattern(text) {
131
+ const word = String(text ?? '').trim().replace(/\s+/g, ' ').toLowerCase();
132
+ if (!word) return null;
133
+ const alias = [...PATTERN_ALIASES].find(([old]) => old.toLowerCase() === word)?.[1];
134
+ return [...FUNCTIONAL_PATTERNS.values()].find(p => p.name.toLowerCase() === word || p.name === alias) ?? null;
135
+ },
136
+ /**
137
+ * The pattern a control record's name says it has, by the artifact it ends
138
+ * with ('CurrentAccountFacility' or 'Current Account Facility': Fulfill;
139
+ * a former artifact name too), the longest match first; null for none.
140
+ */
141
+ patternOfControlRecord(name) {
142
+ const words = String(name ?? '').replace(/([a-z0-9])([A-Z])/g, '$1 $2').replace(/([A-Z]+)([A-Z][a-z])/g, '$1 $2').toLowerCase().split(/\s+/).filter(Boolean).join(' ');
143
+ const ends = [...FUNCTIONAL_PATTERNS.values()]
144
+ .flatMap(p => [p.artifact, ...p.formerArtifacts].map(a => [a.toLowerCase(), p]))
145
+ .sort(([a], [b]) => b.length - a.length);
146
+ return ends.find(([a]) => words === a || words.endsWith(` ${a}`))?.[1] ?? null;
147
+ },
148
+ /** Every action term. */
149
+ actionTerms() { return [...ACTION_TERMS.values()]; },
150
+ actionTerm(name) { return ACTION_TERMS.get(name) ?? null; },
151
+ /** The behaviour qualifier types. */
152
+ qualifierTypes() { return [...QUALIFIER_TYPES]; },
153
+ isQualifierType(type) { return QUALIFIER_TYPES.includes(type); },
154
+
155
+ /**
156
+ * A service domain's default service operations for a functional pattern
157
+ * (the starting point BIAN gives; a deployment may drop or add some): the
158
+ * service-domain-wide terms on the service domain; the pattern's creating
159
+ * term on the control record and on each behaviour qualifier; and each
160
+ * instance and read term on the control record and each behaviour qualifier.
161
+ * @param {string} patternName
162
+ * @param {{serviceDomain: string, controlRecord: string, qualifiers?: string[]}} names
163
+ * 'Current Account', 'Current Account Arrangement', ['Interest', 'Payments']
164
+ * @returns {Array<{actionTerm: string, target: string, qualifier: string|null, name: string}>}
165
+ */
166
+ serviceOperations(patternName, { serviceDomain, controlRecord, qualifiers = [] }) {
167
+ const pattern = FUNCTIONAL_PATTERNS.get(patternName);
168
+ if (!pattern) return [];
169
+ const op = (term, target, qualifier = null) => ({
170
+ actionTerm: term, target, qualifier,
171
+ name: `${term} ${target}${qualifier ? ` | ${qualifier}` : ''}`,
172
+ });
173
+ const terms = (group) => [...ACTION_TERMS.values()].filter(t => group(t.group)).map(t => t.name);
174
+ const onInstance = terms(g => ON_INSTANCE.includes(g));
175
+ return [
176
+ ...terms(g => g === 'service-domain').map(t => op(t, serviceDomain)),
177
+ op(pattern.creates, controlRecord),
178
+ ...onInstance.map(t => op(t, controlRecord)),
179
+ ...qualifiers.flatMap(q => [op(pattern.creates, controlRecord, q), ...onInstance.map(t => op(t, controlRecord, q))]),
180
+ ];
181
+ },
182
+ };